2012-02-02 55 views
4

每一行的開頭誰能告訴我如何做到這一點的映射相反在Vim中:減半空格的數量在Vim的

nnoremap <leader>iw :let [email protected]/<Bar>:let _s2=line(".")<Bar>:%s/^\s*/&&/ge<Bar>:let @/=_s<Bar>:nohl<Bar>exe ':'._s2<CR> 

由於澄清,這種映射雙打(&&部分)的數量在每行開始處的空格。 只有第一個常規字符之前的空格纔會受到影響。 保留當前搜索字符串(變量_s)。 此轉換後位置恢復(變量_s2

所以基本上我正在尋找一個映射,如果它們被一個接一個地執行,將會撤銷這個映射。

我在計算如何限制這個新操作只能在第一個常規字符之前的空格上工作時遇到了問題。

回答

5

下面的替代命令反轉其對應 加倍前導空格的效果。

:%s/^\(\s*\)\1/\1/ 

映射到被構造爲這個命令需要遵循相同 圖案如問題語句中使用(除了 取代來執行,當然)之一。爲了減少 定義重複,一個可以將狀態保持代碼分離成小 功能:

nnoremap <silent> <leader>> :call Preserve('%s/^\s*/&&/')<cr> 
nnoremap <silent> <leader><lt> :call Preserve('%s/^\(\s*\)\1/\1/')<cr> 
function! Preserve(cmd) 
    let [s, c] = [@/, getpos('.')] 
    exe a:cmd 
    let @/ = s 
    call setpos('.', c) 
endfunction 
+0

美麗!我嘗試過這樣的事情,但我不知道你可以在第一個替代塊中使用'\ 1'。簡單而有效! – 2012-02-03 07:56:59

+0

@PrinceGoulash:謝謝!它有點習慣於模式。您可能已經注意到了一個非凡的例子,它是可用於測試非負整數是否爲素數的正則表達式。在Vim腳本中,測試看起來像'repeat'('1',n)!〜'^ 1 \?$ \ |^\(1 \ { - 2,} \)\ 1 \ + $'', n'是有問題的數字。 – 2012-02-03 09:17:18

+0

謝謝,這真是優雅的解決方案。 – 2012-02-03 18:05:02

2

你原有的替換是這樣(我與#的可讀性取代/分隔符):

%s#^\s*#&&# 

這裏是我提出的反替代(深呼吸......):

%s#^\s*#\=matchstr(submatch(0),'^.\{'.string(float2nr(len(submatch(0))/2)).'\}')# 

比方說,匹配的字符串(submatch(0))包含n空白字符。我正在做的是計算這個數字的一​​半(n/2 = string(float2nr(len(submatch(0))/2))),然後從匹配中提取很多字符(基本上是matchstr(n/2))。這確保我們獲得剛剛開始的空白的一半(可能是空格和製表符的混合)。

如果你知道的空白將只包含空格或ONLY選項卡,這可能有所簡化,例如:

%s#^\s*#\=repeat(" ",indent(".")/2)# 

在另一方面,我會建議重新擬定您的地圖,使他們更具可讀性,因此更容易修改和維護。我的方法是定義了兩個功能:

function! DoubleWS() 
    let pos = getpos('.') 
    let reg = getreg('@') 
    exe '%s/^\s*/&&/e' 
    call setreg('@',reg) 
    call setpos('.',pos) 
endfunction 

function! HalfWS() 
    let pos = getpos('.') 
    let reg = getreg('@') 
    exe '%s#^\s*#\=matchstr(submatch(0),"^.\\{".string(float2nr(len(submatch(0))/2))."\}")#e' 
    call setreg('@',reg) 
    call setpos('.',pos) 
endfunction 

注意,get/setpos/reg功能是保持光標位置並註冊的一個更可靠的方法。然後,您可以根據需要映射這些功能:

nnoremap <silent> <leader>iw :call DoubleWS()<CR> 
nnoremap <silent> <leader>rw :call HalfWS()<CR> 

希望有所幫助!

+0

謝謝。完美的作品。我也決定按照你的建議使用函數。 (我剛剛進入這個階段,在這個階段中,您實際上試圖將Vim個性化爲您的需求和口味,所以這些是我使用的第一個功能(外部插件)。 – 2012-02-02 21:13:31

+0

歡迎光臨!這正是Vim變得非常強大的地方。這些是非常有用的功能,因爲它們引入了變量並執行普通的Vim命令。 (請注意,我編輯了我的答案,刪除了不需要的_s2'的定義。) – 2012-02-02 21:22:27

+0

@GoranNovosel:雖然解決了這個問題,但這個實現設置了一個過度設計和重複的Vim腳本的例子:替代命令減半領先的空白可能會更習慣和[近五倍](http://stackoverflow.com/a/9124761/254635);狀態保存功能可以[泛化以避免重複](http://stackoverflow.com/a/9124761/254635)。 – 2012-02-03 06:58:58