Colorized text in Emacs

| categories: emacs | tags:

As I continue investigating Emacs + org-mode as a platform for creating applications, it has come up a few times that it would be useful to display colored text. For example, in a summary report of a git repo, you might want to see some information in red, e.g. if you have uncommitted changes, and some information in green, e.g. the repo is clean and consistent with a remote.

We can set colors on a string in Emacs like this:

(propertize "Red Text" 'font-lock-face '(:foreground "red"))

The only tricky part is that we need to insert the text into a font-locked buffer to see it. That is also a tad tricky to illustrate in a code block, so here is a way to try it:

(re-search-forward "-> ")
(insert
  (propertize "Red Text" 'font-lock-face '(:foreground "red")))

-> Red Text

The red text does not show in the HTML post, so this is a screenshot of what it looks like in my buffer:

Now, here is how we might use this in a summary report. Say we have a git repo, and we want to know various facts about it. We can get information about tracked/ untracked and modified files like this:

git status --porcelain
 M _blog/blog.html
 M _blog/blog.org
A  _blog/images/red-text.png

This shows we have two tracked, but modified files, and on added but not committed file. We can use this code to show if we have any untracked files.

(let ((n 0) s)
  (dolist (line (split-string
                 (shell-command-to-string "git status --porcelain")
                 "\n"))
    (when (string-match "^\\?\\?" line)
      (setq n (+ 1 n))))
  (if (> n 0)
      (setq s (propertize (format "%s untracked files" n)
                          'font-lock-face '(:foreground "red")))
    (setq s (propertize "No untracked files" 
                        'font-lock-face '(:foreground "forest green"))))
  (re-search-forward "->")
  (insert s))

->No untracked files

In HTML (i.e. the blog post) you cannot really see the green text, so here is a screenshot illustrating it.

Similarly, we can check for modified files. We add a wrinkle and add a tooltip like text that shows the output of the git command.

(let ((n 0)
      (output (shell-command-to-string "git status --porcelain"))
      s)
  (dolist (line (split-string
                 output
                 "\n"))
    (when (string-match "^ M" line)
      (setq n (+ 1 n))))
  (if (> n 0)
      (setq s (propertize (format "%s modified files" n)
                          'help-echo output
                          'font-lock-face '(:foreground "red")))
    (setq s (propertize "No modified files" 
                        'font-lock-face '(:foreground "forest green"))))
  (re-search-forward "-> ")
  (insert s))

-> 2 modified files

That looks like this in emacs:

That is the main idea in this post. You can create strings with properties, and use code to determine what they e.g. what color the text is, etc… There are lots of properties listed at http://www.gnu.org/software/emacs/manual/html_node/elisp/Special-Properties.html that might be helpful in an application. Here are some previous posts that examined similar ideas.

http://kitchingroup.cheme.cmu.edu/blog/2014/02/06/Invisible-text-in-emacs/

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.7c

Discuss on Twitter