如何在执行ex命令之前使vim的`:global`命令可以确认?

Rod*_*gel 6 vim

如何让vim的:global命令询问用户是否要执行ex命令?:substite与使用'c'选项的命令所发生的情况类似%s:Foo:Fighters:gc

我试过了:

:g/mypattern/.s:.*\n::gc
Run Code Online (Sandbox Code Playgroud)

:g/mypattern/s:.*\n::gc
Run Code Online (Sandbox Code Playgroud)

但是如果在下面的线上有匹配则跳跃.例如:

MATCH
NONMATCH
MATCH

MATCH
MATCH
Run Code Online (Sandbox Code Playgroud)

结果是:

NONMATCH

MATCH  <<-- this should be erased.
Run Code Online (Sandbox Code Playgroud)

提示g/FOO/d是完美的.

Pet*_*ker 5

没有本地方法可以做到这一点。典型的方法是记录一个宏并重复一个宏。确保您n/在宏结束时前进到下一场比赛。跳绳是现在只是n@@执行宏。

自定义:Global命令

但是,如果您真的想要:global使用带有确认的命令,您可以通过confirm()在您的命令中使用来模拟这一点。一般的想法是做这样的事情:

:g/pat/if confirm("&yes\n&no", 2) == 1 | cmd | endif
Run Code Online (Sandbox Code Playgroud)

由于以下原因,这并不完全有效:

  • 你不知道你的光标在哪里。需要像:match:redraw
  • 不会很好地流产。需要一种方法来抛出异常来中止
  • 把这一切都打出来非常笨拙

我想出了以下确认:Global/:G命令

command! -nargs=+ -range=% -complete=command Global <line1>,<line2>call <SID>global_confirm(<q-args>)
command! -nargs=+ -range=% -complete=command G <line1>,<line2>call <SID>global_confirm(<q-args>)
function! s:global_confirm(args) range
  let args = a:args
  let sep = args[0]
  let [pat, cmd; _] = split(args[1:], '\v([^\\](\\\\)*\\)@<!%d' . char2nr(sep), 1) + ['', '']
  match none
  let options = ['throw "Global: Abort"', cmd, '', 'throw "Global: Abort"']
  let cmd = 'exe ''match IncSearch /\c\%''.line(''.'').''l''.@/.''/'''
  let cmd .= '| redraw'
  let cmd .= '| exe get(options, confirm("Execute?", "&yes\n&no\n&abort", 2))'
  try
    execute a:firstline . ',' . a:lastline . 'g'.sep.pat.sep.cmd
  catch /Global: Abort/
  finally
    match none
  endtry
endfunction
Run Code Online (Sandbox Code Playgroud)

注意:按原样使用。用途IncSearch为亮点和力量\c

现在您可以运行:G/foo/d.

自定义:Confirm命令

如果您更愿意使用与@Randy Morris 提供的技术类似的技术,并在执行前使用以下:Confirm {cmd}命令进行确认{cmd}

command! -nargs=+ -complete=command Confirm execute <SID>confirm(<q-args>) | match none
function! s:confirm(cmd)
  let abort = 'match none | throw "Confirm: Abort"'
  let options = [abort, a:cmd, '', abort]
  match none
  execute 'match IncSearch /\c\%' . line('.') . 'l' . @/ . '/'
  redraw
  return get(options, confirm('Execute?', "&yes\n&no\n&abort", 2), abort)
endfunction
Run Code Online (Sandbox Code Playgroud)

这将允许您使用 :g/foo/Confirm d

如需更多帮助,请参阅:

:h @
:h q
:h confirm()
:h :exe
:h get()
:h :match
:h :redraw
Run Code Online (Sandbox Code Playgroud)