Làm cách nào tôi có thể ngăn chặn việc đọc trên mạng từ tin nhắn STDIN Cảnh trong Vim?


18

Khi sử dụng Vim để đọc từ stdin, nó sẽ in một thông báo:

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

$

Đây chỉ là một ví dụ. Việc sử dụng thực tế không cho phép cấu trúc vỏ. vim <(echo foo)không phải là một sự lựa chọn.

Tôi có thể ngăn chặn việc chỉ sử dụng các tùy chọn Vim và / hoặc cài đặt vimrc không?


Trong trường hợp bạn cần biết cái này để làm gì, tôi đang cố gắng sử dụng Vim để đọc các trang man (phích cắm không biết xấu hổ). GNU man không cho phép cấu trúc shell MANPAGER, và bằng cách sử dụng ftplugin/man.vimvà những thứ khác, tôi đã quản lý thành công để có trải nghiệm thoải mái khi sử dụng MANPAGER="vim -". Điều khó chịu cuối cùng còn lại là thông điệp khó coi được in sau mỗi trang mà tôi đã xem.


Sử dụng export MANPAGER='vim -c "%! col -b" -c "set ft=man nomod nolist ignorecase" -'hoặc export MANPAGER="vim -"tôi thấy không có vấn đề? man lsmở trang web như mong đợi.
Martin Tournoij

@Carpetsmoker và sau khi bạn đóng nó?
muru

Không, không thấy gì cả ...
Martin Tournoij

@Carpetsmoker bạn đang sử dụng phiên bản nào của Vim? Thế cònecho foo | vim -Nu NONE -
muru

Trong vim, : help lesscung cấp một số thông tin để sử dụng nó như một máy nhắn tin.
mtklr

Câu trả lời:


8

Bắt đầu với Vim 8.0.1308 (tháng 11 năm 2017), bạn có thể sử dụng --not-a-termtùy chọn để chặn thông báo này; ví dụ với quit:

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

Hoặc với exit:

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

Như vậy, điều này tương đương với cat, nhưng nó vẫn có thể hữu ích cho việc áp dụng Vimscript cho đầu vào, ví dụ: +'runtime! syntax/2html.vim'để xuất văn bản được tô sáng dưới dạng HTML được tạo kiểu (giả sử kiểu tệp được suy ra hoặc được chỉ định). Có một vài lựa chọn khác ngoài những lựa chọn được đề cập cho đến nay; đầu tiên bạn nghĩ đến là sử dụng mktempđể lưu trữ đầu ra của lệnh và sử dụng nó làm đầu vào của Vim. Bạn có thể thêm các lệnh chuyển hướng và shell của Vim để 'dán' kết quả lệnh vào bộ đệm, nhưng việc này cần thêm một số công việc. (Tệp tập lệnh Vim có thể tự động hóa các lệnh dài thay vì sử dụng bí danh.)
John P

Có thể chỉnh sửa / dán đầu ra từ một ổ cắm, điều này có thể thực sự hữu ích nếu nó là sự thật. Tôi vẫn nói tùy chọn tốt nhất là một tệp tạm thời, trừ khi có những cảnh báo tồi tệ hơn những câu trả lời được chấp nhận. Tuy nhiên, đối với một lớp vỏ nhất định, có thể có một bí danh / dựng sẵn / cú pháp hiện có để đơn giản hóa một phần của quy trình này, giống như các phần được liệt kê trong trang chủ cho zshmisc (chuyển hướng, v.v.) Một lần nữa - có thể bạn có thể thoát khỏi đầu vào và cung cấp nó làm đối số sau khi đối số vào chế độ chèn, vì vậy nó phân tích cú pháp như thể đã gõ?
John P

Tôi thấy --not-a-termtrong Vim 7.4.1689 trong Ubuntu 16.04 (nhưng không phải 7.4.8056 trên máy Mac), nhưng nó không chặn thông báo.
Tạm dừng cho đến khi có thông báo mới.

@DennisWilliamson Xem thay đổi bởi :help version8.txt. --not-a-termlựa chọn riêng của mình đã được bổ sung trong 7.4.1419và hành vi của nó đã được đổi thành cũng đàn áp các Reading từ stdin ... tin nhắn trong 8.0.1308. (Nhân tiện, các tệp N để chỉnh sửa tin nhắn cũng bị loại bỏ 8.1.1258)
ynn

