如何使用宏/映射/函数删除Vim中的YAML节?
YAML部分以如何使用宏/映射/函数删除Vim中的YAML节?,vim,yaml,Vim,Yaml,YAML部分以^-开头,没有任何结尾分隔符。示例文件: --- a header data: key: value key2: value --- another header data: name: 理想的方法是使用运算符挂起映射(请参见和),这样您就可以删除、更改或拖动一个节。我的部分工作解决方案“环绕---”映射是: :onoremap a- :<c-u>execute "normal! ?^--- \r:nohlsearch\rVNk"<cr>
^-
开头,没有任何结尾分隔符。示例文件:
--- a header
data:
key: value
key2: value
--- another header
data:
name:
理想的方法是使用运算符挂起映射(请参见和),这样您就可以删除、更改或拖动一个节。我的部分工作解决方案“环绕---”映射是:
:onoremap a- :<c-u>execute "normal! ?^--- \r:nohlsearch\rVNk"<cr>
这是可能的,还是我需要编写一个函数来更改选择?我还不知道vimscript,所以任何指向该方向的指针都会很感激。使用Kent建议的函数更干净、更易于维护,但我能够修改原始映射,并将其发布在这里以确保完整性 igemnace给了我一些关于vim IRC聊天的建议。关键的一点是,我可以通过在搜索中包含
\n
来搜索以文件结尾的行(而不是文字换行符)。接下来,我需要更改运动字符,因为匹配会提前一行开始。我们需要从上一场比赛(j)往下走一条线,而不需要从下一场比赛(k)往上走。最后,需要使用\zs
修改搜索匹配区域,以便如果光标位于标题前的行上,vim不会认为光标与匹配重叠。在这种情况下,这将导致编辑删除错误的部分。逻辑是:
- 向后搜索
*\zs\n----\\\\%$
- 排队
- 视觉选择,直到下一个较低的匹配
:onoremap a- :<c-u>execute "normal! ?.*\\\zs\\n--- \\\|\\\%$\r:nohlsearch\rjVN"<cr>
:onoremap a-:执行“正常!?\\\\\zs\\n--\\\\\\\\\\%$\r:nohlsearch\rjVN”
但我不想让映射擦除我的搜索缓冲区,所以我保存并还原了它:
:onoremap a- :<c-u>let savedSearch=@/\|execute "normal! ?.*\\\zs\\n--- \\\|\\\%$\rjVN"\|let @/=savedSearch<cr>
:onoremap a-:let savedSearch=@/\\\执行“正常”?.\\\\\zs\\n----\\\\\\\\\\\\%$\rjVN“\\\\\\\\\\/=savedSearch
请注意,当文件以节头开头时,此解决方案不起作用,但YAML从不起作用。这种假设不适用于其他数据语言,因此这也是为什么编写函数是更好的解决方案的另一个原因。尝试以下方法:
来源:此函数:
function! GimmeRange() abort
let pat = '^--- \|\%$'
let start = search(pat, 'b')
let end = search(pat)
let end = end == line('$')? end:end-1
return ":\<c-u>exec 'normal! ".start.'GV'.( end-start )."+'\<CR>"
endfunction
函数!GimmeRange()中止
让pat='^-\\\%$'
让我们开始=搜索(轻拍“b”)
让结束=搜索(pat)
让end=end==line(“$”)?完:完一
return:“\exec'normal!”.start'GV.”(end-start)。“+”
端功能
创建此地图:
onoremap <expr> a- GimmeRange()
onoremap a-GimmeRange()
使用OMapa-
一个简单的映射进行测试:
:map £ mdG:set paste<CR>o---<Esc>:set nopaste<CR>'d$/---<CR>NedddnGdd
:map.%mdG:set pasteo---:set nopaste'd$/--neddngdd
:在当前行上设置md
标记(指定为属于要删除的节)d
:转到文件末尾G
:临时禁用自动缩进(:设置粘贴
通过CTRL-V CTRL-M获得)
:添加由o--
组成的新的最后一行(--
通过CTRL-V ESC获得)
:恢复以前的自动缩进设置:设置nopaste
:转到'd$
标记行的末尾d
:转到要删除的节的开头/--N
:删除节头,然后删除节体dddn
:删除最后一行(带有Gdd
的那一行)--
--
,以便正确处理最后一个部分?@mouviciel在映射中这样做并在之后将其删除会很困难。手动操作意味着另外两个步骤,我可能会把事情搞砸。我想尽量减少潜在的错误。谢谢!我已经找到了如何在在IRC社区的帮助下,我使用了纯映射,但我的方法很荒谬。你的解决方案更好,甚至不需要我隐藏/恢复搜索缓冲区。
:map £ mdG:set paste<CR>o---<Esc>:set nopaste<CR>'d$/---<CR>NedddnGdd