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

柔情痞子 提交于 2019-12-11 13:07:05

问题


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))) )))

回答1:


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.



来源:https://stackoverflow.com/questions/25109011/how-to-speed-up-a-custom-mode-line-face-change-function-in-emacs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!