情况#1:我刚刚选择了一个文本块.然后我输入“:Command”,它会调用一些函数.
情况#2:目前没有视觉选择(尽管我之前在编辑会话中做过这样的选择).我输入“:Command”,它调用(相同的)函数.
是否有(强大的)方法将上述两种情况与功能区分开来?我尝试了mode(),但问题是在两种情况下我都处于命令模式,虽然在第一种情况下我从视觉模式进入命令模式,而在第二种情况下我从正常模式进入.也许通过检查a:firstline / a:lastline / v:count?
更新 – 用例示例:“:Sum”.如果存在当前视觉选择,例如,一列数字(块选择)或仅包含数字的一系列行,则该命令将回显数字的总和.否则,它需要一个以空格分隔的数字列表作为参数,并将回显这些数字的总和.基本框架:
command! -nargs="*" -range Sum :call CalcSum(<f-args>) function! CalcSum(...) range " 1. collect numbers from visual selection if there is a current active selection " 2. otherwise,if len(args) > 0,collect numbers from args " 3. other cases (i.e.,no selection and no args or both selection and args) handled reasonably " 4. sum collection of numbers " 5. return/echo result endfunction
步骤(2) – (5)是直截了当的.我遇到麻烦(1).我使用“<”/“>”用于重新创建的标记从视觉选择中收集数字.但是,如果当前突出显示/活动的视觉选择,我只想这样做.
如果你需要使用命令,我看到的唯一方法是检查:firstline / a:lastline:
" Assuming that you have passed -range=% when defining command if a:firstline==1 && a:lastline==line('$') " Do something endif
但是当你选择整个缓冲区时,这并不成立.我建议你使用表达式映射:
function DoCommand() if mode()!~#"^[vV\<C-v>]" " Do something. For example,set global variable (and unset it in :Command) endif return ':Command' endfunction noremap <expr> {lhs} DoCommand()
更新:可视模式在命令模式下从不活动.决不.仅仅因为命令模式不是可视模式.使用映射是实现所需内容的唯一方法,这里有两种方法:对所有模式使用完全相同的expr映射,并在此表达式中的某处检查mode(),或者为不同模式定义不同的映射,并使用这些差异来判断从什么模式调用它.