unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
@ 2019-04-21 19:30 Drew Adams
  2019-07-09 14:21 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 59+ messages in thread
From: Drew Adams @ 2019-04-21 19:30 UTC (permalink / raw)
  To: 35367

1. I believe `dired-copy-how-to-fn' was added to Emacs quite a while ago
   (1991[1]).  But it's not clear to me what it's really for, and there
   seem to be no uses of it in the distributed Emacs code, apart from
   `dired-do-copy', which just passes it on to `dired-create-files'.
   The variable's doc just says to "See HOW-TO argument for
   `dired-create-files'."

   So why was this variable created?

2. Apart from the variable, why was the HOW-TO arg of
   `dired-do-create-files' added?  I find no uses of it, apart from
   `dired-do-copy' (which just passes it along).

   Presumably someone thought that someone might want to pass such a
   thing to `dired-do-copy', but why?

   Half the doc of `dired-do-create-files' is for this parameter.  And
   its description, although probably correct and complete, reads like
   gobbledygook, to me.

   For one thing, the nil case should not be described under this
   parameter; it should be described as the function's default behavior,
   up above the parameter list.  (That's already 4 lines of its
   description.)

   Beyond that:

   * A value of `t' is unclear to me.  What does it mean to target a
     plain file - is this the same as using a `nil' value?  What happens
     with `t' if the target is a directory or if there are multiple
     marked files?  Is that where the difference lies somehow (how)?

   * A unary function value is the most confusing.  I can't follow it,
     I'm afraid.

   If HOW-TO is to stay (and I assume it is) then we really need some
   kind of motivating explanation - perhaps an example of why/when/how
   you would use a function here.  With no existing examples in the code
   this seems a bit
   maybe-someone-someday-might-need-this-thing-that-somebody-dreamed.

   It was apparently RMS who added this [1].  I'm surprised that it's
   not more clear what good it is.

[1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25075#20


In GNU Emacs 26.2 (build 1, x86_64-w64-mingw32)
 of 2019-04-13
Repository revision: fd1b34bfba8f3f6298df47c8e10b61530426f749
Windowing system distributor `Microsoft Corp.', version 10.0.17134
Configured using:
 `configure --without-dbus --host=x86_64-w64-mingw32
 --without-compress-install 'CFLAGS=-O2 -static -g3''





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
  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
  0 siblings, 1 reply; 59+ messages in thread
From: Lars Ingebrigtsen @ 2019-07-09 14:21 UTC (permalink / raw)
  To: Drew Adams; +Cc: 35367

Drew Adams <drew.adams@oracle.com> writes:

> 1. I believe `dired-copy-how-to-fn' was added to Emacs quite a while ago
>    (1991[1]).  But it's not clear to me what it's really for, and there
>    seem to be no uses of it in the distributed Emacs code, apart from
>    `dired-do-copy', which just passes it on to `dired-create-files'.
>    The variable's doc just says to "See HOW-TO argument for
>    `dired-create-files'."
>
>    So why was this variable created?

I hoped that the code might throw some light on this variable, but:

(defun dired-into-dir-with-symlinks (target)
  (and (file-directory-p target)
       (not (file-symlink-p target))))
;; This may not always be what you want, especially if target is your
;; home directory and it happens to be a symbolic link, as is often the
;; case with NFS and automounters.  Or if you want to make symlinks
;; into directories that themselves are only symlinks, also quite
;; common.

;; So we don't use this function as value for HOW-TO in
;; dired-do-symlink, which has the minor disadvantage of
;; making links *into* a symlinked-dir, when you really wanted to
;; *overwrite* that symlink.  In that (rare, I guess) case, you'll
;; just have to remove that symlink by hand before making your marked
;; symlinks.

(defvar dired-copy-how-to-fn nil
  "Either nil or a function used by `dired-do-copy' to determine target.
See HOW-TO argument for `dired-do-create-files'.")

It's still clear as mud to me.

> 2. Apart from the variable, why was the HOW-TO arg of
>    `dired-do-create-files' added?  I find no uses of it, apart from
>    `dired-do-copy' (which just passes it along).
>
>    Presumably someone thought that someone might want to pass such a
>    thing to `dired-do-copy', but why?
>
>    Half the doc of `dired-do-create-files' is for this parameter.  And
>    its description, although probably correct and complete, reads like
>    gobbledygook, to me.
>
>    For one thing, the nil case should not be described under this
>    parameter; it should be described as the function's default behavior,
>    up above the parameter list.  (That's already 4 lines of its
>    description.)

Well...  I think it makes sense (in so far as this parameter makes any
sense) to keep it where it is:

Optional arg HOW-TO determines how to treat the target.
  If HOW-TO is nil, use `file-directory-p' to determine if the
   target is a directory.  If so, the marked file(s) are created
   inside that directory.  Otherwise, the target is a plain file;
   an error is raised unless there is exactly one marked file.
  If HOW-TO is t, target is always treated as a plain file.
  Otherwise, HOW-TO should be a function of one argument, TARGET.
   If its return value is nil, TARGET is regarded as a plain file.
   If it return value is a list, TARGET is a generalized
    directory (e.g. some sort of archive).  The first element of
    this list must be a function with at least four arguments:
      operation - as OPERATION above.
      rfn-list  - list of the relative names for the marked files.
      fn-list   - list of the absolute names for the marked files.
      target    - the name of the target itself.
    The rest of elements of the list returned by HOW-TO are optional
    arguments for the function that is the first element of the list.
   For any other return value, TARGET is treated as a directory."


>    Beyond that:
>
>    * A value of `t' is unclear to me.  What does it mean to target a
>      plain file - is this the same as using a `nil' value?  What happens
>      with `t' if the target is a directory or if there are multiple
>      marked files?  Is that where the difference lies somehow (how)?

My interpretation of t is that all files you copy will up in the same
file if it's t, which is a supremely useless thing, you'd think...

>    It was apparently RMS who added this [1].  I'm surprised that it's
>    not more clear what good it is.

Does anybody know what this parameter and variable was meant to do, and
whether it's used anywhere out-of-tree?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
  2019-07-09 14:21 ` Lars Ingebrigtsen
@ 2019-07-11  5:51   ` Mike Kupfer
  2019-07-11 14:04     ` Lars Ingebrigtsen
                       ` (2 more replies)
  0 siblings, 3 replies; 59+ messages in thread
From: Mike Kupfer @ 2019-07-11  5:51 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 35367

Lars Ingebrigtsen wrote:

> Drew Adams <drew.adams@oracle.com> writes:
> 
> > 1. I believe `dired-copy-how-to-fn' was added to Emacs quite a while ago
> >    (1991[1]).

lisp/ChangeLog.8 in the 25.3 tarball attributes the change to Inge
Frick, with a date of 1999-09-14 (a couple days before the date listed
in bug#25075).

> > But it's not clear to me what it's really for, and there
> >    seem to be no uses of it in the distributed Emacs code, apart from
> >    `dired-do-copy', which just passes it on to `dired-create-files'.
> >    The variable's doc just says to "See HOW-TO argument for
> >    `dired-create-files'."
> >
> >    So why was this variable created?

Presumably it's so you could override dired's behavior for handling a
target.  If the target is a symlink to a directory, the default behavior
would be to treat it as a directory, but maybe there are cases where you
want to replace the link instead.

The bit about

   If it return value is a list, TARGET is a generalized
    directory (e.g. some sort of archive).  The first element of
    this list must be a function with at least four arguments:

looks like it might be useful when the target is, for example, a tar
file.  By default, copying a single file would replace the tar file.
But this could be overridden (I think) to add or replace entries in the
tar file.

Besides the possibility of a user setting dired-copy-how-to-fn, I can
imagine a package might want to dynamically rebind dired-copy-how-to-fn,
perhaps as a buffer-local variable in a dired buffer.  (I'm not sure
what sort of package might want to do that, but it seems like a possible
reason for having a variable.)

> I hoped that the code might throw some light on this variable, but:
> 
> (defun dired-into-dir-with-symlinks (target)
>   (and (file-directory-p target)
>        (not (file-symlink-p target))))
> ;; This may not always be what you want, especially if target is your
> ;; home directory and it happens to be a symbolic link, as is often the
> ;; case with NFS and automounters.  Or if you want to make symlinks
> ;; into directories that themselves are only symlinks, also quite
> ;; common.
> 
> ;; So we don't use this function as value for HOW-TO in
> ;; dired-do-symlink, which has the minor disadvantage of
> ;; making links *into* a symlinked-dir, when you really wanted to
> ;; *overwrite* that symlink.  In that (rare, I guess) case, you'll
> ;; just have to remove that symlink by hand before making your marked
> ;; symlinks.
> 
> (defvar dired-copy-how-to-fn nil
>   "Either nil or a function used by `dired-do-copy' to determine target.
> See HOW-TO argument for `dired-do-create-files'.")
> 
> It's still clear as mud to me.

dired-into-dir-with-symlinks returns t if TARGET is a real directory.
It returns nil if TARGET is a plain file or a symlink to a directory.
The first generation automounter(s) mounted your home directory in a
temporary directory and then created a symlink to the mounted directory.
But $HOME would be the path to the symlink.

> My interpretation of t is that all files you copy will up in the same
> file if it's t, which is a supremely useless thing, you'd think...

No, you can only copy one file if the target is a plain file.  From
earlier in the docstring for dired-do-create-files:

    The target may also be a non-directory file, if only
    one file is marked.

Maybe this sentence should be deleted:

    Otherwise, the target is a plain file;
    an error is raised unless there is exactly one marked file.

The way the docstring is currently written, it seems to imply that the
error only gets raised in the case where HOW-TO is nil.

I agree that this is all very complicated and confusing.  It doesn't
help that if HOW-TO is t, the target is treated as a plain file.  But if
HOW-TO is a function, it returns nil to indicate a plain file.

mike






^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
  2019-07-11  5:51   ` Mike Kupfer
@ 2019-07-11 14:04     ` Lars Ingebrigtsen
  2019-07-11 14:18     ` Drew Adams
  2022-01-22 14:43     ` Lars Ingebrigtsen
  2 siblings, 0 replies; 59+ messages in thread
From: Lars Ingebrigtsen @ 2019-07-11 14:04 UTC (permalink / raw)
  To: Mike Kupfer; +Cc: 35367

Mike Kupfer <mkupfer@alum.berkeley.edu> writes:

> Presumably it's so you could override dired's behavior for handling a
> target.  If the target is a symlink to a directory, the default behavior
> would be to treat it as a directory, but maybe there are cases where you
> want to replace the link instead.

Ah, I see.

[More useful explanation deleted; thanks for figuring it out.]

>> My interpretation of t is that all files you copy will up in the same
>> file if it's t, which is a supremely useless thing, you'd think...
>
> No, you can only copy one file if the target is a plain file.  From
> earlier in the docstring for dired-do-create-files:
>
>     The target may also be a non-directory file, if only
>     one file is marked.
>
> Maybe this sentence should be deleted:
>
>     Otherwise, the target is a plain file;
>     an error is raised unless there is exactly one marked file.
>
> The way the docstring is currently written, it seems to imply that the
> error only gets raised in the case where HOW-TO is nil.
>
> I agree that this is all very complicated and confusing.  It doesn't
> help that if HOW-TO is t, the target is treated as a plain file.  But if
> HOW-TO is a function, it returns nil to indicate a plain file.

Could you perhaps propose a rewrite of the doc string here to make it
more understandable; both what it does and say when it might be useful?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
  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
  2022-01-22 14:43     ` Lars Ingebrigtsen
  2 siblings, 1 reply; 59+ messages in thread
From: Drew Adams @ 2019-07-11 14:18 UTC (permalink / raw)
  To: Mike Kupfer, Lars Ingebrigtsen; +Cc: 35367

Thanks, Mike.  I probably would never have
figured out all of that.

Kinda seems odd that we'd have created a
variable for something that someone _might_
want to do (but probably never has done).

Usually, when someone proposes something
like that it gets rejected as fulfilling
only a hypothetical need.

Anyway, if the variable will stay then it
would be great if the doc could be fixed
a bit, based on some of what you said here.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
  2019-07-11 14:18     ` Drew Adams
@ 2019-07-12  3:20       ` Mike Kupfer
  2019-07-12  3:33         ` Drew Adams
  0 siblings, 1 reply; 59+ messages in thread
From: Mike Kupfer @ 2019-07-12  3:20 UTC (permalink / raw)
  To: Drew Adams; +Cc: 35367, Lars Ingebrigtsen

Drew Adams wrote:

> Kinda seems odd that we'd have created a
> variable for something that someone _might_
> want to do (but probably never has done).
> 
> Usually, when someone proposes something
> like that it gets rejected as fulfilling
> only a hypothetical need.

Indeed.  Maybe there were consumers of dired-copy-how-to-fn back in the
1990s.  While poking around in the sources I noticed a comment in
vc-dir.el saying that it *used to be* based on dired.  (Or maybe whoever
was the Emacs maintainer at the time thought dired-copy-how-to-fn was a
cool idea and didn't insist on having a consumer for it.)

> Anyway, if the variable will stay then it
> would be great if the doc could be fixed
> a bit, based on some of what you said here.

I can try proposing clearer wording for the dired-do-create-files
docstring, though it'll probably be several days before I can get to it.

I want to be cautious about proposing ways to use dired-copy-how-to-fn.
My earlier comments were based on my reading of the documentation and a
tiny bit of testing.  I wasn't involved with Emacs development when the
dired how-to stuff was introduced, so I don't have any special insights
into what the thinking was at the time.  Though the more I think about
my tarfile example, the more I think it'd be a fun little hack.

mike





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
  2019-07-12  3:20       ` Mike Kupfer
@ 2019-07-12  3:33         ` Drew Adams
  0 siblings, 0 replies; 59+ messages in thread
From: Drew Adams @ 2019-07-12  3:33 UTC (permalink / raw)
  To: Mike Kupfer; +Cc: 35367, Lars Ingebrigtsen

> > Kinda seems odd that we'd have created a
> > variable for something that someone _might_
> > want to do (but probably never has done).
> >
> > Usually, when someone proposes something
> > like that it gets rejected as fulfilling
> > only a hypothetical need.
> 
> Indeed.  Maybe there were consumers of dired-copy-how-to-fn back in the
> 1990s.  While poking around in the sources I noticed a comment in
> vc-dir.el saying that it *used to be* based on dired.  (Or maybe whoever
> was the Emacs maintainer at the time thought dired-copy-how-to-fn was a
> cool idea and didn't insist on having a consumer for it.)
> 
> > Anyway, if the variable will stay then it
> > would be great if the doc could be fixed
> > a bit, based on some of what you said here.
> 
> I can try proposing clearer wording for the dired-do-create-files
> docstring, though it'll probably be several days before I can get to it.
> 
> I want to be cautious about proposing ways to use dired-copy-how-to-fn.
> My earlier comments were based on my reading of the documentation and a
> tiny bit of testing.  I wasn't involved with Emacs development when the
> dired how-to stuff was introduced, so I don't have any special insights
> into what the thinking was at the time.  Though the more I think about
> my tarfile example, the more I think it'd be a fun little hack.

Sounds good.  I don't think you have to worry
about hurrying.  Instead of several days it
could probably be several years (decades?)
without anyone noticing. ;-)





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
@ 2020-05-21 16:56 Philip K.
  2020-05-21 22:18 ` Juri Linkov
  2020-06-26 19:46 ` Philip K.
  0 siblings, 2 replies; 59+ messages in thread
From: Philip K. @ 2020-05-21 16:56 UTC (permalink / raw)
  To: 41438

[-- Attachment #1: Type: text/plain, Size: 1091 bytes --]


Hi,

I'm probably not the only one who tends to use C-{f,b,n,p} over the
arrow keys, but also sometimes gets annoyed by navigating windows. I
recently realised that the reason I didn't use windmove as much as I
would want to, was that I coudln't find a satisfying modifier-key. My
idea was then to try windmove without any modifier, and I quite like
it. The only "annoying" thing is that I have to bind all keys
manually, instead of using a function like
`windmove-default-keybindings', because `nil' is interpreted as a
default binding.

This patch adds a pseudo-modifier (`none') to allow bindings the
windmove functions without any real modifier or prefix key, depending on
the function.

--

Another question I'd like to ask before trying it out: Would there be
any interest in adding user options for the "default" modifiers that
windmove should use? If yes, one could add a :set function that
automatically calls the apropriate bindings function, when it's value
is non-nil. I have a very customize-centric configuration, where something
this would fit in very well.

-- 
	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 0fb951817fc11983498052f2a4fdb8815bc89b92 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 f96383197b..3d7f86b9af 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)
@@ -568,9 +571,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)
@@ -640,11 +646,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)
@@ -695,9 +706,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


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  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>
  2020-06-26 19:46 ` Philip K.
  1 sibling, 2 replies; 59+ messages in thread
From: Juri Linkov @ 2020-05-21 22:18 UTC (permalink / raw)
  To: Philip K.; +Cc: 41438

> I'm probably not the only one who tends to use C-{f,b,n,p} over the
> arrow keys, but also sometimes gets annoyed by navigating windows. I
> recently realised that the reason I didn't use windmove as much as I
> would want to, was that I coudln't find a satisfying modifier-key. My
> idea was then to try windmove without any modifier, and I quite like
> it. The only "annoying" thing is that I have to bind all keys
> manually, instead of using a function like
> `windmove-default-keybindings', because `nil' is interpreted as a
> default binding.
>
> This patch adds a pseudo-modifier (`none') to allow bindings the
> windmove functions without any real modifier or prefix key, depending on
> the function.

Thanks, since `nil' means a default binding it seems there is no other way
than using a pseudo-modifier `none'.

> Another question I'd like to ask before trying it out: Would there be
> any interest in adding user options for the "default" modifiers that
> windmove should use? If yes, one could add a :set function that
> automatically calls the apropriate bindings function, when it's value
> is non-nil. I have a very customize-centric configuration, where something
> this would fit in very well.

I think that adding defcustoms (including a new const `none')
would be the most natural way to customize windmove modifiers
(provided that the existing functions should remain).





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-05-21 22:18 ` Juri Linkov
@ 2020-05-22 18:26   ` Philip K.
       [not found]   ` <(message>
  1 sibling, 0 replies; 59+ messages in thread
From: Philip K. @ 2020-05-22 18:26 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 863 bytes --]

Juri Linkov <juri@linkov.net> writes:

>> Another question I'd like to ask before trying it out: Would there be
>> any interest in adding user options for the "default" modifiers that
>> windmove should use? If yes, one could add a :set function that
>> automatically calls the apropriate bindings function, when it's value
>> is non-nil. I have a very customize-centric configuration, where something
>> this would fit in very well.
>
> I think that adding defcustoms (including a new const `none')
> would be the most natural way to customize windmove modifiers
> (provided that the existing functions should remain).

I made a first concept, but it doesn't work unless windmove is explicity
required (see below). As far as I know, autoloading variables isn't good
style, so is there any other way to invoke the :set property of a user
option?

-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Implement-user-options-for-windmove-modifiers-and-pr.patch --]
[-- Type: text/x-diff, Size: 8273 bytes --]

From b35173936e681e170172eb3d4548a2f91f70dad3 Mon Sep 17 00:00:00 2001
From: Philip K <philip@warpmail.net>
Date: Fri, 22 May 2020 20:21:59 +0200
Subject: [PATCH] Implement user options for windmove modifiers and prefixes

---
 lisp/windmove.el | 103 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 95 insertions(+), 8 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 3d7f86b9af..95f74bfb81 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -162,6 +162,19 @@ 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))
+  "Customisation type for windmove modifiers")
+
 \f
 ;; Note:
 ;;
