根据evil和内置输入法的状态调整modeline的背景色

;; {{ change modeline color by evil&ime state
(defconst my-default-color (cons (face-background 'mode-line)
                                 (face-foreground 'mode-line)))

(defun my-show-evil-state ()
  "Change modeline color to notify user evil current state."
  (let ((color (cond
                ((minibufferp)
                 my-default-color)
                (current-input-method
                 '("#e80074" . "#ffffff"))
                ((evil-insert-state-p)
                 '("#e80000" . "#ffffff"))
                ((evil-emacs-state-p)
                 '("#444488" . "#ffffff"))
                ((buffer-modified-p)
                 '("#006fa0" . "#ffffff"))
                (t
                 my-default-color))))
    (set-face-background 'mode-line (car color))
    (set-face-foreground 'mode-line (cdr color))))
(add-hook 'post-command-hook #'my-show-evil-state)
;; }}

输入法启动后modline外观

6 个赞

感谢 @redguardtoo,根据代码改了个 meow 版本。

;; change modeline color by meow&ime state
(defconst my-default-color (cons (face-background 'mode-line)
                                 (face-foreground 'mode-line)))

(defun my-show-meow-state ()
  "Change modeline color to notify user current ime & meow state."
  (let ((color (cond
                ((minibufferp)
                 my-default-color)
                ;; 因为各种状态有重叠,以下顺序影响最终效果,重要的条目往前排
                (current-input-method
                 '("#e80074" . "#ffffff"))
                ((meow-normal-mode-p)
                 my-default-color)
                ((meow-insert-mode-p)
                 '("#e80000" . "#ffffff"))
                ;; ((meow-motion-mode-p)
                ;;  '("#444488" . "#ffffff"))
                ;; ((meow-beacon-mode-p)
                ;;  my-default-color)
                ;; ((meow-keypad-mode-p)
                ;;  my-default-color)
                ((buffer-modified-p)
                 '("#006fa0" . "#ffffff"))
                (t
                 my-default-color))))
    (set-face-background 'mode-line (car color))
    (set-face-foreground 'mode-line (cdr color))))

(add-hook 'post-command-hook #'my-show-meow-state)
;; 可能有用的hook,根据需要启用:
;; 1. 若开启了老猫auto-save或者super-save,则用after-save-hook触发更新(buffer-modified-p)
;; (add-hook 'after-save-hook #'my-show-meow-state)
;; 2. 根据窗口变动
;; (add-hook 'window-configuration-change-hook #'my-show-meow-state)
;; 3. 根据聚焦窗口变动
;; (add-function :after after-focus-change-function #'my-show-meow-state)

Edit 1~ 4: 调整了代码和相关说明。

2 个赞

友谊提醒一下,post command hook 慎重使用,前两天刚解决了一个编辑卡顿的问题,就是某 hook 导致的。

请教下, 在windows 平台下, 即 emacs for windows 中, 用什么 谓词函数 来判断

windows 中的 输入法/非输入法的切换

我想通过 获取这个 状态来 把模式行 变色

eval w32-get-ime-open-status

多谢, 因用的是 小狼毫, windows 下最终还是用 AHK 来解决了 全局不变, 在 emacs 内 再一起 发送2次键

AppsKey::Send, ^+{Space}
#IfWinActive ahk_class Emacs  
  +Capslock::Capslock
  Capslock::Send, {Home}
  AppsKey::
  Send, ^+{Space}
  Send, ^+{F6}
  Return
;;^Space::ControlSend, ,^g , ahk_class Emacs
#IfWinActive 

参考各位前辈的代码做了一些定制:

1、感觉用边框颜色指示 evil 状态更合理(不会影响 modeline 其他信息的背景色)

2、修改了更新边框颜色的 hook,感觉这样更加合理

(defun my/update-modeline-box (&rest _)
  (unless (minibufferp)
    (when (eq (window-buffer (selected-window)) (current-buffer))
      (let* ((face (cond
                    ((evil-normal-state-p) 'doom-modeline-evil-normal-state)
                    ((evil-emacs-state-p) 'doom-modeline-evil-emacs-state)
                    ((evil-insert-state-p) 'doom-modeline-evil-insert-state)
                    ((evil-motion-state-p) 'doom-modeline-evil-motion-state)
                    ((evil-visual-state-p) 'doom-modeline-evil-visual-state)
                    ((evil-operator-state-p) 'doom-modeline-evil-operator-state)
                    ((evil-replace-state-p) 'doom-modeline-evil-replace-state)
                    (t 'doom-modeline-evil-user-state)))
             (color (face-foreground face nil t)))
        (set-face-attribute 'mode-line-active nil :box `(:line-width (-1 . -2) :color ,color))))))
(add-hook 'evil-emacs-state-entry-hook #'my/update-modeline-box)
(add-hook 'evil-insert-state-entry-hook #'my/update-modeline-box)
(add-hook 'evil-motion-state-entry-hook #'my/update-modeline-box)
(add-hook 'evil-normal-state-entry-hook #'my/update-modeline-box)
(add-hook 'evil-visual-state-entry-hook #'my/update-modeline-box)
(add-hook 'evil-replace-state-entry-hook #'my/update-modeline-box)
(add-hook 'evil-operator-state-entry-hook #'my/update-modeline-box)
(add-hook 'window-selection-change-functions #'my/update-modeline-box)

output

3 个赞

你那个缩进对齐的竖线用的是啥包啊?

图中用的是 indent-bars,其实我之前一直用 highlight-indent-guides 后者也挺好用。

只能配合 doom-modeline 么?

因为 doom-modeline-evil-*-state 这一系列的 face 是在 doom-modeline 中定义的,如果不配合 doom-modeline 的话,就得自己改一改,来控制后面使用颜色。