There might be an easier way, but this seems to work:
texfiles () { names=( "$2"*.tex ); COMPREPLY=( "${names[@]%.tex}" ); }
complete -F texfiles tex
This first sets up a shell function called texfiles. It uses the second command line argument ($2, the word typed by the user on the command line before pressing Tab to complete the word), and populates the COMPREPLY array with all names that matches "$2"*.tex.
For each of these names, the suffix .tex is removed before adding it to the array.
The complete command is then used to tell the shell to execute the texfiles function for file name completion for the tex command specifically. You may repeat the same complete command for all commands that should complete .tex files in the same way. For pdf-viewer you may want to create a corresponding pdffiles function (the names of these functions are arbitrary).
This is it in action (<tab> signifies me pressing the Tab key):
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
(the ile in file is inserted by the shell)
Read the "Programmable Completion" section of the bash manual for the gory details.
testin place oftest.texis a convenience, not a requirement. One option is modify the completion fortexto only expand to names ending in.tex. I know it involves the-Goption to thecompletecommand, but I can never figure out how to make it work correctly. I'll post an answer if I do.