Search code examples
zshtmux

Tmux name window at creation and use the name in zsh command


Currently, in my tmux.conf I have the following binding which allows me to name a window when I create a new one. Then the window opens in the same directory I was in the last window:

# Name windows before you create them
bind-key c command-prompt -p "window name:" "new-window -c '#{pane_current_path}'; rename-window '%%'"

I want to achieve the following instead: When I type the name, it will create the window and execute a bash command like z <TYPED_NAME> - the idea is that it will use the name I typed to search for the most relevant directory (using the z command for example) and cd into it. Can that be achieved? If no relevant directory is found with z it will use the current behaviour which is to cd into the current path.


Solution

  • One problem is that only the first %% in the template is replaced. The other is that a cd command done in a subshell will be lost when you return to the parent shell. For bash you can try a binding something like this:

    bind-key c command-prompt -p "window name:" \
      "new-window -c '#{pane_current_path}' 'myfn \"%%\"'"
    

    This runs a bash script myfn that must be in your PATH to do the work. It contains:

    #!/bin/bash
    name=$1
    tmux rename-window "$name"
    cd ../"$name" || echo "failed to cd to $name" >&2
    exec bash -i
    

    Remember to chmod +x the script. It calls tmux to rename the window, and then you would have your z code to find and cd to a directory. In this example, I just look in ../ for it. The final exec ensures we replace the current shell by an interactive one.

    For zsh, you can do something similar, but if you want myfn to be found in your fpath you need new-window to run zsh with the -i option, as zsh only does this for interactive shells. So use a binding like

    bind-key c command-prompt -p "window name:" \
       "new-window -c '#{pane_current_path}' 'exec zsh -ic \"myfn %%\"'"
    

    Here I've added an exec to avoid having a pointless parent shell, and since -c must be followed by the command as a single string I've put myfn and %% inside the same double-quotes. You'll need to add more quoting if your name can contain whitespace etc.

    The myfn zsh script can be the same, with bash replaced by zsh. I don't know enough about zsh to avoid the final exec zsh -i which is needed to stop the zsh -ic shell from terminating.