如何在Vim中便捷选中Markdown围栏代码块内的全部内容?
如何在Vim中便捷选中Markdown围栏代码块内容?
Vim原生没有针对Markdown围栏代码块的内置文本对象(类似vip或vi{),但我们可以通过自定义映射实现同样便捷的操作,以下是两种实用方案:
方案一:基础映射快速实现
在你的~/.vimrc(Neovim用户为~/.config/nvim/init.vim)中添加以下配置:
" 选中代码块内部内容(不含上下的```,对应vi{逻辑) xnoremap ic :<C-u>execute "normal! ?```\<CR>jvg_/```\<CR>k"<CR> onoremap ic :normal vic<CR> " 选中整个代码块(包含上下的```,对应va{逻辑) xnoremap ac :<C-u>execute "normal! ?```\<CR>vg_/```\<CR>"<CR> onoremap ac :normal vac<CR>
用法
- 光标在代码块内部时,按下
vic即可一键选中代码块内的全部内容,和你之前手动操作的结果一致。 - 若要选中包含上下围栏线的整个代码块,按下
vac即可。 - 支持操作符模式,比如
dic可直接删除代码块内部内容,yic可复制内部内容,和原生文本对象的使用逻辑完全一致。
方案二:健壮函数实现(支持带语言标识的围栏)
如果你的代码块带语言标识(比如```python),基础映射可能出现匹配问题,这时可以用searchpair()函数实现精准匹配:
function! MarkdownCodeBlockInner() abort let s:start_line = searchpair('```', '', '```', 'bW') if s:start_line == 0 return endif call cursor(s:start_line + 1, 1) let s:end_line = searchpair('```', '', '```', 'W') normal! v call cursor(s:end_line - 1, col('$')) endfunction function! MarkdownCodeBlockOuter() abort let s:start_line = searchpair('```', '', '```', 'bW') if s:start_line == 0 return endif call cursor(s:start_line, 1) let s:end_line = searchpair('```', '', '```', 'W') normal! v call cursor(s:end_line, col('$')) endfunction " 映射到文本对象 xnoremap ic :<C-u>call MarkdownCodeBlockInner()<CR> onoremap ic :<C-u>call MarkdownCodeBlockInner()<CR> xnoremap ac :<C-u>call MarkdownCodeBlockOuter()<CR> onoremap ac :<C-u>call MarkdownCodeBlockOuter()<CR>
这个版本会自动忽略围栏后的语言标识,精准匹配成对的代码块,适用性更强。
内容的提问来源于stack exchange,提问作者yhd.leung
相关产品推荐
相关产品推荐