@@ -419,6 +432,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,9 +447,10 @@ 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))
+  (unless modifiers
+    (setq modifiers windmove-modifiers))
   (when (eq modifiers 'none) (setq modifiers nil))
   (unless (listp modifiers) (setq modifiers (list modifiers)))
   (global-set-key (vector (append modifiers '(left)))  'windmove-left)
@@ -443,6 +458,25 @@ windmove-default-keybindings
   (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)
+         (when val
+           (windmove-swap-states-default-keybindings val))
+         (set-default sym val)))
+
 \f
 ;;; Directional window display and selection
 
@@ -565,6 +599,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.
@@ -573,7 +609,7 @@ 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)))
   (when (eq modifiers 'none) (setq modifiers nil))
@@ -586,6 +622,17 @@ 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))
 
+(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)
+         (when val
+           (windmove-display-default-keybindings val))
+         (set-default sym val)))
+
 \f
 ;;; Directional window deletion
 
@@ -640,6 +687,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.
@@ -649,12 +699,13 @@ 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)
@@ -662,6 +713,28 @@ 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
+  :set (lambda (sym val)
+         (windmove-delete-default-keybindings
+          val windmove-delete-modifiers)
+         (set-default sym val)))
+
+(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 (lambda (sym val)
+         (when val
+           (windmove-delete-default-keybindings
+            windmove-delete-prefix val))
+         (set-default sym val)))
+
 \f
 ;;; Directional window swap states
 
@@ -700,6 +773,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.
@@ -709,9 +784,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)
@@ -719,6 +795,17 @@ 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))
 
