From 1e7a874303ab2e5461ec3556338fa94f4fe052c0 Mon Sep 17 00:00:00 2001 From: Ryo Fukumuro Date: Fri, 1 Jan 2016 10:24:18 +0900 Subject: [PATCH] Use text properties instead of overlays for ANSI coloring --- CHANGELOG.md | 4 ++-- cider-repl.el | 33 +++++++++------------------------ test/cider-tests.el | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8bd6b06c..b10c6ef52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and try to associate the created connection with this project automatically. ### Changes +* [#1500](https://github.com/clojure-emacs/cider/pull/1500): Improve the performance of REPL buffers by using text properties instead of overlays for ANSI coloring. * `cider-current-connection` considers major mode before `cider-repl-type`. * `cider-inspect` now operates by default on the last sexp. Its behavior can be altered via prefix arguments. * Requires Clojure(Script) 1.7 or newer. @@ -24,9 +25,8 @@ and try to associate the created connection with this project automatically. * [#1466](https://github.com/clojure-emacs/cider/issues/1466): Correctly font-lock pretty-printed results in the REPL. * [#1475](https://github.com/clojure-emacs/cider/pull/1475): Fix `args-out-of-range` error in `cider--get-symbol-indent`. * [#1479](https://github.com/clojure-emacs/cider/pull/1479): Make paredit and `cider-repl-mode` play nice. -* [#1452](https://github.com/clojure-emacs/cider/issues/1452): Prevent ANSI color overlays in the REPL buffer from being extended. +* [#1452](https://github.com/clojure-emacs/cider/issues/1452): Fix wrong ANSI coloring in the REPL buffer. * [#1486](https://github.com/clojure-emacs/cider/issues/1486): Complete a partial fix in stacktrace font-locking. -* [#1488](https://github.com/clojure-emacs/cider/pull/1488): Delete zombie overlays in the REPL buffer. * [#1482](https://github.com/clojure-emacs/cider/issues/1482): Clear nREPL sessions when a connection is closed. * [#1435](https://github.com/clojure-emacs/cider/issues/1435): Improve error display in cider-test. * [#1379](https://github.com/clojure-emacs/cider/issues/1379): Fix test highlighting at start of line. diff --git a/cider-repl.el b/cider-repl.el index 87136e91f..2d7f85671 100644 --- a/cider-repl.el +++ b/cider-repl.el @@ -469,13 +469,13 @@ If BOL is non-nil insert at the beginning of line." (goto-char position) ;; TODO: Review the need for bol (when (and bol (not (bolp))) (insert-before-markers "\n")) - (cider-propertize-region `(font-lock-face ,output-face - rear-nonsticky (font-lock-face)) - (insert-before-markers string) - (when (and (= (point) cider-repl-prompt-start-mark) - (not (bolp))) - (insert-before-markers "\n") - (set-marker cider-repl-output-end (1- (point)))))))) + (insert-before-markers (ansi-color-apply (propertize string + 'font-lock-face output-face + 'rear-nonsticky '(font-lock-face)))) + (when (and (= (point) cider-repl-prompt-start-mark) + (not (bolp))) + (insert-before-markers "\n") + (set-marker cider-repl-output-end (1- (point))))))) (cider-repl--show-maximum-output))) (defun cider-repl--emit-interactive-output (string face) @@ -483,20 +483,7 @@ If BOL is non-nil insert at the beginning of line." (with-current-buffer (cider-current-repl-buffer) (let ((pos (cider-repl--end-of-line-before-input-start)) (string (replace-regexp-in-string "\n\\'" "" string))) - (cider-repl--emit-output-at-pos (current-buffer) string face pos t) - (ansi-color-apply-on-region pos (point-max)) - - ;; If the output has a trailing overlay created by ansi-color, it would be - ;; extended by the following outputs. To avoid this, ansi-color adds - ;; `ansi-color-freeze-overlay' to the `modification-hooks', but it never - ;; seems to be called. By using `insert-behind-hooks' instead, we can make - ;; it work. For more details, please see - ;; https://github.com/clojure-emacs/cider/issues/1452 - (dolist (ov (overlays-at (1- (cider-repl--end-of-line-before-input-start)))) - ;; Ensure ov is created by ansi-color - (when (and (member #'ansi-color-freeze-overlay (overlay-get ov 'modification-hooks)) - (not (member #'ansi-color-freeze-overlay (overlay-get ov 'insert-behind-hooks)))) - (push #'ansi-color-freeze-overlay (overlay-get ov 'insert-behind-hooks))))))) + (cider-repl--emit-output-at-pos (current-buffer) string face pos t)))) (defun cider-repl-emit-interactive-stdout (string) "Emit STRING as interactive output." @@ -521,9 +508,7 @@ FORMAT is a format string to compile with ARGS and display on the REPL." "Using BUFFER, emit STRING font-locked with FACE. If BOL is non-nil, emit at the beginning of the line." (with-current-buffer buffer - (let ((pos (cider-repl--end-of-line-before-input-start))) - (cider-repl--emit-output-at-pos buffer string face cider-repl-input-start-mark bol) - (ansi-color-apply-on-region pos (point-max))))) + (cider-repl--emit-output-at-pos buffer string face cider-repl-input-start-mark bol))) (defun cider-repl-emit-stdout (buffer string) "Using BUFFER, emit STRING as standard output." diff --git a/test/cider-tests.el b/test/cider-tests.el index ed75b733e..52fae700a 100644 --- a/test/cider-tests.el +++ b/test/cider-tests.el @@ -532,6 +532,23 @@ (should (equal (cider-repl-prompt-abbreviated "some.pretty.long.namespace.name") "s.p.l.n.name> "))) +(ert-deftest test-cider-repl--emit-output-at-pos-with-ansi-code () + (with-temp-buffer + (let* ((ansi-color-names-vector ["black" "red3" "green3" "yellow3" "blue2" "magenta3" "cyan3" "gray90"]) + (ansi-color-map (ansi-color-make-color-map))) + (cider-repl-reset-markers) + + (cider-repl--emit-output-at-pos (current-buffer) "a" 'cider-repl-stdout-face (point)) + (cider-repl--emit-output-at-pos (current-buffer) "b" 'cider-repl-stdout-face (point)) + (cider-repl--emit-output-at-pos (current-buffer) "c" 'cider-repl-stdout-face (point)) + (cider-repl--emit-output-at-pos (current-buffer) "d" 'cider-repl-stdout-face (point)) + + (should (string= (buffer-string) "a\nb\nc\nd\n")) + (should (equal (get-text-property 1 'font-lock-face) '(foreground-color . "black"))) + (should (equal (get-text-property 3 'font-lock-face) 'cider-repl-stdout-face)) + (should (equal (get-text-property 5 'font-lock-face) '(foreground-color . "red3"))) + (should (equal (get-text-property 7 'font-lock-face) '(foreground-color . "red3")))))) + (ert-deftest test-cider--url-to-file () (should (equal "/space test" (cider--url-to-file "file:/space%20test"))) (should (equal "C:/space test" (cider--url-to-file "file:/C:/space%20test"))))