12

Câu trả lời cho câu hỏi chính xác của bạn :

Tôi có thể ngăn chặn việc chỉ sử dụng các tùy chọn Vim và / hoặc cài đặt vimrc không?

là: không, điều đó là không thể vì phần sau của đoạn mã

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

điều đó có nghĩa là nếu bạn đưa ra -làm đối số cho vim, thì nó sẽ hiển thị một cách máy móc thông điệp đó.

mặc dù, như một công việc xung quanh, nếu bạn sử dụng chuyển hướng tệp thay vì -đối số, bạn sẽ thoát khỏi thông báo:

echo "foo" | vim < /dev/tty

và đây là một ví dụ về MANPAGEcài đặt chỉ hoạt động ™ (được lấy từ các 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
Khi được ALWAYS_USE_GUI xác định, bạn có biết?
muru

2
xem Feature.h (nó được thực hiện khi ALWAYS_USE_GUI không được xác định, vì vậy về cơ bản cho tất cả các phiên bản unix).
Christian Brabandt

2
Tôi không thể có được echo "foo" | vim < /dev/ttycông việc giải quyết . Làm nó cho [2]+ Stopped echo "foo" | vim < /dev/tty.
Léo Léopold Hertz

2
Giống như @ LéoLéopoldHertz, thủ thuật tty không hiệu quả với tôi (gvim đưa ra một tài liệu trống, vim bị nhầm lẫn thực sự với các đầu vào bàn phím, nhưng ít nhất nó không nhận được SIGSTOP). Tôi đã có nhiều may mắn hơn echo "foo" | gvim /dev/stdin(mặc dù vim không phải GUI vẫn sẽ đưa ra khiếu nại về điều đó Vim: Warning: Input is not from a terminal:).
Adam Katz

2
Thôi, quên tin nhắn trước của tôi đi. Bí quyết trong câu trả lời là <(col -b)một phần. Về cơ bản, đó là một số phiên bản tinh vi catđể in trang người đàn ông và cuối cùng bạn có thể thoát khỏi thông điệp của vim vớiecho test | vim < /dev/tty <(cat>
Alexander Solovets

1

Trong Vim, vấn đề này đã được giải quyết trong 234d162cam kết (> = v8.0.1387).

Giải pháp: Không hiển thị thông báo với --not-a-termđã được sử dụng.

Vì vậy, thông báo chỉ được hiển thị khi người dùng chưa chuyển hướng stdin.


Vấn đề tương tự đã được giải quyết trong phiên bản gần đây của Neovim ( > = v0.2.2-dev ) mà bạn có thể sử dụng thay vì Vim.

Khi NVim v0.2.2 được phát hành, bạn sẽ có thể chạy:

$ echo foo | nvim -

mà không có tin nhắn.


0
  1. Với vim của phiên bản 8.0.1387 trở lên, bạn có thể sử dụng --not-a-termtùy chọn.

  2. Đối với phiên bản cũ hơn, hãy sử dụng mẹo sau: $ echo foo | bash -c 'vim < /dev/tty <(cat)'

Đối số đầu tiên /dev/ttybằng cách nào đó lừa Vim nghĩ rằng đầu vào đến từ bàn phím. Tôi đoán, đó là vì isatty (3) trả về True cho tệp đó. Và đối số thứ hai chỉ đơn giản là chuyển qua mọi thứ từ đầu vào tiêu chuẩn của nó đến đầu vào tiêu chuẩn của Vim. Cuối cùng, bash -ctiền tố là bắt buộc để cấu trúc đặc biệt <(...)hoạt động nếu shell không hỗ trợ nó. Trong bash , giải pháp ban đầu có thể được đơn giản hóa thành $ echo foo | vim < /dev/tty <(cat)


Cả hai câu hỏi này đều được đề cập trong các câu trả lời hiện có hoặc chính câu hỏi. Có gì mới ở đây?
muru

@muru Không giải thích được trường hợp thứ hai hoạt động như thế nào và mọi người tự hỏi tại sao nó chỉ hoạt động trong MANPAGE.
Alexander Solovets
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.