Bagaimana saya bisa menekan pesan "membaca dari STDIN" dari dalam Vim?


18

Saat menggunakan Vim untuk membaca dari stdin, ia mencetak pesan yang informatif:

$ echo foo | vim -
Vim: Reading from stdin...

$

Ini hanya sebuah contoh. Penggunaan aktual tidak memungkinkan konstruksi shell. vim <(echo foo)bukan pilihan.

Bisakah saya menekannya dengan hanya menggunakan opsi Vim dan / atau pengaturan vimrc?


Jika Anda perlu tahu untuk apa ini, saya mencoba menggunakan Vim untuk membaca halaman manual (plug shameless). Orang GNU tidak mengizinkan shell konstruksi di MANPAGER, dan dengan menggunakan ftplugin/man.vimdan hal-hal lain, saya telah berhasil berhasil memiliki pengalaman yang nyaman menggunakan adil MANPAGER="vim -". Gangguan terakhir yang tersisa adalah pesan yang tidak sedap dipandang dicetak setelah setiap halaman yang saya lihat.


Menggunakan export MANPAGER='vim -c "%! col -b" -c "set ft=man nomod nolist ignorecase" -'atau export MANPAGER="vim -"saya tidak melihat masalah? man lsmembuka halaman manual seperti yang diharapkan.
Martin Tournoij

@Carpetsmoker dan setelah Anda menutupnya?
muru

Tidak, tidak melihat apa-apa ...
Martin Tournoij 8-15

@Carpetsmoker versi Vim apa yang Anda gunakan? Bagaimana denganecho foo | vim -Nu NONE -
muru

Di vim, : help lessberikan beberapa info untuk menggunakannya sebagai pager.
mtklr

Jawaban:


8

Dimulai dengan Vim 8.0.1308 (Nov 2017), Anda dapat menggunakan --not-a-termopsi untuk menekan pesan ini; misalnya dengan quit:

$ echo hello | vi - --not-a-term -esc '%p|q!'
hello

Atau dengan exit:

$ echo hello | vi - --not-a-term -esc 'x!/dev/stdout'
hello

Seperti ini, ini setara dengan cat, tetapi masih bisa berguna untuk menerapkan Vimscript ke input, misalnya +'runtime! syntax/2html.vim'untuk mengekspor teks yang disorot sebagai gaya HTML (dengan asumsi tipe file yang dikurangi atau ditentukan). Ada beberapa opsi selain yang disebutkan sejauh ini; yang pertama terlintas dalam pikiran adalah menggunakan mktempuntuk menyimpan output perintah dan menggunakan ini sebagai input Vim. Anda bisa menambahkan perintah pengalihan dan shell Vim untuk 'menempelkan' hasil perintah ke dalam buffer, tetapi ini membutuhkan lebih banyak pekerjaan. (File skrip Vim dapat mengotomatiskan pemanggilan yang panjang alih-alih menggunakan alias.)
John P

Dimungkinkan untuk mengedit / menempelkan output dari soket, yang bisa sangat berguna jika itu benar. Saya masih mengatakan pilihan terbaik adalah file temp, kecuali ada peringatan yang lebih buruk daripada jawaban yang diterima. Namun untuk shell tertentu, mungkin ada alias / builtin / sintaksis yang ada yang menyederhanakan beberapa bagian dari proses ini, seperti yang tercantum dalam halaman manual untuk zshmisc (pengalihan, dll.) Satu lagi - mungkin Anda dapat melarikan diri dari input dan menyediakannya sebagai argumen setelah argumen memasuki mode insert, jadi parse seolah diketik?
John P

Saya melihat --not-a-termdi Vim 7.4.1689 di Ubuntu 16.04 (tetapi tidak 7.4.8056 di Mac), tetapi tidak menekan pesan.
Dijeda sampai pemberitahuan lebih lanjut.

@DennisWilliamson Lihat changelog oleh :help version8.txt. --not-a-termOpsi itu sendiri ditambahkan 7.4.1419dan perilakunya diubah untuk juga menekan pesan Reading dari stdin ... di 8.0.1308. (Ngomong-ngomong, file N untuk mengedit pesan juga ditekan dari 8.1.1258)
ynn

