1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-07 06:50:23 -08:00

Clean up text properties in 'visual-wrap-prefix-mode'

Before refontifying a region, remove any text properties we care about
so that we don't end up with stray properties.  Additionally, make sure
to remove all the properties when deactivating the mode.

* lisp/emacs-lisp/subr-x.el (add-remove--display-text-property): New
function, extracted from...
(add-display-text-property): ... here.
(remove-display-text-property): New function.

* lisp/visual-wrap.el (visual-wrap--remove-properties): New function...
(visual-wrap-prefix-function, visual-wrap-prefix-mode): ... call it.

* test/lisp/emacs-lisp/subr-x-tests.el
(subr-x-test-remove-display-text-property): New test.

* test/lisp/visual-wrap-tests.el
(visual-wrap-tests/wrap-prefix-stickiness, visual-wrap-tests/cleanup):
New tests.

* doc/lispref/display.texi (Display Property): Document
'remove-display-text-property'.

* etc/NEWS: Announce 'remove-display-text-property' (bug#76018).
This commit is contained in:
Jim Porter 2025-05-28 09:44:34 -07:00
parent 24e6cd4233
commit 90c0c9a01e
6 changed files with 174 additions and 23 deletions

View file

@ -416,28 +416,25 @@ indivisible unit."
(setq start (1+ start))))
(nreverse result)))
;;;###autoload
(defun add-display-text-property (start end spec value &optional object)
"Add the display specification (SPEC VALUE) to the text from START to END.
If any text in the region has a non-nil `display' property, the existing
display specifications are retained.
OBJECT is either a string or a buffer to add the specification to.
If omitted, OBJECT defaults to the current buffer."
(defun add-remove--display-text-property (start end spec value
&optional object remove)
(let ((sub-start start)
(sub-end 0)
(limit (if (stringp object)
(min (length object) end)
(min end (point-max))))
disp)
(while (< sub-end end)
(setq sub-end (next-single-property-change sub-start 'display object
(if (stringp object)
(min (length object) end)
(min end (point-max)))))
limit))
(if (not (setq disp (get-text-property sub-start 'display object)))
;; No old properties in this range.
(put-text-property sub-start sub-end 'display (list spec value)
object)
(unless remove
(put-text-property sub-start sub-end 'display (list spec value)
object))
;; We have old properties.
(let (type)
(let ((changed nil)
type)
;; Make disp into a list.
(setq disp
(cond
@ -460,14 +457,41 @@ If omitted, OBJECT defaults to the current buffer."
;; regions of text.
(setq disp (if (eq type 'list)
(remove old disp)
(delete old disp))))
(setq disp (cons (list spec value) disp))
(when (eq type 'vector)
(setq disp (seq-into disp 'vector)))
;; Finally update the range.
(put-text-property sub-start sub-end 'display disp object)))
(delete old disp))
changed t))
(unless remove
(setq disp (cons (list spec value) disp)
changed t))
(when changed
(if (not disp)
(remove-text-properties sub-start sub-end '(display nil) object)
(when (eq type 'vector)
(setq disp (seq-into disp 'vector)))
;; Finally update the range.
(put-text-property sub-start sub-end 'display disp object)))))
(setq sub-start sub-end))))
;;;###autoload
(defun add-display-text-property (start end spec value &optional object)
"Add the display specification (SPEC VALUE) to the text from START to END.
If any text in the region has a non-nil `display' property, the existing
display specifications are retained.
OBJECT is either a string or a buffer to add the specification to.
If omitted, OBJECT defaults to the current buffer."
(add-remove--display-text-property start end spec value object))
;;;###autoload
(defun remove-display-text-property (start end spec &optional object)
"Remove the display specification SPEC from the text from START to END.
SPEC is the car of the display specification to remove, e.g. `height'.
If any text in the region has other display specifications, those specs
are retained.
OBJECT is either a string or a buffer to remove the specification from.
If omitted, OBJECT defaults to the current buffer."
(add-remove--display-text-property start end spec nil object 'remove))
;;;###autoload
(defun read-process-name (prompt)
"Query the user for a process and return the process object."