diff options
author | Juri Linkov <juri@linkov.net> | 2018-11-16 01:40:15 +0200 |
---|---|---|
committer | Juri Linkov <juri@linkov.net> | 2018-11-16 01:40:15 +0200 |
commit | 2cf9d9fed7de87a7b78fbc75a67a71fff00e8ffc (patch) | |
tree | 07cd4db69ac3bda1f6705d1731e33b6268554adc /lisp/windmove.el | |
parent | f22a16ae066cc512322f115c2098837d74feeff8 (diff) | |
download | emacs-2cf9d9fed7de87a7b78fbc75a67a71fff00e8ffc.tar.gz emacs-2cf9d9fed7de87a7b78fbc75a67a71fff00e8ffc.tar.bz2 emacs-2cf9d9fed7de87a7b78fbc75a67a71fff00e8ffc.zip |
* lisp/windmove.el: Directional window display (bug#32790)
* lisp/windmove.el (windmove-display-no-select): New defcustom.
(windmove-display-in-direction, windmove-display-left)
(windmove-display-up, windmove-display-right)
(windmove-display-down, windmove-display-same-window)
(windmove-display-default-keybindings): New functions.
Diffstat (limited to 'lisp/windmove.el')
-rw-r--r-- | lisp/windmove.el | 108 |
1 files changed, 107 insertions, 1 deletions
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 @@ -;;; windmove.el --- directional window-selection routines +;;; windmove.el --- directional window-selection routines -*- lexical-binding:t -*- ;; ;; Copyright (C) 1998-2018 Free Software Foundation, Inc. ;; @@ -571,6 +571,112 @@ Default value of MODIFIERS is `shift'." (global-set-key (vector (append modifiers '(up))) 'windmove-up) (global-set-key (vector (append modifiers '(down))) 'windmove-down)) +;;; Directional window display and selection + +(defcustom windmove-display-no-select nil + "Whether the window should be selected after displaying the buffer in it." + :type 'boolean + :group 'windmove + :version "27.1") + +(defun windmove-display-in-direction (dir &optional arg) + "Display the next buffer in the window at direction DIR. +The next buffer is the buffer displayed by the next command invoked +immediately after this command (ignoring reading from the minibuffer). +Create a new window if there is no window in that direction. +By default, select the window with a displayed buffer. +If prefix ARG is `C-u', reselect a previously selected window. +If `windmove-display-no-select' is non-nil, this command doesn't +select the window with a displayed buffer, and the meaning of +the prefix argument is reversed." + (let* ((no-select (not (eq (consp arg) windmove-display-no-select))) ; xor + (old-window (or (minibuffer-selected-window) (selected-window))) + (new-window) + (minibuffer-depth (minibuffer-depth)) + (action display-buffer-overriding-action) + (command this-command) + (clearfun (make-symbol "clear-display-buffer-overriding-action")) + (exitfun + (lambda () + (setq display-buffer-overriding-action action) + (when (window-live-p (if no-select old-window new-window)) + (select-window (if no-select old-window new-window))) + (remove-hook 'post-command-hook clearfun)))) + (fset clearfun + (lambda () + (unless (or + ;; Remove the hook immediately + ;; after exiting the minibuffer. + (> (minibuffer-depth) minibuffer-depth) + ;; But don't remove immediately after + ;; adding the hook by the same command below. + (eq this-command command)) + (funcall exitfun)))) + (add-hook 'post-command-hook clearfun) + (push (lambda (buffer alist) + (unless (> (minibuffer-depth) minibuffer-depth) + (let ((window (if (eq dir 'same-window) + (selected-window) + (window-in-direction + dir nil nil + (and arg (prefix-numeric-value arg)) + windmove-wrap-around))) + (type 'reuse)) + (unless window + (setq window (split-window nil nil dir) type 'window)) + (setq new-window (window--display-buffer buffer window type alist))))) + display-buffer-overriding-action) + (message "[display-%s]" dir))) + +;;;###autoload +(defun windmove-display-left (&optional arg) + "Display the next buffer in window to the left of the current one. +See the logic of the prefix ARG in `windmove-display-in-direction'." + (interactive "P") + (windmove-display-in-direction 'left arg)) + +;;;###autoload +(defun windmove-display-up (&optional arg) + "Display the next buffer in window above the current one. +See the logic of the prefix ARG in `windmove-display-in-direction'." + (interactive "P") + (windmove-display-in-direction 'up arg)) + +;;;###autoload +(defun windmove-display-right (&optional arg) + "Display the next buffer in window to the right of the current one. +See the logic of the prefix ARG in `windmove-display-in-direction'." + (interactive "P") + (windmove-display-in-direction 'right arg)) + +;;;###autoload +(defun windmove-display-down (&optional arg) + "Display the next buffer in window below the current one. +See the logic of the prefix ARG in `windmove-display-in-direction'." + (interactive "P") + (windmove-display-in-direction 'down arg)) + +;;;###autoload +(defun windmove-display-same-window (&optional arg) + "Display the next buffer in the same window." + (interactive "P") + (windmove-display-in-direction 'same-window arg)) + +;;;###autoload +(defun windmove-display-default-keybindings (&optional modifiers) + "Set up keybindings for directional buffer display. +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. +Default value of MODIFIERS is `shift-meta'." + (interactive) + (unless modifiers (setq modifiers '(shift meta))) + (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)) (provide 'windmove) |