5

Мне интересно, как я могу настроить Zsh, чтобы не расширять подстановочный знак в имени файла. Например, у меня есть каталог из пары сотен файлов, который называется следующим образом:

a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo

Я хотел бы иметь возможность выполнить сопоставление табуляции после подстановочного знака, поэтому

cat *.foo-< tab > => cat *.foo-bar

Вот что я получаю вместо этого:

$  cat *.foo-
=> cat a.foo-bar
   file
   a.foo-bar b.foo-bar c.foo-bar

3 ответа3

5

Один вариант заключается в том, что вы заменяете привязку ключа по умолчанию для клавиши TAB

bindkey "^I" expand-or-complete

с

bindkey "^I" complete-word

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

Решить это гораздо сложнее. Вы должны написать свой собственный виджет завершения (см. man zshcompwid).

  1. Давайте начнем с определения:

    zle -C complete-glob menu-complete compglob
    

    Это вводит новый виджет complete-glob, который ведет себя как menu-complete и использует функцию оболочки compglob для генерации совпадений.

    [Примечание: если вы не хотите дополнения меню, используйте гораздо более элементарные опции complete-word или list-choices ]

  2. Свяжите этот новый виджет с удобным сочетанием клавиш, например CTRL+K:

    bindkey "^K" complete-glob
    

    Не связывайте это с TAB , так как виджет в его текущей форме только завершает файлы!

  3. Определите функцию оболочки compglob следующим образом, которая выполняет реальную работу:

    compglob () {
        setopt localoptions globsubst
        compset -P '*'
        files=(${IPREFIX}*) 
        display=(${files/${IPREFIX}/${(q)IPREFIX}}) 
        glob=(${files/${IPREFIX}/}) 
        compadd -d display -- $glob
    }
    
  4. Демонстрация:

    $ touch a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo
    $ cat *.f<CTRL+K>
    $ cat *.foo
    \*.foo      \*.foo-bar
    

    Единственный недостаток, который я вижу, это \ перед звездой в представленном списке. Но это только оптический недостаток, так как завершение правильное: *.foo или *.foo-bar .

0

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

0

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

Вы также можете копаться в man zshoptions , man zshcompctl , man zshcompwid и / или подобных. Завершение для zsh довольно сложное, так что я думаю, что вполне может быть способ сделать это.

Также обратите внимание, несколько связанный вопрос:

Как мне получить автозаполнение zsh для завершения подстановочных знаков, как это делает bash?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .