Updates and clarifications

Posted on Wed 26 August 2009 in geek

My previous post regarding the frustrations of a slow frame update when emacsclient was spawning frames wasn't helped by a gotcha I've walked into a couple of times regarding the if function. In my haste to debug problems I'd added a message in some code:

 (if I-am-emacs-22+
+    (message "loading color-theme at %s" (current-time-string))
     (if (maybe-load-library "color-theme")

As my eyes are used to scanning indentation and considerably sparser use of {}'s I never twigged that I'd completely changed the meaning of the code. As C-f h if will tell you:

if is a special form in `C source code'.

(if cond then else...)

If cond yields non-nil, do then, else do else...
Returns the value of then or the value of the last of the else's.
then must be one expression, but else... can be zero or more expressions.
If cond yields nil, and there are no else's, the value is nil.

If we ever want to have multiple line of functions in the "true" case you always need to wrap them up using something like progn:

(if "true"
    (progn
      (message "It's true")
      (message "I wanted to say something else"))
  (message "No it's not"))

Of course this makes things a little messier (even more parenthesis!) and you'll notice a lot of LISP code strives to be as dense as possible. However it's a worthwhile gotcha to keep in mind if your just starting with LISP.

In the meantime I've made a few changes to my .bashrc_emacs when I realised having emacsclient called with -n makes no sense in EDITOR and VISUAL environment variables. These variables are typically used by tools such as crontab or git which get confused when the editor they spawned for a user input returns straight away.

I also solved (or at least mitigated) the slow drawing of new frames by caching the colour theme so it doesn't get set every time I bring up a new frame. Notice the use of progn in the code ;-)

(defvar my-last-theme 'nil
  "Last color theme we set")

(defun my-color-theme-set (theme)
  "Set colour theme but don't bother if we already have"
  (if (eq my-last-theme theme)
      (message "my-color-theme-set: theme already set")
    (if (fboundp theme)
        (progn
          (funcall theme)
          (setq my-last-theme theme)))))

(defun my-set-tty-colours ()
  "Set the colours for tty mode"
  (my-color-theme-set 'color-theme-midnight)
  ; some tweaks
  (set-face-attribute 'show-paren-match-face nil :weight 'extra-bold)
  (set-face-background 'region "blue"))

(defun my-set-x-colours()
  "Set the colours for X windows mode"
  (my-color-theme-set 'color-theme-gnome2))

(defun my-new-frame-colours(frame)
  "Set the colour scheme of a new frame"
  (if (frame-parameter frame 'tty)
      (my-set-tty-colours)
    (my-set-x-colours)))

; Lets hook into the frame function
(add-hook 'after-make-frame-functions 'my-new-frame-colours)