您可以在Ex模式下以编程方式执行普通模式命令,通过执行normal,例如
:execute "normal" "iNEWTEXT\<Esc>0"
切换到插入模式(i),写入&#34; NEWTEXT&#34;,转到正常模式(\&lt; Esc&gt;),然后移动到行的开头(0)。
但是,使用非常量字符串(寄存器或变量),行为是不同的。例如,假设您在任何文件(不一定是vimscript文件)中的行上保存了相同的命令:
iNEWTEXT\<Esc>0
然后,您可以通过"zy$
将文本复制到任何寄存器(此处为z),并通过@z
执行注册。但这一次,输出是不同的:
NEWTEXT\<Esc>0
进入插入模式后,Escape不再被视为特殊字符,而是按字面意思进行处理。其他形式如\ e也不起作用。有没有解决的办法?
编辑:使用Ingo的答案,我创建了以下功能。基本上,用于将一组普通/插入命令嵌入文件的文本中,并且能够执行它们。更常见的是,running Ex commands from a line of text使用了类似的东西,但我找不到任何能为普通模式和插入模式做到这一点的东西。
因此,您的文件中包含以下文字:
jy10j10jpO\<Esc>jEll
当在该行上时,您可以调用该函数或重新映射,并执行命令(在此示例中,复制和粘贴10行,并移动超过第一个单词的2列)。 Ingo的替代方案更适合严肃使用,即从其他文件中获取命令,在.vimrc中使用命令,或者使用特定于文件类型的选项。由会话保存的宏也可以正常工作,并且比在整个文件中分散命令更实用。在我的情况下,我正在同步多个设备,并且不想使用这个非常具体的命令来创建另一个文件或使我的vimrc混乱,但是并不介意将这个特定文件本身弄得乱七八糟。把它想象成一个便携式宏。
" Execute current line as Vim normal mode commands.
nnoremap <A-y> :call EvaluateLineAsNormalModeCmd()<CR>
function! EvaluateLineAsNormalModeCmd()
let g:getCurrentLine = getline(".")
"have to :execute twice: once to get the contents of the
"register inserted into a double-quoted string, and then once for
"the :normal to evaluate the string.
execute 'execute "normal" "' . g:getCurrentLine . '"'
endfunction
EDIT2 / 3:这是使用Christian Brabandt的答案的两个功能。它们的工作方式大致相同,但最终可以将用户置于插入模式(而根据我的最小信息,在其他上下文中,我认为是不完整的命令而不执行,并且:startinsert可以& #39; t在那种情况下使用)。 PS:请不要问我所有单引号和双引号都在做什么,因为我无法绕过它O_o
function! EvaluateLineAsNormalModeCmd()
normal! 0y$
execute ':call feedkeys("'.@".'", "t")'
endfunction
function! EvaluateLineAsNormalModeCmd()
let g:getCurrentLine = getline(".")
execute ':call feedkeys("'.g:getCurrentLine.'", "t")'
endfunction
答案 0 :(得分:4)
如果你确实需要这个(用例是可疑的),你必须:execute
两次:一次将寄存器的内容插入一个双引号字符串,然后一次用于{{1评估字符串。
:normal
PS:请提供更多背景;你的最终目标是什么?当一个问题只是一个小技术步骤时,很难提供一个好的答案。如果你没有告诉我们为什么你想要这个,那么很容易屈服于XY problem。
答案 1 :(得分:1)
我宁愿使用feedkeys()
函数。例如。对于您的样本,这应该有效:
exe ':call feedkeys("'.@".'", "t")'
(如果你将你的行拉入未命名的寄存器,否则相应地调整寄存器名称)。请注意,引用可能会变得难看。
要了解发生了什么,这就是做了什么:
exe ':call feedkeys(' - First part of the feedkeys() function call
" - Start of Quote for the first argument
. - String concatenation
@" - content of the unnamed register
. - String concatenation
' - Start of second part of the feedkeys function call
" - End of Quote for the first argument
, "t")' - Second argument of feedkeys() function call
你也可以分两步完成:
exe ':let a="'. @". '"' - Also needs to quote @" correctly.
call feedkeys(a, 't')
应该更容易理解。 exe调用只是将规范化的键表示法转换为文字键。