Как сделать так, чтобы пользовательские дополнения zsh «просто работали»?

sed -e '
   1{
      :loop
         N
      /\n\.$/!bloop
      s///;h
      N;s/.*\n//
   }

   G
   y/\n_/_\n/
   s/^\([^_]*\)_\(.*_% BEGIN_[^_]*_\)[^_]*/\2\1/
   y/\n_/_\n/
' input.txt foobar.txt

Работа

  • В этом методе порядок аргументов следующий: :input.txt, затем foobar.txt
  • Поскольку POSIX sedне имеет представления о том, когда заканчивается один файл и начинается следующий, нам нужно либо добавить eof Различение -, скажем, ., ИЛИ основываясь на типе данных в двух файлах. файлов, чтобы определить, в каком файле мы находимся. В нашем случае я выбираю первый метод.
  • Сначала мы сохраняем файл input.txt в резервной области целиком.
  • Затем для каждой строки, прочитанной из файла foobar.txt, мы добавляем к ней пространство для хранения, а затем заменяем вторую строку после строки % BEGINв пространстве шаблонов на первую строку. Примечание :У нас есть то, что multiline pattern space, что такое...\n...\n...\n...
3
14.08.2019, 11:06
1 ответ

TL,DR :При обычной работе просто поместите файл в соответствующий каталог. Во время тестирования вам нужно удалить файл кеша(.zcompdumpпо умолчанию, но пользователи могут поместить его в другое место, и о -мой -zsh помещает его в другое место ).


Простой ответ — записать функцию завершения в файл, где первая строка —#compdef fab. Файл должен находиться в каталоге $fpath.

Файл может содержать либо тело функции, либо определение функции, за которым следует вызов функции. То есть либо файл содержит что-то вроде

#compdef fab
_arguments …

или

#compdef fab
function _fab {
  _arguments …
}
_fab "$@"

Файл должен присутствовать на $fpathперед запуском compinit. Это означает, что вам нужно обратить внимание на порядок вещей в .zshrc:: сначала добавьте любые пользовательские каталоги в $fpath, а затем вызовите compinit. Если вы используете такой фреймворк, как oh -my -zsh, не забудьте добавить любые пользовательские каталоги в $fpathперед кодом oh -my -zsh.

compinit— это функция, которая инициализирует систему завершения. Он читает все файлы в $fpathи проверяет их первую строку на наличие магических директив#autoloadи #compdef.

.zcompdump— это файл кэша, используемый compinit. ~/.zcompdump— расположение по умолчанию; вы можете выбрать другое место при запуске compinit. О, -мой -zsh вызывает compinitс опцией -dдля использования другого имени файла кеша, заданного переменной ZSH_COMPDUMP, которая по умолчанию равна

ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"

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

Я думаю, что все ваши проблемы связаны с устаревшим файлом кэша (, и поэтому вы слишком усложняете ситуацию ). К сожалению,Алгоритм zsh для определения того, устарел ли файл кэша , не идеален, по-видимому, в интересах скорости. Он не проверяет содержимое или временные метки файлов на $fpath, а просто подсчитывает их. Файл .zcompdumpначинается со строки вида

#files: 858     version: 5.1.1

Если версия zsh и количество файлов правильные, zsh загружает файл кеша.

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

  • Если вы добавите новый файл в $fpath, это сделает кеш недействительным.
  • В более общем случае, если вы добавляете и удаляете файлы на $fpath, а общее количество удаленных файлов не равно общему количеству удаленных файлов, кэш становится недействительным.
  • Если вы переместите файл в другой каталог в $fpathбез изменения его имени, это не повлияет ни на что в кеше, поэтому кеш останется правильным.
  • Если вы измените файл в $fpathбез изменения его первой строки, это не повлияет ни на что в кеше, поэтому кеш останется правильным.

Вот несколько распространенных сценариев, когда кеш становится недействительным, но zsh этого не понимает.

  • Вы добавляете несколько файлов в $fpathи удаляете точно такое же количество файлов.
  • Вы переименовываете файл в $fpath.
  • Вы добавляете или изменяете строку#compdef(или#autoload)вверху файла.

Этот последний пункт имеет тенденцию кусаться во время тестирования. При изменении строки #compdefнеобходимо удалить файл .zcompdumpи перезапустить zsh (или перезапустить compinit).

Если вы помещаете дополнения в распространяемый пакет, просто перетащите файл завершения в системный каталог -по всему $fpath. Для пакета Ubuntu подходящим местом будет /usr/share/zsh/vendor-completions. Для чего-то, установленного под /usr/local, это /usr/local/share/zsh/site-functions.Это все, что вам нужно сделать.

Единственное, что не является прозрачным, — это необходимость изменить строку #compdefпри обновлении или удалить или переименовать некоторые файлы. В таких случаях пользователям потребуется удалить свой файл кеша, а это невозможно сделать из пакета, который устанавливается на многопользовательской машине.

5
27.01.2020, 21:24

Теги

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