Как реализовать завершение табуляции в стиле bash?

Я пытаюсь определить, как система выводит символы на стандартный ввод, то есть как она выводит символы, которые пользователь может удалить и которые считаются вводом, если пользователь нажимает «Ввод».

Я использую C, но я был бы очень удивлен, если бы решение зависело от языка.

Спасибо за любые идеи! : Д


person zslayton    schedule 07.10.2009    source источник
comment
Какова цель здесь? Библиотека GNU Readline содержит поддержку завершения и, конечно же, находится под лицензией GPL.   -  person Cascabel    schedule 07.10.2009
comment
Мне действительно любопытно больше всего на свете. Мне не ясно, как Bash удается это сделать, и я хотел бы знать - это похоже на то, что я мог бы хорошо использовать в сценариях / утилитах. Спасибо, что указали мне на библиотеку GNU Readline, я не был знаком с ней. Я уверен, что обращусь к этому, если мне когда-нибудь понадобится реализовать эту функциональность. Теперь, я думаю, мне нужно выяснить, как это делает библиотека Readline.   -  person zslayton    schedule 07.10.2009
comment
Зак: Я думаю, что мой ответ касается того, как это делает библиотека Readline.   -  person Laurence Gonsalves    schedule 08.10.2009


Ответы (4)


Несколько человек указали, что bash использует readline, и это правда, но я думаю, что вы действительно спрашиваете, как он может увидеть, что вы набрали, прежде чем нажать Enter.

Ответ заключается в том, что ttys (т.е. терминалы) можно переключить в «сырой режим», в котором обработка ввода терминала отключена, и тогда вы будете видеть каждый символ по мере его поступления. Это также отключает автоматическое повторение введенных символов.

Дополнительную информацию см. в этом руководстве по Чтение одного символа из файла или терминала. .

person Laurence Gonsalves    schedule 07.10.2009
comment
Является ли необработанный режим ttys тем, что позволяет программе выводить предложение на экран таким образом, что когда вы нажимаете ввод, оно включается, как если бы пользователь набрал его сам? Если да, то как получить доступ к tty для чтения и записи? Это простой тип вызова open('/dev/tty')? - person zslayton; 08.10.2009
comment
В необработанном режиме программа видит нажатия клавиш еще до того, как пользователь нажмет Enter. Когда вы набираете печатный ключ (например, букву, цифровой символ), программа возвращает его обратно. Когда вы нажимаете клавишу ввода, он уже отслеживает то, что вы набрали, и просто принимает буфер в ответ на нажатие клавиши ввода. - person Laurence Gonsalves; 08.10.2009
comment
В подготовленном режиме терминал вместо этого будет повторять все, что вы набираете, но не отправляет то, что вы набрали, в программу, пока вы не нажмете Enter. bash переключает tty обратно в приготовленный режим непосредственно перед запуском других программ. Вы можете получить представление о том, чем режим приготовленный отличается от режима сырого, запустив команду sleep 300, а затем набрав ее во время выполнения команды sleep. Обратите внимание, что вы можете вводить строки и даже иметь очень простые средства редактирования (например, возврат). Как только вы нажмете Enter, эта строка будет зафиксирована, и когда команда sleep завершится, bash попытается выполнить эти строки (так что будьте осторожны!). - person Laurence Gonsalves; 08.10.2009

Как говорит iny, bash использует readline для ввода. Исходный код доступен здесь, и есть файл с именем complete. в.

Чтобы ответить на ваш вопрос, я не думаю, что они на самом деле печатаются на стандартный ввод. Строка чтения содержит своего рода буфер для содержимого строки, которую редактирует пользователь, и в него печатается завершение. Когда пользователь нажимает клавишу ввода, содержимое буфера отправляется любой программе, которая хочет прочитать строку, а в случае с bash передается на стандартный ввод. (Readline этого не делает — другие программы, использующие readline, могут просто сохранить значение в строку для последующего использования.)

person Cascabel    schedule 07.10.2009
comment
Спасибо, это имеет смысл! Спасибо также iny. - person zslayton; 07.10.2009

Он использует библиотеку readline для обработки ввода, а readline предоставляет историю и завершение.

Чтобы реализовать завершение, необходим доступ к обработке ввода с клавиатуры. Завершение должно иметь возможность модифицировать используемый им буфер. После этого нужно просто просмотреть текущий ввод и проверить, какие дополнения найдены. Фактическая логика завершения может работать по-разному.

person iny    schedule 07.10.2009

Вот фрагмент C, который реализует завершение табуляции через readline:

http://github.com/rupa/el

person Community    schedule 08.10.2009