Pages

Sunday, 6 May 2012

关于vim的编码与文件格式

 vim入门

vi filename       //打开filename文件
press esc,then type ::wq   保存文件且退出编辑器

插入文本
a      //在当前光标位置的右边添加文本

编辑其他文件
:e otherfilename    //编辑文件名为otherfilename的文件。

修改文件格式
:set fileformat=utf-8   //将文件修改为utf-8格式

当如果不知道自己处在什么模式时可以按2次Esc键即可回到命令模式.
-------------------------------------------------------------------------------

encoding 设置 Vim 内部使用的字符编码。它应用于缓冲区、寄存器、表达式所用的字符 串、viminfo 保存的等等各种文本。该选项设置 Vim 可以工作的字符类型。
fileformats ‘ffs’ 字符串
给出换行符 () 的格式,开始编辑新缓冲区或者读入文件到已有的缓冲区
时,尝试这些格式:
- 如果为空,总是使用 ‘fileformat’ 定义的格式。不自动设置该选项。
- 如果设为一个名字,总是为打开的新缓冲区使用该格式,也为该缓冲区相应地
设置 ‘fileformat’。文件读入已有的缓冲区时,使用 ‘fileformats’ 给出的
名字,不管该缓冲区设定的 ‘fileformat’ 是什么。
- 如果给出多于一个以逗号分隔的名字,读入文件时会进行自动 检测。
开始编辑文件时,这样检查 :
1. 如果所有行都以 结尾,而 ‘fileformats’ 包含 “dos” 的话,
‘fileformat’ 设为 “dos”。
2. 如果找到一个 而 ‘fileformats’ 包含 “unix” 的话,’fileformat’
设为 “unix”。注意 如果找到的 没有前导 ,”unix” 比 “dos”
优先。
3. 如果 ‘fileformats’ 包含 “mac”,’fileformat’ 设为 “mac”。这意味着
“mac” 只有在没有给出 “unix” 或者在文件里没有找到 ,并且没有给
出 “dos” 或者没有在文件里找到 时才会使用。
如果先选择 “unix”,但第一个 出现在第一个 之前,而文件里
的 比 多的话,’fileformat’ 也设为 “mac”。
4. 如果还是不能设置 ‘fileformat’,使用 ‘fileformats’ 的第一个名字。
读入文件到已有的缓冲区时,完成相同的步骤,但如同 ‘fileformat’ 已经为
该文件合适地设置过,不改变该选项。
如果置位 ‘binary’,不使用 ‘fileformats’ 的值。
对于使用 DOS 类型的 () 的系统来说,读入待执行的脚本
(“:source”) 或者 vimrc 文件时,可能进行自动 的检测:
- 如果 ‘fileformats’ 为空,没有自动检测。使用 DOS 格式。
- 如果 ‘fileformats’ 设为一到多个名字,进行自动检测。它基于文件中的第
一个 : 如果在它之前有一个 ,使用 DOS 格式,不然,使用 Unix
格式。

fileencodings ‘fencs’ 字符串
全局
{仅当编译时加入 |+multi_byte| 特性才有效}
{Vi 无此功能}
这是一个字符编码的列表,开始编辑已存在的文件时,参考此选项。如果文件被
读入,Vim 尝试使用本列表第一个字符编码。如果检测到错误,使用列表的下一
个。如果找到一个能用的编码,设置 ‘fileencoding’ 为该值。如果全都失败,
‘fileencoding’ 设为空字符串,这意味着使用 ‘encoding’ 的值。
警 告: 转换可能导致信息的丢失!如果 ‘encoding’ 为 “utf-8″ (或
某个其它的 Unicode 变种),那么转换的结果通过逆转换很有可能产生
相同的文本。相反,如果 ‘encoding’ 不是 “utf-8″,一些非 ASCII
的字符可能会丢失!你可用 |++bad| 参数指定转换失败时的行为。
对于空文件或者只含 ASCII 字符的文件,多数编码都可以工作,因而会使用
‘fileencodings’ 的第一项 (除了 “ucs-bom” 以外,它需要 BOM)。如果你更愿
意别的编码,用 BufReadPost 自动命令事件来测试是否需要使用你所喜欢的编
码。比如: >
au BufReadPost * if search(‘\S’, ‘w’) == 0 |
\ set fenc=iso-2022-jp | endif
< 如果文件没有非空白字符,该代码设置 'fileencoding' 为 "iso-2022-jp"。
如果用 |++enc| 参数,不使用 'fileencodings' 的值。
注意 'fileencodings' 不用于新文件。此时,使用 'fileencoding' 的全局
值。你可以这样设置: >
:setglobal fenc=iso-8859-2
< 这意味着不存在的文件可能和空文件得到不同的编码。
特殊值 "ucs-bom" 可用来检查文件开始处的 Unicode 的 BOM (Byte Order
Mark 字节顺序标记)。要使之能正常工作,不能把 "utf-8" 或别的 Unicode 编
码放在它的前面。
8 位编码的项目 (比如,"latin1") 应该放在最后,因为 Vim 不会检测出错,
因而总会接受该编码。
特殊值 "default" 可以用来指定环境使用的编码。这是 'encoding' 的缺省
值。可用于把 'encoding' 设为 "utf-8" 而环境使用非 latin1 编码的场合,
例如俄语。
如果 'encoding' 为 "utf-8" 而文件包含非法的字节序列,它不会被识别为
UTF-8。可用 |8g8| 命令寻找非法的字节序列。

