emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 2cf9d9f: * lisp/windmove.el: Directional window dis


From: Juri Linkov
Subject: [Emacs-diffs] master 2cf9d9f: * lisp/windmove.el: Directional window display (bug#32790)
Date: Thu, 15 Nov 2018 18:40:23 -0500 (EST)

branch: master
commit 2cf9d9fed7de87a7b78fbc75a67a71fff00e8ffc
Author: Juri Linkov <address@hidden>
Commit: Juri Linkov <address@hidden>

    * 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.
---
 etc/NEWS         |  12 +++++++
 lisp/windmove.el | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/etc/NEWS b/etc/NEWS
index 4f3b9a9..6e52f6c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -304,6 +304,18 @@ back, customize follow-hide-ghost-cursors to nil.
 
 ** Windmove
 
+*** Windmove supports directional window display and selection.
+The new command windmove-display-default-keybindings binds default
+keys with provided modifiers (by default, shift-meta) to the commands
+that display the next buffer in the window at the specified direction.
+This is like windmove-default-keybindings that binds keys to commands
+that select the window in the specified direction, but additionally it
+displays the buffer from the next command in that window.  For example,
+'S-M-right C-h i' displays the *Info* buffer in the right window,
+creating the window if necessary.  A special key can be customized to
+display the buffer in the same window, for example, 'S-M-0 C-h e'
+displays the *Messages* buffer in the same window.
+
 *** windmove-create-window when non-nil makes a new window on moving off
 the edge of the frame.
 
diff --git a/lisp/windmove.el b/lisp/windmove.el
index c38524f..898f87e 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)
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]