Що означає "оболонка" в режимі "vi" або "emacs"?


32

Це запитання випливає безпосередньо з відповіді . У цьому випадку я конкретно не можу зрозуміти частину, яка говорить:

У зв'язку з цим його поведінка ближче до emacs ', ніж у режимі bash (readline) / ksh / zsh emacs, але відходить від вбудованого редактора рядків рядків (у канонічному режимі), де Ctrl-Wвидаляється попереднє слово (werase, також in vi ).

Тут ми говоримо про оболонки, а не про редактори, які є двома абсолютно різними програмами. Що означає сказати, що оболонка знаходиться в якомусь режимі редактора?

PS: Свою відповідь ви можете базувати на тому, що я розумію, що таке оболонка, і як використовувати vim для основного редагування.


Йдеться не про функціональність оболонки ядра, а про редагування рядків (що робиш, коли робиш друк і повертаєшся назад та виправляєш себе).
н. 'займенники' м.

Відповіді:


27

У режимі "vi" ви можете редагувати / переходити за поточним запитом оболонки, як рядок у редакторі vi. Ви можете дивитись на це як однорядковий текстовий файл. Аналогічно в режимі "emacs" ви можете редагувати / переходити до поточного командного рядка, використовуючи (деякі) ярлики Emacs.

Приклад

Наприклад, у vi-режимі ви можете зробити щось на кшталт (у bash):

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