12

Jawaban untuk pertanyaan persis Anda :

Bisakah saya menekannya dengan hanya menggunakan opsi Vim dan / atau pengaturan vimrc?

adalah: tidak, itu tidak mungkin karena bagian kode berikut

    if (read_stdin)
    {
#ifndef ALWAYS_USE_GUI
        mch_msg(_("Vim: Reading from stdin...\n"));
#endif

yang berarti bahwa jika Anda memberikan -argumen untuk vim, maka itu akan secara otomatis menunjukkan pesan itu.

meskipun, sebagai solusi, jika Anda menggunakan pengalihan file alih-alih -argumen Anda akan menyingkirkan pesan:

echo "foo" | vim < /dev/tty

dan inilah contoh MANPAGEpengaturan yang hanya berfungsi ™ (diambil dari intertubes):

export MANPAGER='bash -c "vim -MRn -c \"set ft=man nomod nolist nospell nonu\" -c \"nm q :qa!<CR>\" -c \"nm <end> G\" -c \"nm <home> gg\"</dev/tty <(col -b)"'

2
Ketika ini ALWAYS_USE_GUI didefinisikan, kau tahu?
muru

2
lihat feature.h (selesai ketika ALWAYS_USE_GUI tidak didefinisikan, jadi pada dasarnya untuk semua versi unix).
Christian Brabandt

2
Saya tidak bisa echo "foo" | vim < /dev/ttymenyelesaikannya. Melakukannya memberi [2]+ Stopped echo "foo" | vim < /dev/tty.
Léo Léopold Hertz 준영

2
Seperti @ LéoLéopoldHertz 준영, trik tty tidak bekerja untuk saya (gvim memberikan dokumen kosong, vim menjadi benar-benar bingung dengan input keyboard, tetapi setidaknya tidak menerima SIGSTOP). Saya sudah lebih beruntung dengan echo "foo" | gvim /dev/stdin(meskipun vim non-GUI masih akan mengeluarkan keluhan tentang itu Vim: Warning: Input is not from a terminal:).
Adam Katz

2
Yah, lupakan pesan saya sebelumnya. Trik dalam jawabannya <(col -b)sebagian. Pada dasarnya itu adalah beberapa versi canggih catuntuk mencetak halaman manual, dan Anda akhirnya dapat menyingkirkan pesan vim denganecho test | vim < /dev/tty <(cat>
Alexander Solovets

1

Di Vim, masalah ini telah diatasi di 234d162commit (> = v8.0.1387).

Solusi: Jangan tampilkan pesan --not-a-termyang digunakan.

Jadi pesan hanya ditampilkan ketika pengguna belum mengalihkan stdin.


Masalah serupa telah diatasi dalam versi terbaru Neovim ( > = v0.2.2-dev ) yang bisa Anda gunakan sebagai ganti Vim.

Setelah NVim v0.2.2 dirilis, Anda seharusnya dapat menjalankan:

$ echo foo | nvim -

tanpa pesan.


0
  1. Dengan vim versi 8.0.1387 dan yang lebih baru, Anda dapat menggunakan --not-a-termopsi.

  2. Untuk versi yang lebih lama gunakan trik berikut: $ echo foo | bash -c 'vim < /dev/tty <(cat)'

Argumen pertama /dev/ttyentah bagaimana menipu Vim untuk berpikir input berasal dari keyboard. Saya kira, itu karena isatty (3) mengembalikan True untuk file itu. Dan argumen kedua hanya melewati segala sesuatu dari input standarnya ke input standar Vim. Akhirnya, bash -cawalan diperlukan agar konstruksi khusus <(...)berfungsi jika shell tidak mendukungnya. Dalam bash solusi asli dapat disederhanakan $ echo foo | vim < /dev/tty <(cat)


Keduanya tercakup dalam jawaban yang ada atau pertanyaan itu sendiri. Apa yang baru di sini?
muru

@muru Tidak dijelaskan bagaimana case kedua bekerja, dan orang-orang bertanya-tanya mengapa ini hanya bekerja di MANPAGE.
Alexander Solovets
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.