summaryrefslogtreecommitdiff
path: root/frontends/scripts
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-01 19:46:45 +0200
committerPaul Buetow <paul@buetow.org>2026-02-01 19:46:45 +0200
commitb573deca48f8d6e3e878c708aefa3e63bac9c178 (patch)
tree7e7c976dd5324c47b8ed334f2227cebedb2f9c40 /frontends/scripts
parent687132aea4c9ea486fc958f042294fb914d3c1c5 (diff)
Refactor tmux-edit-send and document helpers.
Add function comments and optional logging toggle.
Diffstat (limited to 'frontends/scripts')
-rw-r--r--frontends/scripts/tmux-edit-send221
1 files changed, 136 insertions, 85 deletions
diff --git a/frontends/scripts/tmux-edit-send b/frontends/scripts/tmux-edit-send
index af2ffa3..712b809 100644
--- a/frontends/scripts/tmux-edit-send
+++ b/frontends/scripts/tmux-edit-send
@@ -1,57 +1,57 @@
#!/usr/bin/env bash
set -u -o pipefail
+LOG_ENABLED=0
log_file="${TMPDIR:-/tmp}/tmux-edit-send.log"
log() {
- printf '%s\n' "$*" >> "$log_file"
+ if [ "$LOG_ENABLED" -eq 1 ]; then
+ printf '%s\n' "$*" >> "$log_file"
+ fi
+}
+
+# Read the target pane id from a temp file created by tmux binding.
+read_target_from_file() {
+ local file_path="$1"
+ if [ -n "$file_path" ] && [ -f "$file_path" ]; then
+ sed -n '1p' "$file_path" | tr -d '[:space:]'
+ fi
}
-target_file="${1:-}"
-target=""
-if [ -n "$target_file" ] && [ -f "$target_file" ]; then
- target="$(sed -n '1p' "$target_file" | tr -d '[:space:]')"
- log "file target=${target:-<empty>}"
- rm -f "$target_file"
-fi
-
-if [ -z "$target" ]; then
- target="${TMUX_EDIT_TARGET:-}"
-fi
-log "env target=${target:-<empty>}"
-if [ -z "$target" ]; then
+# Read the target pane id from tmux environment if present.
+read_target_from_env() {
+ local env_line
env_line="$(tmux show-environment -g TMUX_EDIT_TARGET 2>/dev/null || true)"
case "$env_line" in
- TMUX_EDIT_TARGET=*) target="${env_line#TMUX_EDIT_TARGET=}" ;;
+ TMUX_EDIT_TARGET=*) printf '%s' "${env_line#TMUX_EDIT_TARGET=}" ;;
esac
-fi
-log "tmux env target=${target:-<empty>}"
-
-current_pane="$(tmux display-message -p "#{pane_id}" 2>/dev/null || true)"
-log "current pane=${current_pane:-<empty>}"
-if [ -n "$target" ] && [[ "$target" == *"#{"* ]]; then
- log "format target detected, clearing"
- target=""
-fi
-if [ -z "$target" ]; then
- target="$(tmux display-message -p "#{last_pane}" 2>/dev/null || true)"
-elif [ "$target" = "$current_pane" ]; then
- last_pane="$(tmux display-message -p "#{last_pane}" 2>/dev/null || true)"
- if [ -n "$last_pane" ]; then
- target="$last_pane"
- fi
-fi
-log "fallback target=${target:-<empty>}"
+}
-editor="${EDITOR:-vi}"
-tmpfile="$(mktemp "./.tmux-edit-send.XXXXXX.md")"
+# Resolve the target pane id, falling back to the last pane.
+resolve_target_pane() {
+ local candidate="$1"
+ local current_pane last_pane
-cleanup() {
- rm -f "$tmpfile"
+ current_pane="$(tmux display-message -p "#{pane_id}" 2>/dev/null || true)"
+ log "current pane=${current_pane:-<empty>}"
+ if [ -n "$candidate" ] && [[ "$candidate" == *"#{"* ]]; then
+ log "format target detected, clearing"
+ candidate=""
+ fi
+ if [ -z "$candidate" ]; then
+ candidate="$(tmux display-message -p "#{last_pane}" 2>/dev/null || true)"
+ elif [ "$candidate" = "$current_pane" ]; then
+ last_pane="$(tmux display-message -p "#{last_pane}" 2>/dev/null || true)"
+ if [ -n "$last_pane" ]; then
+ candidate="$last_pane"
+ fi
+ fi
+ printf '%s' "$candidate"
}
-trap cleanup EXIT
-prompt_text="$(tmux capture-pane -p -t "$target" -S -2000 2>/dev/null | \
- awk '
+# Capture the latest multi-line prompt content from the pane.
+capture_prompt_text() {
+ local target="$1"
+ tmux capture-pane -p -t "$target" -S -2000 2>/dev/null | awk '
function trim_box(line) {
sub(/^ *│ ?/, "", line)
sub(/ *│ *$/, "", line)
@@ -86,51 +86,102 @@ prompt_text="$(tmux capture-pane -p -t "$target" -S -2000 2>/dev/null | \
if (text != "") last = text
if (last != "") print last
}
- ')"
-if [ -n "$prompt_text" ]; then
- printf '%s\n' "$prompt_text" > "$tmpfile"
-fi
-
-"$editor" "$tmpfile"
-log "editor exited with status $?"
-
-if [ ! -s "$tmpfile" ]; then
- log "empty file, nothing sent"
- exit 0
-fi
-
-# Validate target after editor so popup stays open.
-if [ -z "$target" ]; then
- log "error: no target pane determined"
- echo "Could not determine target pane." >&2
- exit 1
-fi
-
-target_found=0
-for pane in $(tmux list-panes -a -F "#{pane_id}" 2>/dev/null || true); do
- if [ "$pane" = "$target" ]; then
- target_found=1
- break
+ '
+}
+
+# Write captured prompt text into the temp file if available.
+prefill_tmpfile() {
+ local tmpfile="$1"
+ local prompt_text="$2"
+ if [ -n "$prompt_text" ]; then
+ printf '%s\n' "$prompt_text" > "$tmpfile"
+ fi
+}
+
+# Ensure the target pane exists before sending keys.
+validate_target_pane() {
+ local target="$1"
+ local pane target_found
+ if [ -z "$target" ]; then
+ log "error: no target pane determined"
+ echo "Could not determine target pane." >&2
+ return 1
fi
-done
-
-if [ "$target_found" -ne 1 ]; then
- log "error: target pane not found: $target"
- echo "Target pane not found: $target" >&2
- exit 1
-fi
-
-# Send line by line to preserve newlines reliably.
-first_line=1
-while IFS= read -r line || [ -n "$line" ]; do
- if [ "$first_line" -eq 1 ] && [ -n "${prompt_text:-}" ]; then
- if [[ "$line" == "$prompt_text"* ]]; then
- line="${line#"$prompt_text"}"
- line="${line# }"
+ target_found=0
+ for pane in $(tmux list-panes -a -F "#{pane_id}" 2>/dev/null || true); do
+ if [ "$pane" = "$target" ]; then
+ target_found=1
+ break
fi
+ done
+ if [ "$target_found" -ne 1 ]; then
+ log "error: target pane not found: $target"
+ echo "Target pane not found: $target" >&2
+ return 1
fi
- first_line=0
- tmux send-keys -t "$target" -l "$line"
- tmux send-keys -t "$target" Enter
-done < "$tmpfile"
-log "sent content to $target"
+}
+
+# Send temp file contents to the target pane line by line.
+send_content() {
+ local target="$1"
+ local tmpfile="$2"
+ local prompt_text="$3"
+ local first_line=1
+ local line
+ while IFS= read -r line || [ -n "$line" ]; do
+ if [ "$first_line" -eq 1 ] && [ -n "$prompt_text" ]; then
+ if [[ "$line" == "$prompt_text"* ]]; then
+ line="${line#"$prompt_text"}"
+ line="${line# }"
+ fi
+ fi
+ first_line=0
+ tmux send-keys -t "$target" -l "$line"
+ tmux send-keys -t "$target" Enter
+ done < "$tmpfile"
+ log "sent content to $target"
+}
+
+# Main entry point.
+main() {
+ local target_file="${1:-}"
+ local target
+ local editor="${EDITOR:-vi}"
+ local tmpfile
+ local prompt_text
+
+ target="$(read_target_from_file "$target_file" || true)"
+ if [ -n "$target" ]; then
+ log "file target=${target:-<empty>}"
+ rm -f "$target_file"
+ fi
+ if [ -z "$target" ]; then
+ target="${TMUX_EDIT_TARGET:-}"
+ fi
+ log "env target=${target:-<empty>}"
+ if [ -z "$target" ]; then
+ target="$(read_target_from_env || true)"
+ fi
+ log "tmux env target=${target:-<empty>}"
+ target="$(resolve_target_pane "$target")"
+ log "fallback target=${target:-<empty>}"
+
+ tmpfile="$(mktemp "./.tmux-edit-send.XXXXXX.md")"
+ trap 'rm -f "$tmpfile"' EXIT
+
+ prompt_text="$(capture_prompt_text "$target")"
+ prefill_tmpfile "$tmpfile" "$prompt_text"
+
+ "$editor" "$tmpfile"
+ log "editor exited with status $?"
+
+ if [ ! -s "$tmpfile" ]; then
+ log "empty file, nothing sent"
+ exit 0
+ fi
+
+ validate_target_pane "$target"
+ send_content "$target" "$tmpfile" "$prompt_text"
+}
+
+main "$@"