Не раскрывать подстановочный знак при завершении табуляции

Не раскрывать подстановочный знак при завершении табуляции

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

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

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

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

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

$ cat *.foo-
=> кот а.foo-bar
   файл
   а.foo-bar б.foo-bar в.foo-bar

решение1

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

bindkey "^I" expand-or-complete

с

bindkey "^I" complete-word

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

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

  1. Начнем с определения:

    zle -C complete-glob menu-complete compglob
    

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

    [ Примечание: Если вам не нужно автодополнение меню, используйте гораздо более элементарные опцииполное словоилисписок-выборов]

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

    bindkey "^K" complete-glob
    

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

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

    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.

решение2

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

решение3

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

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

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

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

Связанный контент