WSL 中的 VIM 与 Windwos 剪切板通信


title: WSL 中的 VIM 与 Windwos 剪切板通信
date: 2019-05-28 13:52
categories: linux
tags: [vim,操作系统]
keywords:
mathjax: false
description:
WSL(Windows Subsystem for Linux)真香,然而还是存在一些瑕疵。比如 WSL不是使用的系统剪切板,与系统剪切板通信,进行复制粘贴,是一个很棘手的问题。本文谈谈解决这个问题的一些方法。


WSL(Windows Subsystem for Linux)真香,然而还是存在一些瑕疵。比如 WSL不是使用的系统剪切板,与系统剪切板通信,进行复制粘贴,是一个很棘手的问题。本文谈谈解决这个问题的一些方法。

说明

环境如下

  • Windows 10: 1709
  • WSL: Ubuntu 1904

说明

  • <c-r> 代表组合键 ctrl+r
  • <cr> 代表回车键
  • <f1> 可以从 1到12, 代表F1
  • ^J 代表换行的控制字符,而不是^,J的连接,在 linux 上 换行为 ^@,
    在 VIM 输入控制字符,比如^M,需要按下<c-r><c-m>

前言

在网上看到最新的 Windows 版本支持用 ctrl+shift+c/v 进行复制粘贴, 或者有的可以在 shell 窗口>属性>选项中开启这个功能。
我这个不行。

而且 vim --version | grep clipboard 没有 加号(系统)寄存器, 再加之懒得重新编译 vim(开启 featured) . 所以我只有另寻解决办法.

在命令行下,已经有很好的解决方法: 可以右击进行复制(先选中)和粘贴
另外 也可以使用 ctrl+c 复制(有两个功能,分别是中断和复制)

vim 下就比较麻烦了。我尝试了很多种方法,从操作的舒适程度,以及实现效果来选择出最终最优的解决方法: 通过运行 windows 的 paste.exe, clip.exe程序进行复制粘贴

复制

从 VIM 中 复制文本到 Windoes 剪切板。

寄存器

通过 VIM 寄存器实现: 将 visual 模式下选中的文本复制到 vim 寄存器,然后将寄存器内容通过 shell 处理进入到剪切板。

首先选中(在 visual 模式下),用"ay将内容保存到 a寄存器,然后在命令行模式下 !echo <c-r>a \| /mnt/c/Windows/System32/clip.exe(执行 shell 命令。 a 寄存器的内容直接 作为参数文本传递(命令行模式下, <c-r>再接寄存器名字,可以将寄存器内容拷贝过来)

然而拷贝的文本很可能不能直接在shell 下作为参数,有特殊字符,比如",$等等。
所以要进行转义,用 vim 的 escape函数 (我试了shellescape, 效果不怎么好)

把上面的操作映射到按键下, 我映射的是 ;y, 就得到如下的 vim 键盘映射
在 visual 模式下选中,依次按下 ;y即可复制

map ;y "ay: let @a="'".escape(@a,"\\'\"")."'" <cr>:!echo <c-r>a \|"/mnt/c/Windows/System32/clip.exe"<cr>

然而在复制多行时,寄存器中会包含换行控制字符^J^@,^M,这在传递到shell 中时执行会截断这个参数(在参数还没有输入完全按下 enter 回车),所以有时不会成功。
而且有些字符 escape 也很难转换为 shell 的原文本参数

所以,这个方法行不通

新建文件

由于寄存器难以传到 shell 作为参数, 我就想到可以把寄存器的内容复制到一个新的 文件 buffer 中, 然后将文件内容拷贝到剪切板,然后删除文件。
如下,每个 <cr> 分隔开 两条 命令,

在 visual 模式下选中,依次按下 ;y即可复制

map ;y "ay: vs vim-copy<cr>"aP:wq<cr>:call system("/mnt/c/Windows/System32/clip.exe < vim-copy && rm vim-copy")<cr><cr>

各部分解释如下

  • "ay: 复制选中区域到 a寄存器
  • vs vim-copy: 新建文件 vim-copy到新窗口
  • "aP:wq: 拷贝 a 内容到 文件并保存退出
  • call system("..."): 执行 shell 命令, shell 命令的内容就是复制 文件内容到剪切板,再删除文件

这个办法可以很好地复制, 唯一的缺点就是打开新buffer 窗口,再关闭,屏幕画面变化大,看着不舒服:astonished:

write命令

write 命令缩写为 w, 直接使用就是 保存缓冲区

他后面可以接shell 命令与 shell 交互


:w !echo

这是对于整个文件,也可以选择一部分,
而进入 visual 模式下选中,再按下:, 则进入命令行且将选择的位置也输入进命令行
这是可以 直接 传递给 clip.exe 程序。 执行后,选中的部分备剪切掉了,可以按 u恢复

在 visual 模式下选中,依次按下 ;y即可复制
map ;y : !/mnt/c/Windows/System32/clip.exe<cr>u
这也是最优的方法了,如果你有更好的方法,欢迎赐教。

粘贴

从 Windows 剪切板 粘贴到 VIM

pastetoggle

如果 VIM 没有设置set mouse=a, 那么可以直接右击粘贴,设置了之后要按住 shift再右击粘贴

然而这样存在问题,就是 vim 设置了autoindent,它会错误的将粘贴进的文本进行缩进, 而不是粘贴原文。

这个办法可以 set pasteset nopaste解决,设置了paste 后,就可以原文粘贴,

而这样输入命令切换很麻烦, 可以set pastetoggle=<f12>,或者其他按键,这样按一次就可以切换 paste 状态。

这样比平常的 paste 动作 要多一个pastetoggle 操作,所以不好

windows paste 程序

在 了解到上面 复制时使用的 clip.exe程序,我就在想是不是 windows 有也专门paste的程序 (这个程序是和 cmd 交互的,加之, wsl 也可以执行 exe程序)

很遗憾,windows 没有

但是令人高兴的是,一个网站上有,点击这里下载, 然后解压放到 C:Windows/System32目录下
使用 vim 的 read 命令进行与 shell 的交互, 即将 shell命令执行的输出 读到当前 buffer

映射如下

在任何模式下按下 ;p 即可粘贴

map ;p :read !/mnt/c/Windows/System32/paste.exe <cr>i<bs><esc>l
map! ;p <esc>:read !/mnt/c/Windows/System32/paste.exe <cr>i<bs><esc>l

后面的 i<bs><esc>l执行退格操作,以便接着当前的行 粘贴。不然会 paste 到新的一行.

综上所述,最终解决方案为:
点击这里下载, 然后解压放到 C:Windows/System32目录下

再在 .vimrc文件中增加如下映射

map ;y : !/mnt/c/Windows/System32/clip.exe<cr>u
map ;p :read !/mnt/c/Windows/System32/paste.exe <cr>i<bs><esc>l
map! ;p <esc>:read !/mnt/c/Windows/System32/paste.exe <cr>i<bs><esc>l

WSL 真香,强烈推荐入坑 :grimacing:
还想起一个 瑕疵, WSL 不支持32 位的程序, 不过可以安装 qemu 等解决。

另外 windows terminal 在今年 6月中旬也会来到,值得期待。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容