WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 11aeb1c

Browse files
committed
compat-31: New function remove-display-text-property
1 parent a9158a2 commit 11aeb1c

File tree

5 files changed

+126
-41
lines changed

5 files changed

+126
-41
lines changed

NEWS.org

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- compat-31: New function =unbuttonize-region=.
1717
- compat-31: New extended function =seconds-to-string=.
1818
- compat-31: New function =hash-table-contains-p=.
19+
- compat-31: New function =remove-display-text-property=.
1920
- Drop support for Emacs 24.x. Emacs 25.1 is required now. In case
2021
Emacs 24.x support is still needed, Compat 30 can be used.
2122

compat-29.el

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -584,47 +584,15 @@ be marked unmodified, effectively ignoring those changes."
584584
(equal ,hash (buffer-hash)))
585585
(restore-buffer-modified-p nil))))))))
586586

587-
(compat-defun add-display-text-property (start end prop value ;; <compat-tests:add-display-text-property>
588-
&optional object)
589-
"Add display property PROP with VALUE to the text from START to END.
590-
If any text in the region has a non-nil `display' property, those
591-
properties are retained.
592-
593-
If OBJECT is non-nil, it should be a string or a buffer. If nil,
594-
this defaults to the current buffer."
595-
(let ((sub-start start)
596-
(sub-end 0)
597-
disp)
598-
(while (< sub-end end)
599-
(setq sub-end (next-single-property-change sub-start 'display object
600-
(if (stringp object)
601-
(min (length object) end)
602-
(min end (point-max)))))
603-
(if (not (setq disp (get-text-property sub-start 'display object)))
604-
;; No old properties in this range.
605-
(put-text-property sub-start sub-end 'display (list prop value)
606-
object)
607-
;; We have old properties.
608-
(let ((vector nil))
609-
;; Make disp into a list.
610-
(setq disp
611-
(cond
612-
((vectorp disp)
613-
(setq vector t)
614-
(append disp nil))
615-
((not (consp (car disp)))
616-
(list disp))
617-
(t
618-
disp)))
619-
;; Remove any old instances.
620-
(when-let ((old (assoc prop disp)))
621-
(setq disp (delete old disp)))
622-
(setq disp (cons (list prop value) disp))
623-
(when vector
624-
(setq disp (vconcat disp)))
625-
;; Finally update the range.
626-
(put-text-property sub-start sub-end 'display disp object)))
627-
(setq sub-start sub-end))))
587+
(compat-defun add-display-text-property (start end spec value &optional object) ;; <compat-tests:add-display-text-property>
588+
"Add the display specification (SPEC VALUE) to the text from START to END.
589+
If any text in the region has a non-nil `display' property, the existing
590+
display specifications are retained.
591+
592+
OBJECT is either a string or a buffer to add the specification to.
593+
If omitted, OBJECT defaults to the current buffer."
594+
(declare-function add-remove--display-text-property "compat-31")
595+
(add-remove--display-text-property start end spec value object))
628596

