Завершение команды Bash с полным расширением пути, введенным в историю для vim - PullRequest
0 голосов
/ 15 февраля 2019

Я потратил целую неделю на поиск в Интернете и пробовал много разных способов решить сложную проблему.в основном, я хотел бы использовать vim для редактирования пользовательских команд / скриптов, которые находятся в моем $ PATH, без необходимости вначале переходить к их заданным каталогам или вручную вводить их полные пути в командной строке.

по сути, я бы хотел комбинировать завершение команды stock bash (compgen -c) с одновременным расширением пути, когда указывает сценарии в моем $ PATH как vim FILE ARGUMENTS .Кстати, я использую заглавные буквы, чтобы прояснить, что может быть сложным предметом, а не кричать.

вероятно, проще показать вам, что я пытаюсь сделать, а затем объяснить это.скажем, у меня есть сценарии в каталогах, которые находятся на моем $ PATH

~/bin/x/y/cmd1.sh
~/bin/a/b/cmd2.sh
/ppp/n/m/cmd3.sh

иногда эти сценарии предоставляют функциональные возможности для файлов, которые существуют в других каталогах, поэтому я хотел бы иметь возможность легко их редактировать из любой точки файловой системы.иногда я просто хочу иметь возможность редактировать эти скрипты из других каталогов, потому что это более удобно.Допустим, я в данный момент нахожусь в следующем каталоге.

/completely/different/dir

, но теперь мне нужно vim edit

~/bin/a/b/cmd2.sh

мои варианты для достижения этой цели исключительно с функциональностью bash по умолчанию - это сделать одиниз следующего, что занимает много времени

cd ~/bin/a/b/; vim cmd.sh
vim ~/<tab-complete-my-way-to-file>
open a new terminal window plus some combination of the above

, так как я знаю имена своих пользовательских скриптов, было бы намного проще просто сделать следующее, которое не требует завершения полного пути к файлу иликаталог, а не cd'ing в другой каталог, чтобы изменить мой контекст !!!

vim cmd2.sh

но по умолчанию это не сработает b / c vim нужен полный путь к сценарию

моей первой мыслью было написать функцию-обертку vimкоторый в основном использует which, чтобы выполнить расширение $ PATH для меня, а затем привязать завершение команды bash к моей функции vc следующим образом:

vc () { vim $(which "$@"); }
complete -c vc

я могу запустить следующее в оболочке, чтобы завершить частичные имена сценариев, которыеначните с "c" из вариантов cmd1.sh, cmd2.sh, cmd3.sh

vc c<tab>

, пока я не получу то, что я хочу здесь, что здорово

vc cmd2.sh

, когда я нажму Enter и выполню команду все этоработает нормально, НО не внедряет расширенный путь в командную строку READLINE и, таким образом, ПУТЬ С ПОЛНЫМ ОБЪЕДИНЕНИЕМ 'cmd2.sh' никогда не появляется в моей истории команд !моя история покажет это

vc cmd2.sh

вместо

vc ~/bin/a/b/cmd2.sh

или vim ~ / bin / a / b / cmd2.sh

я хочу этот расширенный путь вмоя история команд, потому что она делает будущие операции с этим файлом сценария очень легкими при повторном использовании истории команд.то есть я могу использовать ls, file, diff, mv, cp, этот расширенный путь намного проще, повторно используя историю, чем писать больше сценариев-оболочек для ls, file, diff, mv, cp и т. д., как я должен был делать с vc выше.

ВОПРОСЫ:

ОПЦИЯ 1

есть ли способ повторно внедрить полный расширенный путь, предоставленный which в моей функции vc, обратно обратно в исходный vc READLINEили просто вставить всю команду vim, которая фактически выполняется в vc, в качестве замены исходной команды vc в READLINE?любой метод, который позволяет мне добавить расширенную команду vim в историю, даже если она в дополнение к оригинальной команде vc, мне подходит.

В основном, как вы можете программно получить доступ и редактировать текущий READLINE в bash?

OPTION 2

обратите внимание, что я также могу сделать что-то подобное ПРЯМО в командной строке в режиме реального времени

vim $(which cmd2.sh) C-x-e 

, что дает мне то, что я хочу (это расширяетпуть, который затем поместит его в историю), но я должен всегда вводить дополнительную подоболочку и какой текст, а также Cxe (для расширения строки) на каждой итерации команды, теряя при этом функциональность завершения команды, что в основном делает это бесполезным.другими словами, есть ли возможность автоматизировать вышесказанное с помощью клавиши привязки, чтобы

vc cmd2.sh 

