Custom background for active window - emacs

How can I configure a different background color for the active window in Emacs?

Try Yoshida's hiwin-mode (visible active window mode): https://github.com/yoshida-mediba/hiwin-mode

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)

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

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.

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.

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.

Related

Evil mode has unpredictable behavior when using compile

I have this issue, where whenever I run the compile command evil mode creates a new window instead of using the windows on the screen which the normal compile command would or it would compile on the current window I am on.
Take the following images as examples:
Without evil mode, if I have 2 windows open in a split and I am on a window on the left and I run M-x compile and specify an argument (assume it will be a batch script called build.bat) emacs will use the screen on the right as shown in this image:
https://i.stack.imgur.com/LeoMm.png
The .emacs is:
(require 'ido)
(require 'compile)
(ido-mode t)
; Compilation
(defun make-without-asking ()
(interactive)
(switch-to-buffer-other-window "*compilation*")
(compile "build.bat")
(other-window 1))
(define-key global-map "\em" 'make-without-asking)
(add-to-list 'default-frame-alist '(font . "Liberation Mono-11.5"))
(set-face-attribute 'default t :font "Liberation Mono-11.5")
(set-face-attribute 'font-lock-builtin-face nil :foreground "#DAB98F")
(set-face-attribute 'font-lock-comment-face nil :foreground "gray50")
(set-face-attribute 'font-lock-constant-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-doc-face nil :foreground "gray50")
(set-face-attribute 'font-lock-function-name-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-keyword-face nil :foreground "DarkGoldenrod3")
(set-face-attribute 'font-lock-string-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-type-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-variable-name-face nil :foreground "burlywood3")
(menu-bar-mode -1)
(set-foreground-color "burlywood3")
(set-background-color "#161616")
(set-cursor-color "#40FF40")
However, as soon as I add evil mode the behavior becomes unpredictable as it would sometimes create a new window or it will compile on the window I am on.
In the following example I am on the window on the right with evil mode enabled and when I run M-x compile with build.bat as the argument (like before), evil mode compiles the code and shows the *compilation* buffer on the same window instead of using the window on the left:
https://i.stack.imgur.com/MdNpg.png
The .emacs with evil mode enabled is:
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
(require 'package)
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(setq package-selected-packages '(evil))
(package-install-selected-packages)
(require 'ido)
(require 'compile)
(require 'evil)
(evil-mode 1)
(ido-mode t)
; Compilation
(defun make-without-asking ()
(interactive)
(switch-to-buffer-other-window "*compilation*")
(compile "build.bat")
(other-window 1))
(define-key global-map "\em" 'make-without-asking)
(add-to-list 'default-frame-alist '(font . "Liberation Mono-11.5"))
(set-face-attribute 'default t :font "Liberation Mono-11.5")
(set-face-attribute 'font-lock-builtin-face nil :foreground "#DAB98F")
(set-face-attribute 'font-lock-comment-face nil :foreground "gray50")
(set-face-attribute 'font-lock-constant-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-doc-face nil :foreground "gray50")
(set-face-attribute 'font-lock-function-name-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-keyword-face nil :foreground "DarkGoldenrod3")
(set-face-attribute 'font-lock-string-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-type-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-variable-name-face nil :foreground "burlywood3")
(menu-bar-mode -1)
(set-foreground-color "burlywood3")
(set-background-color "#161616")
(set-cursor-color "#40FF40")
I just switched over to neovim and setup this functionlity using vimscript, it was much easier.

Emacs 26.3 scrollbar refuses to move up if not moved up immediately

On Fedora Release 31. Using Xming on Windows 7 as X server. EDIT: also Emacs 24.3 running on RHEL7 with MobaXterm 12.2 4204, whether in -Q mode or not
The scrollbar I'm seeing is a medium-dark rectangle (the scrollbar "elevator") with rounded left-hand corners and square right-hand corners, in a light-gray vertical area (the scrollbar "track"). When I mouse over the rectangle it switches to dark gray.
When I click it, it turns blue. After about 1/2 second, if not moved, it narrows about 2 pixels on the right [EDIT: on the 24.3/RHEL7/MobaXterm setup, narrows on both sides], and refuses to move. Moving the mouse will sometimes get one scroll of the window contents, and sometimes not.
If I click it and move it slightly in that 1/2 second, it will move, and continue to be movable even if I hold still for a while. But I have to move it substantially (at least half its height, it seems, in a 2000 line file) or it will then freeze at the 1/2 second mark.
Here's my current .emacs file:
(defun switch-to-next-buffer-frank ()
(interactive)
(switch-to-buffer (other-buffer)))
(defun switch-to-prev-window ()
(interactive)
(other-window -1))
(defun scroll-one-line-up (&optional arg)
"Scroll the selected window up (forward in the text) one line (or N lines)."
(interactive "p")
(scroll-up (or arg 1)))
(defun scroll-one-line-down (&optional arg)
"Scroll the selected window down (backward in the text) one line (or N)."
(interactive "p")
(scroll-down (or arg 1)))
(global-set-key [(control ?z)] 'scroll-one-line-up)
(global-set-key [(meta ?z)] 'scroll-one-line-down)
(global-set-key [(meta ?g)] 'goto-line)
(global-set-key [(control ?x)(k)] 'kill-this-buffer)
(global-set-key [(control meta ?l)] 'switch-to-next-buffer)
(global-set-key [(control shift meta ?l)] 'switch-to-prev-buffer)
(global-set-key [(control tab)] 'other-window)
(global-set-key [(control shift iso-lefttab)] 'switch-to-prev-window)
(modify-syntax-entry ?_ "w")
(setq scroll-bar-mode 'left)
(setq scroll-bar-adjust-thumb-portion nil)
(setq gutter-buffers-tab-visible-p nil)
(setq inhibit-startup-screen t)
(setq mouse-yank-at-point t)
(setq inhibit-startup-buffer-menu t)
(tool-bar-mode -1)
(delete-selection-mode 1)
;(setq inhibit-splash-screen t)
;(setq inhibit-startup-message t)
;(setq initial-scratch-message nil)
;(delete-selection-mode 1)
;
;(defun ask-user-about-supersession-threat (fn)
; "blatantly ignore files that changed on disk"
; )
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(ansi-color-faces-vector
[default default default italic underline success warning error])
'(ansi-color-names-vector
["#3F3F3F" "#CC9393" "#7F9F7F" "#F0DFAF" "#8CD0D3" "#DC8CC3" "#93E0E3" "#DCDCCC"])
'(background-color "#000000")
'(background-mode dark)
'(company-quickhelp-color-background "#4F4F4F")
'(company-quickhelp-color-foreground "#DCDCCC")
'(cursor-color "#ffffff")
'(custom-enabled-themes (quote (manoj-dark)))
'(custom-safe-themes
(quote
("54f2d1fcc9bcadedd50398697618f7c34aceb9966a6cbaa99829eb64c0c1f3ca" "4138944fbed88c047c9973f68908b36b4153646a045648a22083bd622d1e636d" "8885761700542f5d0ea63436874bf3f9e279211707d4b1ca9ed6f53522f21934" "59e82a683db7129c0142b4b5a35dbbeaf8e01a4b81588f8c163bd255b76f4d21" default)))
'(fci-rule-color "#383838")
'(font-use-system-font t)
'(foreground-color "#00ff00")
'(gutter-buffers-tab-visible-p nil t)
'(indent-tabs-mode nil)
'(nrepl-message-colors
(quote
("#CC9393" "#DFAF8F" "#F0DFAF" "#7F9F7F" "#BFEBBF" "#93E0E3" "#94BFF3" "#DC8CC3")))
'(pdf-view-midnight-colors (quote ("#DCDCCC" . "#383838")))
'(query-user-mail-address nil)
'(tool-bar-mode nil)
'(user-mail-address "fsheeran#gmail.com")
'(vc-annotate-background "#2B2B2B")
'(vc-annotate-color-map
(quote
((20 . "#BC8383")
(40 . "#CC9393")
(60 . "#DFAF8F")
(80 . "#D0BF8F")
(100 . "#E0CF9F")
(120 . "#F0DFAF")
(140 . "#5F7F5F")
(160 . "#7F9F7F")
(180 . "#8FB28F")
(200 . "#9FC59F")
(220 . "#AFD8AF")
(240 . "#BFEBBF")
(260 . "#93E0E3")
(280 . "#6CA0A3")
(300 . "#7CB8BB")
(320 . "#8CD0D3")
(340 . "#94BFF3")
(360 . "#DC8CC3"))))
'(vc-annotate-very-old-color "#DC8CC3"))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(default ((t (:foreground "#00ff00" :background "#000000" :size "10pt" :family "DejaVu Sans Mono" :foundry "PfEd" :slant normal :weight normal :height 144 :width normal))))
'(font-lock-builtin-face ((t (:foreground "#00ccff"))))
'(font-lock-comment-delimiter-face ((t (:foreground "#ffff00" :slant normal))))
'(font-lock-comment-face ((t (:foreground "#ffff00" :slant normal))))
'(font-lock-constant-face ((t (:foreground "#00ff99" :weight normal))))
'(font-lock-function-name-face ((t (:foreground "#00ff00" :weight normal :height 1.0))))
'(font-lock-preprocessor-face ((t (:foreground "#ff4040"))))
'(font-lock-string-face ((t (:foreground "#00ffee"))))
'(font-lock-type-face ((t (:foreground "#33ccff"))))
'(font-lock-variable-name-face ((t (:foreground "#66ff00"))))
'(italic ((t nil)))
'(mode-line ((t (:background "#445555" :foreground "#ffffff" :box (:line-width 2 :color "#445555") :height 1.0))))
'(mode-line-buffer-id ((t (:background "#445555" :foreground "#55ff55" :weight normal :height 1.0))))
'(mode-line-emphasis ((t (:weight normal))))
'(mode-line-highlight ((t (:box (:line-width 2 :color "#445555")))))
'(mode-line-inactive ((t (:background "#445555" :foreground "#ffffff" :box (:line-width 2 :color "#445555") :weight normal :height 1.0))))
'(scroll-bar ((t (:background "#334444" :foreground "#ddffff")))))
Here's a screenshot: of emacs -Q 24.3/RHEL7/MobaXterm:
Then here is the same window after I've held the top scrollbar about 1 second without moving after clicking down:

How to speed-up a custom mode-line face change function in Emacs

The following function named my-modeline-face-function causes Emacs to pause for approximately one-half to one full second, and I'm looking for some suggestions please to significantly increase the speed.
It doesn't seem like much, but this function is used a lot. For example, every time I enable multiple-cursors mode (aka mc-mode), I end up twiddling my thumbs before I can get down to business -- the same thing happens when exiting multiple-cursors mode.
Adding (redisplay t) at the tail end of the function does nothing to increase the speed.
Using (force-mode-line-update) following this function does not increase the speed.
(defun my-modeline-face-function ()
(cond
((minibufferp)
(set-face-attribute 'mode-line nil :height 140 :foreground "gray70"
:background "black" :box '(:line-width 1 :color "black"))
(set-face-attribute 'minibuffer-prompt nil :background "black"
:foreground "cyan" :bold t)
(set (make-local-variable 'face-remapping-alist)
'((default :background "black" :foreground "yellow"))))
(save-as-variable
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "#eab700" :box nil))
(insert-variable
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "orange" :box nil))
((or multi-extract-variable multi-attach-variable)
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "magenta" :box nil))
(open-with-variable
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "ForestGreen" :box nil))
(mc-mode
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "cyan" :box nil))
(isearch-mode
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "yellow" :box nil))
((eq major-mode 'lawlist-calculator-mode)
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "firebrick" :box nil))
(t
(set-face-attribute 'mode-line nil :height 140
:foreground "black" :background "gray70" :box nil)
(set-face-attribute 'minibuffer-prompt nil
:background "black" :foreground "white"))) )
EDIT (August 5, 2014):
● Using a measure-time macro (i.e., http://lists.gnu.org/archive/html/help-gnu-emacs/2008-06/msg00087.html ), I verified that the run-time for the function internal-set-lisp-face-attribute within set-face-attribute occurs within mere fractions of a second. However, it takes up to one full second for me to see the visual effect. The same holds true whether it is the initial call of the function or subsequent calls within the same buffer.
● As to the first call of face-remapping-alist within a buffer, the visual effect takes up to one full second for me to see. However, subsequent calls using the face-remapping-alist within that same buffer occur within fractions of the second. I have not been able to eliminate the time needed to see the visual effect following the first call. This may be as good as it gets -- i.e., up to one full second for the first call, and light speed for subsequent calls within that same buffer.
(defun my-modeline-face-function ()
(cond
((minibufferp)
(set 'face-remapping-alist '(
(mode-line modeline-inactive-face)
(minibuffer-prompt minibuffer-prompt-active-face))) )
(save-as-variable
(set 'face-remapping-alist '((mode-line save-as-modeline-face))))
(insert-variable
(set 'face-remapping-alist '((mode-line insert-modeline-face))))
((or multi-extract-variable multi-attach-variable)
(set 'face-remapping-alist '((mode-line multi-attach-extract-modeline-face))))
(open-with-variable
(set 'face-remapping-alist '((mode-line open-with-modeline-face))))
(mc-mode
(set 'face-remapping-alist '((mode-line mc-modeline-face))))
(isearch-mode
(set 'face-remapping-alist '((mode-line isearch-modeline-face))))
((eq major-mode 'lawlist-calculator-mode)
(set 'face-remapping-alist '((mode-line lawlist-calculator-modeline-face))))
(t
(set 'face-remapping-alist '(
(mode-line modeline-active-face)
(minibuffer-prompt minibuffer-prompt-inactive-face))) )))
Changing faces dynamically is going to be slow because the redisplay code is written under the assumption that faces don't change (if they change, we basically redo a lot of work). Using face-remapping-alist will result in much better performance because the redisplay code does expect it to change and know how to cache the result.

How to change modeline color with active minibuffer and switch to other-window

Within the same frame and with an active minibuffer, can anyone think of a way to have switch to other-window behave similar to a minibuffer-exit-hook (without completely exiting the minibuffer)?
Essentially, I'd like to have the main windows show an inactive modeline color when focus is in the minibuffer, and then update the modline to active (for a window that has focus) when I move from the semi-active minibuffer to another window using other-window.
For example, there are two windows open in the same frame (side by side) -- Window # 1 are my notes -- Window # 2 is a Big Brother Database display of a record that I want to modify. So I open the minibuffer to input my record modification and then switch back and forth between my notes in Window # 1 and the minibuffer to copy and paste the relevant portions. When using other-window to jump between the three areas, it is still difficult to know whether focus is in the minibuffer or another window.
Window # 1 (notes)         | Window # 2 (bbdb record display)
                           |
___________________________|_____________________________________
Name: lawlist . . .
(defun enter-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black")
(set (make-local-variable 'face-remapping-alist)
'((default :background "gray10" :foreground "yellow"))))
(defun exit-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "black" :background "gray70"))
(add-hook 'minibuffer-setup-hook 'enter-minibuffer-setup)
(add-hook 'minibuffer-exit-hook 'exit-minibuffer-setup)
One option would be to "advise" the other-window function to execute some form when switching to the minibuffer.
For example, the following code will turn the minibuffer prompt green when you cycle back to it using other-window, and if you land on a non minibuffer window it turns the prompt grey:
(defadvice other-window (after adv-other-window-minibuffer
(COUNT &optional ALL-FRAMES))
"Make minibuffer prompt green when switched to"
(if (minibufferp)
(set-face-attribute 'minibuffer-prompt nil
:foreground "green" :background "black")
(set-face-attribute 'minibuffer-prompt nil
:foreground "dark grey" :background "black")))
(ad-activate 'other-window)
Of course you are not limited to just setting the minibuffer prompt, but it's not clear to me exactly what effect your are trying to achieve.
Updated draft -- borrowing (minibufferp) from #Carl Groner
(defun enter-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black")
(set (make-local-variable 'face-remapping-alist)
'((default :background "black" :foreground "yellow")))
(set-face-attribute 'minibuffer-prompt nil
:background "black" :foreground "cyan"))
(defun exit-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "black" :background "gray70")
(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")
(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))

Change Emacs Mode-Line color based on major-mode

I like to see if there is a way to change the mode-link foreground and background color base on the major-mode,
I was thinking to add the logic in the
(add-hook 'after-change-major-mode-hook
But, I do not have all the emacs lisp experience to make such change. Here is the logic:
switch major-mode:
case "emacs-lisp-mode":
(set-face-foreground 'mode-line "ivory")
(set-face-background 'mode-line "DarkOrange2")
case "ruby-mode":
(set-face-foreground 'mode-line "white")
(set-face-background 'mode-line "red")
...
default:
(set-face-foreground 'mode-line "black")
(set-face-background 'mode-line "white")
end switch
Many thanks in advance!.
You probably want something like:
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(face-remap-add-relative
'mode-line '((:foreground "ivory" :background "DarkOrange2") mode-line))))
You might want to use face-remap for the mode-line-inactive face as well.
"The logic" you are talking about is something like this:
(add-hook 'after-change-major-mode-hook 'my-set-mode-line-colors)
(defvar my-mode-line-colors
'((emacs-lisp-mode :foreground "ivory" :background "DarkOrange2")
(ruby-mode :foreground "white" :background "red")))
(defun my-set-mode-line-colors ()
(face-remap-add-relative
'mode-line (list (or (cdr (assq major-mode my-mode-line-colors))
'(:foreground "black" :background "white"))
'mode-line)))
Alternatively, you can do that from mode-specific hooks, as suggested by Stefan.