branch: master commit 45b5ad0158985fc50992bb8636ff388b170f3112 Merge: 5fe3695 269a382 Author: Jackson Ray Hamilton <jack...@jacksonrayhamilton.com> Commit: GitHub <nore...@github.com>
Merge pull request #5 from jacksonrayhamilton/prettify-symbols Prettify symbols --- .travis.yml | 1 + Makefile | 4 +-- context-coloring-test.el | 35 +++++++++++++++++++++ context-coloring.el | 63 +++++++++++++++++++++++++++++++------ fixtures/test/prettify-symbols.el | 1 + 5 files changed, 93 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index ba959a9..70d1f6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ env: - EVM_EMACS=emacs-24.3-travis - EVM_EMACS=emacs-24.4-travis - EVM_EMACS=emacs-24.5-travis + - EVM_EMACS=emacs-25.1-travis before_install: - export PATH="/home/travis/.evm/bin:$PATH" diff --git a/Makefile b/Makefile index 4519b70..9763be1 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -EMACS = emacs -CASK = EMACS=${EMACS} cask +EMACS ?= emacs +CASK ?= EMACS=${EMACS} cask DEPENDENCIES = .cask/ SOURCE_FILES = \ context-coloring.el \ diff --git a/context-coloring-test.el b/context-coloring-test.el index ab77254..0d1f539 100644 --- a/context-coloring-test.el +++ b/context-coloring-test.el @@ -344,6 +344,41 @@ signaled." '(context-coloring-level-0-face nil)) (disable-theme 'context-coloring-test-custom-theme))) +(when (fboundp 'prettify-symbols-mode) + + (defun context-coloring-test-assert-prettify-symbols-coloring () + (context-coloring-test-assert-coloring " +(111111 () (222222 ()))")) + + (defun context-coloring-test-assert-prettify-symbols-text-properties () + (unless (cond + ((version< emacs-version "25.0") + (get-text-property 2 'composition)) + (t + (and (get-text-property 2 'prettify-symbols-start) + (get-text-property 2 'prettify-symbols-end)))) + (ert-fail "Expected buffer to have it's symbols prettified, but it didn't."))) + + (context-coloring-test-deftest prettify-symbols-enabled-before + (lambda () + (context-coloring-test-with-fixture + "./fixtures/test/prettify-symbols.el" + (emacs-lisp-mode) + (prettify-symbols-mode) + (context-coloring-mode) + (context-coloring-test-assert-prettify-symbols-text-properties) + (context-coloring-test-assert-prettify-symbols-coloring)))) + + (context-coloring-test-deftest prettify-symbols-enabled-after + (lambda () + (context-coloring-test-with-fixture + "./fixtures/test/prettify-symbols.el" + (emacs-lisp-mode) + (context-coloring-mode) + (prettify-symbols-mode) + (context-coloring-test-assert-prettify-symbols-text-properties) + (context-coloring-test-assert-prettify-symbols-coloring))))) + ;;; Coloring tests diff --git a/context-coloring.el b/context-coloring.el index 06830fd..a64b6a9 100644 --- a/context-coloring.el +++ b/context-coloring.el @@ -41,6 +41,14 @@ "Join a list of STRINGS with the string DELIMITER." (mapconcat #'identity strings delimiter)) +(defun context-coloring-check-predicates (predicates) + "Call PREDICATES until one returns t, otherwise return nil." + (let ((satisfied-p nil)) + (while (and predicates + (not satisfied-p)) + (setq satisfied-p (funcall (pop predicates)))) + satisfied-p)) + ;;; Faces @@ -311,7 +319,11 @@ override `context-coloring-default-delay'. `context-coloring-mode' is enabled. `:teardown' - Arbitrary code to tear down this dispatch when -`context-coloring-mode' is disabled.") +`context-coloring-mode' is disabled. + +`:async-p' - Hint that code will be colorized asynchronously. +Please call `context-coloring-after-colorize' when colorization +completes.") (defun context-coloring-find-dispatch (predicate) "Find the first dispatch satisfying PREDICATE." @@ -345,18 +357,46 @@ override `context-coloring-default-delay'. "Set up environment for colorization." (context-coloring-update-maximum-face)) +(defvar context-coloring-after-colorize-hook nil + "Functions to run after colorizing.") + +(defun context-coloring-after-colorize () + "Do final business after colorization." + (run-hooks 'context-coloring-after-colorize-hook)) + (defun context-coloring-dispatch () "Determine how to color the current buffer, and color it." (let* ((dispatch (context-coloring-get-current-dispatch)) - (colorizer (plist-get dispatch :colorizer))) + (colorizer (plist-get dispatch :colorizer)) + (async-p (plist-get dispatch :async-p))) (context-coloring-before-colorize) (when colorizer (catch 'interrupted - (funcall colorizer))))) + (funcall colorizer))) + (unless async-p + (context-coloring-after-colorize)))) ;;; Colorization +(defvar context-coloring-fontify-keywords-predicates + (list + (lambda () (and (boundp 'prettify-symbols-mode) prettify-symbols-mode))) + "Cases where the whole buffer should have keywords fontified. +Necessary in cases where a mode relies on fontifications in +regions where Context Coloring doesn't happen to touch.") + +(defun context-coloring-maybe-fontify-keywords () + "Determine if the buffer ought to have keywords fontified." + (when (context-coloring-check-predicates + context-coloring-fontify-keywords-predicates) + (with-silent-modifications + (save-excursion + (font-lock-fontify-keywords-region (point-min) (point-max)))))) + +(add-hook 'context-coloring-after-colorize-hook + #'context-coloring-maybe-fontify-keywords) + (defun context-coloring-colorize () "Color the current buffer by function context." (interactive) @@ -381,12 +421,8 @@ permissible.") (defun context-coloring-ignore-unavailable-message-p () "Determine if the unavailable message should be silenced." - (let ((predicates context-coloring-ignore-unavailable-predicates) - (ignore-p nil)) - (while (and predicates - (not ignore-p)) - (setq ignore-p (funcall (pop predicates)))) - ignore-p)) + (context-coloring-check-predicates + context-coloring-ignore-unavailable-predicates)) (defvar context-coloring-interruptable-p t "When non-nil, coloring may be interrupted by user input.") @@ -428,6 +464,14 @@ Feature inspired by Douglas Crockford." (font-lock-set-defaults) ;; Safely change the value of this function as necessary. (make-local-variable 'font-lock-syntactic-face-function) + ;; Improve integration with `prettify-symbols-mode'. It relies on Font + ;; Lock's automatic fontification to apply it's changes on mode change, + ;; so Context Coloring has to make those changes manually. + (add-hook 'prettify-symbols-mode-hook #'context-coloring-maybe-fontify-keywords nil t) + ;; Furthermore, on Emacs < 25.0, `prettify-symbols-mode' calls + ;; `font-lock-fontify-buffer-function' which would overwrite context + ;; coloring, so make it a no-op. + (set (make-local-variable 'font-lock-fontify-buffer-function) (lambda ())) (let ((setup (plist-get dispatch :setup))) (when setup (funcall setup)) @@ -442,6 +486,7 @@ Feature inspired by Douglas Crockford." (let ((teardown (plist-get dispatch :teardown))) (when teardown (funcall teardown))))) + (remove-hook 'prettify-symbols-mode-hook #'context-coloring-maybe-fontify-keywords t) (turn-on-font-lock-if-desired)))) (provide 'context-coloring) diff --git a/fixtures/test/prettify-symbols.el b/fixtures/test/prettify-symbols.el new file mode 100644 index 0000000..0863230 --- /dev/null +++ b/fixtures/test/prettify-symbols.el @@ -0,0 +1 @@ +(lambda () (lambda ()))