使用提示删除包含vim中某些文本的行的有效方法

时间:2017-10-17 03:18:38

标签: vim vi

目前我可以搜索文字

/text

然后使用dd删除行,如果我不想删除,我可以使用n进行下一场比赛。

但是还有更快的方法吗?

下面的命令删除包含文本的所有行,但问题是它一次删除所有行,有时该文本在某行中是异常。

:g/text/d

但我想要像

这样简单的东西
:%s/text/some_other_text/gc

因为这提供了替代或不替换的选项。

3 个答案:

答案 0 :(得分:9)

您不需要全局命令。替换命令本身就足够了

  • 添加通配符
  • 并添加行尾。

示例

%s/.*text.*\n//gc

答案 1 :(得分:8)

您可以混合:help global:help substitute

:g/text/s/.*\n//c

在删除包含text的每一行:

之前,这将要求确认

enter image description here

答案 2 :(得分:3)

我试图找到一种方法来使用global:substitute,并且正确处理连续线上的匹配,并在第一行匹配,但是,唉,我'没有灵感。

所以,我回到我的基础:我已经实现了我认为缺少的东西::confirm global

The result has been pushed in my library plugin

工作原理:

  1. 我准备了一个有状态变量,它记住以前的用户选择(始终退出最后)。
  2. 我对模式执行global,对于每个匹配,我检查用户希望做什么。
    • 我要么使用 don-t-ask-again
    • 或者我要求StatusLineNC + echo "\rmessage"使用:redraw突出显示组。这是我们在Vim 6 IIRC之前做过的一个非常古老的技巧。
  3. 相关代码如下:

    " Function: lh#ui#ask(message) {{{3
    function! lh#ui#ask(message) abort
      redraw! " clear the msg line
      echohl StatusLineNC
      echo "\r".a:message
      echohl None
      let key = nr2char(getchar())
      return key
    endfunction
    
    " Function: lh#ui#confirm_command(command) {{{3
    " states:
    " - ask
    " - ignore
    " - always
    function! s:check() dict abort
      if     self.state == 'ignore'
        return
      elseif self.state == 'always'
        let shall_execute_command = 1
      elseif self.state == 'ask'
        try
          let cleanup = lh#on#exit()
                \.restore('&cursorline')
                \.restore_highlight('CursorLine')
          set cursorline
          hi CursorLine   cterm=NONE ctermbg=black ctermfg=white guibg=black guifg=white
          let choice = lh#ui#ask(self.message)
          if     choice == 'q'
            let self.state = 'ignore'
            let shall_execute_command = 0
            " TODO: find how not to blink
            redraw! " clear the msg line
          elseif choice == 'a'
            let self.state = 'always'
            let shall_execute_command = 1
            " TODO: find how not to blink
            redraw! " clear the msg line
          elseif choice == 'y'
            " leave state as 'ask'
            let shall_execute_command = 1
          elseif choice == 'n'
            " leave state as 'ask'
            let shall_execute_command = 0
          elseif choice == 'l'
            let shall_execute_command = 1
            let self.state = 'ignore'
          endif
        finally
          call cleanup.finalize()
        endtry
      endif
    
      if shall_execute_command
        execute self.command
      endif
    endfunction
    
    function! s:getSID() abort
      return eval(matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_getSID$'))
    endfunction
    let s:k_script_name      = s:getSID()
    
    function! lh#ui#make_confirm_command(command, message) abort
      let res = lh#object#make_top_type(
            \ { 'state': 'ask'
            \ , 'command': a:command
            \ , 'message': a:message . ' (y/n/a/q/l/^E/^Y)'
            \ })
      call lh#object#inject_methods(res, s:k_script_name, 'check')
      return res
    endfunction
    
    " Function: lh#ui#global_confirm_command(pattern, command, message [, sep='/']) {{{3
    " Exemple: to remove lines that match a pattern:
    " > call lh#ui#global_confirm_command(pattern, 'd', 'delete line?')
    function! lh#ui#global_confirm_command(pattern, command, message, ...) abort
      let cmd = lh#ui#make_confirm_command(a:command, a:message)
      let sep = get(a:, 1, '/')
      exe 'g'.sep.a:pattern.sep.'call cmd.check()'
    endfunction
    
    " Function: lh#ui#_confirm_global(param) {{{3
    function! lh#ui#_confirm_global(param) abort
      let sep = a:param[0]
      let parts = split(a:param, sep)
      if len(parts) < 2
        throw "Not enough arguments to `ConfirmGlobal`!"
      endif
      let cmd = join(parts[1:])
      call lh#ui#global_confirm_command(parts[0], cmd, cmd . ' on line?', sep)
    endfunction
    
    command! -nargs=1 ConfirmGlobal call lh#ui#_confirm_global('<args>')
    

    从这里你可以输入:

    • :call lh#ui#global_confirm_command(pattern, 'd', 'delete line?')
    • :ConfirmGlobal/pattern/d会产生不那么有启发性的提示