コマンドの結果をvimのテキストに挿入する方法は?


42

たとえば:echo strftime(%c)、現在の時刻を下部に表示しますが、この時刻文字列をテキスト(カーソルの直後)に挿入する方法は?


1
OPは「Vim式の結果をテキストに挿入する方法」を意味すると思います。
アラステアアーバイン

また、これは、静的テキストのブロックを挿入するためのvim関数の作成と同じ質問ではないことにも言及する価値がありますが、いくつかの答えは依然として当てはまります。
アラステアアーバイン

あなたの例は文字通り私のユースケースであり、私はあなたに敬礼します。
ジョー

レジスタへのリダイレクトも参照してください:stackoverflow.com/questions/2573021/...
NeilG

回答:


49

あなたは使用することができ、表現のレジスタを"=p(またはPノーマルモードまたは<C-R>挿入モードで:

通常モードでは:
<C-M>ここでは意味Control+ M、または押すだけをEnter/ Return

"=strftime('%c')<C-M>p

挿入モードでは:
<C-M>上記と同じ意味を有する<C-R>手段Control+ R

<C-R>=strftime('%c')<C-M>

同じ式の結果を何度も挿入したい場合は、それらを.vimrc:のキーにマッピングすることをお勧めします
(ここで<C-M>and <C-R>は文字どおりに入力する必要があります(5つの印刷可能な文字のシーケンス。Vimはそれらを内部で変換します))

:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>

2
+1オフコース!"=レジスタ。:-/
エルベックス

2
vim変数の値(たとえば、sessionoptions)を取得するには:<C-R>=&sessionoptions-ワイルドモードタブ補完も行います!
ジャスティンM.キーズ

2
:put = strftime( '%c')<CM>
brunch875

挿入モードで<c-r>=は、大量の出力があり、インデントが壊れて出力テキストが読めなくなる可能性のあるコマンドの使用が遅くなります。たとえば<c-r>=execute('nmap')、出力は1行ずつ書き込まれますが、非常に遅いです。
jdhao

22

:r!date +\%c

見る :help :r!


1
date!OPはvimコマンドを要求している間、外部コマンドであり、外部コマンドを呼び出します。
エルベックス

@eelvexいいえ、彼はしませんでした。そしてその !vimおよびviコマンドです。これは標準的な方法です。他の多くのことでも機能します。
キース

5
@Keith:yes !は、外部コマンドを呼び出すvi(m)コマンドです。あなたは正しいvimコマンドだけを出力したくないOPかもしれませんが、もし(s)彼はそうし!ません。
エルベックス

11

これらのコマンドはstrftime("%c")、カーソルがある場所に右の出力を挿入します。

:exe ":normal i" . strftime("%c")

そして

:call feedkeys("i". strftime("%c"))

あなたがしたいことをする他の方法があります(例えば、Mikelの答えにあるような)。

編集:さらに良いことに、インプレース挿入には、Chris Johnsenが説明する=レジスタを使用します


10

関数呼び出しの戻り値ではなく)vim コマンドの出力を挿入する場合、キャプチャする必要があります。これは、vimの標準出力に相当するものを変数、ファイル、レジスタ、またはその他のターゲットにリダイレクトできるコマンドを介して実現されます。:redir

:redir使用するのは非常に不便です。私はそのような機能をより便利な方法でカプセル化する関数を書きます。

funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    return output
endfunct!

このような関数を宣言したら、式レジスタ(Chris Johnsenによる説明)を使用して、カーソル位置にコマンドの出力を挿入できます。そのため、通常モードからヒットi^R=Exec('ls')して、vimの現在のバッファーのリストを挿入します。

コマンドは関数名前空間で実行されることに注意してください。したがって、グローバル変数を使用する場合は、接頭辞を付けて明示的に名前空間を指定する必要がありますg:。またExec()、上記のように、1行の出力にも終端改行を追加することに注意してください。substitute()これを避けるために、関数への呼び出しを追加することをお勧めします。

参照してくださいhttps://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054#2573054をよりについてのblatheringためredirとリンクへ関連コマンド。


2
これはうまく機能します。行が空白で始まるときに階段のインデントを避けるために、set paste出力を返す前と後にコマンドを追加しましたset nopaste。実際、現在の貼り付けオプションの値を保存して返したいと思っていましたが、保存できませんでした。
フアンラナス

1
@JuanLanus はreturn文が関数の出口点であるため、のset nopastereturn outputでは機能しません。このページの別の回答として、この問題の解決策を示しました。
エフゲニーセルゲイエフ

4
:call append(line('.'), strftime("%c"))

次の行に配置し、JShift+ J)を押して現在の位置に結合できます。

または、1つのコマンドですべてが必要な場合は、次のようにすることができます。

:call setline(line('.'), getline(line('.')) . strftime("%c"))

または

:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))

日付の前にスペースを挿入するかどうかによって異なります。


4

@intuitedの回答を改善して、先頭の空白やインデントの増加に関する問題を回避します。

"Examples:
":call Exec('buffers')
"This will include the output of :buffers into the current buffer.
"
"Also try:
":call Exec('ls')
":call Exec('autocmd')
"
funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    let @o = output
    execute "put o"
    return ''
endfunct!

これは:call Exec('command')、通常モードからファイルをコピーするときに、ファイルの現在の場所に挿入するだけです。コメントに記載されているように、文字列=Exec('command')Exec(..)返す元の(挿入モード)Ctrl + R アプローチはを使用して部分的に修正できますset pasteが、set nopasteどこにでも配置する機会は提供しません。

let @o = output構文は、レジスタを設定し、o変数の内容をoutputここで説明したように、:https://stackoverflow.com/a/22738310/1143274

このreturn ''行は、デフォルトの戻り値が0バッファに挿入されないようにするためのものです。


2

これが私のやり方です。を使用するため、カーソルの直後に配置しますp

" save previous yank
let reg_save = @@

" save your text to the '@' register
let @@ = strftime('%c')
" paste it after the cursor
exec "normal! p"

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