Commit a725b718 authored by Paul Seyfert's avatar Paul Seyfert

Imported Upstream version 0.2

parent 62d5d554
preload/shellex_preload.so
shellex
urxvt/shellex
Changelog
=========
0.2 - 2016-12-27
----------------
• Added optional sudo configuration
• Bugfix: flashing window with large completion lists
• Moved config handling from perl to shell
• Disable beeping
• Improved history file handling
• Avoid using temporary files for configuration parsing
• Avoid using temporary files for command execution
0.1 - 2013-09-03
----------------
• History support (default)
• Pass command-line to urxvt (support colors)
• Bugfix: Correct pointer-based positioning
• Bugfix: Correct focus-based positioning
• Bugfix: Correctly predict terminal size, when adding strings
0.0 - 2013-08-31
----------------
• Initial release
Copyright © 2013 Axel Wagner
Copyright © 2016 Axel Wagner and contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
......@@ -22,3 +22,6 @@ DISCLAIMED. IN NO EVENT SHALL Axel Wagner BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
......@@ -10,6 +10,9 @@ typical launcher-behaviour.
This gives you a simple launcher with tab-completion and other shell-features,
configurable in shell.
See this video for a short demonstration and comparison to another app starter:
![demo](http://virgilio.mib.infn.it/~seyfert/images/shellexdemo.gif)
I tried to do this a few years back, then using C and implementing the
terminal-operations myself. This turned out to be a very bad idea, it made the
design overly complex and the state I left it in had regular segfaults and was far
......@@ -18,7 +21,7 @@ start again, this time using `urxvt` to do the terminal-part, which turned out t
be really easy.
So, this is the early prototype. It is usable and should already work and be
usefull, but much is not working yet. I hope this time I will continue the work
useful, but much is not working yet. I hope this time I will continue the work
for longer ;)
......@@ -47,10 +50,10 @@ Working:
Planned, but not Implemented yet:
* Buffering/showing some output, for errors etc. We have to think about some
magic way to determine, wether output is helpfull or the launcher should be
magic way to determine, wether output is helpful or the launcher should be
hidden immediately
* dmenu-like completion, typing part of a command still completing (maybe zsh
has sometething to do that?)
has something to do that?)
* .desktop-file integration
* Your ticket here
......@@ -58,27 +61,105 @@ Planned, but not Implemented yet:
Installation
============
Just do
There are packages in
* [debian](http://packages.debian.org/search?keywords=shellex&searchon=names&suite=all&section=all&sourceid=mozilla-search)
* Arch Linux: [Arch User Repository](https://aur.archlinux.org/packages/?SeB=n&K=shellex) ([latest Release](https://aur.archlinux.org/packages/shellex/) and [git-Repository](https://aur.archlinux.org/packages/shellex-git/))
* Gentoo: there is an [Overlay](https://github.com/proxypoke/gentoo-overlay) which contains shellex
If you are on one of these distributions, we encourage you to install `shellex`
via your package manager.
Else, or if you want to help developing, just do
```sh
$ git clone git://github.com/Merovius/shellex.git
$ cd shellex
$ make
$ make install
```
for installing in `$(HOME).local`
```sh
$ git clone git://github.com/Merovius/shellex.git
$ cd shellex
$ PREFIX=$HOME/.local make
$ PREFIX=$HOME/.local make install
```
Usage
=====
After installing `shellex` you probably want to bind it to a shortcut - most
likely Alt+F2. How to do this depends on your desktop environment and/or window
manager.
## xbindkeys
If you're running [xbindkeys](http://www.nongnu.org/xbindkeys/xbindkeys.html),
the entry for your `~/.xbindkeysrc` file might look like:
```
"shellex"
alt + c:68
```
## i3
[i3](i3wm.org) shortcuts can be modified as described in the
[official documentation](https://i3wm.org/docs/userguide.html).
```
bindsym Mod1+F2 exec shellex
```
Contributing
============
`shellex` is a very young project, it would highly profit from your help. The
following is a not comprehensive list of highly appreciated ways to contribute:
1. Test it and make [tickets](https://github.com/Merovius/shellex/issues) for
*any* problems you stumble upon or ideas you have to make it better.
2. Have a look at a [list of issues](https://github.com/Merovius/shellex/issues)
and find one to fix. But please announce your intention to fix it, so that
we can be sure that it will be merged and there is no duplication of effort.
3. Have a look at the [list of packaged dirstributions](https://github.com/Merovius/shellex#installation).
If your favourite distribution is not on it, please package it. Please
announce your intent to do so (in a ticket) and treat it as at least a
mid-term commitment to maintain the package.
4. Customize `shellex` in self-contained, side-effect free config-snippets and
add them - if you consider them useful to more then just yourself - in a
pull-request to the conf-dir.
5. Contribute comments and documentation. Consider translating the manpage.
Again, please announce your intention and again, if you translate to a
language, that none of the core-developers speak (currently everything but
English and German) please consider it to be at least a mid-term commitment
to maintain the translation.
Configuration
=============
Configuration of `shellex` has two parts: The first one are X-resources (which we will try to eliminate in the future):
Configuration of `shellex` has two parts: The first one are X-resources.
Additionally to the urxvt-class, instances run by shellex will also look for
the shellex-class. This makes it possible to customize the appearance of
shellex without interfering with your usual terminals.
There are also two additional resources defined by shellex:
Resource | Values | Default | Description
----------------- | -------------- | ------- | ---
URxvt.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.
URxvt.shellex.edge | bottom|top | top | On what screenedge to show shellex
The other are small shell-script-snippets. When starting, `shellex` will look
into `$HOME/.shellex` and into `/etc/shellex`. It will then source all the
snippets in either location. If there is an identically named file in both
directories, the one in your home will be preferred.
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.edge | bottom|top | top | On what screenedge to show shellex
The other source of configuration are small shell-script-snippets. When
starting, `shellex` will look into `$HOME/.shellex` and into `/etc/shellex`. It
will then source all the snippets in either location. If there is an
identically named file in both directories, the one in your home will be
preferred.
This makes for a pretty flexible configuration process: Usually there will be a
lot of snippets in `/usr/lib/shellex/conf`, which should be self-contained and
......@@ -89,3 +170,17 @@ snippet form `/etc/shellex` to be used, just create a symlink of the same name
to `/dev/null` in `$HOME/.shellex`. If you want to create your own snippets,
just put them in `$HOME/.shellex` under a name not used yet and it will be
automatically sourced.
Command-line
============
All command-line parameters given to `shellex` are passed directly to `urxvt`,
so if you want to change colors or font, you can do it through the appropriate
`urxvt`-parameters (or by using resources, for persistent configuration). For
example, to get a dark grey background with a slightly yellow font you might
start shellex with
```sh
$ shellex -bg grey15 -fg linen
```
INSTALL_TARGETS += install-conf
INSTALL_TARGETS += install-conf install-rc
CLEAN_TARGETS += clean-shellexrc
ALL_TARGETS += conf/shellexrc
default_confs := 10-autoexec 40-escape 40-setprompt 40-sigint 99-clear
default_confs := 10-autoexec 20-nobeep 40-escape 40-home_end 40-setprompt 40-sigint 90-hist 99-clear
install-conf:
echo "[INSTALL] $@"
$(INSTALL) -d -m 0755 $(DESTDIR)$(PREFIX)$(LIBDIR)/shellex/conf
for file in $(wildcard conf/*); \
for file in $(wildcard conf/[0-9][0-9]-*); \
do \
$(INSTALL) -m 0644 $${file} $(DESTDIR)$(PREFIX)$(LIBDIR)/shellex/conf/; \
done
$(INSTALL) -d -m 0755 $(DESTDIR)$(SYSCONFDIR)/shellex
for link in $(default_confs); \
do \
ln -s $(PREFIX)$(LIBDIR)/shellex/conf/$${link} $(DESTDIR)$(SYSCONFDIR)/shellex; \
[ -e $(DESTDIR)$(SYSCONFDIR)/shellex/$${link} ] || ln -s $(PREFIX)$(LIBDIR)/shellex/conf/$${link} $(DESTDIR)$(SYSCONFDIR)/shellex; \
done
conf/shellexrc: conf/shellexrc.in
echo "[SED] $@"
$(SED) $(sed_replace_vars) $< > $@
install-rc: conf/shellexrc
echo "[INSTALL] $@"
$(INSTALL) -m 0644 conf/shellexrc $(DESTDIR)$(PREFIX)$(LIBDIR)/shellex/shellexrc
[ -e $(DESTDIR)$(SYSCONFDIR)/shellexrc ] || ln -s $(PREFIX)$(LIBDIR)/shellex/shellexrc $(DESTDIR)$(SYSCONFDIR)/shellexrc
clean-shellexrc:
echo "[CLEAN] conf/shellexrc"
rm -f conf/shellexrc
# vim:ft=zsh
# Make zsh automatically execute a command, when enter is hit
zmodload zsh/regex
function accept-line () {
if [ "$BUFFER" -regex-match '^\s*$' ]
then
exit
fi
# © 2013 Axel Wagner and contributors (see also: LICENSE)
# We need to write the buffer to a temporary file to accomodate multiple
# commands (see https://github.com/Merovius/shellex/issues/11). We let the
# shell immediately remove the tempfile, so it's rather short-lived.
file=`tempfile`
echo "rm $file\n$BUFFER" > $file
zmodload zsh/regex
function shellex_preexec () {
# In $1 the command-line is given
# In $3 the command-line with expanded aliases and function-bodies is given
# Execute the tempfile, then exit
BUFFER="zsh $file > /dev/null 2>&1 & disown; exit"
zle .accept-line
zsh -c $3 > /dev/null 2>&1 & disown
exit
}
# We use preexec_functions, so that the user can decide to overwrite our choice
# or ammend it by own functions
preexec_functions=(shellex_preexec)
# preexec doesn't get executed on empty lines, so employ zle to exit on empty lines
# https://www.reddit.com/r/zsh/comments/s6t6d/is_there_an_alias_for_an_empty_line/
function empty-buffer-to-exit() {
if [[ $#BUFFER == 0 ]]; then
BUFFER="exit"
fi
}
zle -N accept-line
# set special widget, see man zshzle
zle -N zle-line-finish empty-buffer-to-exit
# disable beeping of the shellex shell. e.g. when tab-completing
# © 2016 Paul Seyfert and contributors (see also: LICENSE)
setopt NO_BEEP
# vim:ft=zsh
# Make zsh exit on escape
# © 2013 Axel Wagner and contributors (see also: LICENSE)
function _shellex_exit {
fc -P
exit
}
zle -N _shellex_exit
......
# vim:ft=zsh
# Make home and end buttons usable
# © 2014 Axel Wagner and contributors (see also: LICENSE)
bindkey '^[[7~' beginning-of-line
bindkey '^[[8~' end-of-line
bindkey '^[[3~' delete-char
# vim:ft=zsh
# Set the prompt
# © 2013 Axel Wagner and contributors (see also: LICENSE)
PROMPT="shellex> "
# vim:ft=zsh
# Make zsh exit on ^C
# © 2013 Axel Wagner and contributors (see also: LICENSE)
trap exit SIGINT
# vim:ft=zsh
# use gksudo (or kdesudo if gksudo not exists) instead of sudo
# © 2013 Johannes Visintini and contributors (see also: LICENSE)
which kdesudo > /dev/null 2>&1 && alias sudo='kdesudo'
which gksudo > /dev/null 2>&1 && alias sudo='gksudo'
# vim:ft=zsh
# Avoid configuration sourcing in history
# © 2013 Paul Seyfert and contributors (see also: LICENSE)
# ensure history gets actually written (shell gets closed before history gets
# written otherwise)
setopt inc_append_history
HISTSIZE=100
SAVEHIST=100
# Push current history to stack (make e.g. sourcing of configuration
# inaccessible to user). The stack won't be poped. Set HISTFILE to ~/.shellex
# and read history from there.
fc -p ~/.shellex_history
# vim:ft=zsh
# Clear the terminal-window at start
# © 2013 Axel Wagner and contributors (see also: LICENSE)
clear
# vim:ft=zsh
# Source all conf files
# © 2016 Paul Seyfert and contributors (see also: LICENSE)
# get array of all relevant files
# http://stackoverflow.com/a/10981499
# http://unix.stackexchange.com/a/26825
thefiles=(@SYSCONFDIR@/shellex/* $HOME/.shellex/*(.N))
# get the basenames of all files and make unique list
# http://stackoverflow.com/a/9516801
uniquified=( $( for f in "${thefiles[@]}" ; do basename $f ; done | sort -u ) )
# source each file from $HOME/.shellex if it exists there, otherwise from /etc
for f in $uniquified
do
# -r checks if file exists and is readable
if [[ -r $HOME/.shellex/$f ]]
then
source $HOME/.shellex/$f
else
source @SYSCONFDIR@/shellex/$f
fi
done
......@@ -12,15 +12,15 @@ shellex, because when is starting it's output, there is not enough space, for
the tabcompletion, so even if we immediately resize the terminalwindow, it will
be too late and the shell-output is screwed up.
We rectify this, by injecting a custom ioctl-function into urxvt via
LD_PRELOAD, which rewrites all TIOCSWINSZ-requests to have a constant size,
thus faking to the shell that there is more space available, then there
actually is. The actual number of rows is calculated on start of the urxvt and
put into an environment-variable.
We rectify this, by injecting a custom ioctl-function into zsh via LD_PRELOAD,
which rewrites all TIOCGWINSZ-requests to have a constant size. This fakes to
the shell that there is more space available, then there actually is. The
actual number of rows is calculated on start of the urxvt and put into a
temporary file. The size is chosen a bit smaller than the screen, such that if
zsh needs even more space for the tabcompletion than fits on the screen, the
zsh handeling to deal with less space gets active. The filename is generated
with mktemp before either zsh or urxvt start. The file gets unlinked by
preload/main.c once a successful read happened.
With the current state, the window of shellex is able to grow automatically
exactly one time. This is, because zsh is spamming the output with '\n', if we
grow it always and we have yet to figure out why and how to stop that.
Shrinking (i.e. when the tab-completion vanishes again) is not implemented yet.
Shrinking after tab completions mostly works fine: Depending on the
tabcompletion settings, shrinking breaks once one hit the maximum size limit.
......@@ -7,7 +7,7 @@ template::[header-declarations]
<refentrytitle>{mantitle}</refentrytitle>
<manvolnum>{manvolnum}</manvolnum>
<refmiscinfo class="source">shellex</refmiscinfo>
<refmiscinfo class="version">0.0</refmiscinfo>
<refmiscinfo class="version">0.2</refmiscinfo>
<refmiscinfo class="manual">shellex Manual</refmiscinfo>
</refmeta>
<refnamediv>
......
shellex(1)
==========
Axel Wagner <mail@merovius.de>
v0.0, August 2013
Paul Seyfert <pseyfert@mathphys.fsk.uni-heidelberg.de>
v0.2, December 2016
== NAME
......@@ -9,7 +9,16 @@ shellex - shell-based launcher
== SYNOPSIS
*shellex*
*shellex* [...]
== OPTIONS
All command-line parameters (together with some shellex-specific) are passed on
to urxvt. This means, you can you e.g. '-bg grey20' for a lighter background.
Using it for more than just customizing the appearance (for example adding own
extensions) might stop shellex from working, so be careful.
See urxvt(1) for a full list of options.
== DESCRIPTION
......@@ -24,16 +33,20 @@ configurable in shell.
== RESOURCES
*shellex* uses two X-Resources at the monent, to manipulate its behaviour:
*shellex* uses two X-Resources at the moment, to manipulate its behaviour:
URxvt.shellex.pos::
shellex.pos::
If pointer, shellex shows the window on the window, the mousepointer is on. If
focus, it uses the output, where most of the currently focused window is.
Defaults to focus.
URxvt.shellex.edge::
shellex.edge::
On what screen edge to show the launcher (top or bottom). Defaults to top.
Additionally all resources defined by urxvt (with class 'shellex' instead of
'urxvt') can be used to customize the appearance or behaviour of the used
terminal window.
== CONFIGURATION
*shellex* configuration snippets can be found in *@PREFIX@@LIBDIR@/shellex/*.
......
/*
* shellex - shell based launcher
* This is a small LD_PRELOAD library to work around some issues
* © 2013 Axel Wagner and contributors (see also: LICENSE)
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
/* We can not take this from <sys/ioctl.h>, because it would define the
* ioctl-function itself
......@@ -17,28 +24,46 @@ int ioctl (int d, int request, char *argp) {
if (orig_ioctl == NULL) {
orig_ioctl = dlsym(RTLD_NEXT, "ioctl");
}
/* We only care for TIOCGWINSZ ioctls */
if (request != 0x5413) {
return orig_ioctl(d, request, argp);
}
static int max_rows = -1;
/* ioctl gets called once before the perl module had the time to determine
* the right size! Leave max_rows negative to indicat that it still needs to
* be read from the SHELLEX_SIZE_FILE */
if (max_rows < 0 ) {
char *str = getenv("SHELLEX_MAX_ROWS");
if (str != NULL) {
max_rows = atoi(str);
char *fname = getenv("SHELLEX_SIZE_FILE");
if (fname != NULL && fname[0] != '\0') {
FILE *stream = fopen(fname,"r");
char str[5] = "-500";
if (stream != NULL) {
char *ret = fgets(str,5,stream);
fclose(stream);
if (ret != NULL) {
/* this may be -500 */
max_rows = atoi(str);
if (max_rows > 0 ) {
unlink(fname);
}
}
}
}
}
// We only care for TIOCSWINSZ ioctls
if (request != 0x5414) {
return orig_ioctl(d, request, argp);
}
struct winsize ws = *((struct winsize *)argp);
int fheight = ws.ws_ypixel / ws.ws_row;
if (max_rows < 0) {
ws.ws_row = 80;
ws.ws_ypixel += 80 * fheight;
} else {
ws.ws_row = max_rows;
ws.ws_ypixel += max_rows * fheight;
}
int retval = orig_ioctl(d, request, (char *)argp);
struct winsize *ws = (struct winsize *)argp;
/* max_rows is still negative at first invocation */
int fheight = ws->ws_ypixel / ws->ws_row;
ws->ws_row = (max_rows > 0) ? max_rows : 25;
ws->ws_ypixel = ws->ws_row * fheight;
return orig_ioctl(d, request, (char *)&ws);
return retval;
}
......@@ -2,8 +2,8 @@ ALL_TARGETS += preload/shellex_preload.so
INSTALL_TARGETS += install-shellex_preload
CLEAN_TARGETS += clean-shellex_preload
SHELLEX_CFLAGS=-fPIC
SHELLEX_PRELOAD_LDFLAGS=-shared
SHELLEX_PRELOAD_LDFLAGS += -shared
SHELLEX_PRELOAD_CFLAGS += -fPIC
preload/shellex_preload.so: preload/main.c
echo "[CC] $@"
......
#!/bin/sh
# shellex - shell based launcher
# This is a short shellscript to set some needed variables and defaults.
# See shellex(1) for information on invocation.
# © 2013 Axel Wagner and contributors (see also: LICENSE)
export LD_PRELOAD="@PREFIX@@LIBDIR@/shellex/shellex_preload.so"
exec urxvt -perl-lib @PREFIX@@LIBDIR@/shellex/urxvt -pe shellex -override-redirect -name shellex -e env -u LD_PRELOAD zsh -f
SHELLEX_PRELOAD="@PREFIX@@LIBDIR@/shellex/shellex_preload.so"
export SHELLEX_SIZE_FILE=$(mktemp -t shellex-size-XXXXXXXX)
exec urxvt -perl-lib @PREFIX@@LIBDIR@/shellex/urxvt -pe shellex -override-redirect -name shellex $* -e env LD_PRELOAD=$SHELLEX_PRELOAD zsh -f
......@@ -2,9 +2,6 @@ ALL_TARGETS += shellex
INSTALL_TARGETS += install-shellex
CLEAN_TARGETS += clean-shellex
SHELLEX_CFLAGS=-fPIC
SHELLEX_PRELOAD_LDFLAGS=-shared
shellex: shellex.in
echo "[SED] $@"
$(SED) $(sed_replace_vars) $< > $@
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment