Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
vim中的隐藏功能仍然让我在所有角色上移动_Vim - Fatal编程技术网

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

vim中的隐藏功能仍然让我在所有角色上移动,vim,Vim,以下是我所做的 :语法匹配隐藏测试+[A-Z0-9]\{6}+ :设置隐藏级别=2 :设置隐藏光标=nvi 因此,当我在vim中编写123456时,我希望它在那里什么都没有。但当我移动到那个区域上时,实际发生的情况是,我必须沿着我想要移动的方向移动6次,光标才能通过那个区域 有办法解决这个问题吗?我想让维姆看到它,就好像那里什么都没有,当我移动到那个区域时,就好像那里什么都没有。但我仍然希望能够搜索并删除它 目前没有内置的方法来实现这一点。您可以使用synconcealed()确定光标下是否有隐

以下是我所做的
:语法匹配隐藏测试+[A-Z0-9]\{6}+

:设置隐藏级别=2

:设置隐藏光标=nvi

因此,当我在vim中编写
123456
时,我希望它在那里什么都没有。但当我移动到那个区域上时,实际发生的情况是,我必须沿着我想要移动的方向移动6次,光标才能通过那个区域


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

目前没有内置的方法来实现这一点。您可以使用
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)
函数!ForwardSkipConceal(计数)
设cnt=a:count
设mvcnt=0
设c=col(‘.)
设l=直线('.'))
设lc=col(“$”)
let line=getline('.'))
而碳纳米管
如果c>=lc
设mvcnt+=cnt
打破
恩迪夫
如果stridx(&隐藏光标,'n')=-1
设isconcealed=0
其他的
let[isconcealed,cchar,group]=synconcealed(l,c)
恩迪夫
如果是封闭的
设cnt-=strchars(cchar)
设oldc=c
设c+=1

而cZyX的解决方案对我来说并不适用:显然,隐藏文本区域的ID在遍历它时会发生变化,导致运动过早停止

我一直在使用下面粘贴的另一个版本(还有缺少的
BackwardSkipConceal
函数)。在数学文件中取代数学字符在胶乳文档或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)
函数!ForwardSkipConceal(计数)
设cnt=a:count
设mvcnt=0
设c=col(‘.)
设l=直线('.'))
设lc=col(“$”)
let line=getline('.'))
而碳纳米管
如果c>=lc
设mvcnt+=cnt
打破
恩迪夫
如果stridx(&emplaycursor,'n')=-1
设isconcealed=0
其他的
let[isconcealed,cchar,group]=synconcealed(l,c)
恩迪夫
如果是封闭的
设cnt-=strchars(cchar)
设oldc=c
设c+=1
而c
很遗憾,我不认为这个功能存在。如果它没有注册为光标位置,你会用
d{motion}
删除它吗?尽管有隐藏功能,Vim基本上还是一个文本编辑器。该函数的工作方式是每次经过隐藏项时将光标放在行的末尾。我猜这是因为
让lc=col(“$”)
的缘故,而且你永远不会改变它。我测试了这个函数,当我将它放入
let lc=col('6')
时它就可以工作了,所以我接受它,同时我认为我仍然可以使它工作:)编辑:仍然是编写vim函数的新手。@plitter在vim帮助文件上测试时,它没有这样做。它也不应该这样做:
lc
是“最后一列”的缩写:当您可以将光标移过行时,它用于处理
virtualedit
情况,以及隐藏项是行中最后一项时的情况。在这两种情况下,完全没有必要改变它。我不知道您的更改为什么会起作用,但这绝对不是正确的做法,也不会解决任何问题,只是通过创建另一个问题来掩盖一个问题。@plitter Addition:它本来打算做第一个问题。我忘了用
lc
替换
col(“$”)
,现在这样做了。你能说一下你在哪个文件上用哪个语法突出显示测试了它吗?我同意,这对我来说是一个可怕的修复,从我所能说的来看,它只会停止计数器超过6个字符,在我上面的例子中,它应该只移动6个字符。硬编码一个常数只在某些情况下有效。嗯,我又测试了一些,当我将文件类型设置为cpp时,它会执行它应该执行的操作,但是当文件类型未设置时,光标会移动到末尾。几乎!对我来说,隐藏id会更改每个调用,因此我只能依赖synconcealed()中的第一个变量。看到它在这里工作了吗