我的文件如下所示:
>>Start-pattern
some text
some more text
>>Start-pattern
some other text
some more other text
>>Start-pattern
[and so on]
我想要的是一个允许我删除文本当前“块”的映射。其中“块”被定义为所有行,范围从“>> Start-pattern”到之前下一个“>> Start-pattern”行。
我所拥有的是以下内容:
nnoremap ,d $:?^>>Start-pattern?,/^>>Start-pattern/-1delete<CR>
除非我站在文件中的最后一个“块”上,否则无效。
如何才能使这个地图(或完全不同的地图做同样的事情)处理文件中的所有“块”?
答案 0 :(得分:7)
我认为,我们再一次将正则表达式的界限推向了他们擅长的范畴。他们擅长将一个字符串与另一个字符串交换,这是一个副作用,你可以用它们删除文本。
相反,为什么不利用vim提供的迷人脚本语言。它更容易,就像回程机器上的旅行一样。如果您将以下函数添加到.vimrc文件中,它将执行您想要的操作并且更具可重用性/灵活性:
fun! DelBlock(thePattern)
let origLineNumber = line(".")
let lineNumber = origLineNumber
let lineString = getline(lineNumber)
while lineString !~ a:thePattern
let lineNumber = lineNumber - 1
if lineNumber < 0
echo "Function not found :/"
endif
let lineString = getline(lineNumber)
endwhile
let startLine = lineNumber
let lastLineInFile = line("$")
let lineNumber = origLineNumber + 1
let lineString = getline(lineNumber)
while lineNumber != lastLineInFile && lineString !~ a:thePattern
let lineNumber = lineNumber + 1
let lineString = getline(lineNumber)
endwhile
let endLine = lineNumber
if endLine != lastLineInFile
let endLine = endLine - 1
end
execute startLine.","endLine."d"
endfunction
map ,d :call DelBlock("^>>Start-pattern")<CR>
答案 1 :(得分:6)
您可以使用单个正则表达式执行此操作:
nnoremap ,d :1,.s/\v%(%(.*%#&(\>\>Start-pattern))%(\1@!\_.)+)\|%((\>\>Start-pattern)%(\2@!\_.)*%#%(\2@!\_.)+)//
你 是否是另一个问题......
答案 2 :(得分:3)
这是一个可能的黑客。
nnoremap ,d maGo>>Start-pattern<Esc>'a$?^>>Start-pattern<CR>dNmaGdd'a
ma - mark your current position
G - go to the end of the file
o>>Start-pattern<Esc> - append your pattern line
'a - go back to your prior position
$ - go to the end of the current line
?^>>Start-pattern<CR> - find the previous occurrence of the pattern
dN - delete until the next occurence
ma - mark your current position
G - go to the end of the file
dd - delete the last line of the file
'a - return to your previous position
我最初试图让\%$
(文件末尾)起作用,但我无法删除
包括文件中的最后一个字符。所以我尝试了这种方式。
我做了一些测试,它似乎对我有用(中间块和最后一个块)。
答案 3 :(得分:2)
非常感谢你的回答,伙计们!
最后,我选择了最可维护/最强大的。在Whaledawg的回答基础上,考虑到Luc Hermitte的评论,我最终得到了:
fun! DelBlock(pat)
let startLine = search(a:pat, "nbcW")
let endLine = search(a:pat, "nW")
if startLine == 0
echo "Block '".a:pat."' not found"
return
end
if endLine == 0
let endLine = line("$")
else
let endLine = endLine-1
end
execute startLine.","endLine."delete"
endfunction
nmap ,d :call DelBlock("^>>Start-pattern")<CR>