xfce terminal里纠结的vim粘贴乱码

这里所说的乱码问题并不是网上一搜索一大把的vim乱码问题,这个问题实际上可能是
chromium的。
说明:
gvim , vim 打开/编辑 中英文文件没有任何问题。无论是gbk还是utf-8的。
vim在terminal中用”+gp 粘贴来自于firefox浏览器中的文字,没有任何问题。
粘贴来自于mousepad的字符也没有问题。
现在的问题是:
在gvim里面用

1
"+gp

粘贴没有任何问题,在terminal 里面打开vim,在chromium浏览器中复制一段文字(无论是utf-8的网页还是gb2312的网页),
然后在vim里面 执行

1
"+gp

,OK,乱码来了。除了英文,其它字符全部乱码。
如图:

terminal-vim-paste-garbled.png

:reg 查看一下* 和 + 寄存器的内容:
发现*寄存器的内容是没有乱码的,而 + 寄存器的内容则是乱码:

terminal-vim-reg.png

后来查看了下vim 帮助文档,终于知道原因了,原来* 寄存器和 + 寄存器在windows下面并不存在任何区别,但在 linux X11下面则不同了:
以下摘自vim help doc :

X11 选择机制 *x11-selection*

如果使用 X11,无论是 GUI 的还是 xterm 中运行的,Vim 都提供了多种使用 X11 的选
择机制和剪贴板的方法。它们是通过两个选择寄存器 “* 和 “+ 来实现的。

X11 提供了两种基本类型的全局存储方式,选择区和剪切缓冲区。在一个重要的方面它们
是有区别的:选择区是程序拥有的,并在程序退出时 (如 Vim) 消失,因而数据也消失
了。而剪切缓冲区存储在 X 服务器的内部,会保持到被重写或 X 服务器退出 (例如登出
时) 为止。

发起程序拥有选择区的内容 (如,通过复制),仅当其它程序请求时才执行传送操作
(如,通过粘贴)。

剪切缓冲区立即被写入,之后便可直接通过 X 服务器进行存取,无需与发起程序交互。

*quoteplus* *quote+*
文档上说,有三种 X 选择区:PRIMARY (用于代表当前的可视选择内容,就象 Vim 的可
视模式的操作对象),SECONDARY (定义不明) 和 CLIPBOARD (用于剪切、复制和粘贴操
作)。

在三种选择区里,Vim 使用 PRIMARY 用于读写 “* 寄存器 (因而,如果 X11 选择区可
用,Vim 为 |’clipboard’| 的缺省值加上 “autoselect”)。CLIPBOARD 用于读写 “+ 寄
存器。Vim 不使用 SECONDARY 选择区。

例如:(假定使用默认选项)
- 在 Vim 的可视模式里选中一个 URL。转到你的浏览器的 URL 文本框里并单击鼠标中
键。所选择的文字将被插入 (希望如此!)。备注: 在 Firefox 中,可以在
about;config 里设置 middlemouse.contentLoadURL 属性为 true,这样在窗口的大多
数位置单击鼠标中键都可以打开选中的 URL。
- 通过在你的浏览器中拖动鼠标选择一段文字。再到 Vim 中并按鼠标中键:选中的文字
被插入。
- 在 Vim 里选中一段文字并执行 “+y。转到你的浏览器,拖动鼠标选中另一段文字。现
在使用鼠标右键并在弹出菜单里选择 “Paste”。所选中的文字被 Vim 中选中的文字所
替换。
备注: 使用可视模式进行选择时,”+ 寄存器中的文字仍然存在。而选中的文字存于 “*
寄存器中。这样就可以选择被覆盖的文字了。
*x11-cut-buffer*
默认有 8 个剪切缓冲区:CUT_BUFFER0 到 CUT_BUFFER7。Vim 仅使用 CUT_BUFFER0,就
是 xterm 默认使用的那一个。

只有当 Vim 不可用 (或退出或挂起),并且因此不能响应另一个程序的选择区请求时,
Vim 才将它自己的选择区内容写入 CUT_BUFFER0 中。如果是 Vim 拥有 “+ CLIPBOARD 选
择区,那么优先写入它的值;否则,如果 Vim 拥有 “* PRIMARY 选择区,写入该值。

类似的,当 Vim 试图从 “* 或 “+ 来粘贴时 (或显式或通过点击鼠标中键隐式地对 “*
寄存器操作),如果被请求的 X 选择区为空或不可用,Vim 退而求取 CUT_BUFFER0 的
值。

备注: 用这种方式复制文字到 CUT_BUFFER0 时,选择区的类型 (字符,行或列块) 总是
被丢失,即使之后要粘贴的还是 Vim。


默认情况下 Xterm 总是将选择区内容同时写入 PRIMARY 和 CUT_BUFFER0 中。当它粘贴
时,xterm 会优先选用 PRIMARY。如果失败才会选用 CUT_BUFFER0。因此,在 Vim 和
Xterm 之间剪切和粘贴时,你应该使用 “* 寄存器。Xterm 不用 CLIPBOARD,所以 “+ 在
xterm 中无效。

多数较新的应用程序会通过 PRIMARY (“*) 来提供它们当前的选择区内容,并使用
CLIPBOARD (“+) 用作剪切、拷贝、粘贴操作。你可以通过选择 “* 或 “+ 寄存器来访问
两者。

按照doc所说,用 *寄存器试了一下粘贴,果然没有乱码。
但是 * 寄存器实际上是你当前选择的内容,而 + 寄存器才是你复制到剪切板中的内容,
自然还是没有 + 寄存器好用的。

目前我只找到这几种方案可以不乱码的:

1,按文档所说,用 * 寄存器
选择浏览器中的内容后,用 “*gp 粘贴到vim中,这样不会乱码。
2,复制浏览器中的文本后,用terminal的快捷键Shift+Ctrl+V 删除到vim中。
3,从浏览器提制文本后,打开一个mousepad,将它粘贴至mousepad中,然后再在
mousepad中复制一遍那文本,再在vim中执行 “+gp ,这样也不会乱码。

唉,这个问题真纠结。
如有朋友知道更好的解决这个问题的办法,欢迎转告我。
也许这是chromium浏览器的一个bug ?

更多
2 Responses Post a comment
  1. Soli

    编辑评论功能不好使。搞成重复评论了。

  2. Soli

    原因在于,vim 在退出是没有想剪贴板管理器发送托管请求,导致剪贴板内容丢失。

    你可以使用 "xsel -b" 观察一下剪贴板内容的变化。

    解决办法就是安装Parcellite,或者针对 Gnome 平台的 glipper、针对 KDE 平台的 klipper 以及针对 XFCE 平台的 Clipman 等。

    详情请移步:http://www.cbug.org/2012/11/27/vim-clipboard.html

Leave a Reply

Note: You may use basic HTML in your comments. Your email address will not be published.

Subscribe to this comment feed via RSS