[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/typescript-mode 782e8dd32e 071/222: Add fontification supp
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/typescript-mode 782e8dd32e 071/222: Add fontification support for jsdoc/typedoc tags. |
Date: |
Sun, 6 Feb 2022 16:59:18 -0500 (EST) |
branch: elpa/typescript-mode
commit 782e8dd32e7b30fbecd52ff49eaa65b78af0800f
Author: Louis-Dominique Dubeau <ldd@lddubeau.com>
Commit: Louis-Dominique Dubeau <ldd@lddubeau.com>
Add fontification support for jsdoc/typedoc tags.
This commit adds the machinery necessary for fontifying the jsdoc-like
comments that appear in documentation comments (comments that start
with "/**").
---
typescript-mode-tests.el | 71 ++++++++++++++++
typescript-mode.el | 208 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 279 insertions(+)
diff --git a/typescript-mode-tests.el b/typescript-mode-tests.el
index ad69c1736e..cbc25dccdf 100644
--- a/typescript-mode-tests.el
+++ b/typescript-mode-tests.el
@@ -164,6 +164,77 @@ a severity set to WARNING, no rule name."
(ert-deftest re-search-backwards-skips-multi-line-comments ()
(test-re-search "token" "let token; /* token in \nmulti-line token comment"
0))
+;; Adapted from jdee-mode's test suite.
+(defmacro test-with-temp-buffer (content &rest body)
+ "Fill a temporary buffer with `CONTENT' and eval `BODY' in it."
+ (declare (debug t)
+ (indent 1))
+ `(with-temp-buffer
+ (insert ,content)
+ (typescript-mode)
+ (font-lock-fontify-buffer)
+ (goto-char (point-min))
+ ,@body))
+
+(defun get-face-at (loc)
+ "Get the face at `LOC'. If it is not a number, then we `re-search-forward'
with `LOC'
+as the search pattern."
+ (when (not (numberp loc))
+ (save-excursion
+ (re-search-forward loc)
+ (setq loc (match-beginning 0))))
+ (get-text-property loc 'face))
+
+(setq font-lock-contents
+ " * @param {Something} bar A parameter. References [[moo]] and [[foo]].
+ * @param second May hold ``x`` or ``y``.")
+
+(defun font-lock-test (contents expected)
+ "Perform a test on our template. `CONTENTS' is the string to
+put in the temporary buffer. `EXPECTED' is the expected
+results. It should be a list of (LOCATION . FACE) pairs."
+ (test-with-temp-buffer
+ contents
+ (dolist (spec expected)
+ (should (eq (get-face-at (car spec)) (cdr spec))))))
+
+(ert-deftest font-lock/documentation-in-documentation-comments ()
+ "Documentation in documentation comments should be fontified as
+documentation."
+ (font-lock-test
+ (concat "/**\n" font-lock-contents "\n*/")
+ '((1 . font-lock-comment-delimiter-face)
+ (5 . font-lock-comment-face)
+ ("@param" . typescript-jsdoc-tag)
+ ("{Something}" . typescript-jsdoc-type)
+ ("bar" . typescript-jsdoc-value)
+ ("\\[\\[moo\\]\\]" . typescript-jsdoc-value)
+ ("\\[\\[foo\\]\\]" . typescript-jsdoc-value)
+ ("``x``" . typescript-jsdoc-value)
+ ("``y``" . typescript-jsdoc-value))))
+
+(ert-deftest font-lock/no-documentation-in-non-documentation-comments ()
+ "Documentation tags that are not in documentation comments
+should not be fontified as documentation."
+ (test-with-temp-buffer
+ (concat "/*\n" font-lock-contents "\n*/\n")
+ (let ((loc 3))
+ ;; Make sure we start with the right face.
+ (should (eq (get-face-at loc) font-lock-comment-face))
+ (should (eq (text-property-not-all loc (point-max) 'face
font-lock-comment-face)
+ (1- (point-max)))))))
+
+(ert-deftest font-lock/no-documentation-in-strings ()
+ "Documentation tags that are not in strings should not be
+fontified as documentation."
+ (test-with-temp-buffer
+ (concat "const x = \"/**" font-lock-contents "*/\";")
+ (let ((loc (search-forward "\"")))
+ ;; Make sure we start with the right face.
+ (should (eq (get-face-at loc) font-lock-string-face))
+ ;; Make sure the face does not change later.
+ (should (eq (text-property-not-all loc (point-max) 'face
font-lock-string-face)
+ (1- (point-max)))))))
(provide 'typescript-mode-tests)
diff --git a/typescript-mode.el b/typescript-mode.el
index 6eaca9a16c..7f5f4c4375 100644
--- a/typescript-mode.el
+++ b/typescript-mode.el
@@ -414,6 +414,147 @@ Match group 1 is the name of the macro.")
:paren-depth most-negative-fixnum
:type 'toplevel))
+;; Note that all typedoc/jsdoc regexp by themselves would match occurrences
that appear outside
+;; documentation comments. The logic that uses these regexps must guard
against it.
+(defconst typescript-typedoc-link-tag-regexp
+ "\\[\\[.*?\\]\\]"
+ "Matches a typedoc link.")
+
+(defconst typescript-typedoc-literal-markup-regexp
+ "\\(`+\\).*?\\1"
+ "Matches a typedoc keyword markup.")
+
+;; This was taken from js2-mode.
+(defconst typescript-jsdoc-param-tag-regexp
+ (concat "\\(?:^\\s-*\\*+\\|/\\*\\*\\)\\s-*\\(@"
+ "\\(?:param\\|arg\\(?:ument\\)?\\|prop\\(?:erty\\)?\\)"
+ "\\)"
+ "\\s-*\\({[^}]+}\\)?" ; optional type
+ "\\s-*\\[?\\([[:alnum:]_$\.]+\\)?\\]?" ; name
+ "\\_>")
+ "Matches jsdoc tags with optional type and optional param name.")
+
+;; This was taken from js2-mode.
+(defconst typescript-jsdoc-typed-tag-regexp
+ (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+ (regexp-opt
+ '("enum"
+ "extends"
+ "field"
+ "id"
+ "implements"
+ "lends"
+ "mods"
+ "requires"
+ "return"
+ "returns"
+ "throw"
+ "throws"))
+ "\\)\\)\\s-*\\({[^}]+}\\)?")
+ "Matches jsdoc tags with optional type.")
+
+;; This was taken from js2-mode.
+(defconst typescript-jsdoc-arg-tag-regexp
+ (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+ (regexp-opt
+ '("alias"
+ "augments"
+ "borrows"
+ "callback"
+ "bug"
+ "base"
+ "config"
+ "default"
+ "define"
+ "emits"
+ "exception"
+ "fires"
+ "func"
+ "function"
+ "member"
+ "memberOf"
+ "method"
+ "name"
+ "namespace"
+ "since"
+ "suppress"
+ "this"
+ "throws"
+ "type"
+ "version"))
+ "\\)\\)\\s-+\\([^ \t]+\\)")
+ "Matches jsdoc tags with a single argument.")
+
+;; This was taken from js2-mode.
+(defconst typescript-jsdoc-empty-tag-regexp
+ (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+ (regexp-opt
+ '("addon"
+ "author"
+ "class"
+ "const"
+ "constant"
+ "constructor"
+ "constructs"
+ "copyright"
+ "deprecated"
+ "desc"
+ "description"
+ "event"
+ "example"
+ "exec"
+ "export"
+ "fileoverview"
+ "final"
+ "func"
+ "function"
+ "hidden"
+ "ignore"
+ "implicitCast"
+ "inheritDoc"
+ "inner"
+ "interface"
+ "license"
+ "method"
+ "noalias"
+ "noshadow"
+ "notypecheck"
+ "override"
+ "owner"
+ "preserve"
+ "preserveTry"
+ "private"
+ "protected"
+ "public"
+ "static"
+ "supported"
+ ))
+ "\\)\\)\\s-*")
+ "Matches empty jsdoc tags.")
+
+;; Note that this regexp by itself would match tslint flags that appear inside
+;; strings. The logic using this regexp must guard against it.
+(defconst typescript-tslint-flag-regexp
+ "\\(?://\\|/\\*\\)\\s-*\\(tslint:.*?\\)\\(?:\\*/\\|$\\)"
+ "Matches tslint flags.")
+
+;;; Faces
+
+(defface typescript-jsdoc-tag
+ '((t :foreground "SlateGray"))
+ "Face used to highlight @whatever tags in jsdoc comments."
+ :group 'typescript)
+
+(defface typescript-jsdoc-type
+ '((t :foreground "SteelBlue"))
+ "Face used to highlight {FooBar} types in jsdoc comments."
+ :group 'typescript)
+
+(defface typescript-jsdoc-value
+ '((t :foreground "gold4"))
+ "Face used to highlight tag values in jsdoc comments."
+ :group 'typescript)
+
;;; User Customization
(defgroup typescript nil
@@ -1417,6 +1558,53 @@ point of view of font-lock. It applies highlighting
directly with
;; Matcher always "fails"
nil)
+(defun typescript--in-documentation-comment-p ()
+ "Reports whether point is inside a documentation comment."
+ (let ((parse (syntax-ppss)))
+ (and
+ (nth 4 parse) ;; Inside a comment ...
+ (save-match-data
+ (save-excursion
+ (goto-char (nth 8 parse))
+ (looking-at "/\\*\\*")))))) ;; ... which starts with /**
+
+(defun typescript--documentation-font-lock-helper (re limit)
+ "This is a helper macro that determines whether jsdoc highlighting is to be
applied,
+and searches for the next token to be highlighted."
+ (loop while (re-search-forward re limit t)
+ if (typescript--in-documentation-comment-p)
+ return (point)))
+
+(defun typescript--jsdoc-param-matcher (limit)
+ "Font-lock mode matcher that finds jsdoc parameter tags in documentation."
+ (typescript--documentation-font-lock-helper
typescript-jsdoc-param-tag-regexp limit))
+
+(defun typescript--jsdoc-typed-tag-matcher (limit)
+ "Font-lock mode matcher that finds jsdoc typed tags in documentation."
+ (typescript--documentation-font-lock-helper
typescript-jsdoc-typed-tag-regexp limit))
+
+(defun typescript--jsdoc-arg-tag-matcher (limit)
+ "Font-lock mode matcher that finds jsdoc tags that take one argument in
documentation."
+ (typescript--documentation-font-lock-helper typescript-jsdoc-arg-tag-regexp
limit))
+
+(defun typescript--jsdoc-empty-tag-matcher (limit)
+ "Font-lock mode matcher that finds jsdoc tags without argument in
documentation."
+ (typescript--documentation-font-lock-helper
typescript-jsdoc-empty-tag-regexp limit))
+
+(defun typescript--typedoc-link-matcher (limit)
+ "Font-lock mode matcher that finds typedoc links in documentation."
+ (typescript--documentation-font-lock-helper
typescript-typedoc-link-tag-regexp limit))
+
+(defun typescript--typedoc-literal-markup-matcher (limit)
+ "Font-lock mode matcher that finds typedoc literal markup in documentation."
+ (typescript--documentation-font-lock-helper
typescript-typedoc-literal-markup-regexp limit))
+
+(defun typescript--tslint-flag-matcher (limit)
+ "Font-lock mode matcher that finds tslint flags in comments."
+ (loop while (re-search-forward typescript-tslint-flag-regexp limit t)
+ if (nth 4 (syntax-ppss (match-beginning 1)))
+ return (point)))
+
(defconst typescript--font-lock-keywords-3
`(
;; This goes before keywords-2 so it gets used preferentially
@@ -1428,6 +1616,26 @@ point of view of font-lock. It applies highlighting
directly with
,@typescript--font-lock-keywords-2
+ (typescript--jsdoc-param-matcher (1 'typescript-jsdoc-tag t t)
+ (2 'typescript-jsdoc-type t t)
+ (3 'typescript-jsdoc-value t t))
+
+ (typescript--jsdoc-typed-tag-matcher (1 'typescript-jsdoc-tag t t)
+ (2 'typescript-jsdoc-type t t))
+
+ (typescript--jsdoc-arg-tag-matcher (1 'typescript-jsdoc-tag t t)
+ (2 'typescript-jsdoc-value t t))
+
+ (typescript--jsdoc-empty-tag-matcher (1 'typescript-jsdoc-tag t t))
+
+ (typescript--typedoc-link-matcher (0 'typescript-jsdoc-value t))
+
+ (typescript--typedoc-literal-markup-matcher
+ (0 'typescript-jsdoc-value t))
+
+ (typescript--tslint-flag-matcher
+ (1 font-lock-preprocessor-face t))
+
("\\.\\(prototype\\)\\_>"
(1 font-lock-constant-face))
- [nongnu] elpa/typescript-mode c766ec8009 159/222: Include symbol constituents in typescript--function-call-re, (continued)
- [nongnu] elpa/typescript-mode c766ec8009 159/222: Include symbol constituents in typescript--function-call-re, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 5e0b9ee095 168/222: Add a test that fails without the following indentation fix., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 42a60e5c88 190/222: Merge pull request #137 from sirikid/feature/comma-first-lists, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 1c2a8b2391 211/222: Move build to use proper tasks, support OSX and Windows., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 7f1cde0a90 221/222: Make c-comment-line-break-function work as expected., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 438fc968bf 016/222: Highlight set and get keyword, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode b6e993513c 015/222: Merge pull request #10 from nahuel/patch-1, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 09123ba690 002/222: prepare for melpa, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode abc0751c0e 025/222: Merge pull request #22 from josteink/master, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 5931f2776d 049/222: Add keyof keyword., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 782e8dd32e 071/222: Add fontification support for jsdoc/typedoc tags.,
ELPA Syncer <=
- [nongnu] elpa/typescript-mode f6d28c7a0d 073/222: Remove the fontification hack., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 4b69ca57f5 080/222: Simplify regexp literal, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 7249d76e2d 097/222: Merge pull request #64 from dakra/master, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode d1ddaad259 089/222: Fix indentation of continued expressions., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 526f307ca8 101/222: Fontify yield and yield* as keyword, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 67d67f0c20 099/222: Typo in the readme, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode b5e3f2a8a6 100/222: Merge pull request #68 from GeertVL/patch-1, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode a5f342e539 160/222: Add snake_cased function call to regression test suite, ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 6eaddf6c17 162/222: Drop the custom insert-and-indent code in favor of electric-indent., ELPA Syncer, 2022/02/06
- [nongnu] elpa/typescript-mode 0fc7297870 184/222: Add compilation-mode support for ng lint too., ELPA Syncer, 2022/02/06