Commit f0713093 authored by Paul Seyfert's avatar Paul Seyfert

New upstream version 0.3

parent a725b718
Changelog Changelog
========= =========
0.3 - 2018-12-10
----------------
• Miscellaneous maintenance changes
• Updated empty-line treatment
• Changed xrandr parseing
• Cleanup of unused perl modules
• Bugfix: allow symlinks in user .shellex directories
• Use configuration from `$XDG_CONFIG_HOME`
• Enable compinit by default, add ctrl-x r for recent file completion
The slight change in the default completion behaviour is very likely desirable.
In the unlikely chance that a user does not appreciate the change, refer to the
README about how to disable the snippet `20-completion`.
0.2 - 2016-12-27 0.2 - 2016-12-27
---------------- ----------------
• Added optional sudo configuration • Added optional sudo configuration
......
...@@ -13,6 +13,7 @@ include preload/preload.mk ...@@ -13,6 +13,7 @@ include preload/preload.mk
include shellex.mk include shellex.mk
include urxvt/urxvt_shellex.mk include urxvt/urxvt_shellex.mk
include conf.mk include conf.mk
include format.mk
include doc/man/man.mk include doc/man/man.mk
real-all: $(ALL_TARGETS) real-all: $(ALL_TARGETS)
......
...@@ -20,10 +20,10 @@ from working. After not much seem to happen in that direction, I decided to ...@@ -20,10 +20,10 @@ from working. After not much seem to happen in that direction, I decided to
start again, this time using `urxvt` to do the terminal-part, which turned out to start again, this time using `urxvt` to do the terminal-part, which turned out to
be really easy. be really easy.
So, this is the early prototype. It is usable and should already work and be While this had the label “early prototype”, it has worked in daily use quite
useful, but much is not working yet. I hope this time I will continue the work reasonably. A few possible improvements were never apparently important enough
for longer ;) to invest serious amounts of time and work into them. Still, contributions are
welcome.
Architecture Architecture
============ ============
...@@ -48,13 +48,13 @@ Working: ...@@ -48,13 +48,13 @@ Working:
* Dynamic resizing of the launcher-window e.g. for multiple lines of * Dynamic resizing of the launcher-window e.g. for multiple lines of
suggestions for tab-completions (see [doc/autoresize.txt](doc/autoresize.txt)) suggestions for tab-completions (see [doc/autoresize.txt](doc/autoresize.txt))
Planned, but not Implemented yet: Planned, but not implemented:
* Buffering/showing some output, for errors etc. We have to think about some * Buffering/showing some output, for errors etc. We have to think about some
magic way to determine, wether output is helpful or the launcher should be magic way to determine, whether output is helpful or the launcher should be
hidden immediately hidden immediately
* dmenu-like completion, typing part of a command still completing (maybe zsh * dmenu-like completion, typing part of a command still completing (maybe zsh
has something to do that?) has something to do that? possibly [fzf](https://github.com/junegunn/fzf))
* .desktop-file integration * [.desktop-file integration](https://github.com/pseyfert/shellex-desktop)
* Your ticket here * Your ticket here
...@@ -79,7 +79,7 @@ $ make ...@@ -79,7 +79,7 @@ $ make
$ make install $ make install
``` ```
for installing in `$(HOME).local` for installing in `$(HOME)/.local`
```sh ```sh
$ git clone git://github.com/Merovius/shellex.git $ git clone git://github.com/Merovius/shellex.git
...@@ -139,6 +139,19 @@ following is a not comprehensive list of highly appreciated ways to contribute: ...@@ -139,6 +139,19 @@ following is a not comprehensive list of highly appreciated ways to contribute:
to maintain the translation. to maintain the translation.
Customizations
==============
Users are invited to publish their customizations. Either as a contribution
(see above) if these are changes that are a sensible default for all users, or
in their own small packages which contain only the customizations. Especially,
when the customization will be useful for many, but not all users.
Existing customization projects are:
* [pseyfert's customizations](https://github.com/pseyfert/shellex-customizations)
* Your project here
Configuration Configuration
============= =============
...@@ -155,22 +168,27 @@ Resource | Values | Default | Description ...@@ -155,22 +168,27 @@ Resource | Values | Default | Description
shellex.pos | pointer|focus | focus | If pointer, shellex shows the window on the window, the mousepointer is on, else it uses the output, where most of the currently focused window is (falling back to the pointer-method, if the root-window is focused). shellex.pos | pointer|focus | focus | If pointer, shellex shows the window on the window, the mousepointer is on, else it uses the output, where most of the currently focused window is (falling back to the pointer-method, if the root-window is focused).
shellex.edge | bottom|top | top | On what screenedge to show shellex shellex.edge | bottom|top | top | On what screenedge to show shellex
The other source of configuration are small shell-script-snippets. When On start, `shellex` assembles a list of snippet basenames by looking at all of
starting, `shellex` will look into `$HOME/.shellex` and into `/etc/shellex`. It the paths listed below. For each snippet basename, `shellex` loads the first
will then source all the snippets in either location. If there is an file it finds when looking through the paths in order:
identically named file in both directories, the one in your home will be
preferred. 1. `$XDG_CONFIG_HOME/.shellex`. Typically unset, defaulting to `$HOME/.config/shellex`.
2. `$HOME/.shellex`
This makes for a pretty flexible configuration process: Usually there will be a 3. `/etc/shellex` (shellex defaults, symlinks to `/usr/shellex/conf/`)
lot of snippets in `/usr/lib/shellex/conf`, which should be self-contained and
without a lot of side-effects. In `/etc/shellex` there then are some symlinks To customize shellex, you can do the following things in
to those snippets, making up the default-configuration on this system, together `$XDG_CONFIG_HOME/.shellex` or `$HOME/.shellex/`:
with administrator-provided additional defaults. Whenever you don't want a
snippet form `/etc/shellex` to be used, just create a symlink of the same name 1. Overwrite a default by creating a new snippet of the same name
to `/dev/null` in `$HOME/.shellex`. If you want to create your own snippets, 2. Not include a default by creating a symlink to `/dev/null` of the same same
just put them in `$HOME/.shellex` under a name not used yet and it will be 3. Include an example-snippet not used by default, by creating a symlink to `/usr/shellex/snippet`
automatically sourced. 4. Write you own snippets with a currently unused name
To avoid naming-conflicts in the future, you should add a common suffix to all
your own snippets. Snippets are run in ascending order. By choosing a number
which sorts between/after the existing snippet(s) you can ensure it runs at the
desired time. E.g. if your snippet beeps on errors, name it 15-errorbeep so that
it sorts before 20-nobeep.
Command-line Command-line
============ ============
......
...@@ -2,7 +2,7 @@ INSTALL_TARGETS += install-conf install-rc ...@@ -2,7 +2,7 @@ INSTALL_TARGETS += install-conf install-rc
CLEAN_TARGETS += clean-shellexrc CLEAN_TARGETS += clean-shellexrc
ALL_TARGETS += conf/shellexrc ALL_TARGETS += conf/shellexrc
default_confs := 10-autoexec 20-nobeep 40-escape 40-home_end 40-setprompt 40-sigint 90-hist 99-clear default_confs := 10-autoexec 20-completion 20-nobeep 40-escape 40-home_end 40-setprompt 40-sigint 40-recent 90-hist 99-clear
install-conf: install-conf:
echo "[INSTALL] $@" echo "[INSTALL] $@"
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
# Make zsh automatically execute a command, when enter is hit # Make zsh automatically execute a command, when enter is hit
# © 2013 Axel Wagner and contributors (see also: LICENSE) # © 2013 Axel Wagner and contributors (see also: LICENSE)
zmodload zsh/regex
function shellex_preexec () { function shellex_preexec () {
# In $1 the command-line is given # In $1 the command-line is given
# In $3 the command-line with expanded aliases and function-bodies is given # In $3 the command-line with expanded aliases and function-bodies is given
...@@ -21,7 +20,8 @@ preexec_functions=(shellex_preexec) ...@@ -21,7 +20,8 @@ preexec_functions=(shellex_preexec)
# https://www.reddit.com/r/zsh/comments/s6t6d/is_there_an_alias_for_an_empty_line/ # https://www.reddit.com/r/zsh/comments/s6t6d/is_there_an_alias_for_an_empty_line/
function empty-buffer-to-exit() { function empty-buffer-to-exit() {
if [[ $#BUFFER == 0 ]]; then if [[ $#BUFFER == 0 ]]; then
BUFFER="exit" fc -P
exit
fi fi
} }
# set special widget, see man zshzle # set special widget, see man zshzle
......
# enable tab completion system
# © 2016 Paul Seyfert and contributors (see also: LICENSE)
autoload -U compinit
compinit -C
# 'ctrl-x r' will complete the 12 last modified (mtime) files/directories
# © 2018 Michael Stapelberg and contributors (see also: LICENSE)
# only add this completion if compinit has been called
if [[ -v _comps ]]
then
# 'ctrl-x r' will complete the 12 last modified (mtime) files/directories
zle -C newest-files complete-word _generic
bindkey '^Xr' newest-files
zstyle ':completion:newest-files:*' completer _files
zstyle ':completion:newest-files:*' file-patterns '*~.*(omN[1,12])'
zstyle ':completion:newest-files:*' menu select yes
zstyle ':completion:newest-files:*' sort false
zstyle ':completion:newest-files:*' matcher-list 'b:=*' # important
fi
...@@ -5,17 +5,31 @@ ...@@ -5,17 +5,31 @@
# get array of all relevant files # get array of all relevant files
# http://stackoverflow.com/a/10981499 # http://stackoverflow.com/a/10981499
# http://unix.stackexchange.com/a/26825 # http://unix.stackexchange.com/a/26825
thefiles=(@SYSCONFDIR@/shellex/* $HOME/.shellex/*(.N)) # parentheses after * steer zsh's globbing
# . means "only regular files"
# -. means "regular files and symlinks pointing to regular files"
# N means "empty list in case of no matches"
thefiles=(
@SYSCONFDIR@/shellex/*
${XDG_CONFIG_HOME:-$HOME/.config}/shellex/*(-.N)
$HOME/.shellex/*(-.N)
)
# get the basenames of all files and make unique list # get the basenames of all files and make unique list
# http://stackoverflow.com/a/9516801 # http://stackoverflow.com/a/9516801
uniquified=( $( for f in "${thefiles[@]}" ; do basename $f ; done | sort -u ) ) uniquified=( $( for f in "${thefiles[@]}" ; do basename $f ; done | sort -u ) )
# source each file from $HOME/.shellex if it exists there, otherwise from /etc # source each file from the first of:
# 1. $XDG_CONFIG_HOME/.shellex (typically $HOME/.config/shellex)
# 2. $HOME/.shellex
# 3. @SYSCONFDIR@/shellex
for f in $uniquified for f in $uniquified
do do
# -r checks if file exists and is readable # -r checks if file exists and is readable
if [[ -r $HOME/.shellex/$f ]] if [[ -r ${XDG_CONFIG_HOME:-$HOME/.config}/shellex/$f ]]
then
source $HOME/.config/shellex/$f
elif [[ -r $HOME/.shellex/$f ]]
then then
source $HOME/.shellex/$f source $HOME/.shellex/$f
else else
......
...@@ -7,7 +7,7 @@ template::[header-declarations] ...@@ -7,7 +7,7 @@ template::[header-declarations]
<refentrytitle>{mantitle}</refentrytitle> <refentrytitle>{mantitle}</refentrytitle>
<manvolnum>{manvolnum}</manvolnum> <manvolnum>{manvolnum}</manvolnum>
<refmiscinfo class="source">shellex</refmiscinfo> <refmiscinfo class="source">shellex</refmiscinfo>
<refmiscinfo class="version">0.2</refmiscinfo> <refmiscinfo class="version">0.3</refmiscinfo>
<refmiscinfo class="manual">shellex Manual</refmiscinfo> <refmiscinfo class="manual">shellex Manual</refmiscinfo>
</refmeta> </refmeta>
<refnamediv> <refnamediv>
......
shellex(1) shellex(1)
========== ==========
Paul Seyfert <pseyfert@mathphys.fsk.uni-heidelberg.de> Paul Seyfert <pseyfert.mathphys@gmail.com>
v0.2, December 2016 v0.3, July 2018
== NAME == NAME
...@@ -51,12 +51,16 @@ terminal window. ...@@ -51,12 +51,16 @@ terminal window.
*shellex* configuration snippets can be found in *@PREFIX@@LIBDIR@/shellex/*. *shellex* configuration snippets can be found in *@PREFIX@@LIBDIR@/shellex/*.
On start, *shellex* looks into @SYSCONFDIR@/shellex for default-snippets to On start, *shellex* assembles a list of snippet basenames by looking at all of
source (usually this will be symlinks to *@PREFIX@@LIBDIR@/shellex/*) as well the paths listed below. For each snippet basename, *shellex* loads the first
as into *$HOME/.shellex/* for any user-configuration. If a file of the same file it finds when looking through the paths in order:
name exists in both locations, it will only use the one in *$HOME/.shellex/*.
To customize shellex, you can do the following things in *$HOME/.shellex/*: 1. $XDG_CONFIG_HOME/.shellex. Typically unset, defaulting to $HOME/.config/shellex.
2. $HOME/.shellex
3. @SYSCONFDIR@/shellex (shellex defaults, symlinks to *@PREFIX@@LIBDIR@/shellex/conf/*)
To customize shellex, you can do the following things in
*$XDG_CONFIG_HOME/.shellex* or *$HOME/.shellex/*:
1. Overwrite a default by creating a new snippet of the same name 1. Overwrite a default by creating a new snippet of the same name
2. Not include a default by creating a symlink to */dev/null* of the same same 2. Not include a default by creating a symlink to */dev/null* of the same same
...@@ -64,7 +68,10 @@ To customize shellex, you can do the following things in *$HOME/.shellex/*: ...@@ -64,7 +68,10 @@ To customize shellex, you can do the following things in *$HOME/.shellex/*:
4. Write you own snippets with a currently unused name 4. Write you own snippets with a currently unused name
To avoid naming-conflicts in the future, you should add a common suffix to all To avoid naming-conflicts in the future, you should add a common suffix to all
your own snippets. your own snippets. Snippets are run in ascending order. By choosing a number
which sorts between/after the existing snippet(s) you can ensure it runs at the
desired time. E.g. if your snippet beeps on errors, name it 15-errorbeep so that
it sorts before 20-nobeep.
== AUTHORS == AUTHORS
......
format: format_c format_perl format_vim
format_perl: urxvt/shellex.in
echo "[FORMAT] $^"
cd $(shell dirname $^) && perltidy $(shell basename $^)
format_c: preload/main.c
echo "[FORMAT] $^"
clang-format -i $^
format_vim:
echo "[FORMAT]"
for shfile in $(wildcard conf/*) shellex.in; do echo "[FORMAT] $${shfile}"; ./indent.sh $${shfile}; done
.PHONY: format format_c format_perl format_vim
#!/bin/sh
# vim:ft=zsh
# Helper script for CI to auto indent files
# © 2017 Paul Seyfert and contributors (see also: LICENSE)
if [ -f "$1" ]; then
vim -f +"set softtabstop=2" +"set tabstop=2" +"set shiftwidth=2" +"set expandtab" +"gg=G" +":x" $1
else
echo "USAGE: $0 <filename>"
echo "to autoindent file with vim"
fi
exit $?
---
Language: Cpp
# BasedOnStyle: WebKit
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 8
UseTab: Never
...
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include <dlfcn.h> #include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <unistd.h> #include <unistd.h>
/* We can not take this from <sys/ioctl.h>, because it would define the /* We can not take this from <sys/ioctl.h>, because it would define the
...@@ -19,7 +19,7 @@ struct winsize { ...@@ -19,7 +19,7 @@ struct winsize {
unsigned short ws_ypixel; unsigned short ws_ypixel;
}; };
int ioctl (int d, int request, char *argp) { int ioctl(int d, int request, char *argp) {
static int (*orig_ioctl)(int, int, char *); static int (*orig_ioctl)(int, int, char *);
if (orig_ioctl == NULL) { if (orig_ioctl == NULL) {
orig_ioctl = dlsym(RTLD_NEXT, "ioctl"); orig_ioctl = dlsym(RTLD_NEXT, "ioctl");
...@@ -36,19 +36,19 @@ int ioctl (int d, int request, char *argp) { ...@@ -36,19 +36,19 @@ int ioctl (int d, int request, char *argp) {
* the right size! Leave max_rows negative to indicat that it still needs to * the right size! Leave max_rows negative to indicat that it still needs to
* be read from the SHELLEX_SIZE_FILE */ * be read from the SHELLEX_SIZE_FILE */
if (max_rows < 0 ) { if (max_rows < 0) {
char *fname = getenv("SHELLEX_SIZE_FILE"); char *fname = getenv("SHELLEX_SIZE_FILE");
if (fname != NULL && fname[0] != '\0') { if (fname != NULL && fname[0] != '\0') {
FILE *stream = fopen(fname,"r"); FILE *stream = fopen(fname, "r");
char str[5] = "-500"; char str[5] = "-500";
if (stream != NULL) { if (stream != NULL) {
char *ret = fgets(str,5,stream); char *ret = fgets(str, 5, stream);
fclose(stream); fclose(stream);
if (ret != NULL) { if (ret != NULL) {
/* this may be -500 */ /* this may be -500 */
max_rows = atoi(str); max_rows = atoi(str);
if (max_rows > 0 ) { if (max_rows > 0) {
unlink(fname); unlink(fname);
} }
} }
...@@ -56,7 +56,6 @@ int ioctl (int d, int request, char *argp) { ...@@ -56,7 +56,6 @@ int ioctl (int d, int request, char *argp) {
} }
} }
int retval = orig_ioctl(d, request, (char *)argp); int retval = orig_ioctl(d, request, (char *)argp);
struct winsize *ws = (struct winsize *)argp; struct winsize *ws = (struct winsize *)argp;
......
-pt=2
-ce
-l=91
-b
...@@ -4,19 +4,24 @@ ...@@ -4,19 +4,24 @@
# This is the urxvt extension part of shellex. # This is the urxvt extension part of shellex.
# © 2013 Axel Wagner and contributors (see also: LICENSE) # © 2013 Axel Wagner and contributors (see also: LICENSE)
use X11::Protocol; use X11::Protocol;
use File::Temp qw|tempfile|;
use File::Basename qw|basename|;
use POSIX qw|ceil|; use POSIX qw|ceil|;
use strict; use strict;
# The existing Randr-modules on CPAN seem to work only barely, so instead we # At the time of the original version of this function, the existing
# just parse the output of xrandr -q. This is an uglyness, that should go away # Randr-modules on CPAN seem to work only barely, so instead we just parse the
# some time in the feature. # output of xrandr --listactivemonitors. This is an uglyness, that should go
# away some time in the future.
sub get_outputs { sub get_outputs {
my @outputs = (); my @outputs = ();
for my $line (qx(xrandr -q)) { for my $line (qx(xrandr --listactivemonitors)) {
next unless $line =~ /\sconnected/; next if $line =~ /Monitors: /;
my ($w, $h, $x, $y) = ($line =~ /(\d+)x(\d+)\+(\d+)\+(\d+)/);
# output looks like:
#Monitors: 2
# 0: +*LVDS-1 1366/277x768/156+0+0 LVDS-1
# 1: +HDMI-2 1920/518x1200/324+1366+0 HDMI-2
my ($w, $h, $x, $y) = ($line =~ /(\d+)\/\d+x(\d+)\/\d+\+(\d+)\+(\d+)/);
print "found monitor with dimensions and position w=$w h=$h x=$x y=$y\n";
push @outputs, { w => $w, h => $h, x => $x, y => $y }; push @outputs, { w => $w, h => $h, x => $x, y => $y };
} }
return @outputs; return @outputs;
...@@ -32,9 +37,11 @@ sub geometry_from_ptr { ...@@ -32,9 +37,11 @@ sub geometry_from_ptr {
my $ptr = { $self->{X}->QueryPointer($self->DefaultRootWindow) }; my $ptr = { $self->{X}->QueryPointer($self->DefaultRootWindow) };
for my $output (@outputs) { for my $output (@outputs) {
if ($output->{x} <= $ptr->{root_x} && $ptr->{root_x} < $output->{x} + $output->{w}) { if ($output->{x} <= $ptr->{root_x} && $ptr->{root_x} < $output->{x} + $output->{w})
{
$self->{x} = $output->{x}; $self->{x} = $output->{x};
if ($self->{bottom}) { if ($self->{bottom}) {
# The real y-coordinate will change during execution, when the window grows # The real y-coordinate will change during execution, when the window grows
$self->{y} = $output->{y} + $output->{h}; $self->{y} = $output->{y} + $output->{h};
} else { } else {
...@@ -54,6 +61,7 @@ sub max { ...@@ -54,6 +61,7 @@ sub max {
} }
return $max; return $max;
} }
sub min { sub min {
my $min = shift; my $min = shift;
while (my $n = shift) { while (my $n = shift) {
...@@ -74,6 +82,7 @@ sub geometry_from_focus { ...@@ -74,6 +82,7 @@ sub geometry_from_focus {
# If the root-window is focused, we fall back to using the pointer-position # If the root-window is focused, we fall back to using the pointer-position
if ($focus == $self->DefaultRootWindow) { if ($focus == $self->DefaultRootWindow) {
print "Fall back to getting shellex-position from pointer\n";
return $self->geometry_from_ptr(); return $self->geometry_from_ptr();
} }
...@@ -85,7 +94,8 @@ sub geometry_from_focus { ...@@ -85,7 +94,8 @@ sub geometry_from_focus {
# The (x,y) coordinates we get are relative to the parent not the # The (x,y) coordinates we get are relative to the parent not the
# root-window. So we just translate the coordinates of the upper-left # root-window. So we just translate the coordinates of the upper-left
# corner into the coordinate-system of the root-window # corner into the coordinate-system of the root-window
my (undef, undef, $fx, $fy) = $self->{X}->TranslateCoordinates($focus, $self->DefaultRootWindow, 0, 0); my (undef, undef, $fx, $fy) =
$self->{X}->TranslateCoordinates($focus, $self->DefaultRootWindow, 0, 0);
# Returns the area (in pixel²) of the intersection of two rectangles. # Returns the area (in pixel²) of the intersection of two rectangles.
# To understand how it works, best draw a picture. # To understand how it works, best draw a picture.
...@@ -117,6 +127,7 @@ sub geometry_from_focus { ...@@ -117,6 +127,7 @@ sub geometry_from_focus {
$max_area = $area; $max_area = $area;
$self->{x} = $output->{x}; $self->{x} = $output->{x};
if ($self->{bottom}) { if ($self->{bottom}) {
# The real y-coordinate will change during execution, when the window grows # The real y-coordinate will change during execution, when the window grows
$self->{y} = $output->{y} + $output->{h}; $self->{y} = $output->{y} + $output->{h};
} else { } else {
...@@ -152,14 +163,14 @@ sub on_start { ...@@ -152,14 +163,14 @@ sub on_start {
# TODO: Remove compatibility code in future version # TODO: Remove compatibility code in future version
if (defined $self->x_resource("%.edge") || defined $self->x_resource("%.pos")) { if (defined $self->x_resource("%.edge") || defined $self->x_resource("%.pos")) {
print "WARNING: URxvt.shellex.* resources are deprecated and will be removed in the future. Use shellex.*\n" print
"WARNING: URxvt.shellex.* resources are deprecated and will be removed in the future. Use shellex.*\n";
} }
if ($self->x_resource("edge") eq 'bottom' || $self->x_resource("%.edge") eq 'bottom') { if ($self->x_resource("edge") eq 'bottom' || $self->x_resource("%.edge") eq 'bottom') {
print "position should be at the bottom\n"; print "position should be at the bottom\n";
$self->{bottom} = 1; $self->{bottom} = 1;
$self->{y} = $self->{h}; $self->{y} = $self->{h};
} else { } else {
print "position should be at the top\n"; print "position should be at the top\n";
} }
...@@ -172,11 +183,14 @@ sub on_start { ...@@ -172,11 +183,14 @@ sub on_start {
$self->geometry_from_focus(); $self->geometry_from_focus();
} }
# This environment variable is used by the LD_PRELOAD ioctl-override to # This environment variable is used by the LD_PRELOAD ioctl-override to
# determine the values to send to the shell # determine the values to send to the shell
# TODO revisit communication protocol (from file to pipe?) # TODO revisit communication protocol (from file to pipe?)
# TODO check if user defined their own SHELLEX_MAX_ROWS, which should be used like # TODO check if user defined their own SHELLEX_MAX_ROWS, which should be used like
#$ENV{SHELLEX_MAX_ROWS} = $sane_max_rows < $ENV{SHELLEX_MAX_ROWS} ? $sane_max_rows : $ENV{SHELLEX_MAX_ROWS} ; #$ENV{SHELLEX_MAX_ROWS} = $sane_max_rows < $ENV{SHELLEX_MAX_ROWS} ? $sane_max_rows : $ENV{SHELLEX_MAX_ROWS} ;
#
# shellex should leave part of the screen uncovered (10 lines), this assumes
# that a screen will always be larger than 10 lines.
my $sane_max_rows = int($self->{h} / $self->fheight) - 10; my $sane_max_rows = int($self->{h} / $self->fheight) - 10;
$ENV{SHELLEX_MAX_ROWS} = $sane_max_rows; $ENV{SHELLEX_MAX_ROWS} = $sane_max_rows;
...@@ -184,7 +198,7 @@ sub on_start { ...@@ -184,7 +198,7 @@ sub on_start {
open(my $fh, '>', $filename); open(my $fh, '>', $filename);
print $fh "$ENV{SHELLEX_MAX_ROWS}\n"; print $fh "$ENV{SHELLEX_MAX_ROWS}\n";
close $fh; close $fh;
print "writing max rows file done\n"; print "wrote $sane_max_rows as max rows to $filename done\n";
$self->{border} = $self->x_resource('internalBorder'); $self->{border} = $self->x_resource('internalBorder');
...@@ -196,7 +210,8 @@ sub on_start { ...@@ -196,7 +210,8 @@ sub on_start {
$self->{row_height} = $self->fheight + $self->x_resource('lineSpace'); $self->{row_height} = $self->fheight + $self->x_resource('lineSpace');
my $height = $self->{row_height} + 2 * $self->{border}; my $height = $self->{row_height} + 2 * $self->{border};
my $y = $self->{y}; my $y = $self->{y};
# Our initial position is different, if we have to be at the bottom # Our initial position is different, if we have to be at the bottom
$y -= $height if $self->{bottom}; $y -= $height if $self->{bottom};
...@@ -219,20 +234,20 @@ sub on_line_update { ...@@ -219,20 +234,20 @@ sub on_line_update {
# TODO: Does this work as intended, if there is an empty line in the # TODO: Does this work as intended, if there is an empty line in the
# middle? # middle?
my $nrow = 0; my $nrow = 0;
for my $i ($self->top_row .. $self->nrow-1) { for my $i ($self->top_row .. $self->nrow - 1) {
if ($self->ROW_l($i) > 0) { if ($self->ROW_l($i) > 0) {
$nrow++; $nrow++;
} }
} }
$nrow = $nrow > 0 ? $nrow : 1;
$nrow = $nrow > $ENV{SHELLEX_MAX_ROWS} ? $ENV{SHELLEX_MAX_ROWS} : $nrow; $nrow = $nrow > $ENV{SHELLEX_MAX_ROWS} ? $ENV{SHELLEX_MAX_ROWS} : $nrow;
$nrow = $nrow > 0 ? $nrow : 1;
print "resizing to $nrow\n"; print "resizing to $nrow\n";
# If the window is supposed to be at the bottom, we have to move the # If the window is supposed to be at the bottom, we have to move the
# window up a little bit # window up a little bit
my $y = $self->{y}; my $y = $self->{y};
if ($self->{bottom}) { if ($self->{bottom}) {
$y -= 2+$nrow*$self->fheight; $y -= 2 + $nrow * $self->fheight;
} }
$self->cmd_parse("\e[8;$nrow;t\e[3;$self->{x};${y}t"); $self->cmd_parse("\e[8;$nrow;t\e[3;$self->{x};${y}t");
();