Skip to content

Registers Clipboard

Riteo edited this page Dec 16, 2023 · 28 revisions

Sharing clipboards between kakoune clients (e.g. tmux panes)

If your kak clients are connected to the same session (either created through :new inside supported windowing managers or explicitly by running in client mode kak -c <session>), registers are shared, so copy paste should work directly, without needing to use the system clipboard.

Using the System Clipboard

You can use kakoune with system clipboard tools like xsel, xclip or pbcopy/pbpaste (macOS). See xsel vs xclip.

On OS X, you can also use osxsnarf. This is a bit more complicated, but has the advantage that you can forward your clipboard access to other (not necessarily OS X) machines. In this case, the commands are 9 9p write snarf/snarf and 9 9p read snarf/snarf.

On Windows, you can use clip.exe (in the path by default) to save to system clipboard, e.g. when using WSL. Unfortunately it does not provide the functionality to read from the clipboard. To read from the clipboard you can invoke Get-Clipboard via Powershell. The output in this case will have Windows-style line endings which can be removed with tr or similar programs i.e. powershell.exe Get-Clipboard | tr -d "\r".

You can also sync with the paste buffer in tmux with save-buffer and show-buffer commands, as shown below.

Paste raw text without indentation

Use \ before the edit mode (E.g. \i) to prevent hooks from interfering with indentation while pasting.

To yank (copy)

<a-|> xsel --input --clipboard <ret>

<a-|> pipes each selection through the given external filter program and ignore its output.

If your copy of Kakoune is newer than July 2020, you can use the RegisterModified hook to automatically update the system clipboard whenever you yank, delete, change, or otherwise update the default change register (", the double-quote register):

hook global RegisterModified '"' %{ nop %sh{
  printf %s "$kak_main_reg_dquote" | xsel --input --clipboard
}}

If your copy of Kakoune is older, you can get nearly the same effect by hooking the y, d, and c keys directly:

hook global NormalKey y|d|c %{ nop %sh{
  printf %s "$kak_main_reg_dquote" | xsel --input --clipboard
}}

You can replace xsel --input --clipboard with:

  • xclip -in -selection clipboard >&- 2>&- if you prefer xclip
  • wl-copy > /dev/null 2>&1 & for Wayland's equivalent
  • pbcopy for macOS equivalent
  • clip.exe for Windows

Because tmux doesn't accept buffer data on standard input, you need to replace that entire line with::

tmux set-buffer -- "$kak_main_reg_dquote"

If you use the same Kakoune configuration in different environments, you may want to intelligently decide which clipboard to try to copy to:

if [ -n "$DISPLAY" ]; then
    printf %s "$kak_main_reg_dquote" | xsel --input --clipboard
elif [ -n "$TMUX" ]; then
    tmux set-buffer -- "$kak_main_reg_dquote"
fi

Yank using terminal escape sequences (OSC 52)

Some terminals and tmux also allow setting the system clipboard (or tmux buffer) by sending a special escape sequence to the terminal. This also allows forwarding through SSH sessions if you are running kakoune on a remote server. See this post for setup instructions.

To paste

! xsel --output --clipboard <ret>

! inserts program output before selection while <a-!> inserts program output after selection.

Therefore you can add the following mappings:

Paste before

map global user P '!xsel --output --clipboard<ret>'

Paste after

map global user p '<a-!>xsel --output --clipboard<ret>'

Replace selection

map global user R '|xsel --output --clipboard<ret>'

You can replace xsel --output --clipboard with:

  • wl-paste -n for Wayland's equivalent
  • pbpaste for macOS equivalent
  • tmux show-buffer for tmux
  • powershell.exe Get-Clipboard | tr -d "\r" for Windows (WSL)

How to use it now

  • y/d - yank/delete using internal clipboard AND system clipboard at once
  • p - paste from internal clipboard
  • <space>p - paste after from system clipboard ( is default for user mode)
  • <space>P - paste before from system clipboard ( is default for user mode)
  • <space>R - replace selection from system clipboard ( is default for user mode)

Paste with mouse middle click

Requires at least Kakoune v2020.08.04.

hook global RawKey <mouse:press:middle:.*> %{ exec !xclip<space>-o<ret> }

Linewise vs characterwise

If the content of the register you're about to paste ends with a new line char \n, the p command effect will be transformed from a InputMode::Append to InsertMode::InsertAtNextLineBegin meanwhile a P command effect will be transformed from a InputMode::Insert to InsertMode::InsertAtLineBegin.

There's no easy way to avoid this behavior. So use the _ trim command before yanking a line you need to be pasted on the same line than your target.

Plugins

Sharing data across sessions without using the system clipboard

The following command allows setting a given register in another Kakoune session with the contents of the current selection. It allows virtually “sending” a selection over, when copying it to the system clipboard would clump it down, or if overriding the system clipboard isn’t desirable.

define-command -params 2.. -docstring %{
    send-selection-to-session-register <register> <session>: assign the current selection to the given register of the target session
} -shell-script-candidates %{
    case "$kak_token_to_complete" in
        0) printf 'arobase\ncaret\ncolon\ndot\ndquote\nhash\npercent\npipe\nslash\nunderscore\n';;
        1)
            if [ -n "${XDG_RUNTIME_DIR}" ]; then
                ls -1 "${XDG_RUNTIME_DIR}"/kakoune/
            else
                ls -1 "${TMPDIR:-/tmp}"/kakoune-"${USER}"/
            fi
            ;;
    esac
} send-selection-to-session-register %{
    evaluate-commands -save-regs m %{
        execute-keys \"my
        edit -scratch
        execute-keys \"m<a-R>

        try %{
            execute-keys -draft s "'" <ret> yP
        }
        execute-keys i " '" <esc> a "'" <esc> gg i "reg %arg{1} " <esc> <percent>
        execute-keys <a-|> " kak -p %arg{2}" <ret>
        delete-buffer
    }
}

Example usage:

  1. select that data to send over to another session
  2. call :send-selection-to-session-register dquote <session>
  3. in a client of the target session (whose name was passed to the command above), hit a-p
Clone this wiki locally