Многоточечные пути в zsh, как `cd ....`

Все оболочки понимают эти команды:

$ cd .
$ cd ..

И зш тоже поймет

$ cd ...
$ cd ....

При условии, что вы говорите:

$ alias -g ...='../..'
$ alias -g ....='../../..'

Теперь, как я могу заставить это сделать правильное завершение табуляции, когда я начал печатать cd ..../<TAB>? Я помню, что это было реализовано в oh-my-zsh, но я прекратил его использовать сейчас.

Было бы также признательно, если бы это работало не только для cdСкажи, что я хочу выполнить cat ..../a/b/..../c/d | less,

4 ответа

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

function expand-dots() {
    local MATCH
    if [[ $LBUFFER =~ '\.\.\.+' ]]; then
        LBUFFER=$LBUFFER:fs%\.\.\.%../..%
    fi
}

function expand-dots-then-expand-or-complete() {
    zle expand-dots
    zle expand-or-complete
}

function expand-dots-then-accept-line() {
    zle expand-dots
    zle accept-line
}

zle -N expand-dots
zle -N expand-dots-then-expand-or-complete
zle -N expand-dots-then-accept-line
bindkey '^I' expand-dots-then-expand-or-complete
bindkey '^M' expand-dots-then-accept-line

То, что я сделал, чтобы справиться с той же проблемой, это просто позволить zsh заполнить ../.. когда я печатаю ... и имеет смысл расширять его таким образом. Может подойдет вам (или нет:-P):

if is-at-least 5.0.0 && [[ ! $UID -eq 0 ]]; then                                                                                                                             
  ## http://www.zsh.org/mla/users/2010/msg00769.html                                                                                                                       
  function rationalise-dot() {                                                                                                                                             
    local MATCH # keep the regex match from leaking to the environment                                                                                                   
    if [[ $LBUFFER =~ '(^|/| |      |'$'\n''|\||;|&)\.\.$' && ! $LBUFFER = p4* ]]; then                                                                                  
        #if [[ ! $LBUFFER = p4* && $LBUFFER = *.. ]]; then                                                                                                               
        LBUFFER+=/..                                                                                                                                                     
    else                                                                                                                                                                 
        zle self-insert                                                                                                                                                  
    fi                                                                                                                                                                   
}                                                                                                                                                                        
zle -N rationalise-dot                                                                                                                                                   
bindkey . rationalise-dot                                                                                                                                                
bindkey -M isearch . self-insert                                                                                                                                         
fi

У меня также есть псевдоним для ..., но это не глобально.

Заметьте, я проверяю, начинается ли командная строка с p4 (инструмент командной строки Perforce) и не связывайтесь с ним в этом случае, так как аргументы Perforce часто включают в себя литералы ..., Если вы не используете p4 очевидно, вы можете удалить этот чек.

Хороший вариант - много-точечная магия, которая расширяет ... в ../.. и т. д., но делает это разумно. Смотрите ссылку выше для более подробной информации, но кратко:

  • Это позволяет вам вернуть расширение с помощью одного Backspace (если это было последнее, что вы набрали).
    • Но он не будет возвращаться в явном виде ../..
  • Вы можете использовать его в строке, например, cd a/b/..../y/z,
  • Тем не менее, он не будет расширяться, когда это не имеет смысла, например, git log branch...
  • Это расширится, когда это будет иметь смысл, но вернется, когда вы наберете больше. например
    • git diff ... -> git diff ../..
    • git diff ...b -> git diff ...b (за git diff ...branch)

Вы должны использовать compinit и использовать _expand_alias как полный. Вот пример:

zstyle ':completion:*' completer _complete _ignored _expand_alias
autoload -Uz compinit
compinit

_complete _ignored это настройка по умолчанию для completer, вы можете установить его только _expand_alias но тогда завершение будет работать только для псевдонимов.

Если compinit уже настроен в вашем ~/.zshrcтогда вам просто нужно добавить _expand_alias в список для completer, например:

zstyle ':completion:*' completer _expand _complete _ignored _approximate _expand_alias

По умолчанию _expand_alias расширяет глобальные и обычные псевдонимы, если вы не хотите расширять обычные псевдонимы, установите:

zstyle ':completion:*' regular false

Примечание: это, конечно, работает только там, где будут работать глобальные псевдонимы. Таким образом, они не будут расширены как часть всего пути, как a/b/..../c/d

Другие вопросы по тегам