From 0810857131fb2cc7103dbf26d5ed48d21c151829 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sat, 30 May 2020 17:01:21 +0100 Subject: [PATCH] feat(windows): Integrate windmove with tmux When Emacs is launched within Tmux, and a windmove command fails (due to it reaching the left/right/top/bottom edge of frame, instead trigger a Tmux pane switch in that direction. This allows a nearly seamless window/pane switching experience between Emacs and Tmux. It does require the following configuration in Tmux to work properly: # Enable smart pane switching that's Emacs aware. is_emacs='echo "#{pane_current_command}" | grep -iqE "(^|\/)emacs$"' # Use Alt-[i/k/j/l] keys without prefix key to switch panes if current pane is # not running Emacs. If the pane is running Emacs, let Emacs receive the # keybindings instead. bind -n M-i if-shell "$is_emacs" "send-keys M-i" "select-pane -U" bind -n M-k if-shell "$is_emacs" "send-keys M-k" "select-pane -D" bind -n M-j if-shell "$is_emacs" "send-keys M-j" "select-pane -L" bind -n M-l if-shell "$is_emacs" "send-keys M-l" "select-pane -R" bind -T copy-mode M-i if-shell "$is_emacs" "send-keys M-i" "select-pane -U" bind -T copy-mode M-k if-shell "$is_emacs" "send-keys M-k" "select-pane -D" bind -T copy-mode M-j if-shell "$is_emacs" "send-keys M-j" "select-pane -L" bind -T copy-mode M-l if-shell "$is_emacs" "send-keys M-l" "select-pane -R" bind -T copy-mode-vi M-i if-shell "$is_emacs" "send-keys M-i" "select-pane -U" bind -T copy-mode-vi M-k if-shell "$is_emacs" "send-keys M-k" "select-pane -D" bind -T copy-mode-vi M-j if-shell "$is_emacs" "send-keys M-j" "select-pane -L" bind -T copy-mode-vi M-l if-shell "$is_emacs" "send-keys M-l" "select-pane -R" --- modules/windows/siren-windmove.el | 39 +++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/modules/windows/siren-windmove.el b/modules/windows/siren-windmove.el index 4123bd7..ef35ab8 100644 --- a/modules/windows/siren-windmove.el +++ b/modules/windows/siren-windmove.el @@ -8,11 +8,40 @@ (use-package windmove :straight (:type built-in) - :config - (global-set-key (kbd "M-k") (siren-ignore-error-wrapper 'windmove-down)) - (global-set-key (kbd "M-i") (siren-ignore-error-wrapper 'windmove-up)) - (global-set-key (kbd "M-j") (siren-ignore-error-wrapper 'windmove-left)) - (global-set-key (kbd "M-l") (siren-ignore-error-wrapper 'windmove-right))) + + :bind + ("M-i" . siren-windmove-up) + ("M-k" . siren-windmove-down) + ("M-j" . siren-windmove-left) + ("M-l" . siren-windmove-right) + + :custom + (siren-windmove-tmux-fallback (if (getenv "TMUX") t nil)) + + :init + (defun siren-windmove-up () + (interactive) + (if (and (not (ignore-errors (windmove-up))) + siren-windmove-tmux-fallback) + (shell-command "tmux select-pane -U"))) + + (defun siren-windmove-down () + (interactive) + (if (and (not (ignore-errors (windmove-down))) + siren-windmove-tmux-fallback) + (shell-command "tmux select-pane -D"))) + + (defun siren-windmove-left () + (interactive) + (if (and (not (ignore-errors (windmove-left))) + siren-windmove-tmux-fallback) + (shell-command "tmux select-pane -L"))) + + (defun siren-windmove-right () + (interactive) + (if (and (not (ignore-errors (windmove-right))) + siren-windmove-tmux-fallback) + (shell-command "tmux select-pane -R")))) (provide 'siren-windmove) ;;; siren-windmove.el ends here