11

Not a duplicate:
I'm not looking for a way to complete directory names or execute scripts from a fixed directory. The issue I'm trying to solve is to get completion for the current directory without pressing /


I want zsh to tab-complete . to ./ like bash.

With bash I'm used to press .TABTAB to see all files in the current working directory since it first completes to ./ and then shows all content in that directory. Reason for my desire to avoid / at all cost is that / is way harder on my german keyboard than TAB since it's either with 2 fingers with shift or far away on numpad and I'd rather switch back to bash than type a /. What I'd like to achieve, in other words what bash does:

$ . <TAB> $ ./ <TAB> foo.sh somedir/ $ ./ <F><TAB> $ ./foo.sh <ENTER> 

Using zsh / oh-my-zsh when I hit .TAB I get . (dot space) which is not useful at all for me.

  • Using zstyle ':completion:*' special-dirs true with setopt auto_cd (which is oh-my-zsh default) gives me the even less useful option for ../ on top, so I turned that off already. I'm happy with completion of cd.
  • There is no . on $PATH and it should stay that way. Though I wouldn't mind completion of e.g. f<TAB> to ./foo.sh for example.

How can I teach zsh to complete . to ./ or even better to local directory content right away? Or is there another way to work with local script files in an efficient way that does not involve /?

4
  • 1
    Possible duplicate of zsh autocomplete directory Commented Jul 15, 2019 at 10:40
  • 2
    @Sparhawk No, not really my issue or a solution to it. Commented Jul 15, 2019 at 10:45
  • in bash you are getting foo.sh as one if suggestion is because that's executable otherwise that is out. you can check the code of bash-completion to see what is does and maybe you can simulate the same in zsh Commented Feb 6, 2020 at 15:43
  • @αғsнιη the issue is not that zsh won't complete executables once you're at ./, it's that it doesn't get there from . - There's surely a simple regex rules one can put somewhere that triggers for exactly the string .? Commented Feb 6, 2020 at 19:05

2 Answers 2

3
+50

Great challenge! Try this on the commandline, if it works add it to ~/.zshrc

bindkey '^I' dotcomplete zle -N dotcomplete 
function dotcomplete() { if [[ $BUFFER =~ ^'\.'$ ]]; then BUFFER='./' CURSOR=2 zle list-choices else zle expand-or-complete fi } 

It adds a function which runs every time you press TAB (^I). If the the line you've currently typed only contains a dot (^=beginning of line, '\.' =super-escape the dot, $=end of line), then replace that dot with a ./ then continue with the normal completion.

It doesn't exactly do what you ask, which is to treat the dot as the current directory. But it will save you they keystrokes you want to save.

1
  • 1
    This works great! Changed regex to if [[ $BUFFER =~ ^'\.'$ ]]; then ($ at the end) so it doesn't act on ./foo<TAB>. Also had to add the line zle -N dotcomplete to my .zshrc. Commented Feb 12, 2020 at 14:33
1

given your f<TAB> option/workaround, I present:

$ function f(){ local x=$1; shift; ./"$x" "$@"; } $ f foo<TAB> 

notice the space after f in that last line

2
  • Nice. While I don't have that f<TAB> workaround, this still works because f<SPACE><TAB> suggests local directory files and selecting one will correctly execute it. A little odd to remember f (or whatever name that function gets) though. Commented Feb 12, 2020 at 14:18
  • yes, I only used 'f' because you had it, but perhaps 'x' ("execute") would be better Commented Feb 13, 2020 at 11:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.