Visual focus enhancement for Emacs by adjusting buffer brightness based on window focus state.
- Active Window Darkening: Darken the background of the active window to provide visual focus
- Inactive Window Lightening: Optionally lighten inactive windows for contrast
- Smart Posframe Detection: Automatically detects and ignores posframe overlays (vertico-posframe, company-posframe, etc.)
- Configurable Ignore Lists: Skip specific modes and buffers
- Always-Darken Lists: Force certain buffers to always appear darkened
- Split Window Support: Handles multiple windows showing the same buffer
;; Add to your init.el or early-init.el
(add-to-list 'load-path "~/.emacs.d/localpackages/spotlight-mode")
(require 'spotlight-mode)
(spotlight-mode 1)(use-package spotlight-mode
:load-path "~/.emacs.d/localpackages/spotlight-mode"
:config
(spotlight-mode 1))(use-package spotlight-mode
:straight (:host github :repo "konrad1977/spotlight-mode")
:config
(spotlight-mode 1));; Percentage to dim (darken) the active buffer (default: 10)
(setq spotlight-active-dim-percentage 15)
;; Percentage to lighten inactive buffers (default: 0)
(setq spotlight-inactive-lighten-percentage 5)
;; Percentage for always-darkened buffers (default: 15)
(setq spotlight-always-darken-percentage 20)Buffers matching these criteria will not have effects applied:
;; Major modes to ignore
(setq spotlight-mode-ignore-modes
'(treemacs-mode vterm-mode eshell-mode shell-mode term-mode))
;; Buffer names to ignore (exact match)
(setq spotlight-mode-ignore-buffers
'("Messages" "dashboard" "*compilation*"))
;; Regular expressions for buffer names to ignore
(setq spotlight-mode-ignore-buffers-regexp
'("posframe"
"\\*.*posframe.*\\*"
"messages"
"compilation"
"faces"))Buffers matching these criteria will always be darkened when visible:
;; Buffer names to always darken (exact match)
(setq spotlight-mode-always-darken-buffers
'("*compilation*"))
;; Regular expressions for buffer names to always darken
(setq spotlight-mode-always-darken-buffers-regexp
'("\\*which-key-\\*"
"\\*Flycheck.+\\*"
"\\*Flymake.+\\*"))Assign specific background and foreground colors to buffers:
;; Buffer names with custom colors (exact match)
(setq spotlight-mode-always-color-buffers
'(("*iOS Simulator*" . (:background "#181926" :foreground "white"))
("*dape-repl*" . (:background "#252535" :foreground "gray100"))
("*dape-info*" . (:background "#43242B" :foreground "gray100"))))
;; Regular expressions with custom colors
(setq spotlight-mode-always-color-buffers-regexp
'(("\\*help.*\\*" . (:background "#0f3460" :foreground "#ffffff"))
("\\*compilation\\*" . "#1e1e2e")))Note: Custom colors can be either:
- A single color string (for background only):
"#1a1a2e" - A plist with
:backgroundand/or:foreground:(:background "#1a1a2e" :foreground "#ffffff")
M-x spotlight-mode- Toggle the global mode on/offM-x spotlight-mode-toggle-effect- Toggle effect for current bufferM-x spotlight-mode-set-active-dim-percentage- Interactively set active dim percentage
(use-package spotlight-mode
:config
(setq spotlight-active-dim-percentage 8
spotlight-inactive-lighten-percentage 0
spotlight-always-darken-percentage 12)
(spotlight-mode 1))(use-package spotlight-mode
:config
(setq spotlight-active-dim-percentage 0
spotlight-inactive-lighten-percentage 10
spotlight-always-darken-percentage 15)
(spotlight-mode 1))(use-package spotlight-mode
:config
(setq spotlight-active-dim-percentage 10
spotlight-inactive-lighten-percentage 5)
(spotlight-mode 1))(use-package spotlight-mode
:ensure nil
:hook (after-init . spotlight-mode)
:config
(setq spotlight-mode-ignore-buffers '("*Messages*" "*scratch*" "*Android Emulator*")
spotlight-mode-always-color-buffers '(("*iOS Simulator*" . (:background "#181926" :foreground "white"))
("*dape-repl*" . (:background "#252535" :foreground "gray100"))
("*dape-info*" . (:background "#43242B" :foreground "gray100")))))The package uses Emacs' face remapping functionality to dynamically modify the default, fringe, and line-number faces' background colors. It hooks into window selection and configuration changes to update effects in real-time.
- Custom color buffers: Highest priority, uses exact colors specified
- Always-darken buffers: Second priority, always darkened by
spotlight-always-darken-percentage - Active window: Dimmed (darkened) by
spotlight-active-dim-percentageif > 0 - Inactive windows: Lightened by
spotlight-inactive-lighten-percentageif > 0 - Ignored buffers: No effects applied
When a posframe is detected (e.g., vertico-posframe, company-posframe), all buffer color changes are temporarily suspended to prevent visual artifacts. Effects resume automatically when the posframe closes.
The package only applies effects when there are multiple non-ignored windows visible. This prevents unnecessary color changes when working with a single window.
- Check if the buffer/mode is in the ignore lists
- Ensure multiple non-ignored windows are visible
- Verify
spotlight-modeis enabled
The package caches the theme's background color. If you change themes, the cache is automatically invalidated, but you can manually refresh:
(spotlight-mode-invalidate-caches)
(spotlight-mode-window-switch-hook)If you experience lag with many windows:
;; Reduce hook frequency by removing post-command-hook
(remove-hook 'post-command-hook 'spotlight-mode-window-switch-hook)- Requires Emacs 25.1 or later
- Compatible with most themes and color schemes
- Works with posframe-based packages
- Supports terminal and GUI Emacs
MIT License - see LICENSE file for details
Contributions are welcome! Please submit issues and pull requests on GitHub.
Author: Mikael Konradsson