`

vim寄存器使用详解

 
阅读更多

寄存器用于存储Vim操作中的特定内容,大多数normal命令和部分ex命令都可以指定操作关联的寄存器。寄存器同时也是Vim里特殊的变量,因此可以 在命令行和脚本中被访问,实现一些非常有用的功能。Vim有很多不同类型的寄存器,各司其职,各具其能,若得灵活运用,会令编辑工作轻松高效。本文以 Vim中常见的问题为例,介绍各类寄存器的功能和用法。 

1. 编辑操作中的常用功能 

:h v_p 
:h g@ 
:h redo-register 

Vim 中最常用到的是数字寄存器。当不指定寄存器时,复制操作的内容被保存到"0,删除操作的内容被”压“到"1,同时原先"1的内容转到"2,依此类推,原 先"8转到"9,原先"9的内容丢失。如果指定操作的寄存器,如"ayy和"bdd,则上述的数字寄存器无影响(有些例外情况,详见Vim手册)。未命名 寄存器""保存最近一次复制或删除操作内容,无论是否指定寄存器。还有一个特殊的“黑洞”寄存器"_,当指定其进行删除时,包括""在内的任何寄存器都不 受影响,当然,你也没法把掉进黑洞的物质p出来。 

【例1】复制-删除-粘贴 
这是经常困扰Vim新手的一个问题:当复制了一个词(yw)然后准备将另外一个词替换掉,自然的想法是删除(dw)后粘贴(p),但dw已经将""更新为被删除的词,p的内容将不是复制的那个了。有几个办法以供选择: 
A. 先p后dw,问题是要重新定位需要删除的部分。你可以用gp/gP试试,它与p/P功能一样,不过光标停留在粘贴出的文字之后,便于随后的删除; 
B. 将删除内容转到黑洞("_dw),再p; 
C. 指定复制内容("0p); 
D. 利用Visual mode下p命令的交换特性(vwp),该操作粘贴指定寄存器的内容,然后删除被选择的文字。这种方法的键盘输入比B和C都方便些。 
E. 利用下面这条map的S命令(S原有功能与cc相同,所以把它改了)。 
" replace text with unnamed register (in all modes) 
function! ReplaceWithUnamed(type) 
let paste_save=&paste 
let &paste=1 
if a:type == 'line' 
silent exe "normal! '[V']" 
elseif a:type == 'block' 
silent exe "normal! `[\<C-V>`]" 
elseif a:type == 'char' 
silent exe "normal! `[v`]" 
else 
silent exe "normal! `<" . a:type . "`>" 
endif 
silent exe "normal! \"_c\<C-R>"\<ESC>" 
let &paste=paste_save 
endfunction 
nmap <silent> S :set opfunc=ReplaceWithUnamed<CR>g@ 
vmap <silent> S :<C-U>call ReplaceWithUnamed(visualmode())<CR> 
这种方法符合command-motion的操作流程,而且""里的内容不改变,在需要将多处文字替换成同一内容时非常方便。 

【例2】进行快速倒序 
有时我们需要把一系列的内容交换顺序,比如要把“0x12,0x34,0x56“改成“0x56,0x34,0x12”。假设光标初始在0x12 处,利用数字寄存器的压栈功能,用dw....将5个部分依次删除到"5至"1中,然后用"1p....依次吐出来。巧妙之处在于,若p命令时指定数字寄 存器,则后续的.命令会自动将数字寄存器的编号加一,也就是第一个.执行的是"2p,依次类推。 

【例3】多部分复制粘贴 
上述技巧还可以用来将多段的文字分别复制到不连续的目的地,比如要把一个函数中某个变量的声明和多处引用(记为A、B、C部分)复制到另外一个函 数中(记为X、Y、Z处)。我们可以依次在A、B、C部分执行删除和undo,然后在Z、Y、X处执行"1p和2个redo,这样将不用在两个函数之间跑 来跑去。 
数字寄存器的这一用法还可以用来试选历史删除内容,比如想要粘贴之前某次删除内容,但不知道已经被压到哪层了,则可以"1pu(或者比如"3p,如果你确信不是最近两次删除内容),然后执行几次.u直到想要的内容出来。当然,直接用:di看一下各个寄存器的内容也许更快。 
本例也可以把3个部分分别y到"a,"b和"c里,然后到各自的目的地"ap,"bp,"cp。 

"a 到"z这26个命名寄存器为编辑操作提供了丰富的资源,比如,程序员可以将常用的代码模版预设到某些寄存器中(利用ftplugin),需要时p出来。命 名寄存器另有一大功能是有"A到"Z与之对应,当用这些大写字母寄存器时,操作的内容是追加到小写字母寄存器原有内容的后面,这在需要收集多处内容时特别 方便,与其它命令结合使用更有妙用,见下例。 
【例4】提取匹配行内容 
:g/regex/norm "Ayy 
上面这条命令把匹配regex的所有行都保存到"a中,当然在运行前需要把"a清空,比如在一个空行上"ayy。 

寄存器".保存上一次插入的文字,在需要在多个地方插入相同文字,但又因中间进行了其它修改操作而不能redo时,".非常有用。 

寄存器"%和"#保存当前文件和替换文件的文件名,编程写注释头的时候经常用到。需要注意的是,如果文件是在当前目录或其子目录下,文件名是相对路径名,否则是全路径名。 

2. 寄存器的其它引用方式 
:h i_CTRL-R 
:h autocmd 
:h redir 

除了在normal命令中以"x的形式指定外,插入模式和命令行中输入<CTRL-R>-x将插入"x的内容。 因为寄存器是Vim中预定义的特殊的变量,还可以在命令行和脚本中以变量的形式(变量名字符前加@)直接读取或修改。 

Vim 将最近一次的搜索文字保存在"/中,对应的变量@/决定了n/N命令和查找高亮的对象。@/被所有buffer共享,也就是说在一个buffer里进行新 的查找,其它buffer的匹配高亮和n/N命令也随着更新。如果希望每个buffer都维护自己的查找内容,可以参考下例: 
【例5】查找内容本地化 
我们利用autocmd功能,在离开buffer时保存"/的值,在进入buffer时恢复: 
:au BufLeave * let b:search_save=@/ 
:au BufEnter * if exists("b:search_save") | let @/=b:search_save | endif 
还可以把buffer改成window,也就是各个window维护自己的"/,这样在多窗口编辑同一文件时,可以使得查找文字互不干扰。 

【例6】信息重定向 
有时候我们想把执行ex命令的信息保存下来,Vim提供了:redir命令用来把信息输出重定向到文件或寄存器里。例如: 
:redir @a 
:(some commands) 
:redir END 
可以定义一个命令来自动完成上述操作: 
:command! -nargs=* Mc redir @"> | try | exe "<args>" | finally | redir END | endtry 
例如【例4】也可以这么实现,而且不需要预先清除寄存器。 
:Mc g/regex/p 

3. 寄存器与宏 
:h q 
:h @ 
:h :@ 

宏是Vim中非常重要的功能,用来重复执行多个连续操作。当这些操作包含移动、查找、插入、修改等不同类型的命令时,宏显得尤其方便,很多时候 用:s和:g 难以实现的功能,宏都可以轻松搞定。用q录制宏实际上是将键盘输入记录到寄存器的过程,而用@运行宏则是将指定寄存器内容作为normal命令执行的过 程。q命令提供了“所做即所得”,但有时候直接修改寄存器更为方便。比如当你录制完一个非常复杂的宏,但发现有一个小毛病(例如应该是de而不是dw), 不必重新录制一遍,只需要将寄存器的内容p出来修改好再y回去。 
【例5】宏的一些技巧 
A. 容许错误:录制过程中如果有错不必放弃重来,可以undo或<BS>,只要保证这些操作和处理文本无关,寄存器里有些乱七八糟的东西又何妨。 
B. 分而治之:当录制一个很复杂的宏时可以考虑分成几段,比如qa第一步,qb第二步,然后在qc中调用a和b,各个击破简单易行。 
C. 重复运行:@@命令可以重复上次的宏调用。 
D. 另作它用:q命令是向寄存器里录入命令,你也可以什么都不录!有什么用处?【例4】中清除"a最快的方法:qaq。 

Vim 中用":寄存器记录最近一次运行的命令行命令,因此@:是重复上次的命令行操作。值得注意的是,@x宏运行的是normal命令,而@:运行的是Ex命 令。如果某个寄存器"x保存的是Ex命令,你可以用:@x来执行。比如在测试vimrc中的某条命令时,先yy,然后:@"执行。 

4. 寄存器求值 
寄存器"=与众不同,它不存储文本,而是在可以使用寄存器的场合中提供了用表达式求值并取得其结果的途径。简单的说,就是在指定"=时,Vim会提示输入一个表达式,然后将求值结果返回,至于这串文本如何使用,就看在什么地方使用了。 

【例6】十六进制转十进制 
在插入模式下输入<C-R>=,Vim会提示一个=,再输入0x1234<CR>,4660就自动插入到当前位置。 

【例7】十进制转十六进制 
上例的反操作可就没那么方便了,你得用printf函数。下面这个map是将当前的数字替换成十六进制。这个map也许不大易懂,命令其实是【例1】中提到到v_p,只不过用于替换的内容是通过"=进行求值的结果。 
:nmap \h viw"=printf("0x%X",<C-R><C-W>)<CR>p 

【例8】设置字体 
一个常见的问题是如何将guifont的设置写入到_vimrc中,字体名加上字号通常很长,比如我用的是 ”Bitstream_Vera_Sans_Mono:h9:cANSI”,照着敲实在太麻烦。当然可以利用【例6】中的:redir把:set guifont的输出抓出来,但这不是最好的方法。Vim中的选项也是变量,变量名是选项名前加&,因此我们可以方便的用<C- R>=&guifont<CR>得到它。需要其它变量,比如环境变量$HOME,也可以如法炮制。 

"=不光用来插入文字,任何能使用寄存器的地方都可以引用。比如用qa录了一个宏后,执行时又想不要最后的dw命令,一个快捷的方法是执行 
@=@a[:-3] 
@=运行后面表达式的结果,[x:y]是取字符变量的子字串(串首从0编号,串尾从-1编号),因此@a[:-3]返回除最后dw之外的内容。记住,若要再次运行只需敲@@。 

【例9】寄存器求值在在命令行中的示例 
:noremap ,e :e <C-R>=expand("%:p:h") . "/" <CR><C-D> 
:noremap ,s :split <C-R>=expand("%:p:h") . "/" <CR><C-D> 
:noremap ,S :vsplit <C-R>=expand("%:p:h") . "/" <CR><C-D> 
:noremap ,t :tabnew <C-R>=expand("%:p:h") . "/" <CR><C-D> 
上面几个map提示显示当前文件所作目录下的文件列表,以供edit/split/tabnew,目录名是用<C-R>=求值的方式获得。(如果你希望当前目录自动跟随当前文件,设置autochdir。) 

5. 总结 
上面介绍了大部分的寄存器,但没有提及"*、"+和"~,这些寄存器是和GUI的选择和拖拽有关,版内有文章讲解很详细,本文不再累述。有一个常见问题说一下:如果希望和其它程序方便的复制粘贴,可以将剪贴板寄存器"*设为未命名寄存器: 
:set clipboard=unnamed 
另外需要说的是,用q:和q/可以打开保存有命令行和查找内容的历史窗口(命令行历史窗口也可以在命令行下敲CTRL-F打开),在其中可以查找、编辑、修改和执行历史命令或查找。 
寄存器操作看似都是些细碎的东西,但却是编辑中经常用到的。我们不仅需要掌握:s和:g这类复杂、强大的命令,更需要精通像寄存器这样的小东西,因为这才是决定编辑效率的关键所在——点滴加速,高效之源。

分享到:
评论

相关推荐

    vim 使用详解手册

    **vim使用详解手册** 在IT领域,vim(Vi Improved)是一款强大的文本编辑器,深受程序员和系统管理员的喜爱。它的灵活性和高效性使得它在文本处理方面具有无与伦比的优势。下面将对vim的主要功能、操作模式、常用...

    linux下vim命令详解

    ### Linux下Vim命令详解 #### 一、引言 Vim是一款强大的文本编辑器,尤其在Linux环境下被广泛使用。它提供了丰富的功能,包括宏命令、多文件编辑支持、高效的文本导航方式以及灵活的编辑操作。本文将详细介绍Vim的...

    VIM中文使用手册(详解)

    本手册将详细介绍VIM的使用方法,帮助用户从基础操作到高级技巧全面掌握VIM。 一、VIM的基本操作 1. 启动与退出:在命令行输入`vim`后跟文件名即可启动VIM。退出VIM,需在正常模式下输入`:q`,如果已修改文件,需...

    VIM 官方使用手册

    6. **寄存器和缓冲区**:VIM的寄存器系统能存储多个剪贴板,而缓冲区管理则帮助用户在多个文件间切换和操作。 7. **工作区和窗口**:VIM可以同时打开多个文件并在多个窗口间切换,提高多任务处理能力。 8. **调试...

    vim高级使用技巧

    《vim高级使用技巧详解》 vim作为一款强大的文本编辑器,深受程序员和系统管理员的喜爱。本文将深入探讨一些vim的高级使用技巧,帮助有经验的用户提升编辑效率。 1. **插入行号** - `g/^/exec "s/^/".strpart...

    Vim中宏命令的使用实例详解

    在 Vim 寄存器的文章里面已经对 macro 有所涉及, macro 的操作都是以文本的方式存放在寄存器中。 宏是一组命令的集合,应用极其广泛,包括MS Office中的word编辑器,excel编辑器和各种文本编辑器,Linux系统中最强

    史上最全vi/vim使用手册/教程/技巧/键盘图等

    **vim/vi编辑器详解** vim(Vi Improved)是一款强大的文本编辑器,源自早期的vi编辑器,广泛应用于Linux和Unix系统中。它以其高效、命令行操作和丰富的功能著称,是程序员和系统管理员的必备工具。本教程将涵盖vim...

    vim 使用教程

    ### vim使用教程知识点详解 #### 一、Vim简介与特点 - **Vim简介**:Vim(Vi IMproved)是一款基于vi编辑器的强大文本编辑工具,它不仅继承了vi的所有功能,还在此基础上进行了大量的改进和扩展,使之成为现今最...

    vim 命令 详解

    ### Vim命令详解 #### 1. Vim简介 Vim(Vi IMproved)是一款在Linux和其他类Unix系统上广泛使用的文本编辑器。它基于vi(Visual Editor)开发而来,旨在提供更丰富的特性和改进的用户体验。Vim因其强大的功能、高度...

    Mac之vim普通命令使用

    ### Mac之vim普通命令使用详解 #### 一、引言 在现代软件开发环境中,高效地使用文本编辑器是提高工作效率的关键之一。Vim作为一款功能强大的文本编辑器,不仅适用于Unix/Linux系统,也在MacOS平台上得到了广泛的...

    VIM操作精心整理版本

    - **寄存器**:Vim支持使用寄存器存储文本片段,可以通过`"a`来选择寄存器,然后使用`y`、`p`等命令进行操作。 #### 七、查找与替换 - **查找**:使用`/pattern`向前查找模式,使用`?pattern`向后查找模式。 - **...

    VIM Quick Reference Card

    ### VIM快速参考卡详解:高效利用vi命令 在Unix/Linux环境下,VIM(Vi IMproved)是一款功能强大且广泛使用的文本编辑器,它继承了Vi编辑器的基础,并在此基础上进行了大量的增强和优化。本文将从VIM的基本移动、...

    windows vim

    **Windows下的Vim编辑器详解** Vim,全称Vi Improved,是一款强大的文本编辑器,最初基于UNIX系统的Vi编辑器发展而来。在Windows系统中,Vim同样提供了高效且高度可定制化的文本编辑体验。Vim以其高效的操作方式、...

    vim reference

    ### Vim 快速参考指南详解 #### 前言 Vim是一款强大的文本编辑器,在开发者社区中享有极高的声誉。对于那些希望提高文本编辑效率的人来说,熟练掌握Vim的各种功能是必不可少的。本文将根据提供的Vim快速参考卡内容...

    Vim_键位图_中文PDF高清版

    本篇将基于提供的“Vim_键位图_中文PDF高清版”文件内容,深入解析Vim中的各种快捷键及其使用场景。 #### 二、Vim的基本模式 - **普通模式**:启动Vim时默认进入的模式,大多数编辑操作都在此模式下完成。 - **插入...

    神器 vim 学习 方法

    ### 知识点详解:Vim学习方法与高级技巧 #### Vim是什么? Vim是一款功能强大的文本编辑器,源于vi编辑器,适用于Unix、Linux以及Windows等操作系统。它以其高度可定制性和高效性,在程序员和系统管理员中广受欢迎...

    vim命令学习笔试总结总结总结

    #### Vim常用命令详解 接下来,我们将详细介绍vim中的一些常用命令。 ##### 命令模式下的操作 1. **移动光标** - `h`:向左移动一个字符。 - `j`:向下移动一行。 - `k`:向上移动一行。 - `l`:向右移动一个...

Global site tag (gtag.js) - Google Analytics