From: "Philip K." <philipk@posteo.net>
To: Juri Linkov <juri@linkov.net>
Cc: 41438@debbugs.gnu.org, larsi@gnus.org
Subject: bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
Date: Fri, 07 Aug 2020 12:53:10 +0200 [thread overview]
Message-ID: <87mu36enhl.fsf@posteo.net> (raw)
In-Reply-To: <87a6z78gqw.fsf@mail.linkov.net> (message from Juri Linkov on Fri, 07 Aug 2020 02:43:03 +0300)
[-- Attachment #1: Type: text/plain, Size: 2002 bytes --]
Juri Linkov <juri@linkov.net> writes:
>>> (I see there were some unfinished parts in your previous patch).
>>
>> It's been a while since I submitted it, so I had to re-read the thread,
>> but I'm not quite sure what the "unfinished" parts were, aside from the
>> missing autoload cookies. Sorry if I missed something :/
>
> I don't know, my impression seems to suggest the first version was not
> completely tested, for example, windmove-modifiers defcustom called
> windmove-swap-states-default-keybindings, not windmove-default-keybindings.
> But maybe you already fixed this.
You're right, I still had a few local changes. A noteworthy addition is
that the user options unbind their previous bindings, before binding the
new ones. This should lead to more consistent behaviour when updating
the option a few times in the same session.
>> Also, the second patch (the one with the user options) depended on the
>> previous one in this thread[0], that introduced the "none" prefix. Is
>> that fine, or should I just merge both patches into one.
>
> This is perfectly fine - better to commit two separate patches.
Ok. I added both below.
But there are a few general issues I noticed:
1. windmove-display-{same-window,new-{frame,tab}} can disturb regular
input when the modifier is set to shift or none. Possible solutions
could be to prohibit using these modifiers or to add a prefix key and
generate a warning when eg. "S-t" or "t" would be rebound.
2. The new function windmove--unbind works with the global-map, so when
someone sets a prefix to none, and then changes it to something else,
the arrow keys are left undefined. I could either see this being
fixed by using a separate map or by somehow memorising what the
previous key was (eg. by using the property list of the windmove
command's symbol).
These are the only edge-cases I found, but I didn't fix them yet, as I'm
not sure what would be preferred. So the patches should not be applies yet.
--
Philip K.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Allow-windmove-keys-to-be-bound-without-prefix-or-mo.patch --]
[-- Type: text/x-diff, Size: 3810 bytes --]
From f87d057b72f0cc374c132100664c5b8553bd58e2 Mon Sep 17 00:00:00 2001
From: Philip K <philip@warpmail.net>
Date: Thu, 21 May 2020 18:44:10 +0200
Subject: [PATCH] Allow windmove keys to be bound without prefix or modifiers
---
lisp/windmove.el | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/lisp/windmove.el b/lisp/windmove.el
index 6557960064..613727f8ed 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -431,9 +431,12 @@ windmove-default-keybindings
"Set up keybindings for `windmove'.
Keybindings are of the form MODIFIERS-{left,right,up,down},
where MODIFIERS is either a list of modifiers or a single modifier.
+If MODIFIERS is `none', the keybindings will be directly bound to
+the arrow keys.
Default value of MODIFIERS is `shift'."
(interactive)
(unless modifiers (setq modifiers 'shift))
+ (when (eq modifiers 'none) (setq modifiers nil))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector (append modifiers '(left))) 'windmove-left)
(global-set-key (vector (append modifiers '(right))) 'windmove-right)
@@ -546,9 +549,12 @@ windmove-display-default-keybindings
Keys are bound to commands that display the next buffer in the specified
direction. Keybindings are of the form MODIFIERS-{left,right,up,down},
where MODIFIERS is either a list of modifiers or a single modifier.
+If MODIFIERS is `none', the keybindings will be directly bound to
+the arrow keys.
Default value of MODIFIERS is `shift-meta'."
(interactive)
(unless modifiers (setq modifiers '(shift meta)))
+ (when (eq modifiers 'none) (setq modifiers nil))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector (append modifiers '(left))) 'windmove-display-left)
(global-set-key (vector (append modifiers '(right))) 'windmove-display-right)
@@ -618,11 +624,16 @@ windmove-delete-default-keybindings
Keys are bound to commands that delete windows in the specified
direction. Keybindings are of the form PREFIX MODIFIERS-{left,right,up,down},
where PREFIX is a prefix key and MODIFIERS is either a list of modifiers or
-a single modifier. Default value of PREFIX is `C-x' and MODIFIERS is `shift'."
+a single modifier.
+If PREFIX is `none', no prefix is used. If MODIFIERS is `none', the keybindings
+are directly bound to the arrow keys.
+Default value of PREFIX is `C-x' and MODIFIERS is `shift'."
(interactive)
(unless prefix (setq prefix '(?\C-x)))
+ (when (eq prefix 'none) (setq prefix nil))
(unless (listp prefix) (setq prefix (list prefix)))
(unless modifiers (setq modifiers '(shift)))
+ (when (eq modifiers 'none) (setq modifiers nil))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector prefix (append modifiers '(left))) 'windmove-delete-left)
(global-set-key (vector prefix (append modifiers '(right))) 'windmove-delete-right)
@@ -673,9 +684,13 @@ windmove-swap-states-default-keybindings
Keys are bound to commands that swap the states of the selected window
with the window in the specified direction. Keybindings are of the form
MODIFIERS-{left,right,up,down}, where MODIFIERS is either a list of modifiers
-or a single modifier. Default value of MODIFIERS is `shift-super'."
+or a single modifier.
+If MODIFIERS is `none', the keybindings will be directly bound to the
+arrow keys.
+Default value of MODIFIERS is `shift-super'."
(interactive)
(unless modifiers (setq modifiers '(shift super)))
+ (when (eq modifiers 'none) (setq modifiers nil))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector (append modifiers '(left))) 'windmove-swap-states-left)
(global-set-key (vector (append modifiers '(right))) 'windmove-swap-states-right)
--
2.20.1
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-Add-user-options-to-bind-windmove-commands.patch --]
[-- Type: text/x-diff, Size: 11235 bytes --]
From c009311887372e1e822739edc050a802bfa4d1d8 Mon Sep 17 00:00:00 2001
From: Philip K <philipk@posteo.net>
Date: Fri, 7 Aug 2020 12:35:49 +0200
Subject: [PATCH] Add user options to bind windmove commands
* windmove.el (windmove-modifier-type): Create
(windmove--unbind): New constant
(windmove-modifiers): New user option
(windmove-default-keybindings): Use windmove-modifiers
(windmove-display-modifiers): New user option
(windmove-display-default-keybindings): Use windmove-display-modifiers
(windmove-delete-prefix): New user option
(windmove-delete-modifiers): New user option
(windmove-delete-default-keybindings): Use windmove-delete-prefix and
windmove-delete-modifiers
(windmove-swap-states-modifiers): New user option
(windmove-swap-states-default-keybindings): Use windmove-swap-states-modifiers
---
lisp/windmove.el | 154 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 145 insertions(+), 9 deletions(-)
diff --git a/lisp/windmove.el b/lisp/windmove.el
index 613727f8ed..9b68f9a5b9 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -162,6 +162,40 @@ windmove-window-distance-delta
(make-obsolete-variable 'windmove-window-distance-delta
"no longer used." "27.1")
+(defconst windmove-modifier-type
+ '(choice (set :tag "Modifier Symbols"
+ :greedy t
+ ;; See `(elisp) Keyboard Events'
+ (const :tag "Meta" meta)
+ (const :tag "Control" control)
+ (const :tag "Shift" shift)
+ (const :tag "Hyper" hyper)
+ (const :tag "Super" super)
+ (const :tag "Alt" alt))
+ (const :tag "No modifier" none)
+ (const :tag "Not bound" nil))
+ "Customisation type for windmove modifiers")
+
+(defun windmove--unbind (prefix modifiers fns &optional extra)
+ "Unbind windmove commands, bound by PREFIX and MODIFIER.
+To ensure that only windmove functions are unbound, the command
+must be member of the list FNS.
+By default only the left, right, up and down keys are unbound,
+but further keys can be added via EXTRA."
+ (setq prefix
+ (cond ((eq prefix 'none) nil)
+ ((not (listp prefix)) (list prefix))
+ (t prefix)))
+ (setq modifiers
+ (cond ((eq modifiers 'none) nil)
+ ((not (listp modifiers)) (list modifiers))
+ (t modifiers)))
+ (dolist (dir (append '(left right up down) extra))
+ (let* ((key (append modifiers (list dir)))
+ (key (vconcat prefix (list key))))
+ (when (memq (lookup-key global-map key) fns)
+ (global-set-key key nil)))))
+
\f
;; Note:
;;
@@ -419,6 +453,7 @@ windmove-down
(interactive "P")
(windmove-do-window-select 'down (and arg (prefix-numeric-value arg))))
+(defvar windmove-modifiers)
;;; set up keybindings
;; Idea for this function is from iswitchb.el, by Stephen Eglen
@@ -433,16 +468,41 @@ windmove-default-keybindings
where MODIFIERS is either a list of modifiers or a single modifier.
If MODIFIERS is `none', the keybindings will be directly bound to
the arrow keys.
-Default value of MODIFIERS is `shift'."
+Default value of MODIFIERS is stored in `windmove-modifiers'."
(interactive)
- (unless modifiers (setq modifiers 'shift))
(when (eq modifiers 'none) (setq modifiers nil))
+ (unless modifiers
+ (setq modifiers windmove-modifiers))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector (append modifiers '(left))) 'windmove-left)
(global-set-key (vector (append modifiers '(right))) 'windmove-right)
(global-set-key (vector (append modifiers '(up))) 'windmove-up)
(global-set-key (vector (append modifiers '(down))) 'windmove-down))
+;; has to be declared AFTER windmove-default-keybindings, or else
+;; windmove is recursivly loaded
+;;;###autoload
+(defcustom windmove-modifiers '(shift super)
+ "Modifiers for `windmove-default-keybindings'.
+Can either be a symbol or list of modifier symbols,
+i.e. `meta',`control', `shift', `hyper', `super', or `alt'
+representing modifier keys to use with the arrow keys.
+
+If the value is just `none', the arrow keys will be directly
+bound to the windmove functions."
+ :type windmove-modifier-type
+ :require 'windmove
+ :initialize #'custom-initialize-changed
+ :set (lambda (sym val)
+ (windmove--unbind nil (default-value sym)
+ '(windmove-left
+ windmove-right
+ windmove-up
+ windmove-down))
+ (when val
+ (windmove-default-keybindings val))
+ (set-default sym val)))
+
\f
;;; Directional window display and selection
@@ -543,6 +603,8 @@ windmove-display-new-tab
(interactive "P")
(windmove-display-in-direction 'new-tab arg))
+(defvar windmove-display-modifiers)
+
;;;###autoload
(defun windmove-display-default-keybindings (&optional modifiers)
"Set up keybindings for directional buffer display.
@@ -551,9 +613,10 @@ windmove-display-default-keybindings
where MODIFIERS is either a list of modifiers or a single modifier.
If MODIFIERS is `none', the keybindings will be directly bound to
the arrow keys.
-Default value of MODIFIERS is `shift-meta'."
+Default value of MODIFIERS is stored in `windmove-display-modifiers'."
(interactive)
- (unless modifiers (setq modifiers '(shift meta)))
+ (unless modifiers
+ (setq modifiers windmove-display-modifiers))
(when (eq modifiers 'none) (setq modifiers nil))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector (append modifiers '(left))) 'windmove-display-left)
@@ -564,6 +627,27 @@ windmove-display-default-keybindings
(global-set-key (vector (append modifiers '(?f))) 'windmove-display-new-frame)
(global-set-key (vector (append modifiers '(?t))) 'windmove-display-new-tab))
+;;;###autoload
+(defcustom windmove-display-modifiers '(shift meta)
+ "Modifiers for `windmove-display-default-keybindings'.
+Analogous to `windmove-modifiers'."
+ :type windmove-modifier-type
+ :require 'windmove
+ :initialize #'custom-initialize-changed
+ :set (lambda (sym val)
+ (windmove--unbind nil (default-value sym)
+ '(windmove-display-left
+ windmove-display-right
+ windmove-display-up
+ windmove-display-down
+ windmove-display-same-window
+ windmove-display-new-frame
+ windmove-display-new-tab)
+ '(?0 ?f ?t))
+ (when val
+ (windmove-display-default-keybindings val))
+ (set-default sym val)))
+
\f
;;; Directional window deletion
@@ -618,6 +702,9 @@ windmove-delete-down
(interactive "P")
(windmove-delete-in-direction 'down arg))
+(defvar windmove-delete-prefix)
+(defvar windmove-delete-modifiers)
+
;;;###autoload
(defun windmove-delete-default-keybindings (&optional prefix modifiers)
"Set up keybindings for directional window deletion.
@@ -627,12 +714,15 @@ windmove-delete-default-keybindings
a single modifier.
If PREFIX is `none', no prefix is used. If MODIFIERS is `none', the keybindings
are directly bound to the arrow keys.
-Default value of PREFIX is `C-x' and MODIFIERS is `shift'."
+The default values for PREFIX and MODIFIERS are stored in `windmove-delete-prefix'
+and `windmove-delete-modifiers' respectively."
(interactive)
- (unless prefix (setq prefix '(?\C-x)))
+ (unless prefix
+ (setq prefix (list windmove-delete-prefix)))
(when (eq prefix 'none) (setq prefix nil))
(unless (listp prefix) (setq prefix (list prefix)))
- (unless modifiers (setq modifiers '(shift)))
+ (unless modifiers
+ (setq modifiers windmove-delete-modifiers))
(when (eq modifiers 'none) (setq modifiers nil))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector prefix (append modifiers '(left))) 'windmove-delete-left)
@@ -640,6 +730,32 @@ windmove-delete-default-keybindings
(global-set-key (vector prefix (append modifiers '(up))) 'windmove-delete-up)
(global-set-key (vector prefix (append modifiers '(down))) 'windmove-delete-down))
+(defcustom windmove-delete-prefix (kbd "C-x")
+ "Prefix for `windmove-delete-default-keybindings'."
+ :type 'key-sequence
+ :require 'windmove
+ :initialize #'custom-initialize-changed)
+
+;;;###autoload
+(defcustom windmove-delete-modifiers '(shift)
+ "Modifiers for `windmove-delete-default-keybindings'.
+See `windmove-modifiers' for more details"
+ :type windmove-modifier-type
+ :require 'windmove
+ :initialize #'custom-initialize-changed
+ :set-after '(windmove-delete-prefix)
+ :set (lambda (sym val)
+ (windmove--unbind windmove-delete-prefix
+ (default-value sym)
+ '(windmove-delete-left
+ windmove-delete-right
+ windmove-delete-up
+ windmove-delete-down))
+ (when val
+ (windmove-delete-default-keybindings
+ windmove-delete-prefix val))
+ (set-default sym val)))
+
\f
;;; Directional window swap states
@@ -678,6 +794,8 @@ windmove-swap-states-right
(interactive)
(windmove-swap-states-in-direction 'right))
+(defvar windmove-swap-states-modifiers)
+
;;;###autoload
(defun windmove-swap-states-default-keybindings (&optional modifiers)
"Set up keybindings for directional window swap states.
@@ -687,9 +805,10 @@ windmove-swap-states-default-keybindings
or a single modifier.
If MODIFIERS is `none', the keybindings will be directly bound to the
arrow keys.
-Default value of MODIFIERS is `shift-super'."
+Default value of MODIFIERS is stored in `windmove-swap-states-modifiers'."
(interactive)
- (unless modifiers (setq modifiers '(shift super)))
+ (unless modifiers
+ (setq modifiers windmove-swap-states-modifiers))
(when (eq modifiers 'none) (setq modifiers nil))
(unless (listp modifiers) (setq modifiers (list modifiers)))
(global-set-key (vector (append modifiers '(left))) 'windmove-swap-states-left)
@@ -697,6 +816,23 @@ windmove-swap-states-default-keybindings
(global-set-key (vector (append modifiers '(up))) 'windmove-swap-states-up)
(global-set-key (vector (append modifiers '(down))) 'windmove-swap-states-down))
+;;;###autoload
+(defcustom windmove-swap-states-modifiers '(shift super)
+ "Modifiers for `windmove-swap-states-default-keybindings'.
+Analogous to `windmove-modifiers'."
+ :type windmove-modifier-type
+ :require 'windmove
+ :initialize #'custom-initialize-changed
+ :set (lambda (sym val)
+ (windmove--unbind nil (default-value sym)
+ '(windmove-swap-states-left
+ windmove-swap-states-right
+ windmove-swap-states-up
+ windmove-swap-states-downp))
+ (when val
+ (windmove-swap-states-default-keybindings val))
+ (set-default sym val)))
+
\f
(provide 'windmove)
--
2.20.1
next prev parent reply other threads:[~2020-08-07 10:53 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-21 16:56 bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers Philip K.
2020-05-21 22:18 ` Juri Linkov
2020-05-22 18:26 ` Philip K.
[not found] ` <(message>
[not found] ` <from>
[not found] ` <Juri>
[not found] ` <Linkov>
[not found] ` <on>
[not found] ` <Fri>
[not found] ` <22>
[not found] ` <May>
[not found] ` <2020>
[not found] ` <04:01:05>
[not found] ` <01:18:18>
[not found] ` <+0300)>
[not found] ` <87v9kn7rnk.fsf@bulbul>
2020-05-22 19:15 ` Drew Adams
2020-05-23 22:12 ` Juri Linkov
2020-06-26 19:46 ` Philip K.
2020-06-27 23:53 ` Juri Linkov
2020-06-28 8:30 ` Philip K.
2020-06-28 23:37 ` Juri Linkov
2020-08-05 18:05 ` Lars Ingebrigtsen
2020-08-05 23:40 ` Juri Linkov
2020-08-06 9:28 ` Philip K.
2020-08-06 23:43 ` Juri Linkov
2020-08-07 10:53 ` Philip K. [this message]
2020-08-08 23:54 ` Juri Linkov
2021-05-12 20:38 ` Lars Ingebrigtsen
2021-05-12 21:27 ` Philip Kaludercic
2021-05-22 20:29 ` Philip Kaludercic
2021-05-22 21:09 ` Philip Kaludercic
2021-05-23 6:49 ` Eli Zaretskii
2021-05-23 12:36 ` Philip Kaludercic
2021-05-25 5:12 ` Lars Ingebrigtsen
2021-05-25 7:25 ` Philip Kaludercic
2021-05-25 9:53 ` Philip Kaludercic
2021-05-25 11:16 ` Arthur Miller
2021-05-25 11:42 ` Philip Kaludercic
2021-05-25 13:31 ` Arthur Miller
2021-05-25 14:39 ` Philip Kaludercic
2021-05-25 11:36 ` Arthur Miller
2021-05-25 11:46 ` Philip Kaludercic
2021-05-25 13:58 ` Arthur Miller
2021-05-25 19:13 ` Lars Ingebrigtsen
2021-05-25 19:16 ` Lars Ingebrigtsen
2021-05-25 19:25 ` Philip Kaludercic
2021-05-25 20:18 ` Juri Linkov
2021-05-25 21:45 ` Philip Kaludercic
2021-05-26 21:35 ` Juri Linkov
2021-05-27 11:09 ` Philip Kaludercic
2021-05-30 22:11 ` Juri Linkov
2021-05-31 8:50 ` Philip Kaludercic
2021-05-31 20:15 ` Juri Linkov
2021-05-31 21:27 ` Philip Kaludercic
2021-06-03 20:36 ` Juri Linkov
-- strict thread matches above, loose matches on Subject: below --
2020-07-30 4:01 bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work Brett Randall
[not found] ` <handler.42611.B.159608273314264.ack@debbugs.gnu.org>
[not found] ` <(Brett>
2020-10-17 8:41 ` Lars Ingebrigtsen
2020-10-27 10:36 ` brett.randall
[not found] ` <(brett>
[not found] ` <randall's>
[not found] ` <"Tue,>
[not found] ` <27>
[not found] ` <Oct>
2020-10-27 10:43 ` Lars Ingebrigtsen
2020-10-27 10:49 ` Brett Randall
2020-10-27 11:08 ` Lars Ingebrigtsen
[not found] ` <(Lars>
[not found] ` <Ingebrigtsen's>
[not found] ` <12:08:50>
2020-10-27 11:19 ` bug#42611: (no subject) Lars Ingebrigtsen
[not found] ` <877drbhq6c.fsf@gnus.org>
[not found] ` <handler.42611.C.160379757411378.notifdonectrl.0@debbugs.gnu.org>
2020-10-27 22:22 ` bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work Brett Randall
2019-04-21 19:30 bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files' Drew Adams
2019-07-09 14:21 ` Lars Ingebrigtsen
2019-07-11 5:51 ` Mike Kupfer
2019-07-11 14:04 ` Lars Ingebrigtsen
2019-07-11 14:18 ` Drew Adams
2019-07-12 3:20 ` Mike Kupfer
2019-07-12 3:33 ` Drew Adams
2022-01-22 14:43 ` Lars Ingebrigtsen
[not found] <Your>
[not found] ` <message>
[not found] ` <of>
[not found] ` <"Thu>
[not found] ` <"Thu,>
[not found] ` <"Tue>
[not found] ` <09>
[not found] ` <Jul>
[not found] ` <2019>
[not found] ` <07:18:26>
[not found] ` <16:21:24>
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87mu36enhl.fsf@posteo.net \
--to=philipk@posteo.net \
--cc=41438@debbugs.gnu.org \
--cc=juri@linkov.net \
--cc=larsi@gnus.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).