commit 99ee4bec41c7fc82c3f96c54ca79fa649451074e
parent 0bb75b90a99f703f5661f252a1b32ff0b878945a
Author: Wilfred Hughes <me@wilfred.me.uk>
Date: Mon, 18 Jun 2018 23:54:38 +0100
Better handling of syntax highlight on large code snippets
I've only seen performance issues on C code, so only apply
helpful-max-highlight on C code snippets. If we do hit this limit, add
a comment saying so, with a link to helpful-max-highlight.
Fixes #116
Diffstat:
| M | CHANGELOG.md | | | 4 | ++++ |
| M | helpful.el | | | 73 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
2 files changed, 51 insertions(+), 26 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -1,5 +1,9 @@
# v0.11
+Further work on syntax highlighting performance for large code
+snippets. Helpful now informs the user when it has intentionally
+disabled highlighting, and shows a link to the relevant setting.
+
Fixed an issue where Helpful didn't find keybindings if the command
was only referenced in `minor-mode-map-alist`.
diff --git a/helpful.el b/helpful.el
@@ -88,8 +88,12 @@ To disable cleanup entirely, set this variable to nil. See also
;; font-lock-keywords-1.
(defconst helpful-max-highlight 5000
"Don't highlight code with more than this many characters.
-This is particularly important for large pieces of C code, such
-as describing `this-command'.")
+
+This is currently only used for C code, as lisp highlighting
+seems to be more efficient. This may change again in future.
+
+See `this-command' as an example of a large piece of C code that
+can make Helpful very slow.")
(defun helpful--kind-name (symbol callable-p)
"Describe what kind of symbol this is."
@@ -915,30 +919,47 @@ hooks.")
"Return a propertized version of SOURCE in MODE."
(unless mode
(setq mode #'emacs-lisp-mode))
- (with-temp-buffer
- (insert source)
-
- (when (< (length source) helpful-max-highlight)
- ;; Switch to major-mode MODE, but don't run any hooks.
- (delay-mode-hooks (funcall mode))
-
- ;; `delayed-mode-hooks' contains mode hooks like
- ;; `emacs-lisp-mode-hook'. Build a list of functions that are run
- ;; when the mode hooks run.
- (let (hook-funcs)
- (dolist (hook delayed-mode-hooks)
- (let ((funcs (symbol-value hook)))
- (setq hook-funcs (append hook-funcs funcs))))
-
- ;; Filter hooks to those that relate to highlighting, and run them.
- (setq hook-funcs (-intersection hook-funcs helpful--highlighting-funcs))
- (-map #'funcall hook-funcs))
-
- (if (fboundp 'font-lock-ensure)
- (font-lock-ensure)
- (with-no-warnings
- (font-lock-fontify-buffer))))
- (buffer-string)))
+ (if (or
+ (< (length source) helpful-max-highlight)
+ (eq mode 'emacs-lisp-mode))
+ (with-temp-buffer
+ (insert source)
+
+ ;; Switch to major-mode MODE, but don't run any hooks.
+ (delay-mode-hooks (funcall mode))
+
+ ;; `delayed-mode-hooks' contains mode hooks like
+ ;; `emacs-lisp-mode-hook'. Build a list of functions that are run
+ ;; when the mode hooks run.
+ (let (hook-funcs)
+ (dolist (hook delayed-mode-hooks)
+ (let ((funcs (symbol-value hook)))
+ (setq hook-funcs (append hook-funcs funcs))))
+
+ ;; Filter hooks to those that relate to highlighting, and run them.
+ (setq hook-funcs (-intersection hook-funcs helpful--highlighting-funcs))
+ (-map #'funcall hook-funcs))
+
+ (if (fboundp 'font-lock-ensure)
+ (font-lock-ensure)
+ (with-no-warnings
+ (font-lock-fontify-buffer)))
+ (buffer-string))
+ ;; SOURCE was too long to highlight in a reasonable amount of
+ ;; time.
+ (concat
+ (propertize
+ "// Skipping highlighting due to "
+ 'face 'font-lock-comment-face)
+ (helpful--button
+ "helpful-max-highlight"
+ 'helpful-describe-exactly-button
+ 'symbol 'helpful-max-highlight
+ 'callable-p nil)
+ (propertize
+ ".\n"
+ 'face 'font-lock-comment-face)
+ source)))
(defun helpful--source (sym callable-p)
"Return the source code of SYM.