Skip to content

Instantly share code, notes, and snippets.

@donaldguy
Last active July 19, 2025 23:54
Show Gist options
  • Select an option

  • Save donaldguy/04e52a4bc7d22d881403311860bc7e60 to your computer and use it in GitHub Desktop.

Select an option

Save donaldguy/04e52a4bc7d22d881403311860bc7e60 to your computer and use it in GitHub Desktop.
~/Library/LaunchAgents/com.mitchellh.ghostty.quick-terminal.plist
<!--
vim: ft=xml ts=4 noet
-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.mitchellh.ghostty.quick_terminal</string>
<key>AssociatedBundleIdentifiers</key>
<string>com.mitchellh.ghostty</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string><![CDATA[
#!/bin/zsh
#vim: ft=xml ts=4 noet
export ghostty="${$(realpath -q $"(whence -p ghostty)"):-/Applications/Ghostty.app/Contents/MacOS/ghostty}"
GHQT_CONFIG_FILE="$(VISUAL=echo "$ghostty" +edit-config).quick-terminal"
if [[ ! -s "$GHQT_CONFIG_FILE" ]]; then
cat > "$GHQT_CONFIG_FILE" <<-'EOFDefaultConfig'
keybind = global:ctrl+`=toggle_quick_terminal
quick-terminal-position = top
quick-terminal-autohide = true
quick-terminal-screen = main
quick-terminal-space-behavior = move
#quick-terminal-animation-duration = 0.2
#quick-terminal-keyboard-interactivity = on-demand
# on ⌘N:
# instead of doing `new_window` action, which would create a window
# also subject to macos-hidden=always, etc
#
# we spawn a second instance of Ghostty.app that behaves more normally
keybind = super+n=text:\x1A\nzsh --norcs\nif [ -z \"$(/usr/bin/lsappinfo find applicationtype\x3DForeground bundleid\x3Dcom.mitchellh.ghostty)" ]; then\n\texec open -na /Applications/Ghostty.app --args \\\n\t\t--initial-window=true --quit-after-last-window-closed\x3Dtrue\nfi\n
# as:
#
# ⒈ `\x1A` ->
# Send a ^Z in case there was something in foreground
# (we still end up in a bit of a race but don't have better options?)
# ⒉ `/bin/zsh --norcs\n` ->
# Start a vanilla zsh shell for predictability (e.g. I was being fouled by my
# env's zsh-autopair, but people could e.g. be in a different shell!)
#
# ⒊ `if [[ -z "$(lsappinfo find applicationtype=Foreground bundleid=com.mitchellh.ghostty)" ]]; then` ->
# We nicely ask CoreApplicationServices [aka lsd(8)] if theres already
# a 2nd non-hidden copy of Ghostty running; and if there is, then:
# ⒋ `exec open -na /Applications/Ghostty.app --args \` ->
# [`exec` -> consuming / reusing memory space of the zsh we fork(2)ed]
# `open -n` -> we start a second instance; `-a …Ghostty.app` -> of Ghostty
# `--args` -> and in this second proces, make sure, whatever config file says:
# 4A. `--initial-window=true` -> a 1st window is opened, to fulfill the ⌘N
# 4B. `--quit-after-last-window-closed=true` ->
# after that window is (and any other opened window(s) are) closed,
# we let things go back to just our original background for quick terminal
# ghostty process
EOFDefaultConfig
fi
exec $ghostty --title="Quick Terminal" \
--macos-hidden=always --window-save-state=never --initial-window=false \
--config-default-files=true \
--config-file="$GHQT_CONFIG_FILE"
]]></string>
</array>
<!-- don't impose any more resource restrictions than for normal ghostty-->
<key>ProcessType</key>
<string>Interactive</string>
<!-- while man 5 launchd.plist discourages this, I think it's needed to avoid needing an explicit
launchctl [kick]start -->
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true />
<!-- <dict>
<key>PathState</key>
<dict>
<key>/var/run/ghostty-quick-term</key>
<true/>
</dict>
</dict>
-->
</dict>
</plist>
# the config the above rights by default
keybind = global:ctrl+`=toggle_quick_terminal
quick-terminal-position = top
quick-terminal-autohide = true
quick-terminal-screen = main
quick-terminal-space-behavior = move
#quick-terminal-animation-duration = 0.2
#quick-terminal-keyboard-interactivity = on-demand
# on ⌘N:
# instead of doing `new_window` action, which would create a window
# also subject to macos-hidden=always, etc
#
# we spawn a second instance of Ghostty.app that behaves more normally
keybind = super+n=text:\x1A\nzsh --norcs\nif [ -z \"$(/usr/bin/lsappinfo find applicationtype\x3DForeground bundleid\x3Dcom.mitchellh.ghostty)" ]; then\n\texec open -na /Applications/Ghostty.app --args \\\n\t\t--initial-window\x3Dtrue --quit-after-last-window-closed\x3Dtrue\nfi\n
# as:
#
# ⒈ `\x1A` ->
# Send a ^Z in case there was something in foreground
# (we still end up in a bit of a race but don't have better options?)
# ⒉ `/bin/zsh --norcs\n` ->
# Start a vanilla zsh shell for predictability (e.g. I was being fouled by my
# env's zsh-autopair, but people could e.g. be in a different shell!)
#
# ⒊ `if [[ -z "$(lsappinfo find applicationtype=Foreground bundleid=com.mitchellh.ghostty)" ]]; then` ->
# We nicely ask CoreApplicationServices [aka lsd(8)] if theres already
# a 2nd non-hidden copy of Ghostty running; and if there is, then:
# ⒋ `exec open -na /Applications/Ghostty.app --args \` ->
# [`exec` -> consuming / reusing memory space of the zsh we fork(2)ed]
# `open -n` -> we start a second instance; `-a …Ghostty.app` -> of Ghostty
# `--args` -> and in this second proces, make sure, whatever config file says:
# 4A. `--initial-window=true` -> a 1st window is opened, to fulfill the ⌘N
# 4B. `--quit-after-last-window-closed=true` ->
# after that window is (and any other opened window(s) are) closed,
# we let things go back to just our original background for quick terminal
# ghostty process
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment