завершение zsh для пользовательского скрипта :полные параметры из оператора case

Вы можете перечислить файлы по времени модификации (или созданию или доступу )с помощью ls.

просто скажи

ls -t *.txt | head -n5 

, чтобы получить последние 5 последних файлов.txt

Вы можете передать его в myutility с помощью $ ()или xargs.

ls -t *.txt | head -n5 | xargs myutility

Если вам нужна рекурсия, вы можете использовать find.

find -type f -iname "*.txt" | xargs ls -t | head -n5 | xargs myutility

(возможная проблема :у вас должен быть хотя бы один файл.txt, чтобы это работало. вы можете исправить это, но это самое чистое решение ).

РЕДАКТИРОВАТЬ :ОП хотела знать, как обрабатывать имена файлов с пробелами.Вот одно решение:

find -type f -iname "*.txt" | xargs ls -t | head -n5 | tr '\n' '\0' | xargs -0 myutility

Если вы хотите решить возможную проблему, упомянутую выше, вы можете проверить наличие файлов перед -с помощью find..... | egrep '.*' || exitили просто включить какое-то бессмысленное имя файла в ls и проигнорировать предупреждение вроде xargs ls -t ''.

1
08.08.2020, 06:59
1 ответ

Предположим, что функция, для которой вы хотите определить завершение, называется myfunc.

Во-первых, давайте настроим фактическую функцию:

  1. Поместите свою функцию в файл с именем myfunc.
    • Обратите внимание, что это не заканчивается на .zshили .sh.
  2. Убедитесь, что каталог, содержащий файл myfunc, находится в вашем $fpath. Например, если файл myfuncнаходится в ~/func, добавьте его в свой ~/.zshrcфайл :.
    fpath+=( ~/func )
    
  3. Наконец, автозагрузка myfuncв файл ~/.zshrc:
    # We pass a couple of options that make the code less likely to break:
    # -U suppresses alias expansion
    # -z marks the function for zsh-style autoloading == `unsetopt KSH_AUTOLOAD`
    autoload -Uz myfunc
    

Теперь вы сможете использовать myfuncв командной строке (, но без каких-либо дополнений ).

Далее создадим функцию завершения:

  1. Создайте файл с именем _myfunc.
  2. Поместите в этот файл следующее :
    #compdef myfunc
    
    # The line above means "This function defines completions for myfunc."
    # The combination of that line, plus the file name starting with an 
    # `_`, plus having this file's parent dir in your `$fpath`, ensures 
    # this file will get autoloaded when you call `compinit`.
    
    # `+X` makes sure `myfunc`'s definition will get loaded immediately, 
    # even if you have not called this function yet.
    autoload +X -Uz myfunc
    
    # Get the definition of `myfunc` in string form.
    local funcdef=$(type -f myfunc)
    
    # Get the part that matches `case*esac`, then split it on whitespace 
    # and put the resulting words in an array.
    local -a words=( ${=funcdef[(r)case,(r)esac]} )
    
    # Keep only the words that start with `(` and end with `)`.
    # Even if you used the `case` syntax with only the closing `)`s,
    # in `type -f`, your cases will appear with both `(` and `)`.
    local -a required=( ${(M)words:#'('*')'} )
    
    # `-s`: Allow options to `myfunc ` to be stacked, that is, you are 
    #       allowed to specify `myfunc -rm`. If not, remove the `-s` 
    #       option.
    # `*:`: Let this argument be completed in any position.
    _arguments -s \
      {-r,--readonly}'[description for "readonly"]' \
      {-m,--mount}'[description for "mount"]' \
      "*:required argument:( ${required//[()]/}  )"
    
    замените required argument тем, что вы хотите назвать своим аргументом, и заполните описания параметров.
    • Примечание. :Когда вы помещаете функцию в автозагружаемый файл,вам не нужен шаблон funcname() {…}.
  3. Еще раз убедитесь, что каталог, в котором находится этот файл, находится в вашем $fpath.
  4. Убедитесь, что вы сделали autoload -Uz compinit; compinitв своем файле .zshrcи убедитесь, что он запускается после того, как указанный выше каталог был добавлен в ваш $fpath.
  5. Перезапустите оболочку с помощью exec zshили закройте окно терминала и откройте новое.

Теперь вы должны получить завершение для myfunc.


Если readonlyи mountявляются взаимоисключающими, вам нужно будет переписать последнюю строку функции завершения следующим образом:

_arguments \
    (-m --mount){-r,--readonly}'[description for "readonly"]' \
    (-r --readonly){-m,--mount}'[description for "mount"]' \
    "*:required argument:( ${required//[()]/}  )"
5
18.03.2021, 23:14

Теги

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