629597
(compat-defmacro while-let (spec &rest body) ;; <compat-tests:while-let>
630598
"Bind variables according to SPEC and conditionally evaluate BODY.

compat-31.el

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,71 @@ METADATA should be an alist of completion metadata. See
232232

233233
;;;; Defined in subr-x.el
234234

235+
(compat-defun add-remove--display-text-property (start end spec value &optional object remove) ;; <compat-tests:add-display-text-property>
236+
"Helper function for `add-display-text-property' and `remove-display-text-property'."
237+
(let ((sub-start start)
238+
(sub-end 0)
239+
(limit (if (stringp object)
240+
(min (length object) end)
241+
(min end (point-max))))
242+
disp)
243+
(while (< sub-end end)
244+
(setq sub-end (next-single-property-change sub-start 'display object
245+
limit))
246+
(if (not (setq disp (get-text-property sub-start 'display object)))
247+
;; No old properties in this range.
248+
(unless remove
249+
(put-text-property sub-start sub-end 'display (list spec value)
250+
object))
251+
;; We have old properties.
252+
(let ((changed nil)
253+
type)
254+
;; Make disp into a list.
255+
(setq disp
256+
(cond
257+
((vectorp disp)
258+
(setq type 'vector)
259+
(seq-into disp 'list))
260+
((or (not (consp (car-safe disp)))
261+
;; If disp looks like ((margin ...) ...), that's
262+
;; still a single display specification.
263+
(eq (caar disp) 'margin))
264+
(setq type 'scalar)
265+
(list disp))
266+
(t
267+
(setq type 'list)
268+
disp)))
269+
;; Remove any old instances.
270+
(when-let* ((old (assoc spec disp)))
271+
;; If the property value was a list, don't modify the
272+
;; original value in place; it could be used by other
273+
;; regions of text.
274+
(setq disp (if (eq type 'list)
275+
(remove old disp)
276+
(delete old disp))
277+
changed t))
278+
(unless remove
279+
(setq disp (cons (list spec value) disp)
280+
changed t))
281+
(when changed
282+
(if (not disp)
283+
(remove-text-properties sub-start sub-end '(display nil) object)
284+
(when (eq type 'vector)
285+
(setq disp (seq-into disp 'vector)))
286+
;; Finally update the range.
287+
(put-text-property sub-start sub-end 'display disp object)))))
288+
(setq sub-start sub-end))))
289+
290+
(compat-defun remove-display-text-property (start end spec &optional object) ;; <compat-tests:remove-display-text-property>
291+
"Remove the display specification SPEC from the text from START to END.
292+
SPEC is the car of the display specification to remove, e.g. `height'.
293+
If any text in the region has other display specifications, those specs
294+
are retained.
295+
296+
OBJECT is either a string or a buffer to remove the specification from.
297+
If omitted, OBJECT defaults to the current buffer."
298+
(add-remove--display-text-property start end spec nil object 'remove))
299+
235300
(compat-defvar work-buffer--list nil ;; <compat-tests:with-work-buffer>
236301
"List of work buffers.")
237302

compat-tests.el

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,18 @@
485485
4 8 (display ((raise 0.5) (height 2.0)))
486486
8 12 (display (raise 0.5))))))
487487

488+
(ert-deftest compat-remove-display-text-property ()
489+
(with-temp-buffer
490+
(insert "Foo bar zot gazonk")
491+
(add-display-text-property 4 12 'height 2.0)
492+
(add-display-text-property 2 8 'raise 0.5)
493+
(remove-display-text-property 6 10 'height)
494+
(should-equal (get-text-property 2 'display) '(raise 0.5))
495+
(should-equal (get-text-property 11 'display) '(height 2.0))
496+
(should-equal (get-text-property 5 'display)
497+
'((raise 0.5) (height 2.0)))
498+
(should-not (get-text-property 9 'display))))
499+
488500
(ert-deftest compat-line-number-at-pos ()
489501
(with-temp-buffer
490502
(insert "\n\n\n")

compat.texi

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3452,6 +3452,45 @@ older than 31.1. Note that due to upstream changes, it might happen
34523452
that there will be the need for changes, so use these functions with
34533453
care.
34543454

3455+
@c copied from lispref/display.texi
3456+
@defun remove-display-text-property start end spec &optional object
3457+
Remove the display specification @var{spec} from the text from
3458+
@var{start} to @var{end}. @var{spec} is the @sc{car} of the display
3459+
specification to remove, e.g.@: @code{height} or @code{'(margin nil)}.
3460+
3461+
If any text in the region has any other @code{display} properties, those
3462+
properties are retained. For instance:
3463+
3464+
@lisp
3465+
@group
3466+
(add-display-text-property 1 8 'raise 0.5)
3467+
(add-display-text-property 4 8 'height 2.0)
3468+
(remove-display-text-property 2 6 'raise)
3469+
@end group
3470+
@end lisp
3471+
3472+
After doing this, the text will have the following @code{display}
3473+
properties:
3474+
3475+
@itemize @bullet
3476+
@item
3477+
The region from 1 to 2, only @code{raise}
3478+
3479+
@item
3480+
The region from 2 to 4, no properties
3481+
3482+
@item
3483+
The region from 4 to 6, only @code{height}
3484+
3485+
@item
3486+
The region from 6 to 8, both @code{raise} and @code{height}
3487+
3488+
@end itemize
3489+
3490+
@var{object} is either a string or a buffer to remove the specification
3491+
from. If omitted, @var{object} defaults to the current buffer.
3492+
@end defun
3493+
34553494
@c based on lisp/subr.el
34563495
@defmac hash-table-contains-p key table
34573496
Return non-nil if @var{table} has an element with @var{key}.

0 commit comments

Comments
 (0)