+(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-swap-states-default-keybindings val)
+         (set-default sym val)))
+
 \f
 (provide 'windmove)
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
       [not found]                         ` <87v9kn7rnk.fsf@bulbul>
@ 2020-05-22 19:15                           ` Drew Adams
  2020-05-23 22:12                           ` Juri Linkov
  1 sibling, 0 replies; 59+ messages in thread
From: Drew Adams @ 2020-05-22 19:15 UTC (permalink / raw)
  To: philip, Juri Linkov; +Cc: 41438, emacs-devel

Please don't send the same mail to both the bug list and emacs-devel.  Thx.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
       [not found]                         ` <87v9kn7rnk.fsf@bulbul>
  2020-05-22 19:15                           ` Drew Adams
@ 2020-05-23 22:12                           ` Juri Linkov
  1 sibling, 0 replies; 59+ messages in thread
From: Juri Linkov @ 2020-05-23 22:12 UTC (permalink / raw)
  To: Philip K.; +Cc: 41438

>>> Another question I'd like to ask before trying it out: Would there be
>>> any interest in adding user options for the "default" modifiers that
>>> windmove should use? If yes, one could add a :set function that
>>> automatically calls the apropriate bindings function, when it's value
>>> is non-nil. I have a very customize-centric configuration, where something
>>> this would fit in very well.
>>
>> I think that adding defcustoms (including a new const `none')
>> would be the most natural way to customize windmove modifiers
>> (provided that the existing functions should remain).
>
> I made a first concept, but it doesn't work unless windmove is explicity
> required (see below). As far as I know, autoloading variables isn't good
> style, so is there any other way to invoke the :set property of a user
> option?

Recently we had a similar problem in char-fold.el that was solved using
defconst for the default value and a :set function, this might help here.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  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-06-26 19:46 ` Philip K.
  2020-06-27 23:53   ` Juri Linkov
  1 sibling, 1 reply; 59+ messages in thread
From: Philip K. @ 2020-06-26 19:46 UTC (permalink / raw)
  To: juri; +Cc: 41438


> Recently we had a similar problem in char-fold.el that was solved
> using defconst for the default value and a :set function, this might
> help here.

I've been trying to understand what was changed there (I presume you're
referring to 376f5df), but I don't think I can quite follow. What
difference does adding the defconst forms to the eval-and-compile block
do?

-- 
	Philip K.






^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-06-26 19:46 ` Philip K.
@ 2020-06-27 23:53   ` Juri Linkov
  2020-06-28  8:30     ` Philip K.
  0 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2020-06-27 23:53 UTC (permalink / raw)
  To: Philip K.; +Cc: 41438, 41438

>> Recently we had a similar problem in char-fold.el that was solved
>> using defconst for the default value and a :set function, this might
>> help here.
>
> I've been trying to understand what was changed there (I presume you're
> referring to 376f5df), but I don't think I can quite follow. What
> difference does adding the defconst forms to the eval-and-compile block
> do?

Actually, I meant not so much the defconst form (that is an unimportant
detail), but more the :set function, and also I forgot to mention
:initialize.  Their combination in char-fold.el looks like:

  :initialize #'custom-initialize-default
  :set (lambda (sym val)
         (custom-set-default sym val)
         (char-fold-update-table))

Then after loading char-fold.el, this function is executed at the top level:

(char-fold-update-table)

Maybe something like this could help to initialize default keybindings
after loading windmove.el.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-06-27 23:53   ` Juri Linkov
@ 2020-06-28  8:30     ` Philip K.
  2020-06-28 23:37       ` Juri Linkov
  0 siblings, 1 reply; 59+ messages in thread
From: Philip K. @ 2020-06-28  8:30 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438

Juri Linkov <juri@linkov.net> writes:

> Actually, I meant not so much the defconst form (that is an unimportant
> detail), but more the :set function, and also I forgot to mention
> :initialize.  Their combination in char-fold.el looks like:
>
>   :initialize #'custom-initialize-default
>   :set (lambda (sym val)
>          (custom-set-default sym val)
>          (char-fold-update-table))
>
> Then after loading char-fold.el, this function is executed at the top level:
>
> (char-fold-update-table)
>
> Maybe something like this could help to initialize default keybindings
> after loading windmove.el.

I get what you were saying, but it seems the issue with windmove is the
opposite. Just loading windmove shouldn't create any new keybindings,
but customising the new user options should, *even if* windmove hasn't
been loaded yet (ideally).

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-06-28  8:30     ` Philip K.
@ 2020-06-28 23:37       ` Juri Linkov
  2020-08-05 18:05         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2020-06-28 23:37 UTC (permalink / raw)
  To: Philip K.; +Cc: 41438

> I get what you were saying, but it seems the issue with windmove is the
> opposite. Just loading windmove shouldn't create any new keybindings,
> but customising the new user options should, *even if* windmove hasn't
> been loaded yet (ideally).

Then it seems explicitly requiring windmove and autoloading variables
is unavoidable, so your previous patch was the right thing to do.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work
@ 2020-07-30  4:01 Brett Randall
       [not found] ` <handler.42611.B.159608273314264.ack@debbugs.gnu.org>
  2020-10-17  8:41 ` Lars Ingebrigtsen
  0 siblings, 2 replies; 59+ messages in thread
From: Brett Randall @ 2020-07-30  4:01 UTC (permalink / raw)
  To: 42611

[-- Attachment #1: Type: text/plain, Size: 4444 bytes --]

Actions that triggered the bug:


M-x edit-abbrevs


Enter abbrevs in fundamental or global abbreviations at bottom of the list, e.g.:


"dfn" 0 "definition"


C-c C-c


Buffer appears committed (modified flag disappears). Close buffer, test the abbrev in "abbrev-mode" minor mode and nothing happens. M-x edit-abbrevs again. The definition I entered is no longer there. This is in the same session. Emacs was not closed/reopened. The definitions are not applying/temporarily saving.


In GNU Emacs 26.3 (build 1, x86_64-pc-cygwin)
of 2019-08-31 built on moufang2
Repository revision: 522486e90a3d9402d836c2186be9e73299423cd9
Windowing system distributor 'Microsoft Corp.', version 10.0.19041
Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.
Quit
(New file)
Making completion list...
Abbrev mode enabled in current buffer
Saving all Org buffers... done


Configured using:
'configure
--srcdir=/home/kbrown/src/cygpackages/emacs/emacs-26.3-2.x86_64/src/emacs-26.3
--prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc
--docdir=/usr/share/doc/emacs --htmldir=/usr/share/doc/emacs/html -C
--with-w32 'CFLAGS=-ggdb -O2 -pipe -Wall -Werror=format-security
-Wp,-D_FORTIFY_SOURCE=2 -fstack-protector-strong
--param=ssp-buffer-size=4
-fdebug-prefix-map=/home/kbrown/src/cygpackages/emacs/emacs-26.3-2.x86_64/build=/usr/src/debug/emacs-26.3-2
-fdebug-prefix-map=/home/kbrown/src/cygpackages/emacs/emacs-26.3-2.x86_64/src/emacs-26.3=/usr/src/debug/emacs-26.3-2'
CPPFLAGS= LDFLAGS='


Configured features:
XPM JPEG TIFF GIF PNG IMAGEMAGICK SOUND DBUS GLIB NOTIFY ACL GNUTLS
LIBXML2 ZLIB TOOLKIT_SCROLL_BARS XIM THREADS LCMS2


Important settings:
locale-coding-system: nil


Major mode: Info


Minor modes in effect:
global-auto-revert-mode: t
tooltip-mode: t
global-eldoc-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
buffer-read-only: t
line-number-mode: t
transient-mark-mode: t


Load-path shadows:
None found.


Features:
(shadow sort mail-extr emacsbug message rmc puny dired dired-loaddefs
rfc822 mml mml-sec epa derived epg gnus-util rmail rmail-loaddefs
mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils
mailheader sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr
mail-utils jka-compr info elec-pair org-element avl-tree generator org
org-macro org-footnote org-pcomplete pcomplete org-list org-faces
org-entities noutline outline easy-mmode org-version ob-emacs-lisp ob
ob-tangle org-src ob-ref ob-lob ob-table ob-keys ob-exp ob-comint comint
ansi-color ring ob-core ob-eval org-compat org-macs org-loaddefs
format-spec find-func cal-menu calendar cal-loaddefs edmacro kmacro
advice autorevert filenotify arjen-theme finder-inf package easymenu
epg-config url-handlers url-parse auth-source cl-seq eieio eieio-core
cl-macs eieio-loaddefs password-cache url-vars seq byte-opt gv bytecomp
byte-compile cconv cl-loaddefs cl-lib time-date mule-util tooltip eldoc
electric uniquify ediff-hook vc-hooks lisp-float-type mwheel disp-table
term/w32-win w32-win w32-vars term/common-win tool-bar dnd fontset image
regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode
lisp-mode prog-mode register page menu-bar rfn-eshadow isearch timer
select scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang
vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932
hebrew greek romanian slovak czech european ethiopic indian cyrillic
chinese composite charscript charprop case-table epa-hook jka-cmpr-hook
help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote threads dbusbind gfilenotify w32 lcms2 multi-tty
make-network-process emacs)


Memory information:
((conses 16 165726 13709)
(symbols 48 27132 1)
(miscs 40 72 220)
(strings 32 55598 1442)
(string-bytes 1 1610203)
(vectors 16 22900)
(vector-slots 8 589906 9136)
(floats 8 97 210)
(intervals 56 320 176)
(buffers 992 16))

Brett

[-- Attachment #2: Type: text/html, Size: 6111 bytes --]

^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-06-28 23:37       ` Juri Linkov
@ 2020-08-05 18:05         ` Lars Ingebrigtsen
  2020-08-05 23:40           ` Juri Linkov
  0 siblings, 1 reply; 59+ messages in thread
From: Lars Ingebrigtsen @ 2020-08-05 18:05 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, Philip K.

Juri Linkov <juri@linkov.net> writes:

>> I get what you were saying, but it seems the issue with windmove is the
>> opposite. Just loading windmove shouldn't create any new keybindings,
>> but customising the new user options should, *even if* windmove hasn't
>> been loaded yet (ideally).
>
> Then it seems explicitly requiring windmove and autoloading variables
> is unavoidable, so your previous patch was the right thing to do.

The patch wasn't applied, though?  I know nothing about windmove, so I'm
not really qualified to have an opinion, but if you think it's the right
thing to do, then you should apply it?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-08-05 18:05         ` Lars Ingebrigtsen
@ 2020-08-05 23:40           ` Juri Linkov
  2020-08-06  9:28             ` Philip K.
  0 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2020-08-05 23:40 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 41438, Philip K.

>>> I get what you were saying, but it seems the issue with windmove is the
>>> opposite. Just loading windmove shouldn't create any new keybindings,
>>> but customising the new user options should, *even if* windmove hasn't
>>> been loaded yet (ideally).
>>
>> Then it seems explicitly requiring windmove and autoloading variables
>> is unavoidable, so your previous patch was the right thing to do.
>
> The patch wasn't applied, though?  I know nothing about windmove, so I'm
> not really qualified to have an opinion, but if you think it's the right
> thing to do, then you should apply it?

Philip, could you please prepare the final version of your patch
(I see there were some unfinished parts in your previous patch).





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-08-05 23:40           ` Juri Linkov
@ 2020-08-06  9:28             ` Philip K.
  2020-08-06 23:43               ` Juri Linkov
  0 siblings, 1 reply; 59+ messages in thread
From: Philip K. @ 2020-08-06  9:28 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, larsi

Juri Linkov <juri@linkov.net> writes:

> Philip, could you please prepare the final version of your patch

Sure, I'll try to finish it today.

> (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 :/

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.

[0] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=41438#5

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-08-06  9:28             ` Philip K.
@ 2020-08-06 23:43               ` Juri Linkov
  2020-08-07 10:53                 ` Philip K.
  0 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2020-08-06 23:43 UTC (permalink / raw)
  To: Philip K.; +Cc: 41438, larsi

>> (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.

> 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.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-08-06 23:43               ` Juri Linkov
@ 2020-08-07 10:53                 ` Philip K.
  2020-08-08 23:54                   ` Juri Linkov
  2021-05-12 20:38                   ` Lars Ingebrigtsen
  0 siblings, 2 replies; 59+ messages in thread
From: Philip K. @ 2020-08-07 10:53 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, larsi

[-- 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


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-08-07 10:53                 ` Philip K.
@ 2020-08-08 23:54                   ` Juri Linkov
  2021-05-12 20:38                   ` Lars Ingebrigtsen
  1 sibling, 0 replies; 59+ messages in thread
From: Juri Linkov @ 2020-08-08 23:54 UTC (permalink / raw)
  To: Philip K.; +Cc: 41438, larsi

> 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.

Perhaps displaying a warning should be sufficient.

> 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).

I'm not sure whether such complication is necessary.  Usually
users will try to customize the option and then restart Emacs.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work
  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>
@ 2020-10-17  8:41 ` Lars Ingebrigtsen
  2020-10-27 10:36   ` brett.randall
  1 sibling, 1 reply; 59+ messages in thread
From: Lars Ingebrigtsen @ 2020-10-17  8:41 UTC (permalink / raw)
  To: Brett Randall; +Cc: 42611

Brett Randall <brett.randall@gmail.com> writes:

> Actions that triggered the bug:
>
> M-x edit-abbrevs
>
> Enter abbrevs in fundamental or global abbreviations at bottom of the list, e.g.:
>
> "dfn" 0 "definition"
>
> C-c C-c
>
> Buffer appears committed (modified flag disappears). Close buffer, test the abbrev
> in "abbrev-mode" minor mode and nothing happens. M-x edit-abbrevs again. The
> definition I entered is no longer there. This is in the same session. Emacs was not
> closed/reopened. The definitions are not applying/temporarily saving.

I'm unable to reproduce this bug either in Emacs 26.3 or on the trunk.
`C-c C-c' in the *Abbrevs* buffer updates the abbreviation for me.

Are you able to reproduce this bug starting from "emacs -Q"?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work
  2020-10-17  8:41 ` Lars Ingebrigtsen
@ 2020-10-27 10:36   ` brett.randall
       [not found]     ` <(brett>
  2020-10-27 10:43     ` Lars Ingebrigtsen
  0 siblings, 2 replies; 59+ messages in thread
From: brett.randall @ 2020-10-27 10:36 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 42611

[-- Attachment #1: Type: text/plain, Size: 969 bytes --]



--- original message ---
On October 17, 2020, 7:41 PM GMT+11 larsi@gnus.org wrote:


Brett Randall <brett.randall@gmail.com> writes:

>> Actions that triggered the bug:
>>
>> M-x edit-abbrevs
>>
>> Enter abbrevs in fundamental or global abbreviations at bottom of the list, e.g.:
>>
>> "dfn" 0 "definition"
>>
>> C-c C-c
>>
>> Buffer appears committed (modified flag disappears). Close buffer, test the abbrev
>> in "abbrev-mode" minor mode and nothing happens. M-x edit-abbrevs again. The
>> definition I entered is no longer there. This is in the same session. Emacs was not
>> closed/reopened. The definitions are not applying/temporarily saving.

> I'm unable to reproduce this bug either in Emacs 26.3 or on the trunk.
> `C-c C-c' in the *Abbrevs* buffer updates the abbreviation for me.

> Are you able to reproduce this bug starting from "emacs -Q"?


Yes, the bug exists from there too.


Brett
--- end of original message ---

[-- Attachment #2: Type: text/html, Size: 1806 bytes --]

^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work
  2020-10-27 10:36   ` brett.randall
       [not found]     ` <(brett>
@ 2020-10-27 10:43     ` Lars Ingebrigtsen
  2020-10-27 10:49       ` Brett Randall
  1 sibling, 1 reply; 59+ messages in thread
From: Lars Ingebrigtsen @ 2020-10-27 10:43 UTC (permalink / raw)
  To: brett.randall; +Cc: 42611

brett.randall@gmail.com writes:

>  I'm unable to reproduce this bug either in Emacs 26.3 or on the trunk.
>  `C-c C-c' in the *Abbrevs* buffer updates the abbreviation for me.
>
>  Are you able to reproduce this bug starting from "emacs -Q"?
>
>  Yes, the bug exists from there too.

Can you give a recipe for how to reproduce the bug, starting from
"emacs -Q"?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work
  2020-10-27 10:43     ` Lars Ingebrigtsen
@ 2020-10-27 10:49       ` Brett Randall
  2020-10-27 11:08         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 59+ messages in thread
From: Brett Randall @ 2020-10-27 10:49 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 42611

[-- Attachment #1: Type: text/plain, Size: 888 bytes --]



Brett

--- original message ---
On October 27, 2020, 9:43 PM GMT+11 larsi@gnus.org wrote:


brett.randall@gmail.com writes:

>> I'm unable to reproduce this bug either in Emacs 26.3 or on the trunk.
>> `C-c C-c' in the *Abbrevs* buffer updates the abbreviation for me.
>>
>> Are you able to reproduce this bug starting from "emacs -Q"?
>>
>> Yes, the bug exists from there too.

> Can you give a recipe for how to reproduce the bug, starting from
> "emacs -Q"?


Yes:



emacs -Q

M-x edit-abbrevs

Scroll to last line - (global-abbrev-table)

Append: "dfn" 0 "definition"

C-c C-c (removes "modified" flag)

C-x k

M-x edit-abbrevs

Scroll down to last line - abbreviation is not there

C-x C-c (results in "Save abbrevs in ~/.emacs.d/abbrev_defs? (y or n) ")

"y" to above

Inspect .emacs.d/abbrev_defs - only contains one line:

;;-*-coding: utf-8;-*-
--- end of original message ---

[-- Attachment #2: Type: text/html, Size: 1980 bytes --]

^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work
  2020-10-27 10:49       ` Brett Randall
@ 2020-10-27 11:08         ` Lars Ingebrigtsen
       [not found]           ` <(Lars>
  2020-10-27 11:19           ` bug#42611: (no subject) Lars Ingebrigtsen
  0 siblings, 2 replies; 59+ messages in thread
From: Lars Ingebrigtsen @ 2020-10-27 11:08 UTC (permalink / raw)
  To: Brett Randall; +Cc: 42611

Brett Randall <brett.randall@gmail.com> writes:

>  1 emacs -Q
>  2 M-x edit-abbrevs
>  3 Scroll to last line - (global-abbrev-table)
>  4 Append: "dfn" 0 "definition"
>  5 C-c C-c (removes "modified" flag)
>  6 C-x k
>  7 M-x edit-abbrevs
>  8 Scroll down to last line - abbreviation is not there

Thanks.

The format of that buffer is very specific, though.  The entries must be
on the format:

(global-abbrev-table)

"def"	       0    "definition"

with one blank line between the name of the section and the start of the
definitions; neither more nor less.  If you do it that way, does the
mode work for you?

In any case, I don't quite see why it's that strict about the format: It
should just grok all the lines between the sections, I think?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: (no subject)
  2020-10-27 11:08         ` Lars Ingebrigtsen
       [not found]           ` <(Lars>
@ 2020-10-27 11:19           ` Lars Ingebrigtsen
       [not found]             ` <877drbhq6c.fsf@gnus.org>
  1 sibling, 1 reply; 59+ messages in thread
From: Lars Ingebrigtsen @ 2020-10-27 11:19 UTC (permalink / raw)
  To: Brett Randall; +Cc: 42611

Lars Ingebrigtsen <larsi@gnus.org> writes:

> In any case, I don't quite see why it's that strict about the format: It
> should just grok all the lines between the sections, I think?

I've now altered the parser to just ignore blank lines in Emacs 28,
which should make the mode somewhat less brittle. 

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#42611: 26.3; edit-abbrevs lets me type and commit, but doesn't store anywhere and abbrevs don't work
       [not found]               ` <handler.42611.C.160379757411378.notifdonectrl.0@debbugs.gnu.org>
@ 2020-10-27 22:22                 ` Brett Randall
  0 siblings, 0 replies; 59+ messages in thread
From: Brett Randall @ 2020-10-27 22:22 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 42611

[-- Attachment #1: Type: text/plain, Size: 1161 bytes --]

Thanks Lars, it works now that I understand the formatting requirement. Appreciate your help.

Brett

--- original message ---
On October 27, 2020, 10:08 PM GMT+11 larsi@gnus.org wrote:

Brett Randall <brett.randall@gmail.com> writes:


>> 1 emacs -Q

>> 2 M-x edit-abbrevs

>> 3 Scroll to last line - (global-abbrev-table)

>> 4 Append: "dfn" 0 "definition"

>> 5 C-c C-c (removes "modified" flag)

>> 6 C-x k

>> 7 M-x edit-abbrevs

>> 8 Scroll down to last line - abbreviation is not there


> Thanks.


> The format of that buffer is very specific, though. The entries must be

> on the format:


> (global-abbrev-table)


> "def" 0 "definition"


> with one blank line between the name of the section and the start of the

> definitions; neither more nor less. If you do it that way, does the

> mode work for you?


> In any case, I don't quite see why it's that strict about the format: It

> should just grok all the lines between the sections, I think?


> -- 

> (domestic pets only, the antidote for overdose, milk.)

> bloggy blog: http://lars.ingebrigtsen.no
--- end of original message ---

[-- Attachment #2: Type: text/html, Size: 2063 bytes --]

^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2020-08-07 10:53                 ` Philip K.
  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
  1 sibling, 2 replies; 59+ messages in thread
From: Lars Ingebrigtsen @ 2021-05-12 20:38 UTC (permalink / raw)
  To: Philip K.; +Cc: 41438, Juri Linkov

"Philip K." <philipk@posteo.net> writes:

> 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.

Have you done any further work on this?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-12 20:38                   ` Lars Ingebrigtsen
@ 2021-05-12 21:27                     ` Philip Kaludercic
  2021-05-22 20:29                     ` Philip Kaludercic
  1 sibling, 0 replies; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-12 21:27 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 41438, Juri Linkov

Lars Ingebrigtsen <larsi@gnus.org> writes:

> "Philip K." <philipk@posteo.net> writes:
>
>> 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.
>
> Have you done any further work on this?

No, not since whenever that message was sent.

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  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-25  5:12                       ` Lars Ingebrigtsen
  1 sibling, 2 replies; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-22 20:29 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 41438, Juri Linkov

[-- Attachment #1: Type: text/plain, Size: 1033 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

> "Philip K." <philipk@posteo.net> writes:
>
>> 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.
>
> Have you done any further work on this?

I have been thinking about this a bit more, and tried a different
approach. The implementation is not prefect, but basically I am playing
with emulation-mode-map-alists to bind the keys, instead of using the
global map.

The should solve the two issues I brought up, because I do not have to
worry about restoring the previous keys, and some edge-cases are
avoided, where e.g. doc-view would override up and down breaking the
expected behaviour when setting the prefix to 'none.

The code should probably be refactored, moving more of the common
functionality into it's own function, but I am primarily wondering if
using emulation-mode-map-alists the way I am proposing it here is ok. Or
should I prefer minor-mode-map-alist?

-- 
	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: 7384 bytes --]

From eba161853d50c2a6ce27af5907efdae4f6ab81eb Mon Sep 17 00:00:00 2001
From: Philip K <philipk@posteo.net>
Date: Sat, 22 May 2021 22:03:22 +0200
Subject: [PATCH] Allow windmove keys to be bound without prefix or modifiers

---
 lisp/windmove.el | 91 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..acd9cb41fc 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,35 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-map (make-sparse-keymap)
+  "Keymap to bind windmove keys to.")
+
+(add-to-list 'emulation-mode-map-alists
+             (list (cons t windmove-map)))
+
 ;;;###autoload
 (defun windmove-default-keybindings (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (dolist (bind '((windmove-left left)
+                  (windmove-right right)
+                  (windmove-up up)
+                  (windmove-down down)))
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-map))
+        (define-key windmove-map old nil))
+      (define-key windmove-map
+        (vector (append modifiers (cdr bind)))
+        (car bind)))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +562,27 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (dolist (bind '((windmove-display-left left)
+                  (windmove-display-right right)
+                  (windmove-display-up up)
+                  (windmove-display-down down)
+                  (windmove-display-same-window ?0)
+                  (windmove-display-new-frame ?f)
+                  (windmove-display-new-tab ?t)))
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-map))
+        (define-key windmove-map old nil))
+      (define-key windmove-map
+        (vector (append modifiers (cdr bind)))
+        (car bind)))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +644,28 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (dolist (bind '((windmove-delete-left left)
+                  (windmove-delete-right right)
+                  (windmove-delete-up up)
+                  (windmove-delete-down down)))
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-map))
+        (define-key windmove-map old nil))
+      (define-key windmove-map
+        (vector (append modifiers (cdr bind)))
+        (car bind)))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +711,25 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (dolist (bind '((windmove-swap-states-left left)
+                  (windmove-swap-states-right right)
+                  (windmove-swap-states-up up)
+                  (windmove-swap-states-down down)))
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-map))
+        (define-key windmove-map old nil))
+      (define-key windmove-map
+        (vector (append modifiers (cdr bind)))
+        (car bind)))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-22 20:29                     ` Philip Kaludercic
@ 2021-05-22 21:09                       ` Philip Kaludercic
  2021-05-23  6:49                         ` Eli Zaretskii
  2021-05-25  5:12                       ` Lars Ingebrigtsen
  1 sibling, 1 reply; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-22 21:09 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 41438, Juri Linkov

[-- Attachment #1: Type: text/plain, Size: 358 bytes --]


Philip Kaludercic <philipk@posteo.net> writes:

> The code should probably be refactored, moving more of the common
> functionality into it's own function, but I am primarily wondering if
> using emulation-mode-map-alists the way I am proposing it here is ok. Or
> should I prefer minor-mode-map-alist?

Here is a slightly cleaner version.

-- 
	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: 7168 bytes --]

From 03248e79527f9603aa944e7e147fc67a8886eb3a Mon Sep 17 00:00:00 2001
From: Philip K <philipk@posteo.net>
Date: Sat, 22 May 2021 22:03:22 +0200
Subject: [PATCH] Allow windmove keys to be bound without prefix or modifiers

---
 lisp/windmove.el | 79 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 58 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..bb9478eab4 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,41 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-default-map (make-sparse-keymap)
+  "Map used by `windmove-install-defaults'.")
+
+(defun windmove-install-defaults (modifiers alist)
+  "Install keys as specified by ALIST.
+Every element of ALIST has the form (FN KEY), where KEY is
+appended to MODIFIERS, before installing the key.  Previous
+bindings of FN are unbound."
+  (add-to-list 'emulation-mode-map-alists `((t . ,windmove-default-map)))
+  (dolist (bind alist)
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-default-map))
+        (define-key windmove-default-map old nil))
+      (define-key windmove-default-map
+        (vector (append modifiers (cdr bind)))
+        (car bind)))))
+
 ;;;###autoload
 (defun windmove-default-keybindings (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-left left)
+                               (windmove-right right)
+                               (windmove-up up)
+                               (windmove-down down))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +568,21 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (windmove-install-defaults modifiers
+                             '((windmove-display-left left)
+                               (windmove-display-right right)
+                               (windmove-display-up up)
+                               (windmove-display-down down)
+                               (windmove-display-same-window ?0)
+                               (windmove-display-new-frame ?f)
+                               (windmove-display-new-tab ?t))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +644,22 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-delete-left left)
+                               (windmove-delete-right right)
+                               (windmove-delete-up up)
+                               (windmove-delete-down down))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +705,19 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-swap-states-left left)
+                               (windmove-swap-states-right right)
+                               (windmove-swap-states-up up)
+                               (windmove-swap-states-down down))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-22 21:09                       ` Philip Kaludercic
@ 2021-05-23  6:49                         ` Eli Zaretskii
  2021-05-23 12:36                           ` Philip Kaludercic
  0 siblings, 1 reply; 59+ messages in thread
From: Eli Zaretskii @ 2021-05-23  6:49 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, larsi, juri

> From: Philip Kaludercic <philipk@posteo.net>
> Date: Sat, 22 May 2021 21:09:00 +0000
> Cc: 41438@debbugs.gnu.org, Juri Linkov <juri@linkov.net>
> 
> Philip Kaludercic <philipk@posteo.net> writes:
> 
> > The code should probably be refactored, moving more of the common
> > functionality into it's own function, but I am primarily wondering if
> > using emulation-mode-map-alists the way I am proposing it here is ok. Or
> > should I prefer minor-mode-map-alist?
> 
> Here is a slightly cleaner version.

Thanks.  Should this be in NEWS?





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-23  6:49                         ` Eli Zaretskii
@ 2021-05-23 12:36                           ` Philip Kaludercic
  0 siblings, 0 replies; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-23 12:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41438, larsi, juri

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Philip Kaludercic <philipk@posteo.net>
>> Date: Sat, 22 May 2021 21:09:00 +0000
>> Cc: 41438@debbugs.gnu.org, Juri Linkov <juri@linkov.net>
>> 
>> Philip Kaludercic <philipk@posteo.net> writes:
>> 
>> > The code should probably be refactored, moving more of the common
>> > functionality into it's own function, but I am primarily wondering if
>> > using emulation-mode-map-alists the way I am proposing it here is ok. Or
>> > should I prefer minor-mode-map-alist?
>> 
>> Here is a slightly cleaner version.
>
> Thanks.  Should this be in NEWS?

I think so. IIRC the plan was to add a few additional user options to
make it easier to configure.

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-22 20:29                     ` Philip Kaludercic
  2021-05-22 21:09                       ` Philip Kaludercic
@ 2021-05-25  5:12                       ` Lars Ingebrigtsen
  2021-05-25  7:25                         ` Philip Kaludercic
  2021-05-25  9:53                         ` Philip Kaludercic
  1 sibling, 2 replies; 59+ messages in thread
From: Lars Ingebrigtsen @ 2021-05-25  5:12 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Juri Linkov

Philip Kaludercic <philipk@posteo.net> writes:

> The code should probably be refactored, moving more of the common
> functionality into it's own function, but I am primarily wondering if
> using emulation-mode-map-alists the way I am proposing it here is ok. Or
> should I prefer minor-mode-map-alist?

Making windmove into a regular (global) minor mode would be less
surprising, I think, but I'm not really familiar with windmove, and
whether that would be an easy rewrite?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25  5:12                       ` Lars Ingebrigtsen
@ 2021-05-25  7:25                         ` Philip Kaludercic
  2021-05-25  9:53                         ` Philip Kaludercic
  1 sibling, 0 replies; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-25  7:25 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 41438, Juri Linkov

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>
>> The code should probably be refactored, moving more of the common
>> functionality into it's own function, but I am primarily wondering if
>> using emulation-mode-map-alists the way I am proposing it here is ok. Or
>> should I prefer minor-mode-map-alist?
>
> Making windmove into a regular (global) minor mode would be less
> surprising, I think, but I'm not really familiar with windmove, and
> whether that would be an easy rewrite?

From my experience, it should be possible, I'll try preparing a
patch. The only issue is that most people won't realize there is a minor
mode at first, but that should be OK as long as the actual windmove
commands do not depend on said minor mode.

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  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
                                             ` (3 more replies)
  1 sibling, 4 replies; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-25  9:53 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 41438, Juri Linkov

[-- Attachment #1: Type: text/plain, Size: 682 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>
>> The code should probably be refactored, moving more of the common
>> functionality into it's own function, but I am primarily wondering if
>> using emulation-mode-map-alists the way I am proposing it here is ok. Or
>> should I prefer minor-mode-map-alist?
>
> Making windmove into a regular (global) minor mode would be less
> surprising, I think, but I'm not really familiar with windmove, and
> whether that would be an easy rewrite?

I have tried this out, and it seems somewhat elegant.  From my testing,
it seems to behave the same way as the previous approach.

-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-windmove-default-keybindings-fuctions.patch --]
[-- Type: text/x-diff, Size: 7751 bytes --]

From 2f7a8d89cdb5835cf875bc1f2bcfcb6755a0e0c0 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Tue, 25 May 2021 11:47:51 +0200
Subject: [PATCH] Improve windmove-*-default-keybindings fuctions

* windmove.el (windmove-default-map): Add special map for windmove
commands
(windmove-mode): Add minor mode for activating windmove-default-map
(windmove-install-defaults): Add general function for manipulating
windmove-default-map
(windmove-default-keybindings): Use windmove-install-defaults
(windmove-display-default-keybindings): Use windmove-install-defaults
(windmove-delete-default-keybindings): Use windmove-install-defaults
(windmove-swap-states-default-keybindings): Use
windmove-install-defaults
---
 lisp/windmove.el | 84 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 63 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..5a81893bf9 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,46 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-default-map (make-sparse-keymap)
+  "Map used by `windmove-install-defaults'.")
+
+(define-minor-mode windmove-mode
+  "Global minor mode for default windmove commands."
+  :keymap windmove-default-map
+  :init-value t
+  :global t)
+
+(defun windmove-install-defaults (modifiers alist)
+  "Install keys as specified by ALIST.
+Every element of ALIST has the form (FN KEY), where KEY is
+appended to MODIFIERS, before installing the key.  Previous
+bindings of FN are unbound."
+  (dolist (bind alist)
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-default-map))
+        (define-key windmove-default-map old nil))
+      (define-key windmove-default-map
+        (vector (append modifiers (cdr bind)))
+        (car bind)))))
+
 ;;;###autoload
 (defun windmove-default-keybindingsq (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-left left)
+                               (windmove-right right)
+                               (windmove-up up)
+                               (windmove-down down))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +573,21 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (windmove-install-defaults modifiers
+                             '((windmove-display-left left)
+                               (windmove-display-right right)
+                               (windmove-display-up up)
+                               (windmove-display-down down)
+                               (windmove-display-same-window ?0)
+                               (windmove-display-new-frame ?f)
+                               (windmove-display-new-tab ?t))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +649,22 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-delete-left left)
+                               (windmove-delete-right right)
+                               (windmove-delete-up up)
+                               (windmove-delete-down down))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +710,19 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-swap-states-left left)
+                               (windmove-swap-states-right right)
+                               (windmove-swap-states-up up)
+                               (windmove-swap-states-down down))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25  9:53                         ` Philip Kaludercic
@ 2021-05-25 11:16                           ` Arthur Miller
  2021-05-25 11:42                             ` Philip Kaludercic
  2021-05-25 11:36                           ` Arthur Miller
                                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 59+ messages in thread
