[英]How can I delete a YAML section in Vim with a macro/mapping/function?
YAML部分以^---
開頭,沒有任何結尾定界符。 示例文件:
--- a header
data:
key: value
key2: value
--- another header
data:
name:
理想的方法是使用操作符未決的映射(請參閱a。和b。 ),因此您可以刪除,更改或拉緊某個部分。 我的部分可行的解決方案“ ---”映射為:
:onoremap a- :<c-u>execute "normal! ?^--- \r:nohlsearch\rVNk"<cr>
這對於中間部分效果很好,但是在文件的最后部分失敗,因為它找不到后續的標頭匹配項。 我可以修改搜索,以便除了標題文本(搜索/^--- \\|\\%$
或/\\v^--- |%$
)之外,還可以找到文件的末尾,但是錯過了文件的最后一行。 搜索應該向上一行以不選擇后續標題,但是如果到達文件末尾,則不能向上搜索。
一種替代方法是使用/search/offset
功能,但是我不知道是否有一種方法可以對搜索進行分組以找到pattern\\|end
,其中將偏移量應用於成功的pattern
匹配,而不是end
。 由於“在模式上方一行”是/pattern/-1
,因此我希望可以進行以下操作(這是簡化的語法):
/(/header/-1)|end
這可能嗎,還是我需要編寫一個函數來更改選擇? 我還不了解vimscript,因此也歡迎您注意該方向的任何指針。
嘗試這個:
源此功能:
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
創建此地圖:
onoremap <expr> a- GimmeRange()
使用對應的a-
做測試
一個簡單的映射:
:map £ mdG:set paste<CR>o---<Esc>:set nopaste<CR>'d$/---<CR>NedddnGdd
md
:在當前行設置d
標記(被認為屬於要刪除的部分)
G
:轉到文件末尾
:set paste<CR>
:暫時禁用自動縮進( <CR>
通過CTRL-V CTRL-M獲得)
o---<Esc>
:添加由---
組成的新的最后一行(通過CTRL-V ESC獲得<Esc>
)
:set nopaste<CR>
:恢復以前的自動縮進設置
'd$
:轉到d
標記的行尾
/---<CR>N
:轉到要刪除的部分的開頭
dddn
:刪除節標題,然后刪除節正文
Gdd
:刪除最后一行(帶有---
那一行)
如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- :<c-u>let savedSearch=@/\|execute "normal! ?.*\\\zs\\n--- \\\|\\\%$\rjVN"\|let @/=savedSearch<cr>
請注意,當文件以節標題開頭時,此解決方案不起作用,但是YAML則行不通。 這個假設不能移植到其他數據語言中,因此這是編寫函數是更好的解決方案的另一個原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.