1

I have:

(setq mode-line-end-spaces "string")

That displays string in the mode-line.
How can I get string in red there?

Stefan
  • 26,154
  • 3
  • 46
  • 84
Gabriele Nicolardi
  • 1,199
  • 8
  • 17

2 Answers2

4

@NickD provided a good answer: use a face.

OP's comment to Nick's answer says that he'll try to write a function that, given a string, returns a propertized string. Such functions already exist: propertize does that, and so does add-face-text-property.

For example:

(setq ss  (propertize "abcde" 'face '(:foreground "red")))

or

(setq ss  "abcde")
(add-face-text-property 0 (length ss) '(:foreground "red") nil ss)
Drew
  • 75,699
  • 9
  • 109
  • 225
  • That's good to know. Thanks. – Gabriele Nicolardi Jul 23 '20 at 21:08
  • You should not try to modify a literal string: `(setq ss (copy-sequence "abcde"))`. –  Jul 25 '20 at 11:42
  • @Fólkvangr: Depends on what behavior you want. Do you want to modify a copy of the original string or the original string? The example of using a literal string here is also for brevity - who knows where the actual original string comes from? But if the intention is to modify the original string, then you don't want to use `copy-sequence`. – Drew Jul 25 '20 at 16:15
  • @Drew: `copy-sequence` allows to create a mutable string (c.f. Elisp manual version 27, section 2.9 Mutability). In your sample code, `add-face-text-property` modifies a literal string. –  Jul 25 '20 at 17:19
  • @Fólkvangr: Yes, I know. And? If you can modify something then it's mutable. But all of this is extraneous. If you prefer, read *"Suppose that the value of `ss` is a string"*, instead of the `setq`. The point of the answer is that you can use `add-face-text-property` to add color to a string. – Drew Jul 25 '20 at 18:15
3

You need to create a string with the appropriate face. You do that by attaching a face text property to the string, giving it value of some face (predefined or defined for the specific purpose - you can look at all the predefined faces with M-x list-faces-display and pick one from there, or you can define your own face). E.g. here's a snippet to use a predefined face:

(setq s (copy-sequence "sring"))
(put-text-property 0 6 'face 'custom-invalid s)
(setq mode-line-end-spaces s)
NickD
  • 27,023
  • 3
  • 23
  • 42
  • 1
    I understand. To generalize your answer, I'll try to write a function that, given a string, returns a propertized string. – Gabriele Nicolardi Jul 23 '20 at 14:02
  • You should not try to modify a constant string: `(setq s (copy-sequence "string"))`. –  Jul 25 '20 at 11:43
  • OK - edited. Here are some links to provide some context: [When to use quote for lists? Modifying quoted lists in Elisp](https://emacs.stackexchange.com/questions/45820/when-to-use-quote-for-lists-modifying-quoted-lists-in-elisp) and [Which Lisp objects are byte-compiled?](https://emacs.stackexchange.com/questions/57806/which-lisp-objects-are-byte-compiled) plus a [similar complaint by @Fólkvangr on an answer of mine that I have not fixed](https://emacs.stackexchange.com/questions/59652/is-there-a-way-to-spread-a-list-like-in-typescript-or-golang). – NickD Jul 27 '20 at 19:03