Integrate readline's kill-ring and the X11 clipboard Integrate readline's kill-ring and the X11 clipboard unix unix

Integrate readline's kill-ring and the X11 clipboard


Bash 4.0 introduces some new functionality:

NEWS

The command assigned to a key sequence with `bind -x' now sets two new variables in the environment of the executed command: READLINE_LINE_BUFFER and READLINE_POINT. The command can change the current readline line and cursor position by modifying READLINE_LINE_BUFFER and READLINE_POINT, respectively.

The NEWS file seems to be inaccurate; READLINE_LINE (no _BUFFER) is what's documented elsewhere and actually works.

The following will simulate the behavior of Bash's existing Ctrl+(U|K|Y) but affecting the X selection, though I use Meta/Esc because I don't like overwriting existing functionality.

_xdiscard() {    echo -n "${READLINE_LINE:0:$READLINE_POINT}" | xclip    READLINE_LINE="${READLINE_LINE:$READLINE_POINT}"    READLINE_POINT=0}_xkill() {    echo -n "${READLINE_LINE:$READLINE_POINT}" | xclip    READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}"}_xyank() {    READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$(xclip -o)${READLINE_LINE:$READLINE_POINT}"}bind -m emacs -x '"\eu": _xdiscard'bind -m emacs -x '"\ek": _xkill'bind -m emacs -x '"\ey": _xyank'

I still like screen more, but this better answers your question — as long as the only readline application you care about is Bash.


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.


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.