emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[elpa] externals/vertico 6775e3e2eb 1/2: vertico-suspend: New experiment


From: ELPA Syncer
Subject: [elpa] externals/vertico 6775e3e2eb 1/2: vertico-suspend: New experimental extension
Date: Sat, 9 Sep 2023 06:58:57 -0400 (EDT)

branch: externals/vertico
commit 6775e3e2eb3178c8c8385a22da23124cb6a4cb6b
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>

    vertico-suspend: New experimental extension
---
 CHANGELOG.org                 |   1 +
 README.org                    |   1 +
 extensions/vertico-repeat.el  |  12 +++--
 extensions/vertico-suspend.el | 122 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 133 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.org b/CHANGELOG.org
index 7ae4610acf..e87138bfa0 100644
--- a/CHANGELOG.org
+++ b/CHANGELOG.org
@@ -4,6 +4,7 @@
 
 * Development
 
+- =vertico-suspend=: New experimental extension.
 - =vertico-directory-enter=: Exit with input if prefix argument is given. 
Mirrors
   the behavior of =vertico-exit=.
 - =vertico-mouse-map=: New keymap.
diff --git a/README.org b/README.org
index 2e867a217b..38442965c3 100644
--- a/README.org
+++ b/README.org
@@ -252,6 +252,7 @@ following extensions come with the Vertico ELPA package:
 - 