From: Arthur Miller @ 2021-05-25 11:16 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen, Juri Linkov

Philip Kaludercic <philipk@posteo.net> writes:

> Lars Ingebrigtsen <larsi@gnus.org> writes:
>
>> Philip Kaludercic <philipk@posteo.net> writes:
>>
>>> The code should probably be refactored, moving more of the common
>>> functionality into it's own function, but I am primarily wondering if
>>> using emulation-mode-map-alists the way I am proposing it here is ok. Or
>>> should I prefer minor-mode-map-alist?
>>
>> Making windmove into a regular (global) minor mode would be less
>> surprising, I think, but I'm not really familiar with windmove, and
>> whether that would be an easy rewrite?
>
> I have tried this out, and it seems somewhat elegant.  From my testing,
> it seems to behave the same way as the previous approach.
>
> -- 
> 	Philip K.
>
> From 2f7a8d89cdb5835cf875bc1f2bcfcb6755a0e0c0 Mon Sep 17 00:00:00 2001
> From: Philip Kaludercic <philipk@posteo.net>
> Date: Tue, 25 May 2021 11:47:51 +0200
> Subject: [PATCH] Improve windmove-*-default-keybindings fuctions
>
> * windmove.el (windmove-default-map): Add special map for windmove
> commands
> (windmove-mode): Add minor mode for activating windmove-default-map
> (windmove-install-defaults): Add general function for manipulating
> windmove-default-map
> (windmove-default-keybindings): Use windmove-install-defaults
> (windmove-display-default-keybindings): Use windmove-install-defaults
> (windmove-delete-default-keybindings): Use windmove-install-defaults
> (windmove-swap-states-default-keybindings): Use
> windmove-install-defaults
> ---
>  lisp/windmove.el | 84 ++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 63 insertions(+), 21 deletions(-)
>
> diff --git a/lisp/windmove.el b/lisp/windmove.el
> index e4ea8e0f69..5a81893bf9 100644
> --- a/lisp/windmove.el
> +++ b/lisp/windmove.el
> @@ -426,19 +426,46 @@ windmove-down
>  ;; I don't think these bindings will work on non-X terminals; you
>  ;; probably want to use different bindings in that case.
>  
> +(defvar windmove-default-map (make-sparse-keymap)
> +  "Map used by `windmove-install-defaults'.")
Sorry if I ask, but wouldn't ordinary windmove-mode-map do here?

