branch: elpa/raku-mode commit a94d11b81255a52ef0b9b29543deeca97c1b887e Author: Hinrik Örn Sigurðsson <hinrik....@gmail.com> Commit: Hinrik Örn Sigurðsson <hinrik....@gmail.com>
Complete support for embedded/multiline comments Supports comments with any set and amount of paired delimiters. I'm bumping the Emacs version requirement due to this: http://git.savannah.gnu.org/cgit/emacs.git/commit/lisp/emacs-lisp/syntax.el?id=70203c2ec17efdb68b0873e4a62e2862a347e095 --- perl6-font-lock.el | 54 +++++++++++++++++++++++++++++++++++++++++++++---- perl6-mode.el | 3 ++- test/perl6-mode-test.el | 7 ++++--- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/perl6-font-lock.el b/perl6-font-lock.el index d388af17b5..fc7d979ffc 100644 --- a/perl6-font-lock.el +++ b/perl6-font-lock.el @@ -177,6 +177,53 @@ table) "The top level syntax table for Perl 6.") +(defvar perl6-comment-syntax-table + (let ((table (make-syntax-table perl6-mode-syntax-table))) + (modify-syntax-entry ?< "(>" table) + (modify-syntax-entry ?> ")<" table) + table) + "Syntax table for comments.") + +(defun perl6-forward-embedded-comment (open close length) + "Move point past the end of an embedded comment. + +Skips over any nested balanced delimiters. + +OPEN and CLOSE are the delimiting characters (e.g. ?< and ?>). +LENGTH is the length of the delimiters (e.g. 2 for a #`<<foo>> comment)." + (let ((pattern (rx-to-string `(or (group (= ,length ,open)) + (group (= ,length ,close))))) + (found-closing nil) + (depth 1)) + (while (and (not found-closing) + (< (point) (point-max))) + (re-search-forward pattern (point-max) 'noerror) + (cond ((match-string 1) + (if (looking-at (rx-to-string open)) + (re-search-forward (rx-to-string `(1+ ,open))) + (setq depth (1+ depth)))) + ((match-string 2) + (setq depth (1- depth)) + (when (eq depth 0) + (setq found-closing t))))))) + +(defun perl6-syntax-propertize-embedded-comment () + "Add syntax properties to embedded comments." + (with-syntax-table perl6-comment-syntax-table + (when (and (following-char) + (eq ?\( (char-syntax (following-char)))) + (let* ((comment-beg (- (point) 2)) + (open-delim (following-char)) + (close-delim (matching-paren open-delim))) + (put-text-property comment-beg (1+ comment-beg) + 'syntax-table (string-to-syntax "!")) + (re-search-forward (rx-to-string `(1+ ,open-delim))) + (let ((delim-length (length (match-string 0)))) + (perl6-forward-embedded-comment open-delim close-delim delim-length) + (put-text-property comment-beg (point) 'syntax-multiline t) + (put-text-property (- (point) 1) (point) + 'syntax-table (string-to-syntax "!"))))))) + (defun perl6-syntax-propertize (start end) "Add context-specific syntax properties to code. @@ -188,10 +235,9 @@ Takes arguments START and END which delimit the region to propertize." ;; [-'] between identifiers are symbol chars ((rx (any "A-Za-z") (group (any "-'")) (any "A-Za-z")) (1 "_")) - ;; multiline comments - ((rx (group "#`<") (*? anything) (group ">")) - (1 "< b") - (2 "> b"))) + ; multiline comments + ((rx "#`") + (0 (ignore (perl6-syntax-propertize-embedded-comment))))) start end))) (defun perl6-font-lock-syntactic-face (state) diff --git a/perl6-mode.el b/perl6-mode.el index 333c38b9eb..5add05750a 100644 --- a/perl6-mode.el +++ b/perl6-mode.el @@ -6,7 +6,7 @@ ;; URL: https://github.com/hinrik/perl6-mode ;; Keywords: languages ;; Version: 0.1-git -;; Package-Requires: ((emacs "24.3") (pkg-info "0.1")) +;; Package-Requires: ((emacs "24.4") (pkg-info "0.1")) ;; This file is not part of GNU Emacs. @@ -46,6 +46,7 @@ "Major mode for editing Perl 6 code." ;; Syntaxification and font locking (setq-local syntax-propertize-function 'perl6-syntax-propertize) + (add-hook 'syntax-propertize-extend-region-functions 'syntax-propertize-multiline nil 'local) (setq-local font-lock-syntactic-face-function 'perl6-font-lock-syntactic-face) (setq-local font-lock-defaults '(perl6-font-lock-keywords nil nil)) ;; Comments diff --git a/test/perl6-mode-test.el b/test/perl6-mode-test.el index c7126e7d7b..b8fc39be6f 100644 --- a/test/perl6-mode-test.el +++ b/test/perl6-mode-test.el @@ -64,12 +64,13 @@ POS." (ert-deftest perl6-mode-syntax-table/fontify-line-comment () :tags '(fontification syntax-table) (perl6-test-with-temp-buffer "# class -bar" - ;(should (eq (perl6-test-face-at 1) 'font-lock-comment-delimiter-face)) +bar #`<foo> baz" (should (eq (perl6-test-face-at 3) 'perl6-comment)) (should (eq (perl6-test-face-at 7) 'perl6-comment)) (should (eq (perl6-test-face-at 8) 'perl6-comment)) - (should (eq (perl6-test-face-at 9) 'perl6-identifier)))) + (should (eq (perl6-test-face-at 9) 'perl6-identifier)) + (should (eq (perl6-test-face-at 16) 'perl6-comment)) + (should (eq (perl6-test-face-at 21) 'perl6-identifier)))) (ert-deftest perl6-font-lock-keywords/phaser () :tags '(fontification font-lock-keywords)