Use short symbols for query-replace-show-preview (bug#81583)

* lisp/replace.el (query-replace-show-preview): Accept the
symbols `replacement-only' and `both'.  Update the :type
accordingly, which also fixes the name of a function that does
not exist.
(query-replace-preview-match): Update the doc string.
(replace-preview-both, replace-preview-replacement-only): Say
which value of the option calls them.
(replace-preview--format): Dispatch on the new values, and still
call a function value.
(replace-preview-setup): Test the option for non-nil instead of
testing it with `functionp'.
* test/lisp/replace-tests.el (replace-tests--preview)
(replace-tests-preview-both, replace-tests-preview-cleanup)
(replace-tests-preview-disabled): Use the new values.
* doc/emacs/search.texi (Replace): Document the new values.
This commit is contained in:
Rahul Martim Juliato 2026-09-06 19:19:48 -03:00 committed by Juri Linkov
parent 530271f5a0
commit 92acd66831
4 changed files with 47 additions and 37 deletions

View file

@ -1576,14 +1576,15 @@ look after the replacement. This tells you what back-references like
replacement. However, replacements that use @samp{\,} or @samp{\#} are
not previewed.
The value can be @code{replace-preview-replacement-only}, to display
the replacement alone, @code{replace-preview-both}, to display the match
next to its replacement, separated by an arrow, or a function of your
own, written by copying either of those two. Such a function takes the
match and the replacement and returns the string to display in place of
the match. If the replacement is empty,
@code{replace-preview-replacement-only} would display nothing at all, so
it displays a thin bar to mark the place of the match.
The value can be @code{replacement-only}, to display the replacement
alone, @code{both}, to display the match next to its replacement,
separated by an arrow, or a function of your own, written by copying
@code{replace-preview-replacement-only} or @code{replace-preview-both},
which are the functions those two symbols stand for. Such a function
takes the match and the replacement and returns the string to display in
place of the match, or @code{nil} to leave that match alone. If the
replacement is empty, @code{replacement-only} would display nothing at
all, so it displays a thin bar to mark the place of the match.
@vindex query-replace-preview@r{ face}
@vindex query-replace-preview-match@r{ face}

View file

@ -139,9 +139,10 @@ type it: the matches visible in the window are shown as they would look
after the replacement. Replacements that use '\,' or '\#' are not
previewed. The preview is off by default.
The value is a function. 'replace-preview-replacement-only' shows the
replacement alone, and 'replace-preview-both' shows the match and
replacement side-by-side. Or you can use a custom function.
The value can be the symbol 'replacement-only', which shows the
replacement alone, the symbol 'both', which shows the match and the
replacement side-by-side, or a custom function of the match and the
replacement, returning the string to show in place of the match.
** Electric Pair mode

View file

@ -119,17 +119,17 @@ This variable affects only `query-replace-regexp'."
The matches visible in the window are shown as they would look after the
replacement. Replacements using \\, or \\# are not previewed.
The value can be nil, for no preview;
`replace-preview-replacement-only', to show the replacement alone;
`replace-preview-both', to show the match and the replacement side by
side; or a function of two string arguments, the match and the
replacement, returning the string to show in place of the match."
:type '(choice (const :tag "No preview" nil)
(function-item :tag "Show the replacement"
replace-preview-only-replacement)
(function-item :tag "Show both match and replacement"
replace-preview-both)
(function :tag "Other function"))
The value can be nil, for no preview; the symbol `replacement-only', to
show the replacement alone; the symbol `both', to show the match and the
replacement side by side; or a function of two string arguments, the
match and the replacement, returning the string to show in place of the
match, or nil to leave that match alone. See the functions
`replace-preview-replacement-only' and `replace-preview-both' for two
examples of such a function."
:type '(choice (const :tag "No preview" nil)
(const :tag "Show the replacement" replacement-only)
(const :tag "Show both match and replacement" both)
(function :tag "Other function"))
:group 'matching
:version "32.1")
@ -182,7 +182,7 @@ friends when `query-replace-show-preview' is non-nil."
'((t (:inherit lazy-highlight)))
"Face for the matched text in the preview.
Used for the left half of the preview when `query-replace-show-preview'
is `replace-preview-both'."
is `both'."
:group 'matching
:version "32.1")
@ -401,7 +401,8 @@ overlay string they would show something other than the preview."
(defun replace-preview-both (match replacement)
"Return MATCH and REPLACEMENT side by side, separated by an arrow.
MATCH and REPLACEMENT are strings, shown in the faces
`query-replace-preview-match' and `query-replace-preview'."
`query-replace-preview-match' and `query-replace-preview'. This is what
`query-replace-show-preview' does when it is `both'."
(let ((sep (if (char-displayable-p ?→) "" "->")))
(concat (replace-preview-propertize (concat match sep)
'query-replace-preview-match)
@ -411,7 +412,9 @@ MATCH and REPLACEMENT are strings, shown in the faces
(defun replace-preview-replacement-only (_match replacement)
"Return REPLACEMENT in the face `query-replace-preview'.
REPLACEMENT is a string. If it is empty, previewing it would show
nothing at all, so return a thin bar to mark the place of the match."
nothing at all, so return a thin bar to mark the place of the match.
This is what `query-replace-show-preview' does when it is
`replacement-only'."
(let ((text (replace-preview-propertize replacement
'query-replace-preview)))
(if (equal text "")
@ -421,12 +424,17 @@ nothing at all, so return a thin bar to mark the place of the match."
(defun replace-preview--format (match replacement)
"Return the string to show in place of MATCH, or nil for no preview.
MATCH is the matched string and REPLACEMENT is the string that would
replace it. They are combined by the function
`query-replace-show-preview'."
(when (functionp query-replace-show-preview)
(let ((s (save-match-data
(funcall query-replace-show-preview match replacement))))
(and (stringp s) s))))
replace it. They are combined as `query-replace-show-preview' says."
(let ((s (save-match-data
(pcase query-replace-show-preview
('nil nil)
('replacement-only
(replace-preview-replacement-only match replacement))
('both
(replace-preview-both match replacement))
((pred functionp)
(funcall query-replace-show-preview match replacement))))))
(and (stringp s) s)))
(defun replace-preview-update (from to regexp-flag delimited-flag case-fold)
"Preview the result of replacing FROM with TO in the current buffer.
@ -472,7 +480,7 @@ on every change it shows, in the original window, how the visible
matches of FROM would look after the replacement.
REGEXP-FLAG and DELIMITED-FLAG say how to search for FROM, as in
`replace-search'."
(if (or (not (functionp query-replace-show-preview)) (minibufferp))
(if (or (not query-replace-show-preview) (minibufferp))
#'ignore
(let ((unwind (make-symbol "replace-preview--unwind"))
(after-change (make-symbol "replace-preview--after-change"))

View file

@ -709,9 +709,9 @@ bound to HIGHLIGHT-LOCUS."
"Return the previews of replacing FROM with TO in a buffer holding TEXT.
Each preview is a list (BEG END STRING).
Unless the caller binds `query-replace-show-preview' to something else,
the previews are those of `replace-preview-replacement-only'."
the previews are those of `replacement-only'."
(let ((query-replace-show-preview
(or query-replace-show-preview #'replace-preview-replacement-only)))
(or query-replace-show-preview 'replacement-only)))
(with-temp-buffer
(insert text)
(set-window-buffer (selected-window) (current-buffer))
@ -751,7 +751,7 @@ the previews are those of `replace-preview-replacement-only'."
'((1 4 " ")))))
(ert-deftest replace-tests-preview-both ()
(let ((query-replace-show-preview #'replace-preview-both)
(let ((query-replace-show-preview 'both)
(arrow (if (char-displayable-p ?→) "" "->")))
(should (equal (replace-tests--preview "foo\n" "foo" "bar" nil)
`((1 4 ,(concat "foo" arrow "bar")))))))
@ -767,7 +767,7 @@ the previews are those of `replace-preview-replacement-only'."
(with-temp-buffer
(insert "foo foo\n")
(set-window-buffer (selected-window) (current-buffer))
(let ((query-replace-show-preview #'replace-preview-replacement-only))
(let ((query-replace-show-preview 'replacement-only))
(replace-preview-update "foo" "bar" nil nil nil))
(should replace-preview-overlays)
(replace-preview-cleanup)
@ -777,7 +777,7 @@ the previews are those of `replace-preview-replacement-only'."
(ert-deftest replace-tests-preview-disabled ()
(let ((query-replace-show-preview nil))
(should (eq (replace-preview-setup "foo" nil nil) #'ignore)))
(let ((query-replace-show-preview #'replace-preview-replacement-only))
(let ((query-replace-show-preview 'replacement-only))
(should-not (eq (replace-preview-setup "foo" nil nil) #'ignore))))
(ert-deftest test-count-matches ()