Создать сценарий завершения удара для автоматического заполнения путей после-знака-"равно"?

[srikanth@myhost ~]$ sh sample.sh 

-option1 -option2 -option3

[srikanth@myhost ~]$ cat sample.sh

#!/bin/bash

my_array=(option1 option2 option3)

echo ${my_array[@]} | sed 's/\</-/g'
11
12.11.2012, 18:03
2 ответа

Я нашел решение обеих проблем!

  1. Для не добавления пространства используйте nospace опция. Это может быть сделано двумя способами:

    • Передайте его complete:
      complete -o nospace -F _chromium chromium
    • Используйте compopt встроенный:
      compopt -o nospace (для включения опции)
      compopt +o nospace (для отключения опции)

    Я нашел его в документации Bash по gnu.org, 8.7 Программируемых Завершений Builtins.

  2. Завершение файлов.
    • peterph предложил использовать -f флаг с compgen. Я последовал тому совету и реализовал его как COMPREPLY=( $(compgen -f "$cur") ). Это хорошо работало, пока я не пытался завершить путь, содержащий пробелы.
      На Переполнении стека я нашел этот ответ, который рекомендует ручное создание списка завершения (без использования compgen). Этот подход хорошо работал.
    • Используйте filenames опция сказать Readline, что compspec генерирует имена файлов, таким образом, это может:
      • выполните любую определенную для имени файла обработку (как добавление наклонной черты к именам каталогов, заключение в кавычки специальных символов или подавление конечных пробелов)
      • используйте различные цвета для указания на тип файла (с colored-stats включенный)

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

_chromium() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Some interesting options
    opts="
--disable-web-security
--easy-off-store-extension-install
--incognito
--load-extension=
--pack-extension=
--pack-extension-key=
--user-data-dir=
"
    # Handle --xxxxxx=
    if [[ ${prev} == "--"* && ${cur} == "=" ]] ; then
        compopt -o filenames
        COMPREPLY=(*)
        return 0
    fi
    # Handle --xxxxx=path
    if [[ ${prev} == '=' ]] ; then
        # Unescape space
        cur=${cur//\\ / }
        # Expand tilder to $HOME
        [[ ${cur} == "~/"* ]] && cur=${cur/\~/$HOME}
        # Show completion if path exist (and escape spaces)
        compopt -o filenames
        local files=("${cur}"*)
        [[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]// /\ }" )
        return 0
    fi

    # Handle other options
    COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
    if [[ ${#COMPREPLY[@]} == 1 && ${COMPREPLY[0]} != "--"*"=" ]] ; then
        # If there's only one option, without =, then allow a space
        compopt +o nospace
    fi
    return 0
}
complete -o nospace -F _chromium chromium
11
27.01.2020, 19:58
  • 1
    Потрясающий ответ, большое спасибо. Вы сэкономили много моего времени. Я использовал -f переключатель для завершения пути к файлу, но это не завершается / символ, если это - каталог..., это - мелочь все же. –  Jiri Kremser 07.03.2014, 00:52

Для завершения имен файлов пытаются передать -f кому: compgen.

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

1
27.01.2020, 19:58
  • 1
    Спасибо за предложение -f. Я попробовал его, но это правильно не имеет дело с пробелами: путь /tmp/foo bar результаты в двух записях завершения /tmp/foo и bar. О нежелательном --arg=<SPACE>: Я нашел решение этого и отправил его ответ inthe ниже. –  Rob W 13.11.2012, 18:23

Теги

Похожие вопросы