Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrate readline's kill-ring and the X11 clipboard

In my .zshrc, I use the following snippet to integrate the shell's clipboard and my primary X11 clipboard. Thanks to this integration, I can cut-and-paste text to and from emacs, firefox, and the terminal without having to use the mouse.

kill-line() { zle .kill-line ; echo -n $CUTBUFFER | xclip -i }
zle -N kill-line # bound on C-k

yank() { LBUFFER=$LBUFFER$(xclip -o) }
zle -N yank # bound on C-y

Note: I use this trick on mac os x as well (with pbcopy/pbpaste instead of xclip) and thanks to Synergy my two computers share a single clipboard. Neat. But it doesn't work with readline. And I find myself using readline quite often, for example in (i)python, in gdb, in ncftp...

So here comes my question: is there a way to integrate readline's clipboard with the-rest-of-the-world ?

Of course, I'm thinkging about some .inputrc wizardry here, but any insight/ideas would be welcome.

like image 239
Gyom Avatar asked Jun 15 '09 05:06

Gyom


2 Answers

Personally, I run everything inside GNU screen. This gives me tons of functionality across all terminal-based programs, not just readline-based ones. It has its own paste buffer(s), which are shared between all screens in your current session, and can read/write an exchange file (configurable with bufferfile).

  • A screen selection is made with Ctrl+A, [, <movement>, Space, <movement>;
  • copied to the paste buffer with Enter;
  • pasted with Ctrl+A, ];
  • replaced by the contents of the exchange file with Ctrl+A, <;
  • and written out to the exchange file with Ctrl+A, >.

Then all you need are little helpers to synchronize /tmp/screen-exchange and the X selection. Something as simple as this would work.

# ~/.screenrc (or entered at C-a : command prompt)
bind '{' exec sh -c 'xclip -o>~/.screen_exchange'
bind '}' exec sh -c 'xclip -i ~/.screen_exchange'

Of course some nicer bindings and macros would make life easier (this requires C-a { C-a < C-a ] to paste X selection to the terminal), but it's completely up to you.

like image 62
ephemient Avatar answered Nov 10 '22 08:11

ephemient


I'd like to propose the following _xyank() function based on ephemient's answer:

_xyank() {
    CLIP=$(xclip -o)
    COUNT=$(echo -n "$CLIP" | wc -c)
    READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}${CLIP}${READLINE_LINE:$READLINE_POINT}"
    READLINE_POINT=$(($READLINE_POINT + $COUNT))
}

What this does is to move the cursor to the end of yanked text, making it more consistent with other built-in commands.

like image 5
Wei Hu Avatar answered Nov 10 '22 08:11

Wei Hu