How can I configure a different background color for the active window in Emacs?
问题:
回答1:
If by "window" you mean Emacs' definition of windows, i.e., panes, not really.
If by "window" you mean everyone else's conception of windows, which Emacs calls frames, then yes. Here's an example:
(defadvice handle-switch-frame (around switch-frame-set-background)
(set-background-color "white")
ad-do-it
(set-background-color "yellow"))
(ad-activate 'handle-switch-frame)
(defadvice delete-frame (after delete-frame-set-background)
(set-background-color "yellow"))
(ad-activate 'delete-frame)
回答2:
Try Yoshida's hiwin-mode (visible active window mode): https://github.com/yoshida-mediba/hiwin-mode
回答3:
Here is an alternative using the modeline inactive color matching the background so the only modeline with color is the active window. I have a hooks for the minibuffer enter and exit, and also when switching windows. I use bold for certain modeline things like read only and the file name, so that the a different color doesn't stand out when switching windows. When I enter the minibuffer, the active window modeline turns to inactive until I exit the minibuffer, or when I switch from an active minibuffer (leaving it open) to another window. I had to set the modeline background box to match also.
(set-face-attribute 'default nil :background "black" :foreground "white"
:font "Courier" :height 180)
(set-face-attribute 'mode-line nil
:height 160 ;; affects everything
:foreground "black" :background "gray70")
(set-face-attribute 'mode-line-inactive nil
:foreground "gray70" :background "black" :box '(:line-width 1 :color "black"))
(defun enter-minibuffer-setup ()
(whitespace-mode t)
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black" :box '(:line-width 1 :color "black"))
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "cyan")
(set (make-local-variable 'face-remapping-alist)
'((default :background "black" :foreground "yellow"))) )
(defun exit-minibuffer-setup ()
(cond
((or save-as-variable multi-extract-variable multi-attach-variable)
(set-face-attribute 'mode-line nil :height 160 :foreground "black" :background "#eab700"))
(t (set-face-attribute 'mode-line nil :height 160 :foreground "black" :background "gray70" :box nil)))
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "cyan"))
(add-hook 'minibuffer-setup-hook 'enter-minibuffer-setup)
(add-hook 'minibuffer-exit-hook 'exit-minibuffer-setup)
(defun lawlist-minibuffer-conditions ()
(cond
((minibufferp)
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black" :box '(:line-width 1 :color "black"))
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "cyan"))
(t
(set-face-attribute 'mode-line nil
:height 160 :foreground "black" :background "gray70")
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "gray70")) ))
(defun lawlist-forward-window ()
(interactive)
(other-window 1)
(lawlist-minibuffer-conditions))
(defun lawlist-backward-window ()
(interactive)
(other-window -1)
(lawlist-minibuffer-conditions))
ALTERNATIVE ANSWER (similar concept): set-face-attribute
is too slow for changing faces during redisplay
. The preferred method for adjusting faces in that context is with the function face-remap-add-relative
; however, that function is a little complicated to use because faces stack up one behind the other and get shadowed. So, I'll need to revise the following draft alternative answer (in the future) to incorporate face-remap-add-relative
-- in the meantime, I'm setting the face-remapping-alist
manually (which admittedly is not the preferred method according to the manual / doc-string).
(defvar modeline-selected-window nil)
(let ((default-background (face-background 'default nil 'default)))
(set-face-attribute 'mode-line-inactive nil :background default-background :box nil))
(defun modeline-record-selected-window ()
(setq modeline-selected-window (selected-window)))
(defun modeline-update-function ()
(cond
((minibufferp)
(let ((default-background (face-background 'default nil 'default)))
(with-selected-window (minibuffer-window)
(setq-local face-remapping-alist '(
(default :foreground "blue")
(minibuffer-prompt :foreground "red"))))
(setq-default face-remapping-alist `((mode-line ,'mode-line-inactive)))))
(t
(with-selected-window (minibuffer-window)
(when (local-variable-p 'face-remapping-alist)
(kill-local-variable 'face-remapping-alist)))
(setq-default face-remapping-alist nil))))
(defun modeline-set-format ()
(setq mode-line-format '(
(:eval
(if (eq modeline-selected-window (selected-window))
(propertize "SELECTED WINDOW" 'face 'font-lock-warning-face)
(propertize "NOT-SELECTED WINDOW" 'face 'font-lock-keyword-face)))))
;; next two lines make the affect immediately apparent
(setq modeline-selected-window (selected-window))
(force-mode-line-update))
(define-minor-mode modeline-mode
"This is a minor-mode for `modeline-mode`."
:init-value nil
:lighter " ML"
:keymap nil
:global t
:group nil
(cond
(modeline-mode
(add-hook 'post-command-hook 'modeline-record-selected-window)
(add-hook 'buffer-list-update-hook 'modeline-update-function)
(add-hook 'text-mode-hook 'modeline-set-format)
(when (called-interactively-p 'any)
(message "Globally turned ON `modeline-mode`.")))
(t
(remove-hook 'post-command-hook 'modeline-record-selected-window)
(remove-hook 'buffer-list-update-hook 'modeline-update-function)
(remove-hook 'text-mode-hook 'modeline-set-format)
(when (called-interactively-p 'any)
(message "Globally turned OFF `modeline-mode`.") ))))
(modeline-mode 1) ;; globally turn on minor-mode
Example http://www.lawlist.com/images/modeline-example.png
回答4:
If what you are trying to achieve is to highlight the current buffer/frame, the way I do that is through Highlight-Current-Line. It shows you the line where the cursor is, but a side effect of that is that it also shows you which buffer/frame you are in. You could configure it to highlight the entire buffer, or look into the code to see how they do it.
回答5:
Crosshairs mode is your best bet, I think. It not only draws attention to the active window, but it also shows you immediately where the cursor is in an obvious way. You can easily toggle it on/off (I bind it to C-+
.)
You can also use crosshairs-toggle-when-idle
as an alternative. It does not show the crosshairs until a delay has past. It too is a toggle.
You can of course use crosshairs together with an in-your-face mode-line
face.
回答6:
I was using hiwin-mode
as suggested in this topic but there is an open issue with shell buffers (when inactive, the text becomes invisible).
Therefore, another option which I'm enjoying so far is auto-dim-other-buffers mode.