如何以交互方式按第二个列表的元素替换一个值列表的元素?

时间:2012-09-28 21:33:23

标签: vim

有时写作时我必须连续替换几个不同的单词,比如a1 - > a2,b1-> b2,c1-> c2等。

为此我手动编辑命令历史记录,所以我从

开始
:s/a1/a2/gc

在go之后用b1和b2替换a1和a2,进行替换并继续下一个项目。

我想要的工作流程如下:

:let in = ['a1', 'b1', 'c1']
:let out = ['a2', 'b2', 'c2']
:call ReplaceAllWithConfirmation(in, out)

其中ReplaceAllWithConfirmation将是一个执行替换的函数,但每次都要求我确认。

这可能吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

您不需要编写函数。只需运行此命令:

:%s/[a-c]1/\={'a1':'a2','b1':'b2','c1':'c2'}[submatch(0)]/gc

您可以在\=之后使用表达式。

答案 1 :(得分:2)

对于Tim Pope的Abolish plugin,你的例子就是

%Subvert/{a,b,c}1/{}2/g

答案 2 :(得分:0)

在我提出问题之后,我想出了这个功能和映射几乎可以实现我想要的功能。这并不像其他两个答案那样优雅,但它可以适用于执行一系列通用命令,这些命令由在每个命令之间暂停的列表指定,所以我在这里写。

function! MyLatexReplaceText(...)
  if a:0 > 0
    if a:0 != 2
      echom "provide two lists to the function"
      return ''
    endif
    let g:replace_list_in = a:1
    let g:replace_list_out = a:2
    let g:replace_ncur = 0
  endif
  if a:0 == 0 && !exists("g:replace_ncur")
    let g:replace_list_in = ['a1', 'b1', 'c1']
    let g:replace_list_out = ['a2', 'b2', 'c2']
    let g:replace_ncur = 0
  endif
  if g:replace_ncur == len(g:replace_list_in)
    let g:replace_cmd = ":echom 'reached end of list'\<CR>"
    let g:replace_ncur = -1
  else
    let range_ = "'<,'>"
    let extra_flags = 'gc'
    let g:replace_cmd = ':' .range_ . "s/" .  g:replace_list_in[g:replace_ncur] 
          \ . "/" . g:replace_list_out[g:replace_ncur] . "/" . extra_flags
          \ . "\<CR>"
    call histadd("cmd", g:replace_cmd)
  endif
  let g:replace_ncur += 1
  return g:replace_cmd
endfunction
nnoremap <silent><expr> <Leader>ns MyLatexReplaceText()