最佳vim技巧
----------------------------------------
# 信息来源
----------------------------------------
www.vim.org : 官方站点
comp.editors : 新闻组
http://www.newriders.com/books/opl/ebooks/0735710015.html : Vim书籍
http://vimdoc.sourceforge.net/cgi-bin/vim2html2.pl : 关于vim的可查询文档
http://vimdoc.sourceforge.net/vimfaq.html : VIM FAQ
----------------------------------------
# 基础
----------------------------------------
* # g* g# : 寻找光标处的狭义单词(<cword>) (前向/后向)
% : 括号配对寻找 {}[]()
matchit.vim : 使得 % 能够配对标记 <tr><td><script> <?php 等等
<C-N><C-P> : 插入模式下的单词自动完成
<C-X><C-L> : 行自动完成(超级有用)
/<C-R><C-W> : 把狭义单词 <cword> 写到 搜索命令 行
/<C-R><C-A> : 把广义单词 <cWORD> 写到 搜索命令 行
:set ignorecase : 搜索时忽略大小写
:syntax on : 在 Perl,HTML,PHP 等中进行语法着色
:h regexp<C-D> : 按下 control-D 键即可得到包含有 regexp 的帮助主题的列表
: (使用TAB可以实现帮助的自动补齐)
----------------------------------------
# 使更新 _vimrc 更容易
:nmap ,s :source $VIM/_vimrc # 译释:nmap 是绑定一个在normal模式下的快捷键
:nmap ,v :e $VIM/_vimrc
# 译释:在normal模式下,先后按下 ,s 两个键执行_vimrc,而 ,v 则是编辑_vimrc
----------------------------------------
# visual 模式 (例子是:轻松添加其他的 HTML Tags)
:vmap sb \"zdi<b><C-R>z</b><ESC> :在visual模式下选中的文字前后分别加上<b>和</b>
# 译释:vmap 是绑定一个在visual模式下的快捷键\r\n# 译释:原理:在visual模式下,# 译释:原理:在visual模式下,\"zd 把一个选中的区域命名为z 然后删除,
# i 进入插入模式,输入<b>,<C-R>z 撤销刚才的删除,然后再写入</b>,
# 最后<ESC>返回normal模式\r\n# 译释:\"z 命令创建一个选中的区域为register,并把它命名为z\r\n# 译释:更令人开心的有:在visual模式下选中几行,然后输入 2> ,
# 则选中的行会全部缩进两个tab
# 555,偶一开始还是用 :xx,xx s/^/\\t\\t/,好傻啊!\r\n:vmap st \"zdi<?= <C-R>z ?><ESC> :在visual模式下选中的文字前后分别加上<?= 和 ?>
----------------------------------------
# 文件浏览
:Ex : 开启目录浏览器,注意首字母E是大写的
:Sex : 在一个分割的窗口中开启目录浏览器
:ls : 显示当前buffer的情况
:cd .. : 进入父目录
:args : 显示目前打开的文件
:lcd %:p:h : 更改到当前文件所在的目录
# 译释:lcd是紧紧改变当前窗口的工作路径,% 是代表当前文件的文件名,
# 加上 :p扩展成全名(就是带了路径),加上 :h析取出路径\r\n:autocmd BufEnter * lcd %:p:h : 自动更改到当前文件所在的目录
# 译释:autocmd指定一个自动命令,BufEnter指定一个事件,* 指定事件的对象,
# lcd %:p:h 指定一个动作
# hehe,好像和写记叙文差不多
----------------------------------------
# 缓冲区(buffer)浏览器 (第三方的一个最流行的脚本)
# 需要下载 bufexplorer.vim ,http://www.vim.org/script.php?script_id=42 上就有
\\be : 在缓冲区浏览器中打开缓冲区列表
\\bs : 以分割窗口的形式打开缓冲区浏览器
----------------------------------------
# 大小写转换
guu : 行小写
gUU : 行大写
g~~ : 行翻转(当然指大小写啦)
# 译释: g 是大小写转换命令(greate),u/U/~是三种转换形式(小写/大写/翻转),
# 最后一个重复则表示该转换是对于一行而言的\r\nguw : 字大写(狭义字) 译注:建议对比iw
gUw : 字小写(狭义字)
g~w : 字翻转(狭义字)
# 译释:最后一个w 表示该转换是对于一个字而言的,由于是在normal模式下,
# 所以这个w 表示一个狭义字<cword>\r\nvEU : 字大写(广义字)
vE~ : 字翻转(广义字)
# 译释:vE 这个指令组合会进入visual模式,然后选择一个广义字<CWORD>\r\nggguG : 把整个文章全部小写(ft!bt!)
gf : 取当前光标处的广义字作为文件名,然后试图打开它!
# 译释:为什么是广义字呢?因为这样可以方便的取到路径啊,像/var/www/html/index.htm\r\nga : 显示光标处字符的ascii,hex,oct,...晕菜的一堆转换
ggVGg? : 用rot13编码整个文件(晕!)
# 译释:gg到文件首行首字符,V进入Visual-Line模式,G到文件末行首字符,
# 这样就选中了整篇文章,然后g?就是用rot13编码整个文件啦
#
# 【关于rot13——谁让英文是偶数个字母啊】
# ROT13 是一种简单的编码,它把字母分成前后两组,每组13个,编码和解码
# 的算法相同,仅仅交换字母的这两个部分,即:[a..m] --> [n..z] 和 [n..z]
# --> [a..m] 。 ROT13 用简易的手段使得信件不能直接被识别和阅
# 读,也不会被搜索匹配程序用通常的方法直接找到。经常用于 USENET 中发表一
# 些攻击性或令人不快的言论或有简单保密需要的文章。
# 由于 ROT13 是自逆算法,所以,解码和编码是同一个过程。\r\n<C-A>,<C-X> : 增加,减少 光标处的狭义字所表示的数字
:(,仅仅是分割了这两个命令,不是命令的一部分)
: Win32的用户可能需要重新定义一下Ctrl-A,呵呵
# 译注:good guy, 令人不得不想到perl的数字串\r\n<C-R>=5*5 : 插入25 (这是一个迷你计算器耶!)
----------------------------------------
# 好玩的东东
:h 42 : 也可以访问 http://www.google.com/search?q=42
: 第一个结果就是 News. Douglas Adams 1952 - 2001.
: Floor 42 extends its deepest sympathies to
: the family, friends, and fans of Douglas Adams.
:h holy-grail
:h!
----------------------------------------
# 标记和移动
\'. : 跳到最后修改的那一行 (超级有用)(ft,怎么又是这个评价)
`. : 不仅跳到最后修改的那一行,还要定位到修改点
<C-O> : 依次沿着你的跳转记录向回跳 (从最近的一次开始)
<C-I> : 依次沿着你的跳转记录向前跳
:ju(mps) : 列出你跳转的足迹
:help jump-motions
:history : 列出历史命令记录
:his c : 命令行命令历史
:his s : 搜索命令历史
q/ : 搜索命令历史的窗口
q: : 命令行命令历史的窗口
:<C-F> : 历史命令记录的窗口
----------------------------------------
# 缩写和键盘映射(原文中文件举例都用了c:/aaa/x,偶全给他改成/path/file了,哼唧)
:map <f7> :\'a,\'bw! /path/file
# 译释:map是映射一个normal模式下的键
# 这里是把F7键映射成把标记a到标记b中间的内容另存为一个文件/path/file
# 标记(mark)的方法:把光标移动到需要标记的地方,输入m,然后输入标记名,例如a\r\n# 引用标记的方法:\'a ,即:单引号加标记名\r\n:map <f8> :r /path/file # 译释:把F8键映射成在当前位置插入文件/path/file的内容
:map <f11> :.w! /path/file2<CR>
# 译释:.(点号)表示当前行
# 所以F11就是把当前行存为/path/file2
# 最后的<CR>表示一个回车
:map <f12> :r /path/file2<CR>
:ab php : 列出php表示的缩写
# 译释:定义一个缩写使用::iab hm hmisty
# 一个有趣的现象是,它列出的会是php和它的前子串开头的缩写
# 例如,有这么几个缩写:
# h => hmisty1 , hm => hmisty2 , hmi => hmisty3, m => hmisty4
# 那么使用 :ab hm会显示这么几个缩写:hm 和 h
# 而不是你想象中的 hm 和 hmi\r\n:map , : 列出以逗号开始的键盘映射
# 译释:一般而言,我们称这些逗号开始的组合键为“逗号命令”
# 不过hmisty更喜欢用;构成“分号命令”
# 而且不是用map,而是用imap
# 因为偶懒么,懒得按<Esc>,所以直接在insert模式下就执行命令了
# 为什么用分号呢?因为我最常用它写程序啊
# perl/C/C++/object pascal/java,都是用分号结束一个语句
# 我们一般很少在分号后面连续写其他字符
# 所以用“分号+其他键”就很少会在输入的时候造成冲突\r\n# 在键盘映射中常用的表示
<CR> : 回车
<ESC> : Esc
<LEADER> : 转义符号 \\
<BAR> : 管道符号 |
----------------------------------------
# 列出寄存器(Registers)
:reg : 显示所有当前的registers
\"1p : \"表示引用register,1表示一个名字叫做1的register,
: p就是粘贴(paste)命令
# 译释:\"也用来定义register
# 先输入 \",表示定义register
# 然后输入名字,如0~9,a~z
# 然后执行删除或复制命令,如dd或y,
# 或者是visual模式下的d(删除选中的部分)或y(复制选中的部分)
# 则被删除或复制的部分就被存入了这个命名的register
#
# 观察:一个特殊的register, \"\" ,里面存储了一个匿名的删除/复制
# 在你执行dd或y的时候,被作用的部分被存到了\"\"中
# 这些和perl是多么像啊
----------------------------------------
# Useful trick
\"ayy@a : 把当前行作为一个Vim命令来执行
# 译释:\"ayy 是定义当前行到register a,然后@a是执行register a中存储的指令
# yy: 复制一行
# 10yy: 复制从此向下的10行\r\nyy@\" : 用上面所提到的那个匿名register
----------------------------------------
# 从其他程序获取输出 (需要外部程序)
:r!ls.exe : 读取ls的输出到当前位置
!!date : 读取date的输出 (但是会替换当前行的内容)
# 译释:其实你输入了!!后,vim就自动转换到 :.! 等待你继续输入\r\n# 使用外部程序sort进行排序(sort是Unix标准命令,ls,date也是)
:%!sort -u : 使用sort程序排序整个文件(用结果重写文件)
# 译释:%表示整个文件的所有行
# !sort表示执行外部命令sort
# -u是sort的参数,man sort看看,这个参数的意义是合并相同的行
# u就是unique,如果两行内容相同,则结果中只保留一行的说\r\n:\'a,\'b!sort -u : 对mark a 到mark b中间的内容进行排序
!1} sort -u : 排序当前段落 (只能在normal模式下使用!!)
# 译释:!表示使用filter,1}表示filter的对象是从当前行开始向后数一段
# 段落指到空行处结束,不包括空行
# 其实你一旦输入 !1},vim就自动计算当前段落应该到那一行(eg.+5),然后生成
# :.,.+5! 等待之后输入sort -u,回车,完成操作
# .表示当前行,.+5当然就是当前行向后数5行
----------------------------------------
# 多文档操作 (基础)
# 译注:用 :ls! 可以显示出当前所有的buffer
:bn : 跳转到下一个buffer
:bp : 跳转到上一个buffer
:wn : 存盘当前文件并跳转到下一个(又是“超级……”,ft!)
:wp : 存盘当前文件并跳转到上一个
:bd : 把这个文件从buffer列表中做掉
:bun : 卸掉buffer (关闭这个buffer的窗口但是不把它从列表中做掉)
:badd file.c : 把文件file.c添加到buffer列表
:b 3 : 跳到第3个buffer
:b main : 跳到一个名字中包含main的buffer,例如main.c : (ultra,这个怎么翻译?:()
:sav php.html : 把当前文件存为php.html并打开php.html
:sav! %<.bak : 换一个后缀保存
:e! : 返回到修改之前的文件(修改之后没有存盘)
:w /path/% : 把文件存到一个地儿
:e # : 编辑标记为#的buffer(这个buffer必须含有一个可编辑的文件)
: 用ls命令就能看到哪一个buffer有#
: %a表示当前正在编辑的buffer
: u 表示不能编辑或者已经被做掉的buffer
:e #3 : 编辑编号为3的buffer(这个buffer必须含有一个可编辑的文件)
:rew : 回到第一个可编辑的文件
:brew : 回到第一个buffer
:sp fred.txt : 在一个水平分割的窗口中打开文件fred.txt # 译注:vs fred.txt可以实现垂直分割
:sball : 把当前所有含有可编辑文件的buffer显示到一个分割窗口中 : (偶该考虑把super翻译成 高级指令 了,ft)
:map <F5> :ls<CR>:e # : 在normal模式下按F5键,则会显示所有含有一个\r\n : 可编辑文件的buffer,然后提示你输入buffer的序号,
: 输入后回车,则编辑这个buffer
# 译注:这是一个键盘绑定\r\n:set hidden : 允许不保存buffer而切换buffer (w/o=without)
----------------------------------------
# 在分割窗口中快速切换
:map <C-J> <C-W>j<C-W>_
# 译注:原文此处有误,前面应该加上冒号
# 这是一个键盘绑定,把Ctrl-J定义成切换到下一个窗口并最大化
:map <C-K> <C-W>k<C-W>_
----------------------------------------
# 命令录制 (最佳技巧,ft)
qq #录制到q
.. #输入一系列复杂的指令
q #再次按q停止录制
@q #执行q中存储的指令
@@ #重复执行
# 编辑register/录制
\"ap #把register a中的内容贴到当前位置
.. #现在你可以修改它了
\"add#删除之,重新存入register a
@a #执行register a中的指令
----------------------------------------
# _vimrc基础
:set incsearch : 实时匹配你输入的内容
:set wildignore=*.o,*.obj,*.bak,*.exe : tab键的自动完成现在会忽略这些
:set shiftwidth=4 : 现在自动缩进将是4个字符
# 译注:一个tab位通常是8个字符
# 所以,我们还要设定 :set tabstop=4,这样,所有的缩进都是4字符了
# emacs默认就是4字符缩进吧?
:set vb t_vb=\". : 沉默方式(不要叫beep!)
----------------------------------------
# 加载windows iexplorer来浏览(我想这只有在windows下用gvim才能用到)
:nmap ,f :update<CR>:silent !start c:\\progra~1\\intern~1\\iexplore.exe file://%:p
# 译释:nmap是做一个normal模式下的键盘绑定
# 这里绑定了一个逗号命令 ,f
# :update是写这个文件,与:w不同,它只有当文件被修改了的时候才写
# :silent别让弹出窗口报告执行结果
# !...后面就是执行windows命令了。呵呵,去问bill gates什么意思吧。
# 不过偶用gvim 6.1试过了,好用!\r\n:nmap ,i :update<CR>: !start c:\\progra~1\\intern~1\\iexplore.exe <cWORD><CR>
----------------------------------------
# 用VIM编辑ftp文件
:cmap ,r :Nread ftp://209.51.134.122/public_html/index.html
:cmap ,w :Nwrite ftp://209.51.134.122/public_html/index.html
# 译注:原文丢失了开头的冒号
# cmap是命令(command)模式绑定\r\ngvim ftp://209.51.134.122/public_html/index.html
# 这一句就是开始编辑一个ftp远端的文件,ft
----------------------------------------
# 附加到一个register (就是用大写的register名字啦!)
\"a5yy #复制5行到a中
10j #下移10行
\"A5yy #再添加5行到a中
----------------------------------------
[I : 显示光标处的狭义字可以匹配的行(高级指令)
# 译注:# 可以全文查找与光标处的狭义字相匹配的字,
# 这在查找函数原型和实现,或者变量使用的时候很有用
----------------------------------------
# 常规缩进
:\'a,\'b>>
# 译释:把mark a到mark b之间的内容进行两次缩进\r\n# 在visual模式下缩进 (无限可重复)
:vnoremap < <gv
# 译释::vnoremap 重定义了visual模式下 < 符号的含义
# 把它定义成 <gv
# 即:先<向外缩进,然后gv重新选择上一次选择了的区域
# 这样在visual模式下就可以实现连续按<而连续缩进了
:vnoremap > >gv
# 同里,内缩
----------------------------------------
# 查找(译注:建议先学习正则表达式)
# 译注:查找命令不用进入:命令模式,直接按/就可以了
# 如果没有修饰,可以不要右边的/
# 和smth bbs差不多啦,呵呵
/joe/e : 光标停留在匹配单词最后一个字母处
/joe/e+1 : 光标停留在匹配单词最后一个字母的下一个字母处
/joe/s : 光标停留在匹配单词第一个字母处
/^joe.*fred.*bill/ : ft,标准正则表达式
/^[A-J]\\+/ : 找一个以A~J中一个字母重复两次或以上开头的行
/forum\\(\\_.\\)*pent : 多行匹配
/fred\\_s*joe/i : 中间可以有任何空白,包括换行符\\n
# 译注:这个和perl不太一样的哦
/fred\\|joe : 匹配FRED或JOE
/\\<fred\\>/i : 匹配fred,fred必须是一个独立的单词,而不是子串
# 译注:这和perl也不太一样,perl是用\\b做单词定界符的
/\\<\\d\\d\\d\\d\\> : 匹配4个数字
\\<\\d\\{4}\\> : 也是匹配4个数字
# 在visual模式下查找
:vmap g/ y/<C-R>\"<CR> : 匹配选中的高亮文字
# 译释:vmap是在visual模式下的键盘映射
# 映射了g/这个命令组合
# y 把选中的高亮文字写入匿名register \"
# / 打开搜索模式
# <C-R> 准备粘贴register
# \" 粘贴了\"\"中的内容
# <CR> 回车,执行\r\n:vmap <silent> g/ y/<C-R>=escape(@\", \'\\\\/.*$^~[]\')<CR><CR> : with spec chars
# 译释:@#$&^*@#%&*#$@!\r\n# 跨行匹配,\\_ 表示允许匹配换行符,或者说,允许匹配新行
# 译注:小心,和perl不一样
/<!--\\_p\\{-}--> : 匹配多行注释
/fred\\_s*joe/i : 似乎上面有了,ft
/bugs\\(\\_.\\)*bunny : 中间可以有无数东西
:h \\_ : 看看关于 \\_ 的帮助\r\n# 查找当前光标位置所在子例程/函数(subroutine/function)的声明
:nmap gx yiw/^\\(sub\\<bar>function\\)\\s\\+<C-R>\"<CR>
# 译释:nmap 做一个normal模式下的键盘绑定
# y 进入复制状态,后面需要一个motion
# 接着就用 iw 指出了这个motion,是inner word
# inner word也是狭义字<cword>,但是和 w 不同
# w 是从光标位置开始向后看
# 而inner word总是把光标移到第一个字母,从而总能得到一个完整的狭义字
# 试一试 gUw 和 gUiw 就知道区别了,呵呵。\r\n# 在多个文档中搜索
:bufdo /searchstr
:argdo /searchstr
----------------------------------------
# 替换
# 译注:替换命令需要先进入:命令模式\r\n:%s/fred/joe/igc : 一个常见的替换命令,修饰符igc和perl中一样意思
:%s/\\r//g : 删除DOS方式的回车^M
:%s= *$== : 删除行尾空白
:\'a,\'bg/fred/s/dick/joe/igc : 非常有用!(ft,又来了!)
# 译释:\'a,\'b指定一个范围:mark a ~ mark b
# g//用一个正则表达式指出了进行操作的行必须可以被fred匹配
# 看后面,g//是一个全局显示命令
# s/dick/joe/igc则对于这些满足条件的行进行替换\r\n# 列复制
# 译注:@#%&^#*^%#$!
:%s= [^ ]\\+$=&&= : 复制最后一列
:%s= \\f\\+$=&&= : 一样的功能
:%s= \\S\\+$=&& : ft,还是一样 # 反向引用,或称记忆
:s/\\(.*\\):\\(.*\\)/\\2 : \\1/ : 颠倒用:分割的两个字段
:%s/^\\(.*\\)\\n\\1/\\1$/ : 删除重复行 # 非贪婪匹配,\\{-}
:%s/^.\\{-}pdf/new.pdf/ : 只是删除第一个pdf # 跨越可能的多行
:%s/<!--\\_.\\{-}-->// : 又是删除多行注释(咦?为什么要说“又”呢?)
:help /\\{-} : 看看关于 非贪婪数量符 的帮助
:s/fred/<c-r>a/g : 替换fred成register a中的内容,呵呵 # 写在一行里的复杂命令
:%s/\\f\\+\\.gif\\>/\\r&\\r/g | v/\\.gif$/d | %s/gif/jpg/
# 译注:就是用 | 管道啦\r\n# 或者
:%s/suck\\|buck/loopy/gc : 或者(或者需要\\,ft!,|不是或者)
# ft, \\不就是转义了么!这个和perl真是不同了!\r\n# 调用VIM函数
:s/__date__/\\=strftime(\"%c\")/ : 插入时间串\r\n# 处理列,替换所有在第三列中的str1
:%s:\\(\\(\\w\\+\\s\\+\\)\\{2}\\)str1:\\1str2:\r\n# 交换第一列和最后一列 (共4列)
:%s:\\(\\w\\+\\)\\(.*\\s\\+\\)\\(\\w\\+\\)$:\\3\\2\\1:\r\n# filter all form elements into paste register
# 把所有的form元素(就是html里面的form啦)放到register里?
# ft, 头疼,不解释了
:redir @*|sil exec \'g#<\\(input\\|select\\|textarea\\|/\\=form\\)\\>#p\'|redir END
:nmap ,z :redir @*<Bar>sil exec select\\textarea\\/\\=fo\">\'g@<\\(input\\<Bar>select\\<Bar>textarea\\<Bar>/\\=fo
# 上面这一行不能完全显示,最好Copy Article下去看\r\n----------------------------------------
# 全局(global)显示命令,就是用 :g+正则表达式
# 译释: :g/{pattern}/{cmd} 就是全局找到匹配的行
# 然后对这些行执行命令{cmd}
:g/\\<fred\\>/ : 显示所有能够为单词fred所匹配的行
:g/<pattern>/z#.5 : 显示内容,还有行号,呵呵
:g/<pattern>/z#.5|echo \"==========\" : 漂亮的显示,ft!\r\n# 全局命令 (其他)
:g/^\\s*$/d : 删除所有空行
:g!/^dd/d : 删除不含字串\'dd\'的行
:v/^dd/d : 同上 # 译释:v == g!,就是不匹配!
:g/fred/,/joe/d : not line based (very powerfull)
:v/./.,/./-1join : 压缩空行
:g/^$/,/./-j : 压缩空行
:g/<input\\|<form/p : 或者 要用\\|
:g/^/pu _ : 把文中空行扩增一倍 (pu = put) : 即:原来两行间有一个空行,现在变成2个
:g/^/m0 : 按行翻转文章 (m = move)
:g/fred/t$ : 拷贝行,从fred到文件末尾(EOF)
:%norm jdd : 隔行删除
# 译释:% 指明是对所有行进行操作
# norm指出后面是normal模式的指令
# j是下移一行,dd是删除行\r\n# incrementing numbers
:.,$g/^\\d/exe \"norm! \\<c-a>\" : 增加在BOL(beginning of line)处的数字
# 译注:.,$ 指明命令从当前行执行到最后一行
# 如果没有 .,$ 限定范围,那么g//就会对整个文件进行操作
# exe 是执行后面的命令组合\r\n:.,$g/^\\d/exe \"norm \\<c-p>\" : Win32下必须重定义Ctrl-A\r\n# 保存全局命令的结果 (注意必须使用添加模式)
:g/fred/y A : 添加所有为fred所匹配的行到register a
:\'a,\'b g/^Error/ . w >> errors.txt\r\n# 复制每一行,然后在复制出来的每一行两侧加上一个 print \'复制出来的内容\'
:g/./yank|put|-1s/\'/\"/g|s/.*/Print \'&\'/
----------------------------------------
# 全局命令和替换命令联姻 (强大的编辑能力)
:\'a,\'bg/fred/s/joe/susan/gic : 可以使用反向引用来匹配
:g/fred/,/joe/s/fred/joe/gic : non-line based (ultra)
----------------------------------------
# 先找fred,然后找joe,然后#$^$%^#$%^@%^%&%^*!
:/fred/;/joe/-2,/sid/+3s/sally/alley/gIC
----------------------------------------
# 重定向到register * 和 粘贴register *
:redir @* : 重定向命令的输出结果(最下方命令行上的结果) : 到register * (ft,* 代表0~1,a~z,..)
:redir END : 结束重定向
# 处理粘贴
\"*yy : 上面讲过了,就是复制到register *中
\"*p : 然后贴出来
----------------------------------------
:redir >> out.txt : 重定向到一个文件
----------------------------------------
# 重新格式化文本
gq<CR>
gqap (a是motion p是段落(visual模式))
ggVGgq 重新格式化整个文章
----------------------------------------
# 对多个文档实施命令
:argdo %s/foo/bar/ : 对所有:args列表中的文档执行命令
:bufdo %s/foo/bar/
:windo %s/foo/bar/
:argdo exe \'%!sort\'|w! : 使用外部命令
----------------------------------------
# 命令行的一些好玩的东东
gvim -h : 启动的时候启动帮助(Win32)
vi -h 或 vim -h : 这个是unix下用
ls | gvim - : 编辑一个数据流!
gvim -o file1 file2 : 以分割窗口打开两个文件\r\n# 指出打开之后执行的命令
gvim.exe -c \"/main\" joe.c : 打开joe.c,然后跳转到\'main\'\r\n# 对一个文件执行多个命令
vim -c \"%s/ABC/DEF/ge | update\" file1.c\r\n# 对一组文件执行多个命令
vim -c \"argdo %s/ABC/DEF/ge | update\" *.c\r\n# 自动编辑文件 (编辑命令序列Ex commands已经包含在convert.vim中了)
vim -s \"convert.vim\" file.c\r\n# 不要加载.vimrc和任何plugins (启动一个干净的VIM)
gvim -u NONE -U NONE -N
----------------------------------------
# GVIM 不同的地方
gvim -d file1 file2 : vimdiff (比较不同)
dp : 把光标处的不同放到另一个文件
do : 在光标处从另一个文件取得不同
----------------------------------------
# Vim陷阱
# 在vim的正则表达式中, + 和 | 都必须加转义符 \\
# 小心,这和perl不一样!
/fred\\+/ : 匹配fred或freddy但是不匹配free
----------------------------------------
# \\v ,或叫做very magic (通常都是这么叫)可以取消转义符
/codes\\(\\n\\|\\s\\)*where : 普通的正则表达式
/\\vcodes(\\n|\\s)*where : very magic,| 不用加 \\ 了!\r\n----------------------------------------
# 把东西送到命令行/搜索行 (SUPER:偶不再翻译这种叹词了)
<C-R><C-W> : 送一个狭义词
<C-R><C-A> : 送一个广义词
<C-R>- : 送一个小型删除寄存器register
<C-R>[0-9a-z] : 送一个命名寄存器register
<C-R>% : 送文件名过去 (#也行)
----------------------------------------
# 操作寄存器
:let @a=@_ : 清除register a
:let @*=@a : 寄存器赋值
:map <f11> \"qyy:let @q=@q.\"zzz\"
# 译注:猜猜这个无聊的绑定是什么意思?
----------------------------------------
# 关于帮助的帮助
:h quickref : 翻到VIM Quick Reference页(有用!)
:h tips : Vim自己的tips
:h visual<C-D><tab> : 得到一个关于visual关键字的帮助列表 : 然后用tab键去选择
:h ctrl<C-D> : 显示所有关于Ctrl的帮助
:h :r : :ex冒号命令
:h CTRL-R : 普通模式命令
:h \\r : \\r在正则表达式中是什么意思呢?
:h i_CTRL-R : insert模式下的Ctrl-R
:h c_CTRL-R : 命令行(command-line)模式下的Ctrl-R
:h v_CTRL-V : visual模式下的Ctrl-V
:h tutor : VIM 指南
gvim -h : 关于 VIM 命令的帮助
vi/vim -h
<C-S>T : Control Shift T go backwards in help
: 偶不清楚有什么用:(
----------------------------------------
# 选项设置在哪里?
:scriptnames : 列出所有加载的 plugins, _vimrcs
:verbose set history : 显示history的值并指出设置文件的位置
----------------------------------------
# 制作你自己的VIM帮助
:helptags /vim/vim61/doc : 重建 /doc 中所有的 *.txt 帮助文件
:help add-local-help
----------------------------------------
# 用外部程序来运行程序 (例如 perl :)
map <f2> :w<CR>:!perl -c %<CR>
# 译释::w<CR>写文件
# :!perl -c %<CR>用perl来运行当前文件
# 当前文件必须有文件名!
----------------------------------------
# 插入DOS换行符
:%s/nubian/<C-V><C-M>&/g : Ctrl-V是一种转义,它说要解释<C-M>
:%s/nubian/<C-Q><C-M>&/g : 对于Win32应该这样
:%s/nubian/^M&/g : 你看到的^M是一个字符
:%s/nubian/\\r&/g : 更好的形式
----------------------------------------
# 把最后一个命令贴到当前位置
i<c-r>:
# 把最后一个搜索指令贴到当前位置
i<c-r>/
# 译释:i是进入insert模式,
# Ctrl-r是开启插入模式下register的引用
# :和/分别引用了两个register的内容
----------------------------------------
# 更多的完成功能
<C-X><C-F> :插入当前目录下的一个文件名到当前位置
# 在insert模式下使用
# 然后用 Ctrl-P/Ctrl-N 翻页
----------------------------------------
# 替换一个visual区域
# 选择一个区域,然后输入 :s/Emacs/Vim/ 等等,vim会自动进入:模式
:\'<,\'>s/Emacs/Vim/g : 前面的\'<,\'>是vim自动添加的
----------------------------------------
# 在文件中插入行号(不是显示行号,是插入!)
:g/^/exec \"s/^/\".strpart(line(\".\").\" \", 0, 4)
----------------------------------------
# 用VIM的方式来编号行
:set number :显示行号
:set nonu :取消显示
:%s/^/\\=strpart(line(\'.\').\" \",0,&ts)\r\n#从任意行开始编号(需要perl,嘿嘿)
:\'a,\'b!perl -pne \'BEGIN{$a=223} substr($_,2,0)=$a++\'
#似乎有点小问题,你试试看:)\r\nqqmnYP`n^Aq : 记录到q 然后用 @q 重复
#似乎不能工作,你试试看:)\r\n# 递增已存在数字到文件末
:.,$g/^\\d/exe \"normal! \\<c-a>\"\r\n# 高级递增,看:
http://vim.sourceforge.net/tip_view.php?tip_id=150
----------------------------------------
# 高级递增 (\"真的很有用\",ft)
\" 把下面几句放到 _vimrc #vimrc脚本用 \" 做行注释符
let g:I=0
function! INC(increment)
let g:I =g:I + a:increment
return g:I
endfunction
\" 例如从mark a 到mark b 递增,从223开始,步长为5
:let I=223
:\'a,\'bs/$/\\=INC(5)/
\" (原文:create a map for INC)
\" 但是cab是清楚命令行缩写啊?怎么回事?
cab viminc :let I=223 \\| \'a,\'bs/$/\\=INC(5)/
----------------------------------------
# 加密(小心使用,不要忘了密码)\r\n:X : 然后vim会提示你输入密码
:h :X
----------------------------------------
# modeline (make a file readonly etc) must be in first/last 5 lines
# 不会用,不翻了
// vim:noai:ts=2:sw=4:readonly:
:h modeline
----------------------------------------
# Creating your own GUI Toolbar entry
# 对于text模式下的vim没用,不翻了
amenu Modeline.Insert\\ a\\ VIM\\ modeline <Esc><Esc>ggOvim:ff=unix ts=4 ss=4<CR>v
----------------------------------------
# 一个保存当前光标下的狭义字到一个文件的函数
function! SaveWord() \"这里用!是强制覆盖以前的定义
normal yiw
exe \':!echo \'.@0.\' >> word.txt\'
endfunction
map ,p :call SaveWord() #使用该函数的一个例子
----------------------------------------
# 删除重复行的函数
function! Del()
if getline(\".\") == getline(line(\".\") - 1)
norm dd
endif
endfunction\r\n:g/^/ call Del() #使用该函数的一个例子
----------------------------------------
# 双字节编码 (non alpha-numerics)
:digraphs : 显示编码表
:h dig : 帮助
i<C-K>e\' : 输入 é
i<C-V>233 : 输入 é (Unix)
i<C-Q>233 : 输入 é (Win32)
ga : 查看字符的hex值
----------------------------------------
# 文件名自动完成 (例如 main_c.c)
:e main_<tab> : tab 键完成
gf : 打开光标处广义字命名的文件 (normal模式)
main_<C-X><C-F> : 文件名自动完成(insert模式)
----------------------------------------
# Vim复杂使用
# 交换两个单词
:%s/\\<\\(on\\|off\\)\\>/\\=strpart(\"offon\", 3 * (\"off\" == submatch(0)), 3)/g
----------------------------------------
# 把text文件转换成html文件(oh,ft)
:runtime! syntax/2html.vim : 转换 txt 成 html
:h 2html : 看看帮助
----------------------------------------
# VIM 有一个内部自带的 grep 命令
:grep some_keyword *.c : 得到一个包含some_keyword的c文件名列表
:cn : 去下一个出现的位置
----------------------------------------
# 强制无后缀文件的语法着色方式 .pl
:set syntax=perl # 取消语法着色
:set syntax off # 改变色彩主题 (在~vim/vim??/colors中的任何文件)
:colorscheme blue ----------------------------------------
:set noma (non modifiable) : 防止修改
:set ro (Read Only) : 只读保护
----------------------------------------
# Sessions (打开一系列文件)
gvim file1.c file2.c lib/lib.h lib/lib2.h :在\"session\"中加载一系列文件
:mksession : 生成一个Session文件 (默认是Session.vim)
:q
gvim -S Session.vim : 重新读取一个session,也就读取了所有文件,ft
----------------------------------------
# 标记(tags) (跳转到subroutines/functions)
taglist.vim : 最流行的插件
:Tlist : 显示Tags (functions的列表)
<C-]> : 跳转到光标处的function
: 这个键 Ctrl-] 和vim帮助中是一样的
----------------------------------------
# Just Another Vim Hacker JAVH
# Juat Another Perl Hacker JAPH,嘿嘿
vim -c \":%s/^/WhfgTNabgureRIvzSUnpxre/|:%s/[R-T]/ /Ig|:normal ggVGg?\"
# 译释:呵呵,谁来解释一下吧!
# 其实不过是在启动vim的时候执行了一个命令
# 先写入了 Just Another Vim Hacker 的rot13编码
# 然后再解码
----------------------------------------
终于翻完了,呵呵。好累啊!
__END__\r\n--
hmisty, hey misty!
H misty
Haow Much I\'m Special To You
vi 剪贴操作补充(一)\r\n强烈建议大家先看看 doc/change.txt 里关于寄存器部分的内容,
只是简单提及一下,英文不太好的朋友请找 vim 的中文文档。
我要介绍的超强武器是 ctrl-r,在 insert mode
和 command mode 均可使用,功能就是插入寄存器相关内容。
大家可以试试先 copy 或 delete 一些文本,然后在
normal mode 或 command mode 输入 ctrl-r \",看到了吗,
你粘贴了寄存器\"的内容。\r\n寄存器的主要有以下几种:
a. The unnamed register \"\"
\"d\", \"c\", \"s\", \"x\" 和 \"y\" 等涉及删除或拷贝的命令
都会将内容存放于此(有例外)。\r\nb. 10 numbered registers \"0 to \"9
0 为最近拷贝的内容,1-9 为最近删除的内容。
指定 named register 时不会存放于此。\r\nc. The small delete register \"-
删除不多于一行的内容会存在于此。\r\nd. 26 named registers \"a to \"z or \"A to \"Z
小写与大写的区别是,小写是覆盖方式,大写是添加方式。\r\ne. four read-only registers \":, \"., \"% and \"#
\". 存放上次插入的文本
有什么用?呵,例如,你输入了一段文本,在另一个地方也
要有相同的内容,你输完后,一般要选择并复制一下吧?
而用这个,直接移到需要插入的地方,i<ctrl-r>. 即可。
\"% 是当前编辑文件全名
呵,vim 中,% 就是代表当前编辑文件名的变量,好记吧?
不过,一般直接用 % 就行,例如\":!cat %\",vim 会自动
扩展。
\"# 是alternate file 名称 (这个我不知道)
\": 上次执行的命令
记起来比较容易,冒号就是命令行提示符嘛。这个有些什么用呢?
在测试配置文件时十分有用,先在命令行输入命令,调试好后,
在 insert mode 里按Ctrl-R : 就可将该命令插到文件中。\r\nf. the expression register \"=
呵,表达式寄存器,可以输入一个表达式,并插入结果。\r\ng. The selection and drop registers \"*, \"+ and \"~
跟 gui 即 X/Windows 剪贴板有关的变量。
在 X 中,鼠标中键与系统剪贴板不一样,至于区别,大家自己
试验一下,这里给个提示,在命令行下输入 reg 可以列出所有
寄存器的内容。
h. The black hole register \"_
黑洞\r\ni. Last search pattern register \"/
上次搜索的内容。例如,我要搜索一个单词 linuxforum,但我
比较懒,先输入 /linux,发现出现很多个 linux,多次按 n 无果,
难道要重新输入 /linuxforum ? 不用,只需要 /<ctrl-r>/forum 即可。
呵,聪明的你一定想到了,用命令行历史也可以调来,按 ctrl-p 或 ctrl-n
即可上下翻阅。这样也可以嘛,也比较快捷,但要查找 forumlinux 呢?
用 ctrl-r 的话只需 /forum<ctrl-r>/ 。\r\nvim 使用技巧
作者: camry.wu\r\n我是 vim 粉丝, 用了许久, 有一些自己的感受, 又到处挖到一些别人的技巧. 感觉对 vim
粉丝比较有用, 就把它记在这儿. 希望借此文套出大家自己的巧活, 就正应了抛砖引玉的古
话了.\r\n先稍为介绍一下 vim. vi 是 unix/linux 下极为普遍的一种文本编辑器, 大部分机器上都
有. vi 有各种变种, 在不同的机器上常用不同的变种软件. 其中 vim 比较好用也用得比较
广泛. vim 是 Vi IMproved 的缩写, 表示更好的 vi. 我个人觉得它是非常好的编辑器(为
了避免 Emacs 粉丝挑眼, 就不说最好了). 没用过的也建议试试看, 当然 vim 对编写文本
文件很方便好用, 比如编写程序, html文档等等, 却不能用来编写 word 文档.\r\n关于 vim 的安装, 基本使用方法等网络上能搜出许多, 就不在这里罗嗦了, 要是对 vim 有
兴趣, 那就看看这里(中文文档): http://vcd.cosoft.org.cn/pwiki/index.php\r\n本文就说些其中比较有用, 比较常用的命令, 若能熟练运用这些命令, 那么会发现编辑文件
很舒服.\r\n说明:
以下的例子中 xxx 表示在命令模式下输入 xxx 并回车
以下的例子中 :xxx 表示在扩展模式下输入 xxx 并回车
小括号中的命令表示相关命令.
在编辑模式或可视模式下输入的命令会另外注明.\r\n1. 查找\r\n /xxx(?xxx) 表示在整篇文档中搜索匹配xxx的字符串, / 表示向下查找, ? 表示向上查找.其中xxx可以是正规表达式,关于正规式就不多说了.
一般来说是区分大小写的, 要想不区分大小写, 那得先输入
:set ignorecase
查找到以后, 再输入 n 查找下一个匹配处, 输入 N 反方向查找.\r\n *(#) 当光标停留在某个单词上时, 输入这条命令表示查找与该单词匹配的
下(上)一个单词. 同样, 再输入 n 查找下一个匹配处, 输入 N 反方
向查找.\r\n g*(g#) 此命令与上条命令相似, 只不过它不完全匹配光标所在处的单词, 而
是匹配包含该单词的所有字符串.\r\n gd 本命令查找与光标所在单词相匹配的单词, 并将光标停留在文档的非
注释段中第一次出现这个单词的地方.\r\n % 本命令查找与光标所在处相匹配的反括号, 包括 () [] {}\r\n f(F)x 本命令表示在光标所在行进行查找, 查找光标右(左)方第一个x字符.
找到后:
输入 ; 表示继续往下找
输入 , 表示反方向查找\r\n2. 快速移动光标
在 vi 中, 移动光标和编辑是两件事, 正因为区分开来, 所以可以很方便的进行光标定
位和编辑. 因此能更快一点移动光标是很有用的.\r\n w(e) 移动光标到下一个单词.
b 移动光标到上一个单词.\r\n 0 移动光标到本行最开头.
^ 移动光标到本行最开头的字符处.
$ 移动光标到本行结尾处.\r\n H 移动光标到屏幕的首行.
M 移动光标到屏幕的中间一行.
L 移动光标到屏幕的尾行.
gg 移动光标到文档首行.
G 移动光标到文档尾行.
c-f (即 ctrl 键与 f 键一同按下) 本命令即 page down.
c-b (即 ctrl 键与 b 键一同按下, 后同) 本命令即 page up.\r\n \'\' 此命令相当有用, 它移动光标到上一个标记处, 比如用 gd, * 等查
找到某个单词后, 再输入此命令则回到上次停留的位置.\r\n \'. 此命令相当好使, 它移动光标到上一次的修改行.\r\n `. 此命令相当强大, 它移动光标到上一次的修改点.\r\n3. 拷贝, 删除与粘贴
在 vi 中 y 表示拷贝, d 表示删除, p 表示粘贴. 其中拷贝与删除是与光标移动命令
结合的, 看几个例子就能够明白了.\r\n yw 表示拷贝从当前光标到光标所在单词结尾的内容.
dw 表示删除从当前光标到光标所在单词结尾的内容.
y0 表示拷贝从当前光标到光标所在行首的内容.
d0 表示删除从当前光标到光标所在行首的内容.
y$ 表示拷贝从当前光标到光标所在行尾的内容.
d$ 表示删除从当前光标到光标所在行尾的内容.
yfa 表示拷贝从当前光标到光标后面的第一个a字符之间的内容.
dfa 表示删除从当前光标到光标后面的第一个a字符之间的内容.\r\n 特殊地:
yy 表示拷贝光标所在行.
dd 表示删除光标所在行.
D 表示删除从当前光标到光标所在行尾的内容.\r\n 关于拷贝, 删除和粘贴的复杂用法与寄存器有关, 可以自行查询.\r\n4.
数字与命令
在 vi 中数字与命令结合往往表示重复进行此命令, 若在扩展模式的开头出现则表示行
号定位. 如:\r\n 5fx 表示查找光标后第 5 个 x 字符.\r\n 5w(e) 移动光标到下五个单词.\r\n 5yy 表示拷贝光标以下 5 行.
5dd 表示删除光标以下 5 行.\r\n y2fa 表示拷贝从当前光标到光标后面的第二个a字符之间的内容.\r\n :12,24y 表示拷贝第12行到第24行之间的内容.
:12,y 表示拷贝第12行到光标所在行之间的内容.
:,24y 表示拷贝光标所在行到第24行之间的内容. 删除类似.\r\n5. 快速输入字符
在 vi 中, 不要求你输入每一个字符, 可以有很多种方法快速输入一些字符.
使用 linux/unix 的同学一定有一个经验, 在命令行下输入命令时敲入头几个字符再按
TAB 系统就会自动将剩下的字符补齐, 假如有多个匹配则会打印出来. 这就是著名的命令
补齐(其实windows中也有文件名补齐功能). vi 中有许多的字符串补齐命令, 非常方便.\r\n c-p(c-n) 在编辑模式中, 输入几个字符后再输入此命令则 vi 开始向上(下)搜
索开头与其匹配的单词并补齐, 不断输入此命令则循环查找. 此命令
会在所有在这个 vim 程序中打开的文件中进行匹配.\r\n c-x-l 在编辑模式中, 此命令快速补齐整行内容, 但是仅在本窗口中出现的
文档中进行匹配.\r\n c-x-f 在编辑模式中, 这个命令表示补齐文件名. 如输入:
/usr/local/tom 后再输入此命令则它会自动匹配出:
/usr/local/tomcat/\r\n abbr 即缩写. 这是一个宏操作, 可以在编辑模式中用一个缩写代替另一个
字符串. 比如编写java文件的常常输入 System.out.println, 这很
是麻烦, 所以应该用缩写来减少敲字. 可以这么做:
:abbr sprt System.out.println
以后在输入sprt后再输入其他非字母符号, 它就会自动扩展为System.
out.println\r\n6. 替换
替换是 vi 的强项, 因为可以用正规表达式来匹配字符串.以下提供几个例子.\r\n :s/aa/bb/g 将光标所在行出现的所有包含 aa 的字符串中的 aa 替换为 bb
:s/\\<aa\\>/bb/g 将光标所在行出现的所有 aa 替换为 bb, 仅替换 aa 这个单词
:%s/aa/bb/g 将文档中出现的所有包含 aa 的字符串中的 aa 替换为 bb
:12,23s/aa/bb/g 将从12行到23行中出现的所有包含 aa 的字符串中的 aa 替换为 bb
:12,23s/^/#/ 将从12行到23行的行首加入 # 字符
:%s= *$== 将所有行尾多余的空格删除
:g/^s*$/d 将所有不包含字符(空格也不包含)的空行删除.\r\n7. 多文件编辑
在一个 vim 程序中打开很多文件进行编辑是挺方便的.\r\n :sp(:vsp) 文件名 vim 将分割出一个横(纵)向窗口, 并在该窗口中打开新文件.
从 vim6.0 开始, 文件名可以是一个目录的名称, 这样, vim 会
把该目录打开并显示文件列表, 在文件名上按回车则在本窗口打
开该文件, 若输入 O 则在新窗口中打开该文件, 输入 ? 可以看
到帮助信息.\r\n :e 文件名 vim 将在原窗口中打开新的文件, 若旧文件编辑过, 会要求保存.\r\n c-w-w vim 分割了好几个窗口怎么办? 输入此命令可以将光标循环定位
到各个窗口之中.\r\n :ls 此命令查看本 vim 程序已经打开了多少个文件, 在屏幕的最下方
会显示出如下数据:
1 %a \"usevim.html\" 行 162
2 # \"xxxxxx.html\" 行 0\r\n 其中:
1 表示打开的文件序号, 这个序号很有用处.
%a 表示文件代号, % 表示当前编辑的文件,
# 表示上次编辑的文件
\"usevim.html\" 表示文件名.
行 162 表示光标位置.\r\n :b 序号(代号) 此命令将指定序号(代号)的文件在本窗口打开, 其中的序号(代号)
就是用 :ls 命令看到的.\r\n :set diff 此命令用于比较两个文件, 可以用
:vsp filename
命令打开另一个文件, 然后在每个文件窗口中输入此命令,就能看
到效果了.\r\n8. 宏替换
vi 不仅可以用 abbr 来替换文字, 也可以进行命令的宏定义. 有些命令输起来很费劲,
因此我把它们定义到 <F1>-<F12> 上, 这样就很方便了.这些配置可以预先写到 ~/.vimrc
(windows 下为 $VIM/_vimrc) 中, 写进去的时候不用写前面的冒号.\r\n :nmap <F2> :nohls<cr> 取消被搜索字串的高亮
:nmap <F9> <C-W>w 命令模式下转移光标到不同窗口
:imap <F9> <ESC><F9> 输入模式下运行<F9>
:nmap <F12> :%s= *$==<cr> 删除所有行尾多余的空格.
:imap <F12> <ESC><F12> 同上\r\n :java 中: (注, 这里为什么说 java 中, 因为以下定义对其他文件格式不起作用, 下文
会说到如何实现这一点)
:nmap <F3> :comp javac<CR>:mak -d . %<CR>
此命令用 javac 编译 java 文件, 它会自动将光标定位到出错点. 不过这需要定
义一个 javac.vim 文件在 $VIM/compiler 下, 在 javac.vim 里面只有两行字:
setlocal makeprg=javac
setlocal errorformat=%A%f:%l:\\ %m,%-Z%p^,%-C%.%#\r\n :nmap <F4> :comp ant<CR>:mak<CR>
此命令用 ant 编译 java 文件, 它会自动将光标定位到出错点. 一般来说, 安装
vim 后已经有了compiler/ant.vim文件, 因此这个命令可以直接使用. 但是需要
在当前目录下有 build.xml 文件, 当然还必须安装 ant 才行.\r\n :nmap <F5> :cl<CR> 此命令用于查看所有的编译错误.
:imap <F5> <ESC><F5>\r\n :nmap <F6> :cc<CR> 此命令用于查看当前的编译错误.
:imap <F6> <ESC><F6>\r\n :nmap <F7> :cn<CR> 此命令用于跳到下一个出错位置.
:imap <F7> <ESC><F7>\r\n :nmap <F8> :cp<CR> 此命令用于跳到上一个出错位置.
:imap <F8> <ESC><F8>\r\n :nmap <F11> :JavaBrowser<cr>
此命令用于在窗口左部分割出一个新窗口, 里面的内容是 java 的资源树, 包括
本文件中出现的类, 类的成员变量及成员方法, 就好像 JCreator 表现的那样.
在这个窗口中输入 ? 会看到帮助. 嘿嘿, 很好用, 不过需要 ctags 支持.
:imap <F11> <ESC><F11>\r\n9. TAB
TAB 就是制表符, 单独拿出来做一节是因为这个东西确实很有用.\r\n << 输入此命令则光标所在行向左移动一个 tab.
>> 输入此命令则光标所在行向右移动一个 tab.
5>> 输入此命令则光标后 5 行向右移动一个 tab.
:12,24> 此命令将12行到14行的数据都向右移动一个 tab.
:12,24>> 此命令将12行到14行的数据都向右移动两个 tab.\r\n 那么如何定义 tab 的大小呢? 有人愿意使用 8 个空格位, 有人用4个, 有的用2个.
有的人希望 tab 完全用空格代替, 也有的人希望 tab 就是 tab. 没关系, vim 能
帮助你.以下的设置一般也都先写入配置文件中, 免得老敲.\r\n :set shiftwidth=4 设置自动缩进 4 个空格, 当然要设自动缩进先.
:set sts=4 即设置 softtabstop 为 4. 输入 tab 后就跳了 4 格.
:set tabstop=4 实际的 tab 即为 4 个空格, 而不是缺省的 8 个.
:set expandtab 在输入 tab 后, vim 用恰当的空格来填充这个 tab.\r\n10. autocmd
这个命令十分的强大, 可以用这个命令实现对不同的文件格式应用不同的配置; 可以
在新建文件时自动添加上版权声明等等. 这些命令一般定义在 ~/.vimrc 这样的配置文件
里面. 由于他很强大, 所以我不能给出很具体的说明, 只能举几个例子, 详细的请看帮助.\r\n :autocmd! 删除所有之前的自动命令.
autocmd FileType java source ~/.vim/files/java.vim
autocmd FileType java source ~/.vim/files/jcommenter.vim
以上两条命令让我在打开 java 文件时才应用后面提到的两个配置文件.
autocmd BufNewFile *.java 0r ~/.vim/files/skeletons/java.skel
以上这条命令让我在新建 java 文件时自动加入 java.skel 文件的内容.
autocmd BufNewFile *.java normal gnp
以上这条命令让我在新建 java 文件时自动运行 gnp 命令, 这个命令进行一些特殊化
处理, 比如将新 java 文件中的 __date__ 替换成今天的日期什么的.\r\n11. 常用脚本
在 vim.sf.net 你可以发现很多脚本(script), 这些脚本常常有让你意想不到的作用.
我常用的有:\r\n jcommenter.vim 自动加入 javadoc 风格的注释.
JBrowser.vim 类资源浏览. C, C++ 等可以用 Tlist\r\n 还有许多有用的, 比如 checkstyle.vim 可以检验你的编程风格, jad.vim 可以直接
反编译 .class 文件等等.\r\n12. 常用配置
在~/.vimrc 配置文件中你常常需要一些个性化配置. 比如上面写的一些宏定义, 一些
autocmd 定义等等. 比如:\r\n set suffixes=.bak,~,.o,.h,.info,.swp,.aux,.bbl,.blg,.dvi,.lof,.log,.lot,.ps,.toc
这样在vim中打开文件时, 按 tab 键补齐文件名时它会忽略上述文件.\r\n set nu 显示行号
set ai 设置自动缩进
map Y y$ 让 Y 和 D 一样, 要不然 Y 的本意和 yy 一样.\r\n13. 其他
还有许多有意思的命令, 记录在这里免得忘记.\r\n . 重复上次编辑命令.
:g/^/exec \"s/^/\".strpart(line(\".\").\" \", 0, 4) 在行首插入行号
:runtime! syntax/2html.vim 转换 txt 成 html, 会按照你的
颜色配置来转\r\nVI高级命令集锦及VIM应用实例
作者: 转自:http://linux-down.kmip.net/ 本文已被阅读:5 次
*****************************************************************************\r\n本文由正泰linux http://linux-down.kmip.net搜集,整理,如需转载,请注明出处!
本站有大量的linux电子教程,软件,技术文档,欢迎大家访问!站长阿泰qq:253222170\r\n******************************************************************************\r\nVI高级命令集锦及VIM应用实例\r\njavalee 写到:\r\n1.交换两个字符位置
xp
2.上下两行调换
ddp
3.把文件内容反转
:g/^/m0/ (未通过)
4.上下两行合并
J
5.删除所有行
dG
6.从当前位置删除到行尾
d$
7.从当前位置复制到行尾
y$ 如果要粘贴到其他地方 p 就可以了\r\n由于vi 是建立在 EX 上的 所以 当键入 : 时就来到了 EX 命令状态
8.
:ab string strings
例如 \":ab usa United States of America\" ,
当你在文见里插入 usa 时
United States of America 就蹦出来了
9.
:map keys new_seq
定义你当前 键盘命令
10.
:set [all]
vi or ex 的编辑状态
如 显示每行 :set nu
11.
在命令状态下,nyy表示拷贝从光标行起的下n行内容,p表示paste,可刚复制的内容粘贴在光标处的
下面。\r\n12.
单个字符替换用r,覆盖多个字符用R,用多个字符替换一个字符用s,整行替换用S\r\n13.\r\n:%s/old_word/new_word/g
这个指令是于在整个文件中替换特定字符串\r\n14.光标控制\r\nk:上移 nk 上移n行
j:下移 nj 下移n行\r\n将光标移到第n行,按下 mk
将光标移到第m行,按下 \"ay\'k
即将第n到m的行存到a寄存器,以此类推,b,c........寄存器等\r\n这样就可以将你常用的需要复用的内容粘贴到不同的寄存器中以备用\r\n想粘贴到某处,直接将光标移到某地,按下 \'ap 即可,以此类推,b,c........寄存器等\r\n在当前屏幕中
H 跳到第一行
M 跳到中间一行
L 跳到最后一行\r\n15.
表8-2 删除命令
删除命令操作
d l 删除当前字符(与x命令功能相同)
d 0 删除到某一行的开始位置
d ^ 删除到某一行的第一个字符位置(不包括空格或TA B字符)
d w 删除到某个单词的结尾位置
d 3 w 删除到第三个单词的结尾位置
d b 删除到某个单词的开始位置
d W 删除到某个以空格作为分隔符的单词的结尾位置
d B 删除到某个以空格作为分隔符的单词的开始位置
d 7 B 删除到前面7个以空格作为分隔符的单词的开始位置
d) 删除到某个语句的结尾位置
d 4) 删除到第四个语句的结尾位置
d( 删除到某个语句的开始位置
d } 删除到某个段落的结尾位置
d { 删除到某个段落的开始位置
d 7 { 删除到当前段落起始位置之前的第7个段落位置
d d 删除当前行
d /t e x t 删除从文本中出现\" t e x t\"中所指定字样的位置,一直向前直到下一个该字样所出现的
位置(但不包括该字样)之间的内容
d fc 删除从文本中出现字符\"c\"的位置,一直向前直到下一个该字符所出现的位置(包括
该字符)之间的内容
d tc 删除当前行直到下一个字符\" c\"所出现位置之间的内容
D 删除到某一行的结尾
d $ 删除到某一行的结尾
5 d d 删除从当前行所开始的5行内容
d L 删除直到屏幕上最后一行的内容
d H 删除直到屏幕上第一行的内容
d G 删除直到工作缓存区结尾的内容
d 1 G 删除直到工作缓存区开始的内容\r\n修改命令操作
c l 更改当前字符
c w 修改到某个单词的结尾位置
c 3 w 修改到第三个单词的结尾位置
c b 修改到某个单词的开始位置
c W 修改到某个以空格作为分隔符的单词的结尾位置
c B 修改到某个以空格作为分隔符的单词的开始位置
c 7 B 修改到前面7个以空格作为分隔符的单词的开始位置
c 0 修改到某行的结尾位置
c) 修改到某个语句的结尾位置
c 4) 修改到第四个语句的结尾位置
c( 修改到某个语句的开始位置
c } 修改到某个段落的结尾位置
c { 修改到某个段落的开始位置
c 7 { 修改到当前段落起始位置之前的第7个段落位置
c tc 修改当前行直到下一个字符c所出现位置之间的内容
C 修改到某一行的结尾
c c 修改当前行
5 c c 修改从当前行所开始的5行内容\r\n.重复上一次修改!\r\n表8-4 替换命令
替换命令操作
G的开头处
\" 移至当前行上一次所在位置(在光标移动之后)――一个双引号
\'\' 移至当前行上第一次所在位置的行的开头处(在光标移动之后)――两个单引号\r\n19.
同时vi多个文件时,CTRL-SHIFT-6回到上一个文件,在本次vi的文件和上次vi的文件之间切换。
但是我发现一个BUG:在用CTRL-SHIFT-6切换到上一个文件后,用:args查看多文件vi状态时,
屏幕底部仍然显示目前vi的是刚才的文件。
(在HP-UX,Solaris,AIX上通过)\r\n也可以使用:
:e#
进行切换\r\n20.
sco 下VI 要在文本前同样的字符加用
%s/^/要加的内容/g 要在文本后同样的字符加
%s/$/要加的内容/g\r\n21.
如何去掉文本中的 ^M 硬回车?不必用binary传回去再ascii传回来的方式,用shell或者unix语句实现。\r\ncat filename |tr -d \'\\015\' >newfile
不同的unix系统还存在一些其他不同的命令,如:doscp
sed 也可以实现这个功能.\r\ndos2unix filename filename2
反之
unix2dos filename filename2\r\n在vi 中用:$s/^M//g
^是crtl-V crtl-M\r\n22.如何在\"unix命令行\"下将一个文件的某字符串用另一个串换掉\r\nsed \'s/string1/string2/gp\' file1 > file2\r\n23.将/etc/hosts下所有的地址都ping 2次\r\n1 #/usr/bin/sh
2 #grad /etc/hosts and ping each address
3 cat /etc/hosts|grep -v \'^#\' | while read LINE
4 do
5 ADDR=`awk \'{print $1}\'`
6 for MACHINE in $ADDR
7 do
8 ping $MACHINE -n 2
9 done
10 done\r\n24\r\n到前一个函数[[ ,到下一个函数]] ,括号配对% ,交叉参考Ctrl_] (事先用ctags做索引),回来用e# ` 编辑一个函数:vi -t 函数名 ,编辑加密文本vi -X\r\n25
在插入模式下ctrl+p,自动补齐剩余单词,以赖规则:tags,以有的单词等等\r\n*****************************************************************************\r\n本文由正泰linux http://linux-down.kmip.net 搜集,整理,如需转载,请注明出处!
本站有大量的linux电子教程,软件,技术文档,欢迎大家访问!站长阿泰qq:253222170\r\n******************************************************************************\r\n当今世界,文本编辑器种类繁多,大有\"乱花渐欲迷人眼\"之势。中国有句古语:手巧不如家什妙,作为IT业的专业人士,选择一款优秀的编辑软件至关重要。笔者认为:LINUX下的VIM※以其强大的功能和无穷的魅力将使您终生受益。\r\n作者:闫石 (iloveibm@163.com)
来自:http://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip15/index.shtml\r\n由于被广泛移植,无论是PC机的DOS和WINDOWS,还是RISC/6000的AIX,乃至于IBM的大型机S/390,都能见到VIM的身影。然而,对于初学者,VIM的用户界面与使用方法非常不符合常规,甚至认为它比较混乱,无所适从。事实上,VIM编辑器是专门为经验丰富的用户设计的,它的界面和使用方法提供了更快的速度和更强的功能。对于熟知它的用户,VIM的许多特性节省了时间和击键次数,并可以完成一些其他编辑器无法完成的功能。\r\n学习的最好方法是实践,唯有如此,才能真正掌握其中的精髓。文中列举的实例,都是笔者在实际工作中遇到的,具有一定的代表性,请大家在阅读的过程中仔细体会。\r\n好了,现在让我们共同畅游神奇的VIM的世界!\r\n例一、两个常用的指令序列\r\nxp 左右交换光标处两字符的位置。
ddp 上下交换光标处两行的位置。\r\n例二、重复输入同一字符\r\n有时,我们可能想多次输入同一字符,VIM的插入功能可以很好的完成这项工作\r\n命令 80i=^ESC 一次可以输入80个字符= ,当然,80a=^ESC 也可以完成上述功能。\r\n请注意:此处的^ESC表示键盘左上方上的ESC键。\r\n例三、将两个文本数据文件按行逐条合并,并给出标尺\r\n数据文件1内容如下:
1-----
2-----
3-----\r\n数据文件2内容如下:
1=====
2=====
3=====\r\n要求的结果如下:
|--------1---------2---------3---------4---------5
1-----
1=====
|--------1---------2---------3---------4---------5
2-----
2=====
|--------1---------2---------3---------4---------5
3-----
3=====\r\n也许您会说,这还不简单,无非是反复拷贝、粘贴,任何一款文本编辑器都能完成上述功能。可是,如果这两个文件都很大,每个文件都成千上万行,恐怕简单的拷贝、粘贴就难以胜任了。因此,我们所关心的,是找到一种行之有效的方法,把枯燥乏味的工作留给计算机,我们只需发布指令。为达到此目的,请按以下步骤执行:\r\n㈠、将两文件合并,结果如下
1-----
2-----
3-----
1=====
2=====
3=====\r\n㈡、在两文件头尾相接的地方插入标志行,用以区分两个文件,本文采用的是一整行!字符
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
1=====
2=====
3=====\r\n㈢、在标志行的下方输入标尺
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
1=====
2=====
3=====\r\n㈣、执行宏命令脚本merge_2r.vim,即在VIM编辑器中按如下键 :so merge_2r.vim 回车\r\n㈤、按下键盘上的=键,执行的结果如下
|--------1---------2---------3---------4---------5
1-----
1=====
|--------1---------2---------3---------4---------5
2-----
2=====
|--------1---------2---------3---------4---------5
3-----
3=====
|--------1---------2---------3---------4---------5
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5\r\n㈥、将最后三行删除,即可得到我们需要的结果
|--------1---------2---------3---------4---------5
1-----
1=====
|--------1---------2---------3---------4---------5
2-----
2=====
|--------1---------2---------3---------4---------5
3-----
3=====\r\n怎么样,简单吗?请大家自己实际尝试一下。下面,我来详细讲解宏命令脚本merge_2r.vim 。\r\n该脚本内容如下:\r\n\"--------------------------------------------------------------------
\"Macro Function : Merge File1 And File2,Have Ruler in every record
\" Date : 2001/12/01
\" Author : Yan Shi
\"--------------------------------------------------------------------
\"1-----
\"2----- } Sample File1
\"3-----
\"!!!!!!!!!!!!!!!!!!!!!!!! Flag Row
\"|--------1---------2---------3---------4---------5 Ruler
\"1=====
\"2===== } Sample File2
\"3=====
\"--------------------------------------------------------------------
:1
:map = ma/!!!!!^M+:.co \'a-1^M/!!!!!^M2+:.m\'a^M+=\r\n前14行每行都以\"开始,表明该行是注释行,实际并不执行,只是方便读者阅读,只有最后两行才是真正的代码行。请注意:本例中的^M表示键盘上的回车键,并非^和M两个字符。为了讲述清楚,我把命令行分解开,逐一说明。\r\n首先将第一行置为当前行,然后执行map命令,将一大串VIM指令映像给字符=。这一大串VIM指令共分9步执行:\r\nma 将数据文件一的第一行标记为a
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
1=====
2=====
3=====\r\n/!!!!!^M 找到标志行,置为当前行
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
1=====
2=====
3=====\r\n+ 光标下移一行,即把标尺行置为当前行
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
1=====
2=====
3=====\r\n:.co \'a-1^M 把标尺行复制到标记行(数据文件一的第一行)的上方
|--------1---------2---------3---------4---------5
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
1=====
2=====
3=====\r\n/!!!!!^M 再次找到标志行,置为当前行
|--------1---------2---------3---------4---------5
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
1=====
2=====
3=====\r\n2+ 光标下移2行,即数据文件二的第一行置为当前行
|--------1---------2---------3---------4---------5
1-----
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
1=====
2=====
3=====\r\n:.m\'a^M 把数据文件二的第一行移至标记行的下方
|--------1---------2---------3---------4---------5
1-----
1=====
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
2=====
3=====\r\n+ 光标下移一行,即数据文件一的第二行置为当前行
|--------1---------2---------3---------4---------5
1-----
1=====
2-----
3-----
!!!!!!!!!!!!!!!!!!!!!!!!
|--------1---------2---------3---------4---------5
2=====
3=====\r\n= 这一步很关键,是典型的递归调用,重复完成以上步骤\r\n例四、在文件中置入行号\r\n工作中,我们有时希望把行号置入文件中,而VIM提供的功能 :set nu 只能显示行号,不能编辑或将其置入文件当中,下面的宏命令脚本row_num.vim可以完成此项功能。\r\n\"------------------------------------------
\"Macro Function : Source File Add Row_Num
\" Date : 2001/12/01
\" Author : Yan Shi
\"------------------------------------------
:%s/^/^I/
:$
:let end=line(\".\")
:1
\"------------------------------------------
:let num=1
:while num<=end
:let line=getline(\".\")
:let temp=substitute(line,$,num,\"\")
:call setline(\".\",temp)
:+
:let num=num+1
:endwhile
\"------------------------------------------\r\n请注意:本例中的^I表示键盘上的TAB键,并非^和I两个字符。下面,我针对该宏命令脚本逐一讲解。\r\n:%s/^/^I/ 每一行的行首添加一个TAB字符
:$ 到文件的末行
:let end=line(\".\") 末行的行号 ==〉变量 END,函数line的功能是取得指定行的行号,此处参数\".\"表示当前行
:1 到文件的首行
\"------------------------------------------
:let num=1 1 ==〉计数器
:while num<=end
:let line=getline(\".\") 取当前行的内容 ==〉变量 LINE
:let line=substitute(line,$,num,\"\") 在变量 LINE 的前面置入行号
:call setline(\".\",line) 将变量 LINE 的内容写回当前行
:+ 下移一行
:let num=num+1 计数器加一
:endwhile 循环执行,直到文件结束
\"------------------------------------------\r\n有关正则表达式的使用\r\nUNIX/LINUX下的很多工具之所以强大、灵活,关键是因为有了正则文法和元字符,这也是VIM乃至UNIX/LINUX系统的精华所在。正因为使用灵活,因此掌握起来比较吃力,如果不是真正理解,实际运用中会出现千奇百怪的错误。因此,有必要对这部分知识多花些气力。下面结合具体实例讲解。\r\n例五、有一文件,包含某外企的中国员工的资料,首先是姓名,然后是两个空格,其次是15位身份证号码。\r\nzhang.fei 430759701022003
diao.chan 651302801225012
guan.yu 342869680413001
xi.shi 120638780214006
liu.bei 210324650708001\r\n现在,有以下问题需要解决:\r\n按照外国人的习惯,应该是名在前,姓在后。因此,文件中的姓名字段需要修改。
姓与名的首字母应该大写。
根据身份证号码,还可以判断出生年月日,将其作为一个新字段添加。
根据身份证号码,可以判断出性别。若为男性,添加male,若为女性,添加female 。
将男女员工分开,男员工在前,女员工在后。
将各字段数据左对齐\r\n最终结果如下:\r\nFei.Zhang 430759701022003 1970/10/22 male
Yu.Guan 342869680413001 1968/04/13 male
Bei.Liu 210324650708001 1965/07/08 male
-----------------------------------------------
Chan.Diao 651302801225012 1980/12/25 female
Shi.Xi 120638780214006 1978/02/14 female\r\n为了完成上述功能,只需执行脚本employee.vim ,使用方法为 :so employee.vim 回车即可。\r\n脚本内容如下:\r\n:%s/ / /
:%s/\\(............\\)\\( *\\)/\\1/
:%s/\\([A-Za-z][A-Za-z]*\\)\\(\\.\\)\\([A-Za-z][A-Za-z]*\\)/\\u\\3\\2\\u\\1/
:%s/$/ xxxxxx/
:%s/\\([0-9]\\{6}\\)\\([0-9]\\{6}\\)\\([0-9]\\{3}\\) \\(xxxxxx\\)/\\1\\2\\3 \\2/
:%s/\\(..\\)\\(..\\)\\(..\\)$/19\\1\\/\\2\\/\\3
:%s/$/ xxxxxx/
:%s/\\([0-9]\\{14}[13579]\\)\\(.*\\)\\(xxxxxx\\)/\\1\\2male /
:%s/\\([0-9]\\{14}[02468]\\)\\(.*\\)\\(xxxxxx\\)/\\1\\2female/
:$
:s/.*/&^M-----------------------------------------------
:g/female/.m$\r\n在这个脚本中,使用了大量的正则表达式,这里仅对涉及到的正则表达式做一简要介绍。有关正则表达式的内容相当多,本文不可能占用大量篇幅叙述,请大家谅解。\r\n% 地址范围符号,代表文件中的所有行,作用等同于地址范围 1,$
. 与任意单字符(换行符除外)匹配,例如 y.s 可以匹配 yas y.s 或 y s 等等。
* 与前一字符的0次或多次出现匹配,例如 y*s 可以匹配 yys yyyyys 或 s 等等。
$ 与行尾匹配。
& 代表模式匹配中出现的字符串,例如 s/abc/&def 是把当前行的abc替换成abcdef 。
[] 匹配[]中出现的字符,例如[abc]匹配字符 a,b 或 c ,[a-zA-Z]匹配所有的英文字符。
\\( \\) \\(和\\)之间出现的内容可以由\\num来替代。
\\1\\2\\3 替代\\(和\\)之间出现的内容。
\\u 将后续字符串的首字母大写。
\\{num} 与前一字符的num次出现匹配。\r\n现在,我们对脚本逐条讲解,希望能帮助大家理解正则文法。\r\n⑴:%s/ / /
将文件中每行出现的2个空格替换为10个空格。\r\nzhang.fei 430759701022003
diao.chan 651302801225012
guan.yu 342869680413001
xi.shi 120638780214006
liu.bei 210324650708001\r\n⑵:%s/\\(............\\)\\( *\\)/\\1/
保留行首的12个字符,将其余的空格删除,这样,前两个字段就对齐了。\r\nzhang.fei 430759701022003
diao.chan 651302801225012
guan.yu 342869680413001
xi.shi 120638780214006
liu.bei 210324650708001\r\n⑶:%s/\\([A-Za-z][A-Za-z]*\\)\\(\\.\\)\\([A-Za-z][A-Za-z]*\\)/\\u\\3\\2\\u\\1/
将文件中每行出现的雇员姓名互换,并将首字母大写。\r\nFei.Zhang 430759701022003
Chan.Diao 651302801225012
Yu.Guan 342869680413001
Shi.Xi 120638780214006
Bei.Liu 210324650708001\r\n⑷:%s/$/ xxxxxx/
在每一行的行尾添加2个空格和6个x\r\nFei.Zhang 430759701022003 xxxxxx
Chan.Diao 651302801225012 xxxxxx
Yu.Guan 342869680413001 xxxxxx
Shi.Xi 120638780214006 xxxxxx
Bei.Liu 210324650708001 xxxxxx\r\n⑸:%s/\\([0-9]\\{6}\\)\\([0-9]\\{6}\\)\\([0-9]\\{3}\\) \\(xxxxxx\\)/\\1\\2\\3 \\2/
将xxxxxx替换成出生年月日。\r\nFei.Zhang 430759701022003 701022
Chan.Diao 651302801225012 801225
Yu.Guan 342869680413001 680413
Shi.Xi 120638780214006 780214
Bei.Liu 210324650708001 650708\r\n⑹:%s/\\(..\\)\\(..\\)\\(..\\)$/19\\1\\/\\2\\/\\3
将年月日用/字符分隔,并在年前添加19。\r\nFei.Zhang 430759701022003 1970/10/22
Chan.Diao 651302801225012 1980/12/25
Yu.Guan 342869680413001 1968/04/13
Shi.Xi 120638780214006 1978/02/14
Bei.Liu 210324650708001 1965/07/08\r\n⑺:%s/$/ xxxxxx/
在每一行的行尾添加2个空格和6个x\r\nFei.Zhang 430759701022003 1970/10/22 xxxxxx
Chan.Diao 651302801225012 1980/12/25 xxxxxx
Yu.Guan 342869680413001 1968/04/13 xxxxxx
Shi.Xi 120638780214006 1978/02/14 xxxxxx
Bei.Liu 210324650708001 1965/07/08 xxxxxx\r\n⑻:%s/\\([0-9]\\{14}[13579]\\)\\(.*\\)\\(xxxxxx\\)/\\1\\2male /
身份证号码末位是奇数的,将xxxxxx替换成male\r\nFei.Zhang 430759701022003 1970/10/22 male
Chan.Diao 651302801225012 1980/12/25 xxxxxx
Yu.Guan 342869680413001 1968/04/13 male
Shi.Xi 120638780214006 1978/02/14 xxxxxx
Bei.Liu 210324650708001 1965/07/08 male\r\n⑼:%s/\\([0-9]\\{14}[02468]\\)\\(.*\\)\\(xxxxxx\\)/\\1\\2female/
身份证号码末位是偶数的,将xxxxxx替换成female\r\nFei.Zhang 430759701022003 1970/10/22 male
Chan.Diao 651302801225012 1980/12/25 female
Yu.Guan 342869680413001 1968/04/13 male
Shi.Xi 120638780214006 1978/02/14 female
Bei.Liu 210324650708001 1965/07/08 male\r\n⑽:$ 到文件的最后一行\r\n⑾:s/.*/&^M-----------------------------------------------
在文件的最末行插入一行 \"-\" 字符。\r\nFei.Zhang 430759701022003 1970/10/22 male
Chan.Diao 651302801225012 1980/12/25 female
:g/female/.m$
将所有的女员工记录移至文件尾。
\r\n<P>Fei.Zhang 430759701022003 1970/10/22 male
Yu.Guan 342869680413001 1968/04/13 male
Bei.Liu 210324650708001 1965/07/08 male
-----------------------------------------------
Chan.Diao 651302801225012 1980/12/25 female
Shi.Xi 120638780214006 1978/02/14 female
\r\n<P>笔者目前正在为某外资公司从事大型机(IBM S/390)的软件开发,一切工作都在TSO环境中进行。为了对编写的程序进行测试,必须准备测试数据。有过大型机开发经验的人会知道,通过TSO,输入字符型数据还可以,如果要输入16进制数据,操作起来很麻烦。因为16进制数是纵向排列的,输入时既不方便,又很容易错位。怎么解决呢?我尝试了几种办法,实际证明,用VIM最方便。
\r\n<P>例六、下列数据 1234567890ABCDEF ,将其变成 13579ACE 24680BDF 的形式,这样,数据就可以很方便的粘贴到TSO环境中了。
\r\n<P>下面给出宏命令脚本change_d.vim
\r\n<P>\"----------------------------------------------------
\"Macro Function : Convert Char Arrange Direction
\"
\" Sample : 40 50 60 ==> 4 5 6
\" 0 0 0
\" Date : 2001/12/01
\" Author : Yan Shi
\"----------------------------------------------------
:s/.*/&^M/
:1
:map = malx+$p-`al=
\r\n<P>说明如下:
\r\n<P>⑴ :s/.*/&^M/ 在数据行下方添加一空行。
⑵ :1 回到文件的首行的首字符。
⑶ :map = malx+$p-`al= 将一大串VIM命令映像给字符=
\r\n<P>① ma 将首字符标记为a
② l 光标右移一个字符
③ x 删除光标处字符
④ + 移至下一行
⑤ $ 到行尾
⑥ p 将删除的字符粘贴
⑦ - 回至上一行
⑧ `a 返回到标记字符处
⑨ l 光标右移一个字符
⑩ = 递归调用,重复以上步骤,直到将该行所有的数据处理完。
\r\n<P>上面的这几个实例,展示了VIM强大的文本处理功能,但这远不能覆盖其全貌。VIM的命令很多,而且使用灵活,需要狠下一番气力才能熟练掌握。笔者年龄尚小,经验还很欠缺,希望本文能够起到抛砖引玉的作用。由于时间的原因,上述实例仅在DOS和WINDOWS环境下测试,没有在其他系统下进行进一步的测试,希望各位同行、前辈不吝赐教,谢谢!
\r\n<P>※ VIM 意为 VI Improved ,与VI99%向下兼容。而且,VIM提供了许多VI不具备的功能,内置了诸多函数,因此,建议有经验的VI用户对VIM有所了解,您会发现,转向VIM 是明智之举。欲查询有关VIM的资料,请参考 <A href=\"http://www.vim.org/\"><FONT color=#0000ff>http://www.vim.org</FONT></A>
\r\n<P>注:本文使用 VIM 6.0 版本
\r\n<P>作者简介
闫石,工程师。您可以通过电子邮件:<A href=\"mailto:iloveibm@163.com\"><FONT color=#0000ff>iloveibm@163.com</FONT></A> 或者 <A href=\"mailto:yan-shi@sino-com.com\"><FONT color=#0000ff>yan-shi@sino-com.com</FONT></A> 和他联系。
\r\n<P>附录A:一个用vi作表单的在线教程
<A href=\"http://www-900.ibm.com/developerWorks/cn/cnedu.nsf/linux-onlinecourse-bytitle/9F896668D7EB5CA948256A710030E157?OpenDocument\"><FONT color=#0000ff>http://www-900.ibm.com/developerWorks/cn/cnedu.nsf/linux-onlinecourse-bytitle/9F896668D7EB5CA948256A710030E157?OpenDocument</FONT></A>
\r\n<P>附录B:vi 命令常见问题解答
<A href=\"http://www.linuxsir.com/bbs/showthread.php?s=&threadid=23957\"><FONT color=#0000ff>http://www.linuxsir.com/bbs/showthread.php?s=&threadid=23957</FONT></A>
附录C:命令行下在线教程:
运行vimtutor即可学习!
\r\n<P>vi 命令常见问题解答
\r\n<P>作者:译者Elale
\r\n<P>[vi-faq中文版]
\r\n<P>0.0 - 引言 -- 我怎样用这个FAQ
\r\n<P>这个文档分为了几个部分.首先,第0节和第1节介绍了什么是vi;第2节则收录了很多新
学者的问题,一些对vi没有很多经验的人也经常问这些问题.这里面包括诸如“命令模式
和插入模式之间的区别”,以及“我怎样拷贝和粘贴”之类的问题.第3节是面向vi的中级
用户的,它从问题“我如何查找和替换”开始,逐步深入,直到对vi里面的宏(Macro)的
用法讨论为止.第3节还包括了一个vi的快速参考,有一个规范的vi命令列表.再下面,
是一个有关“:set”命令的列表,包含了所有能定vi环境的变量,这些变量也可以在
.exrc文件中定义.
\r\n<P>我们已经在一个运行SunOS和UCB版本vi的机器上验证了快速参考.除了SunOS带的vi外,
每个命令都可以在系统V和UCB版本vi运行,但是我个人并没有验证这一点.
\r\n<P>除非我们在文档中指明,缺省我们假定你处在命令模式下.
\r\n<P>我们还尝试保留尽可能多的术语,因为在原始的vi文档中使用了这些术语,尽管我可能
忘了它的本来含义.
\r\n<P>0.1 - 索引
\r\n<P>第一个文件:
\r\n<P>0.0 - 引言 -- 我怎样用这个FAQ?
0.1 - 索引
0.2 - 我可以散发这个FAQ吗?
0.3 - 你能为这个FAQ做什么?
\r\n<P>1.0 - 什么是vi?
1.1 - 关于vi有什么重大的交易? 为什么大家都用它? 更进一步说,为什么我要用它?
1.2 - 噢! 这听起来不错! 有没有理由不用vi?
1.3 - vi能在多少不同的操作系统下面运行?
1.4 - 好吧, 你说服了我. 我决定开始使用vi. 我该从哪儿开始?
1.5 - vi有其他一些可用的变种吗?
\r\n<P>2.0 - vi入门
2.1 - 有什么游戏帮助我们学习vi吗?
2.2 - 命令模式和插入模式有什么区别?
2.3 - 等等,我的键盘没有<Esc>键,我该怎么办?
2.4 - 那些~s是什么东西?
2.5 - 我无法习惯用 hjkl, 你有什么建议吗?
2.6 - 我如何才能不存盘就退出?
2.7 - 我怎样插入一个文件?
2.8 - 我怎样查找文本?
2.9 - 我怎样搜索一个控制序列?
2.10 - 我怎样重新格式化文本?
2.11 - 我怎样复制文本?
2.12 - 啊! 我刚才敲了一个dG,然后我的论文就没有了! 我该怎么办?
(或者,我刚才犯了个错误,我该怎么办?)
2.13 - 我正在写我的论文,被告知我必须将每一节都放在不同的文件,我该怎么办?
2.14 - 所有的:命令都是怎样处理的?
\r\n<P>3.0 - 怎样查找和替换?
3.1 - 我怎样在vi中运行一个程序?
3.2 - 啊! 我正在写我的论文, 系统崩溃了! 怎么办?
3.3 - 有没有使vi对程序员更友好的窍门?
3.4 - 宏 -- 我怎样写宏?
3.5 - 我怎样将一个功能键定义成一个宏?
3.6 - 有没有办法缩写文本?
3.7 - 我怎样在当前文档中做拼写检查?
3.8 - 我手头有一个硬拷贝的终端, 我还能用vi吗?
3.9 - 好了,是不是处在开放模式下的原因呀?! 但是我现在没有用硬拷贝终端,
它还是在开放模式呀?
\r\n<P>第二个文件:
\r\n<P>4.0 - vi档案的在线帮助在哪?
5.0 - 好玩的vi诀窍,无聊的宏
5.1 - 好玩的vi诀窍
5.2 - 好玩的宏
6.0 - 依字母顺序的vi快速参考
6.1 - 命令模式的输入选项(:命令)
6.2 - 设置选项(set)
7.0 - 建立 .exrc文件
7.1 - .exrc文件的样本
8.0 - vi的漏洞
9.0 - 术语表
10.0 - 关于vi的参考书目
\r\n<P>0.2 - 我可以散发这个FAQ吗?
\r\n<P>可以!只要你没有对它做任何修改,或者用它来赚钱.
\r\n<P>0.3 - 你能为这个FAQ做什么?
首先, 把你发现的错误告诉我. 如果你有什么建议我们也很欢迎. 你认为还不清楚的
地方告诉我们,我们同样欢迎. 还有, 使用vi! (Spread the word) 我很抱歉我无法将
所有对这FAQ有贡献的人都列出来, 因为许许多多的人都给过我建议和帮助,如果我将
他们都列出来的话,那么恐怕这张贡献者的清单将和这个文档本身一样长了.
\r\n<P>1.0 - 什么是vi?
vi是个可视化的编辑器(vi就意味着可视化--VIsual). 那么,什么是可视化的编辑器呢?
(相对于非可视化的编辑器来说)?可视化的编辑器就是可以让你在编辑文本的时候看到
它们.今天,这听起来似乎非常普通,反之,非可视化的编辑器似乎很奇怪. 非可视化的
编辑器的例子可以举出不少:如ed, sed和edlin(直到相当近的一段时间内,它是DOS自带
的最后一个编辑器) 等.vi是威廉.侨伊写的,作为BSD UNIX的一部分. 后来AT&T也开始
用vi, 于是标准UNIX也开始用vi了.
\r\n<P>1.1 - 关于vi有什么重大的交易吗? 为什么大家都用它? 更进一步说,为什么我要用?
vi是UNIX下面的缺省编辑器, 因此几乎近来所有的UNIX都捆绑了vi(近来是指1984年左右).
这意味着无论何时你跨平台使用某种UNIX,你都知道在你指尖下面有一个强力的编辑器.
为什么不是别的呢? vi是个强大的编辑器.同样,一旦你了解了vi,你就能很快的编辑你的
文件,因为它非常能节省你的敲键次数. 由于它在插入和命令两种情况下使用不同的模式,
它比大多数的不基于这种模式的编辑器要快. 而且,vi非常小(我机器上面的版本只有
200K).还有,vi几乎能做任何事,只要你知道如何使它做你想做的事.
\r\n<P>1.2 - 噢! 这听起来不错! 有没有理由不用vi?
有. 有一个非常好的理: vi稍微有些难学, 如果你开始学的话,vi又慢又让人痛苦,
当然,一旦你学会了, vi就快多了. 但是学习的过程很慢. 有人曾经问我, 如果vi是个
比较易学的编辑器, 它是否直观(intuitive)呢? 我一般这样回答:\"是的,我们有些人是
这样认为.但是大多数人认为我们疯了.\"
\r\n<P>1.3 - vi能在多少不同的操作系统下面运行?
UNIX. 就是它. 尽管如此,还是有很多vi的变种运行在不同的操作系统上. 我就在以下
一些操作系统上用过vi: UNIX, DOS, OS/2, MAC SYSTEM 7.(后面有一个有关细节的列表)
\r\n<P>1.4 - 好吧, 你说服了我. 我决定开始使用vi. 我该从哪儿开始?
好吧, 狡猾的家伙. 关于vi有很多很好的书:大多数讲UNIX的书至少有一章给了vi,而且
有不少是专门讲vi的书.我没有什么偏爱. 所以你最好是问问你们那儿的vi高手们他们
是从哪儿学来的. 还有,到处试. 用vi打开一个不重要的文档(你的论文不象是个学vi的
好实验品),然后再到处. 我无法想象有人学习vi却不花相当多的时间去到处试试. 记住:
如果你有些地方不明白了, 只要敲两次<Esc>键,你就又回到命令模式下了. 我要提到的
一点是,我想在这里提比较合适,就是如果要成为系统管理员或者其他对UNIX配置
做什么修改的话,最好是学学ed或者ex,因为有些版本的UNIX没有把vi放在根分区里面,
这样你就可能无计可施了. ed是个不错的选择.
\r\n<P>1.5 - vi有其他一些可用的变种吗?
只能列出一部分:STvi (STevie), elvis, vile, vim, 和nvi, xvi.
elvis适用于:Amiga, DOS, OS/2, Unix, VMS, Atari.
STevie适用于: Atari ST, DOS, Unix, Mac System 7.
Mac System 7可以在很多info-mac的镜象站点获取,在/info-mac/text下.
(例如<A href=\"ftp://ftp.hawaii.edu/\"><FONT color=#0000ff>ftp.hawaii.edu</FONT></A>)
nvi是将和BSD 4.4捆绑在一起的vi.
vim适用于: Amiga, DOS, Mac System 7, Unix.
Amiga, DOS,和源码可以在以下站点换取:ftp.fu-berlin.de /misc/editors/vim
Mac System 7可以在很多info-mac的镜象站点获取,在/info-mac/text下.
(例如<A href=\"ftp://ftp.hawaii.edu/\"><FONT color=#0000ff>ftp.hawaii.edu</FONT></A>)
vile适用于: DOS, OS/2, Unix, VMS.
xvi适用于: DOS, Unix.
vi的变种之间很有很多差异.很多都改进了vi,大多数都可以使用在这个文档
种列出的命令,但是有一些不同的地方.更进一步的细节,你可以参考这些变
附带的相应的文档.
\r\n<P>2.0 - vi入门
对vi的初学者来说,有些基本的提示.第一,任何时候,手头都要有一份命令摘要.
我们将在后面给出一个快速参考/命令摘要. 第二, 找一本vi方面的比较好的书.
这个文档不是学vi的最佳途径(最起码现在还不是),我不敢保证这个文档能教会一个
对vi一无所知的人, 而很多书已经做到了这一点. 但是,我们这里还是给出了不少
提示. 对选择书籍来说,有一个标准的原则:买之前一定要仔细阅读. 要了解这本书
对你是否有意义.确信它能在你练习vi的时候有用. 和其他的书做个比较 -- 不管怎样,
vi可能让你感到非常莫名其妙, 而且你要确信这么一点:是书让你糊,而不是
你低估了学vi的难度.
还有, 找一些诸如\"学vi\"(vilearn),\"vi向导\"(vitutor)之类的软件来帮助你掌握
vi的基本知识.
\r\n<P>2.1 - 有什么游戏帮助我们学习vi吗?
这似乎很无聊, 但是事实上UNIX系统里面有不少游戏可以帮助你学习使用vi.这些帮助
主要是一些基本知识. 虽然我还不知道有哪个游戏可以帮你学习vi的所有命令, 但我
确实知道有一些可以帮助你学习使用 hjkl来移动光标. NetHack,一个类Rogue的游戏,
就对这非常有帮助. 而且它是一个很大的游戏,能玩很长一段时间. 我没有贬低其他游戏
的意思,这些游戏是: rogue, moria, omega, worm, snake.)
\r\n<P>2.2 - 命令模式和插入模式有什么区别?
vi将命令模式和插入模式区分开来,这经常被认为是vi的一个大问题,但往往这也被认为是
vi的优势所在. 理解其中的区别是掌握vi的关键.vi启动时,开始处于命令模式;在这种模式
下,我们可以在文件中到处移动,改变文本的某个特定区域, 剪切, 复制和粘贴文本,还有更
多. 插入模式是指用户可以真正插入文本.换句话说,命令模式是用来在文件中移动,而插入
模式是用来在文件中键入文本. 有些命令,例如: a, i, c, C, O, o和其他一些可以从命令
模式切换到插入模式. <Esc>键或者^C(CRTL+C)可以脱离插入模式而返回到命令模.
你要适应这种差别. 它使得vi区别于其他的编辑器. 它也使你能在你的手不离开标准
键盘做很多事情.
\r\n<P>2.3 - 等等,我的键盘没有<Esc>键,我该怎么办?
试试敲 ^[(CTRL+[). 如果你的键盘有一个<Meta>键,再试试它.如果还不行,再试试^3.
\r\n<P>2.4 - 那些~s是什么东西?
它们仅仅是用来让你知道你的文档末尾在哪儿.实际上它们并不在你的文档里面,所以
你用不着担心它们.
\r\n<P>2.5 - 我无法习惯用 hjkl, 你有什么建议吗?
首先,如果你的终端设置正确而且你连接的也没有问题的话,你可以使用箭头键.但是,
如果你认为你要经常使用vi,那么最好是习惯使用 hjkl,因为它们敲起来更. 而且,
有时候连接出问题了,使得ESC序列都可能丢失了.(这样你可能就无法使用箭头键了--译注)
\r\n<P>2.6 - 我如何才能不存盘就退出?
:q!可以做到这一点. 如果vi看起来冻住了,确信你没有错敲了个 ^S. 敲^Q可以解开^S.
\r\n<P>2.7 - 我怎样插入一个文件?
:r <文件名>
例如,要插入文件/etc/motd, 可以敲 :r /etc/motd.
这将把文件插入到光标处.如果你在r前面指定了一个数字,那么这条命令将把文件插入
到那个位置.
\r\n<P>2.8 - 我怎样查找文本?
/<文本>将向前查找, ?<文本>将向后查找. ??或者//将重复上次查找. 在UNIX下,这已经
是个可爱的标准用法了. 而且, 在vi中, n将查找文本下一次的出现位置. N重复上次查找,
不过逆转了查找的方向. 在查找中可以使用规范.
\r\n<P>2.9 - 我怎样搜索一个控制序列?
/^V^<序列>
^V会告诉vi照字面理解下一个字符,不要把它看作是一条命令.
\r\n<P>2.10 - 我怎样重新格式化文本?
如果你的计算机有一个名叫fmt的程序, 你要做的仅仅是在命令模式下面敲!}fmt(记住,
不要在前面加. 这可以重新格式化你的文件,从光标所在的位置一直到当前段落的结尾.
如果你的机器里面没有fmt这个程序, 你就得去找个类似的软件了(我记得在公共域里面
有不少这样的程序,但是我对此了解不多)
\r\n<P>2.11 - 我怎样复制文本?
这有点复杂.把这节拿出来,多看几遍;还有,一定要多做实验.
\"<字母>yy可以把一行文本拷贝到寄存器中(这里的寄存器是vi的术语,指可以存放剪切和
拷贝下来的东西的地方), <字母>里面的字母必须是a到z之间的一个. \"<字母>dd可以把
一行剪切下来放到寄存器里面. 你可以在yy或者dd前面用数字指明要拷贝或者剪切的
行数.如果<字母>中的字母是大写的话,意味着把文本插入到寄存器中已有的文本之前.
\"<字母>p把文本插入到光标之后,\"<字母>P把文本插入到光标之前.如果寄存器中含有某
一行的开头或结尾,这一行将会被放到另一合适的行. Y是yy的快捷方式. 还有, y$, yH,
yM,等等,都是可以用的.d命令也是一样的.如果要快速的剪切和粘贴, 你就无须指定寄存器
了.如果这样的话,你就不能往寄存器里面添加文本了.而且只要有一个删除命令的话,
寄存器中的东西就没有了(包括x命令). 举例来说,如果要移动上一段的话,你可以把光标
移到段落的开头,敲\"a13dd,再把光标移到你想要放文本的地方,敲\"ap,就可以把那段文本
放到光标所在的行后面. 现在,大概你想要剪切和粘贴文本到不是行末尾的区域去.我们
来看如何做到这一点:我们可以使用 m<字母> 命令来标记一个区域,这个字母可以和
剪切/粘贴寄存器的字母相,因为它们是保存在内存中的不同位置. 然后,
敲\"<寄存器>`<字母>[yy或者dd], 这里的寄存器就是要保存文本的那个寄存器,<字母>
是用来标记的,yy和dd是你的操作.
\r\n<P>2.12 - 啊! 我刚才敲了一个dG,然后我的论文就没有了! 我该怎么办?
(或者,我刚才犯了个错误,我该怎么办?)
u可以撤消你刚才的操作.U可以撤消你对当前行的修改(当然,一行对于一篇论文来说当然
很不够了). :e!可以不保存修改而重新把你的文件调进来. 还有,你删除的文本都保存在从
0到9编号的寄存器里.所以,\"<n>p就可以把上第n次的删除文本粘贴出来.你可以按如下的
方法迅速地查看所有删除的文. 先试一个,不对的话,敲u,再试下一个.(为加速这个过程,
这时vi中的.命令和通常的用法不一样了.它不是重复上次操作,而是试下一个寄存器,这样
你要做的无非就是: \"1p u . u .,直到你撤消了你想撤消的删除操作)
\r\n<P>2.13 - 我正在写我的论文,被告知我必须将每一节都放在不同的文件里,我该怎么办?
:[m],[n]w <文件名>可以将从第m行到第n行之间的文本保存到<文件名>所指定的文件中.
这种行序号方法几乎在所有的:命令下都可以使用. 如果你用命令:[m],[n] w >><文件名>,
这些文本将添加到文件的后面.
\r\n<P>2.14 - 所有的:命令都是怎样处理的?
:后面的命令都是从ex编辑器里面过来的. 这就给vi加入了很多灵活性,也使vi功能更强
大. 例如, 有很多的方法可以用来查找和替换,它们有很多的类似地方(事实上,它们在
某种意义上说都是一样的)
\r\n<P>3.0 - 怎样查找和替换?
有很多方. 最简单的是:
:s/old/new/g, 但是,这仅对当前行起作用..., 所以,我们用
:%s/old/new/g, 更一般的,我们还可以用
:[范围]s/old/new/[cg],这里,[范围]是任意的行范围,包括行号,$(文件末尾),.(当前行),
%(当前文件),或者两个行号之间加个破折号(或者可以这样: .,+5,这表示下面5行).
[cgi]是c,g,i中间的一个或者什么也没有.c告诉vi每次替换的时候要给提示,g是说对
所有一行中出现的地方都做替换.i则是指在查找时不区分大小写.如果最后一个斜杠(/)
后面没有东西的话,那么vi只替换在行中第一次匹配的地方. 我比较喜欢这样做:
:g/foobar/s/bar/baz/g, 这个命令首先搜寻foobar,然后把它变成foobaz. 它没有改变
jailbars, 而其他的一些命令可能会改变jailbars. 这是我的方法,但是可能比较难记.
当然,你还可以在查找的的时候使用正规式,以及在替换文本的时候使用其他一些命令.如果
你在正规式里用\\(和\\)来剥离一个序列的话,你会发现你可以做很多好玩的事情. 例如:
:g/\\(foo\\)\\(bar\\)/s/\\2/\\1baz/g 将foobar替换成foobaz
还有一些特殊的序列:
& 所有查找时匹配到的东西
\\[1-9] 1到9号用\\(和\\)括起来的东西
\\u 下一个字符将被变成大写.
\\U 以后的字符都变成大写,直到遇到\\e或\\E
\\l 下一个字符将被变成小.
\\L 以后的字符都变成大写,直到遇到\\e或\\E
\\[Ee] 更改大小写的选择区域的终点
\r\n<P>3.1 - 我怎样在vi中运行一个程序?
:!命令 可以在vi中运行程序. :sh会启动一个交互式的外壳(SHELL).在这个外壳
里面, 如果你愿意,你还可以再次运行vi. 当你在编辑Makefiles和配置文件来编译
某个程序的时候,这可能比较有用. 这比:e优越之处在于它无须保存文件,而且如果
你退出外壳的时候,vi还回到原来的地方.(当然,我还是建议你先保存一下文件)
\r\n<P>3.2 - 啊! 我正在写我的论文, 系统崩溃了! 怎么办?
不要怕! 你会收到一封电子邮件,里面就是你的论文.敲入vi -r <文件名>
(这个文件名就是系统崩溃时你正在编辑的文件)你就可以恢复出你的论文来.只敲
vi -r将把所有可能恢复的文件都列出来.
\r\n<P>3.3 - 有没有使vi对程序员更友好的窍门?
:set ai可以让vi自动对齐.
:set sw=#,#是移动的宽度(shiftwidth),或者说TAB键的宽度(tabwidth);你可以
用<<或者>>命令来左移或右移某一行. 还有, 你可以使用 <%或>%来将{,(或[等符号
括起来的文本都左移或右移;这时候,你必须把光标放在这些符号({,(或[)上面.
:set sm会在你敲},]或)显示出对应匹配的{,[或(来.
:set lisp会对lisp编程有些帮助. ()被移到s表达式(s-expressions)外面,如果
原子(atoms)没有停止则{}将被移走.
\r\n<P>3.4 - 宏 -- 我怎样写宏?
:map <lhs> <rhs>, 其中<lhs>最多10个字符,<rhs>最多100个字符. 以后,如果
你敲了<lhs>,vi就会用<rhs>来取代它.所有的宏都是在命令模式下开始的,但是可以
在你想在的模式下终止. 记住,在你想用的控制字符前面加上^V.
:unmap <lhs>将删除这个宏. :map!<lhs> <rhs> 使得<lhs>将<rhs>插入到文档
中去.
\r\n<P>3.5 - 我怎样将一个功能键定义成一个宏?
如果<lhs>是#n,n是0-9之间的一个数,那么这个宏就映射成某一个功能键了.(你
可以试一下F1-F10之间的键--译者)
\r\n<P>3.6 - 有没有办法缩写文本?
当然了. 这可是vi呀,它能做任何事情!
:ab email <A href=\"mailto:ellidz@midway.uchicago.edu\"><FONT color=#0000ff>ellidz@midway.uchicago.edu</FONT></A> 可以在你敲完email后,把那个没有缩写
的文本插入到文件中. :una email取消缩写.
\r\n<P>3.7 - 我怎样在当前文档中做拼写检查?
这儿有一个宏可以做到这一点. 这些应该放在你的.exrc文件中(后面我们将对.exrc
进一步讨论). 它是一个相当简单的宏. 它仅仅是调用ispell来处理当前文件.当然,你
的系统里面一定得有ispell这个程序. 使用它的时候,只需要敲个V键就行了(因为vi并
没有用V,所以V是一个比较合适的键)
\r\n<P>map V :w^M:!ispell % ^M:e!^M^M
第二个^M使你在拼写检查完之后无须敲回车就可以到vi中.
(译注, 在我的系统里,没有ispell,只有spell,我用它替换了ispell,工作的不错;还有,
^M不是两个字符,而是一个字符,通过^V^M敲进去的;另外,我个人认为第二个^M还是不要
的好,因为直接回到vi后你就无法看到拼写检查的结果了)
\r\n<P>3.8 - 我手头有一个硬拷贝的终端, 我还能用vi吗?
好了,好了. 我并认为有人会真的问这个问题.这个问题太偏了,我们大可不必理
它.(而且,它回答了一个非常普通的问题)
vi启动的时候处于一种特殊的模式下面,叫做\"开放模式\"; 在这种状态下,事情或多或少
的有些不同. 删除的字符在你面前显示成一\\\',vi会认为你的终端窗口只有一行. ^r
可以把当前行重新输出. z则把当前行周围的窗口重画一遍.
\r\n<P>3.9 - 好了,是不是处在开放模式下的原因呀?! 但是我现在没有用硬拷贝终端,它还是在
开放模式呀?
这儿的问题就是vi没有认出你用的终端的类型. 于是它假定你有的是个最烂的终端,
所以它决定依然处在开放模式下.这似乎没什么用处.因为没有多少人喜欢开放模式,但是
开放模式还是需要知道你的终端的一些最起码的信息的. 现在,我们来看如何解决这个
问题.我们有可能把它分成几种特殊的情形,但是,一般情况下, 这并没有用处. 如果你
直到你的终端的类, 你可以在UNIX提示符下面设置终端类型(在CSH及其变种下面,使用
命令setenv TERM <终端类型>;在SH及其变种下面,使用命令TERM=<终端类型>;
export TERM) 最好你能把上面的命令写在.profile文件或者.cshrc文件里面,这样你
一登录它就自动地给你设置好了.(当然,你应该知道如何使用ed,或者你能在UNIX提示符
下面设置好终端类型以便能使用vi, 这样你才有可能去编辑这些文件).如果你确实不
知道你地终端类型,试一试vt100.现在大多数地终端或者终端仿真器都能仿真vt100.
如果这还不能生效的话,你只好去找个高手来帮你了.
\r\n<P>4.0 - vi档案的在线帮助在哪儿?
有一个vi的FAQ,其中列出了vi档案的所有在线文件. 同时它还列出了这些文档
的镜象站点. 最主要的一个地址是alf.uib.no,但是这些文档在很多很多地地方
都保存着. vi-archive faq把它们都给列出来了.你在下载这些文件之前一定要
核对一下这个FAQ.因为很有可能有一个站点比去挪威的站点更近更快些.
一个镜象站点是cs.uwp.edu/pub/vi, 另一个是monu6.cc.monash.edu.au/pub/Vi,
这些站点上有很多有关vi的文件,还有一些vi的变种版本;当然,UCB版本的vi是
肯定有的, 还有许多的宏.
\r\n<P>5.0 - 好玩的vi诀窍,好玩的宏
这一节主要讲述一些无聊的诀窍和一些无聊的.事实上,任何vi的诀窍和宏我们
都欢迎,只要它们不是过分冗长. 如果有人向我建议而我也认为确实值得加的话,
我会考虑加进去的.
\r\n<P>5.1 - 好玩的vi诀窍
xp 删除光标下的字符,再把粘贴到后面去.换句话说,它交换了当前两个字符
的位置. ddp 和xp类似,不过是交换两行的位置.
uu 撤消和重复上次所做的修改.(这可以使你不改变什么东西就可以到你上次所
做的修改处)
\r\n<P>5.2 - 好玩的宏
和垂直上方的字符交换位置
map * kxjphxkP
\r\n<P>折行
map g $80|F r
(译注,我对这条宏表示疑问!)
\r\n<P>改变大多数单词的大小写
map v ywmno:s/./\\~/g
(译注,这条好象也不大对!)
\r\n<P>在当前的单词周围加上`和\'
map *` i`\'
在当前的单词周围加上\'和\'
map *\' i\'\'
在当前的单词周围加上\"和\"
map *\" i\"\"
(这几条也太无聊了吧--译注)
在当前的单词周围加上``和``
map! `` `\'
(咦,好象又有问题?--译注)
\r\n<P>从光标处把当前行分开,在下一行开头加上一个>号(例如,引用USENET).如果加上了单词的折行
功能那么最后一个单词可能被折在第一行.
map g may0O`ay$:s/./ /g
(不对吧--译注)
\r\n<P>插入一个字符
map g i$^[r
\r\n<P>6.0 - 依字母顺序的vi快速参考
... 是指有些东西需要在命令之前或之后指明.这通常是说光标的移动键
(h,j,k,l,w,b等等)或者是指行号.
# (这里#代表一个数字) 执行n次后面的命令...
: 进入ex模式
) 下一句
( 上一句
} 下一段
{ 上一段
]] 下一节
[[ 上一节
0 行的开头
$ 行的末尾
^ 行的第一个非空白字符
+ 下一行的开头
- 上一行的开
(空格) 下一个字符
(回车) 下一行
/ 向前搜索
? 向后搜索
% 查找当前小(中,大)括号的匹配字符
, 逆向重复上一个f,F,t或T操作
; 重复上一个f,F,t或T操作
. 重复上一个操作
` 转到标记处
\' 转到标记所在行的开头
`` 查找前回到上一个做标记的地方
\'\' 查找前回到上一个做标记所在行的开头
~ 切换字符的大小写
\" 保存到寄存器中
!! 重复上一次SHELL命令
! 把后面的文本送给命令, 取代输出(例如, !}fmt把当前的段落
送给命令fmt处理,然后用fmt返回的东西替换输出.)
>> 右移当前段落一个移动宽度(shiftwidth)
<< 左移当前段落一个移动宽(shiftwidth)
>% 从当前到匹配小(中,大)括号之间的文本右移
<% 从当前到匹配小(中,大)括号之间的文本左移
(似乎漏了一个符号|, 移动到某一列----译注)
a 在当前位置之后添加
A 在当前行的末尾添加
^a 没有使用
b 上一个单词的开头
B 上一个单词的开头,忽略标点符号
^b 上移一屏
c 覆盖...
C 覆盖到行末尾
^c 终止插入模式,在命令模式没有用
d 删除...
D 删除到行末尾
\r\n<P>^d 下移半屏,如果在插入模式下则移到上一个移动宽度(ShiftTab)处
e 单词的末尾
E 单词的末尾,忽略标点符号
^e 屏幕下卷一行
f 查找...
F 向后查找...
^f 下移一屏
g 未用
G ...跳至[缺省是到文件末尾]
^g 显示状态栏
h 左移
H 屏幕上的第一行
^h 在插入模式下是退格,命令模式下是左移
i 在当前的位置前面插入
I 在本行的第一个非空白字符前面插入
^i 插入模式下是制表键,命令模式下未用
j 下移
J 把下一行合并到本行
^j 命令模式下是下移,插入模式下是建一个新行
k 上移
K 未用
^k 未用
l 右移
L 屏幕中的最后一行
^l 重绘屏
m 把当前位置标记到寄存器中
M 屏幕的中间行
^m 回车
n 重复上次查找
N 逆向重复上次查找
^n 命令模式下是下移
o 在当前行的下面建一个新行
O 在当前行的上面建一个新行
^o 未用
p 在当前行的下面粘贴
(译注--应为在当前位置的后面粘贴)
P 在当前行的上面粘贴
(译注--应为在当前位置的前面粘贴)
^p 命令模式下是上移
q 未用
Q 退出并且启动ex
^q 未用
r 覆盖当前的字符
R 在插入模式下一直覆盖字符
^r 在命令模式下面重绘屏幕
s 替换
S 替换整行
t 到...
T 向后到...
^t 移到下一个移动宽度(shifttab)处
u 撤消上一次操
U 撤消对本行的所有修改
^u 上移半屏
v 未用
V 未用
^v 未用
w 下一个单词的开头
W 下一个单词的开头,忽略标点符号
^w 命令模式下未用,在插入模式下是到上一个单词的开头处
x 删除当前字符
X 删除前一个字符
^x 未用
y 复制...
Y 复制整行
^y 屏幕上卷一行
z 重新配置当前行周围的屏幕
ZZ 保存之后退出
^z 未用
(译注--在命令模式下,^z执行了UNIX暂停操作)
6.1 - 命令模式的输入选项(:命令)
(注: 这不是一个规范的列表,, 我只是列出了一些最重要的命令)
:r <文件> 把<文件>读入到当前文档
:r !<命令> 把<命令>的输出插入到当前文本中
:nr <文件> 把<文件>插入到第n行
:!<命令> 运行<命令>,然后返回
:sh 转到SHELL
:so <文件> 读取<文件>,再执行文件里面的命令
(译注--文件中的命令应该都是一些ex命令)
保存之后退出
:wq 保存之后退出
:l1,l2w <文件>把第l1和第l2行之间的文本写到<文件>中去,如果没有指定<文件>,
vi就假定是当前文件,如果没有指定l1,l2,就假定是整个文件(就成了:w)
:w >> <文> 添加到<文件>末尾. 也可以使用行号
:w! 覆盖当前文件
:q 退出
:q! 不存盘就退出
:e <文件> 不离开vi编辑<文件>
:e! 重新编辑当前文件,忽略所有的修改
:n 编辑下一个文件
:e +n <文件> 从第n行开始编辑<文件>,如果超过了末尾,就从末尾开始编辑
:e# 编辑替换文件(如果使用了命令:e<文件>,替换文件就指的是原始文件)
:args 显示所有要编辑的文件
:rew 重新回到第一个编辑的文档
:map m n 创建一个宏(使 m 做 n)
:map! m n 创建一个插入模式的宏(使 m 做 n)
:unmap m 删除宏m
:unmap! m 删除插入模式的宏m
:ab <1> <2> 缩写,敲<1>的时候<2>取代
:unab <1> 取消缩写<1>
:set <选项> 设置<选项>...
\r\n<P>6.2 - 设置选项(set) 显示所有的制
magic magic 可以使用更多的正规表达式
mesg mesg 允许向终端发送消息
number (nu) nonumber 显示行号
open open 允许开放和可视化
optimize (opt) optimize 优化吞吐量,打印时不发回车
paragraphs= (para=) IPLPPPQPPLIbp 设置{ & }的分界符
prompt prompt 命令模式下的输入给出:的提示符
readonly (ro) noro 除非用!号否则不准保存文件
redraw noredraw 当编辑的时候重绘屏幕
remap remap 允许宏指向其他的宏
report= 5 如果影响的行数>这个数的话就报告
scroll 1/2 window 下卷屏幕时滚动屏幕的数目,
同样这也z命令输出的行数(z 输出2倍滚屏的大小)
sections= SHNHH HU 定义节的末尾(当使用命令[[ 和 ]] 时)
shell= (sh=) /bin/sh 缺省的SHELL,如果设置了环境变量SHELL的话,就使用变量
shiftwidth= (sw=) 8 当使用移动(shift)命令时移动的字符数
showmatch (sm) nosm 显示{, }, (, , [, 或者 ] 的匹配情况
showmode noshowmode 显示你处在什么模式下面
slowopen (slow) 插入之后不要立刻更新显示
tabstop= (ts=) 8 设置制表停止位(tabstop)的长度
taglength= (tl=) 0 重要标记的字符个数(0表示所有的字符)
tags= tag, /usr/lib/tags 定义包含标记的文件路
term= 设置终端类型
terse noterse 显示简短的错误信息
timeout (to) timeout 一秒钟后键盘映射超时
ttytype= 设置终端类型
warn warn 显示\"No write since last change\"信息
window= (w=) 可视模式下窗口的行数
wrapmargin= (wm=) 0 右边距,大于0的话最右边的单词将折行,留出n个空白位置
wrapscan (ws) ws 查找到文件尾后再重头开始
writeany (wa) nowa 可以保存到任意一个文件去
\r\n<P>(译注--这些选项在各种vi版本中都基本上大同小异,以SunOS带的vi为例,它没有这里列
出来的open选项, scroll的参数值也不同,还多出来一些选项,如flash,modelines,
novice,tagstack等等)
\r\n<P>7.0 - 建立 .exrc文件
所有命令输入模式下的命令(即 :命令)都可以在.exrc文件中使用,在.exrc中的命令在
: empty register \"q\"
----------------------------------------
\" Useful tricks
\"<A href=\"mailto:ayy@a\"><FONT color=#0000ff>ayy@a</FONT></A> : execute \"Vim command\" in a text file
yy@\" : same thing using unnamed register
u@. : execute command JUST typed in
----------------------------------------
\" Get output from other commands (requires external programs)
:r!ls.exe : reads in output of ls
!!date : same thing (but replaces/filters current line)
\" Sorting with external sort
:%!sort -u : use an external program to filter content
:\'a,\'b!sort -u : use an external program to filter content
!1} sort -u : sorts paragraph (note normal mode!!)
----------------------------------------
\" Multiple Files Management (Essential)
:bn : goto next buffer
:bp : goto previous buffer
:wn : save file and move to next (super)
:wp : save file and move to previous
:bd : remove file from buffer list (super)
:bun : Buffer unload (remove window but not from list)
:badd file.c : file from buffer list
:b 3 : go to buffer 3
:b main : go to buffer with main in name eg main.c (ultra)
:sav php.html : Save current file as php.html and \"move\" to php.html
:sav! %<.bak : Save Current file to alternative extension (old way)
:sav! %:r.cfm : Save Current file to alternative extension
:sav %:s/fred/joe/ : do a substitute on file name
:sav %:s/fred/joe/:r.bak2 : do a substitute on file name & ext.
:!mv % %:r.bak : rename current file (DOS use Rename or DEL)
:e! : return to unmodified file
:w c:/aaa/% : save file elsewhere
:e # : edit alternative file (also cntrl-^)
:rew : return to beginning of edited files list (:args)
:brew : buffer rewind
:sp fred.txt : open fred.txt into a split
:sball,:sb : Split all buffers (super)
:scrollbind : in each split window
:map <F5> :ls<CR>:e # : Pressing F5 lists all buffer, just type number
:set hidden : Allows to change buffer w/o saving current buffer
----------------------------------------
\" Quick jumping between splits
map <C-J> <C-W>j<C-W>_
map <C-K> <C-W>k<C-W>_
----------------------------------------
\" Recording (BEST TIP of ALL)
qq # record to q
your complex series of commands
q # end recording
@q to execute
@@ to Repeat
5@@ to Repeat 5 times
\" editing a register/recording
\"qp :display contents of register q (normal mode)
<ctrl-R>q :display contents of register q (insert mode)
\" you can now see recording contents, edit as required
\"qdd :put changed contacts back into q
@q :execute recording/register q
\" Operating a Recording on a Visual BLOCK
1) define recording/register
qq:s/ to/ from/g^Mq
2) Define Visual BLOCK
V}
3) hit : and the following appears
:\'<,\'>
4)Complete as follows
:\'<,\'>norm @q
----------------------------------------
\"combining a recording with a map (to end up in command mode)
nnoremap ] @q:w!<bar>bd
----------------------------------------
\" Visual is the newest and usually the most intuitive editing mode
\" Visual basics
v : enter visual mode
V : visual mode whole line
<C-V> : enter VISUAL BLOCK mode
gv : reselect last visual area (ultra)
o : navigate visual area
\"*y : yank visual area into paste buffer
V% : visualise what you match
V}J : Join Visual block (great)
V}gJ : Join Visual block w/o adding spaces
----------------------------------------
\" Delete first 2 characters of 10 successive lines
0<c-v>10j2ld
----------------------------------------
\" how to copy a set of columns using VISUAL BLOCK
\" visual block (AKA columnwise selection) (NOT BY ordinary v command)
<C-V> then select \"column(s)\" with motion commands (win32 <C-Q>)
then c,d,y,r etc
----------------------------------------
\" how to overwrite a visual-block of text with another such block
Pick the first block: ctrl-v move \"ay
Pick the second block: ctrl-v move c ctrl-o \"aP <esc>
----------------------------------------
\" _vimrc essentials
:set incsearch : jumps to search word as you type (annoying but excellent)
:set wildignore=*.o,*.obj,*.bak,*.exe : tab complete now ignores these
:set shiftwidth=3 : for shift/tabbing
:set vb t_vb=\". : set silent (no beep)
:set browsedir=buffer : Maki GUI File Open use current directory
----------------------------------------
\" launching Win IE
:nmap ,f :update<CR>:silent !start c:\\progra~1\\intern~1\\iexplore.exe <A href=\"file://%:p<CR/\"><FONT color=#0000ff>file://%:p<CR</FONT></A>>
:nmap ,i :update<CR>: !start c:\\progra~1\\intern~1\\iexplore.exe <cWORD><CR>
----------------------------------------
\" FTPing from VIM
cmap ,r :Nread <A href=\"ftp://209.51.134.122/public_html/index.html\"><FONT color=#0000ff>ftp://209.51.134.122/public_html/index.html</FONT></A>
cmap ,w :Nwrite <A href=\"ftp://209.51.134.122/public_html/index.html\"><FONT color=#0000ff>ftp://209.51.134.122/public_html/index.html</FONT></A>
gvim <A href=\"ftp://www.somedomain.com/index.html\"><FONT color=#0000ff>ftp://www.somedomain.com/index.html</FONT></A> # uses netrw.vim
----------------------------------------
\" appending to registers (use CAPITAL)
\" yank 5 lines into \"a\" then add a further 5
\"a5yy
10j
\"A5yy
----------------------------------------
[I : show lines matching word under cursor <cword> (super)
----------------------------------------
\" Conventional Shifting/Indenting
:\'a,\'b>>
\" visual shifting (builtin-repeat)
:vnoremap < <gv
:vnoremap > >gv
\" Block shifting (magic)
>i{
>a{
\" also
>% and <%
----------------------------------------
\" Redirection & Paste register *
:redir @* : redirect commands to paste buffer
:redir END : end redirect
:redir >> out.txt : redirect to a file
\" Working with Paste buffer
\"*yy : yank to paste
\"*p : insert from paste buffer
\" yank to paste buffer (ex mode)
:\'a,\'by* : Yank range into paste
:%y* : Yank whole buffer into paste
:.y* : Yank Current line to paster
\" filter non-printable characters from the paste buffer
\" useful when pasting from some gui application
:nmap <leader>p :let @* = substitute(@*,\'[^[:print:]]\',\'\',\'g\')<cr>\"*p
----------------------------------------
\" Re-Formatting text
gq} : Format a paragraph
gqap : Format a paragraph
ggVGgq : Reformat entire file
Vgq : current line
\" break lines at 70 chars, if possible after a ;
:s/.\\{,69\\};\\s*\\|.\\{,69\\}\\s\\+/&\\r/g
----------------------------------------
\" Operate command over multiple files
:argdo %s/foo/bar/e : operate on all files in :args
:bufdo %s/foo/bar/e
:windo %s/foo/bar/e
:argdo exe \'%!sort\'|w! : include an external command
----------------------------------------
\" Command line tricks
gvim -h : help
ls | gvim - : edit a stream!!
cat xx | gvim - -c \"v/^\\d\\d\\|^[3-9]/d \" : filter a stream
gvim -o file1 file2 : open into a split
\" execute one command after opening file
gvim.exe -c \"/main\" joe.c : Open joe.c & jump to \"main\"
\" execute multiple command on a single file
vim -c \"%s/ABC/DEF/ge | update\" file1.c
\" execute multiple command on a group of files
vim -c \"argdo %s/ABC/DEF/ge | update\" *.c
\" remove blocks of text from a series of files
vim -c \"argdo /begin/+1,/end/-1g/^/d | update\" *.c
\" Automate editing of a file (Ex commands in convert.vim)
vim -s \"convert.vim\" file.c
#load VIM without .vimrc and plugins (clean VIM)
gvim -u NONE -U NONE -N
\" Access paste buffer contents (put in a script/batch file)
gvim -c \'normal ggdG\"*p\' c:/aaa/xp
\" print paste contents to default printer
gvim -c \'s/^/\\=@*/|hardcopy!|q!\'
\" gvim\'s use of external grep (win32 or *nix)
:grep somestring *.php : creates a list of all matching files
\" use :cn(ext) :cp(rev) to navigate list
:h grep
----------------------------------------
\" GVIM Difference Function (Brilliant)
gvim -d file1 file2 : vimdiff (compare differences)
dp : \"put\" difference under cursor to other file
do : \"get\" difference under cursor from other file
----------------------------------------
\" Vim traps
In regular expressions you must backslash + (match 1 or more)
In regular expressions you must backslash | (or)
In regular expressions you must backslash ( (group)
In regular expressions you must backslash { (count)
/fred\\+/ : matches fred/freddy but not free
/\\(fred\\)\\{2,3}/ : note what you have to break
----------------------------------------
\" \\v or very magic (usually) reduces backslashing
/codes\\(\\n\\|\\s\\)*where : normal regexp
/\\vcodes(\\n|\\s)*where : very magic
----------------------------------------
\" pulling objects onto command/search line (SUPER)
<C-R><C-W> : pull word under the cursor into a command line or search
<C-R><C-A> : pull WORD under the cursor into a command line or search
<C-R>- : pull small register (also insert mode)
<C-R>[0-9a-z] : pull named registers (also insert mode)
<C-R>% : pull file name (also #) (also insert mode)
<C-R>=somevar : pull contents of a variable (eg :let sray=\"ray[0-9]\")
----------------------------------------
\" manipulating registers
:let @a=@_ : clear register a
:let @a=\"\" : clear register a
:let @*=@a : copy register a to paste buffer
map <f11> \"qyy:let @q=@q.\"zzz\"
----------------------------------------
\" help for help (USE TAB)
:h quickref : VIM Quick Reference Sheet (ultra)
:h tips : Vim\'s own Tips Help
:h visual<C-D><tab> : obtain list of all visual help topics
: Then use tab to step thru them
:h ctrl<C-D> : list help of all control keys
:helpg uganda : grep HELP Files use :cn, :cp to find next
:h :r : help for :ex command
:h CTRL-R : normal mode
:h /\\r : what\'s \\r in a regexp (matches a <CR>)
:h <A href=\"file://zs/\"><FONT color=#0000ff>\\\\zs</FONT></A> : double up backslash to find \\zs in help
:h i_CTRL-R : help for say <C-R> in insert mode
:h c_CTRL-R : help for say <C-R> in command mode
:h v_CTRL-V : visual mode
:h tutor : VIM Tutor
<C-[>, <C-T> : Move back & Forth in HELP History
gvim -h : VIM Command Line Help
----------------------------------------
\" where was an option set
:scriptnames : list all plugins, _vimrcs loaded (super)
:verbose set history? : reveals value of history and where set
:function : list functions
:func SearchCompl : List particular function
----------------------------------------
\" making your own VIM help
:helptags /vim/vim64/doc : rebuild all *.txt help files in /doc
:help add-local-help
----------------------------------------
\" running file thru an external program (eg php)
map <f9> :w<CR>:!c:/php/php.exe %<CR>
map <f2> :w<CR>:!perl -c %<CR>
----------------------------------------
\" capturing output of current script in a separate buffer
:new | r!perl # : opens new buffer,read other buffer
:new! x.out | r!perl # : same with named file
:new+read!ls
----------------------------------------
\" create a new buffer, paste a register \"q\" into it, then sort new buffer
:new +put q|%!sort
----------------------------------------
\" Inserting DOS Carriage Returns
:%s/$/\\<C-V><C-M>&/g : that\'s what you type
:%s/$/\\<C-Q><C-M>&/g : for Win32
:%s/$/\\^M&/g : what you\'ll see where ^M is ONE character
----------------------------------------
\" automatically delete trailing Dos-returns,whitespace
autocmd BufRead * silent! %s/[\\r \\t]\\+$//
autocmd BufEnter *.php :%s/[ \\t\\r]\\+$//e
----------------------------------------
\" perform an action on a particular file or file type
autocmd VimEnter c:/intranet/note011.txt normal! ggVGg?
autocmd FileType *.pl exec(\'set fileformats=unix\')
----------------------------------------
\" Retrieving last command line command for copy & pasting into text
i<c-r>:
\" Retrieving last Search Command for copy & pasting into text
i<c-r>/
----------------------------------------
\" more completions
<C-X><C-F> :insert name of a file in current directory
----------------------------------------
\" Substituting a Visual area
\" select visual area as usual (:h visual) then type :s/Emacs/Vim/ etc
:\'<,\'>s/Emacs/Vim/g : REMEMBER you dont type the \'<.\'>
gv : Re-select the previous visual area (ULTRA)
----------------------------------------
\" inserting line number into file
:g/^/exec \"s/^/\".strpart(line(\".\").\" \", 0, 4)
:%s/^/\\=strpart(line(\".\").\" \", 0, 5)
:%s/^/\\=line(\'.\'). \' \'
----------------------------------------
#numbering lines VIM way
:set number : show line numbers
:map <F12> :set number!<CR> : Show linenumbers flip-flop
:%s/^/\\=strpart(line(\'.\').\" \",0,&ts)
#numbering lines (need Perl on PC) starting from arbitrary number
:\'a,\'b!perl -pne \'BEGIN{$a=223} substr($_,2,0)=$a++\'
#Produce a list of numbers
#Type in number on line say 223 in an empty file
qqmnYP`n^Aq : in recording q repeat with @q
\" increment existing numbers to end of file (type <c-a> as 5 characters)
:.,$g/^\\d/exe \"normal! \\<c-a>\"
\" advanced incrementing
<A href=\"http://vim.sourceforge.net/tip_view.php?tip_id=150\"><FONT color=#0000ff>http://vim.sourceforge.net/tip_view.php?tip_id=150</FONT></A>
----------------------------------------
\" advanced incrementing (really useful)
\" put following in _vimrc
let g:I=0
function! INC(increment)
let g:I =g:I + a:increment
return g:I
endfunction
\" eg create list starting from 223 incrementing by 5 between markers a,b
:let I=223
:\'a,\'bs/^/\\=INC(5)/
\" create a map for INC
cab viminc :let I=223 \\| \'a,\'bs/$/\\=INC(5)/
----------------------------------------
\" generate a list of numbers 23-64
o23<ESC>qqYp<C-A>q40@q
----------------------------------------
\" editing/moving within current insert (Really useful)
<C-U> : delete all entered
<C-W> : delete last word
<HOME><END> : beginning/end of line
<C-LEFTARROW><C-RIGHTARROW> : jump one word backwards/forwards
<C-X><C-E>,<C-X><C-Y> : scroll while staying put in insert
----------------------------------------
#encryption (use with care: DON\'T FORGET your KEY)
:X : you will be prompted for a key
:h :X
----------------------------------------
\" modeline (make a file readonly etc) must be in first/last 5 lines
// vim:noai:ts=2:sw=4:readonly:
\" vim:ft=html: : says use HTML Syntax highlighting
:h modeline
----------------------------------------
\" Creating your own GUI Toolbar entry
amenu Modeline.Insert\\ a\\ VIM\\ modeline <Esc><Esc>ggOvim:ff=unix ts=4 ss=4<CR>vim60:fdm=marker<esc>gg
----------------------------------------
\" A function to save word under cursor to a file
function! SaveWord()
normal yiw
exe \':!echo <A href=\"mailto:\'.@0.\'\"><FONT color=#0000ff>\'.@0.\'</FONT></A> >> word.txt\'
endfunction
map ,p :call SaveWord()
----------------------------------------
\" function to delete duplicate lines
function! Del()
if getline(\".\") == getline(line(\".\") - 1)
norm dd
endif
endfunction
\r\n<P>:g/^/ call Del()
----------------------------------------
\" Digraphs (non alpha-numerics)
:digraphs : display table
:h dig : help
i<C-K>e\' : enters ?i<C-V>233 : enters ?(Unix)
i<C-Q>233 : enters ?(Win32)
ga : View hex value of any character
#Deleting non-ascii characters (some invisible)
:%s/[<C-V>128-<C-V>255]//gi : where you have to type the Control-V
:%s/[€-]//gi : Should see a black square & a dotted y
:%s/[<C-V>128-<C-V>255<C-V>01-<C-V>31]//gi : All pesky non-asciis
:exec \"norm /[\\x00-\\x1f\\x80-\\xff]/\" : same thing
#Pull a non-ascii character onto search bar
yl/<C-R>\" :
----------------------------------------
\" All file completions grouped (for example main_c.c)
:e main_<tab> : tab completes
gf : open file under cursor (normal)
main_<C-X><C-F> : include NAME of file in text (insert mode)
----------------------------------------
\" Complex Vim
\" swap two words
:%s/\\<\\(on\\|off\\)\\>/\\=strpart(\"offon\", 3 * (\"off\" == submatch(0)), 3)/g
\" swap two words
:vnoremap <C-X> <Esc>`.``gvP``P
----------------------------------------
\" Convert Text File to HTML
:runtime! syntax/2html.vim : convert txt to html
:h 2html
----------------------------------------
\" VIM has internal grep
:grep some_keyword *.c : get list of all c-files containing keyword
:cn : go to next occurrence
----------------------------------------
\" Force Syntax coloring for a file that has no extension .pl
:set syntax=perl
\" Remove syntax coloring (useful for all sorts of reasons)
:set syntax off
\" change coloring scheme (any file in ~vim/vim??/colors)
:colorscheme blue
\" Force HTML Syntax highlighting by using a modeline
\" vim:ft=html:
----------------------------------------
:set noma (non modifiable) : Prevents modifications
:set ro (Read Only) : Protect a file from unintentional writes
----------------------------------------
\" Sessions (Open a set of files)
gvim file1.c file2.c lib/lib.h lib/lib2.h : load files for \"session\"
:mksession : Make a Session file (default Session.vim)
:q
gvim -S Session.vim : Reload all files
----------------------------------------
#tags (jumping to subroutines/functions)
taglist.vim : popular plugin
:Tlist : display Tags (list of functions)
<C-]> : jump to function under cursor
----------------------------------------
\" columnise a csv file for display only as may crop wide columns
:let width = 20
:let fill=\' \' | while strlen(fill) < width | let fill=fill.fill | endwhile
:%s/\\([^;]*\\);\\=/\\=strpart(submatch(1).fill, 0, width)/ge
:%s/\\s\\+$//ge
\" Highlight a particular csv column (put in .vimrc)
function! CSVH(x)
execute \'match Keyword /^\\([^,]*,\\)\\{\'.a:x.\'}\\zs[^,]*/\'
execute \'normal ^\'.a:x.\'f,\'
endfunction
command! -nargs=1 Csv :call CSVH(<args>)
\" call with
:Csv 5 : highlight fifth column
----------------------------------------
\" folding : hide sections to allow easier comparisons
zf} : fold paragraph using motion
v}zf : fold paragraph using visual
zf\'a : fold to mark
zo : open fold
zc : re-close fold
----------------------------------------
\" displaying \"invisible characters\"
:set list
:h listchars
----------------------------------------
\" How to paste \"normal commands\" w/o entering insert mode
:norm qqy$jq
----------------------------------------
\" manipulating file names
:h filename-modifiers : help
:w % : write to current file name
:w %:r.cfm : change file extention to .cfm
:!echo %:p : full path & file name
:!echo %:p:h : full path only
:!echo %:t : filename only
:reg % : display filename
<C-R>% : insert filename (insert mode)
\"%p : insert filename (normal mode)
/<C-R>% : Search for file name in text
----------------------------------------
\" delete without destroying default buffer contents
\"_d : what you\'ve ALWAYS wanted
\"_dw : eg delete word (use blackhole)
----------------------------------------
\" pull full path name into paste buffer for attachment to email etc
nnoremap <F2> :let @*=expand(\"%:p\")<cr> :unix
nnoremap <F2> :let @*=substitute(expand(\"%:p\"), \"/\", \"\\\\\", \"g\")<cr> :win32
----------------------------------------
\" Simple Shell script to rename files w/o leaving vim
$ vim
:r! ls *.c
:%s/\\(.*\\).c/mv & \\1.bla
:w !sh
:q!
----------------------------------------
\" count words in a text file
g<C-G>
----------------------------------------
\" example of setting your own highlighting
:syn match DoubleSpace \" \"
:hi def DoubleSpace guibg=#e0e0e0
----------------------------------------
\" reproduce previous line word by word
imap ] @@@<ESC>hhkyWjl?@@@<CR>P/@@@<CR>3s
nmap ] <A href=\"mailto:i@@@<ESC>hhkyWjl?@@@<CR>P/@@@<CR>3s\"><FONT color=#0000ff>i@@@<ESC>hhkyWjl?@@@<CR>P/@@@<CR>3s</FONT></A>
\" Programming keys depending on file type
:autocmd bufenter *.tex map <F1> :!latex %<CR>
:autocmd bufenter *.tex map <F2> :!xdvi -hush %<.dvi&<CR>
----------------------------------------
\" reading Ms-Word documents, requires antiword
:autocmd BufReadPre *.doc set ro
:autocmd BufReadPre *.doc set hlsearch!
:autocmd BufReadPost *.doc %!antiword \"%\"
----------------------------------------
\" a folding method
vim: filetype=help foldmethod=marker foldmarker=<<<,>>>
A really big section closed with a tag <<<
--- remember folds can be nested ---
Closing tag >>>
----------------------------------------
\" Just Another Vim Hacker JAVH
vim -c \":%s%s*%Cyrnfr)fcbafbe[Oenz(Zbbyranne%|:%s)[[()])-)Ig|norm Vg?\"
----------------------------------------
__END__
----------------------------------------
If you liked these please return to <A href=\"http://www.vim.org/\"><FONT color=#0000ff>www.vim.org</FONT></A>
and vote for this tip (It does encourage me!!)
Tip 305
----------------------------------------
Please email any errors, tips etc to
<A href=\"mailto:david@rayninfo.co.uk\"><FONT color=#0000ff>david@rayninfo.co.uk</FONT></A>
----------------------------------------
updated version at <A href=\"http://www.rayninfo.co.uk/vimtips.html\"><FONT color=#0000ff>http://www.rayninfo.co.uk/vimtips.html</FONT></A>
----------------------------------------
\" Information Sources
----------------------------------------
<A href=\"http://www.vim.org/\"><FONT color=#0000ff>www.vim.org</FONT></A>
comp.editors \"VIM\" newsgroup
groups.yahoo.com/group/vim \"VIM\" specific newsgroup
VIM Webring
Vim Book
Searchable VIM Doc
VIM FAQ
VimTips PDF Version
----------------------------------------
\" : commands to neutralise < for HTML display and publish
\" use yy@\" to execute following commands
:w!|sav! vimtips.html|:/^__BEGIN__/,/^__END__/s#<#\\<#g|:w!|/vimtips[f]tp/|:!vimtipsftp
----------------------------------------
\r\n<P>
\r\n<P>
\r\n<P>created: March 23, 2002 3:15 complexity: intermediate
author: Arun Easi as of Vim: 5.7
\r\n<P>:g is something very old and which is very powerful. I just wanted to illustrate the use of it
with some examples. Hope, it will be useful for someone.
\r\n<P>Brief explanation for \":g\"
-------------------------
Syntax is:
:[range]:g/<pattern>/[cmd]
You can think the working as, for the range (default whole file), execute
the colon command(ex) \"cmd\" for the lines matching <pattern>. Also, for all
lines that matched the pattern, \".\" is set to that particular line (for
certain commands if line is not specified \".\" (current line) is assumed).
\r\n<P>Some examples
-------------
Display context (5 lines) for all occurences of a pattern
:g/<pattern>/z#.5
:g/<pattern>/z#.5|echo \"==========\"
<< same as first, but with some beautification >>
Delete all lines matching a pattern
:g/<pattern>/d
Delete all blank lines (just an example for above)
:g/^\\s*$/d
Double space the file
:g/^/pu =\\\"\\n\\\"
:g/^/pu _
<< the above one also works >>
Copy all lines matching a pattern to end of file
:g/<pattern>/t$
Yank all lines matching a pattern to register \'a\'
0\"ay0:g/<pattern>/y A
Increment the number items from current line to end-of-document by one
:.,$g/^\\d/exe \"normal! \\<c-a>\"
Comment (C) lines containing \"DEBUG\" statements
g/^\\s*DEBUG/exe \"norm! I/* \\<Esc>A */\\<Esc>\"
A Reverse lookup for records
(eg: An address book, with Name on start-of-line and fields after a space)
:g/<patern>?^\\w?p \"if only name is interested
:g/<patern>/ka|?^\\w?p|\'ap \"if name and the lookup-line is interested
:g/<patern>/?^\\w?|+,/^[^ ]/-1p \"if entire record is interested
Reverse a file (just to show the power of \'g\')
:g/^/m0
\r\n<P>Foot note 1: use :v to negate the search pattern
Foot note 2: Some explanation of commonly used commands with :g
:2,8co15 => Copy lines 2 through 8 after line 15
:4,15t$ => Copy linesa 4 through 15 towards end of document (t == co)
:-t$ => Copy previous line to end of document
:m0 => Move current line to the top of the document
:.,+3m$-1 => Move current line through cur-line+3 to the last but one line
of the document
Foot note 3: Commands used with :g are ex commands, so a help search should
be,
:help :<help-topic>
eg. :help :k
\r\n<P> rate this tip Life Changing Helpful Unfulfilling
\r\n<P><<Edit file under cursor after a horizontal split | Deleting nested reply threads in emails >>
\r\n<P>Additional Notes
<A href=\"mailto:david@tvis.co.uk\"><FONT color=#0000ff>david@tvis.co.uk</FONT></A>, March 28, 2002 7:10
Thanx Karma for extending my g// knowledge
\r\n<P>Here\'s a very useful g// for day to day use
\r\n<P>:\'a,\'bg/pattern/s/pattern2/string3/gi
\r\n<P>zzapper
Here\'s something very curious:\r\n:%s/foo/bar/gc
is of course a substitution effective for the entire file
with confirm on each occurrence of \"foo\"
with the option of quitting at any point.\r\nHowever, using something similar,\r\n:g/foo/s//bar/gc
using the global g to effect the entire file --
does NOT allow quitting at any point
(even with the use of <ESC>).\r\nIf there are hundreds of \"foo\" -- it\'s an important fine point...\r\nInvite further comments...
Arun Easi, April 23, 2002 23:33
g/foo/s//bar/gc => run the command s//bar/gc for each of the line
matching foo. It is like running multiple \"s//\" commands (Hence
you have to press q for each of the invocation). The
g in \"s///gc\" does not imply entire file, it just implies all occurence
on a line (or else, it would have substituted only the first)
dyang@entropia.com, May 30, 2002 9:04
Here is one that deletes every other line (adjusting double spaced files):\r\n:g/.*/norm jdd\r\npagaltzis()gmx_de, August 6, 2002 15:12
This can be done much simpler:\r\n:%norm jdd
mra@frogne.dk, February 10, 2003 4:49
Another cool g feature is to count the number of lines matching /regexp/\r\nlet x=0 | g/regexp/let x=x+1
echo x\r\nGreat, if you are editing data files.\r\nRegards
Mike
setanta5@excite.com, March 27, 2003 2:14
Reverse all the lines in a file:\r\n:g/^/m0\r\nI have found that useful . . . honest!\r\nPK\r\nkkgahlot@yahoo.com, September 3, 2003 5:06
Can I do something like this using \":g\" (or anything else)\r\nI have a file which contains following kind of lines\r\nabc123=1,2,3
bcd123=100,200,300
abcb123=1,3,4\r\nI want to convert this to following\r\nabc123=1,abc,2,abc,3,abc
bcd123=100,bcd,200,bcd,300,bcd
abcb123=1,abcb,3,abcb,4,abcb\r\nBasically I want to replace each comma in a line with first few letters, which are coming before 123, of that line surrounded by 2 commas.
Anonymous, September 3, 2003 12:45
To answer kkgahlot\'s question:\r\nglobal // execute \"s/\\\\([=,][^,]*\\\\)/\\\\1, \" . matchstr (getline (\".\"), \"^.\\\\{-}\\\\(123\\\\)\\\\@=\") . \"/g\"\r\nTo make the whole thing a little more transparent some explanations (from the inside out):\r\nWe want to execute on each line a command like\r\ns/\\([=,][^,]*\\)/\\1, abc/g\r\nfor each line, but abc gets changed on each line.\r\nThe function\r\nmatchstr (getline (\".\"), \"^.\\\\{-}\\\\(123\\\\)\\\\@=\")\r\nreturns the string that matches the pattern /^.\\{-}\\(123)\\@=/ on the current line. In the given examples this is the text preceding 123= at the beginning of the line. Depending on the actual requierements, a simpler expression like /^[a-z]*/ could work too.\r\nThe command\r\nexecute \"s/\\\\([=,][^,]*\\\\)/\\\\1, \" . matchstr (getline (\".\"), \"^.\\\\{-}\\\\(123\\\\)\\\\@=\") . \"/g\"\r\nassembles the desired substitute command for the current line by joining some static text with the return value of the matchstr function and then executes it.\r\nAs execute works only on the current line, the command\r\nglobal // execute ...\r\napplies it to all line. If only certain lines should be proecessed replace // with some other pattern.\r\nutzb@gmx.de, November 21, 2003 10:39
Reverting lines in a file can also be done via
:%!tac\r\ninstead of tac, you can also use sort, xxd, xxd -r, cut, your-own-filter
Anonymous, March 29, 2004 7:18
too bad :g does not have a /c parameter for confirmed execution of ex commands. Something like the /c used in :<range>s/<PAT>/<REPL>/c for replacing only confirmed pattern locations.\r\nor does it ??
jdimpson@yahoo.com, April 14, 2004 10:06
I just want to add that the :g command in vi/ed is the basis for the name for the Unix grep command, i.e. Global Regular Expression Print. The \"Print\" part described the default behaviour of :g when no command was given. Obviously this behaviour was more useful when using ed.
bsjawle@hotmail.com, August 16, 2004 23:55
Thank you for the tip
发信人: smartiger (天才虎), 信区: Linux
标 题: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 12:14:54 2003), 转信\r\n:v/./$s/$/<ctrl-v><enter>./|\'\';/./-1j|$d
Replaces multiple blank lines with just one blank line.\r\n请问如何解释,特别是|和;\r\n--\r\n RedHat 8.0 Slackware 8.0
Mandrake 9.0 Debian 2.2r6
Xteam 4.0 RedFlag 3.0\r\n SmarTiger\r\n※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 210.138.200.6]
发信人: sk8er (TRUE SK8ER), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 16:32:33 2003), 转信\r\n我试了一下,这个好像不像你所说的那样工作。
:v/./$ 把整个文档都选中了,然后用 s 替换……怎么搞的……看不懂。\r\n还不如用\r\n:%s/\\(\\n\\s*\\)\\{2,}/\\r\\r/g\r\n来删除多余的空行。\r\n【 在 smartiger (天才虎) 的大作中提到: 】
: Replaces multiple blank lines with just one blank line.
: 请问如何解释,特别是|和;\r\n--
People will buy anything that\'s one to a customer.\r\n※ 修改:·sk8er 于 Jan 14 16:33:55 修改本文·[FROM: 166.111.140.66]
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.140.66]
发信人: yeshao (叶少·HP加满了!), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 16:34:07 2003), 转信\r\n :g/^[[:blank:]]*$/d
【 在 sk8er (TRUE SK8ER) 的大作中提到: 】
: 我试了一下,这个好像不像你所说的那样工作。
: 还不如用
: 来删除多余的空行。\r\n--\r\n痛苦和骄傲,这一生都要拥有\r\n※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 202.112.55.84]
发信人: sk8er (TRUE SK8ER), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 16:36:10 2003), 转信\r\n你把空行全删掉了
他还想为多个留一个空行\r\n【 在 yeshao (叶少·HP加满了!) 的大作中提到: 】
: :g/^[[:blank:]]*$/d\r\n--
New York now leads the world\'s great cities in the number of people around
whom you shouldn\'t make a sudden move.
-- David Letterman\r\n※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.140.66]
发信人: scaner (沉默), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Thu Jan 23 16:29:02 2003), 转信\r\n:v/./$s/$/<ctrl-v><enter>./|\'\';/./-1j|$d\r\n|是两个命令风格符号\r\n:v/./$s/$/<ctrl-v>enter./
\'\';/./-1j
$d
??
记得大概是这样.
我也看不动.
自己看help把.
大概意思是吧
所有的空行,变成
<enter>.
变成
<blank line>
........ --> n line -> ndot
然后
d掉最后一行
v那个是区域选择命令\r\n具体的我也不清楚了.\r\n【 在 smartiger (天才虎) 的大作中提到: 】
: Replaces multiple blank lines with just one blank line.
: 请问如何解释,特别是|和;\r\n--
沉默是痛苦的女儿\r\n※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.168.15]
发信人: allanj (木瓜), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Thu Jan 23 18:26:01 2003), 转信\r\n好像在那里见过\r\n你在最后一行加个 . 然后执行下面的命令
:v/./ ; /./-1j
那个 . 就是为了防止原来最后一行为空,
不能再匹配 /./ 了\r\n大意:
/./ 是非空行
v 是 g! 的简写, 而 g! 就是取 g 的反\r\n 所以 v/./ 就是标记出所有空行\r\n 然后对标记出的每一行 操作
; 连接 2 个行号
/./-1 就是从标记那个行号开始找非空行,
然后 (行号 - 1)
j 就是 连接 2 行
所以 () ; () j 就是把连续的几个空行 join
(如果标记的行不存在, g 方式就继续下一个存在的,
所以连接也不会出问题)\r\n原来的:
v/./$s/$/^M./|\'\';/./-1j|$d
在 vim 下没试成, 设了 compatible 也没效果.
他是不是也想在最后加个 . 然后连接, 再去掉?\r\n大致这样分
v/./
$s/$/^M./ |
\'\';/./-1j |
$d\r\nv/./ 对所有的空行执行后面 3 个命令
$s/$/^M./ 对第 $ 行, 执行后面的替换
\'\';/./-1j 从 \'\' 行开始, 到第一个非空行, 执行 j 命令
$d 删除第 $ 行\r\n【 在 smartiger (天才虎) 的大作中提到: 】
: Replaces multiple blank lines with just one blank line.
: 请问如何解释,特别是|和;
--
※ 修改:·allanj 于 Jan 23 18:26:56 修改本文·[FROM: 166.111.215.54]
※ 修改:·allanj 于 Jan 23 18:27:26 修改本文·[FROM: 166.111.215.54]
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.215.54]
发信人: sk8 (destroying Tsinghua), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Thu Jan 23 19:50:40 2003), 转信\r\n不就是合并空行吗?何必搞得这么复杂\r\n这不是解决这个问题的好办法\r\n用
:%s/\\(\\n\\s*\\)\\{2,}/\\r\\r/g
不就行了\r\n【 在 allanj (木瓜) 的大作中提到: 】
: 好像在那里见过
: 你在最后一行加个 . 然后执行下面的命令
: :v/./ ; /./-1j
: 那个 . 就是为了防止原来最后一行为空,
: 不能再匹配 /./ 了
: 大意:
: /./ 是非空行
: v 是 g! 的简写, 而 g! 就是取 g 的反
: 所以 v/./ 就是标记出所有空行
: 然后对标记出的每一行 操作
: ; 连接 2 个行号
: ...................
--
※ 修改:·sk8 于 Jan 23 19:56:07 修改本文·[FROM: 218.88.205.178]
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 218.88.205.178]
vim使用技巧(1)
本文参考了vim官方网站的文档http://www.vim.org/tips/index.php。为了查找方便起见,文中的技巧编号沿用原文档中的编号。\r\n1. 使用 * 键可以向后搜索光标所在位置的单词。反之,使用 # 键可以向前搜索光标所在位置的单词。第一次使用 * 或者 # 进行搜索之后,则可以使用 N 或 Shift-N 继续进行搜索。另外,如果设置了hlsearch选项(:set hlsearch)的话,那么使用 * Shift-N 则可以标记当前的单词为高亮显示。\r\n2. 经常会遇到这样的情况,就是在命令行上输入含有一个长长的路径的命令 vi /home/username/linux/src/dir1/dir2/dir3/srcfile.c,编辑结束之后发现需要编辑同一目录下的另一个文件,这时不得不在vi中重新输入长长的路径。而将下面的脚本放在vimrc文件(Unix下为~/.vimrc,Windows下为_vimrc)中即可快速输入路径:\r\n\" Edit another file in the same directory as the current file
\" uses expression to extract path from current file\'s path
\" (thanks Douglas Potts)
if has(\"unix\")
map ,e :e [C-R]=expand(\"%:p:h\") . \"/\" [CR]
else
map ,e :e [C-R]=expand(\"%:p:h\") . \"\\\" [CR]
endif\r\n这样编辑完第一个文件之后,在vi中输入 ,e ,然后就可以利用Tab键进行自动补齐了。注意上面代码中的[]符号,实际输入的时候需要换成小于号和大于号(由于blog自身原因,小于号和大于号不能直接输入)\r\n4. 单词自动补齐:输入一个单词(例如函数、变量名等)的开头几个字母,然后按Ctrl-N或者Ctrl+P键,vim会在当前文档中查找匹配的单词并自动将输入补齐。\r\n6. 使用 % 键可以查找匹配的括号。\r\n7. 使用 [{ 和 ]} 命令可以跳转到光标所在程序块的开头和结尾。\r\n8. 如果当前光标处的单词是一个局部变量,则使用 gd 来跳转到该变量的定义处;如果当前光标处的单词是全局变量,则使用 gD 来跳转到该变量的定义处。\r\n9. [i 命令可以快速察看光标所在位置的变量的定义,[d 命令可以快速察看光标所在位置的宏的定义。\r\n10. 流行的文本编辑器通常都有前进和后退功能,可以在文件中曾经浏览过的位置之间来回移动。在 vim 中使用 Ctrl-O 执行后退,使用 Ctrl-I 执行前进。
相关帮助: :help CTRL-O :help CTRL-I :help jump-motions\r\n12. 如果想在源程序中不使用TAB键并保证缩进为四字符,那么在 vimrc 中加入下列设置:\r\n set tabstop=4
set shiftwidth=4
set expandtab\r\n13. 使用 set incsearch 之后可以在键入搜索关键字时即时显示匹配的位置。\r\n14. 使用 set hlsearch 可以将匹配进行高亮显示。进行一次搜索之后,执行 :nohlsearch 或 :noh 可以暂时关闭本次搜索结果的高亮显示。而使用 :set nohlsearch 则可以永久关闭搜索高亮显示。
可以将:noh命令映射到一个键上,例如:nmap <silent> <C-N> :silent noh<CR>,这样就可以使用Ctrl-N来关闭高亮显示。\r\nposted on 2004年10月05日 5:19 PM
1. 已经在编辑状态(insert mode)了,如何快速执行 normal mode 的命令?
在编辑文本时,需要快速定位到某个位置,如下一个 d 的位置,难道要
<ESC>、fd、i 这般繁琐吗?
其实,使用 Ctrl-O 就可以临时切换到 normal mode, 执行一个命令后自动返回 insert mode。
于是上述命令序列可以改为:
Ctrl-O、fd 即可。
Ctrl-O 要按两个键呢,很麻烦,于是来个 keymap
\" make ` functions <C-O> in insert mode
inoremap ` <C-O>
nnoremap ` i`<ESC>\r\n在 normal mode 下按 ` (左上角那个),会正常插入 `,
而在 insert mode 下则相当于按 Ctrl-O,
于是上述命令序列又可简化为
`fd 即可。
在 insert mode 想粘贴剪贴板内容时,可以输入 `P,爽吧?
这样就可以在 insert mode 下天马行空,不用再按 <ESC>和a 切来切去了。\r\n2. vim 的剪贴板怎么怪怪的?
用 y 命令拷贝的文本怎么不能在 X/Windows 的其它应用中使用呢?
事实上,vim 有多个所谓寄存器来寄存剪切的内容。
平时是不是只用 y <motion> 和 p 命令呢?
其实这时使用的是 unamed 寄存器(对应寄存器*,不知对否?),即没有给定名称的,
而给定名称的,可以加前缀 \"r 使用。
例如,将当前行放到寄存器a中,输入: \"aY
将另一行(先移到其它行)放到寄存器b中,输入: \"bY
粘贴寄存器a,输入:\"aP
粘贴寄存器b,输入:\"bP\r\n好了,扯远了,X/Windows 的剪贴板的内容是存在寄存器+中,不信,自己试试:\"+P
能不能将简单的 y 和 p命令与系统剪贴板联系起来呢?
就这句,浪费了我许多口水:)
set clipboard+=unnamed \" set clipboard\r\n3. 我不要每次都输入 this_object.set_...
呵,在 C 的结构或 C++ 的对象设置时,那个结构名或对象名总是重复 n 次要输入,挺烦的:(
添加这两句到配置文件中吧:
\" Ctrl-F to yank line upstairs
inoremap <silent> <C-F> <C-O>:exe \"norm! kly0jPD\"<CR>\r\n这是在编辑模式中使用的,怎么个用法?举个例子吧(括号内是我的注释):\r\n(在编辑模式下,先输入这句:)
this_object.set_height(1.80);
( ^)
( |)
(用<tab>啊,空格啊移到箭头所示处,即h处,然后按Ctrl-F)
(自动补全成:)
this_object.set_
(于是你可以继续输入\"weight(100);\" 了)\r\n不知大家明白没有,不明白的先试试:)\r\n4. 我想注释一堆 C++ 代码
当然,这有许多种我不知道的方法,我的通用方法为,先在配置文件里添加:
vnoremap . :normal .<CR>\r\n呵,一句就够了,示例如下:\r\n假设你有如下几行代码需要注释:
this_object.set_height(1.60);
this_object.set_weight(100);
this_object.run();\r\n你先移到第一行,输入 I//<ESC> (<ESC>就是ESC键),将第一行注释。
然后移到第二行,按 V 进行 line visual mode,按 j 或其它方向移动键选好要注释的所有代码行,
最后按: .
是不是很神奇?\r\n呵,说白了,这只是在 visual mode 里使用 redo 的功能而已,有点跑题了。
当然,殊途是同归的,只是路的长远而已。
这是条通用的路,可以用在很多地方。
回到主题,谁有更直接的办法注释一堆 C++ 代码?一堆 C 代码呢(用/* */ 风格) ?\r\n5. vi 的自动完成有什么新奇的东东?
不就是根据 buffer 的内容来自动完成吗?
有些插件是可以动态地读取头文件或模块来提供自动完成的,例如 python 的 pydict。(此列表待补全:)
我想介绍的是 vi 基于字典的自动完成:
1. 增加基于字典的自动完成
set complete+=k \"add dictionary complete
2. 设定字典文件,字典文件其实是个文件文件,每个单词占一行
(以下字典文件可能并不存在)
set dictionary=/usr/share/dict/words \"set dictionary
3. 呵,因此我是不用什么英文字典来自动完成的,很少写英文文章,使用字典后反应很慢。
我用基于字典完成的原因是,使用编辑语言的关键字自动完成,见:
\" complete from filetype syntax file
autocmd Syntax * execute \"setlocal dictionary=\".$VIMRUNTIME.\"/syntax/\".getbufvar(\"%\",\"current_syntax\").\".vim\"
对应的语言语法文件必须存在才可使用,于是写新的 C 文件时,可以直接 inc<Ctrl>-N, cont<Ctrl>-N\r\n(请大家不吝赐教,to be continued)
编辑者: zslevin (10/16/04 10:53)\r\nvi编辑技巧\r\n 游标的移动
本节所述皆是在 common-mode(c-mode,在 vim 又名 normal-mode)下的移动,原始的 vi 只能在 c-mode 移动,在 insert-mode 只做文字的输入,而不做游标的移动。当然 vim 及 elvis 的方向键是不论在那一种 mode 皆可移动自如。\r\n基本的游标移动\r\n h 左,或 Backspace 或方向键
j 下,或 Enter 或 +(要 Shift 键),或方向键\r\nk 上,或 方向键或 -(不必 Shift 键)
l 右,或 Space 或方向键
Ctrl-f 即 PageDown 翻页。
Crtl-b 即 PageUp 翻页。\r\n使用 hjkl 键的移动是为了使手不必离开打字区(键盘*的部位),
以加快打字的速度,如果各位不习惯,那就使用方向键吧!\r\nBackspace 及 Space 的移动方式是到了行首或行尾时会折行,
但方向键或 hl 键的移动则在行首或行尾时您继续按也不会折行。
转折换行的功能是 vim 的扩充功能,elvis 无此功能。\r\njk 及使用方向键的上下移动游标会尽量保持在同一栏位。
使用 Enter,+,- 的上下移动,游标会移至上(下)一行的
第一个非空白字元处。\r\n好像有点复杂,各位就暂时使用方向键来移动就简单明白了!
等您爱上了 vim 后再来讲究吧。\r\n进阶的游标移动\r\n 0 是数目字 0 而不是英文字母 o。或是 Hmoe 键,移至行首,(含空白字元)。
^ 移至第一个非空白字元,注意,要 Shift 键。
$ 移至行尾,或 End 键。要 Shift 键。\r\n以上两个按键是源自规则表示式(regular expression),
在 regexp 中 ^ 是匹配行首,$ 是匹配行尾。\r\nG 移至档尾(最后一行的第一个非空白字元处)
gg □至档首(第一行之第一个非空白字元处)\r\ngg 是 vim 的扩充功能,在 elvis 或原始 vi 中可用 1G 来
移至档首(是数字 1 不是英文字 l)。\r\nG 之原意是 goto,指移至指定数目之行首,如不指定数目,
则预设是最后一行。\r\nw 移至次一个字(word)字首。当然是指英文单字。
W 同上,但会忽略一些标点符号。
e 移至前一个字字尾。
E 同上,但会忽略一些标点符号。
b 移至前一个字字首。
B 同上,但会忽略一些标点符号。
H 移至萤幕顶第一个非空白字元。
M 移至萤幕中间第一个非空白字元。
L 移至萤幕底第一个非空白字元。\r\n这和 PageDown,PageUp 不一样,内文内容并未动,
只是游标在动而已。\r\nn| 移至第 n 个字元(栏)处。注意,要用 Shift 键。n 是从头起算的。
:n 移至第 n 行行首。或 nG。
特殊的移动\r\n ) 移至下一个句子(sentence)首。
( 移至上一个句子(sentence)首。
} 移至下一个段落(paragraph)首。
{ 移至上一个段落(paragraph)首。\r\nsentence 是以 . ! ? 为区格。paragraph 是以空白行为区格。\r\n% 这是匹配 {},[],() 用的,例如您的游标现在在 { 上只要按 %,就会跑到相匹配的 } 上。写程式时满好用的。
另还有一些 vim 的特殊按键,但这得留待最后才来讲述,否则各位恐怕会头昏眼花了。\r\n 基本编辑指令
这个单元就开始进入主题了。下编辑指令都是在 commond-mode (c-mode),就是您一进入 vim 时的模式,只能下指令,不能键入文字。如果印象模糊,请瞄一下第一个单元的内容。这个单元说的是基本的指令,有些比较特殊的编辑指令,因为太有个性了,所以会独立成一个单元来说明。\r\n进入 i-mode 的指令\r\n i 在游标所在字元前开始输入文字(insert)。
a 在游标所在字元后开始输入文字(append)。
o 在游标所在行下开一新行来输入文字(open)。
I 在行首开始输入文字。
此之行首指第一个非空白字元处,要从真正的第一个字元处开始输人文字,
可使用 0i 或 gI(vim)。\r\nA 在行尾开始输入文字。
这个好用,您不必管游标在此行的什么地方,
只要按 A 就会在行尾等著您输入文字。\r\nO 在游标所在行上开一新行来输入文字。
J 将下一行整行接至本行(Joint)。
并无相对的 split 功能,可在 i-mode 下按 Enter 来达成\r\n,当然如果您熟 macro 的话,可自行定义。
使用 J 时,预设会消去本行的 EOL,且上下行接缝间会留下一个空白字元,
这符合英文习惯,却对中文会造成困扰,欲不留空白字元,
可使用 gJ(大写 J)指令,但这是 vim 的扩充功能,elvis 不适用。\r\n请您随便找一个档案来试看看,光看文字说明太抽象了。\r\n删除指令\r\n x 删除游标所在处之字元。在 vim 及 elvis 亦可用 Del 键。
X 删除游标前之字元。不可使用 Spaceback 键。
vim 可以正确使用以上两个指令于中文,会删去一个中文字 elvis 则不行,
一个中文字要删两次,即使用 xx。\r\n dd 删除一整行(delete line)。
dw 删除一个字(delete word)。不能适用于中文。
dG 删至档尾。
d1G 删至档首。或 dgg(只能用于 vim)。
D 删至行尾,或 d$(含游标所在处字元)。
d0 删至行首,或 d^(不含游标所在处字元)。
请回忆一下 $ 及 ^ 所代表的意义,您就可以理解 d$ 及 d^ 的动作,
这就是 vi(m) 可爱之处。\r\n取代及还原\r\n r 取代游标所在处之字元。vi(m) 很有个性的,您在 c-mode 按了 r 她就会停在那里等主人键入所要替代的字元,希望您这个当主人的,不要傻呼呼的也楞在那里,赶快键入您的新字元吧!:-)
vim 中可用于中文字,也就是可以替换一个中文字,elvis 则不行。
当然您的 vim 是要设在 * 的才行。怎么样!有没有看过如此
有个性的取代方式?ㄚ!r 就是 replace 啦!\r\nR 取代字元至按 Esc 为止。
cc 取代整行内容。或大写 S 亦可。
cw 替换一个英文字(word),中文不适用。(change)
~ 游标所在处之大小写互换。当然不能用于中文。别忘了 Shift!
C 取代至行尾,即游标所在处以后的字都会被替换。或 c$。
c0 取代至行首,或 c^。
s 替换一个字元为您所输入的字串。和 R 不同,R 是覆盖式的取代,s 则是插入式的取代,您可亲自实验看看。ㄟ!是小写的 s。
u 这个太重要了,就是 undo,传统的 vi 仅支援一次 undo,vim 及 elvis 就不只了,vim 是没有限制的。
U 在游标没离开本行之前,回复所有编辑动作。
Crtl+r 这个也是很重要,就是 redo 键。
加上数目字
喔!骚到 vi(m) 的痒处了,这是 vi(m) 一个非常骚包的功能,只此一家别无分号(当然同源的 ed,sed 等不在此限)。就是您可以在大部份的指令前加上数目字,代表要处理几次的意思。以下用实例来说明比较清楚。\r\n5dd 删除游标所在处(含)起算以下五行内容。妙吧!
3r 按了 3r 后,您键入一个英文字,则三个字元皆会被您所键入的英文取代。很抱歉,这不能用于中文。
5J 将五行合并成一行。
3x 删除三个字元。抱歉,不能用于中文。
5i A 然后按 Ecs,插入五个 A。中文也可以!
2i system Esc 插入 systemsystem。中文也可以!
5G 游标移至第五行,是从档首开始起算。
5l 移至右第五个字元处,当然 j 是可以用方向键取代的。所有移动指令(参考第二单元)都可以加上数目字来控制,中文也通喔!elvis 当然是不能用于中文。
其它的指令和数目字结合,就留待各位去发掘吧!最重要的是请您亲自操作看看,使用 vi(m) 常常要动动脑筋,会有更妙的操作方式。
简单重排功能\r\n >> 整行向右移一个 shiftwidth(预设是 8 个字元,可重设)。
<< 整行向左移一个 shiftwidth(预设是 8 个字元,可重设)。
:set shiftwidth? 可得知目前的设定值。:set shiftwidth=4
可马上重设为 4 个字元。shiftwidth 可简写成 sw。ㄟ,别忘了 Shift 键!\r\n:ce(nter) 本行文字置中。注意是冒号命令!
:ri(ght) 本行文字靠右。
:le(ft) 本行文字靠左。
所谓置中、靠左右,是参考 textwidth(tw) 的设定。
如果 tw 没有设定,预设是 80,就是以 80 个字元为总宽度为标准来置放。
当然您也可以如 sw 一样马上重设。\r\ngqip 整段重排。中文会出槌!:-(
gqq 本行重排。
重排的依据也是 textwidth。这里的重排是指您键入文字时没有按 Enter 键,
就一直在 keyin,这样会形成一个很长的一行(虽然萤幕上会替您做假性折行),
重排后,则会在每一行最后加入 EOL。gq 重排功能是 vim 才有的功能。\r\n 复制(yank)
yank 是什么意思?有疑问的请查一下字典吧!就好像是中医治疗中的「拔罐」的意思啦(是不是叫「拔罐」?知道的朋友指正一下吧)!反正在 vi(m) 中,她就是复制 copy 的意思。这在 vi(m) 的思考逻辑里,就是「拔」yank 起来,「放」put 上去。其实复制的指令就是 y 一个而已,为什么要独立成一个单元来说明呢?因为 vi(m) 复制、贴上的功能实在太独特了,再配合前面介绍的数目字,及 vi(m) 内部的缓冲区来使用的话,您会发现,原来 vi(m) 肚子里还暗藏著秘密武器。\r\n指令说明]]>
yy 复制游标所在行整行。或大写一个 Y。
2yy 或 y2y 复制两行。ㄟ,请举一反三好不好!:-)
y^ 复制至行首,或 y0。不含游标所在处字元。
y$ 复制至行尾。含游标所在处字元。
yw 复制一个 word。
y2w 复制两个字。
yG 复制至档尾。
y1G 复制至档首。
p 小写 p 代表贴至游标后(下)。
P 大写 P 代表贴至游标前(上)。
整行的复制,按 p 或 P 时是插入式的贴在下(上)一行。
非整行的复制则是贴在游标所在处之后(前)。\r\n\"ayy 将本行文字复制到 a 缓冲区
a 可为 26 个英文字母中的一个,如果是小写的话,原先的
内容会被清掉,如果是大写的话是 append 的作用,会把内
容附加到原先内容之后。\r\n\" 是 Enter 键隔壁的那一个同上符号(ditto marks)。\r\n\"ap 将 a 缓冲区的内容贴上。
缓冲区的术语在 vim 称为 registers,vim 扩充了相当多的
功能,有兴趣深入的朋友请 :h registers。您用 d、c、s、
x、y 等指令改变或删除的内容都是放在 registers 中的。
例如:您用 dd 删除的一行,也是可以使用 p 来贴上的。只
要是在缓冲区的内容都可以使用 p 来贴上,不是一定要 y 起
来的内容才能用 p。因此您认为 p 是 paste 也可以,认为是
put 可能较正确。\r\n5\"ayy 复制五行内容至 a 缓冲区。
5\"Ayy 再复制五行附在 a 内容之后,现在 a 中有十行内容了!
ㄟ!不要我一直用 a 您就认为只有 a 可以用喔。26 个英文
字母都可以的,交叉运用下,您会发觉 vi(m) 肚量不小。\r\n问题来了!忘记谁是谁的时候怎么办? :reg(冒号命令)就
会列出所有 registers 的代号及内容。您现在就试著按看看
咦!怎么还有数目字、特殊符号的缓冲区,原来您刚刚删除
(复制)的内容就预设放在 \" 这个缓冲区,然后依序是
0,1,2,...9。也就是说您按 p 不加什么的话,是取出 \" 缓
冲区的内容的。% 指的是目前编辑的档案,# 指的是前一次
编辑的档案。还有其它的呀!因为没什么重要,就请
:h registers 吧!registers 有个 \"s\" 结尾,不要搞错了,\r\n 而且 Tab 的补全键 vim 也支援的,也就是说您键入 :h regi
再按 Tab 键,vim 就会帮您补全,按了 Tab 后发现不是您要
的,那就继续按,总会出现您要的。:-)\r\nTab 补全的功能,elvis 也有,但叫出 registers 列表的命令
则没有,您得自行记忆在您的脑袋瓜子里。而且 elvis 的补全
能力并没 vim 强。\r\n天大的指令
. 这是什么?ㄚ,是英文句点啦!没错,就是英文句点。什么意思?重复前次的编辑动作。这个指令太高明了,只要是编辑动作(移动游标不算,冒号命令也不算)都可以按英文句点来重复,要重复几次都可以。\r\n例如:您按了 yy,然后按 p 就会复制、贴上一整行,如果要重复这个动作的话,就可以按 . ,也可以把游标移到其它地方后再按。其它 dd,dw,r,cw 等编辑指令都可以这样来重复。如果您要重复做某些编辑动作时,千万千万一定要想到有这么一个英文句点重复指令。ㄚ,拜托啦!您一定要常用这个指令。\r\n疑难杂症\r\n 那 mouse 中键的剪贴功能还有吗?当然还有,不管在 console 或 X terminal 中都照用不误。当然在 windows 下的话就不能用了,可以用 Shift-Insert 来代替。Ctrl-v 在 vim 中另有作用,在 windows 下就不必去麻烦它了。
ㄟ,我从 netscape 用 mouse copy 东东过来的时候,常常都搞得天下大乱耶!要设成 :set paste,预设是 map 至 F9 键的,您要 copy 之前先按一下 F9,copy 完后再按一次 F9 来回复。这是 vim 的扩充功能,elvis 没有。那在 elvis 怎么办?只好 :set noai 了。在 GUI 的版本应不会有这种情形。
set 的功能先不必去理它,往后会有一个单元专门讨论。\r\n朋友!您睡著了吗?不要被吓到了,您只要开个档案,亲自操作一下就能心领神会。那用 mouse 不是更方便吗?不见得,yyp 来复制贴上一整行比较快,还是用 mouse 来拉比较快?您可以试看看。\r\n 寻找/替换
搜寻、替换的功能几乎是每个编辑器必备的功能,那在 vi(m) 中有没有特殊的地方呢?当然有,您忘了,vi(m) 是个性十足的编辑器。最特殊的地方是和规则表示式(regular expression,简称 regexp) 结合在一起。简单的说她是一种 pattern 的表示法,在执行动作,如寻找或替换,就会依据这个 pattern 去找,所有符合 pattern 的地方就会执行您所下的动作。在这个单元里不讨论 regexp,会另立一个单元来探讨,以免搞得头昏脑胀。目前就暂不使用 regexp,您要找什么就直接键入什么就对了。\r\n寻找\r\n / 在 c-mode 的情形下,按 / 就会在左下角出现一个 /,然后键入您要寻找的字串,按个 Enter 就会开始找。
? 和 / 相同,只是 / 是向前(下)找,? 则是向后(上)找。
n 继续寻找。
N 继续寻找(反向)。
更方便的寻找操作(vim 才有)\r\n * 寻找游标所在处之 word(要完全符合)。
# 同上,但 * 是向前(下)找,# 则是向后(上)找。
g* 同 * ,但部份符合即可。
g# 同 # ,但部份符合即可。
n,N 之继续寻找键仍适用。\r\n替换(substitute)
:[range]s/pattern/string/[c,e,g,i]\r\nrange 指的是范围,1,7 指从第一行至第七行,1,$ 指从第一行至最后一行,也就是整篇文章,也可以 % 代表。
还记得吗? % 是目前编辑的文章,# 是前一次编辑的文章。\r\n pattern 就是要被替换掉的字串,可以用 regexp 来表示。\r\nstring 将 pattern 由 string 所取代。\r\nc confirm,每次替换前会询问。\r\ne 不显示 error。\r\ng globe,不询问,整行替换。\r\ni ignore 不分大小写。
g 大概都是要加的,否则只会替换每一行的第一个符合字串。
可以合起来用,如 cgi,表示不分大小写,整行替换,替换前
要询问是否替换。\r\n [实例] :%s/Edwin/Edward/g
这样整编文章的 Edwin 就会替换成 Edward。\r\n更进阶的寻找、替换的例子在说明 regexp 的时候还会再详述。目前只知道最基本的用法就可以了!其实光这样就非常好用了。:-)\r\n书签功能
这又是 vi(m) 的一个秘密武器,简单的说,您可以在文章中的某处做个记号(marks),然后跑到其它地方去编辑,在呼叫这个 mark 时又会回到原处。妙吧!\r\nmx x 代表 26 个小写英文字母,这样游标所在处就会被 mark。
`x 回到书签原设定位置。
` 是 backward quote,就是 Tab 键上面那一个。\r\n\'x 回到书签设定行行首。
\' 是 forward quote,是 Enter 键隔壁那一个。\r\nvim 对于书签的扩充功能\r\n 小写字母 只作用于单一档案内。
大写字母 可作用于编辑中之各档案间。
数目字 可作用于前次编辑的十个档案。
数目字的用法比较特殊,\'0 是回到前一次编辑档案中离开
前的最后位置,\'1 则是回到前二次编辑档案的最后位置,
依此类推。您不必使用 m 来标示,vim 会自动记忆。
很玄吧!其实这是 viminfo 的功能,您要认真追究的话,
请 :h viminfo-file-marks。viminfo 关掉,就没这个功能了!\r\n所谓前次指的是前次启动的 vim。\r\n:marks 得知目前所有书签的列表。\r\n叫档、存档、紧急回复
ㄟ,是不是在灌水呀!怎么开个档也成一个单元?那您就错了,在 vi(m) 里叫档的花样可多了,而且又可以多档编辑,各编辑中的档案还可以互通讯息,这里面学问可大著呢!vim 就更骚包了,也学人家档案可以加密,虽说是噱头,但也还满好用的。\r\n vim + 档名
这样开档后,游标会落在档案最后一行的行尾,在档案屁屁后干什么呢?方便您可以继续编辑嘛!
vim +n 档名
游标会落在第 n 行的行首。
vim +/string 档名
还记得吗? / 就是寻找指令,这样进入档案后游标就会落在第一个找到的 string 上,还可以按 n 继续找 string 喔!哦,string 还可以使用 regexp 来表示喔。
多档编辑
多档编辑会有两种情形,一种是在进入 vim 前所用的参数就是多个档(这种情形称为 argument list)。另一种情形是进入 vim 后另外再开其它的档(称为 buffer list)。不过都可以统称为 buffer。\r\n:n 编辑下一个档案。
:2n 编辑下二个档案。
:N 编辑前一个档案。
注意,这种用法只能用于 argument list 的情形。\r\n:e 档名 这是在进入 vim 后,在不离开 vim 的情形下再开其它档案。只要您要编辑的档案是在目前目录,Tab 补全键还是可以使用。
:e# 或 Ctrl-^ 编辑前一个档案,用于两档互相编辑时相当好用。
这种用法不管是 argument list 或 buffer list 档案间皆可使用。\r\n还记得吗? # 代表的是前一次编辑的档案。\r\n:files 或 :buffers 或 :ls 会列出目前 buffer 中的所有档案。
在 elvis 中可使用 :b 来叫出 buffers。\r\n在 buffers 中,减号 - 表示这个 buffer 并未载入,不过,
不必担心,载入相当快速的。加号 + 表示这个 buffer
已经修改过了。\r\n:bn buffer next。
:bl buffer last。
以上两个指令 elvis 不适用。\r\n:b档名或编号 移至该档。
在 :ls 中就会出示各档案的编号,这个编号在未离开 vim 前是不会变的。
这个指令 elvis 也是可以使用。\r\n当然 :e#编号 也是可以的,这样的用法则是所有 vi clone 都通用了。\r\n如果您是使用 vim 的 GUI,那就在功能表上就会有 Buffers 这个选项,
可以很容易的知道及移动各 buffer 间。\r\n:bd(elete)
buffer 在未离开 vim 前是不会移除的,可使用这个指令移除。其实移除她干什么呢?vim 是您在叫用时才会载入的,因此这些 buffers 并不是像 cache 一般要占记忆体的。
:e! 档名
这样也是会开档,但会放弃目前编辑档案的改变,否则如果档案已有变动,vim 预设是不让您随便离开的。:e! 后不接什么的话,代表舍弃一切修改,重新载入编辑中档案。
:f 或 Ctrl-g
显示目前编辑的档名、是否经过修改及目前游标所在之位置。
:f 档名
改变编辑中的档名。(file)
:r 档名
在游标所在处插入一个档案内容。(read)
:35 r 档名
将档案插入至 35 行之后。
gf
这是 vim 的特殊叫档法,会叫出游标所在处的 word 为名的档案,当然,这个档案要在目前目录内,否则会开新档案。
哦!好像有点给他复杂,主要原因是偶文笔不好啦!不过您何不选个顺手的来用就可以了,选定了,以后就是使用他,这样就不会那么复杂了。:-)
离开\r\n :q 如本文有修改而没存档,会警告,且无法离开。(quit)
:q! 舍弃所有修改,强迫离开。
:wq 存档后离开。纵使档案未曾修改也是会再存一次档。
:x 也是存档后离开,但如果档案没有修改,则不会做存档的动作。
ZZ 和 :x 完全一样,随您高兴用哪一个。
:w 档名 另存他档。不加档名就是写入原档。(write)
:q 及 :q! 是对目前编辑中的档案作用,如果多档编辑的情形
并不会离开 vim,这时可下 :qa 或 :qa! 来整个离开 vim。
a 就是 all 的意思。\r\nvim 的加密功能
vim -x [档名]
这样进入 vim 后会要求输入密码。以后加密过的档案由 vim 开启时会自动要求输入密码。否则无法开启。其它的编辑器当然是无法开启的。\r\n进入 vim 编辑档案中,临时想加密,可用 :X 指令。
小心!vim 一开档就会有个 .档名.swp 这个档,是为了紧急回复用的,
一般是在您所开档案的所在目录,这是个隐藏档,ls 要有 -a 参数才看得到,
您加密的功能并没有作用在这个 swp 档,因此 root 还是知道您在
写些什么关于他的坏话的。:-) 当然啦!山不转,路转,路不转,人转,
您也是可以把 swap 的功能关掉的 :set noswf 就行了!但如果您编辑的是
大档案,则不建议您把 swap 关掉,这样会很吃记忆体的。\r\nelvis 的话,其暂存档是统一集中存放在 /var/tmp/*.ses,
权限是档案所有者始能读写。vim 的早期版本,其 *.swp
档是依原档案的权限来设定的,最近的版本则从善如流,
已经改成档案所有人始能读写,就是 -rw------- 啦!\r\n 紧急回复
vim -r 档名,或进入 vim 后,下 :recover 档名,来回复。\r\n大家来学 VIM (三)
各种标示方法及视窗操作
这个单元多了一种模式,那便是 visual mode(以下简称 v-mode)v-mode下的反白区(反黑区?^_^)在本文就统一称为标示区,不知各位是否有更好的中文名称?ㄟㄟㄟ,视窗操作和标示有什么关系?为什么摆在这里说明?ㄚ,是因为这两个单元内容都不多,没地方摆,所以就将凑在一起的啦!乱点鸳鸯谱就请各位见谅。\r\n标示指令\r\n v 小写 v 这是属于字元标示(character visual),按下 v 后您就可以移动游标,游标走过的地方就会标示起来。再按一次 v 就会结束 v-mode。您用 mouse 拉出的标示区也是属于这类的标示。
V 大写 V 这是行标示(line visual),按下 V 后会整行标示起来(包括空白的部分),您移动上下键,会标示多行。mouse 连按三次左钮,也是属于此类的标示。再按一次 V 就会结束 v-mode。
mouse 按两次左钮是标示一个 word。\r\nCtrl-v 这是方块标示(block visual),可纵向标示矩形区域。再按一次 Ctrl-v 就会结束 v-mode。
结束 v-mode 的方式亦可使用 Esc 键,或一使用 Ctrl-c。
windows 系统下 Ctrl-v 是复制键,可以使用 Ctrl-Q 来替代。
d 删除标示区内容。
y 复制标示区内容。
ㄟ…是要先标示好才按的。\"ay 还能不能用呢?当然可以,
这样就会把标示区内容存于 a 缓冲区中。可以用 \"ap 来贴上。\r\nShift-> 标示区内容向右移一个 Tab。
Shift-
可设成 dark 或 light,这是两种不同的 highlight 颜色设定,详见 $VIMRUNTIME/syntax/synload.vim。不过您要更动颜色的设定,最好是设在 ~/.vimrc 或 ~/.gvimrc 中,原始档最好不要去动她。
ㄟㄟㄟ,你从没提过 $VIMRUNTIME 好不好!其实这是最近版本的 vim
为了不至安装新版本时把旧版本的一些设定或 macro 档干掉,
所以 $VIMRUNTIME 就是 $VIM/vimxx,xx 就是版本号码啦!
例如您使用的是 vim 5.6 版,那么就是 $VIM/vim56。\r\nbackup(bk)
是否要 backup file。预设不打开。
writebackup(wb)
在写入档案前先备份一份,和 backup 的作用不尽相同,请:h backup-table。预设是打开的,所以您如果不要 backup,那要关掉的是这个项目,而不是 backup。但请先检查一下您编译时是不是有编译进去,请 :ver。
backupdir(bdir)
设定存放 backup file 的目录。预设在所编辑的档案之所在目录。
binary(bin)
设在编辑二进位档状态,这是防止存二进位档时把 EOL 也写进二进位档,那就会悔不当初,如果是图档将会无法再观看,如果是可执行档就无法执行了!因此预设是 off。
elvis 会自动判断是否为二进位档,而且会分成左右两半,左半部会以 16 进位的方式显示,
右半部则是以 ASCII 的方式来显示。\r\nbrowsedir(bsdir)
浏览档案的目录,GUI 版本始有。预设是上一次浏览的目录。就是 GUI版本功能表上的 [File] -> [Open] 会打开的目录。
cindent(cin)
写 C 时很好用,indent 比一般敏感,专为 C 程序码而设。预设 off。编辑 C/C++ code 时会自动打开。
cmdheight(ch)
状态列的行数,预设一行,建议设成两行。
compatible(cp)
设为和原始 vi 相容的状态,vim 的扩充功能会被抑制。预设 off。
confirm(cf)
各种确认动作。预设 off。
directory(dir)swap 档存放的目录。前面单元已有说明。
fileformat(ff)
这是写入档案时置放 EOL(end of line) 的形式
dos 是以 0D 0A 来断行。
unix 是以 0A 来断行。
mac 是以 0D 来断行。
预设以各系统平台而定,在 Linux 当然是 unix 形式。
fileformats(ffs)
可指定多个,会依载入的档案形式来调整 ff。例如 :set ffs=unix,dos ff=unix 则预设为 unix 格式,但如读入的是 dos 格式的档案,会自动调整为 dos 格式,这样存档时就会以 dos 格式存档(状态列会显示)。此时如要改成 unix 格式,可 set ff=unix 然后存档就会转成 unix 格式,反之亦然。
注:\r\n如果不这样设,也就是您不管 ff 或 ffs 都设成 unix,那读入dos 格式的档案时在每行尾会出现 ^M 这个字元(就是 0D 啦!)这时纵使 :set ff=unix 也来不及了!只好 :%s/^M//g 来消去这个^M。ㄟ,还记得怎么替换吗?就是把 ^M 换成没有啦!而且 ^M 怎么打出来的还记得吧!翻一翻前面的单元吧!
Hey,你怎么知道是 0D 呀!好吧!告诉您一个密秘,您把游标移到^M 那个位置,然后按 ga 在状态列就会显示 10,16,8 进位的值。其它的字元也是可以如此显示。a 就是 ascii 的意思。但这是 vim 的扩充功能,elvis 没有。
elvis 纵使载入 dos 格式的档案,也是会自动把 ^M 隐藏起来。
ignorecase(ic)
寻找时不分大小写,这对中文会造成困扰。预设 off。
incsearch(is)
加强式寻找功能,在键入 patern 时会立即反应移动至目前键入之 patern 上。预设 off。
hlsearch(hls)
寻找时,符合字串会反白表示。预设 off。如果您是使用 vim 的预设的 vimrc 档的话,会设在 F8 键来切换。
textwidth(tw)
是一种 word wrap 的功能,从左起算之固定每行的最大字元宽度。超过此宽度就会自动折行,这可是真的折行,也就是说在折行处会插入 EOL。预设是 0,也就是没有 word wrap 的功能。
wrapmargin(wm)
和 textwidth 作用相同,只是是从右视窗边向左算起要几个字元起折行。预设是 0。textwidth 与 wrapmargin 的功能目前并不适用于中文,打中文还是您自行按 Enter 吧!
wrap
这也是折行功能,可是只是萤幕效果的折行,实际上并没有插入 EOL。
wrapscan(ws)这和折行没有关系,是指寻找时,找至档尾时,是否要从档首继续找。预设是要。
paste
这是防止在做剪贴时位置会不正确,前面单元已有说明。
ruler(ru)
会在状态列显示游标所在处之行列状态,预设不打开,但建议打开。最右边之代号的意义如下:
Top 档案第一行在萤幕可见范围。
Bot 档案最后一行在萤幕可见范围。
All 档案首尾皆在一个萤幕范围内。
如非以上三种情形,则会显示相对百分比位置。
statusline(stl)
状态列显示的格式,使用预设就可以了,如果您想骚包一下的话,那就请您 :h stl。
shiftwidth(sw)
指由 >> 移动整行内容时,一次移动的字元宽度,一般是使用 Tab 的值,但可由这个设定来改变。
tabstop(ts)
一个 Tab 键宽度。预设是 8 个字元宽度。最好不要随便改,以免您写的东西由其它编辑器来阅读时造成困扰,为解决这个问题,vim 有一种 softtabstop 的机制,在下一节会详细说明。
showcmd(sc)
在状态列显示目前所执行的指令。
showmode(smd)
在状态列显示目前的模式,例如是 Insert mode 或是 Visual mode。当然平常的 normal mode(commond mode)是不显示的。
viusalbell(vb)
以萤幕闪动代替 beep 声。
number(nu)
显示行号。注意,冒号命令也有 :nu 这是显示游标所在行的行号,您嫌多打一个字的话,:# 也行。不过如果 ruler 打开的话,在状态列本就会显示门前游标所在处的行列值。
list
这也可以算是一种模式,list mode。就是 Tab 的地方会以 ^I 显示,而行尾之 EOL 会显示成 $。可以让您清楚的知道 Tab 在哪里,折行是不是真的。
swapfile(swf)
是否需 swap 至磁碟。如果设为 noswf 的话,那将不会有 swapfile产生,通通会载入在记忆体中。预设是要 swapfile。
fileencoding(fe)
首先先鼓掌一下,啪啪啪…,因为有支援 *,也支援 XIM,也就是说可以使用 xcin-2.5x 来作输入,当然您用 xcin-2.3x 配合XA 也是可以啦!目前支援简繁中文、日文、韩文,unicode 尚未植入。但前提是您要把 multi_byte 编译进去,这在一开始就讲过了。预设是使用 ansi。set guifont 及 set guifontset 已在一开始讲过,在此就不重复了。
history(hi)
记录冒号命令的历史纪录档,就是可以用上下方向键叫出来的那锅。预设是 20 笔。
关于 softtabstop(sts)
几乎所有的 OS 及软件都设定 Tab 就是 8 个字元长,这已经是个公认值,您硬要去改变它的话恐怕带来许多不便,但实际上关于程序风格,许多人又认为 8 个字元太长了,几个巢状回圈下来就需折行,反而不方便。因此 vim 体贴您,内建了 softtabstop 的功能,就是由 vim 来代您制造出一个假的Tab,实际上是空白字元组成的 Tab。\r\n 举个例子来说明比较清楚。
set softtabstop=4
set shiftwidth=4\r\n 这样会由 4 个空白字元取代一个 Tab,您按 Tab 键 vim 就跳 4 格,需注意的是,如果您按了三次 Tab 键,那就是一个实际的 Tab 加上四个空白字元,可不是 12 个空白字元喔!是混合 Tab 及 space 的。\r\n问题来了!那我要按真正的 8 字元的 Tab 时怎么办?简单,还记得怎么按特殊字元吗? Ctrl-v Tab 或 Ctrl-v I 就可以了,那就是如假包换的 8 字元长之 Tab。当然,您按两次 Tab 不就得了!:-)\r\n关于折行
前面已说过 set wrap 就可以造成萤幕折行,可是却会把一个英文单字折成两半,实在很不雅观。好了,vim 再体贴您一次,set linebreak(lbr) 就会避免这种问题发生,会在空白或标点符号的地方来折行,但也仍属萤幕折行,并不会插入 EOL。这个功能目前在中文判断上还是会出槌!:-(\r\n规则表示式的运用
在本系列文章一开始就说明了学 vi(m) 可以顺便学规则表示式(regular expression,以下简称 regexp),那为什么到现在才来讲呢?因为 regexp 说简单也算不很难,但您要深入去使用的话,有时会马上看不出一个复杂的 regexp 在说些什么的,就曾有人形容 regexp 为「有字天书」!而且在 vi(m) 整体都还没一个概念就加入 regexp 的话,那后面的单元恐怕就没人看了!而 regexp 各家有各家的 extensions,这也是大家视为畏途的原因之一,不过总是大同小异,只需注意一下就可以了。目前先不必管别家怎么说,就让 vim 暂时先成为我们的「标准」,以后碰到其它程序的 regexp 应该就可以触类旁通。以下我们尽量由实例去了解。当然,小小的一篇文章是没有办法详尽介绍,只能捡重点来说明了。如有疑问,可 :h pattern 或在Un*x 系统中可 man 7 regex,甚至 man ed,man sed,man grep,man awk,man perlre 里面也是会说些 regexp,但要注意和 vim 差异的地方!其中 perl 的 regexp 应该是最完整的了,如果您的系统没有 perl 那应该是「稀有动物」了!:-) ㄟㄟㄟ!vim 只是一个编辑器,可不是独立的程序语言!\r\n基本的匹配\r\n * 指前所绑住的字元或字元集合,出现 0 次或 0 次以上。
+ 和 * 作用相同,但不包括出现 0 次。
= 指前所绑住的字元恰好出现 0 或 1 次。
| 这是多选,就是 or 的意思,被 | 隔开的 pattern,任一个符合的话就算符合。注:
+, =, | 会加上一个 ,是因原字元在 vi(m) 就具有特殊意义,在一般的 regexp 中是 +,?,| 就可以了,只是提醒您一下,以免搞混了!
在 elvis 及 ed 中是使用 ? 来匹配出现 0 或 1 次,而不是 =,这里要非常小心!
[实例]
dg*\r\n 指 * 前所绑住的字元 g 出现 0 次或 0 次以上。也就是说 d(出现 0 次),dg,dgggg,dgggggggg 都是符合这个 pattern。如果您下寻找指令 /dg*,那符合这个 pattern 的字串都会被找出来。如果用在代换就要非常小心了,像 extended 中的 d 也是会被置换掉的。例如您下 :%s/dg*/test/g 的话,那 extended 这个字会换成 extentestetest。注 : shell 中使用的通用字元为 pattern matching notation 和 regexp 不同的。dg* 在 shell 中是解为以 dg 开头的任意字串,这就不包括 d 在内了,也就是说在 shell 中,* 是代表任一字元或字串。\r\n[实例]
dg+\r\n dg, dgg, dgggggg 皆符合,但 d 则不符合。如果是 dg= 的话,就只有 d、dg 这两个符合了。\r\n[实例]
:%s/The|All/test/g\r\n 全文中只要是 The 或 All 都会被替换成 test。注意,如果文中有 There 也是会被替换成 testre!要如何避免这种情形呢?下面会另述及限定使用法。\r\n[实例]
/123-=4567\r\n 这样会找出,123-4567 及 1234567。当然 123-456789 也是会被找出来。\r\n[...] 字元集合,表示中括号中所有字元中的其中一个。
[^..] 这是上述 [...] 的补集,表非中括号内字元的其中一个。
. 除换行字元外的任一单一字元。指本身,非指前所绑之字元。就好像 shell 中的 ? 一样。如果要指定真正的英文句点,要用 来 escape,就是说 . 这时的 . 是代表真正句点,而不是 regexp 中的特殊意义。其他如 * 亦同。
[实例]
[Aa]\r\n A 或 a 其中的一个。\r\n [12345]\r\n 12345 其中的一个数目字。可用 [1-5] 来表示。连续性的数目字或字元可用 - 来隔开,写出头尾来代表就可以了。[0-9] 就表 0 到 9 的数目字,[a-d] 就代表 abcd 四个英文字母。\r\n[实例]
W[0-9]*.cc\r\n 这个例子是说以 W 开头,后接 0-9 其中一个或多个数目字或不接什么,然后是一个句点,最后是 cc。所以 W.cc,W1.cc,W2.cc,W345.cc,W8976543287.cc 皆符合。如果要表示 W 及 .cc 间夹一个以上的数目字,要写成 W[0-9][0-9]*.cc。\r\n[实例]
.*\r\n 这代表任意字元或字串,或什么都没有,脑筋急转弯,对照前面的定义想 一下。\r\n[实例]
[^M]\r\n 表除 M 以外的任意字元。
[^Tt]\r\n 表 T 及 t 以外的任意字元。
[^0-9]\r\n 表非数目字之字元。
[^a-zA-Z]\r\n 表非英文字母之字元。\r\n注:\r\n注意,^ 要在中括号内,且在最开头的地方,否则另有含意。^ 匹配行首,指其后绑住的字串,出现在行首才符合。$ 匹配行尾,指其前绑住的字串,出现在行尾才符合。含换行字元。
不是在行首的 ^ 指的是 ^ 这个字元。不是在行尾的 $ 是指 $ 本身这个字元。
[实例]
/^What\r\n 这样只有在行首的 What 才会被找出来。注意! Whatever, What\'s 也是会被找出来。如果是 /What$ 则是在行尾的 What 才会被找出来。\r\n[实例]
^$\r\n 这是什么东东?行首也是行尾的行。ㄚ,就是空白行嘛!当然也不能说这个行是没有什么东东啦!空白行至少也是会有个换行字元。在后面会详述如何消除全文的空白行。\r\n(...) 记忆 pattern,可由 1, 2...9 来叫出。
[实例]
:%s/([a-z])1/test/g\r\n 这样 aa, bb, cc, dd, ..., zz 都会被 test 替换掉。这和 :%s/[a-z][a-z]/test/g 是不一样的意思,后者会把 aa, ab, ac... ba, bb, bc...zz 都换成 test。也就是说 (...) 由 1 叫出时会有对称性的配对出现。\r\n[实例]
:%s/(.)(.)r21/test/g\r\n 会将中间为 r,前有二个任一字元,后有两个具对称性的字元所组成的字串替换成 test。例如:12r21,cfrfc,7grg7 等都会被替换成 test。\r\n匹配字尾。这就是前所提及的限定用法,被 括住的 pattern 就会被限制住,使 regexp 不能再向右(左)扩充解释。
注: ed 及 perl 中可以 来表示这两个符号,但 perl 中只支援 ,ed 则 及 皆支援。在 vim 中 是表示 即 backspace 键。功能上而言,这是和 ^ $ 一样的定位样式(anchor pattern)指所绑住的字串必须是单字边界(word boundary),前或后或前后除了空白字元及标点符号外不可再有其它字元。\r\n[实例]
:%s//test/g\r\n 这样只有 abbbc 才会被替换成 test。如果没有这样限定, :%s/abbbc/test/g,那 deabbbcly 中的 \"abbbc\" 亦会被替换成 test。所以前面 :%s/The|All/test/g 可换成 :%s/|/test/g 这样一来,There 就不会被替换成 testre 了!\r\n[实例]
:%s/]*$/d\r\n 在 vim 或 elvis 里您可以如此照打,也就是 代表空白字元, 代表按 Tab 键的结果。在原始 vi 则不行,得自行按出特殊字元出来,就是 Ctrl-v Space 及 Ctrl-v Tab。或采更简单的打法:
:g/^s*$/d\r\n 还记得中介中元吗?好用吧!少打了不少字。:-) 意思就是删除含 0 或 1 个以上空白字元的行。注: 有些书中写成 :%s/^$//g 可以删除空白行,这是错误的,因为 :s 这个指令只更动一行里的内容物,但不会做删除一行的动作。\r\n& 替代变数
代表置换时合于 patern 的字元或字串。\r\n[实例]
:%s/uddddddddd>/ID:&/g\r\n 这样全文中的身份证字号前就会加上 ID: 字样,也就是说 T123456789 会被换成 ID:T123456789。还记得吗? d 就是 [0-9],u 代表大写的英文字母。加个 > 是防止 T12345678999 也被换掉。当然前面再加个\r\n 就是删去行首的二个空白啦!\r\n[实例] 将全文的 Edward 这个单字,前后加上中括号
:%s//[&]/g\r\n [实例] 将全文的 Edward 这个单字,改成大写的。
:%s//U&/g\r\n 注: ㄟ!U 不是代表非大写字母吗?喔!您搞错位置了。U 在 pattern 的位置的时候是指非大写字母的样式,即 [^A-Z],但如果是在置换字串位置的时候是指将其后的字串通通改成大写。与其相对的是 L,会将其后的字串改为小写。详细请 :h sub-replace-special。\r\n[实例] 将全文每行最后加上
这个 HTML tag。
:%s/.*/&/g\r\n 怎么样,是否已感觉到 regexp 威力无穷了呢?还是您已经快睡著了呢?:-) 不过也请您想想,如果是在没有 regexp 功能的编辑器里,范例中的一些动作您会怎么做呢?一个一个去改?\r\ngreedy 陷阱
regexp 会有贪心的倾向,什么意思呢?就是说在同一行内,如果有多个符合 pattern 的情形,会找最长的那一个。\r\n注: 注意!greedy 的特性是针对会反覆比对的 regexp 而言,例如:*, =, +, {} 等。前面所举的 .* 的例子,由于 greedy 的关系,在整篇文章中做替换时,会被当成是每一行整行,因为 regexp 会去找每一行最长符合的那一个。\r\n[实例] This is a test. Test for regexp. 如果您下
:%s/[Tt].*t/program/g\r\n 原意是想把所有的 Test 或 test换成 program 的,结果由于 regexp 的贪心,整个 \"This is a test. Test\" 会换成 program。结果原文就变成了program for regexp. 因此在全文替换时要非常小心,避免使用弹性太大的 regexp。像此例,只要下
:%s//program/g\r\n 就可以了!\r\n最后提醒您,这可不是 regexp 的全部,碍于篇幅及在下功力的问题,当然是没办法全面详尽的向各位做介绍,在下只是将各位领进门,修行就得看各位了!如果还想更深入的研究 regexp,可参考: Mastering Regular Expressions(O\'Reilly & Associates) 一书。\r\n__________________ 每临大事有静气 不信今时无古贤\r\nThis is very, very simple:\r\n:noremap <F1> #*\r\nI find this helpful when editing multiple files and I want to search for the word under the cursor in *another* file.
I then type F1, C-^, n.
Using Insert mode to insert a single character feels clumsy (you need
3 keypresses for one character), so here\'s a slightly easier way:\r\n:nmap <space> i_<esc>r\r\nNow, when in Normal mode, just press space followed by what
it is you want to insert.\r\nBUG: Repeating the insertion with . doesn\'t work.\r\n rate this tip Life Changing Helpful Unfulfilling\r\n<<Syntax highlighting is \"out of sync\", seems to correct itself with refresh ?? | easy (un)commenting out of source code >>\r\nAdditional Notes
manfred.strubegger@irm.at, July 23, 2002 2:59
Very good tip, but I prefer <C-I> as a {lhs}. It is unused and fits better to the insert logic of VIM, although it saves less key strokes.
reiss_david AT yahoo DOT com, July 29, 2002 10:30
I use
:map gt i$<esc>r
:map gb a$<esc>r
These macros were derived from one I found in a Vi FAQ.
Anonymous, May 20, 2003 10:44
yeah, both comments get to the point, but the author was looking for a way to save a keystroke. both solutions are 3 keystrokes long.
You can use the :redir command to redirect the output of an ex command to
a register and then paste the contents of the register into a Vim buffer.
For example:\r\n:redir @a
:set all
:redir END\r\nNow, register \'a\' will have the output of the \"set all\" ex command. You
can paste this into a Vim buffer. You can also write a Vim function
to do the above.\r\nFor more information, read :help redir
I love using the visual block feature to move columns around (<ctrl-v>, blockwise-visual).
However, this does not work conveniently on the last column
when lines are not of equal length. <ctrl-v> marks then a block which
is equal in width to the shortest line.\r\nIn order to pad all lines to a given width with trailing blanks
you can use the following functions:\r\n\" truncate line \'line\' to no more than \'limit\' width
function! Truncate( line, limit )
call cursor(a:line,a:limit)
norm d$
endfunc\r\n\" Pad all lines with trailing blanks to \'limit\' length.
function! AtOnce( limit )
norm mm
g/^/norm 100A
g/^/call Truncate( getline(\'.\'), a:limit )
let @/=\"\"
norm \'m
endfunc\r\nYou may alternatively use the oneliner:
:g/^/exe \"norm! 100A\" | call cursor(getline(\'.\'), 79) | norm d$\r\nI even saw someone use a standard vi (non vim) oneliner to achieve the
same, but I forgot how. Any ideas?
【 在 neman (行胜于言) 的大作中提到: 】
: 标 题: Re: win Gvim不显示菜单和工具条
: 发信站: BBS 水木清华站 (Tue Jun 8 20:47:50 2004), 站内
:
:
: 【 在 qnx (OS) 的大作中提到: 】
: set guioptions=
: map <F2> :call SwitchShowMenus()<CR>
: function! SwitchShowMenus()
: if &guioptions==\"gmrLtT\"
: set guioptions=
: elseif &guioptions==\"\"
: set guioptions=gm
: else
: set guioptions=gmrLtT
: endif
: endfunction
:
: \"gmrLtT可以显示工具条和菜单,gm仅仅显示菜单
:
:
: 你的这个功能我的那个也是能实现的,
: 本来是介绍一个经验的,结果没有说明白,:)
:
: 我的问题是:
: 1、我不想要title条, set notitle 它只是把title的文字去掉了。
: 2、窗口最大化后最下边的无用空白条太大了,看起来不美观
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这个白边确实没有什么用, 不知道哪位niu能弄掉?
: 有办法解决没有? 谢谢 :)
精华区文章阅读
发信人: vale (浅谷·等待溪流), 信区: VIM
标 题: VIM中不易发现的强劲功能
发信站: BBS 水木清华站 (Mon May 31 10:54:41 2004), 站内\r\n在我最初使用Vim时,有些功能并不知道,等发现后真后悔自己干了那么久的体力活。\r\n1. * (super star)
向下查找光标下(或附近)的<word>。向上找用#。g*查找则不限制whole word。\r\n2. C-R (magic insert)
在insert模式下,C-R (register) 插入register里的内容,一个有趣的reg是\"=\".
假设你想输入123K的具体字节数,不用打开计算器,试试这个“<C-R>=1024*123<CR>”,
“125952”就出来了!
另外在命令行里C-R C-W和C-R C-A是必用的技巧,它们将光标下的<word>和<WORD>
考到命令行里,省了你无数的typing。\r\n3. C-X (auto complete)
在insert模式下,C-X C-P/N/L/F等自动完成前面的词、行、文件名等,是编程时必用的
命令。其中C-P和C-N可以不用C-X。\r\n4. [p & ]p (smart paste)
paste同时自动根据目标行的缩进调整来源行的缩进。在copy代码段的时候非常有用。\r\n5. C-O (fast out, fast in)
在insert模式下,用C-O后可以执行一个normal命令,然后立即返回insert模式,省去了
用ESC的麻烦。\r\n6. [I (fast grep )
[I显示文件中包含光标下<word>的所有行。我常用来浏览某个id在程序中的引用情况。
还有很多相关的命令::h include-search\r\n7. object-select
iw, aw, ib, i], i} ... 都非常有用!看help吧
:h object-select\r\n先写这么多,以后再补充吧。\r\n例如你想把所有的\"...\"形式的串替换成\'...\'的形式
但引号里的内容不变
你就可以用
%s/\"\\(.*\\)\"/\'\\1\'/来做
上面这个正则表达式\"\\(.*\\)\"里 \\用来表示()是元字符
第一个在括号里的被匹配的串就可以被\\1来代表, 以后依次是\\2 \\3。
顺便说一句,我到现在还不
知道怎么限制vim里正则表达匹配的贪婪算法。\r\n------------------------------------\r\n里面说的非贪婪匹配是 \\{-},
也就是 %s/\"\\(.\\{-}\\)\"/\'\\1\'/g
\\ 太多了可以用 \\v,
%s/\\v\"(.{-})\"/\'\\1\'/g
详细
:h /\\{-
:h \\v
另外 和 perl 正则表达式的区别在 :h perl-patterns
把aaaaa.20300.2000.com 替换为aaaaa.com
~字符 ~~~~~数字和点\r\n我用s/\\(^.*)\\(\\.\\d*.\\)com/\\1.com/
结果为 aaaaa.20300.com
请问有没有好点儿的办法?谢谢\r\n
☆─────────────────────────────────────☆
alphatan ( C ) 于 (Tue Aug 10 09:27:19 2004) 提到:\r\n【 在 qiaolin (风儿) 的大作中提到: 】
: 把aaaaa.20300.2000.com 替换为aaaaa.com
: ~字符 ~~~~~数字和点
: 我用s/\\(^.*)\\(\\.\\d*.\\)com/\\1.com/
1. \\(^.*\\) 一下子把整个字符串吞进去了. \\1 = aaaaa.20300.2000.com
2. 遇到com把 com从\\1中吐出来. \\1 = aaaaa.20300.2000.
3. 遇到.把com前面的\\.吐出来 \\1 = aaaaa.20300.2000
4. 遇到\\d*, 再把随后的2000吐出来 \\1 = aaaaa.20300.
5. 遇到\\., 把.也呕出来了. \\1 = aaaaa.20300
所以, 得到你要的结果.
可以用\\{-}进行非贪婪匹配.\r\n但为什么不直接把数字跟它们的点去掉呢?
s/[0-9.]\\+//g\r\n: 结果为 aaaaa.20300.com
: 请问有没有好点儿的办法?谢谢
☆─────────────────────────────────────☆
qiaolin (风儿) 于 (Tue Aug 10 09:36:27 2004) 提到:\r\n谢谢大侠,有问题请教:
贪婪匹配的顺序是怎样的呢?
在这个例子中,先匹配第一个pattern,再从最后面的pattern一个一个“吐”出来?
【 在 alphatan ( C ) 的大作中提到: 】
: 1. \\(^.*\\) 一下子把整个字符串吞进去了. \\1 = aaaaa.20300.2000.com
: 2. 遇到com把 com从\\1中吐出来. \\1 = aaaaa.20300.2000.
: 3. 遇到.把com前面的\\.吐出来 \\1 = aaaaa.20300.2000
: 4. 遇到\\d*, 再把随后的2000吐出来 \\1 = aaaaa.20300.
: 5. 遇到\\., 把.也呕出来了. \\1 = aaaaa.20300
: 所以, 得到你要的结果.
: 可以用\\{-}进行非贪婪匹配.
: 但为什么不直接把数字跟它们的点去掉呢?
: s/[0-9.]\\+//g
这里没有这样用是因为aaaaa也可能是a123a,可不可以用/w呢?
在查找、替换命令 使用以下正则表达式元字符,功能强大。
也可用在:g/命令中\r\n& 代表最近匹配串
~ 代表最近替换串
. 任一字符
^ 行首 或 表示 非
$ 行末
\\< 词首
\\> 词尾
* 0次或多次
\\( \\) 分节指定与其中正则式匹配的部分,在替换时候可以用 \\1 \\2 \\3 ... 引用匹配部
分
[] 表示选择
- 表示范围 ,例如 [0-9]代表数字,[a-z]代表小写字母 [^0-9a-zA-Z] 代表非数字和大小
写字母
\\{m,n\\} 前面部分的从 m 次 至 n 次出现,m n 为数值
\\{m\\} 精确m次出现
\\{m,\\} 大于等于m次出现\r\n以下举几例子,欢迎大家提出问题来共同探讨。
1.在20列后插入串
:%s/^.\\{20\\}/&insert something here/g\r\n2.把C++语言里 //注释 修改为 /* */ 格式
:%s/\\/\\/\\(.*\\)$/\\/\\*\\1\\*\\//g\r\n3.在建存储过程的sql文本里,在每个create procedure procname()
前加上drop procedure procname ; [ ]里输入的是一个空格和TAB键。
:%s/^[ ]*[cC][rR][eE][Aa][tT][eE][ ]*[pP][Rr][oO][cC][eE][dD][uU][rR][eE][ ]*
\\([^(]*\\)/drop procedure \\1;Ctrl_VCtrl_Mcreate procedure \\1/g\r\n----------------\r\n数字加减, CTRL-A, CTRL-X\r\n----------------\r\nvim里自动缩进一段
把光标移动到某个花括号,
按 =% 缩进整段。
把整段不按格式往外缩一个tab
>%
缩两个
>>%
往里缩
<%\r\n注意%匹配很多东西,
如果你想从
#ifdef
缩到
#endif
也可如此\r\ntry :help c_CTRL-R
:help c_CTRL-D\r\n<C-R><C-W>: 将光标下的keyword拷贝到命令行缓冲区中
<C-R>*: 从系统剪贴版中拷贝内容
<C-R>=: 表达式求值
<C-R>\": 拷贝buffer中的内容
....\r\n<C-D>: 命令和文件提示
常用命令:
------------------------------
CTRL-Z vim 切换到后台\r\n :g/xxx 列出所有含 xxx 的行; 适合想到含 xxx 的某行, 但不知道行号,
/xxx 又太慢\r\n q: q/ q? 编辑长命令时比较舒服, 执行按回车, 按 CTRL-C 再次进入
: / ? 原来的输入状态, 再按一次关闭.\r\n CTRL-W= 所有窗口等高, 适合 diff 时自己移动了 window 大小
CTRL-Wo 等效于 :only
CTRL-Wc 等效于 :close!\r\n gvim -u 用 NONE 的话必须大写, 可以用 nul 文件, gvim -u nul, 而且不
区分大小写\r\n -s 执行脚本文件, 是 normal 时的指令, cmd 的命令要 :, 但不用加<CR>
-w 把所有按键记录 appedn 到指定文件中
-W overwrite
这 2 个适合不会 perl sed 的 vimer\r\n --servername
--remote-silent 这 2 个搭配着用, 可以总在一个 vim 里打开新文件, 比如
gvim.exe --servername smarter --remote-silent test.text
命令太长, 可以自己 alias 一下(win32 下用 doskey 就可以)\r\n 再次选中 上次选中的内容, 用 gv
在选中的区域首尾跳动, 用 大写 O\r\n :redi 把输出信息重定向, 比如 保存所有 set 选项到 剪切板
:redi @*
:se all
具体 :h redi\r\nc\\c++ 下常用的:
------------------------------
[[
]] 在 C 的 {} 形成的段落中移动 (在第一列 { 之间跳动,
一次一个函数,一个结构或类的定义)\r\n [# 和 ]# 在 #if #else #endif 的上下位置间移动
[{ ]}
[( ])
[/ ]/ 在注释 /* */ 间移动
这样在这些块的中间位置, 就能迅速到块头和块尾
如果已经在这些行上, 如果不是到对应点,
会到上一级范围, 如 { 上按 [{ 到上一级
]} 则到对应点\r\n (vim 里常用 [ 表示 \"向上\",
] 表示 \"向下\",
比如上面的例子, 以及 [i ]i, diff 时候的 [c ]c 等)\r\n % 在 () {} [] #ifdef #endif /* */之间跳转
可以 :so $VIMRUNTIME/macros/matchit.vim
这样可以在 if endif <tr> <\\tr> 之间使用\r\n 对 1 个块的操作, 具体 :h v_a
里面的 iX aX 什么的都很好用\r\n ctags 用 -a 附加新 tags 到 ctags 文件后\r\n --- 对 c
--- ctags -R --c-types=+px d:\\mingw\\include (etags)
--- 因为 ctags 确省不把函数声明作为 tag\r\n --- 对 c++
--- ctags -R --language-force=c++ --c++-types=+px --verbose --extra=+q
extra=+q 用来增加生成 Class::member 的形式, 默认没有
这样就可以用 :ts CView::OnDraw 这种形式看
--- 因为 c++ 一些头文件不用 .h 所以要用 --language-force\r\n --- 对 java
--- ctags -R --languages=java c:/jdk131/src
--- 要把 src.jar 展开\r\n :che 检查 include 的文件在 path 中是否存在, 注意会递归验证\r\n插入模式
------------------------------
insert 模式下的:
CTRL-W 回删一个 word, 具体 :h i_ctrl-w
CTRL-U 回删在当前行输入的内容\r\n CTRL-R 用某个 reg 的内容\r\n CTRL-E
CTRL-Y\r\n 0CTRL-D 这 2 个对缩进, 具体 :h i_0_CTRL-D
^CTRL-D\r\n CTRL-C 退出 insert\r\n 另外, ascii 第 1 - 26 个对应的就是 CTRL-A 到 CTRL-Z
所以下面几个也常用
CTRL-H 对 <BS>
CTRL-J 对 <LF> vim 里叫 <NL>
CTRL-M 对 <CR>\r\n 不使用 ab: 输入 缩写 后, 按 ctrl-v 接着输入以后的字符
发信人: sysfree (虫), 信区: VIM
标 题: 插入模式下的命令汇总
发信站: BBS 水木清华站 (Wed Nov 17 14:36:29 2004), 站内\r\n插入模式下有用的键盘命令:
(注意:以下命令都是在插入模式用的,也就是左下角要显示\"--Insert--\")\r\nCTRL-[ or CTRL-C: 退出插入模式。如果嫌<Esc>太费事,可以试试这个。
CTRL-A: 插入先前插入过的内容。看起来比较有用,但是飘忽不定,很难把握。
CTRL-N/CTRL-P: 搜索匹配,自动完成单词(超级有用)。
CTRL-R: 插入寄存器内容。例如<C-R>*会插入windows剪贴板的内容。:reg命令查看全部寄存器。
CTRL-T/CTRL-D: 将本行缩进/去缩进,无论光标在什么位置
CTRL-Q: 当CTRL-V不能用时,可以试试这个。
CTRL-Y: 输入和上面一行相同的字符。有时候可能用的着。
CTRL-E: 输入和下面一行相同的字符。
CTRL-X: 进入CTRL-X模式。\r\nCTRL-X模式基本上是用来自动完成的。vim的自动完成可以包含当前文件、头文件、tag文件、字典文件等。
CTRL-X模式中的主要命令:
CTRL-X CTRL-L: 整行自动完成
CTRL-P/CTRL-N: 在当前文件中自动完成单词
CTRL-I: 在头文件中查找匹配的单词
CTRL-]: 在tag中补全单词
CTRL-F: 自动完成文件名
CTRL-D: 在头文件中查找宏定义
以上命令都可以再紧跟CTRL-P或CTRL-N,表示继续向前或向后搜索。
例如:按CTRL-X CTRL-L补全了一行,但不是自己想要的,可以继续按CTRL-L查找,也可以按CTRL-P或CTRL-N继续查找。找到后如果再按CTRL-X CTRL-L将会把找到的那一行的下面的行也复制过来,很过瘾吧?
下面两个命令也在CTRL-X模式,但是不属于自动完成:
CTRL-X CTRL-E: 在插入模式下让屏幕往上滚一行
CTRL-X CTRL-Y: 同上,屏幕下滚一行\r\n其它不常用的命令没有列出。欢迎补充。\r\n去掉菜单 set go-=m
去掉工具条 set go-=T
去掉右边的滚动条 go-=r
去掉下边的滚动条 go-=b
4 最好的办法,编辑_vimrc.
加入set fileformats=unix,dos,mac
不管什么格式都可以识别了。按说vim可以自动转换的,不知道为什么
要自己加,我的是vim63 windows版。
你想要的是 \'cscopequickfix\' 这个选项吧?\r\n首先,你要设置 \'cscopequickfix\' 这个变量,比如
set cscopequickfix=s-,c-,d-,i-,t-,e-
再打开 quickfix 窗口
copen
然后,比如你要找出所有出现 elephant 的地方,可以
cscope find s elephant
所有的结果都显示在 quickfix 窗口里面了,可以双击或者回车来选择。\r\n发信人: ann77 (ann), 信区: VIM
标 题: Re: 请教如何将vim和编译器整合使用
发信站: BBS 水木清华站 (Wed Jul 7 12:49:16 2004), 站内\r\n我做了一个试验,也许对你有帮助。\r\nVIM和其他编译器一起工作的原理就是把
compiler 的stderr 重定向到一个临时文件中。\r\n然后用 :cfile 打开这个临时文件,
用 errorformat 来解释临时文件的内容。\r\n下面我的具体做法,
我是在 BASH 下。
$for i in * ; do echo \"2:$i:$(head -n 1 $i)\" ; done > x
生成一个错误文件,内容如下
2:scr:#!/bin/bash
2:screenshell:#!/bin/bash
2:view-data.py:#!/usr/bin/python
2:view-data.sh:#!/bin/bash
2:x:2:scr:#!/bin/bash
每一行的格式就是
行号:文将名称:错误信息。\r\n然后用 vim
:set errorformat=%l:%f:%m\r\n设定 errorformat 的格式, :help errorformat for more information
:cfile x
打开错误文件。\r\n然后就可以想 make 出错的时候一样,打开每一个文件的第2行了。\r\n
我认为,你切换到了新的 compiler 后,你要做的事情就是
观察新的 compiler 的错误输出,编写一个新的 errorformat
就行了。\r\n调试的时候,可以
$ make 2>temp-error-file
然后 vim 中
:set errorformat=?????
:cfile tmp-error-file\r\n【 在 Charity (花无缺) 的大作中提到: 】
: 在RH下,我已经习惯了
: GCC + Vim + Make整合使用,
: Vim好像可以直接利用GCC编译器生成的Error List,
: ...................
标 题: Re: 如果查看一个10000000行的文件,如何提高速度?
发信站: BBS 水木清华站 (Fri Jul 23 11:03:37 2004), 站内\r\n只要就是颜色高亮引起的, 只要syntax off 或是set filetype= 就可以了
这个在打开那些一行xml文件时尤其明显(xml可以set filetype=html)\r\n【 在 thinelephant (严重消化不良) 的大作中提到: 】
: 主要是翻页的速度,如果向下一点一点的翻页速度还可以,但是向上翻页或者滚动就很慢,或者跳到文件末也要等一会。退出也要等一会。
: 呵呵,我已经找到解决方案了:只读打开,set compatible,syntax off。
: 速度不错,关闭也是瞬间。
: ...................
\'d\r\nd 表示0-9的数字,
代表最近打开的文件
发信人: windblown (......), 信区: VIM
标 题: Re: 问一个替换怎么写
发信站: BBS 水木清华站 (Tue Dec 14 10:08:39 2004), 站内\r\n用sed吧
sed -e \'
:REPEAT
s/\\([[:alpha:]]*\\) \\([0-9]*\\),/\\1 \\2\\n\\1 /
t REPEAT
\' yourfile\r\n【 在 thinelephant (严重消化不良) 的大作中提到: 】
: 每一行都是 \\S\\+ \\(\\d\\+,\\)*\\d\\+ 的形式,想把每行的逗号分割的数字展开成多行。
: 例如
: elephant 13,18,19
: ...................
vim 使用的一些小技巧。 \r\n在每行后面插入一行68个-号,用下面的命令:
:%s/\\n/\\r---------\\r/
暂时没弄明白前面为什么用\\n,而后面用\\r。\r\n
vim的列模式。
在命令模式下,按v(or V)可进入可视模式,但是只能按行选择。要进入列模式,使用ctrl+v。\r\n
VI是VIsual editor的意思,ex是他的“不可视”版本。如果多许多文件进行同样的编辑,用vim一个一个弄,就显得很麻烦。这种情况,我们可以采用ex进行自动化处理。例如要把当前目录下所有的html文件编码由big5转换成gb2312,可以执行下面的脚本:
#!/bin/bash
for I in *.html;do
ex - $I<<EOF
:set encoding=big5
:setfileencoding=gb2312
:wq
EOF
done\r\n
基于GTK2的gvim在gbk的locale下,菜单和编辑区中文字全乱码,而gb2312和utf-8 locale下均正常。解决办法:在自己的home目录下,创建一个.gvimrc文件,其中包括:
set encoding=gb2312
source $VIMRUNTIME/delmenu.vim
source $VIMRUNTIME/menu.vim
其原理似乎也是使用了gb2312的locale。gvim(GTK)本身不支持gbk?\r\n
vim具有的fold功能,可以把相连的某些行折叠起来,在需要的时候展开。
选中要折叠的行,zf命令创建一个fold并折叠起来,zr命令展开。z打头的很多命令都和fold操作有关,具体请:help z\r\n
假设你在编辑一篇html文件,可以使用如下命令对它进行排版:
:%!tidy -iq
tidy是一个html/xml格式化工具,同时还具有查错和转换功能。\r\n
vim对很多源文件提供彩色显示功能,能否把vim中显示的彩色发布到web上呢?下面的命令能帮你完成。
:TOhtml\r\n
使用y命令在vim中复制的时候,可以保存在a-z26个寄存器中,其实还有两个寄存器可以使用:*和+,放置在*寄存器中的文字(\"*yy),可以通过鼠标中健粘贴到其它程序中,比如mozilla,+号寄存器中的文字(\"+yy),通过右健菜单中的paste粘贴出来。反之亦然。(这一招学到smth上acura的,在此表示感谢!)
********************************************************************************
件,然后在里面加入一行就可以打开所有的编码的文件了(暗爽):\r\nset fileencodings=ucs-bom,utf-8,cp936,big5,euc-jp,euc-kr,latin1
保存从新起动vim,打开文件 ok了。说到这里我感觉vim里面还有一个显示行号和语法高亮是我常用的功能,每次在 vim里面输入syntax on太他吗的烦了,我这种懒人是不能容忍这种事情发生的,算了,往里面在写两行字符,让他打开的时候自动的开启吧:\r\nset nu #打开显示行号的功能
syntax on #打开语法高亮的功能
这样打开一个源代码文件感觉就比较爽了,效果太好了,不好,这么正规的软件代码也有bug ,我改改,去除那个bug section,我自己往里面写,输入代码,可是怎么不会自动缩进呀,这让我们这些人怎么能够忍受呀,好了,听说有个vim给写好的配置文件,是推荐的,拷贝了直接使用,估计就可以了,在终端输入命令一条吧。 \r\ncp /etc/vim/vimrc /usr/share/vim/vim63/vimrc_example.vim
好了,就这样从新打开 vim,一切 ok 了,如果能有鼠标控制,有 menu 就更好了,我们继续添加,不就是网 .vimrc 里面加己行字吗,呵呵:\r\nset mouse=a #加入鼠标支持
set wildmenu
这样就差不多了,基本上可以满足一般人的需求了,可是我这种程序源的话可能在读源代码的时候会经常的在多个文件中间转换,如果每次都退出在用vim 打开的话很麻烦的,怎么办,分屏打开多个文件,这个可以,使用:new命令就可以,可以分屏的,但是我的可是15 的显示器,分分还有什么呀,还是想个其他的方法吧,能不能用一个简单的命令在不退出vim的情况下来回转换呀,答案是肯定的,伟大的 vim什么做不到呀。还是在.vimrc里面加入几句话,不过这才麻烦点,呵呵\r\nif has(”unix”)
map ,e :e <C-R>=expand(”%:p:h”) . “/” <CR>
else
map ,e :e <C-R>=expand(”%:p:h”) . “\\” <CR>
endif
保存重新打开 vim,然后用 vim 打开一个源代码文件,在正常模式下输入,e 就会有一个框出来,上面罗列了当前目录下的所有文件,你用 tab 建来选择打开那个文件,太爽了。基本上 vim 的东西就这些了,还有的就是一些汉化的了,我在 linuxfans.org下载了 vim 的中文文档,解压安装了,使用的不错,我先去吃饭,回来继续。
********************************************************************************
vim tips 之五\r\n \r\n
vim设置自动格式化文本:\r\n \r\n源码:--------------------------------------------------------------------------------
:set formatoptions=croamq\r\n :help formatoptions 看帮助;
t 在文本宽度内,自动换行,对注释行无效;
c 对于注释,在文本宽度内自动换行,并自动插入注释前导;
r 在插入模式下,回车后自动插入当前注释前导;
o 在正常模式下,用o或O插入空行时,自动插入当前注释前导;
q 允许用\"gq\"格式化注释。但格式化不改变空行或只带注释前导的行。
m 对于255以上的多字节字符也进行断行。这对于每个字符就是一个字的亚洲文本特别
有用。
n 对于带. ) ] }的数字,如1., 1)等等,自动换行对齐;要求自动缩进选项ai打开。
例如:1. test
wraps.
2. test2...
********************************************************************************
具体的可以help看帮助\r\n讨论到的自动缩进是 autoindent
主要是 c 代码等
拷贝粘贴 就在已经缩进的基础上再缩进 很不美\r\n于是就可以 set noautoindent 解决
或者设置 set paste\r\n具体 vim 网站有 Tips
Tip #330: how to stop auto indenting
http://www.vim.org/tips/tip.php?tip_id=330
********************************************************************************
摘要:vim的一个有趣的用法
\r\n
如果想在vim里面达到这个效果,在vimrc中加入一下两行:
au BufWinEnter *. exe \'set list listchars=tab:\\|\\ \'
au BufWinEnter *. exe \'command Seetab :set list listchars=tab:\\|\\ \'\r\n当你编程序时, 就会达到这个效果. 源自:http://www.vim.org/tips/tip.php?tip_id=460\r\n用法:
当你不想看到对齐线时 在vim的normal模式下 :set nolist
如果你想看到对齐线时 在vim的normal模式下 :Seetab
在我们谈起Vim编辑器似乎只是觉得他只是一个类似于一个命令行方式的文本编辑器。而事实上不是这样的。Vim在窗口环境中也可以完美的完成我们的工作。在窗口环境下,我们不仅可以使用那些在Vim文本方式下的命令来完成工作,而且还有许多的菜单和其他的选项。这些都使得我们可以完美的来完成我们的工作。
我们要启动图形界面的Vim可以用下面的命令:gvim file。这样就可以打开图形界面来编辑文本file。图形界面下的Vim编辑器的外观因你所用的操作系统的不同而有所不同,就是同样的操作系统也会因你所使用的工具集不同(Motif,Athena,GTK)而会呈现不同的外观。而值得向大家推荐的是GTK版本的Vim编辑器,当然其他版本的也是可以来完美的完成我们的工作的。
在Windows系统中我们可以在标准形式下用鼠标来选择文本,而在X Window系统中我们也会有一个标准的系统来使用鼠标,但是这两种标准是不同的。然而比较幸运的是我们可以定制我们的Vim编辑器。我们可以使得我们的Vim中的鼠标的行为看起来像是X Window系统中的鼠标的行为。下面的命令是设置鼠标的行为为X Window风格的鼠标行为::behave xterm。而下面的命令则是使得鼠标的行为是Windows风格的行为::behave mswin。在UNIX和Linux系统中的鼠标风格是xterm风格,而在Windows中的鼠标风格是在安装过程中选择的。为了控制鼠标的行为,命令:behave有以下这些选项:
Setting for Setting for
Option :behave mswin :behave xterm
\'selectmode\' mouse,key (empty)
\'mousemodel\' popup extend
\'keymodel\' startsel,stopsel (empty)
\'selection\' exclusive inclusive
xterm的鼠标风格的行为主要有以下一些:
左键: 移动光标
拉动左键: 在可视化模式下选择文本
右键: 选中光标处到右键点击处的文本
中键: 在光标处粘贴选中的文本
Windows的鼠标风格的行为主要有以下一些:
左键: 移动光标
拉动左键: 在选择模式下选中文本
<S-Left Mouse> 选中到光标处的文本
<S-Right Mouse> 显示弹出菜单
中键: 将系统剪切板中的文本粘贴到文件
(注:其中的S为Shift键)
其他的一些特殊的用法:
Shift+左键: 向前搜索光标处的文本
Shift+右键: 向后搜索光标处的文本
Ctrl+左键: 跳转到以光标处的文本为名字的标记(tag)处
Ctrl+右键: 跳转到前一个标记处
在图形界面的Vim编辑器还有一个有趣的特征,那就是当我们点开一个菜单时就会发在子菜单的第一行有一条虚线,点击此虚线就可以将这个菜单移其他的地方。关闭后Vim的菜单结构又恢复到正常的状态了。在GTK版本和Windows版本中的图形界面的Vim还有一个工具栏,这些工具可以快速的完成我们的工作。\r\n \r\n
vi编辑器的学习使用(一)
vi编辑器是Unix的世界中一个相当强大的可视化编辑器,有人曾这样的说过在世界上有三种人:一种是使用Vi的,另一种是使用是Emacs的,剩下的是第三种人。由此可以看出Vi和Emacs的强大。在有关Linux的论坛中关于Vi和Emacs的论争也是一直不断的。现在看来这样的论争也实在是没有办法的,这两个编辑器是同样的强大,同样有不同的人在支持。在个人看来就是同时喜欢这两个的。然而他的这种强大也是要会付出一定的代价,他的学习和使用也是相当的复杂的,在学习的起点常常会面临着一个巨大的学习困难。但是只要过了这样的一段时间你就可以来体会Vi的强大了。\r\n一 Vi的启动与退出在现在的Linux世界中还有一个发行版本被称为是Vi的改进版本,所以被称为是Vim,也就是Vi Improved的意思。在现在的一般的Linux的发行版本中常常是Vim的。要启动Vi可以终端窗口输入vi或是vim,这样就可以终端窗口打开一个Vi的编辑窗口。或者是输入gvim,这样就可以打开一个类似于gedit这样的文本编辑器,他有一些菜单,但是大部分的功能仍是通过命令行的方式来完成的。在vi中有两种模式:一是命令模式,一是编辑模式。命令模式是用来输入命令行来完成工作的。而编辑模式是用来编辑文本的。在两种模式中切换可以通过Esc来完成。在我们完成了文本编辑以后可以这样的来退出:\r\n:q 这是退出的命令,如果你已经做过了改动,那么就会提示错误。\r\n:q! 这也是一个退出命令,与上一个不同的是,我已经做过了改动,但是我想放弃这些改动,从而用这样的命令。\r\n:w 这是文件写入的命令,但是执行完这个命令后并没有退出vi. \r\n:wq 这个命令的意思是保存并退出\r\n二 Vi的基本编辑命令在启动了Vi以后是在命令模式的,这是可以输入i(insert)进入插入模式。这时会在Vi窗口的下端显示出你这时的状态。这时你就可以来输入文本了。在这样的情况下,你可以用Backspace来Delete来删除一个字符。用方向键来控制光标。其实在知道了这样的几个命令后就可以用来编辑文档了。但是这样的几个命令并不能保证你能高效的来完成你的工作。而事实上在命令模式下我们用键盘来移动光标而不用将手离开键盘去按方向键,这样就可以大大的增强你的编辑速度。\r\n我们可以用h(left),j(down),k(up),l(right)这几个键来移动光标。我们可以将光标放在一个字符上同时按下x键来删除这个字符。\r\n我们可以将光标放在某一行同时按下dd,这样就可以将这一行删除。\r\n当然有的时候也许我们做了一些事情,不过我我们觉得以前的要更好一些,我们想要恢复到以前的状态,在这样的情况下我们可以u和U这两个命令。u要撤销上一次的修改,而U将是撤销所记录的所有的修改。\r\n而有的时候我们觉得现在的工作要好一些,我们希望撤销刚才所做的撤销工作,也就是我们要重做这些工作,这时我们可以使用CTRL_R命令来达到我们的目的。\r\n有时我们可以使用新增的命令,使用a和A来完成这样的工作。a在当前光标所在的字符后面进入插入状态,而A是在一行的末尾进入插入状态。使用这两个命令可以方便我们进行文本的插入操作。\r\n在vi的编辑模式中,是将回车换行看作新的一行的开始。有时我们希望新插入一行,这时可以使用o和O这两个命令来完成。o是在文本的下面新增一行并进入插入模式,而O是在文本的上一行新增一行并进入插入模式。\r\n有了这些命令,现在的我们就可以比较方便的来完成我们的文本编辑工作了。但是有时候得到在线的帮助对于我们来说显得更为重要,要得到vi的帮助,可以在命令的模式下输入:help,这样就可以得到vi的在线帮助了。要想退出帮助,可以输入退出命令,:q.\r\n为得到更明确的帮助,我们可以明确的指明我们所需要知道的内容。例如我们想知道关于x一些更详细的内容我们可以输入:help x.我们要想得到其他的帮助,我们就可以这样来得到我们想要的帮助。\r\n在vi中可以使用数字和命令组合的方式得到新的命令,例如3h,这样就可向左移动3个字符。同样可以使用数字和其他的移动键进行组合来达到快速移到的目的。也可以是数字和其他的命令组合形成新的命令,例如3x就可一次删除3个字符。为了我们更快速的掌握vi的使用,vi本身也提供了一个学习的教程,只要你能耐心的做下来,我想使用vi对你来说应不再是一件难事了。进入vi的学习教程,可以在终端输入vitutor.这样就可以进入vi的学习教程,为了得到更多的帮助信息,可以在vi的窗口内输入:help tutor.这样就会得到更多的关开Tutor的帮助信息的。\r\n
vi编辑器的学习使用(二)
vi学习笔记之二在上一节的学习中,我们只是学习一些使用vi进行文本编辑的基本的命令。有了这些的基本命令我们就可以完成一般的文本编辑任务。在这一节中我们要学习一些其他的一些编辑命令,这些命令将包括其他的一些光标移动命令,如何在一行中快速的查找我们想要的东西,其他的一些文本删除和更改的命令,键盘宏和特殊字符的输入。在vi的编辑中,我们可以有多种的光标移动命令:我们可以用w命令向前移动一个字符,用b命令向后移动一个字符。就像其他的vi命令一样,我们也可以用数字来做前缀从而组成新的命令,来快速的移动。例如4w就是向前移动4个单词,而5b则是向后移动5个单词。而我们在编辑的过程中又如何来快速的移到一行的开始或是结尾处呢?在vi中$和^可以来完成这样的工作。$可以使光标移到一行的结尾处,而^可以使光标移到一行的开始处。$命令可以和数字进行组合形成新的移动命令,而^也可以和数字进行组合,但是组合后组成的新的命令中数字却不起任何的作用。在我们的文本编辑中我们就会移动光标是我们经常要做的事情,但是我们很快就会发现查找我们要找的字符串也是我们经常要做的一件事。那么如何在文本编辑中快速的查找到我们想要的字符呢?在vi的编辑命令有几个这样的小命令可以帮助我们来完成这样的工作:f是向前搜索的命令。例如fx是向前搜索字母x.利用f向前搜索的命令我们也可以快速的移动到指定的位置。而F是向左搜索的命令,也就是向后搜索。例如Fx是向后搜索字母x。与f和F这两个命令相类似的是t和T这两个命令。t命令类似于f向前搜索命令,所不同的是t搜索到时并不是将光标停在目标字符上,而是停在目标字符的前一个字符上。和他相反的就是这个F命令。当然这几个命令都可以和数字组合来形成新的命令来完成我们的工作。在搜索的工作过过程我们可以使用ESC来退出搜索而开始我们新的工作。在我们的工作中常常要求我们移动到指定的行,那么我们如何来做到这一点呢?我们当然可以使用数字和方向键组合来完成。虽然这种方式不够快速,但是确实可以来实现。而在vi中提供了一个新的命令来完成,那就是G。例如3G可以使我们快速的移到第3行。而1G则可以使我们移到文章的最顶端,而G则是定位到文章的最后一行。那么在vi的编辑中我们又如何来知道我们在第几行呢?我们可以使用:set number来叫vi加上行号,这样我们就可以很容易的知道我们所在的行号了,取消行号的命令为:set nonumber。那么在没有行号的文章中我们又如何来知道我们所处在的位置呢?我们可以使用ctrl+G命令来知道。这个命令可以清楚到告诉我们总共有多少行,而当前我们又在多少行,以及所占的百分比等信息。在我们进行编辑的过程中我们可以使用CTRL-U和CTRF-D来进行上下的翻页。当然这样的功能也可以通过功能键来实现。在我们的文本编辑过程中另一件我们要常做的事情就是文本的删除了。我们可以使用dd来删除一行,我们还可以使用dw来删除一个字符。删除的命令操作d是一个相当灵活的命令,我们可以用他来进组合来完成工作。例如d3w则是一次删除3个字符,而3dw则是指一次删除一个字符,而这样的操作进行3次,即总的是也是删掉3个字符。而在d$则是删除从当前位置到本行结束的所有字符.也d命令相类似是的c命令,这是一个更改的命令,所不同的是他在删除一个字符的同时进入插入状态,这样我们就可以进行另外的文本操作了。另一个有兴趣的命令则是.命令。.命令可以使vi重复执行刚才执行的命令。在我们进行文本编辑的时候,有时要用到合并行的命令,也就是将几行合并为一行,这时我们可以使用J命令。这个命令可以将本行和下一行合并为一行。当然,就像大多数的Linux命令一样,我们可以使用数字来使几行合并为一行。例如3J就可以将当前行下的三行(包括当前行)合并为一行。那么我们又如何时来做替换文本的工作呢?我们可以使用r的命令。例如rx就可以当前光标下的字符替换为x。我们当然也是可以用数字来组合以形成新的命令来进行工作,例如5rd就是将当前光标以后的5个字符替换为d。有时我们要进行大小写的转换,这时我们就可以用~命令。这个命令可以实现在大小写的转换。在vi中一个比较有趣的东西便是键盘宏了,这个可以使我们实现多个命令的记录,有时这样可以高效的完成我们的工作。例如我们现在的文本是 stdio.h stdlib.h math.h 但是我们都知道在C语言的编辑中我们所需要的是 #include #include #include 如何来做到?如果你有足够的耐心可以一句一句的来加,但是在这里我们可以使用键盘宏来完成我们的工作,这样我们就可以体会到他的强大之处了。开始输入qa.其中的a是一个宏的名字,我们可以用任何我们喜欢的字母来代替,q是开始录制宏的命令标志。这样我们就可以开始我们的宏输入了: ^ 移到一行的开始 i#include < 在一行的开始插入#include < $ 移到一行的结束 a> 在结束处加入> j 移到下一行 q 结束宏的录制这样当我们要使用宏时就可以输入@a,这样就可以执行这个宏了。我们还可以在执行命令前加上数字来告诉vi执行几次。这样我们就可以快速的完成我们的一些工作了。在vi的编辑中我们还可以输入一些由平常的键盘不可以输入的字符,有关这样的信息我们可以输入:help digraphs得到更多的信息。 (注:在vi中我们通常所指的一行是以回车做为标志的,即只有输入回车才算是一行的结束,从而开始新的一行)
vi编辑器的学习使用(三)
vi学习使用笔记之三我们在使用vi进行编辑文本的时候常作的一件事就是要在所编辑的文本中进行查找。如何快速的查找到我们想要的东西呢?在vi中我们可以使用f,F和t,T来进行向前或是向后查找。除了这些命令,我们还可以使用其他的一些命令来快速高效的完成我们的工作。在vi的编辑操作中,我们可以使用/string命令来查找字符串string,打下回车后,光标就能跳到正确的地方。在这个命令中/后的字符是我们想要查打的字符,而回车键则表明了命令的结束。但是有时我们所想要查找的字符具有特殊的意义,例如.*[]^%?$~等等,那么我们又如何来查找这些具有特殊意义的字符呢?这时我们可以使用\\放在所要查找的字符前,这样再使用/来查找就可以正确的查找了。有时我们在进行查找操作时想要查找的内容并不仅在一处,我们想要做的是在整个文章中进行查找。那么我们又如何来进行我们刚才的查找命令呢?我们可以这样的来做:/。这样我们就可以继续我们刚才的查找操作了。在这里回车是命令结束的标志。我们还可以使用n命令来继续刚才的查找命令。这两个命令都能达到同样的效果,但是显然用n可以有更少的键盘操作。偷懒嘛:)在vi中他还具有记录查找命令历史的作用,这样我们就不用输入刚才输入的查找命令了,而是只需要在他所记录的查找命令进行一下查找就可以了。例如你刚才做过的三次查找分别是:/one,/two,/three.而现在输入/,然后按方向键的上或是下我们就看到刚才查找的内容显示在vi的下面,这时只要打下回车我们就会找到我们要找的内容了。当然在vi中还在一些其他的查找选项,例如我们可选择高亮的显示查找的文本,命令为::set hlsearch,关闭高亮显示的命令为::set nohlsearch.如果也想同时关掉刚才高亮显示的结果,可以用这样的命令::nohlsearch。在我们进行查找的选项中,我们还可以有这样的命令::set incsearch。在我们打开这个选项以后,我们在进行查找时就会显示出不断匹配的过程。例如你想查找的内容是include,在打开这个选项后你可以输入/i,光标定位在i上,再继续输入n光标定位在in上,如此直到查打到我们所要求的。关闭这个选项的命令为::set noincsearch。一般来说我们在进行查找时总是在向前查找,那么又如何来向后查找呢?我们可以使用?命令。这个命令就是向后查找的命令。而还有一个命令N是逆向查找的命令,他可以实现立即反向查找。(注:在查找的时候我们还可以用一些其他的表达式来进行查找,例如/^string是在开头进行查找,而/string$是在一行的末尾进行查找。不过看书我的理解是这样的,不过总是试验不成。而/c.m则是查找所有第一个字母为c,而第三个字母为m的字串,由此可以实现一些查找的匹配
vi编辑器的学习使用(四)
vi学习使用笔记之四我想我们在接触了vi以前一定会用一些其他的编辑器,在那些的编辑器里复制,剪切和粘贴都是最平常的操作,而在vi中这些操作也是同样的存在的。在vi编辑器有一个注册的概念(concept of register),正是这个概念使我们可以时行多次的剪切和粘贴等的操作。在一般的编辑器中我们被限制只有一个剪切板可以用,而在vi中我们最多时可以有26个剪切板可以来使用,这样就会大大的提高我们的完成工作的效率。而在vi中更是有一个相当强大的功能那就是他可以同时处理多个文件。如此强大的功能我们又来如何的操作呢?在vi的编辑中我们可以使用d或是x来删除文本,但是经过这样的操作所删除掉的文本并没有被vi所丢弃,而是被保存起来。我们可以使用p命令来粘贴刚刚所删掉的内容。下面我们可以来试一下看一下他是如何工作的。我们可以在vi中随意的输入几行,然后我们移动到其中的一行,用dd命令来删掉其中的一行,这时我们就不会再在vi中看见他。如何叫他再回来?我们可以将光标移到任意的地方,然后用p命令,我们就会看到刚才被删除掉的内容又回来了。同样我们使用x命令来删除的东西也可以这样的粘贴回来。所不同的就是我们用dd来删除一行再用p命令时是在当前光标的下一行粘贴,而删除一个单词再用p命令来粘贴时是在当光标处粘贴。有了这样的命令有时我们就可以来处理我们输入错误的单词了。例如我们不小心将the输入成了teh,这时我们可以将光标移到e的位置,用x命令删掉,再用p命令粘贴回来,这时我们就会发现现在的输入正是我们想要的输入了。p命令可以在一个文件中使用几次,每一次都可以将刚删除的内容重新粘贴在我们所希望的地方。当然这个命令也可以使用数字做前缀来明确的指出所要执行的次数。在使用vi进行文本编辑的过程中我们还可以对某一行进行标记,做法为我们将光标移到某一行,用命令ma来进行标记。在这里m是标记的命令,a是我们对这一行所做的标记的名称,当然我们也可以使用其他的标记名称,必竟我们是有26个字母可以用的嘛:)。在做了这样的标记以后我们可以快速的移到被标记的地方,‘a就可以使我们快速的移到刚才我们所做标记的地方。这里’是单引号,这时我们就会移到被做标记那一行的行首。我们也可以使用`a来移到我们所做标记的地方,这里`是反引号,也就是数字键1左边的那一个,不要弄错了噢:),这时我们就会移到所做标记时光标所在的位置,可以说是更精确啊。这也是这两个命令的不同之处。在进行文本编辑时我们可以列出当前所做的所有的标记。命令为 ::marks。这时vi就会列出当前的所有的标记。当然如果我们将做了标记的那一行删除的话所做的标记也就不存了。我们用标记不仅可以快速的移到做了标记的行,而且还可以用标记来删除掉一行,例如我们在某一行用ma做了标记,然后我们移到这一行的底部,这样我们就可以用在d‘a来删掉这一行。可以说这也是标记命令提供给我们的方便吧。在vi中还有一个命令可以提供复制的操作,那就是y命令。yy命令可以复制一行,然后我们可以用p命令来粘贴。这时我们也可用标记命令来组合使用,我们可以在一行用ma标记此行,然后将光标移到这一行的底部,用y’a命令就可以来复制这一行了。然后到我们所希望的地方用p命令来粘贴。我们也可以使用Y命令来复制一行,或是用数字做前缀来明确的指明复制几行,然后用p命令粘贴到我们所希望的地方。在vi中还有一个比较有趣的命令便是!命令。这个命令告诉vi编辑器我们要来运行一个系统命令,这时vi就会将以后的输入做为一个命令来运行,运行的结果也就是输出将替代当前光标所在的行的内容。例如我们在 Linux中知道sort是一个排序的命令,他是将一个文件或是一些输入进行排序后输出到屏幕或是其他的文件。那么我们想对vi中的内容进行排序来如何做呢?这时我们可以将光标放在文本的开头的一行,输入!10G,这时vi就知道要到10行,也就是我们要操作的内容是第1行到第10行,这时在vi的下端就会显示出!,这时我们就可以输入命令了,sort。也就是我们要输入的完整的命令应为:!10Gsort。这样回车以后vi就会对文本中的10行进行操作,将操作的结果替换掉现在vi中的文本来显示。而!!是在一行运行命令,并且输入的结果为当前行的内容。例如我们输入!!ls,就会将ls的执行结果显示在vi中,并且是当前的内容,如果此行原先有内容将会被替换掉。如果我们完成一个文件的编辑而要开始一个新的编辑时我们最平常的做法就是退出当前的文件而重启vi开始一个新的编辑。事实我们可以直接在vi中输入:vi file而开始一个新文件的编辑。如果当前的文件你没有保存,vi会给出警告的信息,这时你可以输入:write来保存当前的文件。你也可以用:vi!file强制开始一个新文件的编辑。与vi相类似的一个命令是:view,所不同的是他以只读的方式打开一个文件,这时vi会给出警告信息,但是你也可以进行修改,只是你不能进行保存,如果你要保存,vi就会给出提示。当然在这样的情况下你可以用命令:write!来强制保存。我们还可以使用vi来编辑多个文件。我们可以在终端输入vi file1 file2 file3,这样我们就可以来编辑多个文件了,在默认的情况下vi来显示第一个文件,如果要切换到下一个文件我们可以输入:next,这样我们就可以切换到第二个文件了。如果你没有保存,vi会给出提示信息,这时也就不可能切换到第二个文件了。这时我们可以输入:write进行保存然后再切换到第二个文件,或者是我们输入:write:next.来保存后再切换到第二个文件。或者是我们可以用:wnext来简写这个命令。当然我们也可以用命令:next!来强制切换到第二个文件。当然这样你所做的改动也就会丢失掉。为了避免这样的情况,我们可以打开vi的自动保存功能。:set autowrite.这样我们就不会为没有保存而收到提示信息了。关闭自动保存的命令为::set noautowrite.当然next命令也可以用数字做前缀来指明所要执行的次数。如何来确定我们在编辑哪一个文件呢?我们可以用这样的命令来明确我们所编辑的文件::args.这个命令会显示出我们所打开的文件,同时会显示我们正在编辑的文件。如果我们想要回到上一个文件我们可以用这样的命令::previous或是:Next.如果你要保存当前的文件并切换到前一个文件可以用这样的命令::wprevious或是:wNext.如果我们要编辑第一个文件我们可以用:first或是:rewind来快速的切换到第一个文件,同理如果我们要编辑最后一个文件我们可以用:last来快速切换。如果我们在一个文件中进行一些改动,再切换到另一个文件中进编辑,这时我们就可以用CTRL_^来切换这两个文件。
vi编辑器的学习使用(五)
在使用vi进行文本编辑的时候我们也可以打开多个窗口进行编辑。这也正是vi编辑器的强大这处。那么我们如何来打开多个窗口进行文本编辑呢?我们又如何在多个文本窗口中进行切换呢?如何来控制窗口的大小呢?在vi编辑器还有一个缓冲区的概念,利用缓冲区我们可以进行多文本的编辑。打开一个窗口最简单的方法就是下面的命令::split。输入这样的命令后vi就会将当前的窗口平分为两个。并且在这两个窗口中显示的是同一篇文章。如果你在其中的一个窗口进行文编辑,那么另一个窗口也会同步的显示出你所做的工作。如何在两个窗口中进行切换呢?在gvim中要方便得多,只要用鼠标就可以进行窗口的切换。而在vim中则需要用命令来实现。CTRL_Ww这个命令可以实现在两个文本窗口中进行切换。切换窗口还有另外的命令:CTRL_Wj 可以将光标定位在下一个窗口中,而CTRL_Wk可以将光标定位在上一个窗口中。如果想关闭 一个窗口可以用命令ZZ或是:q.当然了CTRL_Wc也可以做到同样的事情。我们打开一个窗口一般并不是要在两个窗口中显示同一个文件,我们常常需要的是在两个窗口中显示两个文件来加快文件编辑的工作。如何在新窗口中打开一个文件来进行编辑呢?我们可以用这样的命令::split file.这样我们就可以在另一个窗口中打开文件file开始我们的编辑工作了:)。那么我们如何来控制窗口的大小呢?我们在输入split命令时可以带上一个参数,这个参数 也就指定了打开的窗口的大小。例如我们可以这样的输入::3 split file。这样我们就可 以在一个新窗口中打开文件file,而这个窗口的大小有三行。当然我们也可以将这个命令中的空格去掉,也就是写成::3split file这样也可以达到同样的作用。与split命令相类似的一个命令就是:new命令。所不同的就是split命令打开一个新窗口,但是在两个窗口中显示同一个文件,而new命令则是打开一个新窗口开始一个新文件的编辑.我们还可以打开一个新窗口,在这个窗口中打开一个文件来读。命令为:sview。这个命令是:split和:view这两个命令的组合。在这样的多文本窗口中进行操作时我们常做一个工作就是要改变窗口的大小。可以使我们来改变窗口大小的命令为: CTRL_W+这个命令增大窗口,默认增量为1 CTRL_W-这个命令减小窗口,默认值为1 CTRL_W=这个命令可以将几个窗口的大小变得相等。另外还有一个命令countCTRL_W_可以使得当前窗口变得count这样的高。如果没有指定count将会使得当前窗口变得尽可能的最大。 :buffers 这个命令就会列出当前的编辑中所有的缓冲区状态。在这个状态列表中,前面的数字就是缓冲区的数字标记,第二个标记就是缓冲区当前的状态,而后一个则表明与空上缓冲区所关联的文件名。他的一些状态是这样的: - 非活动的缓冲区(Inactive Buffer) h 隐藏的缓冲区(Buffer is hidden) % 当前的缓冲区(current buffer) # 交换缓冲区(Alternate buffer) + 文件已经被修改如果我们要选择一个缓冲区我们可以用这样的命令::buffer number number就是缓冲区状态列表中所显示出来的数字。我们也可以用文件名字来选择缓冲区: :buffer file 关于缓冲区有一些有用的命令可以快速的完成我们的工作:我们可以用下面的命令来分割当前的窗口开始编辑一个缓冲区::sbuffer number 如果我们指明了数字,那么当前窗口就会显示数字所标记的那缓冲区中的内容,而如果没有指明数字,那么就会利用当前的缓冲区。当然这个命令我们也可以用文件名来做为参数进行操作。对于缓冲区还有一些其他相关的命令: :bnext 到下一个缓冲区 :count bnext 到下一个缓冲区执行count次 :count sbnext 命令:split 和 :count bnext组合形成的命令 :count bprevious 到前一个缓冲区count次 :count sbprevious :count bNext 与:bprevious作用相同 :blast 到最后一个缓冲区 :brewind 到第一个缓冲区
vi编辑器的学习使用(六)
vi编辑器学习使用之六在现在的vi版本,或者是说是在vim中,与其先辈区分开来的一个特征就是现在的版本中有一个可视模式。这种可视模式可以使你加亮一个文本块然后整体进行命令操作。例如你可以用高亮显示出一个文本块,然后用d命令来删除这个文本块。这种可视模式与其他的编辑相比的一个好处就是你可以在做改动以前看到你的操作对于所编辑的文本产生的影响。那么我们如何为用这种有趣的可视化模式来进行我们的文本编辑工作呢?要进入可视化模式,我们可以输主命令v,这样在vi的状态行就会显示我们已经进行可视化模式了。在这样的模式下,我们移动光标,那么在光标起始的位置和光标现在的位置之间的文本都会以高亮显示的。这时我们可以对这些高亮显示的文本整体进行命令操作,例如这时我们可以输入d命令,那么这些高亮显示的文本就会被删除掉。一般来说可以化模式可以具体的分为三种可视化模式,一种就是我们刚才用v命令进入的所谓的字符式可视模式(character-by-character visual mode)。在这种模式下,我们在进行文本选择以高亮显示时是以字符为单位的,我们可以一个字符字符的来选择。而第二种就是所谓的行可视化模式(linewise visual mode),这时我们可以输入V命令来进入这种可视化模式。这时我们所进行的操作是在以行为单位来进行的。还有一个命令可以使我们进入可视化模式,这就是CTRL_v,这就是我们所要说到第三种可视化模式,他可以使一个矩形内的文本高亮显示,然后以这些文本为整体进行编辑操作。在可视模式下我们也可以得到一些相关的帮助信息。当然在输入命令时要在所希望帮助的名称前有v_做为前缀。例如我们想得到一些关于在可视模式下进行删除操作的命令,我们可以这样的来得到帮助信息::help v_d 当我们要退出可视化模式时,我们可以按ESC键退出。当然CTRL_c也可达到同样的作用。与ESC作用相同的还有CTRL_和CTRL_N. 在可视化模式下我们可以进行各种各样的编辑操作。如d命令可以删除那些高亮显示的文本内容,而D命令只是来删除一行,哪怕这一行中只有部分文本是高亮显示的。与d和D命令类似的是复制y和Y命令。y命令是将高亮显示的文本复制下来,而Y只是将一行文本复制下来。c命令可以将以高亮显示的文本删除掉然后进入编辑模式,而C命令的作用与其相类似,所不同的只是C命令只是删除一行文本。我们还可以利用可视化模式将几行文本合并为一行。J命令可以将高亮显示的文本内容合并为一行,同时以空格来区分各行,而如果我们不希望看到这些空格,我们可以使用gJ命令。我们在可视模式下进行文本编辑时也可以进行可视化模式的选择和切换。你可以在任何情况下进行这种切换,而切换的做法只是简单的输入那种可视化的命令操作。例如现在我们在字符模式的可视化模式下进行操作,而现在我们想切换到块模式的可视化模式,这时我们只是要简单的输入CTRL_v可以了。当然我们也可以先用ESC来关闭当前的可视化模式,然后再选择我们所希望的可视化模式. 对于程序员来说似乎这种可视化模式会有更大的用处,我们可以用一种可视化模式来高亮显示文本,然后用>命令来进行文本的缩进,我们还可以用<命令来进行相反的缩进。我们更可以用CTRL_]跳转到某一个函数定义的地方。我们还可以利用可视化模式的高亮文本进行做法关键字用man命令来得到更多的信息。当然这必须是man可以查找得到的内容对于可视化模式的文本编辑还有一个有趣的现象,这个主要的表现在CTRL_v所定义的文本块内。例如我们用这个命令来定义了一个文本块,然后输入Istring,这个命令中I是插入文本的命令,string是我们要插的文本,而Esc则是结束插入操作的命令。这时就会看到我们所输入的文本显示在文本块的左侧,也就是开头的地方,当我们结束插入操作时我们就会惊奇的发现我们所输入的文本也会同时出现我们所定义的文本块内所包含的其他行的开头部分。同样当我们用c命令来操作时我们也会发现类似的情况。当然了,在用c这个命令进行操作时你所输入的文本应不超过一行,否则的话将会只有第一行的文本会被改动。而C命令也会有相类似的情况。我们也可以类似的来得到一些关于块操作的命令帮助:例如::help v_b_r
vi编辑器的学习使用(七)
vi编辑器学习使用之七
vi是一个强大的编辑器,他不仅可以用来处理我们平时的文本工作,他还可以用写程序文件。在vi中有许多命令可以方便的完成我们的程序处理工作。在用vi进行程序处理时,vi充分的显示出来了他的强大之处,他可以实现在语法加亮显示,实现自动缩进,实现括号匹配,还可以在程序中实现查找和跳转。
我们可以用这样的命令在vi中打开语法加亮显示的功能::syntax on。这样以后我们在输入的字符中,vi就会自动的识别出关键字,字符串以及其他的一些语法元素,并以不同的颜色来显示出来。这对于程序员来说是一个巨大的帮助。当然你可以自定义语法加亮显示的颜色。
一般情况下,vi的这种语法加亮显示的功能可以工作的很好,但是有时我们也遇到一些小小的麻烦。也许我们都遇到过背景是白色而字体是浅黄色的情况,在这样的情况下是非常难读的。vi编辑器有两种语法加亮的办法,一种是当背景为浅色时用,而另一种是当背景为深色时用的。当我们启动vi时,他会检测我们所使用的端是哪一种背景颜色,是浅色还是深色,然后再应用语法加亮的颜色方案。当然了,有的时候vi也是可以检测出错的。我们可以用这样的命令来知道我们的背景的情况::set background?。这样vi就会在底端给出我们具体的显示。如果vi检测的并不正确,我们可以用这样的命令来为他赋下正确的值::set background=light或是:set background=dark.当然我们要清楚的知道,这样的操作要在打开语法加亮的命令之前来执行。vi实现语法加亮显示的功能是通文件的扩展名来文件的类型从而实现功能的。但是有时我们在编辑一个C程序文件时并没有使用传统的扩展名,那么我们如何来告诉vi我们正在编辑的文件的类型呢?解决的办法就是用filetype这个选项。例如我们要告诉vi我们正在编辑的是一个C程序文件我们可以这样的来做::set filetype=c。这样以后vi就会知道我们正在编辑的是一个C程序文件并正确的加亮语法显示。
除了语法加亮显示的功能以外,vi还提供了缩进的功能。命令<<将使当前行向左移动一个移位宽度,而命令>>将使当前向右移动一个移位宽度。这个所谓的是移位宽度具体是多少呢?在vi中默认的是八个空格的宽度。然而平时的经验可以表明当缩进是四个空格宽度时最有利于程序的阅读。那么我们如何将这个移动宽度定为四个空格的长度呢?这时我们就可以用下面的命令来做到::set shiftwidth=4.而这时的命令仅是对当前的一行有效,我们也可以像其他的vi命令一样的在命令前用数字做为前缀还指定命令作用的范围。如5<<就将缩进五行。
在vi中还有许多自动进行缩进的选项,一般有以下的几种:C缩进(cindent):这是C语言的缩进形式,采用这样的缩进方式的程序语言有:C,C++,Java等。当采用这种缩进格式时,vi就会自动的采用标准的C语言形式。还有一种形式是smartindent:在这种缩进模式中,每一行都和前一行有相同的缩进量,同时这种缩进形式能正确的识别出花括号,当遇到右花括号(}),则取消了缩进形式。另外的一种缩进形式便是所谓的自动缩进(autoindent):在这种缩进形式中,新增加的行和前一行有相同的缩进形式。vi编辑器可以很好的识别出C,C++,Java以及其他的一些结构化程序设计语言,并且能用C语言的缩进格式来很好的处理程序的缩进结构。我们可以用这样的命令来打开C语言形式的缩进结构::set cindent.这样以后vi编辑器就会用C语言的缩进形式来正确的处理程序文件。一般而言C缩进结构可以满中绝大多数人的需要,当然了不同的人有不同的编程风格,如果你不喜欢这样的缩进结构,你可以自己定义自己的缩进形式。也许我们做程序设计的人并不想每一次想要编辑C程序文件时都要用命令:set cindent来打开C缩进形式,为了解决这样的问题,我们可以改写vi的配置文件来使vi能够自动的完成这样的工作。我们在.vimrc(UNIX/LINUX)或是_vimrc(WINDOWS)中加入下面的几句:
:filetype on
:autocmd FileType c,cpp:set cindent
第一行是打开vi文件类型识别功能,第二行是如果所识别的文件类型为C或是C++文件那么便打C缩进形式。
在vi中除了C缩进形式以外我们还有smartindent缩进形式可以来用。在smartindent这种缩进模式中能够正确的识别出{和}。同时增加了识C语言关键字的功能。如果一行是以#开头的,那么这种格式将会被特殊对待而不采用缩进格式。这种缩进格式不如cindent,但是却强于autoindent。另外的一种缩进形式便函是autoindent。在其他的一些结构化程序设计语言如Pascal,Per或是Python语言中,我们所希望的是新的一行能和上一行有相同的缩进形式,这时我们便可以打开autoindent缩进形式,:set autoindent。这样就可以很好的来满足我们的要求了。
vi不仅有这些功能,而且还有更多的功能来快速的处理程序文件。其中一个便是可以快速的在文件中定位变量及宏定义等。其中一些常用到的命令有:
[CTRL_I/]CTRL_I 在本文件中以及在由#include命令包含进来的文件中进行查找光标下面的文字
gd/gD 查找变量的定义
[CTRL_D/]CTRL_D 跳到宏定义的地方
[d/]d/[D/]D 显示宏定义
这几个命令中有一些需要说明的地方:[CTRL_I/]CTRL_I命令用来查找光标下面的文字,查找的范围不仅是在本文件中进行查找,而且还要查找由#include所包含进来的文件中进条查找。变显查找的命令gd和gD有时并不能完美的完我们想要做工作。这是因为vi在理解C和C++的语法方面有一些小的限制。但是大多数的情况下这几个命令还是可以很好的来完成我们工作的。[d/命令可以显示以当前光标下的内容为为名字的第一个宏定义,]d也有着同样的作用,所不同的只是后者是从当前光标处查找下一个宏定义。当然这两个命令也可以在由#inlcude所包含进来的文件中进行查找。[D/]D命令可以用来列出文件中的宏定义。这两个命令有着同样的作用,所不同的只是前者是列出当前光标以后的宏定义,而后者是从当前光标处的下一个宏开始列出文件中的宏义。(注:此处由此书看来似乎是这样的,但是自己亲自来做时并没有出现这样效果)
我们在编写程序时常常要做的一件事便是括号的匹配,我们在vi中可以用%命令来确定匹配的括号。例如我们将光标定位在其中一个括号处,然后执行命令%,光标就会定位在与其相匹配的括号处。有时我们在编写了一段程序后却想着要将这一段程序进行缩进,这时我们可以用这样的命令来做到:将光标定位在第一个或是最后一个包含着所要缩进的程序块的括号处,然后执行下面的命令:>%,这样就可以将这个程序右缩进一段距离。但是我们发现执行这个命令后花括号也一样的进行了缩进,有时我们这并不是我们想要的,我们想要的是仅括号内的文本进行缩进。这时我们又应如何来做呢?这时我们可以用这样的命令:>i{.这个命令是说仅括号内的文本进行缩进。我们还可以用可视化的模式来缩进文本块,具体的做法是这样的:
1 将光标定位在左括号或是右括号处。
2 进入可视化模式:v
3 选中括号内的文本:i}
4 缩进:>
当我们用vi来编辑我们的程序文件时,他提供给了我们定位程序函数的功能。这对于我们想要理解一个程序是非常有帮助的。vi所定位的函数被包含在一个由ctags的程序建立的文件当中。要建立一个名为tags的这样的文件,我们可以输入这样的命令来完成:$ctags *.c
这样以后当我们在vi中来编辑我们的程序文件时我们就可以任意的跳转到我们想要去的函数处,当然这得要求我们想要到函数存在。我们可以用这样的命令来到达我们要到的地方:
:tag function
这个命令甚至可以查找得到在其他文件中的函数。
在完成函数跳转的功能命令中还有几个强大而有趣的命令。CTRL_]命令跳转到以光标下的字符串为函数名的函数处。这样就大大的方便了我们在C程序查找函数的需要。例如你正在看一段名为write_block的函数程序,而在这个程序中调用了函数write_line。这个被调用的函数具体是来做什么的呢?我们可以将光标定位在这个函数上,然用执行命令CTRL_]。这样vi就会马上跳转到这个函数的定义处。我们就可以清楚的看到这个函数的实现的方法。而在这个函数中又调用了函数write_char,这时我们可以用同样的方法来查看这个函数的定义过程。命令:tags可以列出我们已经访问过的函数名称。但是我们在走了一段路以后想回去又该怎么来做呢?命令CTRL_T可以使我们回到上一个访问的函数处。我们为了在函数跳转的命令,我们要用命令ctags建立这文件来存放在C程序中所出现在的函数名,这时vi要建立一个栈来存入函数名。我们用命令CTRL_T回到上一个访问的函数处,这时我们还可以用命令:tag来向前走一步,即回到前一个访问的函数处。我们也还可以像其他大多数的vi命令一样在此命令之前用数字来做前缀,指明要执行的次数。我们还可以用这样的命令::tag function。这样我们就可以来到指定的函数处。
当我们用命令:tag时是将当前窗口中的内容由函数的内容所代替了。我们也可以打开一个新窗口来显示函数的内容。这时我们就要用到下面的命令::stag tag。这个命令是要打开一个新窗口来显示tag指定的函数内容。我们也可以用命令CTRL_W_]来打开一个新窗口显示以光标下的字符串为函数名的函数内容。我们也可以在这个命令前加下数字count做为前缀,这打开的窗口就是count这样的高度。
我想我们常会有这样的情况,那就是我们想要跳到一个函数处却记清他的名字究竟是什么?这是我们要怎么办呢?在vi中有一个很好的解决办法,那就是我们可以用:tag /name来找到你想要的内容。例如在我们上面所举过的例子中曾提到了函数write_line。但是现在我们记不得他的全名了,只是记得好像有一个line。这时我们如何来找到呢?我们可以用这样的命令来做::tag /line。这样vi就会将我们带到write_line定义的地方。我们还可以借助于一些表达式来精确的定位我们要去的地方。例子如我们似乎记得有一个函数是以read开头的,这时我们可以这样的来查找::tag /^read。这个是说read所要查找的内容是以read开头的。或者说我们不能十分清楚的记得一函数的名称是DoFile,do_file还是Do_File。这时我们也可以这样的来查找::tag /DoFile\\|do_file\\|Do_File。或者是我们可以写成这样的表达式::tag /[Dd|o_\\=[Ff|ile。这样我们就可以找到我们想要的内容了。一般情况下我们用这样的命令来查找时并不能精确的得到我们想要的东西,而是得到许多匹配的选项。而我们可以用命令:tselect来列出所有这些合要求的内容。这个列表一般由这样的一些内容组成:
第一列的数字是这些标记(tag)的编号,第二列这些内容的优先级,他一般包含三个字母:F完全匹配,如果没有则是忽略的情况;S静态标记,如果没有,则是全局标记;C则是说是这个标在当前的文件中。在执行完这个命令后,:tselect会给我们一个机会,我们可以选择到标号为哪一个的内容处去,或者是选择离开。命令g]与命令:tselect相类似,只是他是以光标下的内容为查找内容的。命令:tjump的作用与:tselect命令相同,所不同的只是当执行的结果只有一项内容时,则自动的选中这个结果。命令gCTRL_]与此相同,只是他是当前光标下的内容为查找对象的。其他的一些相关的命令如下:
:count tnext 到下一个标记处
:count tprevious 到上一个标记处
:cout tNext 到上一个标记处
:cout trewind 到第一个标记处
:cout tlast 到最后一个标记处
命令:stselect与:tselect命令相同,所不同的只是前者将打开一个新窗口来显示执行的结果。与其类似的命令还有:stjump.
当我们在编写makefile文件时我们所需要的缩进是一个tab,而不是8个空格。这样的区别是很难在屏幕上看出来的。这时我们可以用这样的命令::set list,这样以后tab则显示为^I,同时在每一行的末尾显示$,这样我们就会很好的来区分这些细小的分别了,同时还有助我们来检查我们程序的正确性。当然我们也可以选择用其他的字符来显示,通过listchars选项我们可以做到这一点。如果我们设置了expandtab选项,那么我们输入一个tab时,vi实际上插入的空格。这对于我们编写makefile文件时是很不方便的。如果我们想真正的输入一个tab,而不是插入空格,这时我们可以输入CTRL_V<Tab>,这时的CTRL_V告诉vi不要忽略以后的字符。有时在一个makefile文件中包含许多的文件,我们可以对这些文件进行排序,具体的做法如下:
1 将光标放在文件列表的起始点
2 用命令标记这个位置:ma
3 到这个列表的底部
4 执行命令排序:!\'a sort
我们也可以在可视模式下来排序:
1 移动到要排序的文本的顶部
2 进入可视化模式:V
3 移动到文本的底部
4 执行命令:!sort
vi编辑器还可以允许我们在vi中执行编译程序的make命令,其命令为:make,这时就会来编译程序,同时会显示出错误来。这时我们就可以移到到出错的地方来修正我们的错误,然后再重新编译,直到成功。如果我们的程序编译有错误,vi就会显示出错误的提示信息和错误的地方,同时vi会自动到第一个出现错误的地方。我们在修改完错误以后,可以用命令:cnext来到下一个出错误的地方继续我们的工作。命令:cprevious和命令:cNext可以回到上一个错误的地方。命令:clast可以到最后一个出错的地方,而命令:crewind可以到第一个出现错误的地方。而命令:cnfile可以到下一文件第一个出错的地方。如果我们此时忘记了出现在的错误是什么,我们可以用这样的命令来显示出错信息::cc,如果我们想看到一个错误的列表,我们可以用这样的命令来完成::clist。我们还可以用命令来显示一定范围内的错误。如:
:clist3,5 显示第三行到第五行的错误
:clsit,5 显示第一行到第五行的错误
:clsist5, 显示第五行到最后一行的错误
如果我们已经运行make命令并且生成我们自己的错误信息的文件,我们可以用这样的命令来告诉vi这些情况::cfile error-file。error-file是make或是编译输出的文件。如果我们没有error-file文件,那么我们可以使用errorfile这个选项在。退出错误的状态可以用命令::cquit.这些命令对于我们在使用一个集成的开发环境时会显得更有用一些.
errorfile选项会建立一个默认的文件,这个文件会被命令:clist和-q命令行选项所使用,但是这个文件并不会成为:make命令的输出文件。如果我们想要建立自己的默认错误文件可以使用下面的命令::set errorfile=error.list
:grep与:make相类似,他是执行外部的命令程序grep并显示输出。例如我们要在程序文件中查找变量ground_point我们可以使用下面的命令:
:grep -w ground_point *.c
-w 是告诉grep程序包仅查找单词ground_point,而不是任意匹配的结果。与前面的命令相类似,:cnext,:cprevious,:cc等命令可以在这个匹配的列表中进行移动,:crewind,:clast分别移到到列表中的第一个和最后一个。:cnfile到下一个文件是的第一个。
vi编辑器的学习使用(八) \r\nvi编辑器可以很好的完成一些我们要做的一些重复性的工作。例如我们可以在vi中设置缩写,这样当我们在输入一个单词时只需输入其中的一部分,而要vi来完其余的部分。当然了,我们可以将我们喜欢的一些设置写入vi的配置文件,这样就不要我们每一次都要通过命令来完成了。除了这个功能以外,我们还可以在vi中定义我们自己的功能按键,而不会影响到系统中的功能键。这样的功能是不是很有趣呢?
我们可以在vi中用一个缩写的字符来代替一个单词,然后在我们想要输入这个单词时只要输入这个缩写的字符就可输入我们想要的单词了。我们如何来做到这些呢?这时我们要用到的vi命令是:abbreviate.例如我们可以用ad来vi编辑器可以很好的完成一些我们要做的一些重复性的工作。例如我们可以在vi中设置缩写,这样当我们在输入一个单词时只需输入其中的一部分,而要vi来完其余的部分。当然了,我们可以将我们喜欢的一些设置写入vi的配置文件,这样就不要我们每一次都要通过命令来完成了。除了这个功能以外,我们还可以在vi中定义我们自己的功能按键,而不会影响到系统中的功能键。这样的功能是不是很有趣呢?
我们可以在vi中用一个缩写的字符来代替一个单词,然后在我们想要输入这个单词时只要输入这个缩写的字符就可输入我们想要的单词了。我们如何来做到这些呢?这时我们要用到的vi命令是:abbreviate.例如我们可以用ad来代替advertisement。这样我们在想输入advertisement的时候只要输入ad然后打一下空格或是tab就可以输入advertisement了。具体的做法是这样的:
:abbreviate ad advertisement 这个命令就是在告诉vi我们设置advertisement的缩写为ad,这样我们在要输入advertisement的时候只要输入ad就可了,剩下的工作vi会为我们完成的。当然了这个命令也可以为多个单词设置缩写。例如我们可以设置Jack Berry的缩写为JB。命令为::abbreviate JB Jack Berry 这样我们在输入了JB以后打下空格或是Tab,vi就会自动的用我们设置的单词来替换JB。对于程序员来说这样命令为我们提供了巨大的便利。例如我们可以做出这样的设置:
:abbreviate #b /*************************
:abbreviate #e <space>**********************/
这个缩写可以在加快我们添加注释的速度。我们在编写程序文件时常有这样的习惯,那就是在程序的开头总是要加上一个注释块,来标明我们此程序的目的等。在这个缩写中有一点要我们注意的地方,那就是我们希望在写程序的注释块时下一行要和上一行对齐,要做到这一点就要求第二行的注释开头的两个字母要是空格,但是在这个缩写命令中会忽略到空格的作用,因而我们在写这个缩写时在开头写上<space>,这样就会满足我们的要求了。也许有时我们会在一个文件中设置了多个缩写,我们可以命令:abbreviate来列出我们这个文件中所有的缩写的设置。
另一个比较有趣和强大的命令就是:map命令,这个命令可以使得我们将键盘上的一个按键与vi中的命令绑定在一起。例如我们现在将一个单词用花括号括起来,例如我们要将amount变成{amount}的形式,这时我们就可以这样的来应用这个命令:
:map <F5> i{<Esc>ea}<Esc>
在这个命令中:map是vi中的命令,而F5则是说将下面的命令与F5键绑定,后面的则是具体的命令内容,i{<Esc>是说插入字符{,然后退回到命令状态。e是移到单词的结尾处,a}<Esc>则是增加字符}然后退至命令状态。
在我们做过这样的工作以后我们就可以来执行我们的命令了,我们将光标定位在一个单词上,例如amount,按下F5键,我们就会发现这时就变成了{amount}的形式。
在这里我们要注意的一点就是我们最好不要将在vi中有特殊命令的功能热键与某些命令进行绑定,如果是这样的话就会给我们带来麻烦。
同上面的:abbreviate命令相类似,我们也可以用命令:map来列出在这个文件中所有的功能键,包括我们自己定义的以及系统定义的。
我们在做过这样的设置以后,有时希望这样的设置在下一次使用时会继续有效,这时我们就要用命令:mkvimrc将我们所做的这些设置写入文件中。这个命令的格式如下:
:mkvimrc file
在这里file就是我们要将这些设置写入的文件名。我们可以用命令:source file来读出文件并执行文件中的内容。
在vi的启动过程中,vi会首先查找初始化文件。如果找到就会自动执行文件的内容。而这些初始化文件一般来说是这样的一些文件:
$HOME/.vimrc
$HOME/_vimrc
$HOME/.exrc
$HOME/_exrc
而在Windows和Dos系统中则是这样的一些文件:
$HOME/_vimrc
$HOME/.vimrc
$VIM/_vimrc
$VIM/.vimrc
$HOME/_exrc
$HOME/.exrc
$VIM/_exrc
$VIM/.exrc
而如果我们用一些图形界面的话,那么还会读一些其他的配置文件。如果我们要执行gvim那么$VIMRUNTIME/menu.vim也会被读进来。用命令:version我们可得到这些配置文件的信息。
例如我们可以在.vimrc中写入以下的一些语句:
:syntax on
打开语法加亮功能
:set shiftwidth=4
设置缩进宽度为4
:ab #d #define
将#define缩写为#d
:ab #b /************************
:ab #e <space>*********************/
我们还可以加入一些其他的东西,这样就可大的方便我们的工作了。而这也正是vi的强大之处 。\r\nvi编辑器的学习使用(九)
现代的Vim编辑器是基于一个古老的名为vi的编辑器设计而成的,而vi基于一个更古老的基于命令行方式的ex编辑器设计而成的。ex编辑器是在屏幕产生以前相当流行的一个编辑,他是为那时古老的标准打印而设计的。
仅管ex是基于命令行方式的,然而他也是真正意义上的一个强大而高效的编辑器。即使是在今天他也是发挥着作用。仅管现在的Vim编辑器有一套的命令系统,可是有些事情还是要用ex的命令方式才可以更好的来完成。因而现在的Vim编辑器设计了与ex编辑器的接口,我们可以在Vim中使用ex方式的命令。而那些以冒号开头的命令就是一个ex方式的命令。
如果你想执行单一的命令行方式的命令,那么你只输入:然后输入命令就可以了。例如我们在前面讨论的:set number.事实上他就是一个命令模式的命令。在执行完这个命令以后,Vim编辑器又回到了他原来的状态。我们可以通过命令:ex选择进入命令行模式。Q命令也有同样的作用。如果要选择回到正常模式(normal mode)也就是可视化模式(Visual mode),我们可以使用命令:visual.
命令:print(简写为:p)可以打印出选定的行。如果没有传递参数,他仅是打印当前的行。打印完成以后回到打印行的开头。我们也可以指定要打印的行的范围。例如命令:1,5 print就是要打印1到5行。严格来说你不必须在数5和print之间输入空格,但是如果这样做后我们就会现这个命令看起来会更好。如果你仅仅是想打印第5行,你可以用这样的命令::5 print.当然了我们也可以使用一些特殊的数字标记,例如字符$是指最后一行,因而如果我们想要打印全文的时候我们可以用这样的命令::1,$ print.而字符%是指整篇文章(1,$),因而我们也可用这样的命令来打印整篇文章::% print,而.则是指当前行,我们要打印当前可以用:print命令而不带任何参数,也可以用这样的命令:.print。我们还可以用指定句子中内容来打印选定的行。例如在我们的文章中我们可以用这样的命令来打印含有字符ex的行::/ex/ print。这样就会打印出含用ex的行,并会高亮显示出ex。同样命令:?ex? print也会达到同样的作用,而命令:?ex? print也正是打印含有ex字符的命令格式。
在前面的学习中我们曾学过标记命令m,例如我们可以在任何地方用命令ma做上标记,然后在其他的地方可以用命令‘a回到做了标记的地方。这个命令也可以与print命令组合。例如我们可以在一个地方用命令ma做上标记,然后在其他的地方用命令mb做上另外的标记,然后我们就可以执行下面的命令来打印这两个标记之间的内容了::\'a,\'b print
我们也可以在可视化的模式下来选定要打印的内容。例如我们用命令V进入可视化模式并选定一段内容,这时我们输入:就会在Vim的底部显示<,>两个字符,这两个字符分别指我们的选定内容的开头和结束部分。
命令:substitute可以使我们将指定的字符换成其他的字符。这个命令的格式是这样的:
:range substitute /from/to flags
在这个命令中range是指定了范围,也就说是在哪些行里做替换。而后是说将字符串from替换成字符串to。在默认的情况下,这个替换命令仅是将一行中第一个出的的字符替换成给定的字符。而如果我们想将所有出现的字符都替换成给定的字符我们就用g这个标记命令。例如::% substitute /from/to/g.这个命令就达到将所有出现from的地方全部替换成to。其他的标记(flags)包括:p(print),这个命令是告诉substitute打印所做的改动。c(confirm),这个命令是告诉substitute命令在做出这样的改动以前要询问是否要做这样的改动例如如果我们执行下面的命令::1,$ substitute /Professor/Teacher/c.在Vim就会显示我们将要做改动的文本,并显示下面的内容:
Prfessor: You mean it\'s not supposed to do that?
replace with Teacher(y/n/a/q/^E/^Y)?
这时你可以做出以下这样的回答:
y 执行这个替换
n 跳过这个替换
a 执行所有的替换不要做询问
q 退出,不做任何改动
CTRL─E 向上翻滚一行
CTRL-Y 向下翻滚一行
在Vim的命令还有一些命令可以帮助我们很好的完成我的工作:例如命令:read filename可读进一个文件并将读进和内容插在当前行的后面。而命令:write是将文件写入。这是一个保存我们工作的方法。我们也可以用命令:write newfile将当前的文件内容写入一个新的文件。一般情况下:write命令并不会覆盖已经存在的文件。我们可以用强制操作(!)选项来完成我们所需要的操作并覆盖当前已经存在的文件。而这个命令对于我们要将一个大的文件分拆为小的文件时显得更有用。我们可以用可视化模式选定一个范围然后将这个选定的范围写入新的文件,从而实现了分拆的目的。
我们还可以Vim中不需要退出而执行Shell命令。命令:shell可以使们进入命令终端执行我们需要的命令。当我们要退出终端回到Vim中时可以执行exit命令。我想这对于程序人员来说真是一个巨大的帮助。:)\r\nvi编辑器的学习使用(十)
在我们谈起Vim编辑器似乎只是觉得他只是一个类似于一个命令行方式的文本编辑器。而事实上不是这样的。Vim在窗口环境中也可以完美的完成我们的工作。在窗口环境下,我们不仅可以使用那些在Vim文本方式下的命令来完成工作,而且还有许多的菜单和其他的选项。这些都使得我们可以完美的来完成我们的工作。
我们要启动图形界面的Vim可以用下面的命令:gvim file。这样就可以打开图形界面来编辑文本file。图形界面下的Vim编辑器的外观因你所用的操作系统的不同而有所不同,就是同样的操作系统也会因你所使用的工具集不同(Motif,Athena,GTK)而会呈现不同的外观。而值得向大家推荐的是GTK版本的Vim编辑器,当然其他版本的也是可以来完美的完成我们的工作的。
在Windows系统中我们可以在标准形式下用鼠标来选择文本,而在X Window系统中我们也会有一个标准的系统来使用鼠标,但是这两种标准是不同的。然而比较幸运的是我们可以定制我们的Vim编辑器。我们可以使得我们的Vim中的鼠标的行为看起来像是X Window系统中的鼠标的行为。下面的命令是设置鼠标的行为为X Window风格的鼠标行为::behave xterm。而下面的命令则是使得鼠标的行为是Windows风格的行为::behave mswin。在UNIX和Linux系统中的鼠标风格是xterm风格,而在Windows中的鼠标风格是在安装过程中选择的。为了控制鼠标的行为,命令:behave有以下这些选项:
Setting for Setting for
Option :behave mswin :behave xterm
\'selectmode\' mouse,key (empty)
\'mousemodel\' popup extend
\'keymodel\' startsel,stopsel (empty)
\'selection\' exclusive inclusive
xterm的鼠标风格的行为主要有以下一些:
左键: 移动光标
拉动左键: 在可视化模式下选择文本
右键: 选中光标处到右键点击处的文本
中键: 在光标处粘贴选中的文本
Windows的鼠标风格的行为主要有以下一些:
左键: 移动光标
拉动左键: 在选择模式下选中文本
<S-Left Mouse> 选中到光标处的文本
<S-Right Mouse> 显示弹出菜单
中键: 将系统剪切板中的文本粘贴到文件
(注:其中的S为Shift键)
其他的一些特殊的用法:
Shift+左键: 向前搜索光标处的文本
Shift+右键: 向后搜索光标处的文本
Ctrl+左键: 跳转到以光标处的文本为名字的标记(tag)处
Ctrl+右键: 跳转到前一个标记处
在图形界面的Vim编辑器还有一个有趣的特征,那就是当我们点开一个菜单时就会发在子菜单的第一行有一条虚线,点击此虚线就可以将这个菜单移其他的地方。关闭后Vim的菜单结构又恢复到正常的状态了。在GTK版本和Windows版本中的图形界面的Vim还有一个工具栏,这些工具可以快速的完成我们的工作。\r\n
vi编辑器的学习使用(十一)
虽然现在的专业的文字处理软件例如MS Word,Star Office,Open Office等可以很好的来完成的一些文档处理的工作,但是人们仍然是喜欢用纯文本的形式来处理手中的文本.这里因为用纯文本处理的文件比较容易阅读,不像那些专业的字处理软件,有专门的文件存储格式,少了许多的麻烦.Vim是一个强大的文本编辑器,他也可以像那些专来的字处理软件一样来处理我们手中的文本工作,从而使得我们的工作来得更漂亮.
Vim在默认的情况下是不会自动换行的,这也就是说我们在默认的情况下我们不得不自己决伫回车的位置.这样的设置对于处理程序文件来说是一件相当好的事情,因为这样可以由我们自己来决定回定回车换行的位置,从而可以很好的来完成我们的程序设计工作.但是如果我们是在处理一些文档工作,那么这个问题就有一些成为困挠我们的问题了.幸运的是Vim提供了这样的功能可以使我们来解决这样的问题.当我们指定了textwidth这个选项后,Vim就会自动的在相应的地方加上换行符.例如我们可以用下面的命令来指定一个只有30列的文本:
:set textwidth=30
这样以后当我们再输入文本时如果达到30这个限制,Vim就会自动的依据情况来加上换行符.在Vim中我们可以有两种方法来选择换行的方式.例如下面的命令是告诉Vim从左面算起30个字符时换行::set textwidth=30
而下面的命令则是告诉Vim从右面算起当达到margin个字符的空白时要换行:
:set wrapmargin=margin这里的margin是空白字符的个数.例如如果你有一个80个字符宽的文本,下面的两个命令则是起到了同样的作用:
:set wrapmargin=10
:set textwidth=70
Vim并不是那些专业的字处理软件,在我们指定了文本宽度的情况下,当我们将一行中的前几个文字删掉的话,Vim并不会像那些专业的字处理软件那样将后面行中的文本移到前面的行上,而是形成了一些长短不一的段落.这样看起来不是很好,因为我们需要的是有同一风格的文本形式.在Vim中这样的情况可以有几种处理方法:一是在可视化模式下选中这些文本,然后用gp命令来格式化选中的段落.另一种方法就可以使用gqmotion的命令来完成格式.例如我们要格式化5行,我们就可以用下面的命令:gq4j.这个命令是告诉Vim编辑要格式化本行,同时要格式化下面的4行.这样就达到了格式化5行的目的.在这样的情况下,向前移动的命令}这时就会为我们提供更大的便利了.这时我们的做法是这样的:将光标放在我们要格式化段落的第一行上,然后执行命令gq}.这样就可以达到我们的目的了.这样方法要简便得多,因为我们不必要再数细数我们要格式化多少行了.命令gqip可以格式化当前的段落.这个命令要比上一个的格式命令还要简便一些,因为在这样的情况下我们不必要将光标放在一个段落的第一行了.最后如果我们要想格式化一行的可以使用命令gqgq,当然了我们也可以简记为gqq.
我们都知道在专业的文字处理软件中有文本对齐的选项,而这在Vim当中也是可以做到的.如果要将文本居中对齐我们可以用这样的命令::range ceter width.在这个命令中如果我们没有指定textwidth的值,他将使用我们设置的textwidth的值,如果我们也没有设置这个值,那么他将使用系统定义的80.例如我们要将1到5行的内容居中对齐,我们可以使用下面的命令:
:1,5 center 30
同理右对齐的命令也可以类似的写成:
:1,5 right 30
但是左对齐的命令就与这两个命令有一些不同了,左对齐的命令为:
:range left margin
在这个命令中左对齐的参数并不是文本的宽度,而在文本左边的空白字符的宽度,如果为0,那么将紧靠屏幕的左边沿.在Vim中并没有内置的方法来对齐文本,但是我们可以使用一个简洁的宏包来完成这样的工作.要使用这个包先执行下面的命令:
:source $VIMRUNTIME/macros/justify.vim
在这个包中定义了一个新的可视化的命令_j.要对齐一个文本块,可以在可视化模式中高亮显示这个文本块,然后执行命令_j.
J命令可以使两行合并为一行,同时用空格为分格这两行.在文本处理中有一个joinspace的选项,如果设置了这个选项,那么可果一行是以标点符号来结尾的,那么在用这个命令后会用两个空格来区分这两行.也就是说如果我们用命令:set nojoinspace ,用J命令来合并这两行时会用一个空格来区分.但是如果我们用命令::set joinspace ,用J命令来合并这两行时会用两个空格来区.这就是这个选项所要起到的作用.
在Vim编辑器中我们可以通过设置formatoptions选项来设置Vim中的文本和注释的换行方式.这个命令为:
:set formatoptions=character
在这个命令中character一组格式化的标记,他可以是下面的一些字符:
t 文本自动换行
c 注释自动换行,同时自动在行首添加注释标记
r 当添加新行时自动添加注释符
o 当用O和o开始新的一行时自动在行首添加注释符
q 允许使用gq来格式化文本
2 第二行缩进两个字符
v 采用老的vi换行方式,当你输入空格时换行
b 在达到textwidth以前当输入空格时换行
l 在插入模式下不换行,只用gq来完成相应的工作
下面让我们来看一下这些选项是如何来工作的:
当需要文本自动换行时要打开t标记,当需要注释自动换行时要打c标记.所以对于一个要处理程序文件的人来说打开注释自动换行似乎要有更大的帮助:
:set formatoptions=c
这样在注释中的一个长句就会自动换行,而正常的程序文本就不会被自动换行.事实上我们常做些这样的选项:
:set formatoptions=cq
这个选项是告诉Vim编辑器不仅注释要自动换行,而且这些注释可以使用gq命令来格式化.
Vim编辑器可以很好的处理注释的问题.在C程序风格的程序文本处理过程中,当注释自动换行时Vim会自动在注释的开头加下注释标记.但是在这样的设置也还是存在一个问题的,那就是当你回车时Vim就不会在下一行的开头自动加上注释标记了.如果这一行仍写的是注释,那么就要你亲自来加上了.但是当我们打开r这个标记后就会解决这个问题了.这时如果你打回车,Vim编辑器还会在新的一行加上注释标记.这时如果你要想在下一行写程序文本,那么就不得不动手删除注释标记了.如果你希望当用O或是o添加新的一行时要自动添加注释标记就要打开o这个格式标记了.
格式标记选项是告诉Vim编辑器在格式文本中要从第二行开始而不是第一行.设置这个选项的命令为:
:set formatoptions+=2
而v标记则控制一个句子从哪里进行分裂.例如现在我们有一个句子:
This is a test of the very long warpp.
现在我们要在这个句子的后面新增一个词logic
如果没有v标记结果就会变成:
This is a test of the very
long line warpping logic.
而如果打开v标记,结果就会变成:
This is a test of the very long line wrapping
logic.
令管已经存在的文本已经远远的超过了textwidth的限制,但是因为设置了v标记,所以Vim编辑器也不会换行,相反只有你新增了一个词时才会换行.
在默认的情况下vim编辑器是使用内部的格式程序来模式文本,当然了我们也可以使用外部的格式程序来格式我们的文本.在UNIX和Linux系统中有一个标准的程序fmt可以很好的来做这样的工作.如果我们想用命令gq来执行这个处部命令,我们可这样的来进行设置:
:set formatprg=fmt
即使是没有进行这样的设置,我们也可以使用命令!来格式文本.例如如果我们想用程序fmt来格式一个段落,我们可以用这样的命令:!}fmt.!是开始了一个过滤命令,而}是告诉Vim过滤一个段落.fmt是我们要使用的命令的名字.
在早期的打印机的时代,开始新的一行要占用两个字符的时间.如果到了一行的结尾处,你要他快速的回到新的一行的开头,打印的针头在纸面上飞快到掠过,常常就会在纸面的中间留不希望的污点.这个问题的解决办法就是用两个字符来解决:一个字符<Return>来移到第一列,而字符<Line feed>来新增一行.计算机产生以后,存储较为昂贵,在如何解决回车换行这个老问题上,人们产生了不同的意见.UNIX人认为在到达一行的结尾时新增一行(<Line feed>),而苹果人则认同<Return>的解决办法,MS则坚持古老的<Return>,<Line feed>的方法.这就意味着如果你将一个文件从一个系统转移到另一个系统,你就面临着回车换行的问题.而Vim编辑器则会自动的认出这种文件格式方面的区别,并会为我们做出相应的处理.
fileformats选项包含了许多当编辑一个新文件时会用到的一些文件格式.例如下面的命令就是告诉vim编辑器将UNIX的文件格式做为第一选择,而将MS-DOS的文件格式做为第二选择:
:set fileformats=unix,dos
检测到的文件格式会被存放在fileformat选项中,我们可以且下面的命令来查找我们所使用的文件格式:
:set fileformat?
我们还可以应用fileformat这个选项将一个文件从一种文件模式转换成另一种文件格式.例如我们有一个名为readme.txt的MS-DOS文件格式的文件,而我们想将他转换为UNIX文件格式的文件.我们可以按照下面的方法来做:
首行编辑该文件:
$ vim readme.txt
其次将文件格式改为UNIX文件格式:
:set fileformat=unix
然后保存该文件,此时这个文件就转换成为了UNIX文件格式的文件.
在默认的情况下Vim编辑器认为我们的文件是由行组成的,也就是他认为文件中的最后一行是以<EOL>为结束符的.有时我们会遇到不包含有结束标记行的文件,当Vim遇到这样的文件时,他就会设置noendofline选项,而当遇到正常结束符的文件时则会设置endofline选项.如果你想设置你的文件以<EOL>结束符结尾则可以用下面的命令:
:set endofline
如果你想设置一个文件不以<EOL>结束符来结尾,则可以用下面的命令:
;set noendofline
在Vim中,我们有一系列的命令可使得我们在文件中进行移动,例如)命令向前移动一个句子,而(是向后移动一个句子,}向前移动一个段落,而{是向后移动一个段落.
曾经Troff是UNIX系统上专业的字处理程序,虽然在现代这个程序已经很少用了,可是Vim还是包含了一些选项使得我们可以用这种曾经的方式来处理文本.Troff需要用宏来告诉他应做一些什么.其中的一些宏开始一个新的段落.因为Troff要用许多的宏包来,因而Vim需要知道哪些宏将开始一个新的段落.paragraphs选项可以做这些工作.这个选项的格式如下:
:set paragraphs=\"macromacro...\"
每一个宏是两个字符的Troff宏名,例如:set paragraphs=\"P LP\"是告诉Vim宏.P和.LP开始一个新行.在默认的情况下paragraph的选项如下:
:set paragraphs=IPLPPPQPP LIpplpipbp
这个命令列出下面的一些开始一个新段落的宏名:
.IP .LP .PP .QP .P .LI .pp .lp .ip .bp
我们可以使用命令[[和[]向前移动一个区间,而使用命令]]和][向后移动一个区间,一个区间是用页分隔符(CTRL-L)定义的文本.我们也可以用Troff的宏来定义一个区间,section选项有些类似于paragraph选项,所不同的是前者定义一个宏用来分隔区间,而后者是段落.默认情况下是这样的;
:set section=SHNHH HUnhsh
在用Vim进行文本处理时我们还可以对文本进行加密处理,这种加密处理是最弱的一种加密处理方法,常常用新闻的发布.这时我们要用到的命令为g?motion.例如我们可以用命令g?g?或者是g??来加密当前行.当我们对一文本进行两次加密处理就为解密处理了.\r\n
vi编辑器的学习使用(十二)
我们在用Vim来处理文件时可以使用Vim的自动完成功能来大大加速我们的工作速度.所谓的自动完成也就是说当我们输入一个单词的一部分以后,按CTRL-P,Vim就会自动的来完成剩下的部分.我们在前面的学习过程中曾用:abbreviate命令来简记某一个单词来达到自动完成的目的,而在这里我们将看到是一个更加强大的自动完成功能.Vim能非常简单和灵活的来决定要用哪一个单词来自动完成. 我们在使用Vim这个强大的自动完成功能的同时,还可以自已定义我们的自动完成的特征,而且还可以使用不同类型的自动完成功能.
如果我们在编写C程序,而我们所谓得到的下面的一个句子:
total=ch_array[0]+ch_array[1]+ch_array[2]
这时我们输入total=ch_array[0]+ch_,然后按下CTRL-P,Vim就会自动的替我们完成其余的部分,这时我们得到将是
total=ch_array[0]+ch_array
由此可以看到我们在处理文件时用这样的方式可以大大的加快我们的处理速度.
那么Vim是如何找到匹配的单词的呢?在默认的情况下,Vim在查找一个单词时是按照如下的步骤:
1 在当前文件中进行查找
2 在其他窗口中进行查找
3 在其他的已装入的缓冲区中进行查找
4 在没有装入缓冲区的文件中进行查找
5 在当前的标记(tag)列表是进行查找
6 在所有的由当前文件的#include包含进来的文件中进行查找
当然了我们也可以自定义我们的查找顺序.
我们在使用自动完成功能时的命令CTRL-P是向后查找匹配的单词,而还有一个命令CTRL-N是向前查找匹配的单词.他们有同样的功能和作用,所不同的只是查找方向上的不同.
Vim还提供了许多的命令可以使得我们来自定义我们的一些查找上的特征.例如我们可以用下面的命令来告诉Vim在在自动完成的查找过程中忽略大小写的区别:
:set ignorecase
这样以后如果我们输入ins,Vim就会认为是INSERT,Inside或者是instep.当然了前提是在我们所编辑的文本中含有这些词,要不就会找得到了.
为了能够精确的进行查找来自动完成,我们并不希望上面的情况出现,我们可以设置一些选项来告诉Vim区分大小写的情况.这时我们要用到下面的命令:
:set infercase
这样以后如果我们再输入ins,与其相匹配的列表就成为了instep,inside,insert.我们可以通过按CTRL-P或是CTRL-N来进行匹配完成.
在大多数情况下,Vim默认的设置可以很好的来完成工作,但是有时我们要定义自己的一些完成的选项,这时我们就要用到complete这个选项了.这个选项的格式如下:
:set complete=key,key,key
而这个命令中可能出现的key值如下:
. 当前文件
b 已被装缓冲区,但是没有在窗口内的文件
d 在当前的文件中定义和由#include包含进来的文件
i 由#include包含进来的文件
k 由dictionary选项定义的文件
kfile 名为{file}的文件
t 标记(tags)文件
u 没有载入的缓冲区
w 在其他窗口中的文件
我们可以使用path选项来告诉Vim如何来查找我们在当前文件中所包含进来的文件.我们还可以指定一个字典,这个选项的格式如下:
:set dictionary=file,file,....
这个选项定义了由命令CTRL-P和CTRL-N进行匹配查找时所要查找的文件.在Linux系统中这个定义文件在/usr/dict/words中,所以如果我们要将这个文件添加进来进行查找的话,我们就要用到下面的命令:
:set dictionary=/usr/dict/words
如果我们要使用一个我们自己的文件也可以这样的来设置
:set dictionary=/home/oualline/words,/usr/doc/words
我们也可以指定一个字典文件和k选项组合使用:
:set dictionary=k/usr/oualline/words
我们也可以多次的使用k这个标记选项:
:set dictionary=k/usr/dict/words,k/usr/share/words
在上面提到的CTRL-P和CTRL-N进行查找匹配时查找的范围比较的宽范,我们当然也可以使用命令进行一些比较严格的查找.这时我们可以使用命令CTRL-X.当我们输入CTRL-X时我们会进入CTRL-X的一个子模式.这时我们可以使用下面的命令进行查找:
CTRL-D 宏定义
CTRL-F 文件名
CTRL-K 字典
CTRL-I 当前文件以及由#include包含进来的文件
CTRL-L 整个行
CTRL-] 标记(tags)
CTRL-P 向前查找,与没有CTRL-X命令时相同
CTRL-N 向后查找,与没有CTRL-X命令时相同
CTRL-X
CTRL-D命令查找宏定义.他也会查找#include文件.当我们执行完这个命令以后就可以使用CTRL-P,CTRL-N来进行匹配查找.
例如我们可以编辑下面的测试文件:
include.h文件中的内容
#define MAX(x,y) ((x)<(y)?(y):(x))
#define MIN(x,y) ((x)<(y)?(x):(y))
int sum(int i1,int i2)
{return (i1+i2);}
main.c文件中的内容:
#include \"include.h\"
#define MORE \"/usr/ucb/more\"
这时我们开始编辑main.c文件,如果我们按下CTRL-X我们就会进入CTRL-X的子模式.如果我们要查找一个宏定义,我们可以按下CTRL-D,这时就会在屏幕的底部简单的显示出有多少匹配的选项.这样我们就可以用CTRL-P和CTRL-N来进行自动完成的功能了.而命令CTRL-X CTRL-]则是查找下一个标记(tag),标记是一个C函数的定义.我们可以用命令ctags命令来生成一个C函数定义的列表.我们可以这样的来使用这个命令:
$ctags *.c *.h
这样以后我们就可以在插入模式入下用CTRL-X CTRL-]命令来进行标记的查找和匹配了.
在默认的情况下,vim编辑器只是简单的显示出标记的名字,我们可以执行下面的命令,这样以后就可以显示出整个标记了:
:set showfulltag
我们可以使用CTRL-X CTRL-F命令来匹配文件名.他会在当前的目录下查找文件并会显示出匹配的内容,这时你就可以用CTRL-P和CTRL-N命令来选择你想要的匹配选项了.
到目前为止我们所说还只是对单词进行操作,我们可以用命令CTRL-X CTRL-L对一行进行匹配操作,同样的我们也可以用CTRL-N和CTRL-P来进行选项的匹配.我们还可以在输入CTRL-X命令后用CTRL-Y向下滚动文本,而用CTRL-E向上滚动文本.\r\n
vi编辑器的学习使用(十三)
Vim最大的一个优点就是他的灵活性.使得他具有如此灵活性的一个重要原因就是自动命令.所谓的自动命令就是一条命令,所不同的只是他可以在某些事件发生时自动执行.
例如通过Vim的这样自动命令,我们可以使用Vim来编辑压缩文件,这是因为我们可以定义一个自动命令在我们读取文件时解压缩,在我们写入文件时进行压缩.
我们在处理文件时有时希望文件在保存时在文件的结尾处插入当前的日期,而这在Vim当中我们可以使用自动命令来完成.我们可以定义这样的一个函数:
:function DateInsert()
: $read !date \"在文件的结尾处插入日期
:endfunction
当我们要保存文件时可以调用这个函数:
:call DateInsert()
然后我们就可以保存退出了.
我们还可以将这个功能绑定在一个按键上:
:map <F12>:call DateInsert()<CR>\\|:write<CR>
这种方法使用问题的解决更简单,因为我们只需在要保存文件时按一下F12键就可以了.
但是也许有时我们会忘记这样的步骤,而使用正常的保存命令,那么这时这个函数也就失去了意义.我们希望这个插入日期的命令可以自动被执行,这也正是自动命令的意义所在.
下面的命令就可以来满足我们的要求了:
:autocmd FileWritePre * :callDateInsert()<CR>
这个命令会使得所有的文件在保存之前调用这个插入日期的函数.我们并不需要每一次都要输入:write来保存文件,也就是说当我们定义了这个命令以后,当我们输入一次:write命令,vim就会自动检查所有未保存的文件并执行我们定义的这个命令,然后执行保存命令.
:autocmd命令的一般格式如下:
:autocmd group events file_patter nested command
在这个格式中组名(group)是一个可选项,他被用于管理和调用命令.参数事件(events)是一个事件列表,指明引发命令的事件,而嵌套标记(nested)可以允许嵌套自动命令,最后是所要执行的命令.
命令:augroup可以使得我们定义一组自动命令.这个组名最好应是一个和我们要定义的一组自动命令相关联的名字,如下面的例子:
:augroup cprograms
: autocmd FileReadPost *.c :set cindent
: autocmd FileReadPost *.cpp :set cindent
:augroup END
在这里因为这些自动命令是在:augroup的作用域之内的,所以他们被放在cprogram这个组内.这组自动命令是在读取C和Cpp之后执行的.如果我们想在这个组中添加关于头文件的自动命令,我们可以使用:augroup命令,或者是在我们的定义中包含这个组名.
如果我们正在编辑的文件名为sam.cx,而我们想将他当作C程序文件来对处理.这时我们可以通过命令来告诉Vim编辑器在文件读入以后将他与*.c文件相匹配.我们所用的命令如下:
:doautocmd group event file_name
在这个命令执行的时候,Vim是将假定当前文件的名字为file_name,而实际上这并不是他真正的文件名.如果在这个命令中我们并没有指明组(group),那么所有的组都会被用到.而且我们必须指明事件,并且Vim会认为这个事件已经发生.与命令:doautocmd相类似的是命令:doautoall,所不同的只是后者是针对每一个缓冲区(buffer).这个命令的格式为:
:doautoall group event file_name
我们可以使用下列的命令来引发命令:
BufNewFile 当编辑一个新文件时引发命令
BufReadPre BufReadPost 在读入之前或是读入之后引发命令
BufRead BufReadPost的另一种说法
BufFilePre BufFilePost 在通过:file命令更改缓冲区名字之前或是之后引发
FileReadPre FileReadPost
在用:read命令读入文件之前或之后.在文件读入之后,在文件的开头和结尾处有由[和]来标记
FilterReadPre FilterReadPost 在用过滤命令(filter)读入文件之前或之后
FileType 当FileType设置时有效
Syntax 当Syntax设置时有效
StdinReadPre StdReadPost 由标准输入设备读入或是输出
BufWritePre BufWritePost 在将整个缓冲区写入文件之前或是之后
BufWrite BufWritePre的另一种说法
FileWritePre FileWritePost 将部分缓冲区内容写入文件之前或是之后
FileAppendPre FileAppendPost 将一个文件由过滤命令输入之前或之后
FileChangedShell
这个事件是在Vim运行Shell命令而文件的修改时间已经改变时引发
FocusGained FocusLost
这个事件是在Vim编辑器得到或是失运输入光标时引发.这意味着vim运行图形界面,并且是Vim成为当前窗口或是其他的成为当前窗口
CursorHold
用户停止输入的时间长于由updatetime所指定的时间时引发
BufEnter BufLeave 当进入或离开缓冲区时引发
BufUnload 在缓冲区未载入之前引发
BufCreate BufDelete 在缓冲区产生以后或是在缓冲区删除以前引发
GuiEnter 启动GUI时引发
VimEnter Vim启动而初始化文件还没有读入进引发
VimLeave 退出Vim编辑器而.viminfo还没有改写时引发
FileEncoding fileencoding已经被设置时有效
TermChanged term选项被更改时引发
User
并不是一个真正的事件,而是命令:doautocmd一起使用的一个事件
当存文件时,只有下列事件成对出现时才引发:
BufWritePre BufWritePost
FilterWritePre FilterWritePost
FileAppendPre FileAppendPost
FileWritePre FileWritePost
当读文件进,只要下列事件中的一个被设置则会引发:
BufNewFile
BufReadPre BufReadPost
FilterReadPre FilterReadPost
FileReadPre FileReadPost
文件名类型与UNIX标准系统相匹配.下面列出是一些特殊字符匹配的情况:
* 匹配任意长度的任意字符
? 匹配单个字符
\' 分隔交替的类型
\\? 字符?
\\, 字符,
\\character
将这个字符看作是一个要查找的类型字符,例如:a\\+可以匹配,aa,aaa等等
一般情况下一个命令的执行结果并不会引发另一个事件.例如Syntax的执行结果并不会引发FileReadPre事件.但是如果我们在自动命令中加入nested关键字就可以来引发了,例如下面的命令:
:autocmd FileChangedShell *.c nested e!
我们可以使用命令:autocmd列出所有的自动命令.
如果我们想要得到所有这些命令中的一个子集命令,我们可以使用如下的命令:
:autocmd group event pattern
在这个命令中如果我们指定了group,那么就会所有与group相匹配的命令.event可以是以前定义的或是所有的事件,pattern指了与类型相匹配的文件选项.只有那些与命令相匹配的命令才会被列出来.
我们可以建立我们自已的自动命令,当然了我们也可以移除那些我们不再需要的自动命令.例如命令:autocmd!就可以移除所有的自动命令.
我们也可以用下面的命令来移除指定的组命令:
:autocmd! group
在这个命令中我们当然也可以为这个组指定事件或是类型
:autocmd! group event pattern
event可以用*代替所有的事件
我们可以用命令:autocmd!来移除那些已经存在的自动命令,我们还可以同时在一个命令中再新建一个我们自己的自动命令.这个语法的格式如下:
:autocmd! group event pattern nested command
这个命令等价于下面的两个命令:
:autocmd! group event pattern
:autocmd group event pattern nested command
有时我们并不想引发某个命令,在这样的情况下我们可以设置eventignore选项来指定那些要忽略的事件.例如下面的命令将进入窗口和离开窗口的事件忽略掉:
:set eventignore=WinEnter,WinLeave
如果要忽略所有的事件,可以用下面的命令:
:set eventignore=all\r\nvi编辑器的学习使用(十四)
Vim编辑器的不仅可以使得我们编辑各种各样的文件,而且还有一些附加的功能来完成我们的作.例如说Vim可以实现在对文本文件进行加密,而且我们还可以通过一命令行参数来控制我们对文件的处理.我们还可以通过交换文本来实现对文件的修复.
我们在用Vim时常用一些有用的命令行参数,在这些命令行参数中最有用的一个要算是--help,这个命令行参数可以简单的列出一个帮助屏幕,在这个屏幕上列出所有的命令行参数.这个命令的执行结果如下:
这个命令的格式如下:
$ vim --help
如果要查出我们所使用的Vim的版本,我们可以使用下面的命令:
$ vim --version
我们可以用-R参数来在只读状态下打开一个文件,命令格式如下:
$ vim -R filename\r\n在大多数的系统中,这个命令与下面的命令是相同的:\r\n$ view filename
-x参数可以告诉Vim编辑器对某一个文本文件进行加密处理.例如我们想要建立一个文件来保存一些我们自己的小秘密时就可以使用下面的命令:
$ vim -x filename
这时Vim编辑器就会要你来输入加密和解密时所需要的密码.这样以后我们就可以在正常的状态下来编辑我们的文本文件了,当我们完成编辑工作要退出时,Vim就会将文本进行加密处理后退出.当我们想用cat或是type命令来打印出已进行过加密处理的文件时会得到一些无意义的信息.
我们当然是可以在加密和非加密两种状态下进行选择和切换.选项key包含了加密时的密码.如果我们将这一项设为空,那么也就意味着我们关闭了加密选项.这个命令为:
:set key=
如果我们设定了一个密码,那么我们就打开了加密选项.例如下面的命令:
:set key=
保存退出.此时的文件就没有密码,我们可以通cat和type命令来打印文件中的内容.
而我们也可以通过样的命令来重置我们的加密密码.例如下面的命令:
:set key=secret
但是这样的设置并不是一个好主意,因为在输入这个命令时你所输入的密码是可以明文显示的,别人在旁边晃动一下肩膀也许就可以看到了,因而这是一个不安全的加密方法.为了避免这样的问题,我们可以使用:X命令,这个命令可以将我们所输入的密码用*打印出来,因而不易被人看到,所以安全得多.
但是我们要清楚的认识到,Vim所采用的这种加密算法是很弱的.也许他可以防住偶尔路过的小偷,但是不可能防住一个很有时间的密码学专家.同时我们还要认识到我们在编辑文件时所使用的交换文件(swap file)并没有经过加密,因而当我们在进行文件编辑时,一个有着超级权限的人可以通过交换文件得知我们所编辑的内容.一个解决的办法就是我们在编辑文件时不使用交换文件.如果我们在命令行参数中指定-n参数,我们就可以在编辑文件时不使用交换文件,这时我们所输入的内容是存在内存中的.例如我们可以使用下面的命令来编辑一个加密的文件同时不使用交换文件:
$ vim -x -n filename
但是我们应该知道在不使用交换文件的情况下,防止了别人偷看我们编辑器的内容,而我们也不可能通过这个交换文件来恢复我们的文件了.
因为不使用交换文件时我们所输入的内容存在于内存中,因而就百以文本方式存在的.任何人都可以通过查看编辑器的内存来发现我们文件中的内容.如果你真的是想保密你的文件,那只能在使用一个不用联网的电脑,使用好的加密工具,当电脑不用的时候我们要安全的锁起来了.要不我们可要怎么办呢?!:-)
想一下,如果我们要处理许多的文件,而要将这些文件中的字符串-person-换成Jones.我们应怎么样来做呢?一个办法就是我们要输入许多次来手工的更改(想一想这样的事情有多的恐怖),另一个解决办法就是我们可以写一个Shell脚本或是批处理文件来做这样的工作.Vim作为一个原始的屏幕编辑器在正常模式下启动可以极好的完成这样的工作.然而要批处理,Vim并不会产生一个空的有注释的文件,因而我们要使用ex的命令模式.这种方式给了我们一个极好的命令行的接口可以很容易的放入批文件中.
在我们这个例子中我们所需要的命令如下:
:%s/-person-/Jones/g
:write
:quit
我们将这些命令放入一个名为change.vim的文件中,然后在批模式下运行Vim,这时我们可以使用这样的命令:
$ vim -es file.txt<change.vim
这个是告诉Vim是ex命令模式下运行处理文件file.txt并从change.vim中读入文件.-s标记告诉Vim不要给出任何的输出提示一类的内容.
还有另外的一些命令行参数使得我们可以更好的来控制Vim编辑器:
-R 打开一个文件只读
-m 允许修改.这个选项允许我们可以设置write选项和修改文件
-Z
受限模式.这个命令参数可阻止我们使用:shell命令或是其他的一些命令来使用外部的Shell.但是这个选项并不会阻止我们使用:vi命令来编辑文件.
另外还有一些命令行参数可以允许我们决定读取哪一个初始化文件:
-u file
使用file为初始化文件,而不是使用.vimrc作为初始化文件.如果没有这个文件,那么就不会用任何的初始化文件.
-U file
使用file而不使用.gvimrc作为初始化文件.如果没有这个文件,同样不使用任何的初始化文件.
-i file 使用file而不使用.viminfo作为初始化文件.
在UNIX系统中,Vim编辑器实际上是一个有着不同的名字或链接的文件.Vim编辑器在哪种模式下启动,取决于我们用什么样的命令或是名字来启动他.一些常用的命令如下:
vim 在终端模式下启动(在当前窗口内启动编辑)
gvim 在图形模式下启动(编辑器启动他自己的窗口来进行编辑)
ex 在ex模式下启动
view 在正常模式下启动,只读
gview 在图形模式下启动,只读
rvim 在终端模式下启动,受限
rview 在终端模式下启动,只读,受限
rgvim 在图形模式下启动,受限
rgview 在图形模式下启动,只读,受限
vi Linux下的启动命令,同vim
我们也可以通过命令行参数来设置初始化模式:
-g 在图形模式下启动vim(与命令gvim相同)
-v 在可视化模式下启动(与命令vim相同)
-e 在ex模式下启动(与大多数系统上使用ex命令相同)
我们还可以使用一些命令行参数来调试我们的Vim编辑器,常用的命令行参数有下面的一些:
-Vnumber
显示额外的信息以使我们知道在编辑器的内部都做了一些什么.数字越大,我们得到的输出信息也就越多.这个参数常用来调试我们的Vim编辑器脚本.
-f
前景.我们不要在背景模式下启动图形界面.这个启动对于那些只有一个程序执行完毕才开始执行另一个程序的情况显得尤为有用.当然了这个选项对调试也是相当有用的.
-w script
将用户输入的所有字符存入脚本文件.如果这个文件已经存在,那么就追加在文件后面.
-W script -W相类似,只是这个选项会覆盖掉已经存在的数据
-s script 用-w选项来恢复脚本记录
-T terminal
设置终端类型.在UNIX系统中,这会改写$TERM的环境变量(当然了,如果$TERM环境变量错误,其他的许多程序都将会崩溃)
我们还有一些兼容的命令行参数.这些参数可以使得我们的Vim运行起来更像是Vi;
-N
这个参数可以使得Vim以自己的方式来运行,而不是不是像Vi的方式运行.这个参数是被.vimrc文件默认定义的.
-C
兼容模式.这个参数关掉了许多Vim的自己的特征,而是尽量的像Vi的方式一样的运行.
-l
Lisp模式.这种模式完全是由老版本的vi延续下来的.他设置了lisp和showmatch选项.这时的Vim的与文件类型相关的命令都可以很好的处理Lisp程序,并且这是可以自动完成的.
最后还有一些不知道该将他们归为哪一类的命令行参数:
-d device 打开编辑给定的设备文件
-b 二进制模式.设置了noexpandtab,textwidth=0,nomodeline,binary
在一般的情况下,vim是不产生备份文件的.如果我们希望他产生备份文件,我们可以使用下面的命令:
:set backup
产生的备份文件的名称是在原始文件名的最后加上了~.例如我们有一个名为data.txt的文件,那么由Vim所产生的备份文件名即为:data.txt~.
如果我们不喜欢这个备份文件的扩展名,我们可以定义我们自己的备份文件扩展名.这时我们要到下面的命令:
:set backupext=string
例如如果我们设置了backupext的值为.bak,那么新的备份文件名即为data.txt.bak
如果我们设置了patchmode选项,那么Vim编辑器就会以当前文件名加上patchmode的值为文件名备份正在编辑的文件.但是我们要注意的是只有以这个文件名为文件名的备份文件不存在时才会产生这样的备份文件.例如我们执行下面的命令:
:set patchmode=.org
如果我们是第一次编辑一个已经存在的文件:data.txt.当我们执行了这样的命令保存退出想要看一下事实是否是这样的.因为以前这个备份文件并不存在,所以会产生一个备份文件,名为:data.txt.org.但是当我们再一次编辑这个文件保存退出后,因为这个备份文件已经存在,所在现在的备份文件名:data.txt~.
通常情况下Vim编辑器会将备份文件放在与文件相同的目录下,我们可以通过设置backupdir选项来选择我们的备份文件存放的地方,例如我们想将备份文件放在~/tmp目录下,我们可以通过执行下面的命令来做到:
:set backupdir=~/tmp/
但是这样的设置有时也会产生问题的,如果我们在不同的目录下编辑具有相同文件名的文件,当我们保存退出时,Vim会将备份文件放在~/tmp/目录下,名字的冲突会使得老的备份文件丢失.同时我们还要知道的就是这个选项可以同时设置几个值,中间用逗来分隔.Vim会将备份文件放在第一个目录下.
一般情况下,当Vim保存文件时,会执行下面的步骤:
1
Vim要检查Vim外面的文件是否被做了改动.例如也许有的人已将这个文件重新命名了,如果发生这样的情况,Vim就会给出警告并询问是否继续.
2
如果设置了writebackup或是backup选项,Vim就会将旧的备份文件移除,同时产生一个当前文件的副本做为新的备份文件
3 将缓冲区的内容写入文件.
4
如果设置了patchmode选项而不存patch文件,那么Vim就会将备份文件重命名成为patch文件
5 如果没有设置backup选项,而是设置了writebackup选项,就会移除备份文件
Vim覆盖已经存在的文件的原因是因为要保护UNIX系统上的硬链接.在非UNIX系统上,备份文件只是通过重命名当前文件来产生
注意:如果我们设置了nobackup和nowritebackup选项,Vim会覆盖已经存在的文件.这在磁盘已满而更新文件时会造成数据的丢失.
在默认的情况下,Vim设置了writebackup选项.这就意味着Vim很难会丢失数据.通过采用这样的方法,在磁盘已满的情况下,我们就没有机会丢失文件.也许我们会不能写入新文件,但是我们不会丢失我们的旧文件.
我们在用Vim来编写时,Vim会在我们编写的过程中产生一个临时的交换文件,这个交换文件中包含着我们所做过的所有修改,当我们完成编写工作,保存退出后,这个临时文件会被删掉.但是如果Vim遇到了意外情况而退出时,这个临时文件会因为来不及删除而存在于硬盘上.当Vim启动时他会检查在当前目录中是否存着交换文件,如果存在,则意味着有一个Vim正在编辑此文件,或者是我们在Vim编辑器的过程中遇到意外而退出,从而留下交换文件.这时Vim就会给出警告信息,并会给我们机会要我们自己来决定我们下一步要怎么做.这时我们可以有以下四个选项:
Open Read-Only(以只读方式打开)
这个选项会告诉Vim以只读方式打开.如果我们想要看到文件中的内容或是有另一个编辑过程正在运行,我们可以选择这个选项
Edit anyway
如果我们选择这个选项我们可以对这个文件进行编辑.我们最好不要选择这个选项,除非我们对我们正在做的事情有着绝对的把握.这时我们应该知道,如果同时有两个或是多个编辑过程同时编辑一个文件,只有最后一个保存的编辑过程有效
Recover
如果我们正在编辑我们的文件,而由于系统故障或是其他的原因而导致vim意外退出时我们可以选择这个选项.此时Vim会检查交换文件,并试着从我们意外退出的地方重新开始
Quit 取消对此文件的修改
在我们选择了其中的一项后我们就可以正常的开始我们的编辑工作了.如果我们选择了Recover我们要十分小心,因为我们以前所做过的修改并不一定被保存下来.
如果我们记得Vim意外退出时我们正在编辑的文件,我们可以用-r命令参数在修复模式下启动Vim.例如我们在编辑文件commands.c时Vim意外退出,我们就可以用下面的命令在修复模式下启动vim:
$ vim -r commands.c
如果我们想得到一个可以修复的编辑器程序列表,我们可以用下面的命令:
$ vim -r
这样Vim就会在当前目录和标准的临时的目录下查找交换文件,命令的执行结果就像下面的样子:
$ vim -r
找到以下的交换文件:
在目前目录:
1. .vi14.txt.swp
所有者: mayuelong 日期: Wed Jul 27 19:19:39 2005
文件名: ~mayuelong/Documents/vi14.txt
修改过: 是
用户名: mayuelong 主机名: localhost.localdomain
进程 ID: 3070 (正在执行)
在目录 ~/tmp:
-- 无 --
在目录 /var/tmp:
-- 无 --
在目录 /tmp:
-- 无 --\r\nVim在意外退出的情况下并不会覆盖旧的交换文件.例如第一次编辑时产生的交换文件名为.file.txt.swp.如果我们再编辑又遇到意外退出时所产生的交换文件名为.file.txt.swo,到第三次时所交生的交换文件为.file.txt.swn,如此类推.
我们在启动Vim时可以指明用哪一个交换文件来修复文件,命令如下:
$ vim -r .file.txt.swo
如果想知道我们当前正在使用的交换文件的名称可以使用下面的命令:
:swapname
这样就会显示交换文件的名称.
通常情况下,交换文件会每4秒或是每隔200个字符保存一次.这个数值是由updatecount和updatetime选项来控制的.我们可以用下面的命令来设置交换文件每23秒保存一次:
:set updatetime=23000
(注:这个数值是以微秒计的)
或者是我们可用下面的命令来设置vim每400个字符保存一次:
:set updatecount=400
如果我们将updatecount的值为0,那么交换文件就不会被保存了.
事实上我们可以来控制是不是要在编辑的过程中产生交换文件,例如下面的命令是在产生交换文件,而这也正是Vim所默认的:
:set swapfile
我们也可以用下面的命令来使Vim不产生交换文件:
:set noswapfile
我们可以对每一个编辑的文件将这个选项设置或是重置.如果我们正在编辑一个大文件而我们又不想可以修复,我们可设置noswapfile.如果我们同时正在另一个窗口编辑一个文件,那么这个窗口中的文件仍是使用交换文件的.
在UNIX或是Linux系统中,当我们要保存文件时,通常数据被装入内存缓冲区,并肯是在系统认为是一个合适的时才会被写入文件.这通常只是几秒钟的事情.如果我们想要确认数据到达了磁盘,我们可以使用下面的命令:
:set swapsync
这个命令是告诉Vim编辑器在每一次将文件写入交换文件的同时写入磁盘.swapsync选项可以是fsync或是sync,这个取决于我们要保存文件时的系统调用.
通常情况下,Vim是在和当前文件相同的目录下产生交换文件,我们可以通过directory选项来更改交换文件产生的目录.例如下面的命令可以将产生的交换文件放在/tmp目录下:
:set directory=/tmp
这并不是一个好主意,因为如果我们是在不同的目录下编辑具有相同文件名的文件时会产生名字冲突.
我们也可以将这个选项设成一个目录列表,中间用逗号来分隔.最好的方法就是将当前目录(.)设为目录列表的第一个选择.在存放交换文件时首先放在列表的第一项指的目录处,这样交换文件首先会被存放在当前目录下.
如果我们已经做许多的改动,我们想保存我们当前所做工作,我们可以使用下面的命令:
:write
但是这个命令是用我们当前所做的改动来重写已经存的文件,与其相关的一个命令是
:preserve
这个命令是将我们所做工作存入交换文件,而原始的保持不变,直到我们用:write或是ZZ命令退出时才会被重写.在这样的情况下,如果Vim遇到意外,我们可以用交换文件来修复我们所做的工作,哪怕是原始文件已经丢失.如果没有用这个命令,我们就不得不同时修复原始文件和交换文件.
我们不仅可以在启动vim时修复文件,还可以用下面的命令来修复文件:
:recover file.txt
这个命令与下面的有着同样的作用:
$ vim -r file.txt
如果我们用:recover命令试图修复我们正编辑的文件则会返回错误.如果没有指定文件名,则默认的当前缓冲区中的文件.如果我们想要放弃我们所做的修改并试图修复时,我们可以使用下面的命令:
:recover! file.txt
vi编辑器的学习使用(十五)
Vim大量的工作是通过命令行的方式来完成,这样的命令行方式对于则接触Vim新手来说也许会觉得难于操作,可是当我们习惯了这样的工作方式后,我们就不得不佩服Vim的强大功能,正是这些命令使得我们可以高效的来完成我们的工作.而在Vim当中还有一些其他的命令.
命令:ascii或者是ga可以用ASCII码和八进制及十六进制打印出来.当我们编辑多字节文件时,例如说我们的汉语,这个命令就可以打印所有的字节.
命令countgo可以到达当前文件中由count所字的字符数的位置.例如命令3go就可以到达文件中的第三个字符处.而命令gCTRL-G可显示出当前文件中的字符数的信息,同是显示出当前行,当前列以及其他的一些信息.
而命令:goto offset可以将光标置于由offset所指定的字符处.而命令gg则与我们以前见到过的G命令相类似,他也可以到达由count所指定的行.例如5gg可以到达第5行.gg命令与G命令所不同的地方只是在没有指定count值时前者回到第一行,而后者要到最后一行.
而命令CTRL-L可以起到重画屏幕的作用.这个命令在我们使用终端窗口或是在屏幕上存在着一些系统信息时显得尤为有用.而命令:sleep time可以使得我们的Vim编辑器在指定的时间不做任何事情(Sleep嘛:-)).在这个命令中如果时间是以m结尾则是指的微秒.这个命令在我们想暂停执行宏时显得更为有用.而命令count gs命令也有同样的作用.
在大多数的终端上,CTRL-S可以停止输出,如果我们要重新启动他,则要CTRL-Q命令.这两个命令并不是Vim命令中的一部分.为了避免键盘的冲突,我们在Vim中并不用这两个命令.我们最好也不要试着用:map命令将一些功能和这两个键进行绑定,因为在执行这两个命令时是键盘得到命令而不会到达Vim.
如果我们是在UNIX或是LINUX系统的终端模式下进行工作,我们可以用命令CTRL-Z来中止我们的正常编辑状态.如果我们要继续编辑则要使用Shell命令fg.而命令:suspend也会有同样的作用.
在一般的情况下我们可以使用:help或是F1键来显示帮助屏幕,从而得到一般的帮助信息.
我们可以使用z height<CR>来调整当前窗口的高度.如果当前仅有一个窗口,这个命令只是影响到窗口中的行数.
我们在没有输入文件名的情况下启动Vim时会看到一个介绍的屏幕,这个屏幕在我们输入任一字符后消失,如果我们想再看到他,可以使用下面的命令:
:intro
vi编辑器的学习使用(十六)
Vim是一个强大的文本编辑器,这个强大的文本编辑器的大部分工作是通过命令行的方式完成的.Vim一系列的命令可以使得我们快速高效的完成我们的各种各样的工作.下面我们就来看一下在Vim的编辑中常出现的问题的一些解决办法.
在我们快速的输入文本的时候,很容易使得一些单词输入错误.例如我们本应输入的是the,而我们却错输入成了teh,这时我们可以通过简单的命令使得这e和h这两个字母交换一下位置来达我们改错的目的.我们可以将光标放在e上,然后输入命令xp,x命令删除掉字母e,而p命令则是将他放在当前光标的后面,也就是h字母的后,从而就达到了改错的目的.
在我们进行文本编辑的时候有时要做一些文本替换的工作,例如是将文中所有的字符串idiots替换成managers.这时我们可以使用下面的命令:
:1,$s/idiots/manages/g
这个是命令是以冒号(:)开头的,则表明这是一个ex模式的命令.所有的ex命令都指明了命令要作用的范围.在这种情况选定了当前的所有文本,从第一行到最后一行($).我们可以也可以用%来简单指整篇文章.而s命令是命令:substitute的缩写.旧的文本放在前面,而新的文本则放在后面,g标记则指明这是一个全局的替换,这样就不会出在一行中多交出现要替换的文本而只替换第一个的情况了.
但是有时我们希望在进行文本替换以前Vim可以向我们进行一些询问,然后由我们来决定下一步的操作.在这样的情况下我们可以按照下面的方法来做:
1 执行命令1G到文档的开始处.
2 执行命令/idiot来查找文章中出idiot的地方
3 执行命令cwmanager<ESC>,当我们执行cw命令时当前光标处的文本被删除并进入插入模式,这时我们就可以将我想要替换成的文本输入,并退回到命令状态.
4 执行命令n重复上一次的查找
5 执行命令.重复上一次的编辑操作,如果在这一步我们不想进行替换,我们可以跳过这一步,进行下一次的查找.
6 重复以上两步直到将文件中的所有字符idiot替换成manager
我们还可以执行下面的命令来达到同样的作用:
:%s/idiot/manager/cg
在这个命令中我们是用%来指代文章中的所有的行,与上一个命令不同的地方是我们加入了标记c,这个标记可以告诉Vim每一次在替换之前都要进行询问.
我们在进行文本编辑时想要进行文本的移动操作我们又该如何来做呢?这时我们可以按照下面的步骤来做:
1 将光标移到我们要移动的段落的开头部分
2 用命令ma在此处做上标记.
3 将光标移到这个段落的底部
4 执行命令d\'a来删除刚才做了标记的文本.
5 将光标移到我们想放置文本的地方.
6 执行命令p将这段文本放在此处
这样我们就达到移动文本的目的.
我们可以按照下面的方法来做,可以达到同样的效果:
1 用光标放在第一行并将其标记为a
用命令}移动到这个段落的底部,标记为b
3 输入命令:\'a,\'b move来移动文本.
老版本的Vi编辑器不能很好的来处理多文件.但是Vim在处理多文件上却显得优秀得多.我们有多种不同的方法在不同的文件之间进行文件拷贝.我们可以使用传统的Vi风格的命令,也可以使用Vim可视化模式.我们还可以利用系统的剪切板来进行不同文件间的文本拷贝,所有的这些方法都可以很好的来工作,采用哪一种方法这就要看我们个人的喜好了.
使用传统的Vi风格命令来在不同的窗口之间进行文本的拷贝可以按照如下的方法来做:
1 编辑第一文件
2 执行命令:split second_file打开另一个窗口并开始编辑第二个文件
3 使用命令CTRL-W p回到含有原始文件的前一个窗口
4 将光标移动到要拷贝文本的第一行
5 用命令ma标记这一行
6 移动到要拷贝文本的最后一行
7 执行命令y\'a来复制当前光标位置到所做标记之间的文本.
8 使用命令CTRL-W p 回到将要放置文本的这个文件.
9 将光标移到将要插入文本的地方,复制的文本将会放到这一行的前面.
10 使用命令P命令将复制的文本粘贴到文件中.
(注:p命令则是将文本放在光标所在行的后面)
用可视化模式在两个窗口中进行文本的拷贝可以按照如下的方法:
1 编辑第一个文件.
2 执行命令:split开始编辑第二个文件.
3 使用命令CTRL-W p 回到前一个包含有原始文件的窗口.
4 移动到将要复制文本的第一行.
5 执行命令V进入可视化模式.
6 移动到将要复制文本的最后一行,被选中的文本将会被高亮显示.
7 执行命令y复制选中的文本
8 使用命令CTRL-W p 回到将要放置文本的文件中.
9 移动到将要插入文本的地方,所复制的文本将会被放置在光标所在行的前面.
10 使用命令P来放置所复制的文本.
在不同的vim程序间实现在文本的拷贝可以照如下的方法:
1 编辑第一个文件.
2 启动Vim程序并编辑第二个文件
3 回到含有第一个文件的窗口.
4 移到要复制文本的第一行.
5 执行V命令进入可视化模式.
6 移到要复制文本的最后一行,选中的文本将会被高这显示.
7 使用命令\"*y命令将文本复制到系统剪切板.
8 回到另一个窗口.
9 移动到将要放置复制文本的地方,复制的文本将会被放到当前光标的前面.
10 执行命令\"*P将复制的文本放在这个文件中.
(注:这个方法似乎只在Gvim中有效)
也许我们经常会编辑一些文件,其中含有一个名字的列表,这时我们希望做到的是将这个名字列表按照一定的顺序进行排列.例如我们可以按照字母的顺序进行排列,可是按照ASCII的顺序进行排列.我们可以按照下面的方法进行:
1 将光标移到要排列的内容的第一行.
2 使用命令ma进行标记.
3 将光标移到要排序的内容的底部.
4
执行命令!\'asort进行排序.!命令告诉Vim通过UNIX命令来执行.\'a则是告诉Vim这个命令作用的范围.
我们还可以按照下面的方法进行排序:
1 将光标移到要排序内容的第一行.
2 执行命令V进入可视化模式.
3 移到光标到要排序内容的底部,这时选择的文本将会被高亮显示.
4 执行命令!sort进行排序.
Vim编辑器是一个程序员开发给程序员的编辑器.我们可以用这个编辑器在C或是C++程序文件中进行函数的定位.我们要想使用这个功能,我们首先要生成一个名为tags的文件,在这个文件中含C或是C++程序文件中所有函数的信息.我们可以使用下面的命令来当前我们工作的目录下的所有C程序生成一个tags文件:
$ ctags *.c
如果是对于C++文件,我们可以使用下面的命令来生成:
$ ctags *.cpp
如果我们是使用其他的扩展名,我们可以使用相应的扩展名,而不一定非要使用C或是C++的扩展名.
在我们生成这个文件以后,如果我们要利用这个文件来编辑我们的程序文件,这样Vim就会查找相应的文件并会在函数中进行定位,例如我们要编辑的文件为write_file,我们可以使用下面的命令来开始我们的编辑工作:
$ gvim -t write_file
假如我们正在看一个名为write_file的函数,而在这个函数中调用了函数setup_data,而我们又想要知道这个函数的详细内容,这时我们可以将光标位在这个函数的开头部分,然后按下CTRL-],这样Vim就会跳到这个函数定义的地方.哪怕是我们要查找的函数在其他的文件中,Vim也可以为我们进行精确的定位.
如果我们编辑了当前文件在没有保存的情况下使用了这个命令,那么Vim会给出警告信息,并且会忽略这个命令.
有许多和标记函数相关的命令可以使得我们在所标记的函数中进行向前或是向后的跳转和搜索,还可以打开一个新窗口并将被调用的函数在新窗口中打开.
我们在编写程序的时候常常会在程序的开头部分写上一个注释的边框,在其中写一些表明程序用途等等的信息.在Vim我们可以利用在~/.vimrc这个初始化文会写上一些命令来快速的完成这样的工作.例如我们可以其中加入下面的内容:
:ab #b /***************************
:ab #e <space>**************************/
这样就在Vim当中定义的一个简写的标记,在我们要写注释时,只要输入#b<Enter>就可以了.
而我们要输出下面的注释只要输入#e<Enter>就可以了.这样的命令对于那些每天要有大量程序写的朋友们来说是不是一个巨大的帮助呢!:)
我们还可以利用vim来读man帮助手册页,但是用这样的方法并不是太好,因为man显示的结果中一些下划线在Vim中显示会有一些困难.为了去除这样的字符,我们可以使用标准的UNIX命令ul -i.这样就会去除那些很难阅读的控制字符.例如我们可以用下面的命令来读date的man手册页:
$ man date | ul -i | vi -
我们还要用这样的技巧来使用Vim:
:%s/.\\b//g
这个命令是告诉Vim移除那些退格符(\\b),从而使用文件更易读.
位于文件行后面的空格符或是制表符有时是没有用,而他们的存在也使得文件看起为不是太舒服,去除这些多余的符号我们可以使用下面命令:
:%s/\\s*$//
冒号是表明进入命令模式,所有的命令模式都要指明命令作用的范围,在这里我们是指整个文件(%),这个命令是使得Vim将文件行末的空白符(\\s)重复0次或是多数(*).
假如我们正在编辑一个文件,而且在这个文件中我们做了许多的改动.这是一个很重要的文件,我们不希望因为偶然的改动而造成损失,这时我们可以将这个文件进行写保护.当我们用Vim来编辑一个有写保护的文件时我们并不会得到警告或是只有很少的警告,但是当我们想保存退出出Vim会给出错误信息,指出这是一个写保护的文件,并且Vim并不会退出.这时我们要怎么办呢?我们可以使用命令:w!强行保存或是使用:w otherfilename来以另一个文件名进行保存.
在UNIX或是Linux系统中我们可以使用Vim和grep命令组合来编辑一些含有同一个给定单词的文件.这对我们编写程序的朋友们来说是有着极大的帮助,因为有时我们也许可以希望查看或是编辑含有同一个变量的文件.例如我们所有含有frame_counter的C程序文件,这时我们就可以使用下面的命令:
$ vim `grep -l \'frame_counter\' *.c`
grep命令是在所有的文件中查找含有指定单词的文件,因为我们指定了-l选项,所以这个命令只是会列出含这个单词的文件而不会打印出这一行的信息.这样Vim就会打开grep命令列出的文件进行编辑,而我们也就可以使用:n或是:rewind命令在这些文件中进行跳转.
我们还可以在Vim内部使用:grep命令来查找我们想要的字符串,例如我们要在所有的C程序文件中查找含有error_string的字符串,我们可以使用下面的命令:
:grep error_string *.c
但是这个命令是使用外部的UNIX或是Linux命令,而且Vim会打开第一个匹配的文件,并将光标置于第一个查找到的字符串处.
vi编辑器的学习使用(十七)
在Vim编辑器有着相当丰富的命令和设置.有许多的命令设置可以说我们是根本就不会用到的.下面的只是简要的介绍一些这样的命令和设置的方法.
命令cscope可以检查C或是C++程序文件并产生一个含有程序中函数和变量信息的数据库.我们可以使用Cscope程序来查看这个数据库从而可以得函数定义和使用的一些信息.Cscope可以从下处得到:
http://cscope.soureforge.net
我们可以使用下面的命令来得一些详细的帮助信息:
:help cscope
Cscope一些相关的命令如下:
:cs arguments
:cscope argument
处理一些与Cscope程序相关联的活动
:cstag procedure
定位到Cscope数据库中名为procedure的函数标记处
:set csprg=program
:set cscopeprg=program
定义CScope程序名(默认为Cscope)
:set cst
:set cscopetag
:set nocst
:set nocscopetag
如果设置了cscopetag选项就可以在使用Cscope数据中使用命令(:tags,CTRL-])来浏览标记
:set csto=flag
:set cscopetagorder=flag
这个选项设置了CScope标记查询命令的查询顺序.如果是默认的0,那么会先查Cscope数据库,然后是标记;如果是1,则首先查在标记中查找.
:set csverb
:set cscopeverbose
:set nocsverb
:set nocopeverbose
如果设置了cscopeverbose选项,那么在Vim查找Cscope数据库并且查找失败时给出错误信息,而Vim默认的设置为nocscopeverbose
OLE系统是运行在Windows下面的程序彼此之间进行通信的方法.而Vim编辑器可以来扮演一个OLE服务器的角色.这就意味着我们可以来编写Window程序并与Vim通信.我们可以用下面的命令来得到更详细的帮助信息:
:help ole-interface
与Perl的接口可以使得我们在Vim中执行perl命令,同时可以提供给Perl程序一个接口,使得他可以访问Vim的功能.我们可以使用下面的命令来得一些更详细的帮助信息:
:help perl
Perl的一些接口命令如下:
:pe command
:perl command 执行单一的perl命令
:range perld command
:range perldo command 在几行上执行perl命令
与Perl相类似是Python.我们可以用命令:help python得到更详细的帮助信息.
Python的一些接口命令如下:
:range py statement
:range python statement 执行单一的Python命令描述
:range pyf file
:range pyfile file 执行文件中的Python程序
Sniff+的一些接口命令如下:
:sni command
:sniff command 通过与Sniff+的接口来执行命令.如果没有提供命令,则会显示出当前连接信息.
同样我们可以通过命令:help sniff来得到Vim提供的帮助信息.
Tcl的一些接口命令:
:tc command
:tcl command 执行单一的Tcl命令
:range tcld command
:range tcldo command
在所列出的行中每行执行一次Tcl命令
:tclf file
:tclfile file 在给定的文件中执行Tcl脚本
Vim编辑器可以处理各种不同的语言.在这里列出我们一些常用字的用其他语言来编辑文件的命令.如果我们要想得到一些更详细的说明,则要查阅Vim文档或是我们的系统文档了.
下面的是一个固定的常用的命令:
<F8> 在从左到右和从右到左两种模式间切换
:set rl
:set rightleft
:set norl
:set norightleft
通过这些选项的设置我们可以选择是从左到右的模式还是从右到左的模式
:set ari
:set allowrevins
:set noari
:set noallowrevins
通过设置这些选项我们可以通过CTRL-_来设置revins选项.这个可以使得我们选择语言的输入的是从左到右还由右至左.
:set ri
:set revins
:set nori
:set norevins
通过这些选项设置,我们可以选择在插入模式下是由左至右还是由右至左.如果设置了allowrevins选项我们可通过CTRL-_来在这几个选项间进行切换.
:set gfs=f1,f2
:set guifontset=f1,f2
定义英语使用f1字体,而另一种语言使用f2字体
这个选项只有在我们编译Vim编辑器时允许进行字体设置并且是只在UNIX系统才可以正常的工作.
:set lmap=ch1ch2,ch1ch2
:set langmap=ch1ch2,ch1ch2
为外文本设置键盘映射
Vim编辑器对汉字的输入支持由左到右,由右到左几种模式.他还支持传统的中文和简体中文.与中文相关的命令如下:
:set fe=encodning
:set fileencoding=encoding
设置文件的编码.对于中文这个选项可以是对于传统中文的*或是对于简体中文的pre.
如果我们要编辑Vim编辑器时打开了Farsi的支持,我们就可以在用这种语言来编辑文件了.可以用-F选项在启动Vim时进入Farsi模式:
$ vim -F file.txt
我们可以得到更详细的信息:
:help farsi
与Farsi相关的命令如下:
:set fk
:set fkmap
:set nofk
:set nofkmap
通过这些选项的设置我们可以告诉Vim我们正在使用Farsi键盘
:set akm
:set altkeymap
:set noakm
:set noaltkeymap
通过设置这些选项我们可以告诉vim编辑器键盘映射是Farsi还是Hebrew
CTRL-_ 在Farsi和正常模式下进行切换
<F9> 在标准的ISIP-3342编码和扩展的ISIR-3342编码之间进行切换
Hebrew是由右到左的另一种语言.采用Hebrew模式进行编辑可以使用下面的命令:
$ vim -H file.txt
:help hebrew可以使得我们得到更多的帮助信息.
与Hebrew相关的一些命令:
:set hk
:set hkmap
:set nohk
:set nohkmap
通过这些选项我们可以打开或是关闭Hebrew键盘映射
:set hkp
:set hkmappp
:set nohkp
:set nohkmapp
通过这些选项我们可以告诉Vim编辑器我们正在使用Hebrew键盘还是标准的英语键盘(默认为nohkmapp,即标准的英语键盘)
CTRL-_ 这个命令可以使得我们在Hebrew或是正常插入状态下进行切换
:set akm
:set altkeymap
:set noakm
:set noaltkeymap
如果设置了altkeymap选项,那么与其交换的键盘映射为Farsi.如果设置了noaltkeymap选项,那么则是Hebrew键盘映射.(默认为noaltkeymap)
Vim编辑器还可以支持日文,与日文相关的一些命令如下:
:set fe=japan
:set fileencoding-japan
告诉Vim编辑器当前文件采用日文编码.
我们可以通过命令:help hangul得到更多的韩文帮助信息.与韩文相关的命令如下:
:set fe=korea
:set fileencoding=korea
告诉Vim编辑器当前的文本采用韩文的编码.
我们还可以使用Vim编辑器来编辑二进制文件,相关的命令如下:
:set bin
:set binary
:set nobin
:set nobianary
如果我们设置了insertmode选项,那么Vim默认的便为插入模式.我们可以通过命令CTRL-O切换到正常模式.相关的命令如下:
:set im
:set insertmode
:set noim
:set noinsertmode
CTRL-L 如果设置了insertmode选项,则保留这种设置
vi编辑器的学习使用(十八)
我们在Vim编辑器的学习使用(二)曾学过一些基本的编辑命令,有了这样的一些基本的编辑命令,我们可以完成绝大多数的编辑任务.在这一次的学习中我们将会接触到更多的更深一些的东西.
Vim编辑器有着各种不同的命令可以使得我们任意的移到一个单词的开头或是结尾.但是有我们却可以通过Vim的一些选项的内容来自定义一个单词的定义.w命令可以使得光标向前移到一个单词.而命令e也是向前移到一个单词,但是这个命令是将光标定位在一个单词的结尾处.
而命令ge则是向后移到一个单词到达前一个单词的结尾处.
那么怎么样来定义一个单词呢?我们也许都知道单词只是一系列的字母的组合.然而在C程序中size56却会被认为是一个单词,因为在C程序中我们是通过字母,数字和下划线来定义一个单词的.但是在LISP程序中我们可以在变量名中使用-,这时他们会认为total-size是一个单词,而在C程序中这却会被认为是两个单词.我们如何来解决这样的冲突呢?Vim的解决办法是产生一个选项来定义哪些是一个单词中的,而哪些不是.例如下面的命令定义了属于一个单词中的字母:
:set iskeyword=specification
查看当前选项的值我们可以使用下面的命令:
:set iskeyword?
下面的是一般的值:
iskeyword=@,48-57,_,192_255
在这些值中间中用逗号来分隔的.
如果我们想要单词中的字母是专一的元音,我们可以使用下面的命令:
:set iskeyword=a,e,i,o,u
我们还可以使用横线来指定字母的范围.如果要指定所有的小写字母,我们可以用下面的命令:
:set iskeyword=a-z
对于那些不能直接指定的字符我们可以使用十进制的数字来表示.如果我们要指定小写字母和下划线为一个单词,我们可以使用下面的命令:
:set iskeyword=a-z,45
(短横线的十进制数字表示为45)
字母@指代C函数isalpha()返回值为真是的所有的字符.这个要取决于我们所使用的C编译器和我们编译Vim所使用的操作系统)
排除某一个字符我们可以在这个字符前加上一个前缀^.例如我们可以使用下面的命令来定义一个单词,这个单词可以由除了q以外的小写字符组成,也就是说在由空格分格的字符串组成,q为一个单词,而其他的字符串的组合为一个单词:
:set iskeyword=@,^q
而字符@则是由@-@所指代.
iskeyword选项一些特殊字符如下:
a 字符a
a-z 所有由a到z的字符
45 十进制数字45(短横线-)
@ 由函数isalpha()所定义的所有字符
@-@ 字符@
^x 除了x以外的字符
^a-c 除了a以处的到c的字符,即b和c
命令iskeyword可以简记为isk
iskeyword选项可以控制哪些字符可以是一个单词而哪些不是.下列的一些相似的命令可以控制其他类型的字符:
isfname 文件名
isident 定义
isprint 打印字符
选项isfname在使用命令gf时会用到,这个命令将会编辑以光标下的单词为文件名的文件.
选项isident在使用命令[d时会用到,这个命令将会查找以光标下的单词为名称的宏定义.
选项isprint定义了哪些字符可以显示在屏幕上.但是对这个我们要小心,如果我们弄错了,屏幕就会被弄得一团糟.这个选项还可以用特定的查找命令\\p,这代表可打印的字符.
也许到了现在我们已经明白了什么是单词(words).而Vim编辑还有一些命令影响到WORDS.虽然这只是大小的不同,但是他们却代到了两种不同的事物.word是指由iskeyword选项定义的字符串,而WORD则是指没有空白符的字符.在这样的观点上,that-all是两个单词(word),但是却是一个WORD.
W命令是向前移动WORDS,而B命令是向后移动WORDS.
与WORD相关的一些命令如下:
[count]B 向后移动count个WORDS
[count]E 向前移动count个WORDS,并且将光标置于WORD的末尾.
[count]gE 向后移动count个WORDS,并且将光标置于WORD的末尾.
[count]W 向前移动count个OWRDS.
我们可以使用命令将光标移动到一个句子中第一个没有空白符的字符处.如果我们要到达一行的开始处,我们可以命令用0命令.
我们可以使用命令fx在当前行光标的后面查找字符x.如果我们要重复这个查找操作可以使用命令;.就像大多数的Vim命令一样这个命令可以用数字来指明查找的次数.;命令是按照前一次f或是F的查找方向继续查找.如果我们要向相反的方向查找我们可以使用命令,.
命令-可以向上移动到第一个没有空白符的前一行处.我们可以指定参数来移到几行.
命令+可以向下移到到第一个没有空白符的后一行处,我们可以指定参数来移到几行.
命令_可以移动到当前行第一个没有空白符的字符处.
还有一些命令可以使得我们在屏幕的不同地方进行移动.H命令可以将光标移到屏幕的顶端.如果指定的数字参数则可以移动到从屏幕顶端算起的由数字所指定的行处.与H命令相类似是L命令,所不同的只是这个命令移动到屏幕的底端.M命令可以将光标移到屏幕的中间位置.
Vim编辑器还可以记录你曾经到过的地方,并且可以使得我们回到前一次到过的地方.例如我们在编辑一个文件的时候执行了下面的命令从而到过不同的行处:
1G 到第一行
10G 到第十行
20G 第第二十行
现在我们执行下面的命令:
:jumps
这样我们就会看到一个我们曾到过的行数的列表.在这个列表中>指的是这个列表中的当前项.这样在我们处在命令模式下我们就可以使用命令CTRL-O跳回一行.这样>所指的就会上移一项.而命令CTRL-I或是<TAB>可以使得我们在这个列表中向下跳转.应用这样的命令我们就可以实现在文件中进行快速的浏览和跳转.
在通常的情况下,当光标位于一行的开头是结尾的时候Vim是不可以移动光标的.但是我们可以通过设置whichwrap选项来控制光标是否可以越过一行的结尾并且Vim处于哪种模式.whichwrap选项一些可能的值如下表所示:
Character Command Mode(s)
b <BS> 正常模式或是可视模式
s <Space> 正常模式或是可视模式
h h 正常模式或是可视模式
l l 正常模式或是可视模式
< 左移 正常模式或是可视模式
> 右移 正常模式或是可视模式
~ ~ 正常模式
我们可以通过命令CTRL-G来使用Vim在屏幕的下端显示出我们所在的位置的一些信息.然而只要我们来发问我们就可以得到一些更详细的信息.为了得到更详细的信息,我们可以在CTRL-G命令加上一个数字参数.这个数字越大我们得到的信息就越详细.例如命令1CTRL-G会告诉我们文件的全路径.而命令2CTRL-G会同时显示缓冲区的数字标号.而命令gCTRL-G则可以显示当前光标所在的行号,列号以及文章的字符数等一些详细的信息.
我们在前面曾讨论过,CTRL-U命令可以使得vim编辑器向上翻滚半屏,但是我们可通过设置scroll选项来控制这个命令翻滚的行数.例如下面的命令可以使得Vim一次翻滚10行:
:set scroll=10
我们也可以通过防变CTRL-U命令的参数来改变翻滚的行数.例如命令2CTRL-U可以使得Vim编辑器一次向上翻滚两行,直到有命令来翻滚的大小为止.
如果我们要一次翻滚一行我们可以使用CTRL-Y命令.当然这个命令也可以在前面设置参数来控制翻滚的行数.而CTRL-B命令则是一次翻滚一屏.
与向上翻滚的命令相对是向下翻滚的命令,这样的命令有如下的一些:
CTRL-D 向下翻滚.这个数值我们可以通过scroll的值来控制.
CTRL-E 一次向下翻滚一行.
CTRL-F 一次向下翻滚一屏.
当光标到达窗口的上端或是下端的时候窗口要发生滚动.我们可以通过设置scrolljump选项来控制这个翻滚数值的大小.默认情况下为1,当然了我们也可以将其改我们希望的样子.如下面的命令将翻滚量设为5:
:set scrolljump=5
与其相类似的就是sidescroll选项,所不同是后者来控制水平的翻滚.
通常情况下,窗口的翻滚是当光标到达窗口的顶部或是底部时才发生的,我们也可以通过scrolloff选项来控制光标与顶部或是底部有多少距离时发生:
:set scrolloff=3
这个命令将其为3,当光标与顶部距离为三行时发生翻滚,且翻滚后光标与底部相距三行.
也许我们在编辑文件的过程中有时希望将指定的一行放在屏幕顶端.当然了这样的问题我们可以使用CTRL-E或是CTRL-Y命令来一行一行的移动直支满期足要求为止.我们还可以将光标放在指定的行上,然后输入z<Enter>.我们这一行就会出现在屏幕的顶端了.
这个命令在没有任何参数的情况是将当前行置于屏幕的顶端,我们还可以指定参数,这样就可以将指定的行置于屏幕顶端了.例如命令8z<Enter>就是将第八行置于屏幕顶端.这个命令不仅可以将指定的行置于顶端,还可以将光标移动到本行第一个没有空白符(non-blank)的字符处.如果我们要将光标保持在一行的某一位置不变我们可以使用命令zt,这样在这一行的位置发生变化,光标的位置也会保持不变.
如果我们要将指定的一行放在屏幕的底部,我们可以使用命令z-或是zb.所不同的只是前者是将光标放在这一行中第一个没有空白符的字符,而后者是保持光标的位置不变.
命令zz或是z.可以将指定的行放在屏幕的中部.这两个命令的不同就是前者保持光标的位置不变,而后者是将光标置于第一个没有空白符的字符处.
D命令可以将光标所在处到这一行的结尾的文字全部删掉.我们也可以在这个命令前面加上数字做为前缀,这样在执行这个命令以后,Vim不仅会将光标到光标所在行结尾处的字符全部删除,而且会再删除这一行以下的count(数字前缀)-1行文本.
与D命令相类似的是C命令.所不同的仅是C命令在删除文本以后会进入插入模式使得我们可以接着进行文本的编辑.
s命令可以删除单个的字符并进入插入状态.如果我们在前面加上数字做为前缀,那么Vim就会删除数字所指定的那么多的字符,然后进入插入状态.
而S命令是删除当前行然后进入插入状态.我们可以指定数字count做为前缀,这样Vim就会删除count个行,然后进入插入状态.这个命令与C命令的不同之处只是S命令作用整个行,而C命令仅是光标所处的位置到行末.
x命令是删除当前光标下的字符,如果指定count作为参数,则是向右查找count个字符并删除,而X命令是删除当前光标前的一个字行,如果指定count作为参数,则是向左查找count个字符并删除.
在进入插入模式时我们可以使用i或是I命令.i是在当前光标处开始插入字符,而I则是一行的开头部开始插入字符.(所谓的开头是指第一个没有空白符的字符处).如果我们要在一行中的第一个字符处开始插入我们可以使用gI命令(不论有没有空白符).a命令是在当前光标的后开始插入,而A命令与a命令相类似,只是他是在一行的后面开始插入状态.
Vim还可以对于文本进行简单的算术运算.命令CTRL-A可以将当前光标下的数字加1,我们还可以在前面指定参数,这样就可以指定的数字加在光标下的数字上了.如果这个数字是以0开头,那么Vim就会认为这是一个八进制的数.例如0177在我们执行这个命令后就会变为0200.如果一个是以0x或是0X开头的Vim就会这是一个十六进制的数,例如0x1E在我们执行这个命令后就会成为0x1F.与CTRL-A命令相类似的是CTRL-X命令.所不同的只是这个命令会使得当前光标下面的数字减1.Vim是一个精巧的编辑器,他可以很好的来处理十进制,八进制,十六进制的数字计算问题.
在默认的情况下,Vim可以识别出八进制和十六进制的数字.我们可以通过nrformats来控制Vim所识别的数字形式.如果要使得Vim识别出十进制和八进制的数字,我们可以使用下面的命令:
:set nrformats=\"\"
如果我们要使Vim只识别出八进制数,我们可使用下面的命令:
:set nrformats=octal
默认的情况下我们Vim可以识别出十进制,八进制,十六进制数字:
:set nrformats=octal,hex
我们可以使用J命令将当前行和下一行合并为一行.在合并后Vim会加入一空格来分隔这两行.如果我们不希望用空格来分隔,我们可以使用gJ命令.这个命令与J命令类似,只是他不会加入空格来分隔这两行.
R命令可以使得Vim进入替换模式.在这种模式下,我们输入的每一个字符都会替换光标下面的字符,直到我们按<ESC>退出为止.我们还可以指定数字作为参数来指明这条命令所要执行的次数.(注:这里我做的结果是r命令可以指定参数来指明执行次数,而R命令则不成)
当我们在替换的文本中有<Tab>键时,替换命令就会出现问题.因为他也会将<Tab>替换为相应的字符,这样就影响了我们文本的缩进.在这样的情况下我们可以使用gr命令来进行替换.如果光标下的字符是Tab的一部分,那么就会跳过而替换别的字符,这样就不会影响我们文本的缩进了.我们还可以使用gR命令进入虚替换模式(virtual replace mode),这时我们输入的字符就会替换屏幕空白处的一个字符.
我们可以通过执行命令CTRL-K character1 character2来插入一个特殊字符.我们也可以用下面的命令为定义们的自己的特殊字符:
:digraphs character1 character2 number
这就是告诉Vim编辑器当我们输入CTRL-K character1 character2命令以后要插入数字表示为number的字符.
如果我们的工作要我们插入很多的特殊字符,我们可以用下面的命令打开digraph选项:
:set digraph
关闭这个选项的命令为:
:set nodigraph
(注:这部分内容部是看不明白,也做不出结果)
命令~可以改变字母的大小写.~命令的执行结果是由选项tildeop的值来控制的.如果我们没有设置这个选项,那个这个命令就像正常一样的动作:
:set notildeop
但是如果我们设置了tildeop选项,那么这个命令的语法就变成了~motion的形式:
:set tildeop
例如下面的句子:
this is a test
如果我们没设置这个选项,那么在我们执行命令时就会实单个字符的大小转换.但是在我们设置了这个选项以后,我们将光标放在第一t上并执行~ft的结果则为
THIS IS A Test
这个命令会使得当前光标以后第一t和光标间的字符全部转换为大写.如果在这个句子中还有小写的字符,那么这个命令还可以执行第二次.直到句子中的字符全部为大写为止.
这时的命令还可以指定字符转换的个数和方向.例如命令3~l是从当前字符开始向右3个字符进行大小写的转换.与这个命令方式相类似的是g~motion格式的命令,所不同的仅是后者不依赖于tildeop选项的设置.命令g~g~或是g~~是进行整个一行的转换.
其他的一些大小写转换的命令还有:
gUmotion命令是使得当前光标处到motino所指处的字符全部变为大写.而gUU或是gUgU则是作用在整个行上.如果指定了参数count则所指定的行都会发生变化.而gumotion,guu,gugu则是和上面所说的命令相类似,所不同的只是他们是将字符变为小写.
我们在用Vim进行编辑的时候可以进行多次的撤销命令,这个次数是由选项undolevels来指定的.如果我们要将这个值设为5000,那么我们可以用下面命令来做到:
:set undolevels=5000
命令ZQ是命令:q!的另一种说法.这个会放弃我们所做更改然后退出.
命令:write则是保存文件.命令:quit是退出Vim.我们可以使用一个缩写来达到保存退出的目的::wq
这个命令可以用参数来指定保存退出时使用的文件名,如:
:wq filename
如果这个文件存在且是一个只读文件时我们会得到一些错误信息,当然了我们可以强制执行这个命令:
:wq! filename
我们还可以将指定的行进行保存:
:1,10 wq filename
与命令:wq相类似的命令是:xit
vi编辑器的学习使用(十九)
Vim编辑器强大的搜索引擎可以使得我们快速的执行各种类型的查找,从而大的方便了我们的编辑工作,使得我们的编辑工作更加快速和高效.
我们在进行查找的过程中可以打开高亮显示选项,这样在我们找到我们想要的字符后,Vim就会将字符串进行高亮显示,我们也可以很方便的知道我们要找的字符串在哪里.我们可以使用下面的命令来打开高亮显示选项:
:set hlsearch
关闭这个选项的命令为:
:set nohlsearch
在默认的情况下Vim编辑器是很敏感的,也就是Vim编辑器可以很好的来区分一个单词的大小写,从而可以准确的查找得到我们想要的字符串.例如如果一个文件中有这样的几个字符串:
include,INCLUDE,Include.当我们使用命令/include来查找字符串时只有include字符会被高亮显示.
但是如果我们打开ignorecase选项后再执行这个命令结果就不一了,这时所有的类似的字符都会被高亮显示.打开这个选项的命令为:
:set ignorecase
但是这样的查找结果并不是我们想要的,也不是我们所希望发生的,因而我们常用下面的命令选项设置:
:set noignorecase
这样Vim就可以正确的查找我们想要的字符串.
如果我们设置了ignorecase选项后,我们想要查找字符串word,而匹配的则可能是word,Word,WORD.如果我们要查找字符串WORD,匹配的结里也是一样的.但是如果我们设置了以下的两项后的执行结果就会变得不一样了:
;set ignorecase
:set smartcase
经过这样的设置以后,如果我们输入的是小写字符,那么Vim就会匹配各种可能的组合,这时与设置了ignorecase的情况相同,但是如果我们在输入中有一个大写字符,那么这时的查找就变成了精确查找了,与设置了noignorecase的情况相同.
在默认的情下,我们输入要查找的字符串,vim是从当前光标处向前查找,直到文件的结尾,如果没有打到,那么就会从文件的开头开始查找,直到光标所处的位置.我们可以通过设置选项nowrapscan来禁止这种循环查找的方式,这个命令如下:
:set nowrapscan
这样以后如果已经查找到文件的底部时就会在Vim底部显示出一条错误信息.如果我们想要回到正常的状态,我们可以使用下面的命令;
:set wrapscan
如果我们正处在一个很长的查找过短中而我们想要停止这一查找开始我们新的工作,这时我们可以使用CTRL-C命令,如果是在Windows系统上则要使用CTRL-BREAK命令.
我们在编辑文件的过程中还可以使用立时查找的命令.如果我们想快速查找当前光标下的字符串,我们可以使用命令*,这个命令可以向前查找与当前光标下的单词精确匹配的字符串.而命令#则向前查找与当前光标下的字符精确匹配的字符串.换句话说如果当前光标下的字符串为word,在执行*命令查找时并不会与Word相匹配.与这个立时查找命令相类似的就是g*命令.这也是一个立时查找的命令,只不过他不会进行严格的整字匹配,如果用这个命令来查找word那么就有可能和Word相匹配.而g#命令与其相同,只不过他是向相反的方向进行查找匹配.
在默认的情况下,在查找时Vim会将光标放在第一个匹配的结果的开始处.我们也可以指定查找结束后光标所处的位置.对于向前查找的命令我们可以斜线后用数字来指明光标所处的位置,如下面的命令:
/set/2
这个命令会在查找结束后将光标入在第一个set字符串后第二行的开始处.
在这个命令中这个数字可以是正数也可以是负数.如果仅是一个简单的数字,光标会被放在第一个匹配字符串处后或是前的数字所指定的行的开始处.正是向后,负数是向前.如果斜线后是b和数字的,那么在查找结束后,光标将会被置于第一个匹配字符串的开始处,然后向左或是右移动n个字符,这里的n即为数字所指定的数.如果为正数则是向右移动,如果是负数,则是向左移动.如下面的命令:
/set/b2
这个命令会使用Vim在查找结束后将光标放在第一个匹配字符的开始处,然后向右移动两个字符,也就是说最后光标会位于第一个匹配字符串中的t的位置.将b改为s也是一样的效果.
与参数b或是s相类似是e参数,这个参数会使得光标放在第一个匹配字符串的结尾处.同样我们也可以指定数来指是向右还是向左移动光标以及移动的字符数.如下面的命令:
/set/e
这个命令会使光标放在第一个匹配字符处的结尾处,在没有指定数字时是这个样子的.而下面命令:
/set/e2
这个命令是会将光标放在第一个匹配字符串的结尾处,然后向右移动2个字符.这里的数字如果是正数则向右移,如果为负数,则向左移.
例如下面的命令:
/set/e+2
这个命令是告诉Vim在查找set字符串结束后将光标放在第一个匹配字符串的结尾处,然后向右移动两个字符.在这里我们将这个数字称为偏移量.如果我们要重复上一次的查找但是需要不同的偏移量我们可以用下面的命令:
//5
不使用偏移量时我们可以指明一个空的偏移量,如:
//
例如下面的一些例子:
/set/e+2
向前搜索字符串2,并将光标放在第一个匹配字符串的结尾处,然后向右移动2个字符
/ 重复前一次的查找,使用相同的偏移量.
// 重复前一次的查找,但是不使用偏移量.
我们还可以使用查找命令?来进行类似的查找,例如:
?set?b5
这个命令是告诉Vimu将光标放在最后一个匹配字符串的开头部分,然后向右移动5个字符
??-2命令则继续前一次的查找命令,但是使用新的偏移量.
??命令是继续前一次的查找命令,但是不使用偏移量.
但是有一件事我们要清楚的就是我们在用偏移量进行光标定位时的查找是从当前光标所在处开始的,这会给我们带来一些麻烦.例如我们在执行命令/set/-2时Vim会将光标放在第一匹配的字符串处,然后上移两行.当我们用n命令来重复上一次的查找时,我们会找到我们刚才找到过的那个字符串,然后再向上偏移两行.这个结果就是不论我们输入了多少的次n命令,我们仍是在原地踏步的,哪里也去不了.
Vim使用通用的表达式(regular expressions)来进行逻辑查找.我们在以前讨论过用简单的字符串进行查找,但是这里我们将要看到的通用字符串查找要简单字符查找的功能强大得多.通过在我们的命令中使用通用表达式,我们可以查找任何一种字符类型,例如我们可以查找以t开头而以ing结尾的字尾串(通用表达式为\\<t[^]*ing\\>).然而这种强大的功能也是要付出一定的代价的.通用表达式是神秘的和简洁的.也许我们要花上很上的一段时间才会习惯这种查找方式,然后才能掌握这个强大的查找工具.
在学习这些通用表达式的查找的过程中我们最好将高亮显示这个选项打开,这样就可以使Vim高亮显示最后一次查找的匹配结果.打开高亮显示的命令为:
:set hlsearch
一个通用表达式是由一些元素组成的.这些元素是通用表达式中最小的匹配单位.一个元素可以是一个字符,例如a,与字符a相匹配,或者是一个特殊字符,例如$,匹配一行的结束.还可以是其他的字符,例如\\<,是指一个单词的开始.
在通用表达式中,我们用\\<来匹配一个单词的开始,用\\>来匹配一个单词的结束.也就是说要将我们想要查找的字符串放在这两个中间.这样我们就可以精确的来查找我们想要查找的字符串,而不会有其他的一些匹配情况.而如果我们用简单字符串形式来查找,我们就会得到许多的匹配情况,甚至在一个单词中的组成部分也可以成为匹配情况.例如在文件中有Californian,Unfortunately.如果用命令/for来查找,那么就会找到这两个单词.而如果我们用通用表达式\\<for\\>来进行查找,则只会精确的查找到for,而不会用其他的匹配情况.这时的命令形式如下:
/\\<for\\>
我们在进行查找的时候还可以使用一些修饰符来进行表达式的组合.例如修饰符*就可以表示一个字符可以匹配0次或是多次.换句话说,Vim编辑器会进行尽可能多的匹配.所以通用表达式te*可以匹配te,tee,teee等等.基于还可以匹配t,为什么呢?因为在这里e可以匹配0次,所以就可以匹配t.而修饰符\\+则表明这个字符可以匹配一次或是多次.所以表达式te\\+可以匹配te,tee,teee等等.但是这一次这个表达式不可以再匹配t了,因为这里e最少要匹配一次.
最后一个修饰符\\=表示一个字符匹配0次或是一次.这就是说表达te\\=可以匹配t,te,但是不可以是tee,虽然这个命令会匹配tee的前两个字符.
还有一些特殊的字符可以来匹配一定范围的字符.如\\a匹配一个字符,而\\d匹配任何数字.所以表达式\\a\\a\\a可以匹配任意三个字符.例如下面的命令可以查找任意四个数字:
/\\d\\d\\d\\d
我们还可以用下面的命令来查找任意后带一个下划线的三个字符:
/\\a\\a\\a_
\\a可以匹配所有的字符(小写的或是大写的).但是假如我们现在只要匹配元音字符又该如何来做呢?这时我们可以使用范围作用符[].范围作用符可以匹配一系字符中的一个.例如[aeiou]只匹配一个小写元音字符.所以表达式t[aeiou]n可以匹配tan,ten,tin,ton,tun.
我们还可以通过短横线来在括号内指明字符的范围.例如[0-9]可以匹配0到9中的任一字符.
我们还可以组合其他的字符.例如[0-9aeiou]可以匹配任意一个数字或是小写的元音字符.
而修饰符^可以指代除本身以外的所有字符.
下面列出一些匹配的情况:
表达式 匹配结果
one[\\-]way one-way
2\\^4 2^4
2[\\^*]4 2^4,2*4
如果我们要指找所有的大写字符又应如何来做呢?一个办法就是使用表达式[A-Z].还有一个办法就是我们可以使用预先定义的字符类.[:upper:]可以匹配大写字符.所以我们要指找大写字符也可以这样的来写:[[:upper:]].我们可以使用字符类来写出所有的字符:
[[:upper:][:lower:]].
在Vim中还有许多不同的字符类定义
我们还可以通过表达来指出一个字符重复的次数.这个的一般格式如下:
\\{minimum,maximum}
例如表达式a\\{3,5}可以匹配3到5个a.在默认的情况下Vim将会尽可能多的进行匹配.所以表达a\\{3,5}最多可以匹配到5个a.
在这个命令格式中最小次数可以省略,Vim默认的情况下最小次数为0.所以表达式a\\{,5}可以匹配0到5个a.最大次数也可以省略,在这种情况下Vim默认匹配无穷大.所以表达式a\\{3,}最少可以匹配3个a,最多是尽可能的多.
如果我们只指定一个数字,那么Vim就会精确的匹配相应的次数.例如a\\{5}只会精确的匹配5次.
如果我们在数字前加了一个负号(-),那么Vim在查找时就会尽可能少的进行匹配.
例如a\\{-3,5}匹配3到5个a,但是会尽可能少的进行匹配.事实上这个表达式仅会匹配3个a,哪怕是我们的文件中用aaaaa,Vim也只会尽可能少的进行匹配.
表达式a\\{-3,}匹配三个或是更多个a,并且尽可以少地的进行匹配.而表达式a\\{-,5}可以匹配0到五个字符.表达式a\\{-}可以匹配0到无穷大个字符.在通常情况下这个表达式匹配0个符,除非在他的后面还有字符或是表达式.例如[a-z]\\{-}x将会匹配.cxcx中的cx.而表达式[a-z]*x将会匹配整个cxcx.最后表达式a\\{-5}将会精确的匹配5个字符.
我们还可以使用运算符\\(和\\)定义一个组.例如表达式a*b可以匹配b,ab,aab,aaab等等.而表达式a\\(XY\\)*b可以匹配ab,aXYb,aXYXYb,aXYXYXYb等等.
我们还可以用或运算运符\\|来查找两个或是多个可能的匹配.例如通用表达式foo\\|bar可以查找foo或是bar.
现在我们知道了这样多的表达式的表示方法,那么我们如何来应用他们呢?例如我们现在要查的内容为1MGU103.这个字符串是由1个数字,3个大写字符,3个数字组成的.可以有几种方法来表示:
一是先表示前面的一个数字:[0-9],然后加入大写字符后就成为了:[0-9][A-Z].因为有三个大写字符我们可以加入精确匹配的数字:[0-9][A-Z]\\{3}.最后我们再加入最后面的三个数字.所以最后的结果就成了:[0-9][A-Z]\\{3}[0-9]\\{3}
另一种利用\\d指任何的数字,而\\u指任何的大写字符.所以用这样的方法写成的表达示就为:
\\d\\u\\{3}\\d{3}.
从这里我们可以看到用这样的方式来查找要比第一种方法快得多.如果我们编辑的文件在采用这两种方法进行查找时会看出差别,那么我们的文件也许就是太大了.
我们还可以用这样的表达示:\\d\\u\\u\\u\\d\\d\\d,这个也可以找到我们想要的内容.
最后我们还可以用字符类来写出我们的表达式:
[[:digit:]][[:upper:]]\\{3}[[:digit:]]\\{3}
这四种方法都可以很好的来完成我们的工作,我们只要记住一种我们容易记住的就可以了.毕竟我们可以记住的简单的方法要比我们不能记住的精妙的方法快得多啊.
到现在我们所有的讨论和方法都是在认为我们已经打开magic选项的基础上来做的.如果这个选项被关闭了,那么我们在通用表达式中的许多的特殊字符就失去了他们神奇的魔力,我们只有通过字符转义才可以正常的来使用.
关闭magic的选项命令为:
:set nomagic
这时*,.,[,]就都被认为只是平常的字符了.如果我们还想用*来指0次或是更多次就要用到转义:\\*.
所以我们应保证magic选项是打开的,这样我们也才可以使用Vim强大的搜索能力,而这也正是Vim默认情况下所做的.
一些常用的偏移(Offset)定义:
+[num] 光标置于第一个匹配字符下第num行的开始处.
-[num] 光标置于第一个匹配字符上第num行的开始处.
e 匹配字符串的结尾处.
e[num]
光标置于第一个匹配字符串的结尾处,然后移动num个字符,如果为正,向右移,为负,向左移.
b s 第一个匹配字符串的开始处.
b[num]
s[num]
光标置于第一个匹配字符串的开始处,然后移动num个字符,如果为正,向右移,为负,向左移.
常用的通用表达式如下:(认为magic选项打开)
简单的元素:
x 字符x
^ 一行的开始处
$ 一行的结尾处.
. 单一的字符
\\< 查找字符串的开始标记
\\> 查找字符串的结束标记.
范围运算符:
[abc] 匹配a,b或是c
[^abc] 匹配除abc以处的字符
[a-z] 匹配从a到z的所有小写字符
[a-zA-Z] 匹配所有字符,包括大小写.
字符类:
[:alnum:] 匹配所有的字符和数字
[:alpha:] 匹配所有的字符
[:ascii:] 匹配所有的ASCII字符
[:backspace:] 匹配退格符<BS>
[:blank:] 匹配空格和Tab
[:cntrl:] 匹配所有的控制字符
[:digit:] 匹配所有的数字
[:escape:] 匹配Esc
[:graph:] 匹配所打印的字符,不包括空格
[:lower:] 匹配所有的小写字符
[:print:] 匹配所有的要打印字符,包括空格
[:return:] 匹配所有的行末符号(包括<Enter>,<CR>,<NL>).
[:punct:] 匹配所有的功能符号
[:space:] 匹配所有的空白符
[:tab:] 匹配Tab
[:upper:] 匹配所有的大写字符
[:xdigit:] 匹配十六进制数字.
类型:
\\(pattern\\) 标记一个类型以后使用
\\1 与第一个在\\(\\)中的子表达式匹配的字符串匹配相同的字符串
例如表达式\\([a-z]\\)\\1可以匹配aa,bb或是类似的.
\\2 与\\1相类似,但是是使用第二个子表达式
\\9 与\\1相类似,但是是使用第九个子表达式
特殊字符:
\\a 大小写字母字符
\\A 除了a-zA-Z以外的字母字符
\\b <BS>
\\d 数字字符
\\D 非数字字符
\\e <ESC>
\\f 由isfname选项定义的文件名字符
\\F 文件名字符,但是不包含数字
\\h 单词的头字符(A-Za-z)
\\H 不是单词的头字符(A-Za-z)
\\i 由isdent选项定义的字符
\\I 定义的字符,但是不包括数字
\\k 由iskeyword选项定义的关键字字符
\\K 关键字字符,但是不包括数字
\\l 小字字符(a-z)
\\L 非小写字符(除了a-z以外的字符)
\\o 八进制数字
\\O 非八进制数字
\\p 由isprint选项定义的可打印字符
\\P 可打印字符,但是不包括数字
\\r <CR>
\\s 空白符<Space>和<Tab>
\\S 非空白符
\\t <Tab>
\\u 大写字母字符(A-Z)
\\U 非大写字母字符
\\w 单词字符(0-9A-Za-z)
\\W 非单词字符
\\x 十六进制数字
\\X 非十六进制数字
\\~ 匹配最后指定的字符串
修饰符:
* 匹配0次或是多次,尽可能多的匹配
\\+ 匹配1次或是多次,尽可能多的匹配
\\= 匹配0次或是1次
\\{} 匹配0次或是多次
\\{n}
\\{-n} 匹配n次
\\{n,m} 匹配n次到m次
\\{n,} 匹配n次到多次
\\{,m} 匹配0次到m次
\\{-n,m} 匹配n次到m次,尽可能少的进行匹配
\\{-n,} 至少匹配n次,尽可能少的进行匹配
\\{-,m} 匹配到m次,尽可能少的进行匹配
\\{-} 匹配0次到多次,尽可能少的进行匹配
str1\\|str2 匹配str1或是str2
vi编辑器的学习使用(二十)
Vim编辑器有不同的方法来处理各类事物.我们在Vim编辑器的学习使用(四)已经讨论过文本块和多文件的处理方法.有了这些命令,我们就可以很好的来完成我们的工作.在这一次的学习中我们会讨论一些更多的内容.从而使得我们的Vim编辑工作来得更完美一些.
当我们插入文本行的时候可以使用p命令或是P命令.所不同的是p命令是在当前行的下一行进行插入,插入后光标移动到新行的开头处,而P命令是在当前的上一行进行插入,插入后光标移到新行的下一行的开头处.而我们还可以使用gp或是gP命令.不同的是gp命令是将光标移动到新行的结尾处,也就是新行的下一行的开头处.gP命令与此相类似,是在当前的上一行进行插入,插入后,光标移动新行的结尾处,也就是下一行的开头处.
在Vim编辑器中还有一些特殊的标记符,如单引号\'是指光标上一次的位置,但是这个位置不包括由方向键移动的位置.其他的一些特殊的标记包括:
] 上一次插入的文本的开头
[ 上一次插入的文本的结尾
\" 当我们离开文件时光标所处的位置
(注:这个地方看书是这样写的,但是自己做时却只可以是\',[,],而且是要按两次键才行,不解:().
到现在为止我们所做的所有的复制和删除文本时我们并没有指明我们要使用哪一个寄存器.如果我们没有指明要用哪一个寄存器,Vim就会使用默认的没有命名的寄存器.用来指明这个寄存器的标记符是两个双引号(\"\").在这里前一个双引号用来指示一个寄存器,而后一个双引号则是这个寄存器的名字.这样\"a就是指我们使用a寄存器.
我们可以在我们的复制文本或是删除文本这前来指明我们的所复制或是删除的文本要放在哪一个寄存器中,指明寄存器的命令格式如下:
\"register
在这里register是一个小写字母,是我们所指定的寄存器的名字,这样我们就可以有26个寄存器可以使用.
在通常的情况下我们使用yy所复制的文本是被放在没有命名的那个寄存器中,我们可以使用命令\"ayy将我们所复制的文本放在指定的寄存器中.当然如果我们使用这样的命令,我们所复制的文本也会被放入未命名的寄存中的.
如果我们想知道寄存中都包含有哪些内容,我们可以使用下面的命令:
:registers
一般我们复制或是粘贴的文本会被入以字母命名的寄存器中,当然我们也可以使用一些特殊的寄存器.
我们可以通过给命令:registers一个参数,我们可以来查看特定寄存器中的内容,例如我们可以用下面的命令来查看寄存器a和x中的内容:
:registers ax
当我们使用命令\"ayy我们是将当前文本行的内容放入寄存器中,而当我们再使用相应的大写字母来指定寄存器时,如\"Ayy我们是将当前行内容追加到寄存器\"a中,这时候在这个寄存器中就存两行文本,在寄存器中^J是指一行的结束.
在Vim中还有一些特殊的寄存器,第一个就是我们已经知道的未命名寄存器,他的名字是一个双引号\".其他的还有1到9寄存器,寄存器1中含有我们上一次删除的文本,依次类推.
在古老时代的Vi中,Vi只可以撤销三次.如果我们将dd命令执行了三次,也许我们就没有太多的好运来使用u命令将我们删掉的文本再恢复过来.但是幸运的是这三个文本被分别存放在寄存器1,2,3中.我们可以通过命令\"1P,\"2P,\"3P将这些文本再粘贴回来,或者是我们可以使用下面的命令来达到同样的结果:
\"\"P..
其他的一些特殊的寄存器:
寄存器 描述 可复写
0 上一次复制的文本 是
- 上一次删除的文本 否
. 上一次插入的文本 否
% 当前文件的名字 否
# 交替文件的名字 否
/ 上一次查找的字符串 否
: 上一次\":\"命令 否
_ 黑洞(black hole) 是
= 表达式 否
* 由鼠标选中的文本 是
黑洞寄存器(_)(The Black Hole Register)
黑洞寄存器是一个特殊的寄存器,我们放入其中的任何文本都不复存在.当然我们也可以使用p命令来粘贴这个寄存器中的文本,但是这样做是没有意义的,因为在这个寄存器中根本就不存在任何内容.这样的寄存器也有着相当重要的作用.如果我们想永久删除某一文本而不是将他放入1-9中某个寄存中,我们可以使用这个寄存器.例如命令dd删除一行文本并将这一行文本存在寄存器1中,而我们用命令\"_dd则是将这行文本放入黑洞寄存器中,这些文本也就会永久地消失了,而寄存器1中的文本会保持不变.
表达式寄存器(=)(The Expression Register)
我们可以使用表达式寄存器来在文本中输入表达式.当我们输入表达式寄存器开始的命令时,就会在Vim的下部显示一个提示行,这就是给我们一个机会,我们就可以在这里来输入我们的表达式了.然后我们可以使用命令p将表达式的结果粘贴到文本.
例如我们要在文本中插入38*56的值,我们可以这样来做:
进入命令模式,输入表达式寄存器开始的命令\"=,这时就会在Vim的下端显示出=来等待我们的输入,我们可以输入38*56,回车,然后输入命令p,这样就可以将我们的计算结果插入文本中了.
在表达式寄存器中我们不仅可以使用通常的算术运算符,还可以使用Vim特定的函数和运算符.如果我们不仅仅是用常用的算术运算符来完成我们的工作,也许我们就需要来查阅表达式文档了.例如我们可以通过表达式寄存器来得到环境变量的值.如果我们输入\"=$HOME我们就可以得到HOME变量的值了.
剪切板寄存器(*)(The Clipboard Register)
剪切板寄存器可以使得我们通过系统的剪切板来读写数据.如果是在UNIX系统上,这个要在图形界面下使用.这样我们就可以通过剪切板寄存器来在不同的Vim编辑器或者是其他的程序包之间进行文本的剪切和复制.
我们在UNIX或是Linux系统中可以使用Vim编辑器和grep命令处理包含某一个指定词的所有文件.这对于我们有着极大有用处,因为我们可以用这个组合来查看或是处理包含某一个变量的程序文件.例如现在我们要编辑包含有变量frame_counter的C程序文件.这时我们就可以使用下面的命令:
$ vim `grep -l \'frame_counter\' *.c`
(注:在这里最外面的是反外号,即数字键1旁边的,而里面的是单引号)
在这个命令中,grep命令在一系列文件查找包含有指定单词的文件.在这里我们指定-l选项,这样这个命令就会列出包含有这个单词的文件,而不会打印找到的字符串.在这里我们要查找的字符串frame_counter,我们可以使用这个命令来查找其他的字符串或是表达式.而整个的命令由反引号包括起来.这就可以告诉UNIX Shell来运行这个命令,并假定认为这个命令的执行已由命令打印输出.所以这个命令的执行结果就是运行grep命令并产生一个文件的列表,这些文件名放在Vim的命令行中,这样Vim就可以来编辑这些文件了.
也许有的人会说为什么要在这里展现这个命令呢?这是UNIX Shell的特征而不是Vim作品的一部分.而这正是使得Vim更加完美.
我们可以用下面的命令来设置参数列表:
:arg `grep -l \'frame_counter\' *.c`
在这个参数列表中我们可以用命令来指定我们想要编辑的文件,例如如果我们要编辑第三个文件我们可以用下面的命令:
:argument 3
这个命令可以使得我们用文件在参数列表中的位置来编辑这个文件.如果我们是用下面的命令来启动Vim的:
$ gvim one.c two.c three.c four.c five.c
这时如果我们要编辑第四个文件我们可以用下面的命令:
:argument 4
当我们在命令行中用命令来指定一系列文件时,我们完成文件列表的初始化工作.但是我们可以用命令:args来指定新的文件列表.例如下面的命令:
:args alpha.c beta.c gamma.c
执行完毕这个命令以后我们开始编辑文件alpha.c,然后是文件beta.c.
有时我们在编辑文件时希望文件在打开后光标能定位我们希望在的行,这我们该如何来做到呢?例如我们要第12行开始编辑文件,我们可以用命令打开这个文件,然后执行命令12G来使得光标到指定的行.我们也可以在vim启动时在命令后面加上行号来指明光标要到的地方.如下面的命令:
$ gvim +12 file.c
我们还可以用这样的命令形式+/string来使得文件在装入以后光标放在指定的字符串.例如我们希望文件在打开后光标放在第一个包含字符#include处,我们可以用下面这样的命令:
$ gvim +/#include file.c
当然我们可以在+后面放上任何命令模式的命令.
我们可以用多种多样的命令来指明+cmd的参数.通常:vi命令格式如下:
:vi [+cmd] {file}
下面的这些命令也可以带上+cmd的形式:
:next [+cmd]
:wnext [+cmd]
:previous[+cmd]
:wprevious [+cmd]
:Next[+cmd]
:wNext[+cmd]
:rewind[+cmd]
:last[+cmd]
标记符a-z只是当前文件的标记.换句话说,我们可以在一个文件标记a,也可以在另外一个文件中标记a.如果我们执行命令\'a我们就可以跳转到当前文件中的a标记处.而大写字母(A-Z)的标记符则就不一样了.他不仅标记了当前文件中的某一行而且也标记当前文件.例如我们正在编辑文件one.c而且在其中用A做了一处标记.然后当我们在编辑文件two.c时我们就可以执行命令\'A,这样就可以跳转到one.c文件中的标记处
当我们用插入模式进入文本时我们也可以执行种不同的命令.例如<BS><BackSpace>可以清除光标前面的字符,而CTRL-U会清除整个一行或者至少是你刚输入的内容,CTRL-W会清除光标前面的字符.当我们在插入模式时我们也可以来移动光标,这时我们不可以再用传统的h,j,k,l,但是这时我们可以使用小方向键来移动光标.<HOME>可以移动到一行的开头,<END>可以移动到一行结尾.<PageUp>可以向上翻屏,<PageDown>可以向下翻屏.
在插入模式下如果我们输入CTRL-A,Vim编辑器就会插入我们上一次在Vim插入状态时所输入的文本.例如如果我们在文件中一行里输入#include,然后我们用命令j向下移动一行并插入新的一行,这时如果我们想输入#include,可以用命令CTRL-A来完成.CTRL-@命令与其相类似,所不同的只是在执行完这个命令后会退出插入模式.我们还可以用命令CTRL-V来引用下一个字符,换句话说任何有着特殊意义的字符他都将被忽略掉.例如如果我们输入CTRL-V<Esc>会在文本中插入空白符.我们也可以用命令CTRL-Vdigits来插入这个数字所指的字符,例如如果我们输入CTRL-V64就会在文本中插入@.在默认的情况下CTRL-V是使用十进制的数字,但是我们也可以插入十六进制的数字.
CTRL-Y命令可以输入光标上面的字会,当我们想要重复上一行时这个命令就会显得尤为有用.
与CTRL-Y命令相似的是CTRL-E命令,不同的是这个命令可能重复光标下面的字符.
命令CTRL-Rregister可以使得我们寄存器中的内容插入文本中.如果寄存器的内容含有类似于<BS>这样的特殊字符时,这些特殊会被重样解释,就像我们从键盘中输入这些字符一样.如果我们想这样,只是想着将这些字符作为普通字符业对待,我们可以用这样的命令:CTRL-R
CTRL-R register
例如我们输入下面的文本:
This is a test.
然后我们用命令\"ayy将这些文本复制到寄存器a中,完成以后我们进入插入模式,输入命令CTRL-Ra,我们就会刚才我们复制的内容就会出现在文本行了.
如果我们不希望特殊字符被重新解释我们可以用命令CTRL-R CTRL-R register.
命令CTRL-\\CTRL-N可以离开插入模式而回到正常模式下.换句话这个命令与<ESC>相类似,但这个命令可以在任何模式下使用,就这一点而似乎是要比<ESC>命令强大一些啊.
最后要介绍的就是CTRL-O命令,这个命令可以回到命令模式执行Vim命令在执行完以后又回到了插入模式.例如我们执行命令CTRL-Odw,Vim就会回到命令模式执行命令dw,在执行完毕后又回到了插入模式.
我们在使用全局标记时遇到的一个问题就是当我们退出Vim以后我们所设定的那些全局变量就不在存在.而我们希望能将这些保存下来.文件viminfo就是设计成为一个用保存标记信息以及下面的一些信息的文件:
命令行历史
查找历史
输入历史
寄存器
标记
缓冲区列表
全局变量
保存某一项的办法是我们要打开这个保存的选项,我们可以下面的命令来做到:
:set viminfo=string
这里的string表明了我们要保存的内容.
这里的string的语法是一个选项字符跟上一个参数.中间用逗号来分隔.首先\'option用来表明我们要为少文件保存局部标记,我们可以选一个合适的数字,例如我们要选1000,那么这时的命令形式如下:
:set viminfo-\'1000
而f选项则用来控制是否要保存全局标记.如果这个选项的值为0,则不保存,如果值为1或是我们没有指明f选项,那么vim都会保存这些全局标记.如果我们要用这一特征,我们可以用下面的命令:
:set viminfo=\'1000,f1
选项r会告诉Vim一些关于可移动介质的情况.在Vim中为可移动介质上的文件所做标记是不会被保存的,原因就是我们在Vim中要跳转到软盘文件的标记处是一个很难的操作.我们多次来表明r选项.如果我们在Windows系统上就可以用下面的命令来告诉Vim磁盘A和B是可移动介质:
:set viminfo=\'1000,f1,rA:,rB:
在UNIX系统并没有标准的软盘名称.在一般的情况下我们总是将软盘挂载在/mnt/floppy文件下,所以我们可以用下面的命令:
:set viminfo=\'1000,f1,r/mnt/floppy
\\\"选项用来控制每一个寄存器可以保存多少行.在默认的情况下,所有的行都会被保存.如果是0就不会保存.一般情况默认的设置已经可以很好的来满足我们的要求了,所以我们可以不必加入我们自己的设置.
:选项可以用来控制:历史行的记录.我想100应是可以满足我们的要求了吧:-):
:set viminfo=\'1000,f1,r/mnt/floppy,:100
/选项可以用来定义查找历史记录的大小,100也已是很充足的了:
:set viminfo=\'1000,f1,r/mnt/floppy,:100,/100
(注:Vim不会保存那些超过他的记录能力的内容,这是在选项history中设置的)
通常,当我们启动Vim以后如果我们已经设置了hlsearch选项,编辑器就会高亮显示上一次查找的内容.要关闭这个选项,我们可以viminfo的选项列表中加入h标记,或者是我们在Vim启动后执行命令:nohlsearch来关闭这个选项.
@选项用来控制输入历史记录的行数.输入历史会记住我们输入的所有内容.
如果我们设置了%选项,我们就可以保存缓冲区列表记录.如果我们没有在命令行指定一个文件来编辑,缓冲区列表就会被重新保存:
:set viminfo=\'1000,f1,r/mnt/floppy,:100,/100,%
!选项用保存全局变量,这些全局是名字全部为大写字母的变量:
:set viminfo=\'1000,f1,r/mnt/floppy,:100,/100,%,!
最后n选项用来指明viminfo的文件名.在UNIX系统中默认的为$HOME/.viminfo
我们可以将这些命令以及一些其他的初始化命令放在初始文件vimrc中.这样viminfo文件就会在Vim退出时自动保存,启动时来读取初始化.
如果我们要更清楚一些的来保存和读取这个文件,我们可以用下面的命令来以另外的文件名保存:
:wviminfo[file]
这样我们的这一些设置信息就会被写入这个文件中了.
我们可以用下面的命令来读取这个文件:
:rviminfo [file]
这样就会从这个文件中读入设置信息.如果这些信息与当前的设置有冲突,那么我们的这些设置信息就不再起作用了.我们可以用下面的命令来强制这些设置信息起作用:
:rviminfo![file]
有时我们会编辑一些文件中一行的宽度要超过屏幕的宽度.当行宽超过屏幕的宽度会发生什么事情呢?这时vim会将这一行进行回折以适应屏幕的宽度.如果我们设置了nowrap选项,则Vim会用单行来处理文件的第一行文本.这时超出屏幕的部分就会不再出现,从而从屏幕消失.
在默认的情况下,Vim并不会显示水平滚动条,我们可以用下面的命令来使得Gvim显示小平滚动条:
:set guioptions+=b
这样Gvim就可以水平滚动了.
当我们设置了nowrap选项后,命令^将光标移动当前行的第一个非空字符处.g^命令可以将光标移动到当前屏幕的第一个非空字符处.在执行这们执行这样的命令时如果在窗口的其他部分有文本,那么这一部分的文本将会被忽略.类似的一些命令如下:
命令 命令 含义
^ g^ 向左移动当前屏幕的第一个非空字符处
<Home> g<Home>
0 g0 向左移动当前屏幕的第一个字符处
<End> g<End>
$ g$ 向右移动当前屏幕的结尾处
gm 移动到屏幕的中间
命令count|可将光标移动屏幕中指定的列.
命令countzh可以向左移动屏幕,移动的量度为count个字符.而命令countzl与其相类似,只是这个命令是向右移动屏幕.
命令zH可以向左移动个屏幕,而命令zL可以向右移到半个屏幕.命令j或是<Down>可以下移一行.在这里我们要知道的就是如果我们设置了wrap选项,那么下移一行在屏幕上显示也许就会是几行,这时我们要清楚,此时的几行正是设置了nowrap时的一行.
当我们设置了wrap选项,一个很长的一行Vim就会折成几行显示在屏幕上,这时我们可以用命令gj或是g<Down>来下移屏幕屏幕中显示的一行,这时也许我们移动的并非是真正的一行.而命令gk或是g<Up>命令与其相类似.
在默认的情况下,Vim编辑时会折回很长的一行,这时他首先是尽可能多的在屏幕的第一行放置文本,如果这一行的文本超出了屏幕的范围,Vim就会将其打断,然后在屏幕中的下一行显示其余的部分.我们也可以通过下面的命令来并闭这个选项:
:set nowrap
这时一个很长的句子超出屏幕的部分就在从屏幕上消失.我们可以通过沿着这个句子来移动光标,这样屏幕就会进行水平滚动,我们就可以看到这一行的其余部分了.
当然了我们也可以来自定义我们自己的句子回折形式:
首先我们可以告诉Vim在合适的地方来打断一个句子.我们可以用下面的命令来实现:
:set linebreak
那么又如何来定义一个合适的地方呢?这个是由breakat选项中的字符来确定的.在默认的情况下这些默认的字符是^I!@*-+_;:,./?如果我们不希望在下划线_处打断句子,我们可以用下面的命令来将_从这个列表移除就可以了:
:set breakat-=_
在通常的情况下,如果一个句子被打断Vim是不会在句子的连接的地方显示任何内容的.我们可以通过设置showbreak选项来显示我们所希望显示的内容信息:
:set showbreak=\"->\"
我们最后要讨论的一个问题就当我们要在屏幕的结尾处打断一个句子我们应如何来做呢?这时我们可以用两个选择:一是我们可以不显示半行.这时Vim编辑器会在屏幕的底部来显示@以表时这是一个长句子,我们不能把他全部放在屏幕内.二是我们可以显示半行.
Vim默认的是采用第一种方法.如果我们要采用第二种方法我们可以用下面的命令来实现:
:set display=lastline
vi编辑器的学习使用(二十一)
我们在Vim编辑器的学习使用(五)中曾结讨论了一些基本的窗口使用命令.这些命令可以使得我们在不同的窗口内进行编辑工作,从而使得我们编辑多个文件成为可能.而在这里我们将会讨论一些更多的与窗口相关的命令操作.
当我们使用多个窗口进行文件编辑时,我们如何来进行窗口的切换操作呢?我们可以使用命令CTRL-Wj回到下一个窗口,而使用命令CTRL-Wk回到上一个窗口.我们还可以使用下面的命令来进行窗口的切换操作:
CTRL-Wt 切换到顶部的窗口
CTRL-Wb 切换到底部的窗口
CTRL-Wp 切换到我们进行切换操作以前我们所在的窗口
countCTRL-Ww 向下切换一个窗口.如果是在底部,则进行回环.如果指明了数字,则切换到 数字所指定的窗口.
countCTRL-WW 向下切换一个窗口,如果是在顶部,则进行回环,如果指蝗了数字,则切换到 数字所指定的窗口
我们在使用多个窗口进行文本编辑的时候,我们还可以进行窗口的移动,命令CTRL-Wr命令可以使得窗口向下进行循环移动.这个命令可以带一个数字作为参数,可以指明向下循环移动所执行的次数.与其相类似的命令是CTRL-WR命令,这个命令可以使得窗口向上循环移动.
命令CTRL-Wx可以使得我们将当前窗口与下一个窗口进行位置的对换.如果当前是一个底部,则没有下一个窗口,这时执行这个命令时是将当前窗口与上一个窗口进行位置对换.
当我们在用多窗口进行多文件的编辑时我们可以用命令对这些文件进行共同的操作.:write命令可以保存当前文件.我们可以用下面的命令来实现对所有已经修改过的文件,包括隐藏缓冲区中的文件,进行保存操作:
:wall
命令:quit可以退出当前文件.如果这是一个文件的最后一个窗口,那么这个文件将会被关闭.如果我们同时打开了多个窗口进文本的编辑,我们可以用下面的命令来退出所有的文件:
:qall
如果在这些文件中有文件进行了修改但是没有保存,在执行这个命令时会给出警告信息,这样我们就可以保存那些我们没有保存的修改了,但是如果我们想要放弃我们所做修改工作而强行退出我们可以用下面的命令:
:qall!
我们还可以将这个两个命令进行组合来实现对所有文件的保存退出的命令:
:wqall
命令CTRL-Wo可以使得当前窗口成为屏幕上的唯一的一个窗口,而其他的窗口全部关闭.系统会认为我们在其他的每一个窗口中都执行了命令:quit.
如果我们通过命令:args file-list指定了一个文件列表或是在启动vim时指定了一个文件列表,那么:all命令就会为每一个文件打开一个窗口,这样我们就可以进行多文件的编辑工作了.
下面的命令由命令:all变化而来的,这个命令可以每一个隐藏的缓冲区打开一个窗口:
:unhide
这个命令还可以带一个参数,用来指明一次打开的窗口数.例如如果我们要打开所有的缓冲区但是在屏幕上显示不超过5个窗口,我们可以用下面的命令:
:unhide 5
我们还可以用CTRL-W CTRL-^命令来分裂窗口来编辑交替文件.这个命令是新打开一窗口,并在这个窗口中装入交替文本并进编辑.而命令CTRL-^则是通过切换窗口来编辑交替文件.
命令CTRL-W CTRL-I会分裂当前窗口,然在查找当前光标下的单词第一次出现的地方.这样的查找不不仅是在当前文件中查找,也会在由#include所包含进来的文件中进行查找.
在Vim中还有许多缩写的命令可以来快的完成工作,如下面的一些命令:
:countsnext :split与:countnext的组合
:countsprevious :split与:countprevious的组合
:countsNext :split与:countNext的组合
:srewind :split与:rewind的组合
:slast :split与:last的组合
:sargument :split与:argument的组合
CTRL-WCTRL-D :split与]CTRL-D的组合
CTRL-Wf :split与:find的组合
CTRL-Wg] :split与CTRL-]的组合
在这些命令一个算是优点的地方就是如果命令执行失败那么是不会打开一个新的窗口的.
我们在用Vim编辑器进行文件编辑的时候可以用不同的缓冲区装入不同的文件,我们可以在启动Vim时指定要编辑的文件列表,我们也可以在编辑的过程中用下面的命令新增一个缓冲区:
:badd filename
这样这个指定的文件就会被加到缓冲区的列表中.这个文件的编辑过程只有我们切换到那个缓冲区时才会开始.这个命令还可以带参数,来指明当我们为这个缓冲区打开窗口时,光标所处的位置:
:badd +lnum filename
我们可以用下面的命令来删除一个缓冲区:
:bdelete filename
或者是也可以用下面的命令:
:bdelete 3
:3 bdelete
我们还可以用下面的命令来删除指定范围的缓冲区:
:1,3 bdelete
如果我们使用了!选项,那么我们在缓冲区所有的所有的改动都会被放弃:
:bdelete! filename
命令:bunload会卸载一个缓冲区,这样这个缓冲区就会从内存中卸载,所有为这个缓冲区打开的窗口也会关闭.但是这个文件名文件名仍然会存在于这个缓冲区列表中.:bunload命令与:bdelete命令的用法相类似.
我们可以用下面的命令来为每一个缓冲区打开一个窗口:
:ball
我们可以用laststatus选项来控制最后一个窗口是否显示状态行,这个选项的值如下:
0 最后一个窗口从不显示状态行
1
如果在屏幕上只有一个窗口,那么不显示状态行.如果有两个或更多个,则要在最后一个窗口显示状态行.
2 在窗口上总是显示状态行,哪怕屏幕中只有一个窗口.
我们可以用winheight选项来控制一个窗口最小的行数.但是这个并没有一个硬性的限制,如果窗口显得太拥挤了,Vim会减少窗口的尺寸.
当我们打开equalalways选项后,Vim会以相同的尺寸来分裂窗口,而这也正是Vim编辑器默认的情况,但是如果我们设置了noeqaulalways选项后我们就可以用不同的尺寸来分裂一个窗口.
winheight选项用来控制当前窗口的最小高度.而winminheight选项则用来控制其他窗口显示的高度.
在通常的情况下,:split命令是在当前窗口的上方打开一个新窗口.而splitbelow选项可以使得Vim在当前窗口的下方打开一新窗口.
假如我们正在编辑一个很长的文件,而现在天已经晚了,我们想着退出工作并在第二天接着做.这时我们可以将我们正在编辑的文件信息存成一个文件,在我们要第二天要接着编辑这个文件时只要读入这个文件就可以了.这样的一个文件包含了所有我们正在编辑的文件信息,例如文件列表,窗口,标记,寄存器以及其他的一些信息等等.
我们可以用下面的命令来产生一个程序文件:
:mksession filename
例如我们存储的文件是:
:mksession vimbook.vim
如果我们要接着工作,想要装入这个程序文件时只要用下面的命令:
:source vimbook.vim
我们也可以在启动Vim时指明要读入的程序信息文件:
$ vim -c \":source vimbook.vim\"
我们可以使用sessionoption选项来控制我们在这样的文件存入什么样的内容.他是由逗号分开的一系列的关键的字符串组成的.例如默认的设置是这样的:
:set sessionoptions=buffers,winsize,options,help,blank
可能的关键字的值如下:
buffers 保存所有的缓冲区.包括在屏幕上显示的以及隐藏的和卸载的缓冲区.
globals 保存全局变量.这些全局变量是由大写和至少一个小写字母组成的.
help 帮助窗口
blank 屏幕上的空窗口
options 所有的选项和键盘映射
winpos GUI窗口的位置
resize 屏幕的尺寸
winsize 窗口的尺寸
slash 在文件名中用斜线来代替空格.
unix 用UNIX的行结尾格式来保存程序信息文件.\n\r\nvi编辑器的学习使用(二十二)
我们在Vi编辑器的学习使用(六)学习了基本的可视化模式,这时我们可以执行简单的可视化命令.在这里我们将会讨论更多的与可视化相关的命令.这些命令中的许多只有很少的观众,如果我们可以看这一次的学习,也许这很少的观众中就会包括我们.
我们在Vi编辑器的学习使用(四)知道了如何来用寄存器实现复制,粘贴和删除的工作.我们也可以在可视化模式中来实现这些操作.例如要删除一个文本我们可以这样的来做:在可视化模式中高亮显示这些文本,然后执行d命令.如果要将这些文本删除后放入寄存器中,我们可以用下面的命令来实现:\"register d.要复制文本到寄存器中我们可以使用y命令.而D和Y命令与其相对应的小写字母的命令相类似,只是他们作用在一整行,而d和y命令是作用于高亮显示的部分.
在块可视化模式中,$命令可以使得选中的文本扩展到所有的选中行的结尾处.当我们上下移动光标时,可以使得选中的文本扩展到这一行的结尾处.如果新行要比当前行长得多,这样的扩展也是会发生的.
gv命令可以重复前一次可视化模式时选中的文本.如果我们已经在可视化模式状态下,执行这个命令时会选中前一次选中的文本.如果我们重复执gv命令,就会在当前选中的文本和前一次选中的文本之间进行切换.
在Vim编辑器的可视化模式下的许多命令都是用来帮助我们高亮显示我们想要的文本的.例如命令aw高亮显示下一个单词.事实他不仅高亮显示这个单词,而且也包括这个单词后的空格.在一开始也许我们会认为这个命令没有太大的用处.因为w命令可以向前移动一个单词,我们为什么不用这个命令呢?
这是因为当我们执行选择文本的操作时,选中的是从老的光标所在处到新的光标所在处之间的文本.当我们使用命令w来移动文本时,结果是光标置于下一个单词的第一个字符上.如果这时我们要执行删除操作,我们命令的执行是不仅删掉了我们要删掉的单词,也同时删除了下一个单词的第一个字符.
而aw命令是将光标放在下一个单词的第一个字符的前面.换句话说,我们选中的是下一个单词前面的单词以及空格,而不是选中的下一个单词.
而另外一个使用aw命令而不使用w命令的原因就是不论光标置于一个单词的哪一个字符上,aw命令都可以选中整个单词,而w命令只是选中当前光标处和这个单词结尾之间的字符.
如果我们仅仅是想选中一个单词我们可以使用iw命令.
我们还可以使用下面的命令来选择文本:
countaw 选中一个单词以及其后的空格.
countiw 仅仅是选中一个单词.
countaW 选中一个WORD以及其后的空格.
countiW 仅仅是选中一个WORD
countas 选中一个句子以及其后的空格.
countis 仅仅选中一个句子.
countap 选中一个段落以及后面的空格.
countip 仅仅是选中一个段落.
counta( 在括号所包括的文本内,选择直到括号的文本并包括括号.
counti( 与上面的命令相类似,只是不包括括号.
counta< 选择<>内的文本,包括<>
counti< 选择<>内的文本,不包括<>
counta[ 选择[]内的文本,包括[]
counti[ 选择[]内的文本,不包括[]
counta{ 选择{}内的文本,包括{}
counti{ 选择{}内的文本,不包括{}
在可视化模式下,当我们选中一些文本以后,我们可以用命令o来使用光标移动选中的文本的另一个结尾处.然后我们可能再次执行o命令,来使得光标移动选中文本的另一个结尾处,也就我们来的地方.
而O命令可以在块可视化模式下将光标移动选中文本的另一角.换句话说,O命令是将光标移动选中文本中的同一行的结尾处.
在可视化模式下选中的文本,我们可以用命令~来实现大小写的转换.而U命令是使得选中的文本变成大写的形式,而u命令是将选中的文本变为小写的形式.
我们可以在可视化模式下选中文本,然后用命令J将这些选中的行合并为一行,并用空格来分隔这些行.如果我们希望在合并以并没有空格来分隔,我们可以用命令gJ.
我们可以用命令gq来格式化可视化模式下选中的文本.
我们还可以用g?命令来加密高亮显示的文本,在这个命令中我们采用的是Vim中所采用的rot 13加密算法.如果我们对同一个文本进行两次加密操作,就相当我们进行了解密操作.
在可视化模式下我们还可以用命令:来对指定的范围进行命令行操作.例如我们要将文本块写入一个文件我们可以这样的来做:
在可视化模式下选中我们要写入文件的文本,然后执行下面的命令:
:write block.txt
这样就可以将指定的文本块写入文件了.
命令!是使用外部的命令来对我们所要编辑的文件中的文本进行操作.例如我们可以使用!sort来使用UNIX下的sort程序进行文本的排序.我们可以这样的来做:
在可视化模式下选中我们要进行操作的文本,然后执行下面的命令:
:!sort
这样就可以对这些我们选中的文本进行排序操作了.
选择模式是另一种的可视化模式,他可以允许我们对选中的文本进行的快速的删除作替换的操作.我们使用选择模式也是很简单的操作.我们可以高亮显示文本,然后用<BS>来删除这段文本.我们也可以高亮显示文本,然后用我们所输入的内容来替换这些文本.
那么选择模式和可视化模式相比较又如何呢?在可视化模式下,我们可以高亮显示我们选中的文本,然后执行命令操作.换句话我们要用命令来结束可视化模式.而在选择模式下,命令仅限于<BS>(用于操作删除操作)和可打印的字符(用于替换操作).这样就会使得我们的操作变得更为简单,因为我们不需要来输入命令了,然而与可视化模式相比较他也有着太多的限制.
我们可以用下面命令来开始一种选择模式:
gh 进入字符选择模式
gH 进入行选择模式
gCTRL-H 进入块选择模式
在选择模式下移动光标比在正常模式下要显得困难一些.因为如果我们输入任何的可打印字符,Vim就会删掉我们选中的文本并进插入状态开始我们的输入.所以要选择文本我们只好使用小方向键,CTRL以及功能键.
如果我们进行了如下的设置我们还可以用鼠标来选择文本:
:set selectmode=mouse
(注:如果没有设置这个选项,可以在可视模式下执行鼠标操作而不可以在选择模式下执行鼠标操作)
在选择模式下,我们可以用命令<BS>或是CTRL-H来删除我们选中的文本.如果我们输入可打印的字符Vim编辑就会删除我们选中的文本然后进入插入模式.
我们可以用命令CTRL-O来从选择模式切换到可视化模式.如果我们要可视化模式和选择模式中进行切换,我们可以使用CTRL-G命令.
在通常情况下,当我们选择文本后,这些文本仍会保持选中的状态.有时即使是我们在执行了命令以后,这些文本仍然保持选中的状态.gV命令可以选得选中的文本在命令执行过后消失选中状态.这个在我们使用宏时显得更为有用.我们用他来一些工作,工作完成以后,我们就希望他能消失.\n\r\nvi编辑器的学习使用(二十三))
Vim编辑器由一群需要一个好的文本编辑器的程序员们所写出来的.正因为是这样,Vim中包含了许多的命令,我们可以用这些命令来自定义并且使我们的程序编辑工作变得更为简单.
例如如果我们现在正在编辑我们的程序文件.我们设置了autoindent选项,并且现在正处在第三层次的缩进上.而现在我们要加入一个注释块.这是一个很大的注释块,我们希望能将这个注释块放在文本的第一列.这时我们就需要禁止所有的自动缩进形式.为了这样的目的,一种方法是可以输入几次CTRL-D命令,或者是使用0CTRL-D命令.
命令0CTRL-D是在插入模式下移除所有的自动缩进的设置,并将光标放在第一列(在这里我们要注意的,当我们输入0时,我们所输入的0会显示在屏幕上,这时Vim会认为我们要在文本中插入一个0,然后我们执行命令CTRL-D,这时Vim就会意识到我们要做的是执行命令0CTRL-D,并且这时0会就会从屏幕上消失.
当我们使用0CTRL-D命令以后,光标会回到第一列,而且下一行也是从第一列开始的.
然后如果我们正在输入一个标签或是我们要输入#ifdef时我们只需要一行中的光标移动第一列就可以了.这时我们可以使用命令^CTRL-D.这个命令只会将当前行的光标放在第一列.当我们开始下一行时,这种缩进形式又会自动的执行.
CTRL-T命令与<Tab>命令相类似,只是前者在文本中插入一个缩进,而这个缩进的大小由shiftwidth选项来控制的.如果我们设置了shiftwidth选项的值为4,我们输入<Tab>,光标会移动以后第八列处,这是因为<Tab>缩进的大小是由tabstop选项来控制的,而在默认的情况下这个值为8.但是如果我们输入了CTRL-T命令就会将光标移动以后的第四列处.这两个命令在一行的任何一点都是可以正常工作的.所以我们可以输入一些文本然后执行CTRL-T命令将其缩进,然后用CTRL-D来取消这样的缩进形式.
在通常的情况下当我们用命令CTRL-R来插入寄存器中的内容时,这些内容是自动缩进的.如果我们不希望这样的事情发生,我们可以用CTRL-RCTRL-Orgister命令.或者是如果我们要插入寄存器中的内容,并希望Vim编辑能正确的完成我们的要求我们可以用下面的命令CTRL-R CTRL-P register.这样的命令在我们的程序文件中进行剪切和复制时显得尤为有用,因为在这时的程序文件中一般是设置了自动缩进选项的,而如果我们剪切或是复制后再粘贴时就会用两次的缩进操作,而这不是我们所希望的,这时我们就要用这些命令了.
在通常的情况下,命令\"registerp命令是将指定寄存器中的文本插入到缓冲区中,而命令\"register]p命令与此相类似的,所不同的是这个命令在插入时会有自动缩进的设置.而与此相类似的是命令\"register]P与\"registerP.
在计算机产生以前的时代,存在着一个交流的工具被叫作打印机.打印机的一些模块可以执行tabs.但是很不幸的是这些tab的大小被设置成为八个空格.而在计算机产后以后,他的第一个终端就是打印机.后来有一些更为现代的设备代替了打印机,但是古老的八个空格大小的tab被保留了下来,以保持与以前的相兼容.
但是这样的设计为我们以后的程序设计工作带来无尽的麻烦.因为有研究可以显示最易读的程序是四个字符的缩进,而Tab是八个字符的缩进.我们如何来调合这样的事实.人们想出了许多解决的办法,如下:
1 在我们输入代码时结合使用空格和Tab.如果我们需要12个字符的缩进,我们可以使用一个Tab和四个空格.
2 告诉机器将Tab设为四个字符的大小,然后在任何的地方使用Tab.
3 放开我们的双手并且认为Tab是一个工作的魔鬼,而且我们总是使用空格.
幸运的是Vim编辑器支持以上的三种方法.
如果我们使用空格和Tab的组合,我们可以像正常一样的进行编辑.在默认的Vim设置情况下就可以很好的来工作.
但是我们可以通过设置softtabstop选项的值的来使我们的工作变得再简单一些.这个选项告诉Vim编辑使得Tab键看上去和感觉上是使用softtabstop选项贩值,但是实际上我们是使用Tab和空格的结合在做事情.
例如我们可以用下面的命令来使得以后每一次我们在按下Tab键时光标位于以后的第四列处::set softtabstop=4
当我们第一次按下Tab时,Vim会在文本中插入四个空格.当我们第二次按下Tab键时,Vim就会去掉刚才的四个空格,然后在文本中插入一个Tab.也就是说当有八个空格相当于一个Tab时,Vim就会用一个Tab来代替这八个空格.
另一个相关的选项就是smarttab选项.我们可以用下面的合谋来设置这个选项:
:set smarttab
当我们设置了这个选项以后,插入一行开头的Tab就会被看作是软Tab.在这种情况下,Tab的大小所使用的值就是shiftwidth选项所设定的值.但是在其他的地方插入的Tab就会像是正常的Tab一样的.在这里我们要注意的就是当我们要让这个选项来正常工作时,一定要使软Tab关掉(:set softtabstop=0).
精巧缩进(smart indent)是软Tab和正常Tab的组合.当我们执行下面的命令,Vim编辑器就会区别对待一行开头的Tab:
:set smarttab
例如如果我们有下面的设置:
:set shiftwidth=4
:set tabstop=8
:set smarttab
在这些设置中我们是设置Tab是八个空格而缩进是四个空格.当我们在一行的开始输入Tab时,光标就会移动一个缩进的大小,也就是四个空格.当我们输入两个Tab时,光标就会移动两个缩进的大小,也就是八个空格.
下面的内容则显示出了我们在一行的开始输入特定的内容时的显示:
<Tab> 四个空格
<Tab><Tab> 一个Tab
<Tab><Tab><Tab> 一个Tab,四个空格
<Tab><Tab><Tab><Tab> 两个Tab
但是当我们在一行的其他地方输入Tab时,就会显得像正常的一样.
我们可以用下面的命令来设置一个Tab为四个空格:
:set tabstop=4
事实上我们可以用这个命令来将Tab设置成任何我们想要的值.
如果我们在我们的文件中含有Tab字符,我们可以通过设置expandtab选项来控制.当我们设置了这个选项,一个Tab键就会插入一系列的空格.在这里我们要知道的就是expandtab选项并不会影响文章中的其他的Tab键值.换句说文档中的Tab值仍然会保持.如果我们要将Tab转换为空格,我们可以使用:retab命令.
我们可以使用:retab命令来实现在文章中不同Tab设置之间的转换.我们可以用这个命令来使得文章中一系列的空格转换为Tab,或者是将一个Tab转换为一系列的空格.例如现在我们有一个文件使用是四个空格的Tab设置.但是这并不是标准的设置,而我们希望将他转换为八个空格的设置.我们希望这两个文件看起来是一样的,只是Tab的值不同.我们可以按照下面的方法来做:
:set tabstop=4
:%retab 8
这样以后我们的文件看起来就像是没有做过修改一样的,因为Vim将空白符与tabstop的新值相匹配.
再比如我们需要一个没有Tab的文件.首先我们执行命令设置expandtab选项.这样就会使得我们输入的新文本中的Tab成为空格.但是老文本中的Tab依然存在.要将这些Tab转换为空格,我们可以用下面的命令:
:%retab
因为我们没有指定一个新的Tab值,Vim就会使用现在的tabstop的值.但是因为我们又设置了expandtab这个选项,所以所有的Tab就会用空格来代替.
在这些Tab设置中存在的问题就是会有不同的人用不同的习惯来使用Vim处理文件.所以说如果我们可以很好的处理三种不同类型的人写的文件,我们就可能容易的确处理各种不同的Tab设置.这个问题的一个解决办法就是我们在写文件的时候在文件的开头或是文件的结尾下加上一个注释块,在其中标出我们所使用的Tab设置.例如:
/*vim:tabstop=8:expandtab:shiftwidth=8*/
当我们知道这些以后我们可以建立我们自己所喜欢的格式.但是Vim是一个精巧的编辑器,他可以理解类似这样的注释并且为我们配置这些设置.但是有一点是要严格执行,那就是注释必须是这种形式的,而且是必须是在一个程序文件的前五行或是后五行才可以.这种类型的注释就叫做模式行(modeline).
假如我们设置了shiftwidth的值为四,而我们在一行的开始输入了三个空格.那么当我们执行命令>>时会是什么样呢?会在前面插入四个空格的缩进还是移动到最近的一个缩进处呢?答案取决于我们所设置的shiftround选项的值.
以通常的情况下,这个选项是没有设置的,所以会新增四个空格的缩进.但是如果我们执行了下面的命令,那么光标就会移动到最近的一个缩进处:
:set shiftround
当我们执行命令=时我们可以使用通过equalprg选项所指定的程序来进行文件的格式化工作.如果没有设置这个选项或者是我们没有编辑一个Lisp程序,那么Vim就会使用他自己的缩进程序来缩进C或者是C++的程序文件.如果我们想要使用GNU的缩进程序我们可以执行下面的命令:
:set euqalprg=/usr/local/bin/indent
我们还可以要求Vim来格式化注释而且他可以很好的来完成我们的要求:
例如我们有下面的一段注释:
/*
*This is a test.
*Of the text formatting.
*/
我们可以通过下面的命令来格式化这段注释:
1 将光标放在这段注释开始的地方.
2 用命令v进入可视化模式.
3 将光标移动到这段注释的结尾处.
4 用命令gq来格式化这段注释.
结果如下:
/*
*This is a test.Of the text formatting.
*/
(没有达到预期的效果,想来应处理程序文件中才有用)
我们可以通过comments选项来定义哪些是注释而哪些不是.我们还可以用命令gq{motion}来完成注释的格式化工作.
我们可以使用comments选项来定义哪些文本是注释而哪些文本不是注释.这个选项由成对出现的标记:字符串格式组成(flag:string).
可以使用的标记(flags)如下:
b
后面必须跟上空格.这就是说如果一个字符后面跟上空格或是其他的空白符,那么这个字符开始了一个注释.
f 只有第一行有注释字符串.在下一行不要重复这个字符串,但是要保持缩进格式
l
当使用在三段注释的情况下,必须保证中间一行要与注释的开始和结束相对应.而且必须使用s或是e标记.
n 指明了嵌套注释
r 与l相类似,所不同的只是右对齐
x
告诉Vim在三段注释的情况下我们可以在下面的三种情况下仅输入最后一个字符就可以结束注注释:
1 我们已经在注释的开头输入了.
2 注释有中间部分.
3 结束字符串的第一个字符是这一行的第一个字符.
对于三段注释的情况,下面的一些标记适用:
s 开始三段注释
m 三段注释的中间部分
e 三段注释的结尾
number 在三段注释的中间部分的缩进中添加指定的空格
一个C程序的注释用/*开始,有中间部分*,以*/结尾.就像下面的一样:
/*
* This is a comment
*/
这样的注释结果是由comments选项所指定的:
sl:/*,mb:*,ex:*/
在这个设置中sl表明这是一个三段注释的起始处并且在这个命令中的其他行需要缩进一个额外的空格.这个注释是以/*开始的.
这个注释的中间部分是由mb:*来定义的.m表明了一个中间部分,而b则是说在我们输入的任何内容后必须有一个空格.这段文本以*开始注释.
注释的结束是以ex:*/来指定的.e表明注释的结束,而x则是表明了我们只需要输入结束标记的最后一个字符来完成注释.而结束的定界符是*/.
那么我们如何来使这样的定义工作呢?首先我们要设置下面的选项:
:set formatoptions=qro
下面的一些选项在我们要格式化文本时会显得更为有用:
q 允许使用gq来格式化化注释
r 在我们输入回车后自动的加入注释的中间部分
o 我们用o或是O命令来开始一个注释行时自动的添加注释行的中间部分
下面让我们看一下这样的设置会如何的工作:
我们要开始一段注释,我们在这一行输入注释的开始标记/*,然后我们打下回车,因为在格式选项中我们设置了r,所以在下一行中会自动的添加注释的中间部分并且会在后面添加一个空格.当我们在再输入回来也会出现同样的情况,但是这时我们要结束我们的注释输入了,我们就如何结束呢?Vim是一个精巧的编辑器,当我们在这种情况下只输入/时,光标就会向后移动一格插入/,这样就正确的结束我们的注释输入了.结果如下:
/*
* This is a test
*/
我们还可以使用各种不同的格式命令来格式化文本或是注释.
C程序文件的缩进过程是由下面的一些选项来控制的:
cinkeys 定义了引发缩进事件的关键字
cinoptions 定义了如何缩进
cinwords 定义了C和C++的关键字
cinkeys选项定义了哪些字符会引起缩进的变化.这个选项事实上是一对输入字符和关键字字符的组合(type-chars key-chars).
输入字符如下:
! 他后面的字符不会被插入.这在我们要定义一个字符来格式化一行使之重新缩进时会显得更为有用.在默认的情况下,CTRL-F就被定义为重新缩进.
* 这一行会在这个字符输入之前进行重新缩进.
0 如果这是一行中第一个输入的字符就会影响这一行的缩进发生变化.(这并不是说他是这一行的第一个字符,因为这一行会进行自动缩进.他只是指第一个输入的字符)
关键字符如下:
^X 控制字符CTRL-X
o 告诉Vim在我们用命令o开始一个新行时要缩进该行.
O 与o相同
e 当我们输入最后一个else中的e时重新缩进此行.
: 当我们在一个标签或是事件的描述后输入:时会重新缩进此行.
<^>,<<>,<>>,<o>,<e>,<O> 在尖括号中的精确的字符
而cinkeys选项默认的值如下:
0{,0},:,0#,!^F,o,O,e
cinoptions选项来控制每一行缩进的大小.这个选项是由一系列的关键字和缩进(key indent)所组成的.这里子关键字是一个单一的字符,用来指明影响程序的哪一部分.而缩进(indent)则是告诉程序要用多大的缩进.这个缩进可以是几个空格(如8个),或者是负数量的空格(如-8个).还可以是由s所指定的shiftwidth选项值的倍数.例如1s是指一个shiftwidth,而0.5s是指半个shiftwidth,而-1s则没有缩进一个shiftwidth.
关键字 默认 描述
> s 没有被其他字符所覆盖,正常缩进.
e 0 以花括号为结束标记的行后面的行的额外缩进.
n 0 在if,while后的没有在花括号内的单一行的额外缩进.
f 0 添加到函数体的额外缩进.包括定义函数的{}.
{ 0 添加到开始{的空格
} 0 添加到结束}的空格
^ 0 添加到开始于第一列的{}内的文本的空格.
: s 在switch语句中的自动缩进
= s 在case语句后的额外缩进
g s 对于C++中的保护关键字(public,private,protected)的缩进
h s 保护关键字语句后的语句的缩进
p s K&R风格的缩进
t s 在单一行进行函数类型声明的缩进
+ s 连续行的缩进
c 3 多行注释中间部分的缩进(如果没有指定*)
( 2s 表达式中间部分一行的缩进,事实上是指一对括号内部的缩进.
u 2s 嵌套括号内的一行的缩进,与(相类似,只是这个要更深一层.
) 20 指定用来查找一对闭括号()的行数.
* 30 指定用来查找没有结束的注释的行数
选项cinwords用来定义哪一些单词可以使得下一个C语句在精巧缩进(smartindent mode)模式下和在C缩进模式下(Cindent mode)缩进一个层次.默认的选项值如下:
:set cinwords=if,else,while,do,for,switch
假如我们要用尽量少的编辑动作来比较两个文件的不同,那么我们要怎么样的来做呢?这时我们可以打开两个窗口,分别在两个窗口中进行编辑.然后我们在每一个窗口中执行下面的命令:
:set scrollbind
这样以后如果有一个窗口发生滚动,那么另一个窗口也就会有相同的动作.
就你是我们要在两个文件窗口中进行动作一样,也许有的时候我们会需要移动一个窗口而不要移动另一个窗口,这时我们可以我们要移动的窗口内执行下面的命令就可了:
:set noscrollbind
如果我们要同步滚动,我们可以执行下面的命令:
:set scrollbind
选项scrollopt可以用来控制scrollbind如何的来工作.我们可以将其设为如下的值:
ver 垂直同步滚动
hor 水平同步滚动
jump 当我们在两个窗口中进行切换时,一定要使用偏移(offset)为0
最后如果我们要使两个窗口同步,我们可以使用下面的命令:
:syncbind
假如我们正在看一个文件的两个版本,我们需要在这两个文件中进行滚动查看.也许我们为了查看一些东西而关掉了scrollbind.这样这两个文件就会停在不同的地方.而我们还希望他们可以再一次同步滚动.这时我们可以分别到这两个文件所在的窗口然后将他们移动相同的地方.而事实上我们可以叫Vim来完这样的工作.在这样的情况下,我们可以分别在两个文件中设置scrollbind,然后执行下面的命令:
:syncbind
这样Vim就使得两个文件同步了.
假如我们正在看一个程序文件,但是却碰到一个我们并不理解的函数调用.我们可以用命令CTRL-]跳转到函数定义的地方.但是这样做却有一个问题,那就当前的文件被函数定义的内容所替代,我们也就不可以从屏幕上看到这个文件的内容了.
这个问题的一个解决办法就是我们使用被称为preview的特殊窗口.我们可以通过执行下面的命令来打开preview的特殊窗口,在这个窗口中显示函数定义的内容:
:ptag function
如果我们已经打开了一个preview窗口,那么他就会切换到当前正在查看的函数定义内容.如果我们要关闭这个窗口,我们可以执行下面的命令:
:pclose
命令CTRL-Wz和ZZ也可以有关闭这个窗口的作用.
在preview窗口中我们执行下面的命令来完成我们的工作:
:ppop 在这个窗口中执行一个:pop命令.
:ptselect identifier 打开一个新的preview窗口并执行:tselect命令
:ptjump identifier 打开一个新的preview窗口并执行:ptjump 命令
:count ptnext 在这个窗口中执行:count tnext命令
:count ptprevious 在这个窗口中执行:count ptprevious命令
:count ptrewind 在这个窗口中执行:count ptrewind命令
:ptlast 在这个窗口中执行:ptlast命令.
CTRL-W} 以当前光标下的内容执行一个:ptag命令
CTRL-Wg} 以当前光标下的内容执行一个:ptjump命令
matchpairs选项可以用来控制哪些字符可以用%命令来进行匹配.这个选项默认的值如下:
:set matchpairs=(:),{:},[:]
这就告诉Vim要匹配(),{},[]
匹配<>,我们可以用下面的命令:
:set matchpairs=<:>
这个命令在我们要编写HTML文件时会显得更为有用.
这个命令仅仅是匹配<>.如果我们要同时匹配其他的字符,我们可以用下面的命令:
:set matchpairs=(:),{:},[:],<:>
这样的命令显得似乎是有一些太长了,我们可以用+=命令来达到同样的目的.例如上面的命令我们可以用下面的命令来作到:
:set matchpairs+=<:>
如果我们希望我们在输入括号时,光标会跳转到与其匹配的地方进行显示,我们可以执行下面的命令来做到:
:set showmatch
通常情况下这个跳转持续的时间为0.5秒(半秒),我们可以用matchtime选项来控制这个时间.例如如果我们希望这个时间持续1.5秒,我们可以用下面的命令:
:set matchtime=15
在这里是以0.1秒为单位的.
我们在Vim编辑器还可以用命令来查找未匹配的括号.如[{查找前一个未匹配的{,]{查找后一个未匹配的{.[}查找前一个未匹配的},而]}查找后一个未匹配的}.
])查找后一个未匹配的),而[(查找前一个未匹配的(.[#查找前一个未匹配的#if或者是#else.而]#查找后一个未匹配的同类情况.
下面的命令可以移动一个Java方法的开头或结尾:
[m 向后查找一个方法的开头
[M 向后查找一个方法的结尾
]m 向前查找一个方法的开头
]M 向前查找一个方法的结尾
在Vim编辑器还提供了许多的移动命令来帮助程序人员在他们的程序文件中进行浏览.下面的一些命令可以找到位于第一列的{和}:
count[[ 向后查找位于第一列的前一个{
count[] 向后查找位于第一列的前一个}
count]] 向前查找位于第一列的后一个{
count][ 向前查找位于第一列的后一个}
命令[/和[*可向后移动他可以找到的第一个C注释的开始处,而]/和]*可以向前移动他可以找到下一个C注释的结束处.
随着一个程序文件变得越来越大,我们会将这个程序文件分在不同的目录中,这样就会大大的方便我们的管理.让我们来看一下一个小的工作,我们有一个包含有main.c和main.h的主目录,其余的目录就是含有lib.c和lib.h的lib目录(库文件).
我们从主目录中开始我们的编辑工作.第一件事就是告诉Vim关于是我们的新目录的情况.我们可以用:set ^=将这个目录放在查找路径的上部:
:set ^=../lib
假如我们正在编辑文件main.c,而这个文件的内容类似于下面的:
#include \"main.h\"
#include \"lib.h\"\n\r\nint main(int argc,char*argv[])
现在我们要查看一下lib.h中一个子程序的声明.一个办法是我们可以执行下面的命令:
:vi ../lib/lib.h
这个命令是假定我们知道lib.h的位置所在.但是在这里我们会有一个更好的方法.首先我们将光标放在下面一行中的文件名上:
#include \"lib.h\"
然后我们执行命令gf.这就告诉Vim编辑试着编辑以光标下的内容为文件名的文件.编辑器就会在path(路径)变量的每一个目录中进行查找.
假如我们要编辑文件lib.c,而这个文件名并没有出现在现在的文本内容,我们就没有办法来用gf命令,这时我们可以用下面的命令:
:find lib.c
这个命令类似于:vi命令,所不同的只是他要在路径中进行查找.下面的命令与其相类似,只是他是分裂当前窗口进行查找:
:sfind lib.c
gf命令与:find命令相类似,只是这个命令认为当前光标下的内容是我们要编辑的文件.如果在path中有不只一个文件与指定的文件相匹配,这时我们可以通过给定gf命令一个参数来选择我们要编辑的文件.
换句话说如果我们将光标放在param.h上然后执行命令2gf,Vim就会编辑通过path选项指定的路径目录中查找的文件列表中的第二个文件.
path选项用来告诉Vim在哪里查找被当前文件包含进来的文件,这个选项的格式如下:
:set path=directory,directory,...
在这里的directory是指我们要查找的目录,如:
:set path=/usr/include,/usr/X11R6/include
我们还可以在这个命令中使用通配符来进行匹配,如:
:set path=/usr/include,/usr/include/*
下面是一些特殊的目录:
** 匹配整个目录树,如:
:set path=/usr/include/**
这个命令查找目录/usr/include及其所有的子目录.下面的命令指定了在所有以/ho
me/oualline/progs开始以include结束的目录内的文件
:set path=/home/oualline/progs/**/include
\"\" 空字符串指当前目录
. 指我们正在编辑的文件所在的目录
例如下面的命令是告诉Vim查找的目录包括/usr/include及其所的子目录,我们正编辑的文件所在的目录(.)以及当前目录(,,):
:set path=/usr/include/**,.,,
如果我们想确定一下我们可以查找到所有的#include文件,我们可以使用下面的命令:
:checkpath
这个命令的作用范围不仅仅是我们正在编辑的#include目录,而且包括任何他们#include的目录,结果就是要查看所有的#include文件.
在这种情况下,有许多的文件要包含文件stddef.h和stdarg.h.但是Vim却不能找到这些文件.如果我们要告诉VimLinux特殊的include目录,我们要以执行下面的命令:
:set path+=/usr/include/linux
但是:checkpath命令只是列出所以不能找到的文件,如果我们要列出所以的#include文件,我们可以用下面的命令:
:checkpath!
Vim编辑器知道C和C++的宏定义.但是如果是其他的语言又会怎么样呢?选项define包含了一个长规的表达式,Vim编辑器可以通过他来查找一个定义.例如如果我们要使Vim查找以字符串function开头的宏,我们可以使用下面的命令:
:set define=function
选项include定义一个包含(include)的目录是什么样子的.这个选项可以用来为我们使用命令]CTRL-I,[CTRL-I,]d,[d在这些我们所包含进来的文件中进行查找.这个选项也可以为命令:checkpath所用.正如define选项一样,这个选项的值也是一个长规的表达式.
命令[i用来查找光标下的内容第一次出现的地方.注释的文本会被忽略掉.
命令]j用来查找光标下的内容下一次出现的地方.注释的文本会被忽略掉.
命令[I会列出所有包含当前光标下的内容的句子,命令]I与其相类似,只是这个命令是从当前光标处开始.
:make命令会产生一个错误列表.Vim编辑器会记住我们前10次:make命令和:grep命令的执行结果.如果我们要到前一次的错误列表,我们可以用下面的命令:
:colder
如果我们要到一个新的错误列表,我们可以用下面的命令:
:cnewer
当我们执行:make命令时所要执行的程序名称是由makeprg选项来定义的.在通常的情况下会设为make,但是Visual C++的用户可以通过下面的命令将其设为nmake:
:set makeprg=nmake
:make命令会重定向Make的输出到一个错误文件.这个文件的名字是由makeef选项来控制的.如果这个选项包含有字符##,字符##就会被专一的数字所代替.这个选项默认的值取决于我们正在使用的操作系统.默认的值如下:
Amiga t:vim##.Err
UNIX /tmp/vim##.err
Windows vim##.err
我们可以在命令中包含指定的Vim关键字.%字符可以扩展当前文件的名字,所以我们执行下面的命令:
:set makeprg=make\\%
然后我们执行命令:
:make
他就会执行下面的命令:
$ make file.c
file.c就是我们正在编辑的文件的名字.这个并没有太大的用处,所以我们可以重新定义这个命令并使用:r(root)的权限:
:set makeprg=make\\%:r.o
这样我们就会执行下面的命令:
$ make file.o
选项errorformat可以用来控制Vim如何来组织错误文件以使得他可以知道文件名以及错误发生的地方.这个选项的格式如下:
:set errorformat={string},{string},{string}
这里的字符是由特殊字符%所指出的典型的错误信息用来指明特殊的操作(与标准C函数scanf很相像).这些特殊的字符如下:
%f 文件名
%l 行号
%c 列号
%t 错误类型(单一字符)
%n 错误行号
%m 错误信息
%r 匹配一行中的剩余
%*{char}匹配并跳过由{char}所指定的scanf转换
%% 字符%
当我们在编译一个程序的时候,我们也许要在几个目录中进行遍历.GNU make程序会在当我们进入一个目录或是离开一个目录时打印出相应的信息.
如果要正确的得到文件名,Vim就要清楚的知道这些目录的变化.下面的一些错误格式用来在目录发生变化时告诉Vim一些相关的信息:
%D 当进入一个目录时打印出指定的信息.字符串的%f指明我们所进入的目录
%X 指定离开目录时的信息.字符串中的%f指明了make已用毕的目录.
一些编译器,例如GNU GCC编译器,会输入一些冗长的错误信息.如果我们正在使用默认的errorformat就会导致三种错误信息.这实在是够讨厌的.但是幸运的是Vim编辑器可以识别出不同的错误信息.处理不同信息的模式代码如下:
%A 开始多行信息
%E 开始多行错误信息
%W 开始多行警告信息
%C 连续多行信息
%Z 结束多行信息
%G 全局.只有在+或是-连接时才有用
%O 单行文件信息:重新读入匹配的部分
%P 单行文件信息:将%f文件压入栈
%Q 单行文件信息:将最后一个文件压出栈
+或是-可以放在任何字符的前面,从而组成下面的内容:
%-letter 不要包含输出中的匹配行
%+letter 包含%m错误字符串的整个匹配行
在通常的情况下,我们执行:make命令并有错误发生,Vim会在当前的窗口中显示错误文件.如果我们通过设置switchbuf选项来进行窗口的分裂,Vim就会在一个新的窗口来显示错误文件.:grep命令会运行由选项grepprg所指定的程序.这个选项包含了我们要用的命令行.#和%字符会扩展到当前文件名和交替文件名.而字符串$*将会被:grep命令的参数所代替.
在这里我们要注意的就是在UNIX系统上,grepprg默认是指grep -n.在Windows系统上,默认是指findstr/s
:grep命令使用grepformat选项来告诉Vim如何来组织Grep的输出文件.
在通常的情况下,Vim是使用二分法进行查找指定的标记名字.如果一个标记文件是按序排列的,这样的方法可以是很快速的.否则的话我们可以使用线性查找的方法.如果要强制进行线性查找,我们可以用下面的命令;
:set notagbsearch
这个选项会在我们的标记文件不是有序的时有用.
有一些系统会限制我们在函数名中所使用的字符数.如果我们要在Vim中加入这样的限制,我们可以通过设置taglength选项来限制我们函数名的最大长度.
我们可以用tags选项来指定标记文件名.这个可以用来指其他目录中的文件.如:
:set tags+=/home/oualline/tools/vim/tags
但是这会带来一些令人费解的地方.是我们在当前目录中启动并告诉ctags将标记文件放在目录/home/oualline/tools/vim还是我们在当前的目录执行了ctags呢?现在的Vim编辑器已经用其他的选项来解决了这个问题了.如果我们进行下面的设置,所有的标记都会和含有标记文件的目录有关系:
:set tagrelative
否则的话,他们会和当前目录有关系.
如果我们设置了tagstack选项,那么:tag命令和:tjump命令就会建立一个标记栈.否则是不会保持栈的.
Vim编辑器允许我们自定义用来进行语法高亮显示的颜色.Vim编辑器识别下面三种不同的终端:
term 平常的白色背景色,黑色前景色的终端(没有颜色)
cterm 彩色终端,例如xterm或者是Windows的DOS
gui Gvim所产生的窗口
要改变通常的终端的高亮显示的颜色,我们可以用下面的命令:
:highlight group-name term=attribute
这里的group-name是我们要高亮显示的语法组.这是我们要设置的语法匹配的规则用来告诉Vim程序中的哪一部分要进行高亮显示.而attribute是终端的属性.对于平常的终端如下:
bold underline reverse italic standout
我们可以用逗号来组合这些属性,如:
:highlight Keyword term=reverse,bold
假如我们有一个不是通常代码的终端.我们可以通过start和stop高亮显示的选项来定义我们自己的属性.这些定义一个用来发送的字符串来开始一个颜色和结束一个颜色.例如:
:highlight Keyword start=<Esc>X stop=<Esc>Y
有了这样的定义,当Vim要显示关键字时,例如显示if就会显示为<Esc>Xif<Esc>Y
如果我们对UNIX的终端定义的文件较为熟悉,我们可以使用终端代码.us定义了开始下划线的代码,而ue则是退出下划线模式的字符串.要指定这种高亮显示的方法,我们可执行下面的命令:
:highlight Keyword start=t_us stop=t_ue
颜色是由cterm的设置来定义的.我们可以使用cterm=attribute的方式来进行我们的设置.
但是对于一个彩色终端来说还有许多其他的选项.ctermfg=color-number可以用来设置前景色.ctermbg=color-number用来设置后景色.Vim可以识别出颜色的名称.例如下面的命令可以告诉Vim在显示注释时后景色为蓝色,而前景色为红色,并且有下划线:
:highlight Comment cterm=underline ctermfg=red ctermbg=blue
GUI终端可以使用选项gui=attribute的方式来在图形窗口下显示语法元素的属性.选项guifg和guibg定义了前景和后景的颜色.这些颜色是名称来进行区别的.如果名称中包含空格,那么这个颜色的名称就要用单引号括起来.为了事物的可移动性,Vim建议我们只使用以下的颜色:Black Blue Brown Cyan DarkBlue DarkCyan DarkGray DarkGreen DarkMagenta DarkRed Gray Green LightBlue LightCyan LightGray LightGreen LightMagenta LightRed LightYellow Magenta Orange Purple Red SeaGreen SlateBlue Violet White Yellow
我们可以使用X11的颜色数字来定义我们的颜色.这就可以在所有的系统上正确的显示,而不论是否使用X11系统.这种模式为#rrggbb,在这里rr是红色的数量,bb是蓝色的数量,gg是绿色的数量.
我们还可以在一个高亮显示行来定义几种终端的颜色,如:
:highlight Error term=reverse \\ cterm=blod ctermfg=7 ctermbg=1
语法元素是由$VIMRUNTIME/syntax中的宏来定义的.然而为了使得事情变得更为简单,我们常会用下面的一些名字:
Boolean Character Comment Conditional
Constant Debug Define Delimiter
Error Exception Float Function
Identifier Include Keyword Label
Macro Number Operator PreCondit
PreProc Repeat Special SpecialChar
Structure Tag Todo Type
Typedef
除了这些语法元素,Vim还定义了下面的许多事物:
Cursor 光标下的字符
Directory 目录名称以及其他列出的特殊名称
ErrorMsg 在最底行显示出的错误信息
IncSearch 增长(Incremental)查找的查找结果
ModeMsg 在左下角显示的模式名称
MoreMsg 当Vim在显示一个很长的信息并且要显示更多的信息时的提示
NonText
Vim编辑器会在超出文件结尾时显示~.我们可以用@来表明一行不会在显示一屏上.这些语法元素可以用来定义用哪些颜色来显示语法元素
Question 当Vim询问问题时.
SpecialKey 命令:map列出键盘的映射.这个选项定义了用特殊键来进行高亮显示
StatusLine 当前窗口的状态行.
StatusLineNC 其他窗口的状态行
Title 命令:set all,:autocmd的输出标题
Visual 这个颜色用来高亮显示可文本块
syntax选项包含有用于当有语法高亮显示的语言.我们可以用下面的命令来关闭语法显示:
:set syntax=off
如果想要打开,我们就用下面的命令:
:set syntax=on
vi编辑器的学习使用(二十四)
在这一次的学习中我们会介绍一些更多的关于缩写和键盘映射的问题.
我们在编辑的过程中可以用:abbreviate命令来设置一个缩写,那么我们如何来移除一个缩写呢?我们可以用命令:unabbreviate来移除一个缩写.例如我们用下面的命令来设置一个缩写:
:abbreviate @a fresh
如果我们要移除这个缩写我们可以用下面的命令:
:unabbreviate fresh
如果我们要清除所有的缩写,我们可以用下面的命令:
:abclear
我们用上面的命令定义的缩写可以正常的工作在插入模式和命令行模式两种状态下.如果我们是在文本中输入@a,他就会扩展为fresh,而如果我们在:命令行中输入@a,他也可以扩展成为fresh.如果我们要定义一个只工作在插模式下的缩写,我们可以用这样的命令:
:iabbreviate @a fresh
这也就是说如果我们在命令行输入@a,那么他仅是@a,而不会扩展为fresh.如果要取消一个插入模式的缩定义,我们可以用下面的命令:
:iunabbreviate @a
同样的我们可以用下面的命令来清除所有的插入模式的缩写定义:
:iabclear
相类似的,如果我们要定义一个只在命令行模式下工作的缩写,我们可以用命令:cabbreviate来完成,而取消这个定义的命令为:cunabbreviate,如果要清除所有的缩写列表,我们可以用下面的命令:
:cabclear
如果我们要列出所有的缩定,我们可以用下面的命令:
:abbreviate
在这个命令的执行结果第一列显示出缩写的类型,标记如下:
c 命令行模式
i 插入模式
! 两种模式均可
CTRL-C命令可以使得Vim离开插模式.这个命令与<Esc>命令的不同之处就在于在回到正常状态的过程中并不会检查一个缩写.
map命令可以使得我们将一定的模式与键盘对应起来.例如如果我们要使用F5来复制来选中的文本到寄存器v中,我们可以用下面的命令来定义:
:map <F5>\"vy
这样的定义的F5在正常以及可视模式下都可以使用.但是也许我们真正希望的是只在可视模式下来使用这个命令,这时我们可以用下面的命令来进行定义:
:vmap <F5>\"vy
这里的v是告诉Vim这样定义的命令是只在可视模式下使用.
如下面的列表:
Command Normal Visual Operator Pending Insert Command Line
命令 正常 可视 运算符延伸 插入 命令行
:map y y y
:nmap y
:vmap y
:omap y
:map! y y
:imap y
:cmap y
现在假如我们要定义<F7>以使得命令d<F7>可以删除C程序的文本块.与此相类似的,y<F7>可以将程序块复制到未命名寄存器中.所以我们要做就是要傅F7来选择当前的文本块.我们可以使用下面的命令:
:omap <F7>a{
这个命令会使得<F7>在operator-pending模式下选择文本块.有了这样的映射,当我们输入d<F7>命令中的d时,我们就进入了operator-pending模式.然后执行命令<F7>就可以地命令a{了,这样我就可以选择文本块了.因为我们执行了d命令,所以这个文本块被删除了.
其他的一些映射命令如下:
:map lhs rhs
这个是将lsh映射到rhs,所以当我们按下lhs时我们实际上执行的是rhs
如下面的映射命令:
:map ^A dd
:map ^B ^A
执行了这样的命令以后,当我们输入CTRL-A时Vim会删除一行.而CTRL-B也会是同样的作用.当我们使用控制字符时,我们必须用CTRL-V来引用他.换句话说如果我们要达到:map ^A dd的目的,我们就可以用下面的命令来完成:
:map CTRL-VCTRL-A dd
(似乎这个命令这样的做是不成的)
如果我们要重新映射,我们可以使用命令:noremap,例如:
:noremap lhs rhs
如果我们要取消一个映射,可以使用:unmap命令,如:
:unmap lhs
如果我们取消所有的映射,我们可以使用命令:
:mapclear
但是我们在使用这个命令时要注意,因为这个命令也会移除所有我们自定的默认映射.
如果我们要列出所有的映射,我们可以用下面的命令:
:map
第一列的标记指明了这样的映射可以在哪一种模式下工作:
字符 模式
<space> 正常,可视,运算符(operator-pending)
n 正常
v 可视
o operator-pending
! 插入和命令模式
i 插入模式
c 命令模式
第二列指出各种lhs的任何映射.第三列是rhs的映射值.如果rhs是以*开头的,那么这个rhs是不可以重新映射的.
:map命令可以列出所有的映射,而:map!只列出插入和命令行模式的映射.而:imap,:vmap,:omap,:nmap命令只是列出指定模式的映射.在默认的情况下,Vim允许循环映射,要关掉这个特征,可以执行下面的命令:
:set noremap
如果我们执行下面的命令:
:abbreviate @a ad
:imap ad adder
这样当我们输入@a时,字符ad会被插入,然而ad又映射到插入模式的字符串adder,所以字符串adder会被插入到文本中.如果我们使用用命令:noreabbrev就可以避免这样的问题.\n\r\nvi编辑器的学习使用(二十五)
虽然Vim编辑器在可视的情况下可以极好的完成我们的工作,但是有时我们是也需要使用命令行命令的.例如在脚本中命令行命令的使用会更容易,同时有许多特别的命令是只在命令模式下才可以实现的.
:delete命令可以删除一个范围内的文本行.例如我们要删除1到5行,我们可以用下面的命令来做:
:1,5 delete
:delete命令的一般格式如下:
:range delete register count
在这个命令中的register是我们的删除的文本要放入的寄存器.这个可以是我们用a-z命名的寄存器中的一个.如果我们使用大写的字符做为寄存器的名字,那么这些文本就会被添加到已经存在文本的寄存器中.如果没有指定这个参数,那么就会使用未命名的寄存器.而count则指出要删除的行数.range则是指明要使用的行.
我们还可以使用命令来删除含有指定字符串的行.如我们可以用下面的命令来删除从第一个包含字符串hello到第一个包含字符串goodbye的行之间所有的行:
:/hello/,/goodbye/ delete
在这里我们要注意的就是如果goodbye在hello之前出现,那么这个命令就不会正常的工作了.我们还可以使用偏移量(offset)来重新定义要查找的字符串.例如/hello/+1是指含有hello字符串行的下一行,因而我们还可以使用下面的命令来进行删除的操作:
:/beach/+1,/seashore/-1 delete
我们还可以使用下面的一些简写的运算符:
\\/ 向前查找上一次使用的模式
\\? 向后查找上一次使用的模式
\\& 向前查找上一次使用的子模式
(注:这个地方不懂,也不晓如何来用)
我们还可以使用链式的模式,例如下面的命令在找到字符串first以后要查找second字符串:
/first//second
所以我们还可以使用下面这样的删除命令:
:/hello//goodbye/ delete
我们还可以指定行号,用来指明在第几行进行查找,如果我们要从第七行开始查找,我们可以使用下面的命令:
7/first/
如果我们只是执行一个:命令,那么Vim编辑器就会进行命令行模式然后允许我们指定一个要删除的范围.如果我们在这个命令之前指定了一个数字,例如5:,那么要删除的范围就是这个数字所指定的范围(包括当前行).事实上这样指定的范围如下:
:...+count-1
例如我们在一段文本中执行下面的命令:
3:delete
这实际上是执行下面的命令:
:...+2 delete
这个命令可以删除当前行以及当前行以下的两行,总计三行的文本.
删除命令的另一个形式如下:
:line delete count
在这种情况下,:delete命令回到line所指定的行(默认为当前行),然后删除count行文本(包括当前行).
:copy命令是将几行的文本从一个地方复制到另一个地方.这个命令的一般格式如下:
:range copy address
如果没有特别指定,range默认是指当前行.这个命令是拷贝range所指定的范围行的文本到address指定行的后面.
与:copy命令相类似的是:move命令,所不同的只是这个命令是移动而不复制.
假如我们要在我们正编辑的文本中插入一些行,而由于某些原因,我们要使用命令行的方式来完成这样的工作.这时我们就要将光标移动我们希望新行出现的上一行.换句话说,我们是希望将插入的文本出现在当前行的后面.然后我们可以执行命令:append来开始我们的插入过程,我们输入我们要插入的内容并用句号(.)来结束一行的输入.例如我们在一个测试文本中执行下面的命令:
:1append
这个命令是要第一行的后面插入我们新的文本行.执行这个命令后,我们可以在Vi的底部输入我们要插入的内容.当我们要结束我们的输入时,只要在一新行输入.就可以了.这样我们输入的内容就会出在第一行的后面了.
:append命令的一般格式如下:
:line append
我们输入的新文本将会插入在line所指定的行后面.
:insert命令也可以插入文本,这个命令的一般形式如下:
:line insert
这个命令与:append命令相似,所不同的是后者是当前行的后面插入文本,而前者是在当前的前面插入文本.
我们不必打开number选项也可以实现在打印一行文本时打印此行的行号.命令:#与:print命令相类似,所不同的只是前者可以打印出行号.
例如在我们的测试文本中执行下面的命令:
:1 print
执行结果如下:
A UNIX sales lady,Lenore,
而我们执行下面的命令:
:1#
执行结果如下:
1 A UNIX sales lady,Lenore,
选项list可以使得不可见的字符成为可见字符.命令:list可以列出指定的行,而且这个命令全认为list选项已经打开.如下面的命令:
:1,5 list
这个命令就可以列出1-5行的内容.
这个命令与:print命令不同的地方只是这个命令也可以打印出回车,Tab等不可见的字符.
:z命令可以打印出一个范围内的文本行(默认情况下为当前行)以及这一行附近的行.例如我们执行下面的命令:
:100 z
这个命令会打印出从第100行开始的直到当前屏幕满屏的所有的文本行.
这个命令可以指定一个数字,用来表示除了打印指定的行以外要额外打印的行.例如下面的命令:
:100 z 3
这个就使得Vim除了打印第100行还要另打印额外的三行.
:z命令以后还可以再跟上一个代码用来表示要显示多少的文本.可用的代码如下:
代码 起始行 结束行 当前行
+ 当前行 向前一个屏幕 向前一个屏幕的下一行
- 向后一个屏幕 当前行 当前行
^ 向后两个屏幕 向后一个屏幕 向后一个屏幕
. 向后半屏 向前半屏 向前半屏
= 向后半屏 向前半屏 当前行
基本的substitute命令格式如下:
:range substitute /from/to/flags count
这里的定义符可以是除了字母,数字,反斜线,双引号或是竖线以外的任何字符.在Vim编辑器中Vim还使用一些特殊的字符来表示特殊的事物.例如*表示重复0次或是多次.如果我们设置了nomagic选项,那么这些字符的特殊意义就会被关掉了.
命令:smgic可以执行一个替换操作,但是这个命令要求我们设置了magic选项.
例如我们可以使用只有一行的文件来测试这些命令.我们可以用命令将整个文件打印出来:
:%print
Test aaa* aa* a*
然后我们设置了magic选项并且执行替换命令 .p标记告诉编辑器打印出他所改变的行:
:set magic
:1 substitute /a*/b/p
命令的执行结果如下:
bTest aaa* aa* a*
这个命令只是改变了一行开始的部分.为什么会将Test变为b*Test而且并没有a呢?这就是因为*可以匹配0次或是多次,而Test正是以0个a开始的.但是为什么只是替换了一次呢?这是因为:substitute命令中是改变第一个出现的地方.如果我们使用g标记就可以替换全部的匹配项了,我们撤销刚才的命令并执行下面的命令:
:undo
:1 substitute /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
现在我们在关闭magic选项的情况下再做一次:
:undo
:set nomagic
:1 substitute /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
在没有设置magic的情况下,*仅是一个*.
而:smagic命令则是在执行替换命令时强制转换*以及其他一些字符的意义,例如我们执行下面的命令:
:undo
:smagic /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
而相类似的是命令:snomagic选项强行关掉magic选项:
:undo
:snomagic /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
&命令可以重复执行替换.这个命令可以保存旧的from和to的字符串,但是允许我们使用不同的范围(range)和标记(flags).这个命令的一般形式如下:
:range & flags count
例如我们执行下面的命令:
:1 substitute /a\\+/b/p
这个命令的执行结果如下:
Test b* aa* a*
这个命令可以改变第一个出现from所指的字符的地方.但是我们希望是的整个一行都要发生相应的替换,这时我们可以重复这一次替换命令:
:&g
这一次在命令的执行过程中就不会打印执行结果,因为我们在这里指定的标记是g,而不是p.这个命令的执行结果如下:
Test b* b* b*
命令:&和命令:substitute在没有指定替换字符串的情况下作用相同,都可以执行上一次的替换命令.
在正常的命令状态下命令&可以重复上一次的:substitute命令.例如如果我们执行下面的命令就会将第五行中的字符manager变为idiot:
:5 substitute /manager/idiot/
这时如果在正常的命令模式下我们执行命令&,那么这一行中的下一个manager字符串也会发生变化.如果我们下移一行然后执行命令&,那么这一行也会发生相应的变化.如果我们在这个命令中指定了count,那么这个命令就可以作用多行.
:~命令与命令&g相类似,所不同的是前者使用的字符是上一次使用/或是?查找时使用的字符串,而不是上一次:substitute命令中的字符串.这个命令的一般格式如下:
:range~ flags count
在一般的情况下,:substitute命令只是改变一行中第一个出现指定的字符串处,除非我们使用了g标记.如果我们希望g标记能成为默认的设置,我们可以使用下面的命令:
:set gdefault
但是这里我们要注意的就是也许这样的设置会打断我们的一些脚本.
到了现在我们所说过的一些命令都是有一个限制的,那就是我们所要执行的命令只作用在相邻的行上.然而有时我们所希望是改变含有特定类型的行,这时我们就要用到:global命令了.这个命令的一般形式如下:
:range global /pattern/command
这个命令可以告诉Vim编辑器对在指定的范围内包含有指定的类型的所有行执地指定的命令.例如如果我们要打印出一个文件中所有包含单词Professor的行,我们可以使用下面的命令:
:%global /Professor/ print
而命令:global!将对所有的行执行指定的命令,但是却不匹配指定的类型.与其相类似的是:vglobal命令.
命令:ijump查找指定的类型,并且会跳转到指定的范围内第一个出现的单词处.这个命令不仅会在当前文件中进行查找,而且会在由#include所包含进来的文件中进行查找.这个命令的一般格式如下:
:range ijump count [/]pattern[/]
如果我们在这个命令中指定了count,那么就会跳转到第count个类型出现处.这个类型会被看作是精确的文本,除非是由斜线括起来的.
例如下面的一个Hello.c的文件:
#include <stdio.h>
int main()
{
printf(\"Hello World\\n\");
return (0);
}
如果我们执行下面的命令就会跳转到第一个含有 define EOF的行处:
:ijump /define\\s*EOF/
在我们目录的情况,他是在包含进来的文件stdio.h中
与这个命令相类似的是命令:ilist,所不同的只是这个命令是列出相应的行而不是跳转到相应的行.
命令:isearch与:ilist命令相类似,只是这个命令列出第一个出现指定内容的行.
最后命令:isplit是命令:ijump和命令:split的组合.
我们已经知道用命令[CTRL-D来跳转到当前光标下的宏定义处.下面的命令也可以起到同样的作用:
:djump name
例如我们要跳转到宏MAX处,我们可以用下面的命令:
:djump MAX
执行这个命令我们并不必需要知道我们定义的宏的全名,如果我们只是知道宏名的一部分,我们就可以使用由斜线括起来的常规表达式来进行相应的查找.如下面的命令:
:djump /MAX/
我们还可以指定参数来控制这个命令的查找范围,如下面的命令:
:50,100 djump /MAX/
这个命令只在第50到第100行内进行相应的查找.
如果我们希望查找到是第二个而不是第一个宏定义,我们可以通过指定count参数来做到.例如我们要查找第二个MAX的定义处,我们可以用下面的命令:
:djump 2 MAX
下面的命令会在一个新窗口内显示宏定义:
:range dsplit count [/]pattern[/]
这个命令是命令:split和命令:djump的组合.
命令:dlist与命令:dsplit相类似,只是前者并不会移动到一个宏的定义处,而是列出匹配的宏定义.
而命令:dsearch只是显示第一个匹配的宏定义.如果命令:ilist,ijump,:djump,:dlist,:dsearch带上!选项,那么在注释内的定义也可以进行查找.
如果我们要改变当前Vim的工作目录,我们可以用下面的命令:
:cd dir
这个命令与系统的cd命令相类似.如果没有指定目录,那么就会回到我们的用户主目录.
要查看当前Vim的工作在哪一个目录下,我们可以有用下面的命令:
:pwd
要回到前一个工作目录,我们可以用下面的命令:
:cd -
下面的命令可以打印出当前文件的名字以及一些相关的行信息:
:file
如果我们要改变当前文件的名字,我们可以使用下面的命令:
:file name
例如我们正在编辑的文件名为complete.txt,我们可以使用:write命令进行保存.现在我们要缩短文件并且存为summary.txt,我们可以执行下面的命令:
:file summary.txt
如果我们继续进行编辑,那么所的改动都会被存入文件summary.txt中.
与:file命令相似,命令:=可以打印出当前行的行号.
:write命令可以将缓冲区或是一个文件中指定范围内的文本存入.他还有一些其他的选项.例如下面的命令就可以将我们正编辑的文件内容追加到文件collect.txt中:
:write >> collect.txt
如果这个文件并不存在,那么这个命令就会给出错误信息.如果我们要强行追加,可以使用!选项:
:write!>>collect.txt
:write命令不仅可以保存文件,而且可以将文件导入其他的程序.在Linux系统中,我们可以用下面的命令将文件发送到打印机:
:write !lpr
(注::write! lpr与:write !lpr这两个命令的不同,前才是强行保存文件而后者则是将文件发送到打印机)
命令:uddate与命令:write相类似,所不同的只是如果缓冲区没有被修改,那么这个命令就不会起作用了.
:read命令将会读入一个文件.这个命令的一般格式如下:
:line read file
这个命令会将名为file的文件读入并且插入在line后面.如果没有指定文件,那么就会使用当前的文件,如果没有指定要插入的行,那么就会使用当前的行.
与:write命令相类似,:read命令可以使用一个命令而不是一个文件.如果要读入一个命令的输出并插入到当前行的后面,我们可以使用下面的命令:
:line read !command
我们在以前的学习曾学过如何在寄存器中录制宏.如果我们要在命令行中使用这些宏,我们可以用下面的命令来执行寄存器中的宏内容:
:line@register
这个命令会将光标移动到指定的行,然后执行寄存器中的内容.这就意味着下面的命令执行上一次的命令行:
:@:
如果要执行上一次的:@register命令,我们可以用下面的命令:
:line@@
命令:>使得文本右缩进,:<命令使文本向左缩进.例如下面的命令将会使第五行到第十行向右缩进:
:5,10>
:change命令与:delete命令相类似,所不同的只是他还同时执行:insert命令,也就是有我们可以同时输入我们要插入的文本.
命令:startinsert命令可以开始插入模式,就像是我们在正常模式下执行i命令一样.
如果我们要将几行合并为一行,我们可以使用命令:join,在这个命令的执行中将会使用空格来分隔这几行.如果我们不希望加入空格,我们可以用下面的命令来合并:
:join!
下面的命令可以将指定的行的文本复制到寄存器中:
:range yank register
如果没有指定寄存器,将会使用未命名寄存器.
:put命令会将寄存中的内容粘贴到指定的文本行的后面.例如要将寄存器中的内容粘贴到第五行的后面,我们可以用下面的命令:
:5put a
如果要将文本放在这一行的前面,我们可以用下面的命令:
:5put! a
:undo命令会撤销上一次的命令操作,与u命令相类似.而:redo命令会重做撤销的操作,与命令CTRL-R命令相类似.
如果要标记一行的开始,可以用下面的命令:
:mark {register}
如果指定了行,那么那一行将会被标记.命令:k将会起到同样的作用,只是我们不需要在寄存器名前加上一个空格.例如下面的命令:
:100 mark x
:100 ka
命令:preserve可以将整个文件写入swap文件.这就使得我们可以在没有原始文件的情况下来修复我们的编辑部分.
如果我们要执行单一的Shell命令,我们可以用下面的命令:
:!cmd
cmd就是我们要执行的系统命令.
例如要查看当前的日期,我们可以用下面的命令:
:!date
如果我们要重复上一次的Shell命令,我们可以用下面的命令来做:
:!!
最后下面的命令可以挂起Vim而进入命令提示行:
:shell
现在我们就可以执行各种的系统的命令了.在我们完成我们的工作以后,我们可以用exit命令回到Vim编辑器.
下面的一些选项可以控制命令的执行:
shell 我们要执行的命令名
shellcmdflag 跟在命令后的标记
shellquote 在命令中的引用字符
shellxquote 命令中的引用字符和重定向
shellpipe 使用管道的字符串
shellredir 重定向输出的字符串
shellslash 在文件名中使用向前的斜线(只在DOS中使用)
命令:history可以当前命令模式下的命令历史
Vim编辑器可以记录各种命令的历史,下面的标记指出所记录的历史类型;
c cmd : 命令行历史
s search / 查找字符串历史
e expr = 表达式寄存器历史
i input @ 输入行历史
a all 所有的历史
如果我们列出所有的历史,我们可以用下面的命令:
:history all
:history命令的一般格式如下:
:history code first,last
如果没有指定first和last,那么就会列出所有的命令.first参数默认是指历史第一个输入的,而last就是指最后一个.负数是指由历史的结束处向前的数的第几个.例如-2是指最后个命令的输入.
例如下面的命令列出第一个到第五个的命令行历史:
:history c 1,5
而下面的命令则是列出了上五次的查找历史:
:history s -5
history选项可以用来控制记录的历史命令数.例如我们要将记录的历史命令数增加为50,我们可以用下面的命令:
:set history=50
Vim编辑器可以记录上几次的错误以及在屏幕最后一行显示的信息.要查看这些信息,我们可以用下面的命令:
:messages
下面的命令可以使得信息的输出在显示在屏幕的同时会拷贝到一个文件中:
:redir > file
如果要停止拷贝,可以使用下面的命令:
:redir END
这个命令在保存调试信息时会显得更为有用.
我们还可以用:redir命令将输出追加到文件中:
:redir >> file
:normal命令可以使我们执行一个正常模式下的命令.例如下面的命令是将光标下的单词改为DONE:
:normal cwDONE
在行这些命令时要求命令必须是一个完整的命令.如果我们已经挂起Vim然后执行命令时,Vim显示全直到命令完全时也会发生变化.
下面的命令会将当前的文本写入文件,然后退出:
:exit
如果我们使用!选项,即时这个文件被标记为只读,那么Vim也会强行保存.
我们还可以在命令行指定一个文件名,那么当前的内容就会在退出以前写入我们所指定的文件,例如下面的命令:
:exit save.txt
如果我们只是想着将文件中的一部分保存到另一个文件,我们可以指定一个范围来保存.例如要保存100行,我们可以用下面的命令:
:1,100 exit save.txt
下面的命令与:exit命令相类似,不同的是这个命令总是会保存文件:
:range wq! file
而:exit命令只是在文件发生改变时才会保存.