helpful

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

commit b97947b2033e33eb5fddb71ec840a3221b27e87c
parent c87f865c7a3c15ed0c049099694ee6cc4643b684
Author: Wilfred Hughes <me@wilfred.me.uk>
Date:   Thu, 10 May 2018 08:42:18 +0100

Don't highlight very large code snippets

This stops big code excerpts hanging Emacs when using helpful.
Fixes #107.

Diffstat:
MCHANGELOG.md | 4++++
Mhelpful.el | 47++++++++++++++++++++++++++++-------------------
2 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -14,6 +14,10 @@ Function signatures are now correct when a function uses Fixed an issue where escaped backticks were confused with unescaped backticks in docstrings. +Fixed an issue with very large code snippets making helpful hang due +to slow syntax highlighting. This was particularly problematic for C +functions and variables. + # v0.9 Much better handling of aliases: show aliases differently to their diff --git a/helpful.el b/helpful.el @@ -82,6 +82,14 @@ To disable cleanup entirely, set this variable to nil. See also :type 'function :group 'helpful) +;; TODO: explore whether more basic highlighting is fast enough to +;; handle larger functions. See `c-font-lock-init' and its use of +;; 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'.") + (defun helpful--kind-name (symbol callable-p) "Describe what kind of symbol this is." (cond @@ -905,25 +913,26 @@ hooks.") (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))) + (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))) (defun helpful--source (sym callable-p)