Pode haver uma maneira mais fácil, mas isso parece funcionar:
texfiles () { names=( "$2"*.tex ); COMPREPLY=( "${names[@]%.tex}" ); }
complete -F texfiles tex
Isso primeiro configura uma função de shell chamada texfiles . Ele usa o segundo argumento de linha de comando ( $2 , a palavra digitada pelo usuário na linha de comando antes de pressionar Tab para completar a palavra) e preenche a matriz COMPREPLY com todos os nomes correspondentes "$2"*.tex .
Para cada um desses nomes, o sufixo .tex é removido antes de ser adicionado ao array.
O comando complete é então usado para dizer ao shell para executar a função texfiles para a conclusão do nome do arquivo para o comando tex especificamente . Você pode repetir o mesmo comando complete para todos os comandos que devem concluir .tex arquivos da mesma maneira. Para pdf-viewer você pode querer criar uma função pdffiles correspondente (os nomes dessas funções são arbitrários).
Isto está em ação ( <tab> significa que estou pressionando a tecla Tab ):
bash-4.4$ ls -l
total 0
-rw-r--r-- 1 kk wheel 0 Sep 28 21:43 README.txt
-rw-r--r-- 1 kk wheel 0 Sep 28 21:12 file.tex
-rw-r--r-- 1 kk wheel 0 Sep 28 21:24 file2.tex
-rw-r--r-- 1 kk wheel 0 Sep 28 21:25 hello.tex
bash-4.4$ tex <tab><tab>
file file2 hello
bash-4.4$ tex
bash-4.4$ tex f<tab>ile<tab><tab>
file file2
bash-4.4$ tex file
(o ile em file é inserido pelo shell)
Leia a seção "Conclusão programável" do manual bash para os detalhes sangrentos.