4

In Emacs, on the modeline: I would like the name of the currently focused buffer to be bold, but only when its window is selected.

My modeline looks something like this:

(setq mode-line-format
  (list "%&"
    " "
    (propertize "%b " 'face 'mode-line-buffer-id)
    "%p of %I"
    " "
    "[%l,%c]"
    'vc-mode
    " "
    'mode-line-modes
    ))

I would like "%b" (the name of the buffer) to be bold when its window is selected. I am totally new to Emacs Lisp. I thought setting the face to a variable that is changed by some "focus-in" hook would be the way to go (and possibly forcing the modeline to be redrawn).

I'm not sure what event I should hook in to. I know about focus-in-hook and focus-out-hook but those are for the frame.

Any hints are greatly appreciated.

1
  • The following link contains an example of how to display different things in the active window, versus the inactive window. You can have bold font for the buffer-name in the active window, and just regular font for the buffer-name in the inactive window. Show something in active mode line instead of all mode lines: emacs.stackexchange.com/questions/26222/… See also a related example of the same concept -- Change mode-line-buffer-id face for inactive windows: emacs.stackexchange.com/a/22682/2287
    – lawlist
    Nov 14, 2016 at 4:01

2 Answers 2

1

Just customize face mode-line-buffer-id: M-x customize-face RET mode-line-buffer-id RET

In Customize, you can specify that the face's Weight attribute is Bold.

Set your edit changes, to see the effect. Save your set changes, if you like the effect and want to have it in future Emacs sessions, by default.

6
  • Thank you. So what I'm trying to achieve is to change the face for the modeline corresponding to the currently focused buffer only. Am I missing something?
    – hyperio
    Nov 13, 2016 at 23:56
  • I see. What you mean is for the selected window. You can do that for the whole mode line, using face mode-line versus face mode-line-inactive. But to do it for just part of the mode line I think you will need to use an :eval form. Perhaps someone else will provide a simple answer. I'll delete my answer after a while - leaving it for now, for the comments.
    – Drew
    Nov 14, 2016 at 0:38
  • Thanks. Could you elaborate on how I'd use eval, just for my education?
    – hyperio
    Nov 14, 2016 at 0:47
  • See the Elisp manual (C-h i), node Mode Line Data.
    – Drew
    Nov 14, 2016 at 0:50
  • What confuses me is what exactly would I need to eval. How do I know if a buffer is active or not. What stores this info?
    – hyperio
    Nov 14, 2016 at 0:58
1

Here a solution (works only if buffers are different per windows)

(defun toggle-mode-line-buffer-name-face (window)
  (with-current-buffer (window-buffer window)
    (if (eq (current-buffer) (window-buffer (selected-window)))
        (face-remap-reset-base 'mode-line-buffer-id)
      (face-remap-set-base 'mode-line-buffer-id '(:bold nil)))))
(add-hook 'buffer-list-update-hook (lambda () (walk-windows #'toggle-mode-line-buffer-name-face nil t)))

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