经常处理文本以及经常需要写代码的人,都会有自己比较常用的编辑器,本人喜欢用Vim,理由就是Vim编辑器灵活,并且可以达到纯键盘操作,使用纯熟情况下,根本不需要鼠标操作,听起来是不是很酷的?不过别高兴太早,想达到那个境界必须的指令是需要学习+记忆+练习的。总结指令如下:
高级正则表达式
1./\s*\<\(return\|else\)\@!\w\+\s\+\w\+\s*([^)]*)\s*;\@!\s*$
\<
\@!
2.要求是将
变成
方法一:
第一步,增加id="":
:g/^$/ id="">/g
第二步,增加数字:
:let i=0 | g/^$/\=i/| let i=i+1
这是用|号(逻辑或的符号,不是字母)连接的三个语句,
前后两个就是给i赋初值和递增,
id="\zs\ze">$ \zs
这个语句就是只匹配双引号中间的内容,
这样不会把其他有用的地方替换掉了
\=i \=是把后面的字符串当成表达式来对待,在这里就是i
方法二:
这是用一步解决的方法:
:let i=0 | g/^$/\=substitute(" id = \"0\">", "0", i,"")/| let i = i+1
和上面的方法基本相同,就是替换右尖括号,不过这次是替换为substitute(" id = \"0\">", "0", i,"")
这是一个替换函数,就是在id=0中查找第一个0,并替换为i
08.08.19
:let i = 1 | g/^$/\=" id = " . i . ">"/ | let i += 1
其中\=表示后面是个表达式,小数点用以连接字符串的几个部分,中间用了i
3.
法一:
:g/^/exec "s/^/".strpart(line(".")." ", 0, 4)
法二:
:%s/^/\=strpart(line(".")." ", 0, 4)/g
line()返回一个行数,特别的,
line(".")返回当前光标所在行的行数,其他的参数见:h line()
g/^/exec是对所有行执行一个或多个命令,具体可以:h exec
每个命令必须用字符串,也就是要放在双引号里面,多个命令间用空格分割.
在上面的例子中,后面只有一个命令,但是这个命令是用小数点连起来的一个字符串
4.如下的赋值
firstline=1 //comment line 1
secondline=2
thirdline = 3//comment line 2
forthline= 4
fifthline =5
希望整理成
firstline = 1 //comment line 1
secondline = 2
thirdline = 3 //comment line 2
forthline = 4
fifthline = 5
下面是我写的语句,比较长,应该还有更好的写法,以后有改进再补充
:g/=/s#\v(.*)\=\s*(((//|/\*)@!.)*)\ze(//|/\*)?#\=strpart(submatch(1) . " ",0,13) . "= " .
strpart(submatch(2) . " ",0,10)# | s/\s*$//
前面紫色部分,查找所有包含等号的行,然后执行后面两个命令,
第一个命令是橘黄色的部分,第二个命令是蓝绿色部分,
第二个命令就是去掉行末的空格,这个不需要多解释,重点解释第一个命令
s#a#b#是一个替换的命令,这里用#做分隔符,是因为后面的表达式中有斜杆/,
如果用斜杆作为分隔符,则表达式中的斜杆需要转义,稍显累赘
\v表示后面的正则表达式中,除了字母和数字和下划线和斜杆,其他的都作为特殊字符对待,
有这个设置的好处,是后面可以省掉好几个用来转义的反斜杆,
像\(\)\+这些都可以简写成()+
\=
\s*
加粗的部分是一个比较重要的地方,一共三层括号,最外层括号使这个括号内部的内容成为一个子匹配,
在后文中的submatch(2)就是指的这一部分,
后面的一个*号,表示第二个括号内的内容可以匹配0
第二个括号内部,@!是个"零长度匹配",表示前面第三层括号内的内容不能出现,
小数点匹配除了换行符外的任意字符,
第三层括号里面,就是c语言注释的两种形式,//和*.txt
而:argdo %s/hate/love/gc | update
是将参数列表中的所有文件的hate提换成love,并写入硬盘(如果没有|update,就不
会写入,但相应的替换也会被中断)
最后强调一点,使用替换命令的时候,一定记得备份,因为替换是直接写入硬盘滴哦……
专题:
1.模式行
:help modeline
:help 'modeline'
:help 'modelines'
模式一
// vim:ft=cpp tabstop=4
模式二
vim:set tw=78 ts=8 ft=help norl:sdfasdfasdgs
第一种形式中最后一设置项后的冒号或空格是可有可无的。
而第二种形式中最后一设置项后一定要有冒号——不管冒号后有没有文字。
在设置项中如果要使用空格、制表符或冒号可以在前面加上转义符-`\‘。
其他需要转义符的情况见`:help option-backslash‘。
2.折叠
:help folding
:help foldmethod
:help fold-methods
:help
:set foldmethod=manual
:3,8fo
折叠方式:
1)`manual‘
手工规则下,折叠层级由折叠区域的嵌套关系计算。当我们手工指定一个折叠的区域后,Vim
对这个区域的开始行和结束行做记号,多个区域的开始行和结束行形成了嵌套关系。如果一
个折叠区域不包含在其他区域之中,则其折叠层级为1;当这个区域直接包含于另一个区域
时则其为折叠层级为另一个区域的层级加1;依些类推。
2)`marker‘
当使用标记规则折叠时,层级的计算跟手工规则相似。除了它是根据文件中的标记来划分一
个折叠区域而不是手工指定。然后根据这些区域间的嵌套关系计算折叠层级。具体使用的标
记通过`foldmarker‘设置。默认是使用'{{{,}}}'。
手工和标记类似
:set foldmethod=manual
:3,8fo
使用manual一般是临时性的折叠。如果每次编辑特定文件都需要做同样折叠时时建议结合modeline使用其他折叠
规则。如果不得不使用manual方式时,你可以用:mksession保存包括折叠在内的一切当前编辑设置或者
用:mkview保存当前窗口
3)`indent‘
行的缩进宽度除以`shiftwidth‘,并向下取整得到每一行的折叠层级。同一折叠层级及更高折
叠层级的连续行形成折叠。而其中的更高折叠层级的行——如果有的话,形成嵌套的折叠。
4)`syntax‘
跟`marker‘差不多,只是所用的标记是在语法文件中定义的,而不是通过`foldmarker‘设置。
5)`diff‘
除了差异行及其前
6)`expr‘
由用户指定折叠层级的计算方式。方法是对`foldexpr‘进行设置。具体用法稍后说明。
:set foldmethod=expr
:set foldexpr=1
所有的行都被折叠
v:lnum>=8&&v:lnum<=20?1:0
v:lnum>=8\ &&\ v:lnum<=20\ ?\ 1:0
三个在折叠的表达式比较常用几点:
v:lnum
getline()
?:
v:lnum>=8&&v:lnum<=20?1:0
v:lnum>=8\ &&\ v:lnum<=20\ ?\ 1:0
:set foldexpr=(v:lnum>=8&&v:lnum<=20?1:0)
如果一行以@samp{#}开始,折叠。
:set foldexpr=getline(v:lnum)=~/^#/?1:0
以每5行为一组折叠
set v:lnum%5-1?1:'>1'
用正则表达式@samp{.}判断当前行是否含有文字。
set foldexpr=getline(v:lnum)=~'.'?1:0
在文章的末尾加入
vim: ro: fdm=expr: fde=getline(v\:lnum)=~'.'?1\:0:
foldtext=foldtext().v\:folddashes.getline(v\:folds
tart+1): foldcolumn=2
则每次打开文件会折叠(方式是空行之间的折叠在一起)
导出折叠的部分到笔记.txt
:folddoclosed .w! >>笔记.txt
如果folddoclosed
删除所有的marker用
在'.vimrc'(windows中是'_vimrc')中加入,下面的内容:
"
'.eml',则当成邮件处理。
autocmd! BufReadPre *.eml se fdm=expr
fde=v:lnum==1?1:getline(v:lnum)=~'^$'?0:'='
fdt=Mailfdt(v:foldstart,v:foldend) ft=mail | syn on
"
"
func! Mailfdt(fst,fen)
let fst=a:fst
"
let hfrom=''
let hsub=''
let tline=''
while a:fen!=fst
let tline=getline(fst)
"
"
if tline=~'^From: '
let hfrom=tline
elseif tline=~'^Subject: '
let hsub=tline
endif
let fst=fst+1
endwhile
"
if strlen(hfrom) || strlen(hsub)
return hsub . "\t\t\t" . hfrom
else
return getline(a:fst)
endif
endfunc
在加入上面的内容后,我们现在用Vim打开邮件(实际是以.eml作后缀名的文件)
看看,是不是清爽多了!
这是比较不常用但又可能比较有用的内容。使用:help查看相关信息。
v:foldstart
v:foldend
foldlevel()
'foldlevel'
'foldnestmax'
'foldignore'
:folddoclose
:folddoopen
更多内容参考`:help vim-script‘
:help :folddoopen
:help :folddoclosed
3.
高效
1.移动速度
set hlsearch
*
使用fold
2.Don't type it twice
使用CTR+n
3.Fix it when it's wrong
:iabbrev teh the
:syntax keyword WordError teh
4.A file seldom comes alone
:!ctags -R .
:tag init
:tnext
:grep “\” **/*.h
:cnext
:make
gf goto file
语法高亮帮助文档
:help syntax.txt
:help 'tags'
:help tags-file-format
:help tags-and-searches
:tag
:tselect [关键字](显示与“关键字”匹配的标记列表,输入数字跳转到指定的标记)
:tjump [关键字](类似于“:tselect”,但当匹配项只有一个时直接跳转至标记处而不再显
示列表)
:tn(跳转到下一个匹配的标记处)
:tp(跳转到上一个匹配的标记处)
Ctrl-](跳转到与光标下的关键字匹配的标记处;除“关键字”直接从光标位置自动获得外,功
能与“:tags”相同)
g](与“Ctrl-]”功能类似,但使用的命令是“:tselect”)
g Ctrl-](与“Ctrl-]”功能类似,但使用的命令是“:tjump”)
Ctrl-T(跳转回上次使用以上命令跳转前的位置)
gf
1.vim
-o
-O
会自动根据文件的个数分成几行或者几列.
使用
gi - incredibly handy
goes to Insert mode where you left it last time