Since it is a convention to have mode maps called modename-mode-maps,
if people would like to change, or add a binding in the windmove mode
they would probably automatically try to alter windmove-mode-map instead
of windmove-default-map.


> +(define-minor-mode windmove-mode
> +  "Global minor mode for default windmove commands."
> +  :keymap windmove-default-map
> +  :init-value t
> +  :global t)
> +
> +(defun windmove-install-defaults (modifiers alist)
> +  "Install keys as specified by ALIST.
> +Every element of ALIST has the form (FN KEY), where KEY is
> +appended to MODIFIERS, before installing the key.  Previous
> +bindings of FN are unbound."
> +  (dolist (bind alist)
> +    (when (or (memq (cadr bind) '(left right up down))
> +              (not (null modifiers)))
> +      (dolist (old (where-is-internal (car bind) windmove-default-map))
> +        (define-key windmove-default-map old nil))
> +      (define-key windmove-default-map
> +        (vector (append modifiers (cdr bind)))
> +        (car bind)))))
> +
>  ;;;###autoload
>  (defun windmove-default-keybindingsq (&optional modifiers)
>    "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)
> -  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
> -  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-left left)
> +                               (windmove-right right)
> +                               (windmove-up up)
> +                               (windmove-down down))))
>  
>  \f
>  ;;; Directional window display and selection
> @@ -546,17 +573,21 @@ 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)
> -  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
> -  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
> -  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
> -  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
> -  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-display-left left)
> +                               (windmove-display-right right)
> +                               (windmove-display-up up)
> +                               (windmove-display-down down)
> +                               (windmove-display-same-window ?0)
> +                               (windmove-display-new-frame ?f)
> +                               (windmove-display-new-tab ?t))))
>  
>  \f
>  ;;; Directional window deletion
> @@ -618,16 +649,22 @@ 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)
> -  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
> -  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-delete-left left)
> +                               (windmove-delete-right right)
> +                               (windmove-delete-up up)
> +                               (windmove-delete-down down))))
>  
>  \f
>  ;;; Directional window swap states
> @@ -673,14 +710,19 @@ 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)
> -  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
> -  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-swap-states-left left)
> +                               (windmove-swap-states-right right)
> +                               (windmove-swap-states-up up)
> +                               (windmove-swap-states-down down))))
>  
>  \f
>  (provide 'windmove)





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25  9:53                         ` Philip Kaludercic
  2021-05-25 11:16                           ` Arthur Miller
@ 2021-05-25 11:36                           ` Arthur Miller
  2021-05-25 11:46                             ` Philip Kaludercic
  2021-05-25 19:13                             ` Lars Ingebrigtsen
  2021-05-25 19:16                           ` Lars Ingebrigtsen
  2021-05-25 20:18                           ` Juri Linkov
  3 siblings, 2 replies; 59+ messages in thread
From: Arthur Miller @ 2021-05-25 11:36 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen, Juri Linkov

Philip Kaludercic <philipk@posteo.net> writes:

If you are already patching windmove.el, can you consider adding
bindings for these funcitions too (defined in window.el):

enlarge-window-horizontally
shrink-window-horizontally

As well as add these two wrappers for vertical operations:

#+begin_src emacs-lisp

;;;###autoload
(defun enlarge-window-vertically (delta)
  "Make selected window DELTA columns wider.
Interactively, if no argument is given, make selected window one
column wider."
  (interactive "p")
  (enlarge-window delta nil))

;;;###autoload
(defun shrink-window-vertically (delta)
  "Make selected window DELTA columns narrower.
Interactively, if no argument is given, make selected window one
column narrower."
  (interactive "p")
  (shrink-window delta nil))

#+end_src

I have been using those for long time myself since I prefer to do
everything from the keyboard. Maybe someone else finds them useful too;
they have been in my config on GH for long time.

> Lars Ingebrigtsen <larsi@gnus.org> writes:
>
>> Philip Kaludercic <philipk@posteo.net> writes:
>>
>>> The code should probably be refactored, moving more of the common
>>> functionality into it's own function, but I am primarily wondering if
>>> using emulation-mode-map-alists the way I am proposing it here is ok. Or
>>> should I prefer minor-mode-map-alist?
>>
>> Making windmove into a regular (global) minor mode would be less
>> surprising, I think, but I'm not really familiar with windmove, and
>> whether that would be an easy rewrite?
>
> I have tried this out, and it seems somewhat elegant.  From my testing,
> it seems to behave the same way as the previous approach.
>
> -- 
> 	Philip K.
>
> From 2f7a8d89cdb5835cf875bc1f2bcfcb6755a0e0c0 Mon Sep 17 00:00:00 2001
> From: Philip Kaludercic <philipk@posteo.net>
> Date: Tue, 25 May 2021 11:47:51 +0200
> Subject: [PATCH] Improve windmove-*-default-keybindings fuctions
>
> * windmove.el (windmove-default-map): Add special map for windmove
> commands
> (windmove-mode): Add minor mode for activating windmove-default-map
> (windmove-install-defaults): Add general function for manipulating
> windmove-default-map
> (windmove-default-keybindings): Use windmove-install-defaults
> (windmove-display-default-keybindings): Use windmove-install-defaults
> (windmove-delete-default-keybindings): Use windmove-install-defaults
> (windmove-swap-states-default-keybindings): Use
> windmove-install-defaults
> ---
>  lisp/windmove.el | 84 ++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 63 insertions(+), 21 deletions(-)
>
> diff --git a/lisp/windmove.el b/lisp/windmove.el
> index e4ea8e0f69..5a81893bf9 100644
> --- a/lisp/windmove.el
> +++ b/lisp/windmove.el
> @@ -426,19 +426,46 @@ windmove-down
>  ;; I don't think these bindings will work on non-X terminals; you
>  ;; probably want to use different bindings in that case.
>  
> +(defvar windmove-default-map (make-sparse-keymap)
> +  "Map used by `windmove-install-defaults'.")
> +
> +(define-minor-mode windmove-mode
> +  "Global minor mode for default windmove commands."
> +  :keymap windmove-default-map
> +  :init-value t
> +  :global t)
> +
> +(defun windmove-install-defaults (modifiers alist)
> +  "Install keys as specified by ALIST.
> +Every element of ALIST has the form (FN KEY), where KEY is
> +appended to MODIFIERS, before installing the key.  Previous
> +bindings of FN are unbound."
> +  (dolist (bind alist)
> +    (when (or (memq (cadr bind) '(left right up down))
> +              (not (null modifiers)))
> +      (dolist (old (where-is-internal (car bind) windmove-default-map))
> +        (define-key windmove-default-map old nil))
> +      (define-key windmove-default-map
> +        (vector (append modifiers (cdr bind)))
> +        (car bind)))))
> +
>  ;;;###autoload
>  (defun windmove-default-keybindingsq (&optional modifiers)
>    "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)
> -  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
> -  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-left left)
> +                               (windmove-right right)
> +                               (windmove-up up)
> +                               (windmove-down down))))
>  
>  \f
>  ;;; Directional window display and selection
> @@ -546,17 +573,21 @@ 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)
> -  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
> -  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
> -  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
> -  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
> -  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-display-left left)
> +                               (windmove-display-right right)
> +                               (windmove-display-up up)
> +                               (windmove-display-down down)
> +                               (windmove-display-same-window ?0)
> +                               (windmove-display-new-frame ?f)
> +                               (windmove-display-new-tab ?t))))
>  
>  \f
>  ;;; Directional window deletion
> @@ -618,16 +649,22 @@ 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)
> -  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
> -  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-delete-left left)
> +                               (windmove-delete-right right)
> +                               (windmove-delete-up up)
> +                               (windmove-delete-down down))))
>  
>  \f
>  ;;; Directional window swap states
> @@ -673,14 +710,19 @@ 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)
> -  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
> -  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-swap-states-left left)
> +                               (windmove-swap-states-right right)
> +                               (windmove-swap-states-up up)
> +                               (windmove-swap-states-down down))))
>  
>  \f
>  (provide 'windmove)





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 11:16                           ` Arthur Miller
@ 2021-05-25 11:42                             ` Philip Kaludercic
  2021-05-25 13:31                               ` Arthur Miller
  0 siblings, 1 reply; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-25 11:42 UTC (permalink / raw)
  To: Arthur Miller; +Cc: 41438, Lars Ingebrigtsen, Juri Linkov

Arthur Miller <arthur.miller@live.com> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>> +(defvar windmove-default-map (make-sparse-keymap)
>> +  "Map used by `windmove-install-defaults'.")
>
> Sorry if I ask, but wouldn't ordinary windmove-mode-map do here?

You are probably right -- my thought was that the minor mode exists for
the sake of the map.

> Since it is a convention to have mode maps called modename-mode-maps,
> if people would like to change, or add a binding in the windmove mode
> they would probably automatically try to alter windmove-mode-map instead
> of windmove-default-map.

That's the question: should windmove-default-map be accessed by default
or only via the -default-keybindings functions? Either way something
should be changed, if windmove-default-map it should be renamed to
windmove--default-map to explicitly mark it as an internal
map. Otherwise it should be renamed to windmove-mode-map as you suggest.

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  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
  1 sibling, 1 reply; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-25 11:46 UTC (permalink / raw)
  To: Arthur Miller; +Cc: 41438, Lars Ingebrigtsen, Juri Linkov

Arthur Miller <arthur.miller@live.com> writes:

> If you are already patching windmove.el, can you consider adding
> bindings for these funcitions too (defined in window.el):
>
> enlarge-window-horizontally
> shrink-window-horizontally
>
> As well as add these two wrappers for vertical operations:
>
> #+begin_src emacs-lisp
>
> ;;;###autoload
> (defun enlarge-window-vertically (delta)
>   "Make selected window DELTA columns wider.
> Interactively, if no argument is given, make selected window one
> column wider."
>   (interactive "p")
>   (enlarge-window delta nil))
>
> ;;;###autoload
> (defun shrink-window-vertically (delta)
>   "Make selected window DELTA columns narrower.
> Interactively, if no argument is given, make selected window one
> column narrower."
>   (interactive "p")
>   (shrink-window delta nil))
>
> #+end_src
>
> I have been using those for long time myself since I prefer to do
> everything from the keyboard. Maybe someone else finds them useful too;
> they have been in my config on GH for long time.

I am not sure if these commands should be added as part of the same
changeset. The point of this commit is to make configuring windmove keys
using windmove-default-keybindings & co. more consistent.

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 11:42                             ` Philip Kaludercic
@ 2021-05-25 13:31                               ` Arthur Miller
  2021-05-25 14:39                                 ` Philip Kaludercic
  0 siblings, 1 reply; 59+ messages in thread
From: Arthur Miller @ 2021-05-25 13:31 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen, Juri Linkov

Philip Kaludercic <philipk@posteo.net> writes:

> Arthur Miller <arthur.miller@live.com> writes:
>
>> Philip Kaludercic <philipk@posteo.net> writes:
>>> +(defvar windmove-default-map (make-sparse-keymap)
>>> +  "Map used by `windmove-install-defaults'.")
>>
>> Sorry if I ask, but wouldn't ordinary windmove-mode-map do here?
>
> You are probably right -- my thought was that the minor mode exists for
> the sake of the map.

Yeah, exactly in this case. I am not sure if I understand correctly, you
mean people will set new map for the mode to change bindings?

I just remarked on the name you choose for the mode map, most peeps like
me probably expect it to be names after the convention 'modename-mode-map'.

>> Since it is a convention to have mode maps called modename-mode-maps,
>> if people would like to change, or add a binding in the windmove mode
>> they would probably automatically try to alter windmove-mode-map instead
>> of windmove-default-map.
>
> That's the question: should windmove-default-map be accessed by default
> or only via the -default-keybindings functions? Either way something

I think you are thinking about default keybindings reather than default
map. If I assume correctly. If I understand corectly you would like to
preserve some default bindings, the map is just a mean to accomplish it.

> should be changed, if windmove-default-map it should be renamed to
> windmove--default-map to explicitly mark it as an internal
> map. Otherwise it shsould be renamed to windmove-mode-map as you suggest.

Either use default map stored some "default var", and add a function
that restores mode map, or just add a function that resets keybindings
into mode map directly, which might be sufficient. I don't know matter
of taste? A default mode map in a variable is cleaner but more costly?

Emacs provides windows, so I think there should also be a default way of
moving cursor between them, manipulate them and so on. Thus I think
windmove operations should be on by default, I don't think C-x 1/2/3/o
are satisfying when we have more then 2 widows.

A minor mode is probably a good balance between altering Emacs defaults,
so not break someones config, and to give people an option to easily
turn on some useful feature/configuration.






^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 11:46                             ` Philip Kaludercic
@ 2021-05-25 13:58                               ` Arthur Miller
  0 siblings, 0 replies; 59+ messages in thread
From: Arthur Miller @ 2021-05-25 13:58 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen, Juri Linkov

Philip Kaludercic <philipk@posteo.net> writes:

> Arthur Miller <arthur.miller@live.com> writes:
>
>> If you are already patching windmove.el, can you consider adding
>> bindings for these funcitions too (defined in window.el):
>>
>> enlarge-window-horizontally
>> shrink-window-horizontally
>>
>> As well as add these two wrappers for vertical operations:
>>
>> #+begin_src emacs-lisp
>>
>> ;;;###autoload
>> (defun enlarge-window-vertically (delta)
>>   "Make selected window DELTA columns wider.
>> Interactively, if no argument is given, make selected window one
>> column wider."
>>   (interactive "p")
>>   (enlarge-window delta nil))
>>
>> ;;;###autoload
>> (defun shrink-window-vertically (delta)
>>   "Make selected window DELTA columns narrower.
>> Interactively, if no argument is given, make selected window one
>> column narrower."
>>   (interactive "p")
>>   (shrink-window delta nil))
>>
>> #+end_src
>>
>> I have been using those for long time myself since I prefer to do
>> everything from the keyboard. Maybe someone else finds them useful too;
>> they have been in my config on GH for long time.
>
> I am not sure if these commands should be added as part of the same
> changeset.
Those two wrappers itself are not necessary to add, they are just they
for the sake of naming. It looks better and more clear what a binding
does in "whick-key" window, in help buffers, and provides better
symmetry to shrink/enlarge-window-horizontally.

original functions are all in window.el:

shrink-window
enlarge-window
shrink-window-horizontally
enlarge-window-horizontally

> The point of this commit is to make configuring windmove keys
> using windmove-default-keybindings & co. more consistent.

I completeley understand you are concentrated just on windmove keys.

This is just a suggestion. I think windmove should have probably be
named from the beginning as "windoperations", since it does more than
just move corsor between windows.

Shrinking and enlarging windows is definitely a useful window operation
to beind on a key, in my opinion should have been in windmove.el since
beginning.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 13:31                               ` Arthur Miller
@ 2021-05-25 14:39                                 ` Philip Kaludercic
  0 siblings, 0 replies; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-25 14:39 UTC (permalink / raw)
  To: Arthur Miller; +Cc: 41438, Lars Ingebrigtsen, Juri Linkov

Arthur Miller <arthur.miller@live.com> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>
>> Arthur Miller <arthur.miller@live.com> writes:
>>
>>> Philip Kaludercic <philipk@posteo.net> writes:
>>>> +(defvar windmove-default-map (make-sparse-keymap)
>>>> +  "Map used by `windmove-install-defaults'.")
>>>
>>> Sorry if I ask, but wouldn't ordinary windmove-mode-map do here?
>>
>> You are probably right -- my thought was that the minor mode exists for
>> the sake of the map.
>
> Yeah, exactly in this case. I am not sure if I understand correctly, you
> mean people will set new map for the mode to change bindings?

No, that is why the minor mode is active by default. The only reason the
minor mode is defined is to modify minor-mode-map-alist.

>> That's the question: should windmove-default-map be accessed by default
>> or only via the -default-keybindings functions? Either way something
>
> I think you are thinking about default keybindings reather than default
> map. If I assume correctly. If I understand corectly you would like to
> preserve some default bindings, the map is just a mean to accomplish it.

I am not sure what you are referring to, the map is manipulated by
windmove-install-defaults, which in turn is used by

* windmove-default-keybindings
* windmove-display-default-keybindings
* windmove-delete-default-keybindings
* windmove-swap-states-default-keybindings

So it is not just about preserving some default bindings, but ensuring
that the explicitly requested bindings are installed correctly.

>> should be changed, if windmove-default-map it should be renamed to
>> windmove--default-map to explicitly mark it as an internal
>> map. Otherwise it shsould be renamed to windmove-mode-map as you suggest.
>
> Either use default map stored some "default var", and add a function
> that restores mode map, or just add a function that resets keybindings
> into mode map directly, which might be sufficient. I don't know matter
> of taste? A default mode map in a variable is cleaner but more costly?
>
> Emacs provides windows, so I think there should also be a default way of
> moving cursor between them, manipulate them and so on. Thus I think
> windmove operations should be on by default, I don't think C-x 1/2/3/o
> are satisfying when we have more then 2 widows.
>
> A minor mode is probably a good balance between altering Emacs defaults,
> so not break someones config, and to give people an option to easily
> turn on some useful feature/configuration.

I'm sorry, either I am missing something or we are talking besides one
another.

-- 
	Philip K.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 11:36                           ` Arthur Miller
  2021-05-25 11:46                             ` Philip Kaludercic
@ 2021-05-25 19:13                             ` Lars Ingebrigtsen
  1 sibling, 0 replies; 59+ messages in thread
From: Lars Ingebrigtsen @ 2021-05-25 19:13 UTC (permalink / raw)
  To: Arthur Miller; +Cc: 41438, Philip Kaludercic, Juri Linkov

Arthur Miller <arthur.miller@live.com> writes:

> If you are already patching windmove.el, can you consider adding
> bindings for these funcitions too (defined in window.el):

This seems unrelated to this current bug report, but you could open a
new wishlist bug report for this.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25  9:53                         ` Philip Kaludercic
  2021-05-25 11:16                           ` Arthur Miller
  2021-05-25 11:36                           ` Arthur Miller
@ 2021-05-25 19:16                           ` Lars Ingebrigtsen
  2021-05-25 19:25                             ` Philip Kaludercic
  2021-05-25 20:18                           ` Juri Linkov
  3 siblings, 1 reply; 59+ messages in thread
From: Lars Ingebrigtsen @ 2021-05-25 19:16 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Juri Linkov

Philip Kaludercic <philipk@posteo.net> writes:

> I have tried this out, and it seems somewhat elegant.  From my testing,
> it seems to behave the same way as the previous approach.

Looks good to me.  One minor thing:

> +(defvar windmove-default-map (make-sparse-keymap)
> +  "Map used by `windmove-install-defaults'.")

This should be called -mode-map.

I don't actually use windmove -- could somebody else who's using this
try this patch out and see whether it works well for them?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 19:16                           ` Lars Ingebrigtsen
@ 2021-05-25 19:25                             ` Philip Kaludercic
  0 siblings, 0 replies; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-25 19:25 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 41438, Juri Linkov

[-- Attachment #1: Type: text/plain, Size: 684 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>
>> I have tried this out, and it seems somewhat elegant.  From my testing,
>> it seems to behave the same way as the previous approach.
>
> Looks good to me.  One minor thing:
>
>> +(defvar windmove-default-map (make-sparse-keymap)
>> +  "Map used by `windmove-install-defaults'.")
>
> This should be called -mode-map.

Ok, the patch is below. I also added warning this time to net people
know if automatically bound keys would conflict.

> I don't actually use windmove -- could somebody else who's using this
> try this patch out and see whether it works well for them?

-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-windmove-default-keybindings-fuctions.patch --]
[-- Type: text/x-diff, Size: 7733 bytes --]

From d572168a4fce653dcded2c4ca54f324dca78e280 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Tue, 25 May 2021 11:47:51 +0200
Subject: [PATCH] Improve windmove-*-default-keybindings fuctions

* windmove.el (windmove-mode-map): Add special map for windmove
commands
(windmove-mode): Add minor mode for activating windmove-mode-map
(windmove-install-defaults): Add general function for manipulating
windmove-mode-map
(windmove-default-keybindings): Use windmove-install-defaults
(windmove-display-default-keybindings): Use windmove-install-defaults
(windmove-delete-default-keybindings): Use windmove-install-defaults
(windmove-swap-states-default-keybindings): Use
windmove-install-defaults
---
 lisp/windmove.el | 80 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 59 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..479fdef512 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,42 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-mode-map (make-sparse-keymap)
+  "Map used by `windmove-install-defaults'.")
+
+(defun windmove-install-defaults (modifiers alist)
+  "Install keys as specified by ALIST.
+Every element of ALIST has the form (FN KEY), where KEY is
+appended to MODIFIERS, before installing the key.  Previous
+bindings of FN are unbound."
+  (dolist (bind alist)
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-mode-map))
+        (define-key windmove-mode-map old nil))
+      (let ((key (vector (append modifiers (cdr bind)))))
+        (let ((old-fn (lookup-key windmove-mode-map key)))
+          (when old-fn
+            (warn "Overriding %S with %S" old-fn (car bind))))
+        (define-key windmove-mode-map key (car bind))))))
+
 ;;;###autoload
 (defun windmove-default-keybindings (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-left left)
+                               (windmove-right right)
+                               (windmove-up up)
+                               (windmove-down down))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +569,21 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (windmove-install-defaults modifiers
+                             '((windmove-display-left left)
+                               (windmove-display-right right)
+                               (windmove-display-up up)
+                               (windmove-display-down down)
+                               (windmove-display-same-window ?0)
+                               (windmove-display-new-frame ?f)
+                               (windmove-display-new-tab ?t))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +645,22 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-delete-left left)
+                               (windmove-delete-right right)
+                               (windmove-delete-up up)
+                               (windmove-delete-down down))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +706,19 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (windmove-install-defaults modifiers
+                             '((windmove-swap-states-left left)
+                               (windmove-swap-states-right right)
+                               (windmove-swap-states-up up)
+                               (windmove-swap-states-down down))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25  9:53                         ` Philip Kaludercic
                                             ` (2 preceding siblings ...)
  2021-05-25 19:16                           ` Lars Ingebrigtsen
@ 2021-05-25 20:18                           ` Juri Linkov
  2021-05-25 21:45                             ` Philip Kaludercic
  3 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2021-05-25 20:18 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen

> -  (global-set-key (vector prefix (append modifiers '(left)))  'windmove-delete-left)
> -  (global-set-key (vector prefix (append modifiers '(right))) 'windmove-delete-right)
> -  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
> -  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
> +  (windmove-install-defaults modifiers
> +                             '((windmove-delete-left left)
> +                               (windmove-delete-right right)
> +                               (windmove-delete-up up)
> +                               (windmove-delete-down down))))

I haven't yet tested your patch, but after reading it seems 'prefix' is unused now?





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 20:18                           ` Juri Linkov
@ 2021-05-25 21:45                             ` Philip Kaludercic
  2021-05-26 21:35                               ` Juri Linkov
  0 siblings, 1 reply; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-25 21:45 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, Lars Ingebrigtsen

