When string formatting is supported, it's sometimes possible pass in a string which could contain a percentage symbol which would then be interpreted.

For example, this frame-title-format has a bug when the file name contains %b.

(setq-default frame-title-format
      (if (buffer-file-name)
        (abbreviate-file-name (buffer-file-name))
     (:eval (if (buffer-modified-p) " *")) " emacs"))

How can a string have formatting characters converted into literals?

  • The frame-title-format has a long-standing bug that can lead to the name subsequently changing on its own .... Setting the frame title by modifying the frame parameter directly is the best way to work around that bug. The frame title parameter can also be set from the outset when creating the frame ...
    – lawlist
    Jul 28 '19 at 5:31

C-hf format and (for your example) C-hv mode-line-format both use the same escaping mechanism for the % metacharacters:

The format control string may contain %-sequences meaning to substitute the next available argument, or the argument explicitly specified:
Use %% to put a single % into the output.

So to escape the meta-characters in a format STRING, you could do this:

(replace-regexp-in-string "%" "%%" STRING)

And for completeness: if you were calling format yourself, you would simply use:

(format "%s" STRING)
  • Maybe citing C-h v mode-line-format would fit the question's example better.
    – npostavs
    Jul 29 '19 at 0:29
  • Very good point; I obviously wasn't paying enough attention. Happily the %% escaping mechanism is the same in each case :) Fixed now.
    – phils
    Jul 29 '19 at 3:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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