termencoding ‘tenc’ 字符串 (缺省为 “”;GTK+ 2 GUI: “utf-8″;
Macintosh GUI: “macroman”)
全局
{仅当编译时加入 |+multi_byte| 特性才有效}
{Vi 无此功能}
终端使用的编码。它指定键盘产生的和显示能识别的字符编码。对 GUI 而言,
这只适用于键盘 (‘encoding’ 用于显示)。Mac 上如果 ‘macatsui’ 关闭时例
外,此时 ‘termencoding’ 应是 “macroman”。
在 Win32 控制台版本上,缺省值为控制台的代码页,如果和 ANSI 代码页有所
不同的话。
*E617*
注意: 不适用于 GTK+ 2 GUI。那里,GUI 成功初始化后,’termencoding’ 被强
制设为 “utf-8″。任何试图设置不同值的努力都被拒绝,而且会给出错误消息。
对于 Win32 GUI,’termencoding’ 不用于输入的字符,因为 Win32 系统总是传
入 Unicode 字符。
如果为空,使用和 ‘encoding’ 选项相同的编码。这是正常情况。
不是所有的 ‘termencoding’ 和 ‘encoding’ 的组合都是可以的。见
|encoding-table|。
此选项的值必须被内部转换机制或 iconv() 支持。如果这不可能,不会进行任
何转换,非 ASCII 字符可能会遇到问题。
例如: 你在 euc-jp (日本语) locale 的设置下工作,但需要编辑 UTF-8 文
件: >
:let &termencoding = &encoding
:set encoding=utf-8
< 如果你的系统没有 UTF-8 的 locale 支持,需要这么做。
---------------------------------------------------------------------
在vim里复制和粘贴

Vim作为最好用的文本编辑器之一,使用vim来编文档,写代码实在是很惬意的事情。每当学会了vim的一个新功能,就会很大地提高工作效率。有人使用 vim几十年,还没有完全掌握vim的功能,这也说明了vim的强大。而这样何尝不是一件好事呢,只要有的学习,就有的提高。 最近使用Vim来写博客,发现在Vim中粘贴Python代码后,缩进就全乱了。仔细研究了以下,原来是自动缩进的缘故,于是做如下设置:
:set noai nosi
取消了自动缩进和智能缩进,这样粘贴就不会错行了。但在有的vim中不行,还是排版错乱。 后来发现了更好用的设置:
:set paste
进入paste模式以后,可以在插入模式下粘贴内容,不会有任何变形。这个真是灰常好用,情不自禁看了一下帮助,发现它做了这么多事:
  • textwidth设置为0
  • wrapmargin设置为0
  • set noai
  • set nosi
  • softtabstop设置为0
  • revins重置
  • ruler重置
  • showmatch重置
  • formatoptions使用空值
下面的选项值不变,但却被禁用:
  • lisp
  • indentexpr
  • cindent
怪不得之前只设置noai和nosi不行,原来与这么多因素有关! 但这样还是比较麻烦的,每次要粘贴的话,先set paste,然后粘贴,然后再set nopaste。有没有更方便的呢?你可能想到了,使用键盘映射呀,对。我们可以这样设置::
:map <F10> :set paste<CR>
:map <F11> :set nopaste<CR>
这样在粘贴前按F10键启动paste模式,粘贴后按F11取消paste模式即可。其实,paste有一个切换paste开关的选项,这就是pastetoggle。通过它可以绑定快捷键来激活/取消 paste模式。比如::
:set pastetoggle=<F11>
这样减少了一个快捷键的占用,使用起来也更方便一些。 但,这是最方便的吗?Vimer们对高效的追求永无止境。还有其他更好地方法吗? 你可能想到了,vim寄存器。对,使用vim寄存器 "+p 粘贴即可。根本不用考虑是否自动缩进,是否paste模式,直接原文传递!:
"+p
要说vim寄存器,就要从vim文件间的复制粘贴说起。 Vim中,若要复制当前行,普通模式下按 yy 即可,在要粘贴的地方按 p 。这是vim将复制内容保存到了自己的寄存器中的缘故。如果在其他地方执行yy,新的内容将覆盖掉原寄存器中内容。如果想保存原寄存器中内容而同时增加新 的内容呢?这时就要在yy前增加标签了。标签以双引号开始,跟着的是标签名称,可以是数字0-9,也可以是26个字母,然后就是复制操作,这样就把复制内 容保存到该标签寄存器里。通过下面命令显示所有寄存器内容::
:reg
其中注意两个特殊的寄存器:"* 和 "+。这两个寄存器是和系统相通的,前者关联系统选择缓冲区,后者关联系统剪切板。通过它们可以和其他程序进行数据交换。
备注:
若寄存器列表里无"* 或 "+ 寄存器,则可能是由于没有安装vim的图形界面所致。Debian/Ubuntu下可以通过安装vim-gnome解决。
$ sudo apt-get install vim-gnome
选择缓冲区和系统剪切板啥子区别?让我们继续研究。

