2012-02-02 4 views
4

の各行の初めに空白の数を半減各行の先頭にある空白の数。 最初の正規文字の前の空白文字のみが影響を受けます。 現在の検索文字列が保持されます(変数_s)。 この変換後に位置が復元されます(変数_s2誰かがどのようにVimの中でこのマッピングの逆を行うことを教えてもらえますVimの

基本的には、次々に実行される場合は元に戻すマッピングを探しています。

この新しい操作を、最初の正規文字の前に空白でのみ機能するように制限する方法がわかりません。

答えて

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'を使うことはできませんでした。シンプルで効果的! –

+0

@PrinceGoulash:ありがとう!やや慣用的なパターンです。あなたが気付いている注目すべき例は、非負の整数が素数であるかどうかをテストするために使用できる正規表現です。 Vimスクリプトでは、 'repeat( '1'、n)!〜 '^ 1 \?$ \ |^\(1 \ { - 2、} \)\ 1 \ + $' nは問題の番号です。 –

+0

ありがとう、これは本当にエレガントなソリューションです。 –

2

あなたのオリジナルの置換は、この(私は読みやすくするため#/区切り文字を置き換えている)である:

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

%s#^\s*#&&# 

そして、ここが私の提案逆置換(深呼吸を取る...)です

一致する文字列(submatch(0))には、空白文字のnが含まれているとします。私がしていることは、この数字の半分(n/2 = string(float2nr(len(submatch(0))/2)))を計算して、その一致から多くの文字を抽出することです(本質的にmatchstr(n/2))。これにより、開始した空白の半分(空白とタブが混在している可能性があります)が正確に取得されます。

あなたは空白はONLYスペースまたはタブのみが含まれています知っている場合、これは例えば、やや単純化することができます。

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

別のノートで、私は、それゆえ、それらをより読みやすくするために、あなたのマップを改質お勧めしてしまいます変更と保守が簡単です。 get/setpos/regの機能は、カーソル位置を維持し、登録のはるかに堅牢な方法であることを

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 

注:私のアプローチは、2つの関数を定義することです。これらの機能は、必要に応じてマップすることができます。

+0

ありがとうございました。完璧に動作します。また、あなたが提案したように関数を使うことに決めました。 (私はあなたのニーズや好みに合わせてVimを実際にパーソナライズしようとしているこのフェーズには初めてですので、それらは私が使っている最初の機能(外部プラグイン)です)。 –

+0

ようこそ!これはVimが本当に強力になる場所です。これらは、変数を導入して通常のVimコマンドを実行するときに学ぶために非常に便利な関数です。 –

+0

@GoranNovosel:問題を解決するにもかかわらず、この実装では、過剰に設計された繰り返しVimスクリプトの例が設定されています。先頭に空白を半分にする代替コマンドもっと慣用的で、[ほぼ5倍短い]ことができます(http://stackoverflow.com/a/9124761/254635)。状態を保存する機能は[反復を避けるために一般化できる](http://stackoverflow.com/a/9124761/254635)。 –

関連する問題