Functions digest NÃO é tratado da mesma forma que um diretório de arquivos de função!

3

Eu tenho uma função que usa zcompile para criar um resumo assim:

function fpath-setup {
  local FLATFPATH="${TMPPREFIX}-${ZSH_VERSION}-fpath.zwc"

  function {
      typeset -a zarr

      blacklist=('ztodo' 'zed')
      blacklist="^(${(j:|:)blacklist})"

      setopt LOCAL_OPTIONS EXTENDED_GLOB

      for fp in "$fpath[@]"; do
        local ztail=(${zarr:t})
        for it in "${fp}/"$~blacklist; do
          if [[ -z "${ztail[(r)${it:t}]}" ]]; then
            if zcompile "${TMPPREFIX}-try-zcompile" "${it}" &>/dev/null; then
              zarr+="${it}"
            else
              echo "CANNOT COMPILE: ${it}"
            fi
          else
            echo "DUPLICATE: ${it}"
          fi
        done
      done

      zcompile "${FLATFPATH}" "$zarr[@]"

      zcompile -t "${FLATFPATH}" 'compinit' '_complete' || {
        print "Important functions missing from ${FLATFPATH}" >&2
        return 1
      }
  }

  if (( $? )); then
    print "The fpath is left unchanged." >&2
    return 1
  else
    fpath=("${FLATFPATH}")
  fi
}

No ponto em que isso é executado, o $fpath é assim:

/usr/local/share/zsh/site-functions
/usr/local/Cellar/zsh/5.2/share/zsh/functions

Depois disso, o $fpath se parece com isto:

/var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc

Como você pode ver aqui, as principais funções do Zsh estão no resumo:

link

Isso parece funcionar bem até que eu tente usar esse tema de prompts:

link

Eu recebo o seguinte erro em cada prompt:

vcs_info: configured unknown backend: 'git'
vcs_info: use 'vcs_info_printsys' to find supported systems.

Isso pode ser resolvido não criando o resumo em primeiro lugar, ou executando o seguinte comando antes de chamar o prompt:

autoload -Uz VCS_INFO_get_data_git VCS_INFO_detect_git

Então, minhas perguntas são :

  1. É uma má ideia usar zcompile no núcleo Zsh funções?
  2. Por que preciso manualmente autoload de algumas coisas ao usar o zcompile digest, mas esse não é o caso quando se usa arquivos regulares em um diretório?

Editar :

Eu fiz mais algumas investigações e descobri que com um fpath como:

/var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-circuit.zwc

O comando:

prompt pure # ...vcs_info errors
print -f '%s\n' "${(k)functions[@]}" | grep VCS_INFO_get_data_git

Não retorna nada. No entanto, com um caminho como:

/var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc
/usr/local/Cellar/zsh/5.2/share/zsh/functions

O comando:

prompt pure # NO vcs_info errors!
type $(print -f '%s\n' "${(k)functions[@]}" | grep VCS_INFO_get_data_git)

Retorna:

VCS_INFO_get_data_git is a shell function from /var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc/VCS_INFO_get_data_git

Assim, de alguma forma, a mera existência do diretório principal /usr/local/Cellar/zsh/5.2/share/zsh/functions faz com que a função VCS_INFO_get_data_git seja carregada a partir de /var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc .

Isso significa que o Zsh oferece tratamento especial ao diretório principal? Para testar essa teoria, copio os arquivos da função principal para um local temporário:

cp -r /usr/local/Cellar/zsh/5.2/share/zsh/functions /tmp

Em uma nova sessão, com um caminho como:

/var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc
/tmp/functions

O comando:

prompt pure # NO vcs_info errors!!
type $(print -f '%s\n' "${(k)functions[@]}" | grep VCS_INFO_get_data_git)

Retorna:

VCS_INFO_get_data_git is a shell function from /var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc/VCS_INFO_get_data_git

Assim, devo concluir que Zsh NÃO está tratando o seu diretório principal especialmente, mas em vez disso ele está carregando automaticamente VCS_INFO_get_data_git se um FILE desse nome existir em qualquer um dos diretórios no fpath ... No entanto, Zsh irá ainda carregar a partir do DIGEST, se isso vier primeiro no fpath .

Isso é estranho.

Eu não vi esse comportamento documentado em nenhum lugar, e não está claro para mim como o Zsh faz isso (talvez alguém que saiba que os internos do Zsh possam explicar).

Para tentar descobrir QUANDO o autoloading acontece, eu brinco com o fpath em uma nova sessão, alterando o fpath de:

/var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc
/tmp/functions

Para remover o diretório /tmp/functions :

/var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc

Então, tento alterar o prompt:

prompt pure

O que dá os erros vcs_info originais, como antes:

vcs_info: configured unknown backend: 'git'
vcs_info: use 'vcs_info_printsys' to find supported systems.

Para ter certeza, o teste:

print -f '%s\n' "${(k)functions[@]}" | grep VCS_INFO_get_data_git

Não retorna nada! Agora, se neste ponto eu adicionar o diretório /tmp/functions BACK ao fpath novamente, então será:

/var/folders/kb/ydt74z19765cv9vb86rwvcrr0000gn/T/zsh-5.2-fpath.zwc
/tmp/functions

Os erros vcs_info continuam persistindo!

Alguém pode explicar o que diabos está acontecendo aqui com a versão 5.2 do Zsh?

    
por leoj 27.08.2016 / 21:49

1 resposta

3

Eu estava pesquisando coisas semelhantes, então posso ter algumas coisas que poderiam ser úteis.

Se você usa man zshmisc e acessa a seção "Funções de carregamento automático" explica um pouco disso.      link

Ele diz duas coisas aqui que eu vou apontar

Primeiro, acho que um dos seus problemas é que você estava perdendo a sinalização -U acima:

The usual alias expansion during reading will be suppressed if the autoload builtin or its equivalent is given the option -U. This is recommended for the use of functions supplied with the zsh distribution. Note that for functions precompiled with the zcompile builtin command the flag -U must be provided when the .zwc file is created, as the corresponding information is compiled into the latter.'

O segundo é como ele é carregado automaticamente a partir da variável fpath (recomendo ler a página, mas aqui está resumida):

element é o item fpath e function é a função que está tentando ser carregada automaticamente.

Existem 3 maneiras de carregar algo.

  1. Se houver um arquivo chamado element.zwc , ele será carregado e pesquisado pelas funções. (digerir). Eu pessoalmente preciso pesquisar mais sobre isso, mas você pode ver o que está em um arquivo zwc usando zcompile -t . (Eu sei que você usou isso acima, apenas postando aqui)

  2. Se três é um arquivo de código de palavras (arquivo compilado) chamado element/function.zwc

  3. O comum que é se é um arquivo no fpath (então apenas element/function )

Confira também o man zshbuiltins e procure a página man do zcompile . Você pode usar o -c e -a para compilar todas as funções ou todas as funções carregadas automaticamente: link

Além disso, você pode encontrar outro lugar onde os códigos de palavras zsh são mencionados se você procurar o . embutido na página. Você pode ver especificamente se você usá-lo. Ele procurará a versão *.zwc do arquivo e a carregará:

If a file named 'file.zwc' is found, is newer than file, and is the compiled form (created with the zcompile builtin) of file, then commands are read from that file instead of file.

Há também uma função que você pode carregar automaticamente chamada zrecompile, que é um pouco não relacionada, mas recomendo que você faça o check out. Essencialmente recompila seus arquivos conforme necessário:

link

    
por 29.05.2017 / 03:40

Tags