Skip to content

Commit

Permalink
Prevent Emacs fontification failure w/ lots of classes - Fixes #248
Browse files Browse the repository at this point in the history
What I've done to fix this:

- add a sclang-class-list variable in sclang-language.el, which is a
  list of all the classes known to sclang. this is populated when
  sclang starts.
- update sclang-font-lock-class-keyword-matcher in
  sclang-mode.el. since the sclang-class-name-regexp now will match
  all words that start with a capital letter (see next bullet point
  for that change), this function had to be updated to check to make
  sure that the word starting with a capital letter is in the list of
  classes. if it is, then we know it's a class and it gets
  highlighted. if it's not, then it's just something the user typed
  with a capital letter, so we don't highlight it.
- update sclang-update-font-lock in sclang-mode.el. instead of
  generating a huge regexp from a list of all the classes in
  SuperCollider, just run the normal fontification from that
  function. this avoids making the regexp too big and thus prevents
  fontification from failing.
  • Loading branch information
defaultxr committed Nov 21, 2016
1 parent a2234d1 commit 5df9049
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 16 deletions.
3 changes: 3 additions & 0 deletions editors/scel/el/sclang-language.el
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ low-resource systems."
(defvar sclang-symbol-table nil
"List of all defined symbols.")

(defvar sclang-class-list nil
"List of all defined classes.")

(defvar sclang-symbol-history nil
"List of recent symbols read from the minibuffer.")

Expand Down
31 changes: 15 additions & 16 deletions editors/scel/el/sclang-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -244,18 +244,28 @@
'font-lock-comment-face)))

(defun sclang-font-lock-class-keyword-matcher (limit)
(let ((regexp (or sclang-font-lock-class-keywords
(concat "\\<" sclang-class-name-regexp "\\>")))
(case-fold-search nil))
(re-search-forward regexp limit t)))
(let ((regexp (concat "\\<" sclang-class-name-regexp "\\>"))
(case-fold-search nil)
(continue t)
(res nil))
(while continue
(setq res (re-search-forward regexp limit t))
(if (or (null res) (null sclang-class-list))
(setq continue nil)
(let ((thing (thing-at-point 'word)))
(if (null thing)
(setq res nil continue nil)
(when (position (substring-no-properties thing) sclang-class-list :test 'equal)
(setq continue nil))))))
res))

(defun sclang-set-font-lock-keywords ()
(setq
;; level 1
sclang-font-lock-keywords-1
(list
;; keywords
(cons (regexp-opt sclang-font-lock-keyword-list'words)
(cons (regexp-opt sclang-font-lock-keyword-list 'words)
'font-lock-keyword-face)
;; builtins
(cons (regexp-opt sclang-font-lock-builtin-list 'words)
Expand Down Expand Up @@ -302,17 +312,6 @@

(defun sclang-update-font-lock ()
"Update font-lock information in all sclang-mode buffers."
(setq sclang-font-lock-class-keywords
(and sclang-symbol-table
(let* ((list (remove-if
(lambda (x) (or (not (sclang-class-name-p x))
(sclang-string-match "^Meta_" x)))
sclang-symbol-table))
;; need to set this for large numbers of classes
(max-specpdl-size (* (length list) 2)))
(condition-case nil
(concat "\\<\\(?:Meta_\\)?\\(?:" (regexp-opt list) "\\)\\>")
(error nil)))))
;; too expensive
;; (dolist (buffer (buffer-list))
;; (with-current-buffer buffer
Expand Down

0 comments on commit 5df9049

Please sign in to comment.