在vim中删除文本的“块”

时间:2009-05-07 14:33:57

标签: vim

我的文件如下所示:

>>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>

除非我站在文件中的最后一个“块”上,否则无效。

如何才能使这个地图(或完全不同的地图做同样的事情)处理文件中的所有“块”?

4 个答案:

答案 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>