繁体   English   中英

如何从cnoremap执行命令?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM