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.

Drew
  • 75,699
  • 9
  • 109
  • 225
hyperio
  • 153
  • 4
  • 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**: http://emacs.stackexchange.com/questions/26222/show-something-in-active-mode-line-instead-of-all-mode-lines See also a related example of the same concept -- **Change mode-line-buffer-id face for inactive windows**: http://emacs.stackexchange.com/a/22682/2287 – lawlist Nov 14 '16 at 04:01

2 Answers2

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.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • 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 '16 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 '16 at 00:38
  • Thanks. Could you elaborate on how I'd use eval, just for my education? – hyperio Nov 14 '16 at 00:47
  • See the Elisp manual (`C-h i`), node [Mode Line Data](http://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html). – Drew Nov 14 '16 at 00: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 '16 at 00:58
  • What you call "buffer is active" is that its window is the `selected-window`. Compare the values returned by `get-buffer-window` and`selected-window`. – Drew Nov 14 '16 at 02:46
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)))
djangoliv
  • 3,169
  • 16
  • 31