Let repeated windmove override motion restrictions interactively
* lisp/windmove.el (windmove-allow-all-windows): document feature (windmove-allow-repeated-command-override): new option (windmove-do-window-select, windmove-left, windmove-up, windmove-right) (windmove-down): pass interactive * etc/NEWS: mention feature
This commit is contained in:
parent
0972a54a5a
commit
c82495dea7
2 changed files with 79 additions and 21 deletions
6
etc/NEWS
6
etc/NEWS
|
@ -205,6 +205,12 @@ Several functions to modify the window layout have been added:
|
|||
'flip-window-layout-vertically', 'flip-window-layout-horizontally',
|
||||
'transpose-window-layout', 'rotate-windows', and 'rotate-windows-back'.
|
||||
|
||||
+++
|
||||
*** New user option 'windmove-allow-repeated-command-override'.
|
||||
This option controls whether pressing the same windmove command twice
|
||||
overrides the no-other-window property, allowing navigation to windows
|
||||
that would normally be skipped.
|
||||
|
||||
+++
|
||||
*** New hook 'window-deletable-functions'.
|
||||
This abnormal hook gives its client a way to save a window from getting
|
||||
|
|
|
@ -170,10 +170,19 @@ placement bugs in old versions of Emacs."
|
|||
"Whether the windmove commands are allowed to target all type of windows.
|
||||
If this variable is set to non-nil, all windmove commands will
|
||||
ignore the `no-other-window' parameter applied by `display-buffer-alist'
|
||||
or `set-window-parameter'."
|
||||
or `set-window-parameter'.
|
||||
|
||||
Another way to move into windows with the no-other-window property is
|
||||
by invoking the same movement command twice in succession when
|
||||
`windmove-allow-repeated-command-override' is true."
|
||||
:type 'boolean
|
||||
:version "28.1")
|
||||
|
||||
(defcustom windmove-allow-repeated-command-override t
|
||||
"Control whether pressing the same windmove command twice overrides the no-other-window property."
|
||||
:type 'boolean
|
||||
:version "31.1")
|
||||
|
||||
|
||||
;; Note:
|
||||
;;
|
||||
|
@ -359,21 +368,47 @@ use the left or top edge of WINDOW as reference point."
|
|||
|
||||
;; Selects the window that's hopefully at the location returned by
|
||||
;; `windmove-find-other-window', or screams if there's no window there.
|
||||
(defun windmove-do-window-select (dir &optional arg window)
|
||||
(defun windmove-do-window-select (dir &optional arg window calling-command)
|
||||
"Move to the window at direction DIR as seen from WINDOW.
|
||||
DIR, ARG, and WINDOW are handled as by `windmove-find-other-window'.
|
||||
If no window is at direction DIR, an error is signaled.
|
||||
If `windmove-create-window' is a function, call that function with
|
||||
DIR, ARG and WINDOW. If it is non-nil, try to create a new window
|
||||
in direction DIR instead."
|
||||
(let ((other-window (windmove-find-other-window dir arg window)))
|
||||
in direction DIR instead.
|
||||
|
||||
When the same windmove command is invoked twice in succession,
|
||||
the second invocation will override the `no-other-window' property.
|
||||
CALLING-COMMAND is the command that called this function, used to detect
|
||||
repeated commands."
|
||||
(let* ((repeated-command
|
||||
(and calling-command (eq last-command calling-command)))
|
||||
(other-window (windmove-find-other-window dir arg window)))
|
||||
|
||||
(when (and (null other-window)
|
||||
repeated-command windmove-allow-repeated-command-override)
|
||||
(setf other-window (window-in-direction dir window t arg windmove-wrap-around t)))
|
||||
|
||||
;; Create window if needed
|
||||
(when (and windmove-create-window
|
||||
(or (null other-window)
|
||||
(and (window-minibuffer-p other-window)
|
||||
(not (minibuffer-window-active-p other-window)))))
|
||||
(setq other-window (if (functionp windmove-create-window)
|
||||
(funcall windmove-create-window dir arg window)
|
||||
(split-window window nil dir))))
|
||||
(setf other-window
|
||||
(if (functionp windmove-create-window)
|
||||
(funcall windmove-create-window dir arg window)
|
||||
(split-window window nil dir))))
|
||||
|
||||
;; If we still don't have a window but could with allow-all-windows,
|
||||
;; fail with a helpful message.
|
||||
(when (and (null other-window)
|
||||
calling-command
|
||||
(not windmove-allow-all-windows)
|
||||
(not repeated-command)
|
||||
windmove-allow-repeated-command-override)
|
||||
(let ((test-window (window-in-direction dir window t arg windmove-wrap-around t)))
|
||||
(when test-window
|
||||
(user-error "No window %s (repeat to override)" dir))))
|
||||
|
||||
(cond ((null other-window)
|
||||
(user-error "No window %s from selected window" dir))
|
||||
((and (window-minibuffer-p other-window)
|
||||
|
@ -389,7 +424,7 @@ in direction DIR instead."
|
|||
;; `windmove-do-window-select', meant to be bound to keys.
|
||||
|
||||
;;;###autoload
|
||||
(defun windmove-left (&optional arg)
|
||||
(defun windmove-left (&optional arg is-interactive)
|
||||
"Select the window to the left of the current one.
|
||||
With no prefix argument, or with prefix argument equal to zero,
|
||||
\"left\" is relative to the position of point in the window; otherwise
|
||||
|
@ -397,35 +432,50 @@ it is relative to the top edge (for positive ARG) or the bottom edge
|
|||
\(for negative ARG) of the current window.
|
||||
If no window is at the desired location, an error is signaled
|
||||
unless `windmove-create-window' is non-nil and a new window is created."
|
||||
(interactive "P")
|
||||
(windmove-do-window-select 'left (and arg (prefix-numeric-value arg))))
|
||||
(interactive "P\np")
|
||||
(windmove-do-window-select
|
||||
'left (and arg (prefix-numeric-value arg)) nil
|
||||
(and is-interactive this-command)))
|
||||
|
||||
;;;###autoload
|
||||
(defun windmove-up (&optional arg)
|
||||
(defun windmove-up (&optional arg is-interactive)
|
||||
"Select the window above the current one.
|
||||
With no prefix argument, or with prefix argument equal to zero, \"up\"
|
||||
is relative to the position of point in the window; otherwise it is
|
||||
relative to the left edge (for positive ARG) or the right edge (for
|
||||
negative ARG) of the current window.
|
||||
If no window is at the desired location, an error is signaled
|
||||
unless `windmove-create-window' is non-nil and a new window is created."
|
||||
(interactive "P")
|
||||
(windmove-do-window-select 'up (and arg (prefix-numeric-value arg))))
|
||||
unless `windmove-create-window' is non-nil and a new window is created.
|
||||
|
||||
When this command is used twice in quick succession (within
|
||||
`windmove-double-command-timeout' seconds), the second invocation
|
||||
will override the `no-other-window' property of windows, allowing
|
||||
you to move to windows that would normally be skipped."
|
||||
(interactive "P\np")
|
||||
(windmove-do-window-select
|
||||
'up (and arg (prefix-numeric-value arg)) nil
|
||||
(and is-interactive this-command)))
|
||||
|
||||
;;;###autoload
|
||||
(defun windmove-right (&optional arg)
|
||||
(defun windmove-right (&optional arg is-interactive)
|
||||
"Select the window to the right of the current one.
|
||||
With no prefix argument, or with prefix argument equal to zero,
|
||||
\"right\" is relative to the position of point in the window;
|
||||
otherwise it is relative to the top edge (for positive ARG) or the
|
||||
bottom edge (for negative ARG) of the current window.
|
||||
If no window is at the desired location, an error is signaled
|
||||
unless `windmove-create-window' is non-nil and a new window is created."
|
||||
(interactive "P")
|
||||
(windmove-do-window-select 'right (and arg (prefix-numeric-value arg))))
|
||||
unless `windmove-create-window' is non-nil and a new window is created.
|
||||
|
||||
If `windmove-double-command-timeout' is set and a window exists in the
|
||||
requested direction that is marked with the no-other-window property, you
|
||||
can press this command twice in quick succession to override that property."
|
||||
(interactive "P\np")
|
||||
(windmove-do-window-select
|
||||
'right (and arg (prefix-numeric-value arg)) nil
|
||||
(and is-interactive this-command)))
|
||||
|
||||
;;;###autoload
|
||||
(defun windmove-down (&optional arg)
|
||||
(defun windmove-down (&optional arg is-interactive)
|
||||
"Select the window below the current one.
|
||||
With no prefix argument, or with prefix argument equal to zero,
|
||||
\"down\" is relative to the position of point in the window; otherwise
|
||||
|
@ -433,8 +483,10 @@ it is relative to the left edge (for positive ARG) or the right edge
|
|||
\(for negative ARG) of the current window.
|
||||
If no window is at the desired location, an error is signaled
|
||||
unless `windmove-create-window' is non-nil and a new window is created."
|
||||
(interactive "P")
|
||||
(windmove-do-window-select 'down (and arg (prefix-numeric-value arg))))
|
||||
(interactive "P\np")
|
||||
(windmove-do-window-select
|
||||
'down (and arg (prefix-numeric-value arg)) nil
|
||||
(and is-interactive this-command)))
|
||||
|
||||
|
||||
;;; set up keybindings
|
||||
|
|
Loading…
Add table
Reference in a new issue