Bagaimana cara memasukkan hasil dari suatu perintah ke dalam teks dalam vim?
42
Misalnya, :echo strftime(%c)akan menampilkan waktu saat ini di bagian bawah, tetapi bagaimana cara memasukkan string waktu ini ke teks (tepat setelah kursor)?
Dalam mode normal: (di <C-M>sini berarti Control+ M, atau cukup tekan Enter/ Return)
"=strftime('%c')<C-M>p
Dalam mode sisipkan: ( <C-M>memiliki arti yang sama seperti di atas, <C-R>berarti Control+ R)
<C-R>=strftime('%c')<C-M>
Jika Anda ingin menyisipkan hasil dari ekspresi yang sama berkali-kali, maka Anda mungkin ingin memetakannya ke dalam kunci Anda .vimrc: (di sini <C-M>dan <C-R>harus diketik secara harfiah (urutan lima karakter yang dapat dicetak — Vim akan menerjemahkannya secara internal))
untuk mendapatkan nilai dari variabel vim (misalnya, opsi sesi): <C-R>=&sessionoptions- ia bahkan melakukan wildmode tab-completion!
Justin M. Keyes
2
: put = strftime ('% c') <CM>
brunch875
Dalam mode penyisipan, penggunaan <c-r>=lambat untuk perintah yang mungkin memiliki banyak output dan juga dapat mematahkan indentasi sehingga teks keluaran tidak dapat dibaca. Misalnya, <c-r>=execute('nmap')output akan ditulis baris demi baris, yang sangat lambat.
dateadalah perintah eksternal dan !memanggil perintah eksternal sementara OP meminta perintah vim.
Eelvex
@eelvex tidak, dia tidak. dan! adalah perintah, dan vi, perintah. Ini adalah metode kanonik. Berfungsi untuk banyak hal lain juga.
Keith
5
@Keith: yes !adalah perintah vi (m) yang memanggil perintah eksternal . Anda mungkin benar OP tidak ingin hanya output perintah vim tetapi jika dia melakukannya, !tidak akan melakukannya.
Eelvex
11
Perintah-perintah ini akan memasukkan output strftime("%c")tepat di mana kursor Anda berada:
:exe ":normal i" . strftime("%c")
dan
:call feedkeys("i". strftime("%c"))
Ada cara lain untuk melakukan apa yang Anda inginkan (seperti, misalnya, jawaban Mikel ).
Sunting : Lebih baik lagi, untuk penyisipan di tempat, gunakan =register seperti yang dijelaskan oleh John Johnsen
Jika Anda ingin memasukkan output dari perintah vim (sebagai lawan dari nilai balik dari panggilan fungsi ), Anda harus menangkapnya. Ini dilakukan melalui :redirperintah, yang memungkinkan Anda untuk mengarahkan setara dengan output standar vim ke dalam variabel, file, daftar, atau target lainnya.
:rediragak tidak nyaman untuk digunakan; Saya akan menulis fungsi untuk merangkum fungsinya dengan cara yang lebih nyaman, seperti
Setelah Anda mendeklarasikan fungsi tersebut, Anda dapat menggunakan register ekspresi (seperti yang dijelaskan oleh Chris Johnsen) untuk memasukkan output dari perintah pada posisi kursor. Jadi, dari mode normal, tekan i^R=Exec('ls')untuk memasukkan daftar buffer saat vim.
Ketahuilah bahwa perintah akan dieksekusi dalam function namespace, jadi jika Anda menggunakan variabel global Anda harus secara eksplisit namespace dengan awalan dengan g:. Juga perhatikan bahwa Exec(), seperti yang ditulis di atas, akan menambahkan baris baru yang berhenti bahkan untuk output satu baris. Anda mungkin ingin menambahkan panggilan ke substitute()dalam fungsi untuk menghindari ini.
Ini sangat bagus. Saya menambahkan set pasteperintah sebelum mengembalikan output dan set nopastesetelahnya, untuk menghindari indentasi tangga ketika garis mulai dengan kosong. Sebenarnya, saya ingin menyimpan nilai opsi tempel saat ini dan mengembalikannya tetapi saya tidak dapat melakukannya.
Juan Lanus
1
@JuanLanus set nopasteSeharusnya tidak berfungsi setelah itu return output, karena pernyataan kembali adalah titik keluar dari fungsi. Saya telah menempatkan solusi untuk masalah ini sebagai jawaban terpisah di halaman ini.
Evgeni Sergeev
4
:call append(line('.'), strftime("%c"))
Akan meletakkannya di baris berikutnya, maka Anda bisa menekan J( Shift+ J) untuk bergabung ke posisi saat ini.
Atau jika Anda membutuhkan semuanya dalam satu perintah, Anda bisa melakukannya
Meningkatkan jawaban @intuited untuk menghindari masalah dengan memimpin spasi putih dan menumbuhkan indentasi:
"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!
Ini hanya akan menyisipkan di lokasi saat ini di file ketika Anda :call Exec('command')dari mode normal. Seperti disebutkan dalam komentar , =Exec('command')pendekatan Ctrl + R asli (mode-sisipan) dengan Exec(..)mengembalikan sebuah string dapat sebagian dikoreksi dengan menggunakan set paste, tetapi tidak menawarkan kesempatan untuk meletakkan di set nopastemana saja.
Beginilah cara saya melakukannya. Ini menempatkannya tepat setelah kursor karena digunakan 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
Jawaban:
Anda dapat menggunakan register ekspresi
"=
,, denganp
(atauP
) dalam mode normal atau<C-R>
mode insert:Dalam mode normal:
(di
<C-M>
sini berarti Control+ M, atau cukup tekan Enter/ Return)Dalam mode sisipkan:
(
<C-M>
memiliki arti yang sama seperti di atas,<C-R>
berarti Control+ R)Jika Anda ingin menyisipkan hasil dari ekspresi yang sama berkali-kali, maka Anda mungkin ingin memetakannya ke dalam kunci Anda
.vimrc
:(di sini
<C-M>
dan<C-R>
harus diketik secara harfiah (urutan lima karakter yang dapat dicetak — Vim akan menerjemahkannya secara internal))sumber
"=
mendaftar. : - /<C-R>=&sessionoptions
- ia bahkan melakukan wildmode tab-completion!<c-r>=
lambat untuk perintah yang mungkin memiliki banyak output dan juga dapat mematahkan indentasi sehingga teks keluaran tidak dapat dibaca. Misalnya,<c-r>=execute('nmap')
output akan ditulis baris demi baris, yang sangat lambat.:r!date +\%c
Lihat
:help :r!
sumber
date
adalah perintah eksternal dan!
memanggil perintah eksternal sementara OP meminta perintah vim.!
adalah perintah vi (m) yang memanggil perintah eksternal . Anda mungkin benar OP tidak ingin hanya output perintah vim tetapi jika dia melakukannya,!
tidak akan melakukannya.Perintah-perintah ini akan memasukkan output
strftime("%c")
tepat di mana kursor Anda berada:dan
Ada cara lain untuk melakukan apa yang Anda inginkan (seperti, misalnya, jawaban Mikel ).
Sunting : Lebih baik lagi, untuk penyisipan di tempat, gunakan
=
register seperti yang dijelaskan oleh John Johnsensumber
Jika Anda ingin memasukkan output dari perintah vim (sebagai lawan dari nilai balik dari panggilan fungsi ), Anda harus menangkapnya. Ini dilakukan melalui
:redir
perintah, yang memungkinkan Anda untuk mengarahkan setara dengan output standar vim ke dalam variabel, file, daftar, atau target lainnya.:redir
agak tidak nyaman untuk digunakan; Saya akan menulis fungsi untuk merangkum fungsinya dengan cara yang lebih nyaman, sepertiSetelah Anda mendeklarasikan fungsi tersebut, Anda dapat menggunakan register ekspresi (seperti yang dijelaskan oleh Chris Johnsen) untuk memasukkan output dari perintah pada posisi kursor. Jadi, dari mode normal, tekan
i^R=Exec('ls')
untuk memasukkan daftar buffer saat vim.Ketahuilah bahwa perintah akan dieksekusi dalam function namespace, jadi jika Anda menggunakan variabel global Anda harus secara eksplisit namespace dengan awalan dengan
g:
. Juga perhatikan bahwaExec()
, seperti yang ditulis di atas, akan menambahkan baris baru yang berhenti bahkan untuk output satu baris. Anda mungkin ingin menambahkan panggilan kesubstitute()
dalam fungsi untuk menghindari ini.Juga lihat https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054#2573054 untuk ngobrol lebih banyak tentang
redir
dan tautan ke perintah terkait.sumber
set paste
perintah sebelum mengembalikan output danset nopaste
setelahnya, untuk menghindari indentasi tangga ketika garis mulai dengan kosong. Sebenarnya, saya ingin menyimpan nilai opsi tempel saat ini dan mengembalikannya tetapi saya tidak dapat melakukannya.set nopaste
Seharusnya tidak berfungsi setelah itureturn output
, karena pernyataan kembali adalah titik keluar dari fungsi. Saya telah menempatkan solusi untuk masalah ini sebagai jawaban terpisah di halaman ini.Akan meletakkannya di baris berikutnya, maka Anda bisa menekan
J
( Shift+ J) untuk bergabung ke posisi saat ini.Atau jika Anda membutuhkan semuanya dalam satu perintah, Anda bisa melakukannya
atau
tergantung pada apakah Anda ingin ruang dimasukkan sebelum tanggal atau tidak.
sumber
Meningkatkan jawaban @intuited untuk menghindari masalah dengan memimpin spasi putih dan menumbuhkan indentasi:
Ini hanya akan menyisipkan di lokasi saat ini di file ketika Anda
:call Exec('command')
dari mode normal. Seperti disebutkan dalam komentar ,=Exec('command')
pendekatan Ctrl + R asli (mode-sisipan) denganExec(..)
mengembalikan sebuah string dapat sebagian dikoreksi dengan menggunakanset paste
, tetapi tidak menawarkan kesempatan untuk meletakkan diset nopaste
mana saja.The
let @o = output
sintaks set registero
dengan isi variabeloutput
, seperti dijelaskan di sini: https://stackoverflow.com/a/22738310/1143274The
return ''
line adalah sehingga nilai default kembalinya0
tidak mendapatkan dimasukkan ke buffer.sumber
Beginilah cara saya melakukannya. Ini menempatkannya tepat setelah kursor karena digunakan
p
.sumber