gvim脚本无法正常使用删除

时间:2017-08-13 05:39:31

标签: vim

function! Reduce()
    let ls=getpos("'<")
    let lsp=ls[1]
    let tvar = '\<' . @*
    echom tvar

    for i in range(1,30)
      let ssv=getline(lsp+i-1) 
      let t1=matchstr(ssv,tvar)
      echom t1
      if t1 =~ @*
        echom ssv
        delete
      endif
    endfor
endfun
你可以用上面的脚本帮我吗? 这个脚本有什么问题.. 如果我删除if条件,只需打印ssv。它用匹配打印所有30个字符串 但是当我把删除命令 - 它只匹配几个字符串。 尝试和验证相同的行为&#34;正常! DD&#34;取代&#34;删除&#34;命令也是如此。

2 个答案:

答案 0 :(得分:2)

您在getline循环中使用fori作为相对行号。并删除循环中的行。这里发生的是:

line1
line2 <- i = 2
line3
line4

删除第2行:

line1
line3 <- i = 2
line4

然后for循环增加i

line1
line3
line4 <- i = 3

所以下一个处理过的行是line4,而不是您期望的line3

要解决从末尾到开头的删除行,即反向运行range

for i in range(30, 1, -1)

答案 1 :(得分:1)

正如phd所说,你需要改变你的迭代方向。

出于表演原因,我倾向于避免在这里使用循环。如果你有成千上万行(我知道,你只有30 ......),你就会发现它们有所不同。

我会这样写(如果我需要比:delete更复杂的东西):

" untested
let first_line = line("'<")
" 1- extract all lines in the range
let lines= getline( first_line, first_line+30) " or 29 ?
" 2- convert lines into line numbers, or -1 if not matching
let matching_line_nrs = map(lines, 'match(v:val, tvar)>=0 ? v:key : -1')
" 3- keep the positive ones
call filter(matching_line_nrs, 'v:val > 0')
" 4- and finally remove the matching lines, in reserve order
" NB: I though there was a deleteline() function, but couldn't find any
" trace of it, hence execute(linenr.'delete')
call map(reverse(matching_line_nrs), 'execute(v:val."delete")')

与本机(并且效率极高)相比,这是非常复杂的

:exe "'<".',+29g/\<'.@*.'/d'

或者,以交互方式输入

 :'<,+29g/\<^R*/d_
 " With ^R being CTRL-R