Executando verificação de segurança...
1

Comandos/Funções ZSH personalizadas com preenchimento automático

Recentemente, enquanto organizava meus dotfiles, decidi criar algumas funções/comandos personalizados para facilitar as ações que realizo com frequência. Ao concluir essa tarefa, percebi que a funcionalidade de auto-completion seria útil e decidi implementá-la. No processo, descobri que o preenchimento automático pode ser ainda mais útil do que imaginava.

Acessar meu repositório

Normalmente, organizo meus repositórios do GitHub em um diretório específico e, às vezes, existe alguma dificuldade para chegar ao repositório desejado. Por isso, decidi criar um comando que me permitisse acessar automaticamente qualquer um desses repositórios, independentemente de onde eu esteja. Embora pudesse usar vários comandos cd até chegar ao destino desejado, eu queria mais automação.

O comando principal é bastante simples e pode ser adicionado ao arquivo .zshrc da seguinte forma:

function repo() {
  cd ~/repos/$@
}

Em outras palavras, se digitar apenas repo, o comando me levará diretamente ao diretório repos (onde guardo meus repositórios). Se fornecer algum argumento, ele me direcionará ao diretório e/ou subdiretório indicado.

No entanto, o problema é que, ao utilizar o comando, não recebo nenhuma sugestão e preciso saber exatamente o que desejo, o que dificulta seu uso. Vamos resolver isso!

Podemos adicionar o seguinte trecho de código para habilitar o preenchimento automático:

compdef '_files -W ~/repos/' repo

Dessa forma, já temos um preenchimento automático básico.

Para organizar melhor o código, podemos separar as partes relacionadas a essa função em um arquivo separado e dividir os argumentos do compdef em funções individuais:

# .zshrc
source ~/.functions/repo.zsh

# ~/.functions/repo.zsh
function _repo_repositories() {
  _files -W ~/repos/
}

function repo() {
  cd ~/repos/$@
}

compdef _repo_repositories repo

A única "questão" é que esse comando pode receber vários argumentos, mas não é essa a ideia. Podemos resolver esse problema declarando os argumentos que a função repo recebe usando a função _repo:

function _repo_repositories() {
  _files -W ~/repos/
}

function _repo() {
    _arguments -s \
        '1:repository:_repo_repositories'
}

function repo() {
  cd ~/repos/$@
}

compdef _repo_repositories repo

Assim, estamos declarando que a função repo aceita apenas um argumento, chamado repository, cujo tipo é _files -W ~/repos/, representando os subdiretórios do diretório repos.

Com isso, temos o comando desejado, que facilita a navegação entre meus repositórios pessoais de forma fácil e prática.

Clonar meu repositório

Após essa implementação, criei mais alguns comandos, em particular o comando clone, para clonar rapidamente um de meus repositórios. A ideia era ter um comando que completasse automaticamente e fornecesse sugestões dos meus repositórios, a fim de evitar erros ao digitar o nome completo (o que é um desafio para mim, já que nunca me lembro exatamente do nome ou costumo errar durante a digitação).

A melhor maneira de alcançar esse objetivo foi usando o GitHub CLI. Com ele, é possível listar facilmente meus repositórios. Embora seja possível usar a API do GitHub, o CLI é suficiente e mais prático para o que precisamos.

O código é semelhante ao exemplo anterior:

REPOS=$(gh repo list | awk '{print $1}')

function _clone_repositories() {
  compadd $(echo $REPOS)
}

function _clone() {
  _arguments -s \
    '1:repository:_clone_repositories'
}

function clone() {
  gh repo clone $@
}

compdef _clone clone

Inicialmente, definimos a variável REPOS para armazenar os repositórios, evitando assim a necessidade de chamar o GitHub CLI toda vez que quisermos usar o preenchimento automático. Dessa forma, toda vez que iniciarmos o terminal, a lista de repositórios será carregada na memória.

Agora, com esse comando, é fácil clonear meus repositórios pessoais, sem precisar se preocupar em digitar exatamente o nome ou link do repositório desejado.

Além disso existem outras melhorias que podem ser feitas mas esse post já está maior do que eu imaginava, então fica para uma próxima. E obrigado por ler até aqui :)

PS: Peço desculpas caso alguma explicação não tenha ficado clara. A minha ideia era escrever um artigo curto, mas acabou ficando extenso e se explicasse detalhadamente ficaria mais ainda. Além disso, é meu primero post...

1
1

obrigado pelo feedback. Também uso alguns scripts pra automatizar algumas coisas pós-intalação no laboratório de informática que sou monitor, fiquei interessado nesse post