Vỏ có nghĩa là gì trong chế độ của Vi vi hay chế độ của Emacs?


32

Câu hỏi này theo sau trực tiếp từ câu trả lời . Trong trường hợp này, tôi đặc biệt không thể hiểu được phần nói:

Về mặt đó, hành vi của nó gần với emacs 'hơn với chế độ emacs bash (readline) / ksh / zsh, nhưng rời khỏi trình chỉnh sửa dòng nhúng trình điều khiển đầu cuối (trong chế độ chính tắc), trong đó Ctrl-Wxóa từ trước đó (werase, cũng trong vi ).

Ở đây chúng ta đang nói về shell và không phải trình soạn thảo là hai chương trình hoàn toàn khác nhau. Nó có nghĩa gì khi nói shell nằm trong một số chế độ soạn thảo?

PS: Bạn có thể dựa trên câu trả lời của mình dựa trên tiền đề rằng tôi hiểu shell là gì và cách sử dụng vim để chỉnh sửa cơ bản.


Đây không phải là về chức năng shell core mỗi se, mà là về chỉnh sửa dòng (những gì bạn làm khi bạn mắc lỗi đánh máy và quay lại và tự sửa lỗi).
n. 'đại từ' m.

Câu trả lời:


27

Trong chế độ "vi", bạn có thể chỉnh sửa / điều hướng trên dấu nhắc shell hiện tại giống như một dòng trong trình soạn thảo vi. Bạn có thể xem nó như một tệp văn bản một dòng. Tương tự trong chế độ "emacs", bạn có thể chỉnh sửa / điều hướng dòng lệnh hiện tại bằng cách sử dụng (một số) phím tắt của Emacs.

Thí dụ

Ví dụ: trong chế độ vi, bạn có thể làm một cái gì đó như (trong bash):

$ set -o vi
$ ls hello world
<ESC>
bbdw # results in
$ ls world

