2010-07-26 30 views
67

我想在選擇的每一行上運行一個宏,而不是累計我腦海中的行數。舉例來說,我可能會寫一個宏來變換:每一行視覺選擇上的Vim宏

Last, First 

進入

First Last 

,我想它在所有這些線路運行:

Stewart, John 
Pumpkin, Freddy 
Mai, Stefan 
... 

任何想法Vim的大師?

編輯︰這只是一個例子,顯然這是trivialy正則表達式,但也有其他實例,不太容易,我寧願使用宏。

+1

說實話,我可能會做的regex這個特殊的任務。但這個問題對於更復雜的案例仍然有效。 – 2010-07-26 18:50:28

+0

爲什麼選擇vim?在我看來,sed更爲貼心。 – kokosing 2010-07-26 18:54:00

+7

@kogut:爲什麼退出編輯器以一行正則表達式編輯文本? – Stephen 2010-07-26 18:56:24

回答

124

假設你有一個宏q跑(並保持)在單一線。然後,你可以在你的選擇與每行上運行:

:'<,'>normal @q 

(如果你已經有一組線,打:在命令行上產生:'<,'>

例如,下面的宏大寫的每一個字,但在第一上一行:

:let @q="^dwgU$P" 

所以運行它在以下(其中+線被選擇)

0000: a long long time ago 
0001: in a galaxy far away 
+0002: naboo was under an attack 
+0003: and i thought me and qui-gon jinn 
+0004: could talk the federation in 
0005: to maybe cutting them a little slack. 

通過上述normal @q命令,產生:

0000: a long long time ago 
0001: in a galaxy far away 
0002: naboo WAS UNDER AN ATTACK 
0003: and I THOUGHT ME AND QUI-GON JINN 
0004: could TALK THE FEDERATION IN 
0005: to maybe cutting them a little slack. 
+6

':let @q =「^ wgU $」' – 2010-07-27 10:05:27

+0

@Roger Pate:嗯,是的,如果你想打高爾夫球:) – rampion 2010-07-27 13:15:20

+0

@rampion:你的命令是否有錯字?對我來說它只能這樣工作: ':'<,'>正常! @ q' – oliver 2011-07-23 15:29:40

12

選擇線條然後按:進入命令模式。 Vim將自動填寫'<,'>,這將範圍限制爲選定的行。爲了您的例子中,你可以使用:s命令執行交換:

:'<,'>s/\(\w\+\), \(\w\+\)/\2, \1/ 

這將換用逗號在視覺選擇每行分隔的兩個單詞。

與其他書籤或行位置一樣,您也可以使用'<'>。作爲移動命令的一部分,因此在正常模式下,d'<將從當前光標位置刪除到視覺選擇中第一行的開頭。即使該塊不再被直觀地突出顯示,標記仍然有效。

如果要在每一行上重放錄製的宏,則需要使用:normal命令執行宏。不幸的是,:normal命令不能在一系列行上運行,但可以使用:global命令修復該命令。這將運行在每一個正則表達式匹配線的:ex命令,所以你可以這樣做:

:'<,'>g/^/ norm @a 

說明:

:'<,'>  for every line in the visual block 
g/^/   on every line that matches the regex /^/ - i.e. every line 
norm   run in normal mode 
@a   the macro recorded in a 
+1

':help:normal-range' – 2010-07-27 10:08:35

+0

這比接受的答案要好,因爲它支持添加新行的宏。 – 2017-06-30 09:12:55

+0

[@Dave,Kirby](https://stackoverflow.com/users/206417/dave-kirby)也許最好是用'.'交換'^',以使宏只在包含一些文本的行上運行,不會? – SergioAraujo 2017-09-23 18:02:58

0

您可以添加以下的功能,以您的~/.vimrc或者乾脆將它複製到你的瀏覽器,並運行:@+

fun! RunMacroOverSelection(macroname) 
    execute "'<,'>normal @". a:macroname 
endfun 
com -nargs=1 Rover :call RunMacroOverSelection(<f-args>) 
nnoremap <leader>r :Rover<space> 

的優點是,你可以在視覺選擇上應用任何宏。 你需要給宏信作爲參數,如:

:Rover a