Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ SHELL := /bin/bash
INSTALL_SCRIPT := scripts/install-enhanced.sh
TEST_SCRIPT := scripts/test-install.sh
SECURITY_SCRIPT := scripts/security-check.sh
SHELL_SCRIPTS := $(INSTALL_SCRIPT) $(TEST_SCRIPT) $(SECURITY_SCRIPT)
TMUX_OPEN_URL_SCRIPT := tmux/open-url.sh
SHELL_SCRIPTS := $(INSTALL_SCRIPT) $(TEST_SCRIPT) $(SECURITY_SCRIPT) $(TMUX_OPEN_URL_SCRIPT)
BATS_TESTS := tests/test_dotfiles.bats

.PHONY: help syntax lint security test test-bats check install install-dry install-no-backup quick-install backup brew clean
Expand Down
28 changes: 25 additions & 3 deletions tests/test_dotfiles.bats
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,40 @@ EOF

@test "tmux and ghostty preserve clickable URLs" {
grep -q 'terminal-features.*,xterm-ghostty:extkeys:hyperlinks' "$DOTFILES_DIR/tmux/tmux.conf"
grep -q '^set -g word-separators " "$' "$DOTFILES_DIR/tmux/tmux.conf"
grep -q '^bind-key -n MouseDown1Pane if -F "#{mouse_hyperlink}"' "$DOTFILES_DIR/tmux/tmux.conf"
grep -q 'command -v open' "$DOTFILES_DIR/tmux/tmux.conf"
grep -q 'command -v xdg-open' "$DOTFILES_DIR/tmux/tmux.conf"
grep -q 'open-url.sh "#{q:mouse_hyperlink}"' "$DOTFILES_DIR/tmux/tmux.conf"
grep -q 'open-url.sh "#{q:mouse_word}"' "$DOTFILES_DIR/tmux/tmux.conf"
grep -q '^link-url = true$' "$DOTFILES_DIR/ghostty/config"
}

@test "tmux URL opener normalizes plain links safely" {
local fake_bin="$TEST_TMPDIR/fake-bin"
local opened_url="$TEST_TMPDIR/opened-url"
mkdir -p "$fake_bin"

cat > "$fake_bin/open" <<EOF
#!/bin/bash
printf '%s\n' "\$1" > "$opened_url"
EOF
chmod +x "$fake_bin/open"

run env PATH="$fake_bin:$PATH" "$DOTFILES_DIR/tmux/open-url.sh" '"https://example.com/path?x=1".'
[ "$status" -eq 0 ]
[ "$(cat "$opened_url")" = "https://example.com/path?x=1" ]

rm -f "$opened_url"
run env PATH="$fake_bin:$PATH" "$DOTFILES_DIR/tmux/open-url.sh" 'www.example.com/docs,'
[ "$status" -eq 0 ]
[ "$(cat "$opened_url")" = "https://www.example.com/docs" ]
}

@test "tmux config syntax is valid" {
if ! command -v tmux >/dev/null 2>&1; then
skip "tmux not available"
fi

run tmux -f /dev/null source-file -n "$DOTFILES_DIR/tmux/tmux.conf"
run tmux -L "dotfiles-bats-$$" -f /dev/null start-server \; source-file -n "$DOTFILES_DIR/tmux/tmux.conf" \; kill-server
[ "$status" -eq 0 ]
}

Expand Down
20 changes: 20 additions & 0 deletions tmux/open-url.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail

url="${1:-}"

# tmux can hand us surrounding punctuation when it extracts a plain-text URL.
# Strip common wrappers/trailing sentence punctuation before opening.
url="$(printf '%s' "$url" | sed -E "s/^[][[:space:]<({[\"'\`]+//; s/[][[:space:]>)}\"'\`.,;:!?]+$//")"

case "$url" in
http://*|https://*|mailto:*|file://*|ssh://*|git://*) ;;
www.*) url="https://$url" ;;
*) exit 0 ;;
esac

if command -v open >/dev/null 2>&1; then
exec open "$url"
elif command -v xdg-open >/dev/null 2>&1; then
exec xdg-open "$url"
fi
6 changes: 4 additions & 2 deletions tmux/tmux.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ set-option -as terminal-features ",xterm-ghostty:extkeys:hyperlinks"
set-option -g extended-keys always
set-option -g extended-keys-format csi-u
set -g mouse on
# Keep URL punctuation inside tmux mouse_word so plain-text links can be opened.
set -g word-separators " "

# Open OSC 8 hyperlinks directly when clicked, but keep normal tmux mouse behavior elsewhere.
bind-key -n MouseDown1Pane if -F "#{mouse_hyperlink}" { run-shell -b 'url=#{q:mouse_hyperlink}; if command -v open >/dev/null 2>&1; then open "$url"; elif command -v xdg-open >/dev/null 2>&1; then xdg-open "$url"; fi' } { select-pane -t =; send-keys -M }
# Open OSC 8 hyperlinks and plain-text URLs directly when clicked, but keep normal tmux mouse behavior elsewhere.
bind-key -n MouseDown1Pane if -F "#{mouse_hyperlink}" { run-shell -b '~/.config/tmux/open-url.sh "#{q:mouse_hyperlink}"' } { if -F "#{m/ri:^(https?://|mailto:|file://|ssh://|git://|www\.),#{mouse_word}}" { run-shell -b '~/.config/tmux/open-url.sh "#{q:mouse_word}"' } { select-pane -t =; send-keys -M } }

# Forward Shift+Enter as CSI-u so Codex can insert a newline instead of submitting.
bind-key -n S-Enter send-keys -H 1b 5b 31 33 3b 32 75
Expand Down
Loading