Julius Plenz – Blog

zsh: complete words from tmux pane

Today I wrote a rather cool Z-Shell completion function: It will present all words that are found in the current tmux pane in a zsh completion menu. That means you can actually complete words from the output of commands that you just executed. (In a way it's a little bit like the keeper function, without the overhead of remembering to call keeper in the first place.)

The code below defines two keybindings:

Here's the code:

_tmux_pane_words() {
  local expl
  local -a w
  if [[ -z "$TMUX_PANE" ]]; then
    _message "not running inside tmux!"
    return 1
  fi
  w=( ${(u)=$(tmux capture-pane \; show-buffer \; delete-buffer)} )
  _wanted values expl 'words from current tmux pane' compadd -a w
}

zle -C tmux-pane-words-prefix   complete-word _generic
zle -C tmux-pane-words-anywhere complete-word _generic
bindkey '^Xt' tmux-pane-words-prefix
bindkey '^X^X' tmux-pane-words-anywhere
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' completer _tmux_pane_words
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' ignore-line current
zstyle ':completion:tmux-pane-words-anywhere:*' matcher-list 'b:=* m:{A-Za-z}={a-zA-Z}'

How does it work? _tmux_pane_words will just capture the current pane's contents (capture-pane), print out the buffer that contains it (show-buffer) and then delete it again (delete-buffer). – The rest of the magic happens via Zsh's excellent completion mechanisms.

See it in action (after typing spm^X^X):

Update 2013-10-06: Daniel points out that since March ’13, there is a switch -p for capture-pane to print the contents to stdout; also, using the newly introduced -J switch, wrapped words will be joined. See his adaption here.

posted 2012-01-19 tagged zsh, tmux and linux

Domain-Verkaufs-Taktiken

Sven wies mich gerade auf die Domain zsh24.de hin. Da gibt's diverse Links zu Ebay-Angeboten des Zsh-Buchs, aber auch Links, um alte, abgeknipste Dresdner Fahrkarten (deren Ebay-Angebotsname "Zsh" enthält) zu kaufen.

Teilweise kann man wirklich denken, das Blog sei nicht automatisiert erstellt: Im Artikel Tolle Zsh Bilder sind automatisiert Bilder zusammengetragen – wohlgemerkt mit entsprechender Verlinkung und Hinweisen, woher sie kommen! Also nicht dumm.

Wer macht sowas? – Ein Domainregistrar, der statt Platzhalterseiten noch ein bisschen durch Prämien verdienen will. – Mal schauen... das Impressum sagt ja schon, wer verantwortlich ist. Also: tiefer graben.

zsh24.de zeigt auf die IP 46.4.212.70, die im neuen RZ 13 von Hetzner steht. Typischerweise sind ja mehrere Domains auf eine IP gemappt.

Hier eine Auswahl der Domains, die auch auf 46.4.212.70 zeigen:

Die Domains sind absichtlich nicht verlinkt, weil die Leute wohl noch nicht so SEO-begabt sind (keine Verlinkung untereinander) und ich ihnen da nicht noch extra Aufschwung geben will.

Lustig auch zu sehen, wie simpel teilweise nach Schlagwörtern gesucht wird, wie zum Beispiel hier auf enthaltungen.de, wo ein Tweet der kölner Piraten über ein Abstimmungsergebnis verwendet wird.

Was mich ja doch ein wenig schockt ist allerdings die ebenfalls auf obige IP-Adresse zeigende Domain tätervolk.de – die Leute, die solche Worte verwenden, kann man doch immer sehr schnell einordnen. Und so kommt es auch, dass diese die einzige Domain ist, auf der jemand tatsächlich einen der automatisierten Posts kommentiert! Ja: kommentiert! Und nicht nur ein Verwirrter, nein: In den Posts von "Stahlgewitter"-Liedern (srsly!?!) gibt es einmal 22 und einmal 25 Kommentare. Ich werde das nicht verlinken hier.

Y U SO STUPID?!

posted 2011-09-24 tagged zsh and domain

debugging a zsh completion function

There's a Perl module threads::shared. However, it won't show up as a completion match to the perldoc command. Why is that?, a colleague asked me. Now, that obviously is a quirk, so let's debug it.

We start at /usr/share/zsh/functions/Completion/Unix/_perldoc, where we find this:

_alternative \
    'modules:module: _perl_modules -tP' \
    'pods:base pod: _perl_basepods' \
    'files:module or .pod file:_files -g "*.(pod|pm)(-.)"' &&
    ret=0

So, go on to _perl_modules: It searches for paths where Perl would store modules and their documentation (line 85):

inc=( $( $perl -e 'print "@INC"' ) )

Then, they do some complicated globbing stuff on the directories (line 104), where a loop iterates over $inc and stores each element in $libdir:

new_pms=( $libdir/{[A-Z]*/***/,}*${~sufpat}~*blib* )

There's the catch: This globbing expression will only recurse into subdirectories that start with an uppercase letter. Lowercase modules on the highest level are okay, though. That's why threads appears (from threads.pm), but threads::shared doesn't (from threads/shared.pm).

The search for all modules that are missed this way will translate to the following Z-Shell command:

$ print -l ${^=$(perl -e 'print "@INC"')}/[a-z]*/***/*.pm(.N)
/usr/lib/perl/5.10/threads/shared.pm
/usr/share/perl/5.10/encoding/warnings.pm
/usr/share/perl/5.10/warnings/register.pm

posted 2011-09-01 tagged zsh and perl

Automatic screenshot processing

Cut out window borders and application bars from screenshots automatically: note down some corner points (in Gimp), then use ImageMagick:

for f (*.png) { convert -crop 975x559+2+30 $f $f; }

Task done!

NB: This command replaces file contents. So when not sure about the numbers, append some extension to it and view the results first. Or, simply kepp the images in a git controlled directory. That way, a simple git reset -- . will restore your previous images if you added them in the first place.

posted 2011-01-11 tagged zsh, imagemagick and git

First post with posting tool

This is my first post with a custom shell script. It automatically adds a YAML header on top of new posts, starts an editor on it and later converts the title to a nice filename.

Eventually, the script adds and commits the new post to the git repo and pushes the result. "Recovering" is supported – sort of. ;-)

posted 2011-01-04 tagged zsh, jekyll and git