Automaticamente usa a versão '.zwc' de um arquivo 'source'd'

1

Eu encontrei *.zwc arquivos, que eu acredito serem arquivos de código do Word Z-shell, ou% script zsh compilado.

Quando source -ing um arquivo arbitrário, existe uma maneira de ter zsh :

  • Use o arquivo .zwc se ele existir e for mais recente que o arquivo
  • Senão, compile o arquivo para o código de texto do Z-shell e, em seguida, source it

Se eu tiver um arquivo contendo apenas funções, a resposta é diferente?

Não parece haver muitos tutoriais em torno do Código-Palavra do Z-shell, então sinta-se à vontade para me apontar para eles.

    
por Tom Hale 08.07.2018 / 13:04

2 respostas

1

Pelo menos para usar os arquivos .zwc , você não precisa fazer nada. Como a seção no comando . nos estados do Zsh's manpage :

[…] 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.

O mesmo é válido para source , pois é igual a . , exceto para a ordem de pesquisa.

Compilar automaticamente qualquer script de origem pode ser feito criando funções de wrapper. Por exemplo:

source () {
    [[ ! "$1.zwc" -nt $1 ]] || zcompile $1
    builtin source $@
}

. () {
    [[ ! "$1.zwc" -nt $1 ]] || zcompile $1
    builtin . $@
}

É claro que esses wrappers são muito simples e podem precisar de alguns fail-saves extras. Por exemplo, se o diretório, no qual o arquivo a ser armazenado reside, não for gravável. Além disso, a compilação pode falhar, mesmo que o arquivo de origem não tenha erros de sintaxe.

    
por 10.07.2018 / 10:00
0

Com base na resposta de Adaephon , escrevi uma substituição completa de source e . .

Não foi fácil devido ao comportamento interno de passar $@ se nenhum argumento for fornecido.

Os aliases necessários estão nos comentários.

compile-source-file :

# This file needs to be 'sourced' to ensure a drop-in behaviour for 'source' or '.'
# The shell passess "$@" to source if no arguments are given after the file to be sourced.

# Works in bash.

# Required aliases are:
# alias source='builtin source compile-source-file source "$#" "$@"'
# alias      .='builtin .      compile-source-file .      "$#" "$@"'

# zsh: compile functions before sourcing
# This function expects to be called with:
# $1 builtin to use, either '.' or 'source'.
# $2 file to source
# $3... arguments to pass to sourced file
function compile_then_source () {
  local method=$1 file=$2; shift 2; local args=("$@")

  # ${var@Q} gives value of var quoted in a format that can be reused as input
  [[ $BASH_VERSION ]] && { eval builtin "$method" "$file" "${args@Q}"; return $?; }

  if [[ ! $file.zwc -nt $file ]]; then
    # Use canonical pathname for zrecompile's happiness
    if [[ -r $file && -w ${file:h} ]]; then zcompile "${file:P}"; fi
  fi

  eval builtin "$method" "$file" "${(q)args[@]}"
}

function main () {
  local use_builtin=$1  # '.' or 'source'
  local num_args=$2     # Number of elements in calling shell's $@, which follow
  shift 2;
  local wrapper_args=("$@")
  wrapper_args=("${wrapper_args[@]:0:$num_args}")
  shift "$num_args"
  local file=$1; shift;

  # Now $@ is the arguments passed after the file to be soured
  if [[ $# -ge 1 ]]; then # arguments were passed
    use_args=("$@")
  else  # use $@ from the wrapper args
    use_args=("${wrapper_args[@]}")
  fi
  compile_then_source "$use_builtin" "$file" "${use_args[@]}"
}

main "$@"

unset -f main compile_then_source
    
por 13.07.2018 / 13:41