2017-02-24 7 views
2

多くの場合、テキスト行を配列に変換します。たとえば、この:Vim:動きのあるカスタムコマンドを作成する

Monday 
Tuesday 
Wednesday 

は次のようになります。

[ 
    'Monday', 
    'Tuesday', 
    'Wednesday', 
] 

私はそうのような行のいずれかを変更するマップ('Monday',に例えばMonday)を作ることができます。

:nnoremap gsa ^i'<Esc>A,

私がしたいのは、そのコマンドに動きまたはテキストオブジェクトを持たせて、gsaipのように実行できるようにすることです。 gsip3j

どうすればこの問題を解決できますか?

答えて

1

'operatorfunc'[email protected]とすると、動きが のマップを持つことができます。ヘルプは、 :map-operatorのトピックの完全な説明と例を示します。基本的には、 を呼び出す機能をマップに設定し、[email protected]を使用します。 Vimは動きを待ってから のマークを'[']に設定し、関数を呼び出します。

あなたの機能の中で創造的に行くことができます、ここで私はちょうど あなたが必要なものにこの原則をどのように適用できるかの例を作りました。

:nnoremap <silent> gsa :set opfunc=TransformToArray<cr>[email protected] 

function! TransformToArray(type) 
    if a:type == 'line' 
    let s=line("'[") " saving beginning mark 
    ']s/\(\s*\).*\zs/\r\1] 
    exec s ",']-1s/\\s*\\zs.*/ '&'," 
    exec s 's/\(\s*\)\zs\ze /[\r\1' 
    elseif a:type == 'char' 
    " ... 
    endif 
endfunction 
+0

'「ゴー\ ]」'変更しないのはなぜ「行く」に「」? –

+1

@ Meninx-メネンクス私にとってはインデント設定のために必要です。前の行は2字下げされているので、閉じ括弧を挿入する前にbsで削除します。これは単なる速い解決策であり、改善のためのより多くの考えが必要です。 – sidyll

+0

@ Meninx-メネンクス私はそれを変更しました。 – sidyll

0

具体的には、マッピングをモーションオブジェクトまたはテキストオブジェクトで覆われた各行に適用すると思われます。 vipまたはv2j

あなたがビジュアルモードを経由して、このような範囲を確立することができます。次に、:normal gsa(入力;ビジュアルモードからコマンドラインモードを入力した場合、Vimは選択範囲(:'<,'>)を自動的に挿入します)を使用して、各行にカスタムマッピングを適用しますライン、:help :normal-range)。

1

はあなた.vimrcファイルにこれを入れて:

vnoremap <silent> gsa :call Brackets()<CR> 

function! Brackets() 
    execute "normal! I'" 
    if line(".") == a:lastline 
     execute "normal! A'\<cr>]" 
     execute a:firstline."s:^:[\r:" 
    else 
     execute "normal! A'," 
    endif 
endfunction 

たとえばvip用したい視線のブロックを選択し、gsaを押してください。

0

実際に最後の項目の後にカンマを追加する場合は、レジスタを変更せずにそのまま残しておきます。

function! s:to_list() range abort 
    let words = getline(a:firstline, a:lastline) 
    exe a:firstline.','.a:lastline.'d _' " remove the "_" to fill the unnamed register 
    let lines = ['['] + map(words, '" ".string(v:val).","') + [']'] 
    call append(a:firstline-1, lines) 
endfunction 

command! -nargs=0 -range=% ToList <line1>,<line2>call s:to_list() 

最後の2行を取り除くために、私はmap()結果の最後の項目を編集したかjoin()でプレイ:

let lines = "[\n" . join(map(words, '" ".string(v:val)'), ",\n") . "\n]" 
    put!=lines 
関連する問題