[[https://github.com/minad/vertico/blob/main/extensions/vertico-quick.el][vertico-quick]]:
 Commands to select using Avy-style quick keys.
 - 
[[https://github.com/minad/vertico/blob/main/extensions/vertico-repeat.el][vertico-repeat]]:
 The command =vertico-repeat= repeats the last completion session.
 - 
[[https://github.com/minad/vertico/blob/main/extensions/vertico-reverse.el][vertico-reverse]]:
 =vertico-reverse-mode= to reverse the display.
+- 
[[https://github.com/minad/vertico/blob/main/extensions/vertico-suspend.el][vertico-suspend]]:
 The command =vertico-suspend= suspends and restores the current session.
 - 
[[https://github.com/minad/vertico/blob/main/extensions/vertico-unobtrusive.el][vertico-unobtrusive]]:
 =vertico-unobtrusive-mode= displays only the topmost candidate.
 
 See the Commentary of those files for configuration details. With these
diff --git a/extensions/vertico-repeat.el b/extensions/vertico-repeat.el
index 2317ef8e4f..4418e059a7 100644
--- a/extensions/vertico-repeat.el
+++ b/extensions/vertico-repeat.el
@@ -31,13 +31,19 @@
 ;; `vertico-repeat-select' commands.  If the repeat commands are called
 ;; from an existing Vertico minibuffer session, only sessions
 ;; corresponding to the current minibuffer command are offered via
-;; completion.  It is necessary to register a minibuffer setup hook,
-;; which saves the Vertico state for repetition.  In order to save the
-;; history across Emacs sessions, enable `savehist-mode' and add
+;; completion.
+;;
+;; It is necessary to register a minibuffer setup hook, which saves
+;; the Vertico state for repetition.  In order to save the history
+;; across Emacs sessions, enable `savehist-mode' and add
 ;; `vertico-repeat-history' to `savehist-additional-variables'.
 ;;
 ;; (keymap-global-set "M-R" #'vertico-repeat)
 ;; (add-hook 'minibuffer-setup-hook #'vertico-repeat-save)
+;;
+;; See also the `vertico-suspend' extension which uses a different
+;; technique, relying on recursive minibuffers to suspend the current
+;; completion session temporarily while preserving the entire state.
 
 ;;; Code:
 
diff --git a/extensions/vertico-suspend.el b/extensions/vertico-suspend.el
new file mode 100644
index 0000000000..a0b92bff0c
--- /dev/null
+++ b/extensions/vertico-suspend.el
@@ -0,0 +1,122 @@
+;;; vertico-suspend.el --- Suspend the current Vertico session -*- 
lexical-binding: t -*-
+
+;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
+
+;; Author: Daniel Mendler <mail@daniel-mendler.de>
+;; Maintainer: Daniel Mendler <mail@daniel-mendler.de>
+;; Created: 2023
+;; Version: 0.1
+;; Package-Requires: ((emacs "27.1") (vertico "1.4"))
+;; Homepage: https://github.com/minad/vertico
+
+;; This file is part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package is a Vertico extension, which provides the
+;; `vertico-suspend' command to suspend the current Vertico completion
+;; session.  If `vertico-suspend' is called from within the currently
+;; active Vertico completion minibuffer, the completion session is
+;; suspended.  Otherwise the last session is restored.  It is possible
+;; to suspend multiple nested Vertico sessions.
+;;
+;; (keymap-global-set "M-S" #'vertico-suspend)
+;;
+;; The extension is currently experimental and may get removed again.
+;; See also the `vertico-repeat' extension which uses a different
+;; technique, storing a completion session history.
+;;
+;; The extension has the following known problems:
+;;
+;; * `vertico-suspend' has not been tested against all the other
+;;   Vertico extensions.
+;;
+;; * `vertico-suspend' restores the window configuration when resuming
+;;   and when `vertico-buffer' is used.  This can be seen as a
+;;   disturbance.  I think the behavior is not unexpected since
+;;   minibuffer exiting also changes the window configuration by
+;;   default.
+;;
+;; * `echo-keystrokes' does not work in recursive minibuffers.  This
+;;   issue cannot be fixed without modifying the C source of Emacs,
+;;   since Emacs disables echo in recursive minibuffers.
+;;
+;; * The function `set-minibuffer-message' is advised.  Maybe a more
+;;   elegant solution can be found to handle echo area messages?
+
+;;; Code:
+
+(require 'vertico)
+
+(defvar-local vertico-suspend--wc nil)
+(defvar-local vertico-suspend--ov nil)
+
+;;;###autoload
+(defun vertico-suspend ()
+  "Suspend the current completion session.
+If the command is invoked from within the Vertico minibuffer, the
+current session is suspended.  If the command is invoked from
+outside the minibuffer, the active minibuffer is either selected
+or the latest completion session is restored."
+  (interactive)
+  (unless enable-recursive-minibuffers
+    (user-error "Recursive minibuffers must be enabled"))
+  (if-let ((win (active-minibuffer-window))
+           (buf (window-buffer win))
+           ((buffer-local-value 'vertico--input buf)))
+      (cond
+       ((minibufferp)
+        (setq vertico-suspend--ov (make-overlay (point-min) (point-max) nil t 
t))
+        (overlay-put vertico-suspend--ov 'invisible t)
+        (overlay-put vertico-suspend--ov 'priority 1000)
+        (overlay-put vertico--candidates-ov 'before-string nil)
+        (overlay-put vertico--candidates-ov 'after-string nil)
+        (set-window-parameter win 'no-other-window t)
+        ;; vertico-buffer handling
+        (when (memq 'vertico-buffer--redisplay pre-redisplay-functions)
+          (remove-hook 'pre-redisplay-functions 'vertico-buffer--redisplay 
'local)
+          (setq-local cursor-in-non-selected-windows nil
+                      vertico-suspend--wc (current-window-configuration))
+          (dolist (w (get-buffer-window-list buf))
+            (unless (eq w win)
+              (delete-window w)))
+          (set-window-vscroll nil 0))
+        (unless (frame-root-window-p win)
+          (window-resize win (- (window-pixel-height win)) nil nil 'pixelwise))
+        (other-window 1))
+       (t
+        (select-window win)
+        (set-window-parameter win 'no-other-window nil)
+        (when vertico-suspend--ov
+          (delete-overlay vertico-suspend--ov)
+          (setq vertico-suspend--ov nil))
+        ;; vertico-buffer handling
+        (when vertico-suspend--wc
+          (add-hook 'pre-redisplay-functions 'vertico-buffer--redisplay nil 
'local)
+          (set-window-configuration vertico-suspend--wc nil t)
+          (setq vertico-suspend--wc nil))))
+    (user-error "No Vertico session to suspend or resume")))
+
+(defun vertico-suspend--message (&rest app)
+  "Show message in suspended minibuffer, otherwise apply APP."
+  (let ((win (active-minibuffer-window)))
+    (unless (buffer-local-value 'vertico-suspend--ov (window-buffer win))
+      (apply app))))
+
+(advice-add #'set-minibuffer-message :around #'vertico-suspend--message)
+
+(provide 'vertico-suspend)
+;;; vertico-suspend.el ends here



reply via email to

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