Entenda melhor uma função que expande aliases em 'zsh'

3

Estou tentando entender como esse widget zsh funciona:

expand-aliases() {
  unset 'functions[_expand-aliases]'
  functions[_expand-aliases]=$BUFFER
  (($+functions[_expand-aliases])) &&
    BUFFER=${functions[_expand-aliases]#$'\t'} &&
    CURSOR=$#BUFFER
}

zle -N expand-aliases
bindkey '\e^E' expand-aliases

Encontrei o código nesta resposta . Sua finalidade é expandir todos os aliases na linha de comando ao atingir C-M-e .

Funciona, mas há várias coisas que não entendo no código.

Veja o que acho que entendo e o que não entendo:

zle -N expand-aliases

Esta linha instala um widget chamado expand-aliases , que invocará a função com o mesmo nome.

bindkey '\e^E' expand-aliases

Esta linha liga o widget ao acorde de teclas C-M-e .

unset 'functions[_expand-aliases]'

Eu não entendo essa linha, porque não sei como a matriz functions foi preenchida.

functions[_expand-aliases]=$BUFFER

Esta linha armazena dentro da matriz associativa functions o conteúdo da linha de comando atual, com a chave _expand-aliases .

(($+functions[_expand-aliases])) &&

Para entender melhor como essa linha funciona, eu executei os seguintes comandos:

alias ls='ls --color=auto'
alias -g V='|vipe'
functions[_expand-aliases]='ls V'
echo $functions[_expand-aliases]           →  ls --color=auto | vipe
echo $+functions[_expand-aliases]          →  1
(($+functions[_expand-aliases])); echo $?  →  0

Não tenho certeza, mas a partir desses resultados, acho que $functions[_expand-aliases] de alguma forma expande os aliases na linha de comando atual e que $+functions[_expand-aliases] retorna um sinalizador booleano que verifica se a linha de comando é sintaticamente válida. / p>

No entanto, não entendo o token $+ . Eu procurei por ele em todas as páginas zsh man, mas não consegui encontrá-lo.

BUFFER=${functions[_expand-aliases]#$'\t'} &&

Esta linha provavelmente redefine o conteúdo da linha de comando, com sua expansão.

CURSOR=$#BUFFER

Esta linha posiciona o cursor no final do comando.

Alguém poderia explicar melhor como esse código funciona? Ou, pelo menos, cite as seções nas páginas zsh man, onde o $+ token e a functions array são descritos?

    
por user547381 22.06.2017 / 21:51

1 resposta

3

$+functions[_expand-aliases] é 1 se a matriz associativa functions contiver a chave _expand-aliases e 0 caso contrário. Isso é descrito no manual como ${+name} . Sob a entrada para ${name} , o manual explica que as chaves são opcionais. Não creio que o manual indique explicitamente que você pode usar um nome de matriz com um subscrito em vez de um nome. O manual do zsh não é uma leitura fácil.

A matriz functions é uma matriz associativa "mágica" vinculada às definições de função. Definir uma função adiciona um elemento a essa matriz, em que a chave é o nome da função e o valor é o corpo da função, normalizado. Por outro lado, adicionar um elemento à matriz define uma função com o nome e o corpo especificados.

unset 'functions[_expand-aliases]'               # unset any previous function
functions[_expand-aliases]=$BUFFER               # define a function whose body is the content of the command line
(($+functions[_expand-aliases])) &&              # if the command line is a syntactically correct function body, then …
BUFFER=${functions[_expand-aliases]#$'\t'} &&    # set the command line to the normalized function definition
CURSOR=$#BUFFER                                  # move the cursor to the end of the command line

Se functions fosse uma matriz comum, isso não alteraria o valor de BUFFER (exceto para separar uma guia principal) e o teste na terceira linha sempre seria verdadeiro. Mas por causa da natureza “mágica” de functions , o que você ganha com isso não é o que você coloca, é uma versão normalizada - em particular, com aliases expandidos. O teste na terceira linha falhará se a definição da função não estiver sintaticamente correta.

    
por 23.06.2017 / 04:07

Tags