[英]How to execute a command from cnoremap?
我想映射<Mo>
以从命令模式快速查找 buflist。
这是一个普通模式映射示例:
nnoremap <M-o> :ls<CR>
这是使用execute()
对命令模式execute()
相同操作的尝试:
cnoremap <M-o> <C-r>=execute(':ls')<CR>
然而,这只是将空格分隔的:ls
结果附加到命令行,实际上没有显示:ls
表的副作用。
有没有办法在不离开命令模式的情况下执行命令?
更新:
我最近使用 Vimscript 破解这个问题的方法如下:
function! RunCmdFromCmdline(cmd)
let l:cmd_line = getcmdline()
echo execute(a:cmd)
return l:cmd_line
endfunction
cnoremap <M-o> <C-\>eRunCmdFromCmdline(':ls')<CR>
echo
使得a:cmd
的结果在屏幕上弹出,但字体不可见。 我尝试以不同的组合使用:redraw <bar>
,但没有成功。
从<Cr>=
或<C-\\>e
提示符中退出命令模式似乎是不可能的。
您可以将当前命令行的内容保存在寄存器中,然后运行ls
并将其粘贴到寄存器中:
cnoremap <esc>o <home>let @x="<end>"<cr>:ls<cr>:<c-r>x
因此,如果命令行如下所示:
:echo 'some'
键入<Mo>
可获得:
:ls
1 %a + "filename" line 1
:echo 'some'
这有效。 它使用全局变量,但可以说这是它们可以接受的用法,因为一次只能使用一个命令行。
function! SaveCmdline()
let g:save_cmdline = getcmdline()
let g:save_cmdpos = getcmdpos()
return ''
endfunction
function! RestoreCmdline()
call setcmdpos(g:save_cmdpos)
return g:save_cmdline
endfunction
cnoremap <M-o> <C-\>eSaveCmdline()<CR>ls<CR>:<C-\>eRestoreCmdline()<CR>
这适用于您在命令行中使用的任何引号或未完成的语法,将完整的命令行和光标恢复到运行命令之前的位置,不会与任何寄存器混淆(仅涉及两个全局变量)并且也不会弄乱命令行历史记录(请参阅q:
command for history。)
它确实有一个小错误,因为当您在其他一些子模式中键入搜索表达式(在/
或?
)时, cnoremap
实际上也可以工作(请参阅getcmdtype()
以获取其中的列表。)如果您使用在那里映射,它将搜索“ls”,然后将您的搜索词恢复为 Ex 命令,哎呀...
您可能可以使用getcmdtype()
来检测它,并且可能只在您输入 Ex 命令时执行操作,而不是在其他模式下。
更新:这修复了最后一部分,仅在 Ex 命令行中执行命令,而不是在搜索或其他上下文中。 它还使插入的命令可参数化。
function! CmdlineExecute(cmd)
if getcmdtype() != ':'
return ''
endif
return "\<C-\>eSaveCmdline()\r".a:cmd.
\ "\r:\<C-\>eRestoreCmdline()\r"
endfunction
cnoremap <expr> <M-o> CmdlineExecute('ls')
(注意这仍然需要上面两个函数的定义。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.