2013-11-24 40 views
2

最近我一直在玩vim宏(目前在MacVim中),有時候我喜歡用一個宏來明確地將一個宏分配到一個寄存器中。 :let @a='(macro keystrokes)'。這通常工作正常,但我發現一個奇怪的行爲,其中任何時候我分配一個字符串值結束於回車/^M,vim自動添加一個換行/^J到結束之前將其放入該寄存器,影響宏的執行!例如:假設我記錄了一個進入插入模式的簡單宏,類型爲「hey」,從插入模式轉義出來,然後觸擊Enter兩次,向下拖動兩行。我記錄到這個寄存器@a通過鍵入qaihey<Escape><Enter><Enter>q,存儲在@a如下:如何將結尾爲<CR>的字符串分配給vimscript變量而不添加<LF>?

ihey^[^M^M 

到目前爲止好,並通過鍵入@a執行宏不正是它應該。另一個非常好的方法是,我可以將這個宏寫入寄存器@a,將整個事物(ihey<Ctrl-V><Escape><Ctrl-V><Enter><Ctrl-V><Enter>)輸入到緩衝區,然後用"ay將其排序 - 最終結果是一樣的。但這裏的奇怪的事情 - 假設我只是想這個字符串直接使用let語句給到@a:

:let @a='ihey^[^M^M' 

現在,如果我輸入:reg看值,它說有在年底額外^J出於某種原因:

"8  ... 
"9  ... 
"a  ihey^[^M^M^J 
"b  ... 

有額外^J導致它,當我執行宏往下走一個額外的行,所以它實際上改變的行爲。

有人知道爲什麼這個額外的字符被添加?任何人都知道我可以如何獲得以^M結尾的字符串值到一個寄存器(或任何變量)中,而不需要額外添加^J

回答

6

一些快速檢查vim的幫助文件這樣說:

:let @{reg-name} = {expr1}   *:let-register* *:[email protected]* 

... 
If the result of {expr1} ends in a <CR> or <NL>, the 
register will be linewise, otherwise it will be set to 
characterwise. 

換句話說,結束了回車字符串,Vim將它解釋爲結束的行


快速谷歌搜索從VimTips維基給this

但請注意,上述方法使用:let將無法按預期方式工作,因爲您以任何以< CR>或< NL>字符(回車或換行符)結尾的宏。這是因爲,如在help:let- @中所記錄的,Vim會在這些條件下將寄存器視爲「linewise」。其原因是使寄存器設置爲:在處理被抽出/刪除的文本時,讓它採取「正確的方式」,但是在處理記錄的宏時可能會引起頭痛。可能的解決方法包括使用setreg()函數或在宏的末尾添加「no-op」命令,例如< ESC>。有關詳細信息,請參閱有關vim_dev關於:let命令的意外行爲的討論。

所以,你有幾個選擇:使用setreg()或添加某種無操作序列(< ESC>)的字符串當您使用let

+0

太棒了!感謝您迅速而全面的回答。 – murftown

相關問題