[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