[-- Attachment #1: Type: text/plain, Size: 1177 bytes --]

Juri Linkov <juri@linkov.net> writes:

>> -  (global-set-key (vector prefix (append modifiers '(left)))  'windmove-delete-left)
>> -  (global-set-key (vector prefix (append modifiers '(right))) 'windmove-delete-right)
>> -  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
>> -  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
>> +  (windmove-install-defaults modifiers
>> +                             '((windmove-delete-left left)
>> +                               (windmove-delete-right right)
>> +                               (windmove-delete-up up)
>> +                               (windmove-delete-down down))))
>
> I haven't yet tested your patch, but after reading it seems 'prefix' is unused now?

You are right, I didn't test that specific function
properly. windmove-install-defaults had to be extended by another
argument to fix this.

What I don't really like is that only
windmove-delete-default-keybindings can make use of prefixes, while all
commands only use modifiers. Could it make sense to deprecate these
functions in favour of either new functions or user-options?

-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-windmove-default-keybindings-fuctions.patch --]
[-- Type: text/x-diff, Size: 8010 bytes --]

From ecbed85db9622ef5b1680472273163cb7789ae3f Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Tue, 25 May 2021 11:47:51 +0200
Subject: [PATCH] Improve windmove-*-default-keybindings fuctions

* windmove.el (windmove-mode-map): Add special map for windmove
commands
(windmove-mode): Add minor mode for activating windmove-mode-map
(windmove-install-defaults): Add general function for manipulating
windmove-mode-map
(windmove-default-keybindings): Use windmove-install-defaults
(windmove-display-default-keybindings): Use windmove-install-defaults
(windmove-delete-default-keybindings): Use windmove-install-defaults
(windmove-swap-states-default-keybindings): Use
windmove-install-defaults
---
 lisp/windmove.el | 87 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 66 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..d7c1d25d82 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,49 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-mode-map (make-sparse-keymap)
+  "Map used by `windmove-install-defaults'.")
+
+(define-minor-mode windmove-mode
+  "Global minor mode for default windmove commands."
+  :keymap windmove-mode-map
+  :init-value t
+  :global t)
+
+(defun windmove-install-defaults (prefix modifiers alist)
+  "Install keys as specified by ALIST.
+Every element of ALIST has the form (FN KEY), where KEY is
+appended to MODIFIERS, adding PREFIX to the beginning, before
+installing the key.  Previous bindings of FN are unbound."
+  (dolist (bind alist)
+    (when (or (memq (cadr bind) '(left right up down))
+              (not (null modifiers)))
+      (dolist (old (where-is-internal (car bind) windmove-mode-map))
+        (define-key windmove-mode-map old nil))
+      (let ((key (vconcat (if (eq prefix 'none) nil prefix)
+                          (list (append modifiers (cdr bind))))))
+        (let ((old-fn (lookup-key windmove-mode-map key)))
+          (when old-fn
+            (warn "Overriding %S with %S" old-fn (car bind))))
+        (define-key windmove-mode-map key (car bind))))))
+
 ;;;###autoload
 (defun windmove-default-keybindings (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-left left)
+                               (windmove-right right)
+                               (windmove-up up)
+                               (windmove-down down))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +576,21 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-display-left left)
+                               (windmove-display-right right)
+                               (windmove-display-up up)
+                               (windmove-display-down down)
+                               (windmove-display-same-window ?0)
+                               (windmove-display-new-frame ?f)
+                               (windmove-display-new-tab ?t))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +652,22 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (windmove-install-defaults prefix modifiers
+                             '((windmove-delete-left left)
+                               (windmove-delete-right right)
+                               (windmove-delete-up up)
+                               (windmove-delete-down down))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +713,19 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-swap-states-left left)
+                               (windmove-swap-states-right right)
+                               (windmove-swap-states-up up)
+                               (windmove-swap-states-down down))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-25 21:45                             ` Philip Kaludercic
@ 2021-05-26 21:35                               ` Juri Linkov
  2021-05-27 11:09                                 ` Philip Kaludercic
  0 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2021-05-26 21:35 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen

> What I don't really like is that only
> windmove-delete-default-keybindings can make use of prefixes, while all
> commands only use modifiers. Could it make sense to deprecate these
> functions in favour of either new functions or user-options?

Maybe it's possible to add new user options without deprecating the
existing functions?  Then for users an alternative way would be to
customize these options, and enable windmove-mode in the init file.
Or maybe there will be a need to create separate modes for every
keymap, e.g. windmove-display-mode, windmove-delete-mode?





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-26 21:35                               ` Juri Linkov
@ 2021-05-27 11:09                                 ` Philip Kaludercic
  2021-05-30 22:11                                   ` Juri Linkov
  0 siblings, 1 reply; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-27 11:09 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, Lars Ingebrigtsen

