Як я можу отримати завершення bash для псевдонімів команд?


57

Я шукаю завершення вкладки на псевдонімах мого командного рядка, наприклад, скажу, що я визначив наступний псевдонім:

alias apt-inst='sudo aptitude install'

Чи є спосіб отримати доповнення, надані придатністю, коли я натискаю клавішу вкладки? тобто коли я записую "sudo aptitude install gnumer" і клацніть на вкладці, здатність доповнює це до gnumeric, або якщо була невпевненість у списках усіх доступних пакетів, починаючи з gnumer. Якщо я це роблю, використовуючи свій псевдонім, нічого - не завершення.


1
Дивіться також stackoverflow.com/questions/342969 / ...
nschum

Відповіді:


30

Про це є чудова нитка на форумах Ubuntu . Оле J пропонує наступну функцію визначення псевдоніму:

function make-completion-wrapper () {
  local function_name="$2"
  local arg_count=$(($#-3))
  local comp_function_name="$1"
  shift 2
  local function="
    function $function_name {
      ((COMP_CWORD+=$arg_count))
      COMP_WORDS=( "$@" \${COMP_WORDS[@]:1} )
      "$comp_function_name"
      return 0
    }"
  eval "$function"
  echo $function_name
  echo "$function"
}

Використовуйте його для визначення функції завершення для свого псевдоніма, а потім вкажіть цю функцію як доповнення для псевдоніма:

make-completion-wrapper _apt_get _apt_get_install apt-get install
complete -F _apt_get_install apt-inst

Я вважаю за краще використовувати псевдоніми для додавання завжди використовуваних аргументів до існуючих програм. Наприклад, з grep, я завжди хочу пропустити пристрої та бінарні файли, тому я роблю псевдонім для grep. Для додавання нових команд, таких як grepbin, я використовую скрипт оболонки у своїй ~/binпапці. Якщо ця папка знаходиться на вашому шляху, вона автоматично завершиться.


2
Дивовижно, я боявся, що це буде неможливо.
levesque

Зауважте, у цього коду є деякі проблеми. Дивіться мою відповідь щодо їх пояснення та вирішення.
Том Хейл

Примітка: я використовував цю техніку для іншої команди, і мені довелося використовувати complete -o default -F ...замість того, complete -F ...щоб такі речі, як автоматичне заповнення імені файлів, працювали правильно при передачі аргументів (Bash 4.3.46).
joelittlejohn

28

Спробуйте повний псевдонім , який точно вирішує цю проблему.

Після його встановлення ви можете скористатися однією загальною функцією для завершення багатьох таких псевдонімів:

complete -F _complete_alias <myalias1>
complete -F _complete_alias <myalias2>
complete -F _complete_alias <myalias3>

Ви можете створити файл Complete_alias у кожному екземплярі bash через .bash_profileабо подібне.

установка

mkdir ~/.bash_completion.d
curl https://raw.githubusercontent.com/cykerway/complete-alias/master/bash_completion.sh \
     > ~/.bash_completion.d/complete_alias

застосування

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

containerтепер може автоматично _docker()завершитися оригінальним обробником завершення;

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   

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

@muru Я думав вставити тут якийсь код, але це, мабуть, довше, ніж тут прийнято. Я припускаю, що у людей немає проблем з читанням розділу « Встановити» у файлі README, і в цьому випадку це лише кілька рядків.
Cyker

2
справа в тому, щоб мати можливість судити про те, чи варто відвідування зазначеної README лише з відповіді.
муру

Це адекватна відповідь, і вона точно вирішує проблему.
Ярослав Рахматуллін

1
Це відмінна і дуже вичерпна відповідь, яка прекрасно працює, дякую !. Це, ймовірно, оновлено, оскільки у @muru були проблеми.
Брайан Топінг

3

Відповідь 2018 року

Ви повинні додати свій псевдонім до програми "завершено". Залежно від виду автозавершення, якого ви хочете досягти, ви повинні використовувати -c або -F.

Для автоматичного заповнення пакета:

complete -c name_of_your_alias

Для автоматичного завершення команди:

complete -F name_of_your_alias

Щоб перевірити, чи правильно додано ваш псевдонім:

complete | grep name_of_your_alias

Нарешті, щоб видалити псевдонім із "завершення":

complete -r name_of_your_alias

У вашому випадку:

complete -c apt-inst

1
Будь ласка, не продовжуйте свою відповідь у коментарях. Якщо у вас є що сказати, відредагуйте їх у відповідь.
G-Man

2
complete -F xxxне працює на OSX (він просто показує використання complete: usage: complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]). Чи є у вас вказівник? Дякую.
Ентоні Конг

Використовуйте це замість цього: unix.stackexchange.com/questions/224227/…
Rich

2

Ось код з відповіді Шона Дж. Гоффа з деякими вдосконаленнями:

  • Виправлені помилки синтаксису, виділені shell-check, наприклад, першою "з "$@"фактично закінчених рядка визначення функції.
  • Видалено return 0так, що повернене значення основної функції може бути передано назад абоненту.

.

# Wraps a completion function, eg for use with an alias.
# Usage:
# make-completion-wrapper <actual completion function> <name of new func.>
#                         <command name> <list supplied arguments>
# eg.
#   alias agi='apt-get install'
#   make-completion-wrapper _apt_get _apt_get_install apt-get install
#     # defines a function called _apt_get_install (that's $2) that will
#     # complete the 'agi' alias. 
#   complete -F _apt_get_install agi
function make-completion-wrapper {
  local function_name="$2"
  local arg_count=$(( $#-3 ))
  local comp_function_name="$1"
  shift 2
  local function="function $function_name {
      (( COMP_CWORD += $arg_count ))
      COMP_WORDS=( \"\$@\" \${COMP_WORDS[@]:1} )
      \"$comp_function_name\"
    }"
  eval "$function"
  # echo "$function"
}
export -f make-completion-wrapper

Боюсь не працює для мене 4.3.46 Боюся. Відповідь Шон Дж Гоффа дійсно працює.
joelittlejohn

1
"Закінчення" рядка визначення функції призначено за призначенням; справа полягає в тому, щоб включити аргументи зовнішньої функції в COMP_WORDSмасив. Якщо ми будемо використовувати make-completion-wrapper _apt_get _apt_get_install apt-get installяк приклад, після shift 2, $@містить apt-get install. Визначення функції включає apt-get install(два буквальних слова) при призначенні COMP_WORDS.
Джеффі

0

Як розширення до відповіді @Giles, наступна функція зручності автоматично називає обгортку, згенеровану make-completion-wrapperдля того, щоб можна було визначити завершення в одному рядку:

function complete-alias  {
    # uses make-completion-wrapper: https://unix.stackexchange.com/a/4220/50978
    # example usage
    # complete-alias _pass pshow pass show
    # complete-alias _pass pgen pass generate

    EXISTING_COMPLETION_FN=${1} && shift
    ALIAS=${1} && shift
    AUTOGEN_COMPLETION_FN="__autogen_completion_${ALIAS}"
    make-completion-wrapper ${EXISTING_COMPLETION_FN} ${AUTOGEN_COMPLETION_FN} ${*}
    complete -F ${AUTOGEN_COMPLETION_FN} ${ALIAS}
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.