У режимі emacs ви можете натиснути, наприклад, Ctrl+, Aщоб перейти на початку рядка (vi: Ctrl+ [, 0або ESC, 0). Ви можете увімкнути режим emacs через set -o emacs(у bash, ksh, zsh тощо).

Лінія читання

Багато інтерактивних програм командного рядка (включаючи bash ) використовують бібліотеку readline . Таким чином, ви можете налаштувати, який режим введення використовувати (vi чи emacs) та інші параметри в одному місці, таким чином, щоб у кожної програми, що використовує лінію читання, був такий самий інтерфейс редагування / навігації.

Наприклад, моя конфігурація readline виглядає так:

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

Наприклад, zsh / ksh не використовує readline, наскільки я знаю, але також підтримує режими vi / emacs, які дуже схожі на bash / readline.

Звичайно, режим vi / emacs в оболонці командного рядка є лише підмножиною повного набору функцій редактора. Не кожна функція має сенс в оболонці командного рядка, а деякі функції підтримуються складніше, ніж інші.

Канонічний режим

Перш ніж були винайдені режими інтерактивних оболонок командного рядка vi / emacs, ваша оболонка використовувала б лише канонічний режим вашого терміналу, який забезпечує лише обмежений набір команд редагування (наприклад, Ctrl+ Wдля видалення останнього слова.


Припустимо, я не знаю, в якому режимі введення я перебуваю. Чи можу я перевірити це, ввівши текст і натисніть [Ctrl] + [A]? якщо курсор рухається до початку свого emacs, ще це vi?
лімовала

2
@limovala, має бути хорошим наближенням. Звичайно залежить від вашої оболонки - якщо CTL + A не працює, інша можливість полягає в тому, що ваша оболонка не включає жодного режиму редагування. Можливо, деякі оболонки також реалізують інші режими редагування. Але на практиці ваш метод повинен бути досить хорошим. Ви також можете перевірити команду vi після цього, щоб бути впевненішими. У bash ви також можете використовувати щось подібне set -o | grep 'emacs\|vi'. У zsh (де у мене є vi-mode) це не працює.
maxschlepzig

bind -P також добре вкаже, в якому режимі перебуває
Пол

23

Ви помітите, що коли ви запускаєте catпідказку оболонки на терміналі, catбудучи передбачуваним, щоб записати stdout того, що він читає з stdin, і натисніть a, ви побачите aвідгомонений назад драйвером терміналу, але catне пише це a(ви бачите лише один a, той, що лунає водієм терміналу).

Однак якщо ви вводите a Backspace b Enter, ви бачите не catвихідний a\010b\015, а b\012( bта новий рядок).

Це тому, що драйвер терміналу (ми говоримо програмне забезпечення в ядрі, а не в емуляторі термінала xterm) реалізує дуже базовий редактор рядків, коли знаходиться в канонічному режимі. Драйвер терміналу можна налаштувати за допомогою ioctl()системних викликів, наприклад, під час використання sttyкоманди. Наприклад, щоб вийти з канонічного режиму, ви можете зробити stty -icanon. Якщо ти зробиш:

stty -icanon; cat

Потім ви побачите одночасно echo(і ви могли б відключити stty -echo), і catвихід.

Цей редактор - це редактор рядків. Тобто, користувач повинен редагувати один рядок тексту, поки він не буде надісланий програмі, що читає термінальний пристрій, після натискання Enter.

Можливості редагування цього редактора дуже обмежені. У більшості реалізацій є лише 4 клавіші редагування (фактично символи), які також можна налаштувати за допомогою stty:

  • стерти ( ^Hабо ^?зазвичай): стерти попередній символ
  • kill ( ^Uзазвичай): порожній (вбити) рядок, що вводиться до цього часу
  • werase ( ^W): видалити попереднє слово
  • lnext ( ^V): введіть наступний символ буквально (скасуйте спеціальне значення усього перерахованого вище)

Ще в старі часи вважалося, що цей редактор ліній драйверів терміналу буде розширений з більш чудовими можливостями. Ось чому жодна з ранніх оболонок не має жодних можливостей редагування командного рядка (ви отримаєте ті самі можливості редагування рядків у рядку оболонки, ніж при запуску, catяк ми це робили вище).

Однак цього насправді ніколи не бувало, можливо, частиною причини є безлад з різними терміналами, що не надсилають одних і тих же символів на деякі клавіші, що дало зрозуміти, що це не повинно бути реалізовано в просторі ядра.

Тож деякі снаряди почали скидати канонічний режим драйвера терміналу та впроваджувати власний редактор рядків. У той час emacsі viбули найпопулярнішими візуальні текстові редактори з абсолютно різними клавішами прив’язки та режиму роботи. У viвас є один режим для введення тексту та один для редагування. В emacs, ви завжди в час написання тексту режим, але редагування здійснюється натисканням комбінації клавіш (наприклад , ^bдля переміщення персонажа назад).

У той час для снарядів не було сенсу придумувати своє власне інше клювання. Це могло б викликати розчарування у людей, які повинні вивчити інше. Однак вибір одного ( emacsабо vi) стилю над іншим був би вірним способом відчуження користувачів іншого редактора.

Відповідно до https://www.usenix.org/legacy/publications/library/proceedings/vhll/full_papers/korn.ksh.a :

Популярні вбудовані функції редагування (vi та emacs режим) ksh були створені розробниками програмного забезпечення в Bell Laboratories; режим редагування ліній VI Пат Салліван та режим редагування рядків emacs Майком Веач. Кожен незалежно модифікував оболонку Bourne, щоб додати ці функції, і обидві були в організаціях, які хотіли використовувати ksh, лише якщо ksh мав відповідний вбудований редактор. Спочатку ідея додавання редагування командного рядка до ksh була відхилена з надією, що редагування рядків перейде в драйвер терміналу. Однак, коли з’ясувалося, що це, швидше за все, не відбудеться, обидва режими редагування рядків були інтегровані в ksh і стали необов'язковими, щоб їх можна було відключити в системах, які забезпечували редагування як частина термінального інтерфейсу.

Тому замість цього вони реалізували обидва та інтерфейс, щоб користувачі могли обирати між ними. kshнайімовірніше, був першим на початку 80-х (повторне використання коду, який було написано окремо для додавання режиму vi та режиму emacs до оболонки Борна, як видно вище), після чого tcsh( tcshспочатку було лише emacsприв'язка клавіш, viрежим був доданий пізніше) та пізніше bashі zshна початку 90-х.

Ви можете перемикатися між двома режимами в bash, zshабо kshз set -o viабо set -o emacs, і з bindkey -eабо bindkey -vв tcshабо zsh.

POSIX фактично вказує viрежим, а не emacsрежим для sh(історія полягає в тому, що Річард Сталлман заперечував проти POSIX, визначаючи emacsрежим дляsh ).

Режим по замовчуванням bash, суспільне надбання варіанти ksh(pdksh, МКШ, oksh), tcshі zshє режим Emacs (хоча і з zsh, це , viякщо ваш $EDITORє vi), в той час як в AT & T ksh, це німий режим , якщо $EDITORабо $VISUALнемає згадок viабо emacs.

kshпізніше також додали gmacsрежим для розміщення користувачів Gosling, emacsякі керували по- Ctrl+Tрізному.

Тепер обробка ^Wв режимі emacs emacsабо в ньому, tcshймовірно, передує weraseсимволу в редакторі лінійки терміналів, тому ми не можемо насправді звинувачувати їх у тому, і моє твердження про "відхід ..." може розглядатися як оманливе. Це просто , що я знаходжу це дратує , коли речі , як emacs, tcshабо infoповодяться по- різному від решти , коли ви набираєте Ctrl-W. Ви можете собі уявити, що мені було набагато більше дратувати, коли деякі програми почали закривати своє вікно під час введення Ctrl-W.


1
pdkshтакож розбирає $EDITORдля viі перемикає режими при запуску; Я це видалив mksh(тим більше, що я дійсно підтримую режим Emacs так чи інакше).
mirabilos

Дякую вам велике доповнення, особливо за детальне обговорення поведінки та історії різних снарядів. Оскільки людина, якій регулярно потрібно працювати в різних дистрибутивах з оболонками, я не налаштовував, це надзвичайно корисно.
BryKKan

Дякую за відмінний історичний контекст. Шкода, що в той час драйвер терміналу не додавались більш досконалі функції вбудованого редагування. У програмах не було би таких бібліотек, як Readline. Я також цікавився, чому режим Emacs не визначений POSIX, щоб посилання на Обґрунтування було цікавим. (Я також поділяю ваше розчарування із ^Wзакриттям вікон).
Ентоні Г - справедливість для Моніки

1
@AnthonyGeoghegan, нам все ще потрібні такі речі, як zle / readline, оскільки такі речі, як імена файлів / завершення команди, насправді не можна зробити в драйвері терміналу.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.