No zsh, o caminho de busca da função ($ fpath) define um conjunto de diretórios, que contêm arquivos que podem ser marcados para serem carregados automaticamente quando a função que eles contêm é necessária pela primeira vez.
O Zsh possui dois modos de carregamento automático de arquivos: a maneira nativa do Zsh e outro modo que se assemelha ao carregamento automático do ksh. Este último estará ativo se a opção KSH_AUTOLOAD estiver configurada. O modo nativo do Zsh é o padrão e não discutirei o contrário aqui (consulte "man zshmisc" e "man zshoptions" para obter detalhes sobre o carregamento automático no estilo ksh).
OK. Digamos que você tenha um diretório `~ / .zfunc 'e deseje que ele faça parte do caminho de busca da função, faça o seguinte:
fpath=( ~/.zfunc "${fpath[@]}" )
Isso adiciona seu diretório privado à frente do caminho de pesquisa. Isso é importante se você deseja substituir as funções da instalação do zsh por você mesmo (como quando você deseja usar uma função de conclusão atualizada como `_git 'do repositório CVS do zsh por uma versão mais antiga do shell).
Também é importante notar que os diretórios do `$ fpath 'não são pesquisados recursivamente. Se você deseja que seu diretório privado seja pesquisado recursivamente, será necessário cuidar disso, assim (o snippet a seguir requer que a opção `EXTENDED_GLOB 'seja configurada):
fpath=(
~/.zfuncs
~/.zfuncs/**/*~*/(CVS)#(/N)
"${fpath[@]}"
)
Pode parecer enigmático para quem não é treinado, mas na verdade apenas adiciona todos os diretórios abaixo de `~ / .zfunc 'a` $ fpath', enquanto ignora os diretórios chamados "CVS" (o que é útil, se você planeja fazer o checkout completo) árvore de funções do CVS do zsh para o seu caminho de pesquisa particular).
Vamos supor que você tenha um arquivo `~ / .zfunc / hello 'que contenha a seguinte linha:
printf 'Hello world.\n'
Tudo o que você precisa fazer agora é marcar a função a ser carregada automaticamente na primeira referência:
autoload -Uz hello
"O que é o -Uz?", Você pergunta? Bem, isso é apenas um conjunto de opções que farão com que o 'carregamento automático' faça a coisa certa, independentemente de quais opções estejam sendo definidas de outra forma. O `U 'desativa a expansão do alias enquanto a função está sendo carregada e o` z' força o carregamento automático no estilo zsh, mesmo que o `KSH_AUTOLOAD 'esteja definido por qualquer motivo.
Depois disso, você poderá usar sua nova função `hello ':
zsh% olá
Olá Mundo.
Uma palavra sobre o fornecimento desses arquivos: Isso é errado . Se você tivesse originado esse arquivo `~ / .zfunc / hello ', ele imprimiria" Hello world ". uma vez. Nada mais. Nenhuma função será definida. Além disso, a idéia é carregar apenas o código da função quando necessário . Após a chamada `autoload ', a definição da função não é lida. A função está marcada apenas para ser carregada automaticamente mais tarde, conforme necessário.
E, finalmente, uma observação sobre $ FPATH e $ fpath: Zsh mantém esses parâmetros como parâmetros vinculados. O parâmetro em minúsculas é uma matriz. A versão em maiúsculas é uma cadeia de caracteres escalar, que contém as entradas da matriz vinculada unidas por dois pontos entre as entradas. Isso é feito porque o manuseio de uma lista de escalares é muito mais natural usando matrizes, além de manter a compatibilidade com versões anteriores do código que usa o parâmetro escalar. Se você optar por usar $ FPATH (o escalar), precisará ter cuidado:
FPATH=~/.zfunc:$FPATH
funcionará, enquanto o seguinte não:
FPATH="~/.zfunc:$FPATH"
O motivo é que a expansão do til não é realizada entre aspas duplas. Esta é provavelmente a fonte dos seus problemas. Se echo $FPATH
imprimir um til e não um caminho expandido, não funcionará. Para estar seguro, eu usaria $ HOME em vez de um til como este:
FPATH="$HOME/.zfunc:$FPATH"
Dito isto, prefiro usar o parâmetro array como fiz no topo desta explicação.
Você também não deve exportar o parâmetro $ FPATH. É necessário apenas pelo processo atual do shell e não por nenhum de seus filhos.
Atualizar
Em relação ao conteúdo dos arquivos em `$ fpath ':
Com o carregamento automático no estilo zsh, o conteúdo de um arquivo é o corpo da função que ele define. Assim, um arquivo chamado "hello" contendo uma linha echo "Hello world."
define completamente uma função chamada "hello". Você é livre para colocar hello () { ... }
o código em prática
, mas isso seria supérfluo.
A alegação de que um arquivo pode conter apenas uma função não está totalmente correta.
Especialmente se você observar algumas funções do sistema de conclusão baseado em funções (compsys), rapidamente perceberá que isso é um equívoco. Você é livre para definir funções adicionais em um arquivo de função. Você também é livre para fazer qualquer tipo de inicialização, o que pode ser necessário na primeira vez que a função é chamada. No entanto, quando você definir, sempre definirá uma função chamada como o arquivo no arquivo e chamará essa função no final do arquivo, para que seja executada na primeira vez em que a função for referenciada.
Se - com subfunções - você não definiu uma função chamada como o arquivo no arquivo, você acabaria com essa função com definições de funções (a saber, as subfunções no arquivo). Você definiria efetivamente todas as suas subfunções toda vez que chamar a função denominada como o arquivo. Normalmente, não é isso que você deseja, então você redefiniria uma função, denominada como o arquivo dentro do arquivo.
Vou incluir um esqueleto curto, que lhe dará uma idéia de como isso funciona:
# Let's again assume that these are the contents of a file called "hello".
# You may run arbitrary code in here, that will run the first time the
# function is referenced. Commonly, that is initialisation code. For example
# the `_tmux' completion function does exactly that.
echo initialising...
# You may also define additional functions in here. Note, that these
# functions are visible in global scope, so it is paramount to take
# care when you're naming these so you do not shadow existing commands or
# redefine existing functions.
hello_helper_one () {
printf 'Hello'
}
hello_helper_two () {
printf 'world.'
}
# Now you should redefine the "hello" function (which currently contains
# all the code from the file) to something that covers its actual
# functionality. After that, the two helper functions along with the core
# function will be defined and visible in global scope.
hello () {
printf '%s %s\n' "$(hello_helper_one)" "$(hello_helper_two)"
}
# Finally run the redefined function with the same arguments as the current
# run. If this is left out, the functionality implemented by the newly
# defined "hello" function is not executed upon its first call. So:
hello "$@"
Se você executasse este exemplo bobo, a primeira execução seria assim:
zsh% olá
inicializando ...
Olá Mundo.
E as chamadas consecutivas ficarão assim:
zsh% olá
Olá Mundo.
Eu espero que isso esclareça as coisas.
(Um dos exemplos mais complexos do mundo real que usa todos esses truques é a função ` _tmux ' já mencionada no sistema de conclusão baseado em funções do zsh.)