diff options
Diffstat (limited to 'tmuxrdr/plugin/lib.sh')
| -rw-r--r-- | tmuxrdr/plugin/lib.sh | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/tmuxrdr/plugin/lib.sh b/tmuxrdr/plugin/lib.sh new file mode 100644 index 00000000..c7146904 --- /dev/null +++ b/tmuxrdr/plugin/lib.sh @@ -0,0 +1,95 @@ +# Shared by the commands in bin/. POSIX sh -- macOS /bin/sh is bash 3.2. +# Sourced, never run. Every command acts through the herdr CLI, or the raw +# socket for the one method the CLI does not wrap (pane.focus by id). + +set -u + +H="${HERDR_BIN_PATH:-herdr}" +BIN="$(cd "$(dirname "$0")" && pwd)" + +# tmux shows messages and errors ("can't find window: 0") on its status line; +# here they are herdr toasts. +say() { + "$H" notification show "$1" --sound none >/dev/null 2>&1 \ + || printf '%s\n' "$1" >&2 +} + +fail() { + say "$1" + exit 1 +} + +# One newline-delimited JSON request on the session's socket. +api() { + printf '%s\n' "$1" | nc -U -w 2 "${HERDR_SOCKET_PATH:?not run by herdr}" +} + +# The pane the key was pressed in. Keybinding commands and popups get +# HERDR_ACTIVE_PANE_ID; plugin actions get it in their context JSON; anything +# else asks the server which pane is focused. +active_pane() { + _p="${HERDR_ACTIVE_PANE_ID:-}" + if [ -z "$_p" ] && [ -n "${HERDR_PLUGIN_CONTEXT_JSON:-}" ]; then + _p="$(printf '%s' "$HERDR_PLUGIN_CONTEXT_JSON" \ + | jq -r '.focused_pane_id // empty')" + fi + if [ -z "$_p" ]; then + _p="$("$H" pane current | jq -r '.result.pane.pane_id // empty')" + fi + [ -n "$_p" ] || fail "no current pane" + printf '%s' "$_p" +} + +# pane_info PANE FIELD -- e.g. workspace_id, tab_id. +pane_info() { + "$H" pane get "$1" | jq -r --arg k "$2" '.result.pane[$k] // empty' +} + +# Panes of the tab holding PANE, in layout order: tmux's pane index order. +tab_panes() { + "$H" pane layout --pane "$1" | jq -r '.result.layout.panes[].pane_id' +} + +# 0-based position of PANE in its tab: tmux's #P (pane-base-index 0). +pane_index() { + _i="$(tab_panes "$1" | grep -n -x -F "$1" | cut -d: -f1)" + printf '%s' "$((${_i:-1} - 1))" +} + +# Tabs of WORKSPACE in tab-bar order, one "tab_id<TAB>label" per line. +workspace_tabs() { + "$H" tab list --workspace "$1" | jq -r '.result.tabs[] | [.tab_id, .label] | @tsv' +} + +focus_pane() { + api "{\"id\":\"tmux-mode\",\"method\":\"pane.focus\",\"params\":{\"pane_id\":\"$1\"}}" >/dev/null +} + +swap() { + "$H" pane swap --source-pane "$1" --target-pane "$2" >/dev/null +} + +# One keypress, unbuffered, for (y/n) prompts. +read_key() { + _tty="$(stty -g)" + stty -icanon -echo min 1 time 0 + _k="$(dd bs=1 count=1 2>/dev/null)" + stty "$_tty" + printf '%s' "$_k" +} + +# Plugin state (marks, focus history) lives where herdr puts this plugin's, +# one directory per session: herdr shares that directory across sessions, +# and ids repeat between them -- every named session has its own w1. The +# session is the directory holding its socket (herdr for the default one). +state_dir() { + _d="${HERDR_PLUGIN_STATE_DIR:?run as a herdr plugin action}" + _d="$_d/$(basename "$(dirname "${HERDR_SOCKET_PATH:?not run by herdr}")")" + mkdir -p "$_d" + printf '%s' "$_d" +} + +# Tab and workspace ids hold colons; keep file names plain. +key_of() { + printf '%s' "$1" | tr -c 'A-Za-z0-9._-' '_' +} |
