Something went wrong. Try again.
Dotfiles for my macos setup
Something went wrong. Try again.
3.6 kB · 134 lines
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135#!/usr/bin/env bash# Open a new terminal tab (Rex or Ghostty) in a directory, optionally pre-typing a command.## Usage: term-tab [-t|--title <title>] <dir> [command ...]## Inside Rex (REX_SESSION set) it# opens a Rex window in the current session, labelled with the title.# Otherwise it drives Ghostty via AppleScript, falling back to a new window# when Ghostty has no windows open.## For Ghostty the title is also exported as TAB_TITLE;# ~/.config/fish/functions/fish_title.fish turns that into the tab label so# fish's per-prompt title does not clobber it.set -euo pipefail
usage() { echo "usage: term-tab [-t|--title <title>] <dir> [command ...]" >&2 exit 64}
# Render a string as an ASCII-only fish `printf` format: osascript decodes its# argv as MacRoman, so anything non-ASCII (emoji) must travel as \UXXXX escapes# and be rebuilt by fish inside the new tab.fish_printf_ascii() { printf '%s' "$1" | perl -CSD -pe ' s/\\/\\\\/g; s/%/%%/g; s/'\''/\\'\''/g; s/([^\x20-\x7e])/sprintf("\\U%04X",ord($1))/ge; '}
in_rex() { [[ -n ${REX_SESSION:-} ]] && command -v rex >/dev/null 2>&1}
# Create a Rex window (tab) in the current session and type the command into its shell.open_rex_tab() { local dir="$1" title="$2" command="$3" local args=(window new -s "$REX_SESSION" -c "$dir" --json) if [[ -n $title ]]; then args+=("$title") fi
local created block_id created="$(rex "${args[@]}")" block_id="$(jq -er '.block_ids[0]' <<<"$created")" || { echo "term-tab: rex did not return a block id: $created" >&2 exit 70 }
if [[ -n $command ]]; then rex send -b "$block_id" "$command"$'\n' >/dev/null fi}
# Create a Ghostty tab via AppleScript, typing the startup input into it.open_ghostty_tab() { local dir="$1" title="$2" command="$3"
# Title and command go in as separate lines: fish computes the title before # running a command line, so TAB_TITLE must already be set by then. local input="" if [[ -n $title ]]; then input="set -gx TAB_TITLE (printf '$(fish_printf_ascii "$title")')"$'\n' fi if [[ -n $command ]]; then input+="$command"$'\n' fi
osascript - "$dir" "$input" <<-'APPLESCRIPT' on run argv set targetCwd to item 1 of argv set startupInput to item 2 of argv tell application "Ghostty" set cfg to new surface configuration set initial working directory of cfg to targetCwd if startupInput is not "" then set initial input of cfg to startupInput end if if (count of windows) > 0 then new tab in front window with configuration cfg else new window with configuration cfg end if activate end tell end run APPLESCRIPT}
main() { local title="" while [[ ${1:-} == -* ]]; do case $1 in -t | --title) [[ $# -ge 2 ]] || usage title=$2 shift 2 ;; --) shift break ;; *) usage ;; esac done
[[ $# -ge 1 ]] || usage
local raw_dir="$1" shift
# Expand a leading ~ and resolve to an absolute path; AppleScript will not. local dir="${raw_dir/#\~/$HOME}" if [[ ! -d $dir ]]; then echo "term-tab: not a directory: $dir" >&2 exit 66 fi dir="$(cd "$dir" && pwd -P)"
local command="" if [[ $# -gt 0 ]]; then command="$*" fi
if in_rex; then open_rex_tab "$dir" "$title" "$command" else open_ghostty_tab "$dir" "$title" "$command" fi}
main "$@"