summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2022-11-05 13:03:44 -0700
committerSean Whitton <spwhitton@spwhitton.name>2022-11-06 10:50:31 -0700
commit466642c0ff3999cbc8b51431c97a74a5ebef6cb7 (patch)
tree6964a5d5139c51b4d7ac235470743049017249b1
parent2a0a63ab4a6bab8523e5e37bf7e66b3eeafb0e0d (diff)
downloaddotfiles-466642c0ff3999cbc8b51431c97a74a5ebef6cb7.tar.gz
rework some of my cycling bindings inc. introduce use of windmove
-rw-r--r--.config/i3/config12
-rw-r--r--.config/sway/config12
-rw-r--r--.emacs.d/init.el132
3 files changed, 98 insertions, 58 deletions
diff --git a/.config/i3/config b/.config/i3/config
index e4b6fae5..786700d5 100644
--- a/.config/i3/config
+++ b/.config/i3/config
@@ -262,9 +262,9 @@ bindsym Mod1+Ctrl+i kill
bindsym Ctrl+minus layout toggle split
# Cycle through all workspaces on monitor.
-bindsym Ctrl+3 workspace prev_on_output
+bindsym Ctrl+1 workspace prev_on_output
bindsym Ctrl+4 workspace next_on_output
-bindsym Mod1+Ctrl+3 move container to workspace prev_on_output, \
+bindsym Mod1+Ctrl+1 move container to workspace prev_on_output, \
workspace prev_on_output
bindsym Mod1+Ctrl+4 move container to workspace next_on_output, \
workspace next_on_output
@@ -283,10 +283,10 @@ bindsym Mod1+Ctrl+4 move container to workspace next_on_output, \
# bindsym Mod4+Ctrl+Mod2+KP_Right move workspace to output right
# bindsym Mod4+Ctrl+KP_6 move workspace to output right
-bindsym Ctrl+1 focus output left
-bindsym Mod1+Ctrl+1 move workspace to output left
-bindsym Ctrl+2 focus output right
-bindsym Mod1+Ctrl+2 move workspace to output right
+bindsym Ctrl+2 focus output left
+bindsym Mod1+Ctrl+2 move workspace to output left
+bindsym Ctrl+3 focus output right
+bindsym Mod1+Ctrl+3 move workspace to output right
# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
diff --git a/.config/sway/config b/.config/sway/config
index 9b8e7e21..66ed4f3f 100644
--- a/.config/sway/config
+++ b/.config/sway/config
@@ -282,19 +282,19 @@ bindsym Ctrl+minus layout toggle split
# Warp the cursor to a point on the screen which is hopefully a titlebar.
# This means that cycling through workspaces does not abruptly stop because,
# e.g., a VNC client has grabbed the keyboard upon entry to the workspace.
-bindsym Ctrl+3 seat - cursor set 0 0, workspace prev_on_output
+bindsym Ctrl+1 seat - cursor set 0 0, workspace prev_on_output
bindsym Ctrl+4 seat - cursor set 0 0, workspace next_on_output
-bindsym Mod1+Ctrl+3 seat - cursor set 0 0, \
+bindsym Mod1+Ctrl+1 seat - cursor set 0 0, \
move container to workspace prev_on_output, \
workspace prev_on_output
bindsym Mod1+Ctrl+4 seat - cursor set 0 0, \
move container to workspace next_on_output, \
workspace next_on_output
-bindsym Ctrl+1 focus output left
-bindsym Mod1+Ctrl+1 move workspace to output left
-bindsym Ctrl+2 focus output right
-bindsym Mod1+Ctrl+2 move workspace to output right
+bindsym Ctrl+2 focus output left
+bindsym Mod1+Ctrl+2 move workspace to output left
+bindsym Ctrl+3 focus output right
+bindsym Mod1+Ctrl+3 move workspace to output right
# Start swaybar to display a workspace bar (plus the system information
# i3status finds out, if available)
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index c195f234..d9f22481 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -400,6 +400,8 @@ windows side-by-side in the frame."
'(tramp-verbose 1 nil nil "Manual says this should improve performance.")
'(transient-cycles-buffer-siblings-mode t)
'(transient-cycles-tab-bar-mode t)
+ '(transient-cycles-window-buffers-cycle-backwards-key [?\M-1])
+ '(transient-cycles-window-buffers-cycle-forwards-key [?\M-4])
'(transient-cycles-window-buffers-mode t)
'(transient-mark-mode nil)
'(uniquify-buffer-name-style 'post-forward nil (uniquify))
@@ -783,28 +785,28 @@ to open them using `spw/try-external-open'")
;;;; General editing
+(define-minor-mode spw/personal-bindings-mode
+ "A simple way to overcome problems overriding major mode bindings.
+To be used only when it seems to be necessary."
+ :init-value t :lighter nil :keymap (make-sparse-keymap) :global t)
+
;; Bind a key simply to (re-)activate the mark which does not
;; involve moving point, as `exchange-point-and-mark' does. This is
;; useful if you use isearch to select a region but realise only after
;; you've left the intended start of the region that you need to do a
-;; second isearch to extend it far enough: e.g. C-s first M-i C-s second RET
+;; second isearch to extend it far enough: e.g. C-s first M-6 C-s second RET
;;
;; Activating the region prevents the second isearch from resetting
;; the mark. Having this binding removes the need to activate the
;; region before entering the first isearch, which is useful both with
;; and without `transient-mark-mode'.
;;
-;; This makes M-i a sort of prefix command: "execute the next command in
+;; This makes M-6 a sort of prefix command: "execute the next command in
;; temporary Transient Mark mode / as if Transient Mark mode were turned on"
(defun spw/activate-mark (&rest _ignore)
(interactive)
(activate-mark))
-(global-set-key "\M-i" #'spw/activate-mark)
-
-;; resettle the previous occupants of M-i
-(global-set-key "\M-I" #'tab-to-tab-stop)
-(spw/feature-define-keys ((gnus-sum gnus-summary-mode-map))
- "\M-i" nil "\M-I" gnus-symbolic-argument)
+(define-key spw/personal-bindings-mode-map "\M-6" #'spw/activate-mark)
;; Regarding `set-mark-command-repeat-pop': if this is set to t, then
;; re-setting the mark right after popping to it -- to go and edit somewhere
@@ -936,7 +938,8 @@ to open them using `spw/try-external-open'")
(let (case-fold-search)
(apply #',cmd ,args))))))
(global-set-key [remap zap-to-char] (case-sensitively zap-to-char))
- (define-key spw/ctl-z-map "z" (case-sensitively zap-up-to-char)))
+ (define-key spw/personal-bindings-mode-map
+ "\M-5" (case-sensitively zap-up-to-char)))
(global-set-key [remap dabbrev-expand] #'hippie-expand)
@@ -959,9 +962,17 @@ to open them using `spw/try-external-open'")
(revert-buffer (not current-prefix-arg) t)))
;; These don't work in text terminals, so unbind to avoid developing any
-;; habits of using them. In recent Emacs you can release the meta key after
-;; typing the first digit or minus sign of a numeric argument, rendering these
-;; other bindings less useful anyway.
+;; habits of using them. Further, if the goal is to avoid having to release
+;; modifier keys between typing numeric prefix arguments and commands, then in
+;; most cases this will mean one-handed chording, which should be avoided. If
+;; the goal is instead to reduce the total number of keypresses, then it
+;; should be sufficient to use only the M- bindings, releasing the meta key
+;; after typing the first digit or minus sign. But that's a minor benefit
+;; over just starting with C-u. Indeed, I rebind M-0..9 for other purposes.
+;;
+;; (M-- remains bound to `negative-argument' because it's particularly useful
+;; for 'M-- M-l' and 'M-- M-u'. So, C-u and M-- are the two keys I use to
+;; supply non-negative and negative numeric prefix arguments, respectively.)
(cl-loop for i from ?0 to ?9
for key = (read (format "[?\\C-%c]" i))
do (global-unset-key key) (define-key esc-map key nil))
@@ -1035,7 +1046,7 @@ to open them using `spw/try-external-open'")
(diminish 'eldoc-mode)
;; Invert meaning of C-u for M-= except when the region is active (though,
-;; M-i M-= is easier to type than C-u M-=).
+;; M-6 M-= is easier to type than C-u M-=).
(defun spw/count-words ()
(interactive)
(if (or (use-region-p) (not current-prefix-arg))
@@ -1208,7 +1219,8 @@ Permits globally re-binding the four arrow keys without rendering
it impossible to access mode-specific bindings for those four
keys (e.g. the use of the left and right arrow keys in
`fido-mode' minibuffers)."
- :init-value t :lighter nil :keymap spw/arrow-keys-mode-map :global t)
+ ;; :init-value t
+ :lighter nil :keymap spw/arrow-keys-mode-map :global t)
(defun spw/arrow-keys-mode-passthru ()
(interactive)
@@ -1243,21 +1255,13 @@ don't consider windows satisfying the predicate EXCLUDE."
(interactive "P")
(if arg
;; if there's a prefix arg then just `other-window', so that's still
- ;; available on M-1 C-x o
+ ;; available on C-u 1 C-x o
(call-interactively #'other-window)
(if-let ((window (spw/get-mru-window)))
(select-window window)
(user-error "No other window to select"))))
(global-set-key [remap other-window] #'spw/back-and-forth)
-(defun spw/other-window-noselect (count &optional interactive)
- (interactive "p\np")
- (cl-flet ((old-select-window (symbol-function 'select-window)))
- (cl-letf (((symbol-function 'select-window)
- (lambda (window &rest _ignore)
- (old-select-window window 'mark-for-redisplay))))
- (other-window count nil interactive))))
-
;;; Initial motivation for `transient-cycles' work is that we want all these
;;; commands to be easily repeatable but without setting a transient map which
;;; binds self-insert chars, as might want to type those just after switching.
@@ -1268,21 +1272,57 @@ don't consider windows satisfying the predicate EXCLUDE."
;;; sequences which already belong to other keys, one idea is to add
;;; C-c/C-z {h,j,k,l} to `input-decode-map' for the arrow keys (or bind them
;;; to commands setting `unread-command-events'), without any transient maps.
-
-;; C-x o is easier to type than these, but these are wanted for tapping
-;; repeatedly when there are more than two windows. We could allow left/right
-;; to have their normal bindings when there is only one window.
-(transient-cycles-define-commands ()
- ;; Don't select the windows we cycle through, so that the window where we
- ;; started becomes the most recently selected window.
- (([right] . spw/other-window-noselect)
- (([left] . spw/backward-other-window-noselect)
- (count &optional interactive)
- (interactive "p\np")
- (spw/other-window-noselect (* -1 count) interactive)))
- (lambda (_ignore) #'spw/other-window-noselect)
- ;; Select the destination window again with NOSELECT nil.
- :on-exit (select-window (selected-window)) :keymap spw/arrow-keys-mode-map)
+;;;
+;;; Previously we used <left>/<right> for custom next- and previous-window
+;;; commands with transient cycling, and didn't use any windmove commands.
+;;; However, because <left>/<right> are my default transient cycling keys,
+;;; this led to situations where I tried to use <left>/<right> to switch
+;;; window and found myself continuing transient cycling for the previous
+;;; command instead. So, should probably avoid putting anything on unmodified
+;;; <left>/<right>. We could still put something on unmodified <down>/<up>,
+;;; which I used to use for `tab-bar-history-mode' forward & back commands.
+;;; (`spw/arrow-keys-mode' made it feasible to bind things to unmodified arrow
+;;; keys in the global map. That's disabled at present, as the unmodified
+;;; arrow keys are not in use.)
+;;;
+;;; We might put one of the other sets of windmove commands, such as
+;;; windmove-swap-states-* commands, on C-z M-7/8/9/0, or possibly
+;;; C-c w M-7/8/9/0. C-c <left>/<right> are also available, as they tacitly
+;;; belong to `winner-mode' / `tab-bar-history-mode'.
+
+(defvar spw/windmove-transient-map (make-sparse-keymap))
+
+(cl-macrolet
+ ((add-direction (key direction)
+ (let* ((init (intern (format "spw/windmove-%s" direction)))
+ (noselect
+ (intern
+ (format "spw/windmove-%s-noselect" direction)))
+ (noselect-body
+ `(cl-flet ((old-s-w (symbol-function 'select-window)))
+ (cl-letf (((symbol-function 'select-window)
+ (lambda (window &rest _ignore)
+ (old-s-w window 'mark-for-redisplay))))
+ (call-interactively
+ #',(intern (format "windmove-%s" direction)))))))
+ `(progn (defun ,noselect () (interactive) ,noselect-body)
+ (define-key spw/windmove-transient-map ,key #',noselect)
+ (defun ,init ()
+ (interactive)
+ ;; Don't select the windows we move through, so that the
+ ;; window where we started becomes the most recently
+ ;; selected window. Then in the ON-EXIT function, select
+ ;; the destination window again with the NOSELECT argument
+ ;; to `select-window' nil.
+ ,noselect-body
+ (set-transient-map spw/windmove-transient-map t
+ (lambda ()
+ (select-window (selected-window)))))
+ (global-set-key ,key #',init)))))
+ (add-direction "\M-7" "left")
+ (add-direction "\M-8" "down")
+ (add-direction "\M-9" "up")
+ (add-direction "\M-0" "right"))
;; We might resettle `pop-global-mark' to C-z C-SPC.
(define-key ctl-x-map "\C-@" #'transient-cycles-window-buffers-back-and-forth)
@@ -1296,19 +1336,19 @@ don't consider windows satisfying the predicate EXCLUDE."
;; `winner-mode', `tab-bar-history-mode' does not restore just one value for
;; point for all of the windows in the configuration showing a single buffer.
(transient-cycles-define-commands ()
- (([up] . tab-bar-history-back)
- ([down] . tab-bar-history-forward))
+ (("\M-3" . tab-bar-history-back)
+ ("\M-2" . tab-bar-history-forward))
(lambda (_ignore)
(lambda (count)
(interactive "p")
(if (> count 0) (tab-bar-history-forward) (tab-bar-history-back))))
- :keymap spw/arrow-keys-mode-map
- :cycle-backwards-key [up] :cycle-forwards-key [down])
+ :cycle-backwards-key "\M-3" :cycle-forwards-key "\M-2")
+
+(define-key transient-cycles-window-buffers-mode-map "\M-1" #'previous-buffer)
+(define-key transient-cycles-window-buffers-mode-map "\M-4" #'next-buffer)
;; Start transient cycling among the current buffer's siblings.
;; Can be usefully prefixed with C-x 4 4 etc. to start cycling elsewhere.
-(spw/reclaim-keys-from
- tab-bar tab-bar-history-mode-map [?\C-c left] [?\C-c right])
(defun spw/cycle-from-here ()
(interactive)
(push last-command-event unread-command-events)
@@ -1317,8 +1357,8 @@ don't consider windows satisfying the predicate EXCLUDE."
;; window's previous buffers.
(pop-to-buffer-same-window (current-buffer))))
(spw/transient-cycles-define-buffer-switch
- (([?\C-c left] . spw/cycle-from-here)
- ([?\C-c right] . spw/cycle-from-here)))
+ (([?\C-x left] . spw/cycle-from-here)
+ ([?\C-x right] . spw/cycle-from-here)))
(setq display-buffer-alist
`(;; This is meant to say: for these buffers which, unusually, do not