Завершение команды оболочки

Команды пользователя могут иметь опцию -complete=shellcmd. Это оказалось довольно разочаровывающим, поскольку вместо того, чтобы работать так же, как встроенное автодополнение vim для его :!, он просто повторно дополняет имена команд оболочки в пути.

Я хотел бы написать команду, которая завершает имена команд, а затем файлы. Есть ли удобный способ сделать это либо с помощью встроенных функций vim, либо с помощью надстройки?


person intuited    schedule 16.04.2011    source источник


Ответы (2)


Почему бы не использовать bash-complete, пока вы этим занимаетесь? Вы должны иметь возможность разветвить оболочку bash с источником /etc/bash_completion и поговорить с ней по каналам, чтобы опросить ее. Таким образом, у вас будут все вкусности оболочки.

Конечно, вы можете поступить так же, как я, и C-z приостановить работу Vim, чтобы вместо этого вернуться в свою оболочку.

person sehe    schedule 16.04.2011
comment
Кажется, что разветвление будет работать, но я надеюсь на что-то, что будет кросс-платформенным. Конечно, это можно сделать с помощью встроенной в vim функции подстановки; самая сложная часть, кажется, правильно разбивает существующую строку. Ну, это и преодоление моего раздражения по поводу того факта, что vim, по-видимому, не предоставляет свое собственное завершение для :!. Надстройка, которая при желании могла бы воспользоваться преимуществами завершения bash и вернуться к использованию функций vim, была бы действительно крутой. - person intuited; 17.04.2011
comment
Кроме того: ^Z здесь бесполезна, потому что сама команда оболочки должна выполняться функцией vim, которая использует ее вывод. - person intuited; 17.04.2011
comment
Хорошо, тогда я понял. На самом деле это может быть хорошим запросом функции (либо для того, чтобы сделать ее подключаемой (предоставить API), либо просто для реализации желаемых улучшений). См. vim-dev или голосовать - person sehe; 18.04.2011
comment
@sehe: я думаю, есть какое-то негласное правило против раскрытия функций программного завершения: bash это тоже не поддерживает. Кажется, есть частичное решение в stackoverflow.com/questions/3520936/, что, похоже, будет работать для завершения, которое выполняется функциями, но не обеспечивает откат к завершению имени файла. Связь с подпроцессом с помощью каналов, похоже, не сработает, поскольку конвейер в TAB просто приведет к тому, что он будет буквально включен в команду. - person intuited; 18.04.2011
comment
Хорошая находка: это именно та стратегия, которую я предложил. Я никогда не говорил ничего похожего на использование каналов для эмуляции нажатий клавиш? <shock/> Я упомянул каналы, чтобы сделать это, но без необходимости разветвления каждый раз (сделайте это «демоном»). Использование труб - это оптимизация, в основном (не нужно преждевременно) - person sehe; 18.04.2011
comment
@sehe: я рассматривал возможность использования каналов таким образом, но казалось, что изменение каталогов и выполнение любых других действий, связанных с окружением, — чтобы изменения в переменных окружения vim отражались в результатах завершения — было бы очень сложно, и не было бы получить от этого много пользы. Однако это зависит от времени запуска bash. Может быть, это был бы идеальный вариант. Во всяком случае, я собираюсь довольно ПОЦЕЛУЙ на этом. - person intuited; 20.04.2011
comment
Хорошие моменты, интуиция. Я надеюсь увидеть конечный результат на этом. Должно быть довольно гладко - person sehe; 20.04.2011

В итоге я написал надстройку для vim под названием shell_complete. На самом деле это не супер-мегазорд-круто, но он делает почти то, что я искал, то есть более или менее имитирует завершение, используемое :!. Это означает, что это своего рода «псевдозавершение оболочки»: он завершает команды для первого «слова» и файлов оттуда. Базовое \ экранирование пробелов работает нормально.

завершение псевдооболочки

Установка shell_complete несколько сложна, особенно для тех, кто не знаком с vim-addon-manager. . Аддон имеет несколько зависимостей, и ни одна из них не «опубликована», то есть VAM еще не знает о них. Вы можете сообщить о них VAM, установив (через git clone; дополнительную информацию см. в документации) другое дополнение, которое я назвал tt_addons. В любом случае, как только вы это сделаете, вы сможете просто :ActivateAddons tt_addons, а затем :ActivateAddons shell_complete.

Если вы не используете VAM, вам придется загрузить (или git clone, что более вероятно) все соответствующие модули, а затем смешать их в каталоге vim, или создать из них пакеты патогенов, или что-то еще. Если вы действительно в конечном итоге захотите сделать это, вероятно, вам стоит начать использовать VAM. Если вы какой-то ворчливый луддит, который отказывается это делать, дайте мне знать, и я могу опубликовать это на vim.org, если будет достойный интерес.

Я думаю, довольно очевидно (по крайней мере, из документации), как использовать shell_complete, но если вы хотите увидеть его в действии, вы можете проверить мой reput, который использует его для завершения своей команды :RePutShell. reput также в настоящее время доступен только через github, и те же предостережения применяются в отношении установки через VAM.

Фактическое завершение оболочки с использованием оболочки

Для справки, я думаю, что предложение sehe об использовании самой оболочки для завершения полностью вспышка. На самом деле я потратил довольно много времени на выяснение того, как это сделать, и решил, что это возможно, по крайней мере, в теории. Сначала я думал, что будет проще сделать это таким образом, чем делать то, что делает shell_complete, но оказалось, что bash (как и vim) не предоставляет никакого программного способа доступа к своим средствам завершения, поэтому вам в конечном итоге придется переопределить их в bash после очистки конфигурации с помощью grep и друзей. Баш очень плох для такого рода вещей, поэтому я трусливо отказываюсь участвовать в этой битве, по крайней мере, на данный момент.

Если кто-то настолько смелый/глупый, чтобы принять этот стандарт, он может воспользоваться хрониками моих мучений. Мне удалось заставить его выполнять завершения, которые обрабатываются пользовательскими функциями завершения. Однако это лишь малая часть головоломки, потому что bash также предоставляет около 6½ других способов завершения. Он как бы дополняет функциональность, предоставляемую shell_complete, поэтому может быть целесообразно синергетически объединить их в своего рода неуклюжий, пьяный Voltron завершения оболочки vim.

person intuited    schedule 10.05.2011