aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/NEWS12
-rw-r--r--lisp/windmove.el108
2 files changed, 119 insertions, 1 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 4f3b9a9a061..6e52f6cd1fa 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -304,6 +304,18 @@ back, customize follow-hide-ghost-cursors to nil.
304 304
305** Windmove 305** Windmove
306 306
307*** Windmove supports directional window display and selection.
308The new command windmove-display-default-keybindings binds default
309keys with provided modifiers (by default, shift-meta) to the commands
310that display the next buffer in the window at the specified direction.
311This is like windmove-default-keybindings that binds keys to commands
312that select the window in the specified direction, but additionally it
313displays the buffer from the next command in that window. For example,
314'S-M-right C-h i' displays the *Info* buffer in the right window,
315creating the window if necessary. A special key can be customized to
316display the buffer in the same window, for example, 'S-M-0 C-h e'
317displays the *Messages* buffer in the same window.
318
307*** windmove-create-window when non-nil makes a new window on moving off 319*** windmove-create-window when non-nil makes a new window on moving off
308the edge of the frame. 320the edge of the frame.
309 321
diff --git a/lisp/windmove.el b/lisp/windmove.el
index c38524fede6..898f87e2dbf 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -1,4 +1,4 @@
1;;; windmove.el --- directional window-selection routines 1;;; windmove.el --- directional window-selection routines -*- lexical-binding:t -*-
2;; 2;;
3;; Copyright (C) 1998-2018 Free Software Foundation, Inc. 3;; Copyright (C) 1998-2018 Free Software Foundation, Inc.
4;; 4;;
@@ -571,6 +571,112 @@ Default value of MODIFIERS is `shift'."
571 (global-set-key (vector (append modifiers '(up))) 'windmove-up) 571 (global-set-key (vector (append modifiers '(up))) 'windmove-up)
572 (global-set-key (vector (append modifiers '(down))) 'windmove-down)) 572 (global-set-key (vector (append modifiers '(down))) 'windmove-down))
573 573
574;;; Directional window display and selection
575
576(defcustom windmove-display-no-select nil
577 "Whether the window should be selected after displaying the buffer in it."
578 :type 'boolean
579 :group 'windmove
580 :version "27.1")
581
582(defun windmove-display-in-direction (dir &optional arg)
583 "Display the next buffer in the window at direction DIR.
584The next buffer is the buffer displayed by the next command invoked
585immediately after this command (ignoring reading from the minibuffer).
586Create a new window if there is no window in that direction.
587By default, select the window with a displayed buffer.
588If prefix ARG is `C-u', reselect a previously selected window.
589If `windmove-display-no-select' is non-nil, this command doesn't
590select the window with a displayed buffer, and the meaning of
591the prefix argument is reversed."
592 (let* ((no-select (not (eq (consp arg) windmove-display-no-select))) ; xor
593 (old-window (or (minibuffer-selected-window) (selected-window)))
594 (new-window)
595 (minibuffer-depth (minibuffer-depth))
596 (action display-buffer-overriding-action)
597 (command this-command)
598 (clearfun (make-symbol "clear-display-buffer-overriding-action"))
599 (exitfun
600 (lambda ()
601 (setq display-buffer-overriding-action action)
602 (when (window-live-p (if no-select old-window new-window))
603 (select-window (if no-select old-window new-window)))
604 (remove-hook 'post-command-hook clearfun))))
605 (fset clearfun
606 (lambda ()
607 (unless (or
608 ;; Remove the hook immediately
609 ;; after exiting the minibuffer.
610 (> (minibuffer-depth) minibuffer-depth)
611 ;; But don't remove immediately after
612 ;; adding the hook by the same command below.
613 (eq this-command command))
614 (funcall exitfun))))
615 (add-hook 'post-command-hook clearfun)
616 (push (lambda (buffer alist)
617 (unless (> (minibuffer-depth) minibuffer-depth)
618 (let ((window (if (eq dir 'same-window)
619 (selected-window)
620 (window-in-direction
621 dir nil nil
622 (and arg (prefix-numeric-value arg))
623 windmove-wrap-around)))
624 (type 'reuse))
625 (unless window
626 (setq window (split-window nil nil dir) type 'window))
627 (setq new-window (window--display-buffer buffer window type alist)))))
628 display-buffer-overriding-action)
629 (message "[display-%s]" dir)))
630
631;;;###autoload
632(defun windmove-display-left (&optional arg)
633 "Display the next buffer in window to the left of the current one.
634See the logic of the prefix ARG in `windmove-display-in-direction'."
635 (interactive "P")
636 (windmove-display-in-direction 'left arg))
637
638;;;###autoload
639(defun windmove-display-up (&optional arg)
640 "Display the next buffer in window above the current one.
641See the logic of the prefix ARG in `windmove-display-in-direction'."
642 (interactive "P")
643 (windmove-display-in-direction 'up arg))
644
645;;;###autoload
646(defun windmove-display-right (&optional arg)
647 "Display the next buffer in window to the right of the current one.
648See the logic of the prefix ARG in `windmove-display-in-direction'."
649 (interactive "P")
650 (windmove-display-in-direction 'right arg))
651
652;;;###autoload
653(defun windmove-display-down (&optional arg)
654 "Display the next buffer in window below the current one.
655See the logic of the prefix ARG in `windmove-display-in-direction'."
656 (interactive "P")
657 (windmove-display-in-direction 'down arg))
658
659;;;###autoload
660(defun windmove-display-same-window (&optional arg)
661 "Display the next buffer in the same window."
662 (interactive "P")
663 (windmove-display-in-direction 'same-window arg))
664
665;;;###autoload
666(defun windmove-display-default-keybindings (&optional modifiers)
667 "Set up keybindings for directional buffer display.
668Keys are bound to commands that display the next buffer in the specified
669direction. Keybindings are of the form MODIFIERS-{left,right,up,down},
670where MODIFIERS is either a list of modifiers or a single modifier.
671Default value of MODIFIERS is `shift-meta'."
672 (interactive)
673 (unless modifiers (setq modifiers '(shift meta)))
674 (unless (listp modifiers) (setq modifiers (list modifiers)))
675 (global-set-key (vector (append modifiers '(left))) 'windmove-display-left)
676 (global-set-key (vector (append modifiers '(right))) 'windmove-display-right)
677 (global-set-key (vector (append modifiers '(up))) 'windmove-display-up)
678 (global-set-key (vector (append modifiers '(down))) 'windmove-display-down)
679 (global-set-key (vector (append modifiers '(?0))) 'windmove-display-same-window))
574 680
575(provide 'windmove) 681(provide 'windmove)
576 682