macOS: "New wezterm Tab/Window Here" missing for Files and Folders Services Shortcuts
Describe the solution you'd like
macOS offers a Services menu in Finder. kitty and iTerm2 register themselves to enable a "New iTerm2/kitty Tab/Window Here" link. it would be nice to also have wezterm there.
The settings window:
The services context menu:
I plan to work on this FYI. Some references until then:
-
A helpful gist with comments: https://gist.github.com/tonysneed/f9f09bfa28bcf98e8d8306f9b21f99e2
-
I started by making a mac "quick action" with Automator and verified it shows up in the services list for keyboard shortcuts:
-
This adds the item to the "quick actions" menu when right clicking on files/folders, but not the "services" menu:
- For reference, Hammerspoon has a
plistfile, though I don't know how it gets installed automatically. 🤔
- For reference, Hammerspoon has a
-
The suggested method of using
open -n -b "com.github.wez.wezterm" --args "$*"doesn't work as expected:❯ open -n -b "com.github.wez.wezterm" --args "~/Git/some_project" # Nothing happens -
WezTerm itself seems to not support passing a path to its CLI:
❯ wezterm ~/Git/some_project error: unrecognized subcommand '~/Git/some_project' Usage: wezterm [OPTIONS] [COMMAND] For more information, try '--help'.
You need the start subcommand:
https://wezfurlong.org/wezterm/cli/start.html
@wez I tried both wezterm start ~/Git/elixir and wezterm start -- ~/Git/elixir and get a crash each time:
😅
Take a look at the --cwd parameter
Ah thanks!
I've got it working now with /opt/homebrew/bin/wezterm start --cwd "$*":
The actual .workflow Automator file: Open in WezTerm.workflow.zip
The next step is to figure out how to add this as an actual service plist file, which is beyond me at the moment. 😄
I've created a Shortcut for this: https://www.icloud.com/shortcuts/db66b71a7628475a8f7d115ec89ae916
On installation you will have to set the absolute path of the wezterm executable (preset is the Homebrew version). It will launch WezTerm if it's not running, and it will cd into the right-clicked folder. If you right-click a file, it will cd into the containing folder. It will intelligently use a fresh window.
Alternatively, I created an Automator Service script that works like a charm (it uses open -a WezTerm when wezterm is closed or wezterm cli spawn --new-window when there is a live socket in $HOME/.local/share/wezterm (i.e., when there is at least one WezTerm window open)
#!/usr/bin/env bash
set -euo pipefail
# Directory where wezterm's gui-sock files are usually created
SOCK_DIR="$HOME/.local/share/wezterm"
WEZTERM_BIN="/Applications/WezTerm.app/Contents/MacOS/wezterm"
WEZTERM_APP="/Applications/WezTerm.app"
find_live_socket() {
for sock in $(ls -1t "$SOCK_DIR"/gui-sock-* 2>/dev/null || true); do
if WEZTERM_UNIX_SOCKET="$sock" "$WEZTERM_BIN" cli list-clients >/dev/null 2>&1; then
echo "$sock"
return 0
else
# cleanup stale socket
rm -f "$sock"
fi
done
return 1
}
for f in "$@"; do
# resolve symlinks
if [[ -L "$f" ]]; then
f=$(readlink -f "$f")
fi
# find live socket (if any)
if live_socket=$(find_live_socket); then
export WEZTERM_UNIX_SOCKET="$live_socket"
if [[ -d "$f" ]]; then
"$WEZTERM_BIN" cli spawn --new-window --cwd "$f"
else
"$WEZTERM_BIN" cli spawn --new-window --cwd "$(dirname "$f")"
fi
else
if [[ -d "$f" ]]; then
open -a "$WEZTERM_APP" --args start --cwd "$f"
else
open -a "$WEZTERM_APP" --args start --cwd "$(dirname "$f")"
fi
fi
done
I have something similar as @victorgveloso though I never thought of using sockets, nor do I understand why (if) it is better to use them, but this works perfectly and fast for me:
#!/bin/zsh
set -euo pipefail
WEZTERM_APP="/Applications/WezTerm.app"
WEZTERM="$WEZTERM_APP/Contents/MacOS/wezterm"
dir="$1"
[[ -d "$dir" ]] || dir="$(dirname "$dir")"
if "$WEZTERM" cli list >/dev/null 2>&1; then
"$WEZTERM" cli spawn --cwd "$dir" >/dev/null 2>&1 &
open -a "$WEZTERM_APP"
else
open -a "$WEZTERM_APP" --args start --cwd "$dir"
fi
Why do you call
"$WEZTERM" cli spawn --cwd "$dir" >/dev/null 2>&1 & followed by open -a "$WEZTERM_APP"?
That seems to have the same effect as my socket based solution.
I used to use a minimalist script like yours (except I would only call open -a) but I noticed I couldn't alternate between different instances of wezterm with command+~. I assumed MacOS was failing to identify them as instances of the same "app".
The socket was necessary to make that feature work for me. But it's been awhile since I made that script, wezterm might have fixed that issue by now.
Besides, if I called open -a with the socket (instead of cli spawn --new-window) my existing wezterm window would focus and no extra window would be spawned.
I haven't refreshed the page before posting, so I deleted my post and am reposting again, and would first like to reply.
The only reason, I call open -a after cli spawn is to focus the window and not have to manually Alt+Tab.
The rest I understand why you have the need for. I just don't use WezTerm in the same way as you do.
Below is my original comment:
OK, I did some testing... Here are my conclusions.
S1 = @victorgveloso 's script
S2 = my script
S1always opens a new WezTerm window, whileS2adds a new tab to an existing window (if one is running).- These scripts are intended for Automator on macOS, so
zshis always available. Usingbashif fine too; there is no technical limitation either way. - Correct me if I am wrong, because I used ChatGPT to better understand this.
S1needs to handle multiple GUI instances (opens new windows), so inspecting sockets usingcli list-clientsmakes it more robust, albeit a bit slower (no benchmarks. I eyeballed it, so bias is likely).S2assumes a single GUI instance (always only one window and adds tabs to it), so discovery usingcli listis sufficient. Both approaches are valid for their use case. - If WezTerm is already opened, and one selects multiple folders, the
S1action then opens multiple new windows at their respective dir as CWD. If it is closed however, it only opens one window at the first dir as CWD.S2does not support that (I personally don't see a good use case for it, except perhaps in combination with symlinks, ie if you have "homepage" dir full of shortcuts to different locations) S2already opens at the symlinked directory, butS1also resolves a symlinked file. Though it only resolves it once - if there is a double link, it gives the second link's parent dir. Addressed below.
Here is my (so far) final script:
#!/bin/zsh
set -euo pipefail
WEZTERM_APP="/Applications/WezTerm.app"
WEZTERM="$WEZTERM_APP/Contents/MacOS/wezterm"
dir="$1"
[[ -L "$dir" ]] && dir="$(realpath "$dir" 2>/dev/null || printf '%s\n' "$dir")"
[[ ! -d "$dir" ]] && dir="$(dirname "$dir")"
if "$WEZTERM" cli list >/dev/null 2>&1; then
"$WEZTERM" cli spawn --cwd "$dir" >/dev/null 2>&1 &
open -a "$WEZTERM_APP"
else
open -a "$WEZTERM_APP" --args start --cwd "$dir"
fi
That's an impressive analysis. I like the simplicity of your approach but I really need command+~ to work