vim 打通系统剪切板 | 配合 tmux 实现处处通

5,082 阅读3分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

前言

  • 前阵子我研究了 tmux , 也借助插件完成了 tmux 和系统剪切板之间的打通,当然还是需要安装 xsel 或者 xclip 的。 但是随着深入使用之后发现 neovim 中也存在复制的问题,要知道当 neovimtmux 作为我的主要工作流,复制就必须打通,今天我们来完成打通系统剪切板第二章---neovim复制粘贴。

neovim复制粘贴

  • 我的 mac 上之前安装的 neovimtmux ,不知道是不是mac系统的原因,neovim中复制粘贴是打通了系统剪切板的。但是在ubuntu18.04.6 中却不能。而且我百度搜索了一下 neovim 默认是不支持系统剪切板的。想要实现系统的剪切复制就必须使用 "+y 进行复制,"+p进行粘贴 。个人觉得这样操作很是麻烦,我想要的就是 y复制 , p 粘贴。
  • 为什么复制不是通用的呢?主要 vim 考虑数据错乱的情况吧。在 vim 中一共拥有12中类型的剪切板, 我们打开 vim 或者 nvim ,输入:reg 就可以看到当前的剪切板上的内容了。

image-20221126135835331.png

  • 就像上面那种情况一样 , 红框圈中的表示通过输入对应字符后在按p就可以进行粘贴了。比如我想复制 "" 剪切板上的内容,那么我们一共需要按下 ""p 即可复制。至于这12中分别是啥,分别是什么前缀我都不关心,因为我只想只用系统剪切板 "+p" ,这就是系统剪切板。

为什么neovim不能像vim一样yp复制粘贴呢

  • 上面我们提到了12中寄存器, 但是遗憾的是 neovim 中不支持 + * 两种寄存器。这就导致我们无法完成复制粘贴到系统剪切版上。
#!/bin/bash
# Taken and modified from https://github.com/agriffis/skel/blob/master/neovim/bin/clipboard-provider
#
# clipboard provider for neovim
#
# :help provider-clipboard#exec 2>> ~/clipboard-provider.out
#set -x
​
: ${COPY_PROVIDERS:=tmux pb xclip osc52 local}
: ${PASTE_PROVIDERS:=xclip pb tmux local}
: ${TTY:=`(tty || tty </proc/$PPID/fd/0) 2>/dev/null | grep /dev/`}
​
LOCAL_STORAGE=$HOME/.clipboard-provider.out
​
main() {
    declare buffer status=1
​
    case $1 in
        copy)
            buffer=$(base64 | tr -d '\n')
            internal() { base64 --decode <<<"$buffer"; }
            for p in $COPY_PROVIDERS; do
                internal | $p-provider copy && status=0
            done ;;
        paste)
            for p in $PASTE_PROVIDERS; do
                $p-provider paste && status=0 && break
            done ;;
    esac
​
    exit $status
}
​
is-copy() {
    if [[ "$1" == "copy" ]]; then return 0; else return 1; fi
}
​
tmux-provider() {
    [[ -n $TMUX ]] || return `is-copy "$@"`
    case $1 in
        copy) internal | tmux load-buffer - ;;
        paste) tmux save-buffer - ;;
    esac
}
​
pb-provider() {
    if ! command -v pbcopy &>/dev/null;then return $(is-copy $1); fi
    case $1 in
        copy) internal | pbcopy ;;
        paste) pbpaste ;;
    esac
}
​
osc52-provider() {
    # HACK: this ignores stdin and looks directly at the base64 buffer
    case $1 in
        copy) [[ -n "$TTY" ]] && printf $'\e]52;c;%s\a' "$buffer" > "$TTY" ;;
        paste) return 1 ;;
    esac
}
​
local-provider() {
    case $1 in
        copy) internal > $LOCAL_STORAGE ;;
        paste) cat $LOCAL_STORAGE && return 0;;
    esac
}
​
xclip-provider() {
    if ! command -v xclip &>/dev/null;then return $(is-copy $1); fi
    case $1 in
        copy) internal | xclip -i -selection clipboard;;
        paste) xclip -o -selection clipboard;;
    esac
}
​
main "$@"
  • 上面是 github 上大佬提供的脚本, 我稍作一处小小改动,我们只需要将脚本放到 /usr/bin 或者配置到环境变量中即可 。
  • 完成上述配置理论上你将可以通过如下方式测试
echo "hello world" | clipboard-provider copy
  • 通过在终端输入如下命令,再去其他地方进行 Ctrl + V 你就会发现出来的是 hello world 表示我们完成了系统剪切板的配置。

neovim配置打通剪切板

  • 有了上述的脚本我们仅仅是完成了通过命令复制内容到系统剪切板上。但是想要 neovim 上通过 yp 复制粘贴还需要最后一步 。在我们的 neovim 主配置文件入口,正常情况是init.vim
 if executable('clipboard-provider')
 let g:clipboard = {
         \ 'name': 'myClipboard',
         \     'copy': {
         \         '+': 'clipboard-provider copy',
         \         '*': 'clipboard-provider copy',
         \     },
         \     'paste': {
         \         '+': 'clipboard-provider paste',
         \         '*': 'clipboard-provider paste',
         \     },
         \ }
endif
  • 配置完成之后退出重新通过 nvim 打开,这个时候我们就打通的系统剪切板了。你可能会说 vim 咋办呢? 也是一样的配置 ,因为我已经转 neovimvim 配置就没有尝试了。你可以自己尝试下。
  • 最后建议在 init.vim 中添加 set clipboard+=unnamedplus 这段配置,经过测试有没有这段配置都不会影响打通系统剪切板的。

本文正在参加「金石计划 . 瓜分6万现金大奖」