iqbalansari / emacs-emojify

Display emojis in Emacs
GNU General Public License v3.0
411 stars 40 forks source link

100% CPU load #95

Open tmalsburg opened 3 years ago

tmalsburg commented 3 years ago

While developing another package which is using font-lock for displaying links, I noticed an issue where Emacs runs under 100% CPU load. I couldn't nail down the root cause of the issue but I noticed that the problem arises only when emojify-mode is switched on. The problem could be in my code, in emojify, or in Emacs. Not sure. I'll leave a an example below. Works with emacs -Q. Just load the file containing the code below, and then eval-buffer. Not sure what to do about this, but I though this example might be useful when you stumble on this issue as well.

;;; -*- lexical-binding: t -*-

;;
;; Bootstrap straight.el:
;;

(defvar bootstrap-version)

(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;;
;; Emojify:
;;

(straight-use-package 'emojify)

(setq emojify-emoji-set "twemoji-v2")

(require 'emojify)

(emojify-set-emoji-styles '(unicode))

(global-emojify-mode)

;;
;; This code triggers the issue:
;;

(defvar-local my-matchers nil
  "List of matchers for links in local buffer.")

(defun my-make-link (regexp)
  (let ((matcher (lambda (limit)
                   (when (re-search-forward regexp limit t)
                     (let ((map (make-sparse-keymap)))
                       (define-key map [mouse-1]
                         (lambda () (interactive) (find-file "test.org")))
                       (set-text-properties
                        (match-beginning 0) (match-end 0)
                        `(local-map ,map mouse-face 'highlight
                                    help-echo "mouse-1: click me"))
                       t)))))
    (font-lock-add-keywords nil `((,matcher (0 'link t))) t)
    (font-lock-flush)
    (push matcher my-matchers)))

(defun my-clear-links ()
  "Remove matchers for links in local buffer."
  (dolist (link my-matchers)
    (font-lock-remove-keywords nil `((,link (0 'link t)))))
  (font-lock-flush)
  (setq my-matchers nil))

;; Strings for testing (should become links):
;; abcde qwert poiuz asdfg mnbvc

;; Test with just one link (this works):
;; (my-make-link "abcde")
;; (my-clear-links)

;; Test with 5 links (links appear but 100% CPU load):
(dolist (regexpr '("abcde" "qwert" "poiuz" "asdfg" "mnbvc"))
  (my-make-link regexpr))

;; Run this to remove links.  CPU load should return to normal after that.
;; (my-clear-links)