>From 10ae067b0590884c7df6854ca04a1863782c368c Mon Sep 17 00:00:00 2001 From: Nicholas Vollmer Date: Fri, 7 Jun 2024 22:11:16 -0400 Subject: [PATCH] lisp/textmodes/string-edit.el: refactor as minor mode --- lisp/textmodes/string-edit.el | 82 +++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/lisp/textmodes/string-edit.el b/lisp/textmodes/string-edit.el index 03be426ac25..0eeba50b8ed 100644 --- a/lisp/textmodes/string-edit.el +++ b/lisp/textmodes/string-edit.el @@ -23,20 +23,22 @@ ;;; Code: -(require 'cl-lib) - (defface string-edit-prompt '((t (:inherit font-lock-comment-face))) "Face used on `string-edit' help text." :group 'text :version "29.1") -(defvar string-edit--success-callback) -(defvar string-edit--abort-callback) +(defvar-local string-edit--success-callback nil) +(put 'string-edit--success-callback 'permanent-local t) +(defvar-local string-edit--abort-callback nil) +(put 'string-edit--abort-callback 'permanent-local t) +(defvar-local string-edit--prompt nil) +(put 'string-edit--prompt 'permanent-local t) + ;;;###autoload -(cl-defun string-edit (prompt string success-callback - &key abort-callback) +(defun string-edit (prompt string success-callback &optional abort-callback) "Switch to a new buffer to edit STRING. When the user finishes editing (with \\\\[string-edit-done]), SUCCESS-CALLBACK is called with the resulting string. @@ -50,36 +52,16 @@ string-edit Also see `read-string-from-buffer'." (with-current-buffer (generate-new-buffer "*edit string*") - (when prompt - (let ((inhibit-read-only t)) - (insert prompt) - (ensure-empty-lines 0) - (add-text-properties (point-min) (point) - (list 'intangible t - 'face 'string-edit-prompt - 'read-only t)) - (insert (propertize (make-separator-line) 'rear-nonsticky t)) - (add-text-properties (point-min) (point) - (list 'string-edit--prompt t)))) - (let ((start (point))) - (insert string) - (goto-char start)) - + (setq string-edit--prompt prompt + string-edit--success-callback success-callback + string-edit--abort-callback (or abort-callback #'ignore)) + (string-edit-mode) + (save-excursion (insert string)) ;; Use `fit-window-to-buffer' after the buffer is filled with text. (pop-to-buffer (current-buffer) '(display-buffer-below-selected (window-height . (lambda (window) (fit-window-to-buffer window nil 10))))) - - (set-buffer-modified-p nil) - (setq buffer-undo-list nil) - (string-edit-mode) - (setq-local string-edit--success-callback success-callback) - (when abort-callback - (setq-local string-edit--abort-callback abort-callback)) - (setq-local header-line-format - (substitute-command-keys - "Type \\\\[string-edit-done] when you've finished editing or \\[string-edit-abort] to abort")) (message "%s" (substitute-command-keys "Type \\\\[string-edit-done] when you've finished editing")))) @@ -99,9 +81,9 @@ read-string-from-buffer (lambda (edited) (setq string edited) (exit-recursive-edit)) - :abort-callback (lambda () - (exit-recursive-edit) - (error "Aborted edit"))) + (lambda () + (exit-recursive-edit) + (error "Aborted edit"))) (recursive-edit) string) @@ -109,9 +91,35 @@ string-edit-mode-map "C-c C-c" #'string-edit-done "C-c C-k" #'string-edit-abort) -(define-derived-mode string-edit-mode text-mode "String" - "Mode for editing strings." - :interactive nil) +(defun string-edit--prepare-buffer () + "Prepare `string-edit-mode' buffer." + (with-silent-modifications + (when string-edit--prompt + (insert (propertize " " 'intangible t 'read-only t)) + (let ((o (make-overlay (point-min) (point-max)))) + (overlay-put o 'display + (concat (propertize string-edit--prompt 'face 'string-edit-prompt) + "\n" + (propertize "\n" 0 1 'face '(:inherit separator-line :extend t)))) + (overlay-put o 'evaporate nil) + (insert (propertize "\n" 'string-edit--prompt t 'read-only t 'rear-nonsticky t 'intangible t 'front-sticky t))) + (setq string-edit--prompt nil)) + (setq header-line-format + (substitute-command-keys + "Type \\\\[string-edit-done] when you've finished editing or \\[string-edit-abort] to abort")) + (setq buffer-undo-list nil))) + +(define-minor-mode string-edit-mode + "Minor mode for editing strings in a dedicated buffer." + :lighter " string-edit" + (cond + (string-edit-mode + (add-hook 'after-change-major-mode-hook #'string-edit-mode nil t) + (put 'after-change-major-mode-hook 'permanent-local t) + (string-edit--prepare-buffer)) + (t + (remove-hook 'after-change-major-mode-hook #'string-edit-mode t) + (put 'after-change-major-mode-hook 'permanent-local nil)))) (defun string-edit-done () "Finish editing the string and call the callback function. -- 2.45.1