Vimの行J
とそのいくつかのバリアント(gJ
など)を結合できることを知っています。J
う「インデントを削除し、二つの空間まで挿入します」。
しかし、2つのスペースの代わりに別の文字を挿入する簡単な方法もありますか?たとえば、コンマ(,
)またはコンマとスペース(,
)ですか?
与えられた:
8
9
10
32
私は次のようになりたいです:
8, 9, 10, 32
または:
8,9,10,32
Vimの行J
とそのいくつかのバリアント(gJ
など)を結合できることを知っています。J
う「インデントを削除し、二つの空間まで挿入します」。
しかし、2つのスペースの代わりに別の文字を挿入する簡単な方法もありますか?たとえば、コンマ(,
)またはコンマとスペース(,
)ですか?
与えられた:
8
9
10
32
私は次のようになりたいです:
8, 9, 10, 32
または:
8,9,10,32
回答:
Joinプラグインを作成し、必要な処理を実行できます。
build-in:joinコマンドによって提供されるすべての機能を除き、Joinは次のことができます。
- 行をセパレーターで結合(文字列)
- 先頭/末尾の空白をトリミングするかどうかにかかわらず、行を結合します
- 負の数の行を結合(後方結合)
- 行を逆に結合する
- 行を結合し、結合された線を保持します(結合された線を削除せずに)
- 上記のオプションの任意の組み合わせで行を結合します
詳細とスクリーンショット:
簡単な方法はこれです:単にあなたの行(最後の行を除くすべて)を選択する-または使用して%
-を実行します:
:'<,'>s/\n/,/
または
:'<,'>s/\n/, /
(もちろん、選択範囲を対象とするため'<,'>
に:
、Vimによって既にパーツが挿入されている場合)
(2回目)更新:
上記(および佐藤桂のコメント)に基づいて、カウントとオプションの繰り返しサポートを備えた、可能な「対話型結合」の実装を次に示します。
" ================ script ===============================================
" interactive 'J', 'gJ' replacement with optional 'vim-repeat' support
" The last used separator is automatically reused as:
" a. default choice
" b. when repeating (=> non-interactive repeats: same range, same separator)
let g:last_join_separator = " "
function! s:interactiveJoin(use_last_sep,...) range
if (a:use_last_sep == 0) "interactive, ask for separator to use
call inputsave()
echohl Question
let l:sep = input("Separator:", g:last_join_separator)
echohl None
call inputrestore()
redraw!
let g:last_join_separator = l:sep "update last separator value
else "non-interactive (when repeating with '.')
let l:sep = g:last_join_separator
endif
if (a:0 == 0) "with no argument, remove indentation *and trailing spaces*
let l:subst = 's/\s*\n\+\s*/\=' . "'" . l:sep . "'/"
else " don't remove indentation or trailing spaces (act like 'gJ')
let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
endif
if a:firstline < a:lastline "join given range
execute a:firstline . ',' . (a:lastline - 1) . l:subst
let l:count = a:lastline - a:firstline + 1 "default count for repeat
else "or join only with next line
execute l:subst
let l:count = 1 "default count for repeat
endif
"make command repeatable
"(with the tpope/vim-repeat plugin: optional, recommended)
if (a:0 == 0)
silent! call repeat#set("\<Plug>(repeatJoin)", l:count)
else
silent! call repeat#set("\<Plug>(repeatGJoin)", l:count)
endif
endfunction
noremap <silent> <Plug>(interactiveJoin) :call <SID>interactiveJoin(0)<CR>
noremap <silent> <Plug>(interactiveGJoin) :call <SID>interactiveJoin(0,'g')<CR>
noremap <silent> <Plug>(repeatJoin) :call <SID>interactiveJoin(1)<CR>
noremap <silent> <Plug>(repeatGJoin) :call <SID>interactiveJoin(1,'g')<CR>
そして実際のマッピング:
"================= vimrc ================================================
nmap J <Plug>(interactiveJoin)
xmap J <Plug>(interactiveJoin)
nmap gJ <Plug>(interactiveGJoin)
xmap gJ <Plug>(interactiveGJoin)
これはのようなkind(*)ですJ
が、インタラクティブです-区切り文字列の入力を求めます。デフォルトの文字列はスペースです。たとえば、セパレータなしで行を結合しBackspace
、プロンプトが表示されEnter
たらヒットし、デフォルトのスペース文字を削除し、(現在の)空のセパレータを受け入れます。たとえば3J
、カウントも機能します。tpope/vim-repeat
プラグインがインストールされている場合、「。」で繰り返します また、最後のセパレータと(変更されていない場合-たとえば10.
)最後のカウントまたは視覚的な行の範囲を再利用します。
(*)そうではありません正確に同じようJ
しかし、:それはインデントを削除する一方、それがためにチェックしません.!?
代わりに、1の2つのスペースを挿入する(フレーズの終わり)、またはスペースを挿入し、(それはのような何かをするのは難しい欠けている場合にのみ、これは、セパレータ文字列は現在何でも構いませんので)。また、末尾のスペースも削除します(より意味があります)。
これは、限られた演算子のレタースペースをオーバーロードする良い方法だと思います:)
まあ、技術的にJ
は完全に演算子ではありませんが、それに近いです-たとえば、Jaw
「単語」に参加することはできません。
(提案は大歓迎です)
:'<,'>-1s/\n/, /
、マークされた行、または:1,$-1s/\n/, /
ファイル全体です。
-1
か?
'<,'>-s/\n/, /
か、1,$-s/\n/, /
など-
と同じです-1
。
l:sep
である&
ことから、その後、あなたの交換は、正しく動作します&
交換で魔法があります。エスケープを処理するのではなく、\=
を使用してリテラル文字列を使用する方がよい場合がありますlet l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
。
誰かが正規表現を入力してプラグインExコマンドをさらに覚えるのを好まない場合に備えて:
Visual-block AppendはVisual Blockモード(<C-v>
)で使用でき、ブロックAの追加(および追加のブロックI nsert )を実行できます。(参照::help v_b_A
、:help v_b_I
)
ブロックビジュアルモードの最後のモーションがの$
場合、追加はすべての選択の最後に行われます。それ以外の場合は、追加したテキストの前にスペースが挿入されます()
コード内のいくつかのメソッド呼び出しの最後に位置合わせして閉じることを想像してください)。
以下のサンプルテキストとカーソルをオンにして8
:
8
9
10
12
<C-v>}$A,<C-c>
。通常モードに戻った後、,
選択したすべての行に追加されていることがわかります。(なしで試してください$
)
次にgv
、エリアを再選択しますJ
またはまたはgJ
。私たちは、末尾を持っている,
:8,9,10,12,
そして$x
、私たちは完了です。
,
テキストを元に戻して(uu..u
それでも空想でも:ea 1d<cr>:lat 1
)、Visual Insertを試してみましょう:
j<C-v>}I, <C-c>
そして、gJ
スペースなしで行を結合できます。
ちょっと待って、何かが足りない。「アレイ」全体を再選択する方法は?今回は最初の行を選択gv
しませんでした... 助けにはなりません。
-または、gvok
選択し直し(gv
)、o
コーナーをk
上に移動することもできます。
PS私の小指はを入力/\
するの/\n
に十分に速く正確ではないので、Vimの組み込みの操作と動きを組み合わせて正規表現を使用しないようにしています。しかし、マッピングを使用してこれを十分に頻繁に行う場合は、プラグインにマップするものの方が良いでしょう。
マクロを記録して、コンマで行を結合できます。これは、まれなタスクまたは1回限りのタスクであり、タスクを実行するための代替コマンドと正規表現を記述する方法を覚えていないが、マクロを記録して実行する方法を覚えている場合に役立ちます。
行をコンマで結合するにqjgJi,Escqは、register と入力してマクロを記録しますj
。次に、でマクロを実行できます@j。を使用してマクロを再実行できます@@。これにより、連続して複数回実行するときに入力を節約でき@ます。結合する行の終わりに近づくまで押し続けることもできます。@jまたは@@に数字のプレフィックスを使用して、設定した回数だけ繰り返すこともできます。これにより、先頭と末尾のスペースがそのまま残ります。そのため、元のテキストにスペースが含まれている場合、コンマの前後にスペースがあります。
コンマとスペースで結合するには、マクロの記録時Spaceに,との間に挿入しEscます。
マクロを記録するときのJ代わりに使用することもできますgJ。これは通常、行をコンマとスペースで結合します。ただし、現在の行の末尾に空白がある場合は、空白の後にカンマが表示されますが、空白は後に続きません。次の行で始まる場合にも、それはスペースが含まれていない)
、とあれば、それはカンマの後に二つの空白を置くjoinspaces
設定されているとして、現在のラインが終了する.
、!
または?
。これらの注意事項については、で説明し:help J
ます。