Long ago, I used XEmacs, and its buffer-local faces to highlight the active window and modeline. When I switched to Emacs, I was sad to see that it didn't have buffer-local and window-local faces. It does have a separate face for active and inactive modelines though.
Today I learned that Emacs 23 has a buffer-local face remapping feature. I'm using this to highlight the active buffer (not window):
;;; highlight-focus.el --- highlight the active buffer ;; Author: Amit J Patel <amitp@cs.stanford.edu> ;;; Commentary: ;; ;; I find that I'm not good at tracking when focus changes across ;; apps, windows, and within a window. As much as possible, I try to ;; have all my applications somehow draw attention to what has ;; focus. In X11 I marked the focus in red. In Firefox I marked the ;; text fields in yellow. This Emacs package highlights the active ;; buffer. It's inspired by an earlier package I had written for ;; XEmacs, which changes the window color and modeline color for the ;; current window. ;; ;;; History: ;; ;; 2014-05-07: Updated to use the Emacs 24 focus-{in,out}-hook ;; 2013-05-10: Rewritten to use the Emacs 23 "remap faces" feature. ;; 2007-04-16: Initial version, temporarily highlighting the active buffer ;; Also see <https://github.com/emacsmirror/auto-dim-other-buffers> ;;; Code: (require 'face-remap) (defvar highlight-focus:last-buffer nil) (defvar highlight-focus:cookie nil) (defvar highlight-focus:background "white") (defvar highlight-focus:app-has-focus t) (defun highlight-focus:check () "Check if focus has changed, and if so, update remapping." (let ((current-buffer (and highlight-focus:app-has-focus (current-buffer)))) (unless (eq highlight-focus:last-buffer current-buffer) (when (and highlight-focus:last-buffer highlight-focus:cookie) (with-current-buffer highlight-focus:last-buffer (face-remap-remove-relative highlight-focus:cookie))) (setq highlight-focus:last-buffer current-buffer) (when current-buffer (setq highlight-focus:cookie (face-remap-add-relative 'default :background highlight-focus:background)))))) (defun highlight-focus:app-focus (state) (setq highlight-focus:app-has-focus state) (highlight-focus:check)) (defadvice other-window (after highlight-focus activate) (highlight-focus:check)) (defadvice select-window (after highlight-focus activate) (highlight-focus:check)) (defadvice select-frame (after highlight-focus activate) (highlight-focus:check)) (add-hook 'window-configuration-change-hook 'highlight-focus:check) (add-hook 'focus-in-hook (lambda () (highlight-focus:app-focus t))) (add-hook 'focus-out-hook (lambda () (highlight-focus:app-focus nil))) (provide 'highlight-focus) ;;; highlight-focus.el ends here
There's some more tweaking I need to do but so far it seems to be working reasonably well.
Update: [2014-06-01] I updated the code to use Emacs 24.4's focus-in and focus-out hooks.
Update: [2017-10-26] Ram Krishnan has turned this into a package; see github/kriyative/highlight-focus.
Update: [2020-07-01] I now use and recommend auto-dim-other-buffers. It works really well, and is on MELPA!
Labels: emacs
Hi,
I've adapted your solution to have parts of my mode-line colored differently for active and inactive buffers. As long as there is no buffer dsiplayes in more than one window, it kind of works for me. But it also bothers me. So, have you ever figured out how to do this kind of thing not with different buffers but different windows?
Ciao, Marcus
Hi Marcus, no, sorry, I haven't figured out different windows. XEmacs had this feature — you could override faces for a buffer, a window, or a frame. GNU Emacs does not.
For the mode-line I use mode-line and mode-line-inactive faces. They do support per-window colors.
Hi -
I just discovered the very useful highlight-focus Elisp package - thanks for sharing it.
I didn't find a GitHub (or other public) repository for the code, so I created one for my own use - if you have a different repo I can contribute to, please let me know.
https://github.com/kriyative/highlight-focus
I also made a small change to allow rendering the highlight in ways other than changing the buffer/window background color. Hope others find that useful.
Thanks again.
Cheers,
-ram
Thank you Ram! I linked to your github repository at the end of the blog post.
Amit - you're welcome. Do you have a preferred open source license you'd like to assign to this package? I can add to the repo in case anybody else is interested in using/extending the package.
Ram — I usually use MIT for things like this. It seems like the least hassle for people.
Great - I've added the MIT license file.
> Today I learned that Emacs 23 has a buffer-local face remapping feature. I'm using this to highlight the active buffer (not window)
FYI, starting with Emacs 27 this now supports per-window predicates. auto-dim-other-buffers takes advantage of that to highlight the active window.
Thanks mina86! That's great news!
mina86: I've switched to auto-dim-other-buffers and I've updated the blog post to link to it.
Post a Comment