[-- Attachment #1: Type: text/plain, Size: 822 bytes --]

Juri Linkov <juri@linkov.net> writes:

>> What I don't really like is that only
>> windmove-delete-default-keybindings can make use of prefixes, while all
>> commands only use modifiers. Could it make sense to deprecate these
>> functions in favour of either new functions or user-options?
>
> Maybe it's possible to add new user options without deprecating the
> existing functions?  Then for users an alternative way would be to
> customize these options, and enable windmove-mode in the init file.

Of course, why not? The patches below should implement that.

> Or maybe there will be a need to create separate modes for every
> keymap, e.g. windmove-display-mode, windmove-delete-mode?

I don't see why that should be necessary, as the proposed windmove-mode
doesn't even have the interest the user.

-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-windmove-default-keybindings-fuctions.patch --]
[-- Type: text/x-diff, Size: 8244 bytes --]

From 42a66e87af83817b9e989624fdbf9c7ee7c347c7 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Tue, 25 May 2021 11:47:51 +0200
Subject: [PATCH 1/2] Improve windmove-*-default-keybindings fuctions

* windmove.el (windmove-mode-map): Add special map for windmove
commands
(windmove-mode): Add minor mode for activating windmove-mode-map
(windmove-install-defaults): Add general function for manipulating
windmove-mode-map
(windmove-default-keybindings): Use windmove-install-defaults
(windmove-display-default-keybindings): Use windmove-install-defaults
(windmove-delete-default-keybindings): Use windmove-install-defaults
(windmove-swap-states-default-keybindings): Use
windmove-install-defaults
---
 lisp/windmove.el | 91 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..cd8592f341 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,53 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-mode-map (make-sparse-keymap)
+  "Map used by `windmove-install-defaults'.")
+
+(define-minor-mode windmove-mode
+  "Global minor mode for default windmove commands."
+  :keymap windmove-mode-map
+  :init-value t
+  :global t)
+
+(defun windmove-install-defaults (prefix modifiers alist &optional uninstall)
+  "Install keys as specified by ALIST.
+Every element of ALIST has the form (FN KEY), where KEY is
+appended to MODIFIERS, adding PREFIX to the beginning, before
+installing the key.  Previous bindings of FN are unbound.
+If UNINSTALL is non-nil, just remove the keys from ALIST."
+  (dolist (bind alist)
+    (dolist (old (where-is-internal (car bind) windmove-mode-map))
+      (define-key windmove-mode-map old nil))
+    (unless uninstall
+      (let ((key (vconcat (if (or (equal prefix [ignore])
+                                  (eq prefix 'none))
+                              nil prefix)
+                          (list (append modifiers (cdr bind))))))
+        (when (eq (key-binding key) #'self-insert-command)
+          (warn "Command %S is shadowing self-insert-key" (car bind)))
+        (let ((old-fn (lookup-key windmove-mode-map key)))
+          (when old-fn
+            (warn "Overriding %S with %S" old-fn (car bind))))
+        (define-key windmove-mode-map key (car bind))))))
+
 ;;;###autoload
 (defun windmove-default-keybindings (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-left left)
+                               (windmove-right right)
+                               (windmove-up up)
+                               (windmove-down down))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +580,21 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-display-left left)
+                               (windmove-display-right right)
+                               (windmove-display-up up)
+                               (windmove-display-down down)
+                               (windmove-display-same-window ?0)
+                               (windmove-display-new-frame ?f)
+                               (windmove-display-new-tab ?t))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +656,22 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (windmove-install-defaults prefix modifiers
+                             '((windmove-delete-left left)
+                               (windmove-delete-right right)
+                               (windmove-delete-up up)
+                               (windmove-delete-down down))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +717,19 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-swap-states-left left)
+                               (windmove-swap-states-right right)
+                               (windmove-swap-states-up up)
+                               (windmove-swap-states-down down))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Add-user-options-for-default-windmove-commands.patch --]
[-- Type: text/x-diff, Size: 3780 bytes --]

From 21a8a8854249d24d62d4dd8e17c1f1d20de04fd6 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 27 May 2021 12:24:42 +0200
Subject: [PATCH 2/2] Add user options for default windmove commands

* windmove.el (windmove--default-keybindings-type): Add type
(windmove-default-keybindings): Add user option
(windmove-display-default-keybindings): Add user option
(windmove-delete-default-keybindings): Add user option
(windmove-swap-states-default-keybindings): Add user option
---
 lisp/windmove.el | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index cd8592f341..488962c063 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -731,6 +731,86 @@ windmove-swap-states-default-keybindings
                                (windmove-swap-states-up up)
                                (windmove-swap-states-down down))))
 
+\f
+
+(defconst windmove--default-keybindings-type
+  `(choice (const :tag "Don't bind" nil)
+           (cons :tag "Bind using"
+                 (key-sequence :tag "Prefix")
+                 (set :tag "Modifier"
+                      :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))))
+  "Customisation type for windmove modifiers.")
+
+(defcustom windmove-default-keybindings nil
+  "Default bindings for regular windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-left left)
+            (windmove-right right)
+            (windmove-up up)
+            (windmove-down down))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
+(defcustom windmove-display-default-keybindings nil
+  "Default bindings for display windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-display-left left)
+            (windmove-display-right right)
+            (windmove-display-up up)
+            (windmove-display-down down)
+            (windmove-display-same-window ?0)
+            (windmove-display-new-frame ?f)
+            (windmove-display-new-tab ?t))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
+(defcustom windmove-delete-default-keybindings nil
+  "Default bindings for delete windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-delete-left left)
+            (windmove-delete-right right)
+            (windmove-delete-up up)
+            (windmove-delete-down down))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
+(defcustom windmove-swap-states-default-keybindings nil
+  "Default bindings for swap-state windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-swap-states-left left)
+            (windmove-swap-states-right right)
+            (windmove-swap-states-up up)
+            (windmove-swap-states-down down))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
 \f
 (provide 'windmove)
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-27 11:09                                 ` Philip Kaludercic
@ 2021-05-30 22:11                                   ` Juri Linkov
  2021-05-31  8:50                                     ` Philip Kaludercic
  0 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2021-05-30 22:11 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen

>> Maybe it's possible to add new user options without deprecating the
>> existing functions?  Then for users an alternative way would be to
>> customize these options, and enable windmove-mode in the init file.
>
> Of course, why not? The patches below should implement that.

Thanks, I tried out your patches.  The customization saved them
in such format:

  '(windmove-default-keybindings '([ignore] hyper))
  '(windmove-delete-default-keybindings '("\30" hyper))
  '(windmove-display-default-keybindings '([ignore] meta hyper))
  '(windmove-swap-states-default-keybindings '([ignore] shift hyper))

But I guess it's not a problem that it saves nil as [ignore].

