aboutsummaryrefslogtreecommitdiff
path: root/linux/home/.config
diff options
context:
space:
mode:
Diffstat (limited to 'linux/home/.config')
-rwxr-xr-xlinux/home/.config/tmux/file_manager.sh108
-rwxr-xr-xlinux/home/.config/tmux/fzf-menu.sh60
-rwxr-xr-xlinux/home/.config/tmux/notes.sh113
-rwxr-xr-xlinux/home/.config/tmux/tmux-popup-pane-manager.sh152
-rw-r--r--linux/home/.config/tmux/tmux.conf19
-rwxr-xr-xlinux/home/.config/tmux/tmux_number.sh11
6 files changed, 458 insertions, 5 deletions
diff --git a/linux/home/.config/tmux/file_manager.sh b/linux/home/.config/tmux/file_manager.sh
new file mode 100755
index 0000000..b3a70a5
--- /dev/null
+++ b/linux/home/.config/tmux/file_manager.sh
@@ -0,0 +1,108 @@
+#!/usr/bin/env bash
+# tmux file opener with fallback file manager (no preview)
+
+# Mark this pane as the file manager immediately
+tmux select-pane -T "FILE_MANAGER"
+# Also set the option as backup
+tmux set-option -pq @file_manager 1
+
+orig_pane="$1"
+chooser_file="$HOME/.cache/tmux-fm-selected"
+rm -f "$chooser_file"
+
+# Function: pick available file manager
+pick_fm() {
+ if command -v lf >/dev/null 2>&1; then
+ echo "lf"
+ elif command -v nnn >/dev/null 2>&1; then
+ echo "nnn"
+ elif command -v ranger >/dev/null 2>&1; then
+ echo "ranger"
+ else
+ echo ""
+ fi
+}
+
+fm=$(pick_fm)
+if [[ -z "$fm" ]]; then
+ echo "No file manager found (lf, nnn, ranger)." >&2
+ cleanup
+ exit 1
+fi
+
+# Cleanup function to reset both title and option
+cleanup() {
+ tmux select-pane -T ""
+ tmux set-option -puq @file_manager
+ rm -f "$chooser_file"
+}
+
+# Set trap to cleanup on exit (including when user presses 'q')
+trap cleanup EXIT INT TERM
+
+# Launch the chosen file manager with no preview where possible
+case "$fm" in
+ nnn)
+ # Disable preview completely and use picker mode
+ # -A: disable dir auto-select, -e: open text files in editor
+ # -o: open files with opener, -x: show only selection
+ NNN_OPENER="tee \"$chooser_file\"" nnn -Axo
+ ;;
+ lf)
+ # Disable preview and set selection path
+ lf -command 'set preview false' -selection-path="$chooser_file"
+ ;;
+ ranger)
+ # Disable all previews
+ ranger --choosefile="$chooser_file" \
+ --cmd='set preview_files false' \
+ --cmd='set preview_directories false' \
+ --cmd='set preview_images false'
+ ;;
+esac
+
+# Exit if no file chosen (user pressed 'q' or cancelled)
+if [[ ! -s "$chooser_file" ]]; then
+ exit 0
+fi
+
+file="$(head -n 1 "$chooser_file")"
+rm -f "$chooser_file"
+
+# Restrict to current window panes and exclude the file manager pane
+current_window=$(tmux display-message -p '#I')
+mapfile -t panes < <(
+ tmux list-panes -t "$current_window" -F '#S:#I.#P' |
+ grep -v "^$(tmux display-message -p '#S:#I').$(tmux display-message -p '#P')$"
+)
+
+# Choose target pane
+if [[ ${#panes[@]} -eq 0 ]]; then
+ exit 1
+elif [[ ${#panes[@]} -eq 1 ]]; then
+ target="${panes[0]}"
+else
+ echo "Select target pane:"
+ for i in "${!panes[@]}"; do
+ letter=$(printf "\\$(printf '%03o' $((97 + i)))") # a, b, c...
+ echo "$letter) ${panes[$i]}"
+ done
+ read -n 1 -p "Choice: " choice
+ echo
+ idx=$(( $(printf "%d" "'$choice") - 97 ))
+ if [[ $idx -ge 0 && $idx -lt ${#panes[@]} ]]; then
+ target="${panes[$idx]}"
+ else
+ exit 1
+ fi
+fi
+
+# Decide if file is text or binary
+if file --mime-type "$file" 2>/dev/null | grep -q 'text/'; then
+ opener="${EDITOR:-$(command -v nvim || command -v vim || echo 'vi')}"
+else
+ opener="$(command -v xdg-open || command -v open || echo 'cat')"
+fi
+
+# Send open command to target pane
+tmux send-keys -t "$target" "$opener \"$file\"" C-m
diff --git a/linux/home/.config/tmux/fzf-menu.sh b/linux/home/.config/tmux/fzf-menu.sh
new file mode 100755
index 0000000..d7863d9
--- /dev/null
+++ b/linux/home/.config/tmux/fzf-menu.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# fzf session name
+FZF_SESSION_NAME="fzf"
+
+# Print error messages
+error() {
+ echo "Error: $1" >&2
+}
+
+# Check if tmux is installed
+if ! command -v tmux >/dev/null 2>&1; then
+ error "tmux is not installed."
+ exit 1
+fi
+
+# Function to handle file or directory opening
+open_selected_item() {
+ # Use fzf to select a file from the specified directory
+ SELECTED_FILE=$(find ~ -type f | fzf --preview "bat --style=numbers --color=always --line-range=:500 {}" \
+ --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi)
+
+ if [ "$SELECTED_FILE" != "" ]; then
+ # Ask whether to open the file or its directory
+ read -p "Open file (f) or directory (d)? " choice
+ case "$choice" in
+ f | F)
+ # Open the selected file in nvim
+ nvim "$SELECTED_FILE"
+ ;;
+ d | D)
+ # Change to the directory containing the selected file
+ cd "$(dirname "$SELECTED_FILE")"
+ ;;
+ *)
+ echo "Invalid choice. Please enter 'f' for file or 'd' for directory."
+ ;;
+ esac
+ else
+ echo "No file selected."
+ fi
+}
+
+# Check if the fzf session exists
+if tmux has-session -t "$FZF_SESSION_NAME" 2>/dev/null; then
+ # Get the current tmux session name
+ CURRENT_SESSION=$(tmux display-message -p '#S')
+
+ # If currently in the fzf session, detach; otherwise, attach to it
+ if [ "$CURRENT_SESSION" = "$FZF_SESSION_NAME" ]; then
+ tmux detach-client
+ else
+ tmux set -gF '@last_session_name' '#S' # Store the current session name
+ tmux display-popup -E -x200% -y0 -w50% -h99% "tmux attach-session -t $FZF_SESSION_NAME"
+ fi
+else
+ # If the fzf session doesn't exist, create it and run file selection logic in a popup
+ tmux set -gF '@last_session_name' '#S' # Store the current session name
+ tmux display-popup -E -w100% -h100% -y0 -x0 "tmux new-session -A -s fzf '$0 open_selected_item'"
+fi
diff --git a/linux/home/.config/tmux/notes.sh b/linux/home/.config/tmux/notes.sh
new file mode 100755
index 0000000..71a8dc7
--- /dev/null
+++ b/linux/home/.config/tmux/notes.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+
+# Notes/TODO management & quick search engine via tmux
+
+NOTES_DIR="$HOME/documents/main"
+TODO_FILE="$NOTES_DIR/inbox/tasks/TODO.md"
+EDITOR="nvim"
+NOTE_SESSION_NAME="note"
+BROWSER_PREFERENCES=("firefox" "chromium" "google-chrome" "brave-browser" "chrome")
+SEARCH_URL="https://www.google.com/search?q="
+
+# simple error printing
+error() {
+ echo "Error: $1" >&2
+}
+
+# add a TODO entry with timestamp
+add_todo() {
+ local todo_text="$1"
+ [ -z "$todo_text" ] && return 1
+
+ [ ! -f "$TODO_FILE" ] && echo -e "# TODO List\n" > "$TODO_FILE"
+
+ echo "- [ ] $todo_text ($(date '+%Y-%m-%d %H:%M'))" >> "$TODO_FILE"
+ tmux display-message "Added TODO: $todo_text"
+}
+
+# open a web search
+search_web() {
+ local query="$1"
+ [ -z "$query" ] && return 1
+
+ local encoded_query=$(printf '%s' "$query" | sed 's/ /+/g' | sed 's/[^a-zA-Z0-9+._-]//g')
+ local search_url="${SEARCH_URL}${encoded_query}"
+
+ if command -v xdg-open >/dev/null 2>&1; then
+ xdg-open "$search_url" >/dev/null 2>&1 &
+ else
+ for browser in "${BROWSER_PREFERENCES[@]}"; do
+ command -v "$browser" >/dev/null 2>&1 && $browser "$search_url" >/dev/null 2>&1 & break
+ done
+ fi
+
+ tmux display-message "Opening search for: $query"
+}
+
+# display the notes menu (in-editor or popup)
+open_menu() {
+ tmux set -gF '@last_session_name' '#S'
+
+ if tmux has-session -t "$NOTE_SESSION_NAME" 2>/dev/null && tmux list-panes -t "$NOTE_SESSION_NAME" -F "#{pane_current_command}" | grep -q "^nvim$"; then
+ # menu for active nvim session
+ tmux display-menu -T "#[align=center] Notes (nvim-mode)" \
+ "New note" n "command-prompt -p 'Enter note title:' 'send-keys -t $NOTE_SESSION_NAME \":e $NOTES_DIR/%%.md\" Enter'" \
+ "Open note" o "send-keys -t $NOTE_SESSION_NAME \":cd $NOTES_DIR | FzfLua files\" Enter" \
+ "TODO List" t "send-keys -t $NOTE_SESSION_NAME \":e $TODO_FILE\" Enter" \
+ "Add Quick TODO" T "command-prompt -p 'Enter TODO:' 'run-shell \"$0 --add-todo %%\"'" \
+ "Grep/find patterns" g "send-keys -t $NOTE_SESSION_NAME \":cd $NOTES_DIR | FzfLua live_grep\" Enter" \
+ "Web Search" s "command-prompt -p 'Search query:' 'run-shell \"$0 --search %%\"'" \
+ "Quit (q)" q ""
+ else
+ # popup menu outside of nvim
+ tmux display-menu -T "#[align=center] Notes (popup-mode)" \
+ "New note" n "command-prompt -p 'Enter note title:' \"display-popup -w 100% -h 100% -E 'tmux new-session -A -s $NOTE_SESSION_NAME \\\"$EDITOR $NOTES_DIR/%%.md\\\"'\"" \
+ "Open note" o "display-popup -w 100% -h 100% -E \"tmux new-session -A -s $NOTE_SESSION_NAME 'fzf --preview \\\"bat --style=numbers --color=always --line-range=:500 {}\\\" --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi < <(find $NOTES_DIR -type f -name \\\"*.md\\\") | xargs -r $EDITOR'\"" \
+ "TODO List" t "display-popup -w 100% -h 100% -E \"tmux new-session -A -s $NOTE_SESSION_NAME \\\"$EDITOR $TODO_FILE\\\"\"" \
+ "Add Quick TODO" T "command-prompt -p 'Enter TODO:' 'run-shell \"$0 --add-todo %%\"'" \
+ "Grep/find patterns" g "display-popup -w 100% -h 100% -E \"tmux new-session -A -s $NOTE_SESSION_NAME 'rg --color=always --line-number --no-heading --smart-case . $NOTES_DIR | fzf --delimiter=: --preview \\\"bat --style=numbers --color=always --line-range=:500 {1}\\\" --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi | cut -d ':' -f 1 | xargs -r $EDITOR'\"" \
+ "Web Search" s "command-prompt -p 'Search query:' 'run-shell \"$0 --search %%\"'" \
+ "Quit (q)" q ""
+ fi
+}
+
+# make sure tmux is installed
+command -v tmux >/dev/null 2>&1 || { error "tmux is not installed."; exit 1; }
+
+# handle CLI arguments
+if [ "$1" = "--add-todo" ]; then
+ shift
+ add_todo "$*"
+ exit 0
+fi
+
+if [ "$1" = "--search" ]; then
+ shift
+ search_web "$*"
+ exit 0
+fi
+
+if [ "$1" = "--new" ]; then
+ if tmux has-session -t "$NOTE_SESSION_NAME" 2>/dev/null; then
+ # reuse existing session
+ tmux display-popup -w 100% -h 100% -E "
+ FILE=\$(find $NOTES_DIR -type f -name '*.md' \
+ | fzf --preview 'bat --style=numbers --color=always --line-range=:500 {}' \
+ --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi)
+ [ -n \"\$FILE\" ] && tmux send-keys -t $NOTE_SESSION_NAME \":e \$FILE\" Enter
+ "
+ else
+ open_menu
+ fi
+ exit 0
+fi
+
+# default behavior: toggle or open menu
+if [ -z "$1" ]; then
+ if tmux has-session -t "$NOTE_SESSION_NAME" 2>/dev/null; then
+ CURRENT_SESSION=$(tmux display-message -p '#S')
+ [ "$CURRENT_SESSION" = "$NOTE_SESSION_NAME" ] && tmux detach-client || tmux display-popup -E -x200% -y0 -w50% -h99% "tmux attach-session -t $NOTE_SESSION_NAME"
+ else
+ open_menu
+ fi
+fi
diff --git a/linux/home/.config/tmux/tmux-popup-pane-manager.sh b/linux/home/.config/tmux/tmux-popup-pane-manager.sh
new file mode 100755
index 0000000..bb0cfef
--- /dev/null
+++ b/linux/home/.config/tmux/tmux-popup-pane-manager.sh
@@ -0,0 +1,152 @@
+#!/usr/bin/bash
+# tmux-popup-pane-manager.sh - menu driven tmux pane activities
+# github repo: https://github.com/pl643/tmux-scripts
+# resize, selection, syncronize, layout, splits, kill, break
+
+# sample tmux.conf binding:
+# bind-key -n M-p tmux-popup-pane-manager.sh
+
+[ "$TMUX" = "" ] && echo "NOTE: needs to be run inside a tmux sessions" && exit 1
+
+run_after_popup="/tmp/.run_after_popup"
+realpath="$(realpath "$0")"
+if [ "$1" != "--no-popup" ]; then
+ tmux popup -E -T "────────────── Pane Manager ─────" -w 46 -h 35 "$realpath --no-popup"
+
+ [ -f "$run_after_popup" ] && bash "$run_after_popup" && rm "$run_after_popup"
+ exit 0
+fi
+
+pane_border_status="off"
+display_menu() {
+ clear
+ tmux list-windows | grep active | awk '{print $2}' | tail -c2 | grep -q Z && zoom_status="on" || zoom_status="off"
+ tmux show-options -w | grep -q 'synchronize-panes.*on' && synchronize_panes="on" || synchronize_panes="off"
+ tmux show-options -w | grep -q 'pane-border-status.*top' && pane_border_status="top"
+ tmux show-options -w | grep -q 'pane-border-status.*bottom' && pane_border_status="bottom"
+ printf "
+ Resize
+
+ hjkl x 5 HJKL x 1
+ 1 - 9 | x 10%% ! - ) ─ x 10%%
+ = equally | + equally ─
+
+ Split
+
+ s - spilt - v | spilt |
+
+ Navigation
+
+ n p next/prev pane
+ N P next/prev layout
+ u d swap pane up/down
+
+ Toggles
+
+ b border [ %s ]
+ S syncronize [ %s ]
+ z zoom [ %s ]
+
+ Misc
+
+ B break (make pane into window)
+ o join this pane to window
+ D send C-d
+ e display panes / exit
+ t rename pane
+ X kill (no confirm!)
+ q quit" "$pane_border_status" "$synchronize_panes" "$zoom_status"
+}
+display_menu
+
+# https://www.reddit.com/r/tmux/comments/g9nr01/how_to_show_message_or_effect_when/
+# Uncomment this setting if want status of pane sync on the status bar
+tmux set -ag status-right '#{?pane_synchronized, #[fg=red]IN_SYNC#[default],}'
+
+# https://www.reddit.com/r/tmux/comments/dfj5ye/rename_pane_not_window_is_there_a_builtin/
+tmux set -g pane-border-format " [ ###P #T ] "
+
+# If C-c is press in the while [ true ] loop, a run runaway process occurs, limiting
+# it to 20 will cause the loop to exit after 20 loops. Modify MAXNUMLOOP if you
+# need more keys presses.
+MAXNUMLOOP=100
+COUNTER=0
+while [ "$COUNTER" -lt "$MAXNUMLOOP" ]; do
+
+ read -sn1 c || exit
+
+ # Resize x 1
+ [ "$c" = "H" ] && tmux resize-pane -L 1
+ [ "$c" = "L" ] && tmux resize-pane -R 1
+ [ "$c" = "J" ] && tmux resize-pane -D 1
+ [ "$c" = "K" ] && tmux resize-pane -U 1
+
+ # Resize x 5
+ [ "$c" = "h" ] && tmux resize-pane -L 5
+ [ "$c" = "l" ] && tmux resize-pane -R 5
+ [ "$c" = "j" ] && tmux resize-pane -D 5
+ [ "$c" = "k" ] && tmux resize-pane -U 5
+
+ # Resize X percent
+ [ "$c" = "1" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 10 / 100))
+ [ "$c" = "2" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 20 / 100))
+ [ "$c" = "3" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 30 / 100))
+ [ "$c" = "4" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 40 / 100))
+ [ "$c" = "5" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 50 / 100))
+ [ "$c" = "6" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 60 / 100))
+ [ "$c" = "7" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 70 / 100))
+ [ "$c" = "8" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 80 / 100))
+ [ "$c" = "9" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 90 / 100))
+
+ # Resize Y percent
+ [ "$c" = "!" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 10 / 100))
+ [ "$c" = "@" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 20 / 100))
+ [ "$c" = "#" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 30 / 100))
+ [ "$c" = "$" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 40 / 100))
+ [ "$c" = "%" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 50 / 100))
+ [ "$c" = "^" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 60 / 100))
+ [ "$c" = "&" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 70 / 100))
+ [ "$c" = "*" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 80 / 100))
+ [ "$c" = "(" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 90 / 100))
+
+ # Pane layout cycle
+ [ "$c" = "N" ] || [ "$c" = " " ] && tmux next-layout
+ [ "$c" = "P" ] && tmux previous-layout
+
+ # Pane selection cycle
+ [ "$c" = "n" ] && tmux select-pane -t :.+
+ [ "$c" = "p" ] && tmux select-pane -t :.-
+
+ # Pane layout selection even horizontal/vertical
+ [ "$c" = "=" ] && tmux select-layout even-horizontal
+ [ "$c" = "+" ] && tmux select-layout even-vertical
+
+ # Rotate pane
+ [ "$c" = "u" ] && tmux swap-pane -U
+ [ "$c" = "d" ] && tmux swap-pane -D
+
+ # Syncronize pane
+ [ "$c" = "S" ] && tmux setw synchronize-pane && display_menu
+
+ # border status ( 3 toggle off, top, bottom )
+ [ "$c" = "b" ] && [ "$pane_border_status" = "off" ] && tmux set pane-border-status && display_menu && continue
+ [ "$c" = "b" ] && [ "$pane_border_status" = "top" ] && tmux set pane-border-status bottom && display_menu && continue
+ [ "$c" = "b" ] && [ "$pane_border_status" = "bottom" ] && tmux set pane-border-status off &&
+ pane_border_status="off" && display_menu && continue
+
+ # Split panes
+ [ "$c" = "s" ] || [ "$c" = "-" ] && tmux split -v
+ [ "$c" = "v" ] || [ "$c" = "|" ] && tmux split -h
+
+ # Misc
+ [ "$c" = "B" ] && tmux break-pane
+ [ "$c" = "o" ] && printf "\n\n join window: " && read window && tmux join-pane -t "$window"
+ [ "$c" = "X" ] && tmux kill-pane
+ [ "$c" = "D" ] && tmux send-key C-d
+ display_menu
+ [ "$c" = "q" ] && exit
+ [ "$c" = "e" ] && echo tmux display-panes >"$run_after_popup" && exit
+ [ "$c" = "z" ] && tmux resize-pane -Z && display_menu
+ [ "$c" = "t" ] && printf "\n\n pane name: " && read pane_name && tmux select-pane -T "$pane_name" && display_menu
+ let COUNTER=COUNTER+1
+done
diff --git a/linux/home/.config/tmux/tmux.conf b/linux/home/.config/tmux/tmux.conf
index 8a821e6..a62e3e3 100644
--- a/linux/home/.config/tmux/tmux.conf
+++ b/linux/home/.config/tmux/tmux.conf
@@ -46,9 +46,7 @@ set -sg escape-time 10
bind r source-file ~/.config/tmux/tmux.conf \; display "Reloaded!"
# Use <Prefix>L to clear terminal
-#bind -r L send-keys C-l \; send-keys -R \; clear-history
-bind -r L send-keys C-l \; send-keys 'Enter'
-#bind-key -n C-L if-shell "$is_vim" "send-keys C-l" "send-keys C-l"
+bind -r L send-keys "clear" Enter
# Rename current window (Ctrl + A, A)
bind R rename-window '' \; \
@@ -392,8 +390,11 @@ bind -n M-t if-shell -F '#{==:#{session_name},term}' {
## Toggle popup "note" session
-bind-key -n M-n run-shell ~/.config/tmux/tmux-notes-menu.sh
-bind-key -n M-N run-shell "~/.config/tmux/tmux-notes-menu.sh --new"
+bind-key -n M-n if-shell -F "#{client_in_popup}" \
+ "detach-client -P" \
+ "run-shell ~/.config/tmux/notes.sh"
+
+bind-key -n M-N run-shell "~/.config/tmux/notes.sh --new"
# Toggle popup "pack" session
bind-key -n M-p if-shell -F '#{==:#{session_name},pack}' {
@@ -413,6 +414,14 @@ bind-key -n M-o if-shell -F '#{==:#{session_name},todo}' {
display-popup -E -x200% -y0 -w50% -h99% "tmux new-session -A -s todo 'nvim ~/documents/main/inbox/tasks/TODO.md'"
}
+# M-y → Toggle VM popup (starts/attaches session "virt" inside popup)
+bind-key -n M-y if-shell -F '#{==:#{session_name},virt}' {
+ detach-client -P
+} {
+ set -gF '@last_session_name' '#S'
+ display-popup -E -x200% -y0 -w40% -h60% "tmux new-session -A -s virt bash -lc 'echo \"### VM Manager ###\"; echo; echo \"Available VM scripts:\"; ls -1 ~/.scripts/env/virt/ 2>/dev/null || echo \"No scripts found in ~/.scripts/env/virt/\"; echo; echo \"Run your VM by typing its script name (e.g., ubuntu, fedora, win11).\"; exec \$SHELL'"
+}
+
# M-H → Open history in popup
bind-key -n M-H if-shell -F '#{==:#{session_name},hist}' {
detach-client
diff --git a/linux/home/.config/tmux/tmux_number.sh b/linux/home/.config/tmux/tmux_number.sh
new file mode 100755
index 0000000..5d239d0
--- /dev/null
+++ b/linux/home/.config/tmux/tmux_number.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -x
+dest="$1"
+[ "x""$dest" != "x" ]
+tmux list-windows -F "#{window_index}" | grep "^${dest}$" 2>&1 >/dev/null
+ret="$?"
+if [ "x""$ret" = "x0" ]; then
+ tmux swap-window -t ":${dest}"
+else
+ tmux move-window -t ":${dest}"
+fi