我一直在努力开发vim插件一段时间,但已经陷入困境几周了。我是用vimscript编写的,它是()
,{}
,[]
,""
,''
对的简单自动配对程序。当它已经退出时,我一直试图让它跳过结束字符()
,}
,]
)的右边。我现在的重点是让它仅适用于)
,]
,}
字符。
我的问题是我在输入结束字符输入时无法执行该功能。
这是我到目前为止所尝试的内容: 第一次尝试:
inoremap ( ()
inoremap (h ()<LEFT>
inoremap (l ();<RETURN>
inoremap (" ("")<LEFT><LEFT>
inoremap (' ('')<LEFT><LEFT>
inoremap (; ();<DOWN>
inoremap ) call CloseChar()
inoremap [ []
inoremap [h []<LEFT>
inoremap ] call CloseChar()
inoremap { {}
inoremap {h {}<LEFT>
inoremap {<RETURN> {<RETURN><TAB><RETURN><BACKSPACE>}<UP><TAB>
inoremap } call CloseChar()
inoremap " ""
inoremap "h ""<LEFT>
inoremap "l "";<RETURN>
inoremap ' ''
inoremap 'h ''<LEFT>
inoremap 'l '';<RETURN>
function CloseChar()
if matchstr(getline('.'), '\%' . col('.') . 'c.') == '}'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ')'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ']'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '"'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '''
return <RIGHT>
endif
endfunction
第二次尝试:
inoremap ( ()
inoremap (h ()<LEFT>
inoremap (l ();<RETURN>
inoremap (" ("")<LEFT><LEFT>
inoremap (' ('')<LEFT><LEFT>
inoremap (; ();<DOWN>
inoremap ) :call CloseChar()
inoremap [ []
inoremap [h []<LEFT>
inoremap ] :call CloseChar()
inoremap { {}
inoremap {h {}<LEFT>
inoremap {<RETURN> {<RETURN><TAB><RETURN><BACKSPACE>}<UP><TAB>
inoremap } :call CloseChar()
inoremap " ""
inoremap "h ""<LEFT>
inoremap "l "";<RETURN>
inoremap ' ''
inoremap 'h ''<LEFT>
inoremap 'l '';<RETURN>
function CloseChar()
if matchstr(getline('.'), '\%' . col('.') . 'c.') == '}'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ')'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ']'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '"'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '''
return <RIGHT>
endif
endfunction
第三次尝试:
inoremap ( ()
inoremap (h ()<LEFT>
inoremap (l ();<RETURN>
inoremap (" ("")<LEFT><LEFT>
inoremap (' ('')<LEFT><LEFT>
inoremap (; ();<DOWN>
inoremap <silent>) :call CloseChar()
inoremap [ []
inoremap [h []<LEFT>
inoremap <silent>] :call CloseChar()
inoremap { {}
inoremap {h {}<LEFT>
inoremap {<RETURN> {<RETURN><TAB><RETURN><BACKSPACE>}<UP><TAB>
inoremap <silent>} :call CloseChar()
inoremap " ""
inoremap "h ""<LEFT>
inoremap "l "";<RETURN>
inoremap ' ''
inoremap 'h ''<LEFT>
inoremap 'l '';<RETURN>
function CloseChar()
if matchstr(getline('.'), '\%' . col('.') . 'c.') == '}'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ')'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ']'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '"'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '''
return <RIGHT>
endif
endfunction
最后一次尝试:
inoremap ( ()
inoremap (h ()<LEFT>
inoremap (l ();<RETURN>
inoremap (" ("")<LEFT><LEFT>
inoremap (' ('')<LEFT><LEFT>
inoremap (; ();<DOWN>
inoremap [ []
inoremap [h []<LEFT>
inoremap { {}
inoremap {h {}<LEFT>
inoremap {<RETURN> {<RETURN><TAB><RETURN><BACKSPACE>}<UP><TAB>
inoremap " ""
inoremap "h ""<LEFT>
inoremap "l "";<RETURN>
inoremap ' ''
inoremap 'h ''<LEFT>
inoremap 'l '';<RETURN>
function CloseChar()
if matchstr(getline('.'), '\%' . col('.') . 'c.') == '}'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ')'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == ']'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '"'
return <RIGHT>
elseif matchstr(getline('.'), '\%' . col('.') . 'c.') == '''
return <RIGHT>
endif
endfunction
call CloseChar()
而不是CloseChar()
被执行,而是插入新的)
,]
,}
。解决方案的来源我引用了learnvimscriptthehardway和Five Minute Vimscript;以及一些stackoverflow帖子(我没有足够的声誉来链接我找到的所有相关论坛和文章,抱歉)。
所以,基本上,我陷入困境,正在寻求帮助来修复我的插件,以便它可以正常工作。
注意: 不知道它是否有很大的不同,但我通过Windows子系统Linux(wsl)使用vim。
答案 0 :(得分:0)
我正在考虑 首次尝试 这项有效的改进:
inoremap ( ()
inoremap (h ()<LEFT>
inoremap (l ();<RETURN>
inoremap (" ("")<LEFT><LEFT>
inoremap (' ('')<LEFT><LEFT>
inoremap (; ();<DOWN>
inoremap ) <Esc><RIGHT>:call CloseChar()<cr>i
inoremap [ []
inoremap [h []<LEFT>
inoremap ] <Esc><RIGHT>:call CloseChar()<cr>i
inoremap { {}
inoremap {h {}<LEFT>
inoremap {<RETURN> {<RETURN><TAB><RETURN><BACKSPACE>}<UP><TAB>
inoremap } <Esc><RIGHT>:call CloseChar()<cr>i
inoremap " ""
inoremap "h ""<LEFT>
inoremap "l "";<RETURN>
inoremap ' ''
inoremap 'h ''<LEFT>
inoremap 'l '';<RETURN>
function! CloseChar()
if matchstr(getline('.'), '\%' . col('.') . 'c.') =~# '\v\)|]|"|''|}'
normal! l
endif
endfunction
答案 1 :(得分:0)
您最初的问题是您尝试从插入模式映射调用函数而不进入允许调用该函数的模式。它无法运作。
最好的方法是让inoremap-<expr>
返回您输入的内容或<right>
(实际上,您希望返回<c-g>U<right>
以支持重做)如果光标下的字符与您刚键入的键相同。
请注意,使用<esc>
+ i
进行游戏会产生太多副作用。我喜欢<c-o>
,甚至更好inoremap-<expr>
。
此外,如果您映射(
和(;
(IOW,只是一个键,并且此键同后使用其他任何键),您将观察不会立即触发的映射,但超时后。在对括号主题进行了多次实验之后(我已经保持mappings已经发展了近20年),我的结论是:只有一个以括号开头字符开头的映射,以及尽可能多的上下文映射需要在括号之间插入换行符,或者关闭所有打开的括号,或者关闭所有打开的括号并附加一个分号,依此类推。