The real problem is that after replacing this with a manual configuration:

  (use-package windmove
    :custom
    (windmove-default-keybindings '(nil hyper))
    (windmove-delete-default-keybindings `(,(kbd "C-x") hyper))
    (windmove-display-default-keybindings '(nil meta hyper))
    (windmove-swap-states-default-keybindings '(nil shift hyper)))

Then every startup pops up the *Warnings* buffer with:

  Warning (emacs): Overriding 1 with windmove-delete-left [Disable showing] [Disable logging]

But still all keybindings work correctly.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-30 22:11                                   ` Juri Linkov
@ 2021-05-31  8:50                                     ` Philip Kaludercic
  2021-05-31 20:15                                       ` Juri Linkov
  0 siblings, 1 reply; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-31  8:50 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, Lars Ingebrigtsen

[-- Attachment #1: Type: text/plain, Size: 1891 bytes --]

Juri Linkov <juri@linkov.net> writes:

>>> Maybe it's possible to add new user options without deprecating the
>>> existing functions?  Then for users an alternative way would be to
>>> customize these options, and enable windmove-mode in the init file.
>>
>> Of course, why not? The patches below should implement that.
>
> Thanks, I tried out your patches.  The customization saved them
> in such format:
>
>   '(windmove-default-keybindings '([ignore] hyper))
>   '(windmove-delete-default-keybindings '("\30" hyper))
>   '(windmove-display-default-keybindings '([ignore] meta hyper))
>   '(windmove-swap-states-default-keybindings '([ignore] shift hyper))
>
> But I guess it's not a problem that it saves nil as [ignore].
>
> The real problem is that after replacing this with a manual configuration:
>
>   (use-package windmove
>     :custom
>     (windmove-default-keybindings '(nil hyper))
>     (windmove-delete-default-keybindings `(,(kbd "C-x") hyper))
>     (windmove-display-default-keybindings '(nil meta hyper))
>     (windmove-swap-states-default-keybindings '(nil shift hyper)))
>
> Then every startup pops up the *Warnings* buffer with:
>
>   Warning (emacs): Overriding 1 with windmove-delete-left [Disable showing] [Disable logging]
>
> But still all keybindings work correctly.

I was under the impression that this was fixed, but it turns out I did
not read the lookup-key doc string carefully enough:

        A number as value means KEY is "too long";
        that is, characters or symbols in it except for the last one
        fail to be a valid sequence of prefix characters in KEYMAP.
        The number is how many characters at the front of KEY
        it takes to reach a non-prefix key.

But this case can be safely ignored, as define-key will take care of the
prefix. To solve this, the warning is only trigged when a function is
over-riden.

-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-windmove-default-keybindings-fuctions.patch --]
[-- Type: text/x-diff, Size: 8244 bytes --]

From 42a66e87af83817b9e989624fdbf9c7ee7c347c7 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Tue, 25 May 2021 11:47:51 +0200
Subject: [PATCH 1/2] Improve windmove-*-default-keybindings fuctions

* windmove.el (windmove-mode-map): Add special map for windmove
commands
(windmove-mode): Add minor mode for activating windmove-mode-map
(windmove-install-defaults): Add general function for manipulating
windmove-mode-map
(windmove-default-keybindings): Use windmove-install-defaults
(windmove-display-default-keybindings): Use windmove-install-defaults
(windmove-delete-default-keybindings): Use windmove-install-defaults
(windmove-swap-states-default-keybindings): Use
windmove-install-defaults
---
 lisp/windmove.el | 91 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..cd8592f341 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,53 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-mode-map (make-sparse-keymap)
+  "Map used by `windmove-install-defaults'.")
+
+(define-minor-mode windmove-mode
+  "Global minor mode for default windmove commands."
+  :keymap windmove-mode-map
+  :init-value t
+  :global t)
+
+(defun windmove-install-defaults (prefix modifiers alist &optional uninstall)
+  "Install keys as specified by ALIST.
+Every element of ALIST has the form (FN KEY), where KEY is
+appended to MODIFIERS, adding PREFIX to the beginning, before
+installing the key.  Previous bindings of FN are unbound.
+If UNINSTALL is non-nil, just remove the keys from ALIST."
+  (dolist (bind alist)
+    (dolist (old (where-is-internal (car bind) windmove-mode-map))
+      (define-key windmove-mode-map old nil))
+    (unless uninstall
+      (let ((key (vconcat (if (or (equal prefix [ignore])
+                                  (eq prefix 'none))
+                              nil prefix)
+                          (list (append modifiers (cdr bind))))))
+        (when (eq (key-binding key) #'self-insert-command)
+          (warn "Command %S is shadowing self-insert-key" (car bind)))
+        (let ((old-fn (lookup-key windmove-mode-map key)))
+          (when old-fn
+            (warn "Overriding %S with %S" old-fn (car bind))))
+        (define-key windmove-mode-map key (car bind))))))
+
 ;;;###autoload
 (defun windmove-default-keybindings (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-left left)
+                               (windmove-right right)
+                               (windmove-up up)
+                               (windmove-down down))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +580,21 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-display-left left)
+                               (windmove-display-right right)
+                               (windmove-display-up up)
+                               (windmove-display-down down)
+                               (windmove-display-same-window ?0)
+                               (windmove-display-new-frame ?f)
+                               (windmove-display-new-tab ?t))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +656,22 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (windmove-install-defaults prefix modifiers
+                             '((windmove-delete-left left)
+                               (windmove-delete-right right)
+                               (windmove-delete-up up)
+                               (windmove-delete-down down))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +717,19 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-swap-states-left left)
+                               (windmove-swap-states-right right)
+                               (windmove-swap-states-up up)
+                               (windmove-swap-states-down down))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Add-user-options-for-default-windmove-commands.patch --]
[-- Type: text/x-diff, Size: 3780 bytes --]

From 21a8a8854249d24d62d4dd8e17c1f1d20de04fd6 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Thu, 27 May 2021 12:24:42 +0200
Subject: [PATCH 2/2] Add user options for default windmove commands

* windmove.el (windmove--default-keybindings-type): Add type
(windmove-default-keybindings): Add user option
(windmove-display-default-keybindings): Add user option
(windmove-delete-default-keybindings): Add user option
(windmove-swap-states-default-keybindings): Add user option
---
 lisp/windmove.el | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index cd8592f341..488962c063 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -731,6 +731,86 @@ windmove-swap-states-default-keybindings
                                (windmove-swap-states-up up)
                                (windmove-swap-states-down down))))
 
+\f
+
+(defconst windmove--default-keybindings-type
+  `(choice (const :tag "Don't bind" nil)
+           (cons :tag "Bind using"
+                 (key-sequence :tag "Prefix")
+                 (set :tag "Modifier"
+                      :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))))
+  "Customisation type for windmove modifiers.")
+
+(defcustom windmove-default-keybindings nil
+  "Default bindings for regular windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-left left)
+            (windmove-right right)
+            (windmove-up up)
+            (windmove-down down))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
+(defcustom windmove-display-default-keybindings nil
+  "Default bindings for display windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-display-left left)
+            (windmove-display-right right)
+            (windmove-display-up up)
+            (windmove-display-down down)
+            (windmove-display-same-window ?0)
+            (windmove-display-new-frame ?f)
+            (windmove-display-new-tab ?t))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
+(defcustom windmove-delete-default-keybindings nil
+  "Default bindings for delete windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-delete-left left)
+            (windmove-delete-right right)
+            (windmove-delete-up up)
+            (windmove-delete-down down))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
+(defcustom windmove-swap-states-default-keybindings nil
+  "Default bindings for swap-state windmove commands."
+  :set (lambda (sym val)
+         (windmove-install-defaults
+          (car val) (cdr val)
+          '((windmove-swap-states-left left)
+            (windmove-swap-states-right right)
+            (windmove-swap-states-up up)
+            (windmove-swap-states-down down))
+          (null val))
+         (set-default sym val))
+  :type windmove--default-keybindings-type
+  :version "28.1"
+  :group 'windmove)
+
 \f
 (provide 'windmove)
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-31  8:50                                     ` Philip Kaludercic
@ 2021-05-31 20:15                                       ` Juri Linkov
  2021-05-31 21:27                                         ` Philip Kaludercic
  0 siblings, 1 reply; 59+ messages in thread
From: Juri Linkov @ 2021-05-31 20:15 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen

> I was under the impression that this was fixed, but it turns out I did
> not read the lookup-key doc string carefully enough:
>
>         A number as value means KEY is "too long";
>         that is, characters or symbols in it except for the last one
>         fail to be a valid sequence of prefix characters in KEYMAP.
>         The number is how many characters at the front of KEY
>         it takes to reach a non-prefix key.
>
> But this case can be safely ignored, as define-key will take care of the
> prefix. To solve this, the warning is only trigged when a function is
> over-riden.

Did you intend to send a new patch?  (the patches attached were the same as previous)





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-31 20:15                                       ` Juri Linkov
@ 2021-05-31 21:27                                         ` Philip Kaludercic
  2021-06-03 20:36                                           ` Juri Linkov
  0 siblings, 1 reply; 59+ messages in thread
From: Philip Kaludercic @ 2021-05-31 21:27 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41438, Lars Ingebrigtsen

[-- Attachment #1: Type: text/plain, Size: 998 bytes --]

Juri Linkov <juri@linkov.net> writes:

>> I was under the impression that this was fixed, but it turns out I did
>> not read the lookup-key doc string carefully enough:
>>
>>         A number as value means KEY is "too long";
>>         that is, characters or symbols in it except for the last one
>>         fail to be a valid sequence of prefix characters in KEYMAP.
>>         The number is how many characters at the front of KEY
>>         it takes to reach a non-prefix key.
>>
>> But this case can be safely ignored, as define-key will take care of the
>> prefix. To solve this, the warning is only trigged when a function is
>> over-riden.
>
> Did you intend to send a new patch?  (the patches attached were the same as previous)

Oops, I must have forgotten to regenerate patches. The important
difference was

+        (let ((old-fn (lookup-key windmove-mode-map key)))
+          (when (functionp old-fn)
+            (warn "Overriding %S with %S" old-fn (car bind))))


-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-windmove-default-keybindings-fuctions.patch --]
[-- Type: text/x-diff, Size: 8256 bytes --]

From 7e31b789da74655e931adc937b5a22a48d4f676e Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Tue, 25 May 2021 11:47:51 +0200
Subject: [PATCH 1/2] Improve windmove-*-default-keybindings fuctions

* windmove.el (windmove-mode-map): Add special map for windmove
commands
(windmove-mode): Add minor mode for activating windmove-mode-map
(windmove-install-defaults): Add general function for manipulating
windmove-mode-map
(windmove-default-keybindings): Use windmove-install-defaults
(windmove-display-default-keybindings): Use windmove-install-defaults
(windmove-delete-default-keybindings): Use windmove-install-defaults
(windmove-swap-states-default-keybindings): Use
windmove-install-defaults
---
 lisp/windmove.el | 92 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 71 insertions(+), 21 deletions(-)

diff --git a/lisp/windmove.el b/lisp/windmove.el
index e4ea8e0f69..ba59e95624 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -426,19 +426,53 @@ windmove-down
 ;; I don't think these bindings will work on non-X terminals; you
 ;; probably want to use different bindings in that case.
 
+(defvar windmove-mode-map (make-sparse-keymap)
+  "Map used by `windmove-install-defaults'.")
+
+(define-minor-mode windmove-mode
+  "Global minor mode for default windmove commands."
+  :keymap windmove-mode-map
+  :init-value t
+  :global t)
+
+(defun windmove-install-defaults (prefix modifiers alist &optional uninstall)
+  "Install keys as specified by ALIST.
+Every element of ALIST has the form (FN KEY), where KEY is
+appended to MODIFIERS, adding PREFIX to the beginning, before
+installing the key.  Previous bindings of FN are unbound.
+If UNINSTALL is non-nil, just remove the keys from ALIST."
+  (dolist (bind alist)
+    (dolist (old (where-is-internal (car bind) windmove-mode-map))
+      (define-key windmove-mode-map old nil))
+    (unless uninstall
+      (let ((key (vconcat (if (or (equal prefix [ignore])
+                                  (eq prefix 'none))
+                              nil prefix)
+                          (list (append modifiers (cdr bind))))))
+        (when (eq (key-binding key) #'self-insert-command)
+          (warn "Command %S is shadowing self-insert-key" (car bind)))
+        (let ((old-fn (lookup-key windmove-mode-map key)))
+          (when (functionp old-fn)
+            (warn "Overriding %S with %S" old-fn (car bind))))
+        (define-key windmove-mode-map key (car bind))))))
+
 ;;;###autoload
 (defun windmove-default-keybindings (&optional modifiers)
   "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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-left left)
+                               (windmove-right right)
+                               (windmove-up up)
+                               (windmove-down down))))
 
 \f
 ;;; Directional window display and selection
@@ -546,17 +581,21 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
-  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window)
-  (global-set-key (vector (append modifiers '(?f)))    'windmove-display-new-frame)
-  (global-set-key (vector (append modifiers '(?t)))    'windmove-display-new-tab))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-display-left left)
+                               (windmove-display-right right)
+                               (windmove-display-up up)
+                               (windmove-display-down down)
+                               (windmove-display-same-window ?0)
+                               (windmove-display-new-frame ?f)
+                               (windmove-display-new-tab ?t))))
 
 \f
 ;;; Directional window deletion
@@ -618,16 +657,22 @@ 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)
-  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
-  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+  (windmove-install-defaults prefix modifiers
+                             '((windmove-delete-left left)
+                               (windmove-delete-right right)
+                               (windmove-delete-up up)
+                               (windmove-delete-down down))))
 
 \f
 ;;; Directional window swap states
@@ -673,14 +718,19 @@ 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)
-  (global-set-key (vector (append modifiers '(up)))    'windmove-swap-states-up)
-  (global-set-key (vector (append modifiers '(down)))  'windmove-swap-states-down))
+  (windmove-install-defaults nil modifiers
+                             '((windmove-swap-states-left left)
+                               (windmove-swap-states-right right)
+                               (windmove-swap-states-up up)
+                               (windmove-swap-states-down down))))
 
 \f
 (provide 'windmove)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 59+ messages in thread

* bug#41438: [PATCH] Allow windmove keys to be bound without prefix or modifiers
  2021-05-31 21:27                                         ` Philip Kaludercic
@ 2021-06-03 20:36                                           ` Juri Linkov
  0 siblings, 0 replies; 59+ messages in thread
From: Juri Linkov @ 2021-06-03 20:36 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: 41438, Lars Ingebrigtsen

tags 41438 fixed
close 41438 28.0.50
thanks

>> Did you intend to send a new patch?  (the patches attached were the same as previous)
>
> Oops, I must have forgotten to regenerate patches. The important
> difference was
>
> +        (let ((old-fn (lookup-key windmove-mode-map key)))
> +          (when (functionp old-fn)
> +            (warn "Overriding %S with %S" old-fn (car bind))))

Thanks, I've tested your patches, and everything work nicely.
So pushed now.





^ permalink raw reply	[flat|nested] 59+ messages in thread

* bug#35367: 26.2; `dired-copy-how-to-fn' and HOW-TO arg of `dired-create-files'
  2019-07-11  5:51   ` Mike Kupfer
  2019-07-11 14:04     ` Lars Ingebrigtsen
  2019-07-11 14:18     ` Drew Adams
@ 2022-01-22 14:43     ` Lars Ingebrigtsen
  2 siblings, 0 replies; 59+ messages in thread
From: Lars Ingebrigtsen @ 2022-01-22 14:43 UTC (permalink / raw)
  To: Mike Kupfer; +Cc: 35367

Mike Kupfer <mkupfer@alum.berkeley.edu> writes:

> The bit about
>
>    If it return value is a list, TARGET is a generalized
>     directory (e.g. some sort of archive).  The first element of
>     this list must be a function with at least four arguments:
>
> looks like it might be useful when the target is, for example, a tar
> file.  By default, copying a single file would replace the tar file.
> But this could be overridden (I think) to add or replace entries in the
> tar file.

I've now added something like this to the doc string in Emacs 29, and
that should hopefully clarify the use case slightly.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 59+ messages in thread

end of thread, other threads:[~2022-01-22 14:43 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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.
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]     ` <"Tue>
     [not found]       ` <09>
     [not found]         ` <Jul>
     [not found]           ` <2019>
     [not found]             ` <07:18:26>
     [not found]             ` <16:21:24>
     [not found]     ` <"Thu>
     [not found]     ` <"Thu,>

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).