;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+
;;; Code:
(require 'treesit)
table)
"Syntax table for `typescript-ts-mode'.")
-(defvar typescript-ts-mode--indent-rules
- `((tsx
+(defun typescript-ts-mode--indent-rules (language)
+ "Rules used for indentation.
+Argument LANGUAGE is either `typescript' or `tsx'."
+ `((,language
((parent-is "program") parent-bol 0)
((node-is "}") parent-bol 0)
((node-is ")") parent-bol 0)
((parent-is "arrow_function") parent-bol typescript-ts-mode-indent-offset)
((parent-is "parenthesized_expression") parent-bol typescript-ts-mode-indent-offset)
- ;; TSX
- ((parent-is "jsx_opening_element") parent typescript-ts-mode-indent-offset)
- ((node-is "jsx_closing_element") parent 0)
- ((parent-is "jsx_element") parent typescript-ts-mode-indent-offset)
- ((node-is "/") parent 0)
- ((parent-is "jsx_self_closing_element") parent typescript-ts-mode-indent-offset)
- (no-node parent-bol 0)))
- "Tree-sitter indent rules.")
+ ,@(when (eq language 'tsx)
+ `(((parent-is "jsx_opening_element") parent typescript-ts-mode-indent-offset)
+ ((node-is "jsx_closing_element") parent 0)
+ ((parent-is "jsx_element") parent typescript-ts-mode-indent-offset)
+ ((node-is "/") parent 0)
+ ((parent-is "jsx_self_closing_element") parent typescript-ts-mode-indent-offset)))
+ (no-node parent-bol 0))))
(defvar typescript-ts-mode--keywords
'("!" "abstract" "as" "async" "await" "break"
"&&" "||" "!" "?.")
"TypeScript operators for tree-sitter font-locking.")
-(defvar typescript-ts-mode--font-lock-settings
+(defun typescript-ts-mode--font-lock-settings (language)
+ "Tree-sitter font-lock settings.
+Argument LANGUAGE is either `typescript' or `tsx'."
(treesit-font-lock-rules
- :language 'tsx
+ :language language
:override t
:feature 'comment
`((comment) @font-lock-comment-face)
- :language 'tsx
+ :language language
:override t
:feature 'constant
`(((identifier) @font-lock-constant-face
[(true) (false) (null)] @font-lock-constant-face)
- :language 'tsx
+ :language language
:override t
:feature 'keyword
`([,@typescript-ts-mode--keywords] @font-lock-keyword-face
[(this) (super)] @font-lock-keyword-face)
- :language 'tsx
+ :language language
:override t
:feature 'string
`((regex pattern: (regex_pattern)) @font-lock-string-face
(template_string) @js--fontify-template-string
(template_substitution ["${" "}"] @font-lock-builtin-face))
- :language 'tsx
+ :language language
:override t
:feature 'declaration
`((function
(identifier) @font-lock-function-name-face)
value: (array (number) (function))))
- :language 'tsx
+ :language language
:override t
:feature 'identifier
`((nested_type_identifier
(_ (_ (identifier) @font-lock-variable-name-face))
(_ (_ (_ (identifier) @font-lock-variable-name-face)))]))
- :language 'tsx
+ :language language
:override t
:feature 'expression
'((assignment_expression
(member_expression
property: (property_identifier) @font-lock-function-name-face)]))
- :language 'tsx
+ :language language
:override t
:feature 'pattern
`((pair_pattern
(array_pattern (identifier) @font-lock-variable-name-face))
- :language 'tsx
+ :language language
:override t
:feature 'jsx
`((jsx_opening_element
(jsx_attribute (property_identifier) @font-lock-constant-face))
- :language 'tsx
+ :language language
:feature 'number
`((number) @font-lock-number-face
((identifier) @font-lock-number-face
(:match "^\\(:?NaN\\|Infinity\\)$" @font-lock-number-face)))
- :language 'tsx
+ :language language
:feature 'operator
`([,@typescript-ts-mode--operators] @font-lock-operator-face
(ternary_expression ["?" ":"] @font-lock-operator-face))
- :language 'tsx
+ :language language
:feature 'bracket
'((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face)
- :language 'tsx
+ :language language
:feature 'delimiter
'((["," "." ";" ":"]) @font-lock-delimiter-face)
- :language 'tsx
+ :language language
:feature 'escape-sequence
:override t
'((escape_sequence) @font-lock-escape-face)
- :language 'tsx
+ :language language
:override t
:feature 'property
`((pair value: (identifier) @font-lock-variable-name-face)
((shorthand_property_identifier) @font-lock-property-face)
((shorthand_property_identifier_pattern)
- @font-lock-property-face)))
- "Tree-sitter font-lock settings.")
+ @font-lock-property-face))))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode))
;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-ts-mode))
+(add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode))
;;;###autoload
-(define-derived-mode typescript-ts-mode prog-mode "TypeScript"
+(define-derived-mode typescript-ts-base-mode prog-mode "TypeScript"
+ "Major mode for editing TypeScript."
+ :group 'typescript
+ :syntax-table typescript-ts-mode--syntax-table
+
+ ;; Comments.
+ (setq-local comment-start "// ")
+ (setq-local comment-end "")
+ (setq-local comment-start-skip "\\(?://+\\|/\\*+\\)\\s *")
+ (setq-local comment-end-skip
+ (rx (* (syntax whitespace))
+ (group (or (syntax comment-end)
+ (seq (+ "*") "/")))))
+
+ ;; Electric
+ (setq-local electric-indent-chars
+ (append "{}():;," electric-indent-chars))
+
+ ;; Navigation.
+ (setq-local treesit-defun-type-regexp
+ (regexp-opt '("class_declaration"
+ "method_definition"
+ "function_declaration"
+ "lexical_declaration")))
+ ;; Imenu.
+ (setq-local imenu-create-index-function #'js--treesit-imenu)
+
+ ;; Which-func (use imenu).
+ (setq-local which-func-functions nil))
+
+;;;###autoload
+(define-derived-mode typescript-ts-mode typescript-ts-base-mode "TypeScript"
+ "Major mode for editing TypeScript."
+ :group 'typescript
+ :syntax-table typescript-ts-mode--syntax-table
+
+ (when (treesit-ready-p 'typescript)
+ (treesit-parser-create 'typescript)
+
+ ;; Indent.
+ (setq-local treesit-simple-indent-rules
+ (typescript-ts-mode--indent-rules 'typescript))
+
+ ;; Font-lock.
+ (setq-local treesit-font-lock-settings
+ (typescript-ts-mode--font-lock-settings 'typescript))
+ (setq-local treesit-font-lock-feature-list
+ '((comment declaration)
+ (keyword string)
+ (constant expression identifier number pattern property)
+ (bracket delimiter)))
+
+ (treesit-major-mode-setup)))
+
+;;;###autoload
+(define-derived-mode tsx-ts-mode typescript-ts-base-mode "TypeScript[TSX]"
"Major mode for editing TypeScript."
:group 'typescript
:syntax-table typescript-ts-mode--syntax-table
;; Comments.
(setq-local comment-start "// ")
(setq-local comment-end "")
- (setq-local comment-start-skip (rx (group "/" (or (+ "/") (+ "*")))
- (* (syntax whitespace))))
+ (setq-local comment-start-skip "\\(?://+\\|/\\*+\\)\\s *")
(setq-local comment-end-skip
(rx (* (syntax whitespace))
(group (or (syntax comment-end)
(seq (+ "*") "/")))))
- ;; Electric
- (setq-local electric-indent-chars
- (append "{}():;," electric-indent-chars))
-
;; Indent.
- (setq-local treesit-simple-indent-rules typescript-ts-mode--indent-rules)
-
- ;; Navigation.
- (setq-local treesit-defun-type-regexp
- (rx (or "class_declaration"
- "method_definition"
- "function_declaration"
- "lexical_declaration")))
+ (setq-local treesit-simple-indent-rules
+ (typescript-ts-mode--indent-rules 'tsx))
;; Font-lock.
- (setq-local treesit-font-lock-settings typescript-ts-mode--font-lock-settings)
+ (setq-local treesit-font-lock-settings
+ (typescript-ts-mode--font-lock-settings 'tsx))
(setq-local treesit-font-lock-feature-list
- '(( comment declaration)
- ( keyword string)
- ( constant expression identifier jsx number pattern property)
- ( bracket delimiter)))
- ;; Imenu.
- (setq-local imenu-create-index-function #'js--treesit-imenu)
-
- ;; Which-func (use imenu).
- (setq-local which-func-functions nil)
+ '((comment declaration)
+ (keyword string)
+ (constant expression identifier jsx number pattern property)
+ (bracket delimiter)))
(treesit-major-mode-setup)))
-
(provide 'typescript-ts-mode)
;;; typescript-ts-mode.el ends here