12 Feb 2015

Lighten/darken a color in Emacs

I put together a little function to lighten or darken a (hex) color, having tired of using the browser's color picker or other manual means to tweak a color. I couldn't find an existing solution so I hope this helps someone else out!

# scheme
(defun lighten-color-at-point (&optional pct)
  (interactive "p")
  (unless (looking-at-p "#")
     (re-search-backward "#"))
    (push-mark nil t t)
    (let ((dist (skip-chars-forward "#A-Za-z0-9" (+ (point) 7)))
      (percent (or pct 5)))
      (insert (apply 'color-rgb-to-hex
        (apply 'color-hsl-to-rgb
          (apply 'color-lighten-hsl
            (append (apply 'color-rgb-to-hsl
              (color-name-to-rgb (buffer-substring-no-properties (mark) (point))))
              (list percent))))))
    (delete-region (region-beginning) (+ (region-beginning) dist)))))

(defun darken-color-at-point (&optional pct)
  (interactive "p")
  (lighten-color-at-point (if (numberp pct) (* pct -1) -5)))

(defun my-css-mode-hook ()
  (local-set-key (kbd "C-c l") 'lighten-color-at-point)
  (local-set-key (kbd "C-c R") 'darken-color-at-point))

(add-hook 'css-mode-hook 'my-css-mode-hook)

To use this, put your cursor before or after a color and press C-c l or C-c R. For example (cursor denoted with |):

# css
body { background: |#ccc }

By default, it will lighten/darken the color by 5%; with a prefix argument, lighten/darken by that percent. (C-u 20 C-c l to lighten by 20%)