3

I'd like to customize the mode line with my own faces, depending on whether a particular window is selected or not. Let's say I have this:

(setq-default mode-line-format
              '((:eval (propertize
                        (format-mode-line
                         mode-line-buffer-identification)
                        'face (if nil
                                  'mode-line
                                'mode-line-inactive)))))

I'd like to put instead of nil a predicate that checks if the current window is selected. How could I do that?

2 Answers 2

4

Try this:

(defvar my-selwin nil)

(defun foo (windows)
  (when (not (minibuffer-window-active-p (frame-selected-window)))
    (setq my-selwin (selected-window))))

(add-function :before pre-redisplay-function #'foo)

(setq-default mode-line-format
              '((:eval (propertize
                        (format-mode-line
                         mode-line-buffer-identification)
                        'face (if (eq my-selwin (get-buffer-window))
                                  'lazy-highlight
                                'highlight)))))

I believe that the problem with the simple test (eq (selected-window) (get-buffer-window)) (my first answer, since deleted) is that redisplay runs through some or all of the windows in turn, selecting each one. My answer here remembers the window that was selected when redisplay starts, and compares with that. Not very elegant, but it seems to work (you need at least Emacs 24.4 for it, however.)

FWIW, I've added a tiny library, modeline-win.el, which does this: highlights the buffer id in the mode line for the selected window.

0

The way powerline does it is pretty simple and I've never seen an issue with it.

Here is the appropriate code from powerline which you can easily adapt to your own purposes.

(defvar powerline-selected-window (frame-selected-window))
(defun powerline-set-selected-window ()
  "sets the variable `powerline-selected-window` appropriately"
  (when (not (minibuffer-window-active-p (frame-selected-window)))
    (setq powerline-selected-window (frame-selected-window))))

(add-hook 'window-configuration-change-hook 'powerline-set-selected-window)
(add-hook 'focus-in-hook 'powerline-set-selected-window)
(add-hook 'focus-out-hook 'powerline-set-selected-window)

(defadvice select-window (after powerline-select-window activate)
  "makes powerline aware of window changes"
  (powerline-set-selected-window))

;;;###autoload (autoload 'powerline-selected-window-active "powerline")
(defun powerline-selected-window-active ()
  "Return whether the current window is active."
  (eq powerline-selected-window (selected-window)))
1
  • Yeah, issues with powerline are the reason for the question. I think there should be a better way to deal with this than 3 hooks and 1 advice, since they don't cover all the bases.
    – abo-abo
    Jul 11, 2015 at 8:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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