автоматически преобразовывался сначала в

vim $(which cmd2.sh) 

, а затем автоматически следует C-x-e, так что он расширяется до

vim ~/bin/a/b/cmd2.sh

, но все ли перемещения редактирования, вставки текста и окончательного расширения командной строки происходят в одном макросе bindkey?это может быть лучшим решением из всех.

OPTION 3

в качестве альтернативы, поскольку завершение команды bash автоматически заканчивается в READLINE и, следовательно, в истории, пользовательская функция завершения решит мою проблему.Есть ли способ заставить vc использовать функцию завершения, которая будет ОБА завершать команды в $ PATH при использовании в качестве аргументов vim, как описано выше И ТАКЖЕ ОДНОВРЕМЕННО РАСШИРИТЬ ИХ ИХ ПОЛНЫЕ ПУТИ? *

Я знаю, как написать базовую функцию завершения.бесчисленные часы попыток (которые я предпочитаю не помещать сюда, чтобы уменьшить путаницу / длительность поста) терпят неудачу по той простой причине, что я не уверен, что завершение команды совместимо с одновременным расширением полного пути, потому что оно нарушает традиционное завершение.

с пользовательской функцией завершения, вот что происходит, когда я пытаюсь найти один из моих сценариев "cmd2.sh", который находится в "vim ~ / bin / a / b / cmd2.sh", но начинается с "c "и нажмите" ".

vim c<tab>

вместо того, чтобы дать мне эти дополнения на выбор

cmd1.sh cmd2.sh cmd3.sh

это завершает первыйодин он находит в $ PATH и вставляет его в READLINE, который может быть

/ppp/n/m/cmd3.sh

, когда я действительно хочу

~/bin/a/b/cmd2.sh

, это фактически убивает поиск завершения, потому что слово перед моим курсоромв READLINE теперь начинается с /ppp/n/m/cmd3.sh, и нет никакого способа вернуться к cmd2.sh

Надеюсь, это понятно.

спасибо

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Интересно, что я недавно захотел сделать нечто подобное.Я взломал следующий скрипт bash.Это довольно очевидно.Если я хочу отредактировать один из моих скриптов (например, это ~/bin/vm), я просто запускаю vm vm.Я могу открыть несколько файлов в моем пути, либо в буферах, либо в вертикальных / горизонтальных разбиениях и т. Д.*

0 голосов
/ 15 февраля 2019

Для этого требуется шаблон в вашем файле .bashrc, но он может работать для вас.Он использует стек каталогов (некоторые могут сказать, что он злоупотребляет стеком каталогов, но если вы не используете его ни для чего другого, он может быть в порядке).

В вашем .bashrc, добавьте каждый интересующий вас каталог в ваш стек каталогов.Завершите список вашим домашним каталогом, так как pushd также меняет ваш текущий рабочий каталог.

pushd ~/bin/x/y/cmd1.sh
pushd ~/bin/a/b/cmd2.sh
pushd /ppp/n/m/cmd3.sh
pushd ~

Да, он немного дублирует вашу запись PATH, но я утверждаю, что вам действительно не нужен доступв каждый каталог в вашем PATH, только те, где у вас есть файлы, которые вы собираетесь редактировать.(Вы действительно собираетесь попробовать что-нибудь отредактировать в /bin или /usr/bin?)

Теперь, в вашей интерактивной оболочке, вы можете запустить dirs -v, чтобы увидеть вместе с ее индексом каталоги вваш стек:

$ dirs -v
0 ~
1 /ppp/n/m
2 ~/bin/a/b
3 ~/bin/x/y
4 ~

Теперь, независимо от того, где вы находитесь, если вы хотите редактировать ~/bin/x/y/cmd1.sh, вы можете использовать

$ vi ~3/cmd3.sh

Пока вы не используете popd или pushd в другом месте, чтобы изменить стек, индексы останутся прежними.(Использование pushd добавит новый каталог к ​​вершине стека, увеличивая каждый индекс; popd уменьшит каждый индекс после удаления верхнего каталога.)


Гораздо более простой процесспросто определить некоторые переменные, значения которых являются желаемыми каталогами:

binab=~/bin/a/b
binxy=~/bin/x/y
ppp=/ppp/n/m

и просто развернуть их

$ vi $ppp/cmd3.sh

Оболочка выполняет завершение имени параметра, поэтому имена переменных не имеютбыть особенно коротким, но подход dirstack гарантирует, что вам нужно всего 2 или 3 символа.(Кроме того, он не загрязняет глобальное пространство имен дополнительными переменными.)

...