行をコンマ(または別の文字)で結合できますか?


19

Vimの行Jとそのいくつかのバリアント(gJなど)を結合できることを知っています。J「インデントを削除し、二つの空間まで挿入します」

しかし、2つのスペースの代わりに別の文字を挿入する簡単な方法もありますか?たとえば、コンマ(,)またはコンマとスペース(,)ですか?

与えられた:

8
9
10
32

私は次のようになりたいです:

8, 9, 10, 32

または:

8,9,10,32

github.com/sk1418/Join(テストされていない)も好きかもしれません。
ヴァンレーザー

回答:


5

Joinプラグインを作成し、必要な処理を実行できます。

build-in:joinコマンドによって提供されるすべての機能を除き、Joinは次のことができます。

  • 行をセパレーターで結合(文字列)
  • 先頭/末尾の空白をトリミングするかどうかにかかわらず、行を結合します
  • 負の数の行を結合(後方結合)
  • 行を逆に結合する
  • 行を結合し、結合された線を保持します(結合された線を削除せずに)
  • 上記のオプションの任意の組み合わせで行を結合します

詳細とスクリーンショット:

https://github.com/sk1418/Join


23

簡単な方法はこれです:単にあなたの行(最後の行を除くすべて)を選択する-または使用して%-を実行します:

:'<,'>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「単語」に参加することはできません。

(提案は大歓迎です)

ここに画像の説明を入力してください


2
さらに良いのは:'<,'>-1s/\n/, /、マークされた行、または:1,$-1s/\n/, /ファイル全体です。
佐藤桂

確かに、それはさらに良いです:)
VanLaser

@SatoKatsuraについて説明してもらえます-1か?
-alxndr

1
@alxndr-範囲/ファイルの最後の行をスキップするために使用されます。たとえば、OPの例では、32の後のコンマは必要ありません。 。あなたも使用することができる'<,'>-s/\n/, /か、1,$-s/\n/, /など-と同じです-1
ヴァンレーザー

1
場合l:sepである&ことから、その後、あなたの交換は、正しく動作します&交換で魔法があります。エスケープを処理するのではなく、\=を使用してリテラル文字列を使用する方がよい場合がありますlet l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
ジェームスサン

3

外部コマンドを使用した例を次に示します。

:%!paste -sd,

ここで%!、現在のバッファー(ファイルの内容)をコマンドで置き換えます:(paste -sd,パラメーター-sは複数の行を結合し-d、区切り文字をに設定するために使用されます,)。


3

誰かが正規表現を入力してプラグイン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

プラグインや外部コマンドを使用せずにJ、スペースから好きな文字にjoin()を再マップするはるかに簡単な方法。たとえば、カンマとスペースで結合するには:

:nmap J :s/\n/, /^M

末尾の改行(^M)を特殊文字にするには、Ctrl-VEnterキーを押してからEnterキーを押します。あなたは、タブと交換したい場合は、同じが行く(^I)、入力しCtrl-Iた後Tab

:nmap J :s/\n/^I/^M

これは、改行を現在の行のタブに置き換え、その動作をJ文字に再マッピングすることです。

これ4Jは、次の4行を結合するなどの組み合わせでも機能します。


0

マクロを記録して、コンマで行を結合できます。これは、まれなタスクまたは1回限りのタスクであり、タスクを実行するための代替コマンドと正規表現を記述する方法を覚えていないが、マクロを記録して実行する方法を覚えている場合に役立ちます。

行をコンマで結合するにqjgJi,Escqは、register と入力してマクロを記録しますj。次に、でマクロを実行できます@j。を使用してマクロを再実行できます@@。これにより、連続して複数回実行するときに入力を節約でき@ます。結合する行の終わりに近づくまで押し続けることもできます。@jまたは@@に数字のプレフィックスを使用して、設定した回数だけ繰り返すこともできます。これにより、先頭と末尾のスペースがそのまま残ります。そのため、元のテキストにスペースが含まれている場合、コンマの前後にスペースがあります。

コンマとスペースで結合するには、マクロの記録時Space,との間に挿入しEscます。

マクロを記録するときのJ代わりに使用することもできますgJ。これは通常、行をコンマとスペースで結合します。ただし、現在の行の末尾に空白がある場合は、空白の後にカンマが表示されますが、空白は後に続きません。次の行で始まる場合にも、それはスペースが含まれていない)、とあれば、それはカンマの後に二つの空白を置くjoinspaces設定されているとして、現在のラインが終了する.!または?。これらの注意事項については、で説明し:help Jます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.