为何Vim命令normal! VG:center无法正常执行?
Vim函数中
normal! VG:center<cr>无法生效的原因与解决方法 问题描述
我正在为Vim编写一个简单的仪表盘,尝试居中文本时遇到问题。手动依次输入VG选中文本后执行:center命令可正常生效,但在函数中使用normal! VG:center<cr>命令却毫无作用。相关代码如下:
function! DoSomethingIfNoArgs() if argc() return endif " Start a new buffer ... enew " ... and set some options for it setlocal \ textwidth=174 \ bufhidden=wipe \ buflisted \ nocursorcolumn \ nocursorline \ nolist \ nonumber \ norelativenumber \ noswapfile " Now we can just write to the buffer, whatever you want. call append('.', ["", \ "", \ "", \ "", \ " | |", \ " | ████ ██████ █████ ██ |", \ " | ███████████ █████ |", \ " | █████████ ███████████████████ ███ ███████████ |", \ " | █████████ ███ █████████████ █████ ██████████████ |", \ " | █████████ ██████████ █████████ █████ █████ ████ █████ |", \ " | ███████████ ███ ███ █████████ █████ █████ ████ █████ |", \ " | ██████ █████████████████████ ████ █████ █████ ████ ██████ |", \ " ", \ " ", \ " "]) normal! VG:center<cr> " No modifications to this buffer setlocal nomodifiable nomodified " When we go to insert mode start a new buffer, and start insert nnoremap <buffer><silent> e :enew<CR> nnoremap <buffer><silent> i :enew <bar> startinsert<CR> nnoremap <buffer><silent> o :enew <bar> startinsert<CR> endfunction autocmd VimEnter * call DoSomethingIfNoArgs()
原因分析
- 命令作用范围不匹配:执行
append('.', ...)后光标停留在第一行,VG选中从当前行到最后一行的内容,但在非交互脚本中,:center作为Ex命令默认仅作用于当前行,不会自动识别可视选中区域。 - 命令写法错误:
normal!中执行Ex命令的方式有误,:center<cr>无法正确触发可视模式下的批量居中操作。
解决方法
方法一:直接针对全缓冲区执行:center(推荐)
不需要可视模式选中,用范围符号%指定整个缓冲区执行:center,替换原normal! VG:center<cr>行:
%s:center
%等价于1,$,代表从第1行到最后一行的所有内容。
方法二:正确结合可视模式执行命令
如果坚持用可视模式的方式,需要在选中内容后,用:normal命令对选中区域的每一行执行居中操作:
normal! VG:normal center<cr>
解释:VG进入可视行模式选中内容后,:normal会将后续的center命令(普通模式下的居中操作)应用到选中的每一行。
替换上述任意一种写法后,函数执行时文本即可正常居中。
内容的提问来源于stack exchange,提问作者Liam Bunyan
相关产品推荐
相关产品推荐