Trong chế độ emacs, bạn có thể nhấn eg Ctrl+ Ađể nhảy khi bắt đầu một dòng (vi: Ctrl+ [, 0hoặc ESC, 0). Bạn có thể bật chế độ emacs thông qua set -o emacs(trong bash, ksh, zsh, v.v.).

Đường đọc

Rất nhiều chương trình dòng lệnh tương tác (bao gồm cả bash ) sử dụng thư viện readline . Do đó, bạn có thể định cấu hình chế độ đầu vào nào sẽ sử dụng (vi hoặc emacs) và các tùy chọn khác ở một nơi sao cho mọi chương trình sử dụng đường đọc có cùng giao diện chỉnh sửa / điều hướng.

Ví dụ: cấu hình readline của tôi trông như sau:

$ cat ~/.inputrc 
set editing-mode vi
set blink-matching-paren on

Ví dụ, zsh / ksh không sử dụng readline theo như tôi biết, nhưng cũng hỗ trợ các chế độ vi / emacs rất giống với chế độ bash / readline.

Tất nhiên, chế độ vi / emacs trong vỏ dòng lệnh chỉ là một tập hợp con của bộ tính năng soạn thảo hoàn chỉnh. Không phải mọi tính năng đều có ý nghĩa trong trình bao dòng lệnh và một số tính năng phức tạp hơn để hỗ trợ so với các tính năng khác.

Chế độ Canonical

Trước khi chế độ vi / emacs của trình vỏ dòng lệnh tương tác 'được phát minh', trình bao của bạn sẽ chỉ sử dụng chế độ chính tắc của thiết bị đầu cuối của bạn, nó chỉ cung cấp một bộ lệnh chỉnh sửa giới hạn (ví dụ Ctrl+ Wđể xóa từ cuối cùng.


Giả sử tôi không biết tôi đang bật chế độ Nhập liệu nào. Tôi có thể xác minh nó bằng cách nhập một số văn bản và nhấn [Ctrl] + [A] không? nếu con trỏ di chuyển để bắt đầu emacs của nó khác nó vi?
limovala

2
@limovala, nên là một xấp xỉ tốt. Tất nhiên phụ thuộc vào trình bao của bạn - nếu CTL + A không hoạt động thì khả năng khác là trình bao của bạn không bao gồm bất kỳ chế độ chỉnh sửa nào. Có lẽ một số shell cũng thực hiện các chế độ chỉnh sửa khác. Nhưng trong thực tế phương pháp của bạn nên đủ tốt. Bạn cũng có thể kiểm tra bằng lệnh vi sau đó để chắc chắn hơn. Trong bash bạn cũng có thể sử dụng một cái gì đó như set -o | grep 'emacs\|vi'. Trong zsh (nơi tôi có chế độ vi), mặc dù vậy, nó không hoạt động.
maxschlepzig

liên kết -P cũng sẽ đưa ra dấu hiệu tốt về chế độ nào đang ở trong
Paul

23

Bạn sẽ nhận thấy rằng khi bạn chạy catở dấu nhắc shell trên thiết bị đầu cuối, catđược cho là viết để xuất bản những gì nó đọc từ stdin và nhấn a, bạn sẽ thấy atrình điều khiển thiết bị đầu cuối bị dội lại, nhưng catbạn không viết điều đó a(bạn thấy chỉ có một a, một tiếng vang bởi trình điều khiển thiết bị đầu cuối).

Tuy nhiên, nếu bạn nhập a Backspace b Enter, bạn không thấy catxuất ra a\010b\015, nhưng b\012( bvà dòng mới).

Đó là bởi vì trình điều khiển thiết bị đầu cuối (chúng ta đang nói phần mềm trong kernel, không phải trong trình giả lập thiết bị đầu cuối như xterm) thực hiện trình chỉnh sửa dòng rất cơ bản khi ở chế độ chính tắc . Trình điều khiển đầu cuối có thể được cấu hình bằng ioctl()các cuộc gọi hệ thống như khi sử dụng sttylệnh. Ví dụ, để rời khỏi chế độ chính tắc, bạn có thể làm stty -icanon. Nếu bạn làm:

stty -icanon; cat

Sau đó, bạn sẽ thấy cả echo(mà bạn có thể đã tắt stty -echo) và catđầu ra cùng một lúc.

Biên tập viên đó là một biên tập viên dòng. Nghĩa là, người dùng sẽ chỉnh sửa một dòng văn bản cho đến khi nó được gửi đến ứng dụng đọc thiết bị đầu cuối khi nhấn Enter.

Khả năng chỉnh sửa của biên tập viên đó rất hạn chế. Trong hầu hết các triển khai, chỉ có 4 phím chỉnh sửa (thực tế là các ký tự) cũng có thể được cấu hình với stty:

  • erase ( ^Hhoặc ^?thường): xóa ký tự trước
  • kill ( ^Uthường): trống (kill) dòng đã nhập cho đến nay
  • werase ( ^W): xóa từ trước đó
  • lnext ( ^V): nhập ký tự tiếp theo theo nghĩa đen (hủy bỏ ý nghĩa đặc biệt của tất cả các mục trên)

Quay trở lại những ngày xưa, người ta đã nghĩ rằng trình chỉnh sửa dòng trình điều khiển đầu cuối sẽ được mở rộng với khả năng của người hâm mộ. Đó là lý do tại sao không có trình bao đầu tiên nào có bất kỳ khả năng chỉnh sửa dòng lệnh nào (bạn sẽ có cùng khả năng chỉnh sửa dòng tại dấu nhắc trình bao so với khi chạy catnhư chúng tôi đã làm ở trên).

Tuy nhiên, điều đó thực sự không bao giờ xảy ra, có thể một phần lý do là sự lộn xộn với các thiết bị đầu cuối khác nhau không gửi cùng một ký tự khi nhấn một số phím, điều đó chứng minh rằng không nên thực hiện trong không gian kernel.

Vì vậy, một số shell bắt đầu bỏ chế độ chính tắc của trình điều khiển đầu cuối và thực hiện trình soạn thảo dòng riêng của họ. Vào thời điểm đó, emacsvilà các trình soạn thảo văn bản trực quan phổ biến nhất với chế độ thao tác và ràng buộc phím hoàn toàn khác nhau. Trong vi, bạn có một chế độ để nhập văn bản và một chế độ để chỉnh sửa. Trong emacs, bạn luôn ở chế độ văn bản , nhưng việc chỉnh sửa được thực hiện bằng cách nhấn tổ hợp phím (muốn ^bdi chuyển ký tự lùi lại).

Không có điểm nào cho đạn pháo vào thời điểm đó để đưa ra ràng buộc khóa khác nhau của riêng họ. Điều đó sẽ gây ra sự thất vọng cho mọi người khi phải học một cách khác. Tuy nhiên, chọn một ( emacshoặc vi) kiểu này so với kiểu khác sẽ là một cách chắc chắn để xa lánh người dùng của trình chỉnh sửa khác .

Theo https://www.usenix.org/legacy/publications/lvern/proceedings/vhll/full_ con / korn.ksh.a :

Các tính năng chỉnh sửa nội tuyến phổ biến (chế độ vi và emacs) của ksh đã được tạo bởi các nhà phát triển phần mềm tại Phòng thí nghiệm Bell; chế độ chỉnh sửa dòng vi của Pat Sullivan và chế độ chỉnh sửa dòng emacs của Mike Veach. Mỗi người đã sửa đổi độc lập trình vỏ Bourne để thêm các tính năng này và cả hai đều ở trong các tổ chức muốn sử dụng ksh chỉ khi ksh có trình soạn thảo nội tuyến tương ứng. Ban đầu ý tưởng thêm chỉnh sửa dòng lệnh vào ksh đã bị từ chối với hy vọng rằng chỉnh sửa dòng sẽ chuyển sang trình điều khiển đầu cuối. Tuy nhiên, khi rõ ràng điều này sẽ không xảy ra sớm, cả hai chế độ chỉnh sửa dòng được tích hợp vào ksh và được tùy chọn để chúng có thể bị vô hiệu hóa trên các hệ thống cung cấp chỉnh sửa như một phần của giao diện đầu cuối.

Vì vậy, thay vào đó, họ đã triển khai cả hai và một giao diện để người dùng lựa chọn giữa hai. kshcó lẽ là lần đầu tiên vào đầu những năm 80 (sử dụng lại mã được viết riêng để thêm chế độ vi và chế độ emacs vào vỏ Bourne như đã thấy ở trên), sau đó tcsh( tcshban đầu chỉ có emacsràng buộc khóa, vichế độ được thêm vào sau) và sau đó bashzshvào đầu những năm 90.

Bạn chuyển đổi giữa hai chế độ trong bash, zshhoặc kshvới set -o vihoặc set -o emacs, và với bindkey -ehoặc bindkey -vtrong tcshhoặc zsh.

POSIX thực sự chỉ định vichế độ chứ không phải emacschế độ cho sh(câu chuyện mà Richard Stallman phản đối POSIX chỉ định emacschế độ chosh ).

Chế độ mặc định cho bash, các biến thể miền công cộng của ksh(pdksh, mksh, oksh) tcshzshlà chế độ emacs (mặc dù với zsh, đó là vinếu $EDITORlà của bạn vi), trong khi ở AT & T ksh, đó là chế độ câm trừ khi $EDITORhoặc $VISUALđề cập đến vihoặc emacs.

kshsau đó cũng đã thêm một gmacschế độ để phù hợp với người dùng của Gosling emacsxử lý Ctrl+Tkhác nhau.

Bây giờ việc xử lý ^Wtrong emacshoặc trong tcshchế độ emacs có thể có trước werasenhân vật trong trình chỉnh sửa dòng thiết bị đầu cuối, vì vậy chúng tôi thực sự không thể đổ lỗi cho họ về điều đó và tuyên bố của tôi về "khởi hành ..." có thể bị coi là sai lệch. Chỉ là tôi thấy khó chịu khi những thứ như emacs, tcshhoặc infocư xử khác với mọi thứ khác khi bạn gõ Ctrl-W. Bạn có thể tưởng tượng tôi thấy nó khó chịu hơn rất nhiều khi một số ứng dụng bắt đầu đóng cửa sổ của chúng khi bạn gõ Ctrl-W.


1
pdkshcũng phân tích cú pháp $EDITORcho vivà chuyển đổi chế độ khi khởi động; Tôi đã gỡ bỏ nó cho mksh(đặc biệt là khi tôi chỉ thực sự duy trì chế độ Emacs).
mirabilos

Cảm ơn bạn rất nhiều, đặc biệt là với các cuộc thảo luận chi tiết về hành vi và lịch sử của các vỏ khác nhau. Là một người thường xuyên phải làm việc trong các bản phát hành khác nhau với trình bao tôi không cấu hình, điều này rất hữu ích.
BryKKan

Cảm ơn bối cảnh lịch sử tuyệt vời. Thật đáng tiếc khi các tính năng chỉnh sửa nội tuyến phức tạp hơn không được thêm vào trình điều khiển thiết bị đầu cuối tại thời điểm đó. Không cần các chương trình bao gồm các thư viện như Readline. Tôi cũng đã tự hỏi tại sao chế độ Emacs không được chỉ định bởi POSIX để liên kết đến Cơ sở lý luận là thú vị. (Tôi cũng chia sẻ sự thất vọng của bạn với ^Wviệc đóng cửa sổ).
Anthony G - công lý cho Monica

1
@AnthonyGeoghegan, chúng tôi vẫn cần những thứ như zle / readline vì những thứ như tên tệp / hoàn thành lệnh không thể thực sự được thực hiện trong trình điều khiển thiết bị đầu cuối.
Stéphane Chazelas
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.