vim中的隐藏功能仍然让我移动到所有角色

时间:2012-09-12 22:40:25

标签: vim

这是我做的事 :syntax match conceal Test +[A-Z0-9]\{6}+
:set conceallevel=2
:set concealcursor=nvi
所以,当我在vim中写123456时,我希望它不存在。但是当我移动到那个区域时实际发生的事情是我必须朝着我想要移动的方向移动6次以使光标通过该区域。

有办法解决这个问题吗?我希望vim看到它好像什么都没有,当我移动到那个区域时,它就像那里什么都没有。但我仍然希望能够搜索并删除它。

2 个答案:

答案 0 :(得分:9)

目前没有内置方法可以做到这一点。您可以使用synconcealed()来确定光标下是否隐藏了字符,隐藏了什么,并重新映射所有移动键以尊重它:像这样:

function! ForwardSkipConceal(count)
    let cnt=a:count
    let mvcnt=0
    let c=col('.')
    let l=line('.')
    let lc=col('$')
    let line=getline('.')
    while cnt
        if c>=lc
            let mvcnt+=cnt
            break
        endif
        if stridx(&concealcursor, 'n')==-1
            let isconcealed=0
        else
            let [isconcealed, cchar, group]=synconcealed(l, c)
        endif
        if isconcealed
            let cnt-=strchars(cchar)
            let oldc=c
            let c+=1
            while c<lc && synconcealed(l, c)[2]==group | let c+=1 | endwhile
            let mvcnt+=strchars(line[oldc-1:c-2])
        else
            let cnt-=1
            let mvcnt+=1
            let c+=len(matchstr(line[c-1:], '.'))
        endif
    endwhile
    return ":\<C-u>\e".mvcnt.'l'
endfunction
nnoremap <expr> l ForwardSkipConceal(v:count1)

。注意:这适用于单个动作(l)并且在正常模式下,只是为了显示它可以完成的方式。

答案 1 :(得分:4)

上面的ZyX解决方案对我不起作用:显然隐藏文本区域的ID在遍历时会发生变化,导致动作过早停止。

我一直在使用下面粘贴的备用版本(也包含缺少的BackwardSkipConceal功能)。它不漂亮,但在LaTeX文档或C ++代码中替换数学字符时效果很好。

function! ForwardSkipConceal(count)
    let cnt=a:count
    let mvcnt=0
    let c=col('.')
    let l=line('.')
    let lc=col('$')
    let line=getline('.')
    while cnt
        if c>=lc
            let mvcnt+=cnt
            break
        endif
        if stridx(&concealcursor, 'n')==-1
            let isconcealed=0
        else
            let [isconcealed, cchar, group] = synconcealed(l, c)
        endif
        if isconcealed
            let cnt-=strchars(cchar)
            let oldc=c
            let c+=1
            while c < lc
              let [isconcealed2, cchar2, group2] = synconcealed(l, c)
              if !isconcealed2 || cchar2 != cchar
                  break
              endif
              let c+= 1
            endwhile
            let mvcnt+=strchars(line[oldc-1:c-2])
        else
            let cnt-=1
            let mvcnt+=1
            let c+=len(matchstr(line[c-1:], '.'))
        endif
    endwhile
    return ":\<C-u>\e".mvcnt.'l'
endfunction

function! BackwardSkipConceal(count)
    let cnt=a:count
    let mvcnt=0
    let c=col('.')
    let l=line('.')
    let lc=0
    let line=getline('.')
    while cnt
        if c<=1
            let mvcnt+=cnt
            break
        endif
        if stridx(&concealcursor, 'n')==-1 || c == 0
            let isconcealed=0
        else
            let [isconcealed, cchar, group]=synconcealed(l, c-1)
        endif
        if isconcealed
            let cnt-=strchars(cchar)
            let oldc=c
            let c-=1
            while c>1
              let [isconcealed2, cchar2, group2] = synconcealed(l, c-1)
              if !isconcealed2 || cchar2 != cchar
                  break
              endif
              let c-=1
            endwhile
            let c = max([c, 1])
            let mvcnt+=strchars(line[c-1:oldc-2])
        else
            let cnt-=1
            let mvcnt+=1
            let c-=len(matchstr(line[:c-2], '.$'))
        endif
    endwhile
    return ":\<C-u>\e".mvcnt.'h'
endfunction

nnoremap <expr> l ForwardSkipConceal(v:count1)
nnoremap <expr> h BackwardSkipConceal(v:count1)