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()中的第一个变量。看到它在这里工作了吗