29

By a "decorated string" I mean something like

#("foo" 0 4 (fontified t face font-lock-function-name-face))

...as opposed to the "plain string"

"foo"

(If Elisp code reads a string directly from a buffer, it may be decorated like this.)

What's the simplest way to convert a decorated string to a plain one (by stripping all the decorations)?

3
  • 19
    substring-no-properties
    – Dan
    Commented Mar 4, 2017 at 18:45
  • Why do you need these properties removed ? They usually do no harm. Just pretend they don't exist might be a good enough solution.
    – YoungFrog
    Commented Mar 4, 2017 at 20:25
  • 1
    @YoungFrog I e.g. ran into a problem with passing urls as text properties to eww.
    – lupl
    Commented Feb 28, 2022 at 11:31

1 Answer 1

26

[Your propertized string looks wrong - perhaps you copied it wrong. foo has only 3 characters, so it is impossible for it to be fontified on chars 0 to 4 (i.e., chars 0, 1, 2, and 3 - that's 4 chars). I use 3 instead of 4 in the example here.]

(let* ((foo    #("foo" 0 3 (fontified t face font-lock-function-name-face)))
       (start  0)
       (end    (length foo)))
  (set-text-properties start end nil foo)
  foo)

set-text-properties is a built-in function in C source code.

(set-text-properties START END PROPERTIES &optional OBJECT)

Completely replace properties of text from START to END.

The third argument PROPERTIES is the new property list.

If the optional fourth argument OBJECT is a buffer (or nil, which means the current buffer), START and END are buffer positions (integers or markers). If OBJECT is a string, START and END are 0-based indices into it. If PROPERTIES is nil, the effect is to remove all properties from the designated part of OBJECT.

See the Elisp manual, node Changing Properties. There you will see this, under function remove-text-properties (which you could also use to do the job):

To remove all text properties from certain text, use set-text-properties and specify nil for the new property list.


As @Dan mentioned, you can also use substring-no-properties, but be aware that it returns a new string. It does not modify the actual string object that you pass it. Both remove-text-properties and set-text-properties change the string you pass them.

For example:

(setq foo #("foo" 0 3 (fontified t face font-lock-function-name-face)))
(setq bar foo)
(set-text-properties 0 (length foo) nil foo)

Both foo and bar are now just "foo", with no properties.

But:

(setq foo #("foo" 0 3 (fontified t face font-lock-function-name-face)))
(setq bar foo)
(setq foo (substring-no-properties foo))

Now foo has no properties but bar still has them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.