GNU bug report logs - #34656
27.0.50; Directional window swap states

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> linkov.net>

Date: Mon, 25 Feb 2019 21:14:03 UTC

Severity: wishlist

Tags: patch

Found in version 27.0.50

Done: Juri Linkov <juri <at> linkov.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 34656 in the body.
You can then email your comments to 34656 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#34656; Package emacs. (Mon, 25 Feb 2019 21:14:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to Juri Linkov <juri <at> linkov.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 25 Feb 2019 21:14:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: bug-gnu-emacs <at> gnu.org
Subject: 27.0.50; Directional window swap states
Date: Mon, 25 Feb 2019 22:51:06 +0200
[Message part 1 (text/plain, inline)]
Tags: patch
Severity: wishlist

Now we have a useful command ‘window-swap-states’ whose only drawback is that
it operates on a random window, i.e. a next window in some mystic cyclic ordering
whose logic I've never been able to understand.

To simplify its logic, windmove could be extended to support directional swapping
where the user can point at the window whose state should be swapped
with the selected window.

As a funny effect, when windows are arranged as 4x4 square tiles, e.g.

(window-state-put
 '(()
   hc
   (vc
    (leaf (buffer "1"))
    (leaf (buffer "5"))
    (leaf (buffer "9"))
    (leaf (buffer "13")))
   (vc
    (leaf (buffer "2"))
    (leaf (buffer "6"))
    (leaf (buffer "10"))
    (leaf (buffer "14")))
   (vc
    (leaf (buffer "3"))
    (leaf (buffer "7"))
    (leaf (buffer "11"))
    (leaf (buffer "15")))
   (vc
    (leaf (buffer "4"))
    (leaf (buffer "8"))
    (leaf (buffer "12"))
    (leaf (buffer " "))))
 (frame-root-window))

sliding them has the same feeling like solving the 15 puzzle :)

[windmove-swap-states.patch (text/x-diff, inline)]
diff --git a/lisp/windmove.el b/lisp/windmove.el
index 65270d9bbe..e2422a7df4 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -750,6 +752,60 @@ 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))
 
+
+;;; Directional window swap states
+
+(defun windmove-swap-states-in-direction (dir)
+  "Swap the states of the selected window and the window at direction DIR.
+When `windmove-wrap-around' is non-nil, takes the window
+from the opposite side of the frame."
+  (let ((other-window (window-in-direction dir nil nil nil
+                                           windmove-wrap-around t)))
+    (cond ((null other-window)
+           (user-error "No window %s from selected window" dir))
+          (t
+           (window-swap-states nil other-window)))))
+
+;;;###autoload
+(defun windmove-swap-states-left ()
+  "Swap the states with the window on the left from the current one."
+  (interactive)
+  (windmove-swap-states-in-direction 'left))
+
+;;;###autoload
+(defun windmove-swap-states-up ()
+  "Swap the states with the window above from the current one."
+  (interactive)
+  (windmove-swap-states-in-direction 'up))
+
+;;;###autoload
+(defun windmove-swap-states-down ()
+  "Swap the states with the window below from the current one."
+  (interactive)
+  (windmove-swap-states-in-direction 'down))
+
+;;;###autoload
+(defun windmove-swap-states-right ()
+  "Swap the states with the window on the right from the current one."
+  (interactive)
+  (windmove-swap-states-in-direction 'right))
+
+;;;###autoload
+(defun windmove-swap-states-default-keybindings (&optional modifiers)
+  "Set up keybindings for directional window swap states.
+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'."
+  (interactive)
+  (unless modifiers (setq modifiers '(shift super)))
+  (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))
+
+
 (provide 'windmove)
 
 ;;; windmove.el ends here

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#34656; Package emacs. (Tue, 26 Feb 2019 09:11:03 GMT) Full text and rfc822 format available.

Message #8 received at 34656 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>, 34656 <at> debbugs.gnu.org
Subject: Re: bug#34656: 27.0.50; Directional window swap states
Date: Tue, 26 Feb 2019 10:10:11 +0100
+  (let ((other-window (window-in-direction dir nil nil nil
+                                           windmove-wrap-around t)))

If 'windmove-wrap-around' is nil, this may swap the selected window's
state with that of the minibuffer window.  Or am I misinterpreting?

martin





Reply sent to Juri Linkov <juri <at> linkov.net>:
You have taken responsibility. (Wed, 27 Feb 2019 21:14:03 GMT) Full text and rfc822 format available.

Notification sent to Juri Linkov <juri <at> linkov.net>:
bug acknowledged by developer. (Wed, 27 Feb 2019 21:14:04 GMT) Full text and rfc822 format available.

Message #13 received at 34656-done <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 34656-done <at> debbugs.gnu.org
Subject: Re: bug#34656: 27.0.50; Directional window swap states
Date: Wed, 27 Feb 2019 23:12:16 +0200
> +  (let ((other-window (window-in-direction dir nil nil nil
> +                                           windmove-wrap-around t)))
>
> If 'windmove-wrap-around' is nil, this may swap the selected window's
> state with that of the minibuffer window.  Or am I misinterpreting?

Thanks for the review.  Now I fixed the minibuffer case and closed this request.

Before this fix, trying to swap states with the minibuffer failed with the error:

  (error "Window #<window 4 on  *Minibuf-0*> too small to accommodate state")

Now after the fix, it doesn't consider the minibuffer as a candidate to swap states.

BTW, before proposing the implementation in windmove, the first idea was
to improve the logic of finding the second window in window-swap-states like:

diff --git a/lisp/window.el b/lisp/window.el
index 80828bb35c..3961ec3975 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -6018,7 +6018,10 @@ window-swap-states
   (if window-2
       (unless (window-live-p window-2)
         (error "%s is not a live window" window-2))
-    (setq window-2 (next-window window-1 'nomini 'visible)))
+    (setq window-2 (or (get-mru-window 'visible t t)
+                       (get-mru-window 0 t t)
+                       (get-mru-window t t t)
+                       (next-window window-1 'nomini 'visible))))
   (unless (eq window-1 window-2)
     (let* ((height (memq size '(t height)))
            (width (memq size '(t width)))

This logic is like finding the second window in
`compare-windows-get-recent-window'.

But since directional swapping in windmove is more convenient,
it seems the above change is not needed.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Thu, 28 Mar 2019 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 5 years and 24 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.