选择缓冲区和剪切板

不同于Windows,Linux系统里存在两个剪切板:一个叫做选择缓冲区(X11 selection buffer),另一个才是剪切板(clipboard)。 选择缓冲区是实时的,当使用鼠标或键盘选择内容时,内容已经存在于选择缓冲区了,这或许就是选择缓冲区的由来吧。 使用下面的命令查看选择缓冲区的内容::
$ xclip -out
如果没有xclip命令,Debian/Ubuntu下可以通过如下命令安装::
$ sudo apt-get install xclip
可以使用鼠标中键或键入Shift+Insert来粘贴选择缓冲区的内容。但对于有些GUI程序,比如gedit,只能通过鼠标中键调用选择缓冲区的内容,使用Shift+Insert的话,调用的是剪切板的内容。 剪切板和Windows的剪切板类似,在选择文字内容后,执行Ctrl + c或在菜单里选择‘复制’的话,这时内容才存放到剪切板里。 使用下面的命令查看剪切板的内容::
$ xclip -out -sel clipboard
而使用剪切板的内容,则是Ctrl+v。 但在有些情况下,比如gnome-terminal,不能直接使用Ctrl+c,Ctrl+v,这时就要用Shift+Ctrl+c,Shift+Ctrl+v代替。

原格式粘贴

好了,了解了选择缓冲区和剪切板,下面就是实现保留格式粘贴的完美解决方案:
  • 方案一:
  1. 选择文本内容
  2. vim普通模式下按 "*p 将选择缓冲区中内容粘贴进来
  • 方案二:
  1. 复制文件内容
  2. vim普通模式下按 "+ p 将剪切板内容粘贴进来
这时,如果要复制的内容也是vim编辑器中的内容,那么如何复制才更方便呢?

vim中的复制

vim有一个可视模式(Visual Mode),在此模式下可以选择区域。可以在普通模式下键入v进入可视模式,也可以个性化一点,键入V进入行可视模式,或者键入Ctrl+v进入列可视模 式。这时移动光标就可以选择内容了。注意这时被选内容已经实时保存于选择缓冲区了,当然你也可以键入"+y将此内容也保存到剪切板里,或者"ay将内容保 存到标签为a的寄存器中。但要知道,只有前两个中的内容可以在其他程序中使用,而a寄存器中的内容只能在该vim编辑器内使用。 也可以通过鼠标来复制。这里首先要打开鼠标模式。:
:set mouse=a
这样在普通模式下可以直接使用鼠标选择区域复制到选择缓冲区。但这种情况下不能复制到剪切板。 若要使用鼠标复制内容到剪切板,则需要做如下设置::
:set mouse=v
这种情况下,除了可以像上面一样直接使用鼠标选择区域复制到选择缓冲区以外,还可以在右键菜单中选择“复制”来保存到剪切板里。但新问题又出来了。若显示 行号,也会将行号一并选择。你会想到,这好办呀,如果不需要行号的话,在复制前,先执行set nonu来取消行号显示呗。 其实没必要这样,如果不需要复制行号的话,用在可视模式下用键盘来选择不就可以吗? 并且,从上面的讨论,我们不难得出,使用选择缓冲区比使用剪切板要方便的多,可以节省很多步骤。 所以,最终我们得到了vim文件间复制粘贴的完美方案,文件传输的中转使用选择缓冲区。

vim文件间复制粘贴完美方案

  1. 在~/.vimrc中增加如下一行::
    set mouse=v
  2. 复制内容到选择缓冲区。
    • 带行号时,使用鼠标选择内容区域。
    • 不要行号,使用 "*yny 复制n行或可视模式下选择。
  3. 将选择缓冲区中内容粘贴到vim文件:普通模式下按 "*p 。

补充: 设置vim中默认使用选择缓冲区寄存器 "*:
set clipboard = unnamed
则可以直接通过y,p和系统选择缓冲区进行数据交换.
------------------------------------------------------------
http://vimdoc.sourceforge.net/htmldoc/starting.html#gvim,图形化的vim