helpful

a fork of Wilfred's helpful
git clone https://git.trogloxene.org/helpful.git
Log | Files | Refs | README

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:
MCHANGELOG.md | 4++++
Mhelpful.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.