From d094fce66d7c5c936c7bceb2e8cd2783cac51788 Mon Sep 17 00:00:00 2001 From: Martin Larsson Date: Sat, 29 Jun 2024 14:01:03 +0200 Subject: [PATCH] Add tmux config and replace zellij with tmux in zshrc. Zhrc also has some light refactoring, and has added a zsh local file which gets sourced if it exists, useful for adding local environment variables --- home/.config/tmux/tmux-create-session.sh | 5 ++ home/.config/tmux/tmux-fuzzy-find-session.sh | 45 ++++++++++ home/.config/tmux/tmux-move-pane.sh | 14 +++ home/.config/tmux/tmux-set-resize-mode.sh | 13 +++ home/.tmux.conf | 92 ++++++++++++++++++++ home/.zshrc | 23 +++-- 6 files changed, 186 insertions(+), 6 deletions(-) create mode 100755 home/.config/tmux/tmux-create-session.sh create mode 100755 home/.config/tmux/tmux-fuzzy-find-session.sh create mode 100755 home/.config/tmux/tmux-move-pane.sh create mode 100755 home/.config/tmux/tmux-set-resize-mode.sh create mode 100644 home/.tmux.conf diff --git a/home/.config/tmux/tmux-create-session.sh b/home/.config/tmux/tmux-create-session.sh new file mode 100755 index 0000000..19265b7 --- /dev/null +++ b/home/.config/tmux/tmux-create-session.sh @@ -0,0 +1,5 @@ +#!/bin/zsh + +session_name=$1 +tmux new-session -d -s $session_name +tmux switch-client -t $session_name diff --git a/home/.config/tmux/tmux-fuzzy-find-session.sh b/home/.config/tmux/tmux-fuzzy-find-session.sh new file mode 100755 index 0000000..3851bad --- /dev/null +++ b/home/.config/tmux/tmux-fuzzy-find-session.sh @@ -0,0 +1,45 @@ +#!/bin/zsh + +# Run fzf-tmux in the background and serialize the input +( +current_session=$(tmux display-message -p '#S') +selected=$(tmux list-sessions -F '#S' | grep -v "$current_session" | fzf-tmux -p --expect=enter,del --header="Tmux Sessions (Ent/Del)") +echo "$selected" > /tmp/fzf-tmux-target +tmux refresh-client -S +) & + +# Give some time for fzf to initiate and display +sleep 0.1 +tmux refresh-client -S + +# Wait for the fzf-tmux process to complete +wait + +# Read the serialized input +selected=$(cat /tmp/fzf-tmux-target) +rm /tmp/fzf-tmux-target +key=$(head -n1 <<< "$selected") +target=$(tail -n +2 <<< "$selected") + +# Check the pressed key and take appropriate action +case "$key" in + enter) + if [ -n "$target" ]; then + tmux switch-client -t "$target" + tmux display-message "Switched to session: $target" + else + tmux display-message "No session selected" + fi + ;; + del) + if [ -n "$target" ]; then + tmux kill-session -t "$target" + tmux display-message "Deleted session: $target" + else + tmux display-message "No session selected" + fi + ;; + *) + tmux display-message "Action cancelled" + ;; +esac diff --git a/home/.config/tmux/tmux-move-pane.sh b/home/.config/tmux/tmux-move-pane.sh new file mode 100755 index 0000000..8115fbf --- /dev/null +++ b/home/.config/tmux/tmux-move-pane.sh @@ -0,0 +1,14 @@ +#!/bin/zsh + +source_pane=$(tmux display-message -p '#{pane_id}') +target_window=$1 + +window_exists=$(tmux list-windows -F '#I' | grep "^$target_window$") + +if [ -z "$window_exists" ]; then + tmux break-pane -d -t $target_window +else + target_pane=$(tmux list-panes -t $target_window -F '#{pane_id}' | sort | tail -n 1) + tmux join-pane -d -s $source_pane -t $target_pane + tmux select-layout -t $target_window main-vertical +fi diff --git a/home/.config/tmux/tmux-set-resize-mode.sh b/home/.config/tmux/tmux-set-resize-mode.sh new file mode 100755 index 0000000..388e7b7 --- /dev/null +++ b/home/.config/tmux/tmux-set-resize-mode.sh @@ -0,0 +1,13 @@ +#!/bin/zsh + +desired_state=$1 +current_state=$(tmux show-environment -g @resize_mode 2>/dev/null | cut -d '=' -f 2) + +[ "$current_state" = "$desired_state" ] && exit 0 + +tmux set -g @tmux_resize_mode $desired_state +if [ "$desired_state" = "1" ]; then + tmux display-message "Resize mode ON" +else + tmux display-message "Resize mode OFF" +fi diff --git a/home/.tmux.conf b/home/.tmux.conf new file mode 100644 index 0000000..0fd97a5 --- /dev/null +++ b/home/.tmux.conf @@ -0,0 +1,92 @@ +# For some reason, fzf is missing from path when running shell scripts through tmux keybindings +set-environment -g PATH "~/dev/git/fzf/bin:$PATH" + +# Keybindings for navigating between panes +bind-key -n M-Left select-pane -L +bind-key -n M-Down select-pane -D +bind-key -n M-Up select-pane -U +bind-key -n M-Right select-pane -R + +# Resize mode +set -g @tmux_resize_mode 0 +set -g @resize_mode_path "~/.config/tmux/tmux-set-resize-mode.sh" +bind-key -n M-Space if-shell -F "#{==:#{@tmux_resize_mode},0}" "run-shell '#{@resize_mode_path} 1'" "" +bind-key -n Escape if-shell -F "#{==:#{@tmux_resize_mode},1}" "run-shell '#{@resize_mode_path} 0'" "send-keys Escape" +bind-key -n Enter if-shell -F "#{==:#{@tmux_resize_mode},1}" "run-shell '#{@resize_mode_path} 0'" "send-keys Enter" +bind-key -n q if-shell -F "#{==:#{@tmux_resize_mode},1}" "run-shell '#{@resize_mode_path} 0'" "send-keys q" + +# Resize the panes if we are in resize mode +bind-key -n Up if -F "#{==:#{@tmux_resize_mode},1}" "resize-pane -U" "send-keys Up" +bind-key -n Down if -F "#{==:#{@tmux_resize_mode},1}" "resize-pane -D" "send-keys Down" +bind-key -n Left if -F "#{==:#{@tmux_resize_mode},1}" "resize-pane -L" "send-keys Left" +bind-key -n Right if -F "#{==:#{@tmux_resize_mode},1}" "resize-pane -R" "send-keys Right" + +bind-key -n M-p display-message "#{@tmux_resize_mode}" + +bind-key -n M-d run-shell "~/.config/tmux/tmux-fuzzy-find-session.sh" + +# Split window, change keybindings to match vim concept of splits +bind-key -n M-v split-window -h +bind-key -n M-h split-window -v +bind-key -n M-k kill-pane +bind-key -n M-f resize-pane -Z +bind-key -n M-s command-prompt -p "New session: " "run-shell '~/.config/tmux/tmux-create-session.sh '%%''" +bind-key -n M-w new-window +bind-key -n M-r command-prompt -p "Rename window:" "rename-window '%%'" +bind-key -n M-R command-prompt -p "Rename session:" "rename-session '%%'" + +bind-key -n M-c copy-mode +bind-key -T copy-mode-vi v send-keys -X begin-selection +bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel +bind-key -n M-0 select-window -t 0 +bind-key -n M-1 select-window -t 1 +bind-key -n M-2 select-window -t 2 +bind-key -n M-3 select-window -t 3 +bind-key -n M-4 select-window -t 4 +bind-key -n M-5 select-window -t 5 +bind-key -n M-6 select-window -t 6 +bind-key -n M-7 select-window -t 7 +bind-key -n M-8 select-window -t 8 +bind-key -n M-9 select-window -t 9 + +set -g @move-pane-path "~/.config/tmux/tmux-move-pane.sh" +bind-key -n M-) run-shell "#{@move-pane-path} 0" +bind-key -n M-! run-shell "#{@move-pane-path} 1" +bind-key -n M-@ run-shell "#{@move-pane-path} 2" +bind-key -n M-# run-shell "#{@move-pane-path} 3" +bind-key -n M-$ run-shell "#{@move-pane-path} 4" +bind-key -n M-% run-shell "#{@move-pane-path} 5" +bind-key -n M-^ run-shell "#{@move-pane-path} 6" +bind-key -n M-& run-shell "#{@move-pane-path} 7" +bind-key -n M-* run-shell "#{@move-pane-path} 8" +bind-key -n M-( run-shell "#{@move-pane-path} 9" + +# Reload tmux configuration +bind-key -n M-C source-file ~/.tmux.conf \; display-message "Config reloaded" + +# Set the default terminal to support 256 colors +set -g default-terminal "screen-256color" + +# Ensure tmux uses true color +set-option -ga terminal-features 'xterm-256color:RGB' +set-option -ga terminal-overrides ',xterm-256color:Tc' + +# Make sure that the index of windows and panes starts at 1 +set -g base-index 1 +set -g pane-base-index 1 +set -g renumber-windows on + +set -g mode-keys vi + +set -g history-limit 10000 + +set-option -g status-position top + +set -g @catppuccin_flavour "macchiato" +set -g @catppuccin_status_background "#1e2030" +set -g @plugin "catppuccin/tmux" + +set -g @plugin "tmux-plugins/tmux-sensible" + +set -g @plugin "tmux-plugins/tpm" +run "~/dev/git/tpm/tpm" diff --git a/home/.zshrc b/home/.zshrc index 4277866..a680822 100644 --- a/home/.zshrc +++ b/home/.zshrc @@ -17,12 +17,19 @@ set_custom_keybindings() { init() { [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh + [ -f ~/.zshrc_local ] && source ~/.zshrc_local eval "$(fzf --zsh)" eval "$(zoxide init --cmd cd zsh)" set_custom_keybindings } +add_to_path() { + if [[ -d $1 ]] && [[ ! $PATH =~ $1 ]]; then + export PATH=$1:$PATH + fi +} + # Workaround to make sure that the custom keybindings # are persistent when switching modes in zsh-vi-mode ... # It still breaks sometimes when exiting insert mode, but its better than not having it at all @@ -36,9 +43,8 @@ if [[ "$(uname)" == "Darwin" ]]; then fi # Paths -if [[ -d $HOME/.local/nvim ]]; then - export PATH=$HOME/.local/nvim/bin:$PATH # Nightly neovim -fi +add_to_path $HOME/.local/bin +add_to_path $HOME/.local/nvim/bin # Set the directory we want to store zinit and plugins ZINIT_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/zinit/zinit.git" @@ -132,9 +138,14 @@ bwp() { bw get password "$1" | wlc } -# Make sure that zellij isn't recursively started on shell startup -if [[ -z $ZELLIJ ]]; then - zellij --layout ~/.config/zellij/top-bar.kdl +# Check if tmux is already running or if the session is interactive +if [[ -z "$TMUX" ]] && [[ $- == *i* ]]; then + # Create a new tmux session, if one doesnt exist, give it the main name, never attach to a session + if tmux ls &> /dev/null; then + tmux attach + else + tmux new-session -s main + fi fi fastfetch