]> git.eshelyaron.com Git - emacs.git/commitdiff
Make tree-sitter based modes optional
authorEli Zaretskii <eliz@gnu.org>
Fri, 20 Jan 2023 08:28:26 +0000 (10:28 +0200)
committerEli Zaretskii <eliz@gnu.org>
Fri, 20 Jan 2023 08:28:26 +0000 (10:28 +0200)
* lisp/progmodes/c-ts-mode.el: Update Commentary.  Make
'auto-mode-alist' update conditional on the tree-sitter and
grammar libraries being available.
* lisp/progmodes/cmake-ts-mode.el:
* lisp/progmodes/csharp-mode.el:
* lisp/progmodes/dockerfile-ts-mode.el:
* lisp/progmodes/go-ts-mode.el:
* lisp/progmodes/java-ts-mode.el:
* lisp/progmodes/js.el:
* lisp/progmodes/json-ts-mode.el:
* lisp/progmodes/python.el:
* lisp/progmodes/ruby-ts-mode.el:
* lisp/progmodes/typescript-ts-mode.el:
* lisp/textmodes/css-mode.el:
* lisp/textmodes/toml-ts-mode.el:
* lisp/textmodes/yaml-ts-mode.el: Make 'auto-mode-alist' update
for tree-sitter based modes be conditional on the tree-sitter and
grammar libraries being available.  (Bug#60559)

16 files changed:
etc/NEWS
lisp/progmodes/c-ts-mode.el
lisp/progmodes/cmake-ts-mode.el
lisp/progmodes/csharp-mode.el
lisp/progmodes/dockerfile-ts-mode.el
lisp/progmodes/go-ts-mode.el
lisp/progmodes/java-ts-mode.el
lisp/progmodes/js.el
lisp/progmodes/json-ts-mode.el
lisp/progmodes/python.el
lisp/progmodes/ruby-ts-mode.el
lisp/progmodes/rust-ts-mode.el
lisp/progmodes/typescript-ts-mode.el
lisp/textmodes/css-mode.el
lisp/textmodes/toml-ts-mode.el
lisp/textmodes/yaml-ts-mode.el

index 38f2db26a1aa24b59a98a3ba247dcb9b2100e6fa..fa0e7a1f661fba5804e2ec27d606cc0643f2233a 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -34,13 +34,14 @@ This feature existed in Emacs 28.1, but was less easy to request.
 
 +++
 ** Emacs can be built with the tree-sitter parsing library.
-This library, together with grammar libraries, provides incremental
-parsing capabilities for several popular programming languages and
-other formatted files.  Emacs built with this library offers major
-modes, described elsewhere in this file, that are based on the
-tree-sitter's parsers.  If you have the tree-sitter library
-installed, the configure script will automatically include it in the
-build; use '--without-tree-sitter' at configure time to disable that.
+This library, together with separate grammar libraries for each
+language, provides incremental parsing capabilities for several
+popular programming languages and other formatted files.  Emacs built
+with this library offers major modes, described elsewhere in this
+file, that are based on the tree-sitter's parsers.  If you have the
+tree-sitter library installed, the configure script will automatically
+include it in the build; use '--without-tree-sitter' at configure time
+to disable that.
 
 Emacs modes based on the tree-sitter library require an additional
 grammar library for each mode.  These grammar libraries provide the
@@ -3183,19 +3184,19 @@ indentation, and navigation by defuns based on parsing the buffer text
 by a tree-sitter parser.  Some major modes also offer support for
 Imenu and 'which-func'.
 
-Where major modes already exist in Emacs for editing certain kinds of
-files, the new modes based on tree-sitter are for now entirely
-optional, and you must turn them on manually, or customize
-'auto-mode-alist' to turn them on automatically.
+The new modes based on tree-sitter are for now entirely optional, and
+you must turn them on manually, or load them in your init file, or
+customize 'auto-mode-alist' to turn them on automatically for certain
+files.  You can also customize 'major-mode-remap-alist' to
+automatically turn on some tree-sitter based modes for the same files
+for which a "built-in" mode would be turned on.  For example:
 
-Where no major modes previously existed in Emacs for editing the kinds
-of files for which Emacs now provides a tree-sitter based mode, Emacs
-will now try to enable these new modes automatically when you visit
-such files, and will display a warning if the tree-sitter library or
-the parser grammar library is not available.  To prevent the warnings,
-either build Emacs with tree-sitter and install the grammar libraries,
-or customize 'auto-mode-alist' to specify some other major mode (or
-even 'fundamental-mode') for those kinds of files.
+  (add-to-list 'major-mode-remap-alist '(ruby-mode . ruby-ts-mode))
+
+If you try these modes and don't like them, you can go back to the
+"built-in" modes by restarting Emacs.  But please tell us why you
+didn't like the tree-sitter based modes, so that we could try
+improving them.
 
 Each major mode based on tree-sitter needs a language grammar library,
 usually named "libtree-sitter-LANG.so" ("libtree-sitter-LANG.dll" on
@@ -3212,20 +3213,18 @@ We recommend to install these libraries in one of the standard system
 locations (the last place in the above list).
 
 If a language grammar library required by a mode is not found in any
-of the above places, the mode will signal an error when you try to
+of the above places, the mode will display a warning when you try to
 turn it on.
 
 +++
 *** New major mode 'typescript-ts-mode'.
 A major mode based on the tree-sitter library for editing programs
-in the TypeScript language.  This mode is auto-enabled for files with
-the ".ts" extension.
+in the TypeScript language.
 
 +++
 *** New major mode 'tsx-ts-mode'.
 A major mode based on the tree-sitter library for editing programs
-in the TypeScript language, with support for TSX.  This mode is
-auto-enabled for files with the ".tsx" extension.
+in the TypeScript language, with support for TSX.
 
 +++
 *** New major mode 'c-ts-mode'.
@@ -3275,15 +3274,12 @@ Bash shell scripts.
 +++
 *** New major mode 'dockerfile-ts-mode'.
 A major mode based on the tree-sitter library for editing
-Dockerfiles.  This mode is auto-enabled for files which are named
-"Dockerfile", have the "Dockerfile." prefix, or have the ".dockerfile"
-extension.
+Dockerfiles.
 
 +++
 *** New major mode 'cmake-ts-mode'.
 A major mode based on the tree-sitter library for editing CMake files.
-It is auto-enabled for files whose name is "CMakeLists.txt" or whose
-extension is ".cmake".
+
 
 +++
 *** New major mode 'toml-ts-mode'.
@@ -3293,23 +3289,22 @@ files written in TOML, a format for writing configuration files.
 +++
 *** New major mode 'go-ts-mode'.
 A major mode based on the tree-sitter library for editing programs in
-the Go language.  It is auto-enabled for files with the ".go" extension.
+the Go language.
 
 +++
 *** New major mode 'go-mod-ts-mode'.
 A major mode based on the tree-sitter library for editing "go.mod"
-files.  It is auto-enabled for files which are named "go.mod".
+files.
 
 +++
 *** New major mode 'yaml-ts-mode'.
 A major mode based on the tree-sitter library for editing files
-written in YAML.  It is auto-enabled for files with the ".yaml" or
-".yml" extensions.
+written in YAML.
 
 +++
 *** New major mode 'rust-ts-mode'.
 A major mode based on the tree-sitter library for editing programs in
-the Rust language.  It is auto-enabled for files with the ".rs" extension.
+the Rust language.
 
 ---
 *** New major mode 'ruby-ts-mode'.
index 3d887971f643fd9b159b23b395f23dbf0370f524..5749e568185db80d2a22b96a5c8f2d09eadce1cf 100644 (file)
 ;; `c-or-c++-ts-mode' which automatically chooses the right mode for
 ;; C/C++ header files.
 ;;
-;; To use these more by default, evaluate
+;; To use these modes by default, assuming you have the respective
+;; tree-sitter grammars available, do one of the following:
 ;;
-;; (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
-;; (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
-;; (add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode))
+;; - If you have both C and C++ grammars installed, add
 ;;
-;; in your configuration.
+;;    (require 'c-ts-mode)
+;;
+;;   to your init file.
+;;
+;; - Add one or mode of the following to your init file:
+;;
+;;    (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
+;;    (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
+;;    (add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode))
+;;
+;;   If you have only C grammar available, use only the first one; if
+;;   you have only the C++ grammar, use only the second one.
+;;
+;; - Customize 'auto-mode-alist' to turn one or more of the modes
+;;   automatically.  For example:
+;;
+;;     (add-to-list 'auto-mode-alist
+;;                  '("\\(\\.ii\\|\\.\\(CC?\\|HH?\\)\\|\\.[ch]\\(pp\\|xx\\|\\+\\+\\)\\|\\.\\(cc\\|hh\\)\\)\\'"
+;;                    . c++-ts-mode))
+;;
+;;   will turn on the c++-ts-mode for C++ source files.
+;;
+;; You can also turn on these modes manually in a buffer.  Doing so
+;; will set up Emacs to use the C/C++ modes defined here for other
+;; files, provided that you have the corresponding parser grammar
+;; libraries installed.
 ;;
 ;; For C-like language major modes:
 ;;
@@ -1072,6 +1096,22 @@ the code is C or C++ and based on that chooses whether to enable
             (re-search-forward c-ts-mode--c-or-c++-regexp nil t))))
       (c++-ts-mode)
     (c-ts-mode)))
+;; The entries for C++ must come first to prevent *.c files be taken
+;; as C++ on case-insensitive filesystems, since *.C files are C++,
+;; not C.
+(if (treesit-ready-p 'cpp)
+    (add-to-list 'auto-mode-alist
+                 '("\\(\\.ii\\|\\.\\(CC?\\|HH?\\)\\|\\.[ch]\\(pp\\|xx\\|\\+\\+\\)\\|\\.\\(cc\\|hh\\)\\)\\'"
+                   . c++-ts-mode)))
+
+(if (treesit-ready-p 'c)
+    (add-to-list 'auto-mode-alist
+                 '("\\(\\.[chi]\\|\\.lex\\|\\.y\\(acc\\)?\\|\\.x[bp]m\\)\\'"
+                   . c-ts-mode)))
+
+(if (and (treesit-ready-p 'cpp)
+         (treesit-ready-p 'c))
+    (add-to-list 'auto-mode-alist '("\\.h\\'" . c-or-c++-ts-mode)))
 
 (provide 'c-ts-mode)
 
index a31250f68be837c3f48835831591cccb87f77d8d..c241a2868e57dab3bdf9b2cb9562c17177eccdcb 100644 (file)
@@ -194,10 +194,6 @@ the subtrees."
      (t
       `((,name . ,marker))))))
 
-;;;###autoload
-(add-to-list 'auto-mode-alist
-             '("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode))
-
 ;;;###autoload
 (define-derived-mode cmake-ts-mode prog-mode "CMake"
   "Major mode for editing CMake files, powered by tree-sitter."
@@ -229,6 +225,10 @@ the subtrees."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'cmake)
+    (add-to-list 'auto-mode-alist
+                 '("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode)))
+
 (provide 'cmake-ts-mode)
 
 ;;; cmake-ts-mode.el ends here
index 81ce41618e7d0c4882d0e10af082422618c7ea5a..04f7f2223620bb580e8a9350c45c7f990a5db051 100644 (file)
@@ -883,9 +883,6 @@ Return nil if there is no name or if NODE is not a defun node."
        node "name")
       t))))
 
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode))
-
 ;;;###autoload
 (define-derived-mode csharp-mode prog-mode "C#"
   "Major mode for editing Csharp code.
@@ -941,7 +938,9 @@ Key bindings:
                 ("Struct" "\\`struct_declaration\\'" nil nil)
                 ("Method" "\\`method_declaration\\'" nil nil)))
 
-  (treesit-major-mode-setup))
+  (treesit-major-mode-setup)
+
+  (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-ts-mode)))
 
 (provide 'csharp-mode)
 
index 3f8766e6713f06af4afe0c2e549fa209416f15fc..2a295e885b06f208549a42158973dcf049f255ec 100644 (file)
@@ -132,12 +132,6 @@ the subtrees."
      (t
       `((,name . ,marker))))))
 
-;;;###autoload
-(add-to-list 'auto-mode-alist
-             ;; NOTE: We can't use `rx' here, as it breaks bootstrap.
-             '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)\\'"
-               . dockerfile-ts-mode))
-
 ;;;###autoload
 (define-derived-mode dockerfile-ts-mode prog-mode "Dockerfile"
   "Major mode for editing Dockerfiles, powered by tree-sitter."
@@ -172,6 +166,12 @@ the subtrees."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'dockerfile)
+    (add-to-list 'auto-mode-alist
+                 ;; NOTE: We can't use `rx' here, as it breaks bootstrap.
+                 '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)\\'"
+                   . dockerfile-ts-mode)))
+
 (provide 'dockerfile-ts-mode)
 
 ;;; dockerfile-ts-mode.el ends here
index 64e761d2f72d1e629561c49321d14db9b11d643f..d552e1360e0d8ae76b959aec24342d624bb281aa 100644 (file)
    '((ERROR) @font-lock-warning-face))
   "Tree-sitter font-lock settings for `go-ts-mode'.")
 
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode))
-
 ;;;###autoload
 (define-derived-mode go-ts-mode prog-mode "Go"
   "Major mode for editing Go, powered by tree-sitter."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'go)
+    (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)))
+
 (defun go-ts-mode--defun-name (node)
   "Return the defun name of NODE.
 Return nil if there is no name or if NODE is not a defun node."
@@ -345,9 +345,6 @@ what the parent of the node would be if it were a node."
    '((ERROR) @font-lock-warning-face))
   "Tree-sitter font-lock settings for `go-mod-ts-mode'.")
 
-;;;###autoload
-(add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode))
-
 ;;;###autoload
 (define-derived-mode go-mod-ts-mode prog-mode "Go Mod"
   "Major mode for editing go.mod files, powered by tree-sitter."
@@ -376,6 +373,9 @@ what the parent of the node would be if it were a node."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'gomod)
+    (add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode)))
+
 (provide 'go-ts-mode)
 
 ;;; go-ts-mode.el ends here
index d29fcd808612755fde6481e78ee1c1f31b469590..d909a366e5d553295eff9463117454b94e8d83be 100644 (file)
@@ -331,6 +331,9 @@ Return nil if there is no name or if NODE is not a defun node."
                 ("Method" "\\`method_declaration\\'" nil nil)))
   (treesit-major-mode-setup))
 
+(if (treesit-ready-p 'java)
+    (add-to-list 'auto-mode-alist '("\\.java\\'" . java-ts-mode)))
+
 (provide 'java-ts-mode)
 
 ;;; java-ts-mode.el ends here
index cc556c4d0ec38c70cb423ee7fb5911dca337bf6d..176024863f15005b32963a73fb5817ffc3999020 100644 (file)
@@ -3843,7 +3843,10 @@ Currently there are `js-mode' and `js-ts-mode'."
                                         "method_definition")
                                 eos)
                    nil nil)))
-    (treesit-major-mode-setup)))
+    (treesit-major-mode-setup)
+
+    (add-to-list 'auto-mode-alist
+                 '("\\(\\.js[mx]\\|\\.har\\)\\'" . js-ts-mode))))
 
 ;;;###autoload
 (define-derived-mode js-json-mode js-mode "JSON"
index fbcda22acca391523afddb85eb99039b9be8ee41..f54d0187f989b374d5a8ac7c0b39da779c503061 100644 (file)
@@ -160,6 +160,10 @@ Return nil if there is no name or if NODE is not a defun node."
 
   (treesit-major-mode-setup))
 
+(if (treesit-ready-p 'json)
+    (add-to-list 'auto-mode-alist
+                 '("\\.json\\'" . json-ts-mode)))
+
 (provide 'json-ts-mode)
 
 ;;; json-ts-mode.el ends here
index 21d16db287c8788b7a1f8e5c5eddce25104ebbdd..a869cdc5fdbbd7a6a621d537c96ca603a062504e 100644 (file)
@@ -6713,7 +6713,10 @@ implementations: `python-mode' and `python-ts-mode'."
     (treesit-major-mode-setup)
 
     (when python-indent-guess-indent-offset
-      (python-indent-guess-indent-offset))))
+      (python-indent-guess-indent-offset))
+
+    (add-to-list 'auto-mode-alist
+                 '("\\.py[iw]?\\'\\|python[0-9.]*" . python-ts-mode))))
 
 ;;; Completion predicates for M-x
 ;; Commands that only make sense when editing Python code
index 45174811605f71996aaed331ee6d94d8f6d2aff6..d143c06a8a4bc02e9ba916d1c1a71512d87a3216 100644 (file)
@@ -1047,6 +1047,20 @@ leading double colon is not added."
 
   (treesit-major-mode-setup))
 
+(if (treesit-ready-p 'ruby)
+    ;; Copied from ruby-mode.el.
+    (add-to-list 'auto-mode-alist
+                 (cons (concat "\\(?:\\.\\(?:"
+                               "rbw?\\|ru\\|rake\\|thor"
+                               "\\|jbuilder\\|rabl\\|gemspec\\|podspec"
+                               "\\)"
+                               "\\|/"
+                               "\\(?:Gem\\|Rake\\|Cap\\|Thor"
+                               "\\|Puppet\\|Berks\\|Brew"
+                               "\\|Vagrant\\|Guard\\|Pod\\)file"
+                               "\\)\\'")
+                       'ruby-ts-mode)))
+
 (provide 'ruby-ts-mode)
 
 ;;; ruby-ts-mode.el ends here
index 7536726165ec0e6b5292d6976bd4c506639e9dd9..08590ae6a868359feba524feeb044ae7f99dec72 100644 (file)
@@ -275,9 +275,6 @@ Return nil if there is no name or if NODE is not a defun node."
      (treesit-node-text
       (treesit-node-child-by-field-name node "name") t))))
 
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))
-
 ;;;###autoload
 (define-derived-mode rust-ts-mode prog-mode "Rust"
   "Major mode for editing Rust, powered by tree-sitter."
@@ -322,6 +319,9 @@ Return nil if there is no name or if NODE is not a defun node."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'rust)
+    (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode)))
+
 (provide 'rust-ts-mode)
 
 ;;; rust-ts-mode.el ends here
index ffd5b941dafcea524f80a34adfab48073e12f9ea..6aaa852895c682c730d3180daacb33a7c9dfb412 100644 (file)
@@ -314,12 +314,6 @@ Argument LANGUAGE is either `typescript' or `tsx'."
    :override t
    '((escape_sequence) @font-lock-escape-face)))
 
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode))
-
 ;;;###autoload
 (define-derived-mode typescript-ts-base-mode prog-mode "TypeScript"
   "Major mode for editing TypeScript."
@@ -375,6 +369,9 @@ Argument LANGUAGE is either `typescript' or `tsx'."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'typescript)
+    (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode)))
+
 ;;;###autoload
 (define-derived-mode tsx-ts-mode typescript-ts-base-mode "TypeScript[TSX]"
   "Major mode for editing TypeScript."
@@ -410,6 +407,9 @@ Argument LANGUAGE is either `typescript' or `tsx'."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'tsx)
+    (add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode)))
+
 (provide 'typescript-ts-mode)
 
 ;;; typescript-ts-mode.el ends here
index 8991610a50f58a7d6646f54b1326c7c8efebef9f..a1d7d4bbbec12bb8bfb6b74f9278dc807dd65eb6 100644 (file)
@@ -1827,7 +1827,9 @@ can also be used to fill comments.
     (setq-local treesit-simple-imenu-settings
                 `(( nil ,(rx bos (or "rule_set" "media_statement") eos)
                     nil nil)))
-    (treesit-major-mode-setup)))
+    (treesit-major-mode-setup)
+
+    (add-to-list 'auto-mode-alist '("\\.css\\'" . css-ts-mode))))
 
 ;;;###autoload
 (define-derived-mode css-mode css-base-mode "CSS"
index 2430c5f3e769614f254e5ba465d307ef8bb82350..416542084f1a3d6e9cf8e228c5e51c0dab517043 100644 (file)
@@ -117,8 +117,6 @@ Return nil if there is no name or if NODE is not a defun node."
      (or (treesit-node-text (treesit-node-child node 1) t)
          "Root table"))))
 
-(add-to-list 'auto-mode-alist '("\\.toml\\'" . toml-ts-mode))
-
 ;;;###autoload
 (define-derived-mode toml-ts-mode text-mode "TOML"
   "Major mode for editing TOML, powered by tree-sitter."
@@ -155,6 +153,9 @@ Return nil if there is no name or if NODE is not a defun node."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'toml)
+    (add-to-list 'auto-mode-alist '("\\.toml\\'" . toml-ts-mode)))
+
 (provide 'toml-ts-mode)
 
 ;;; toml-ts-mode.el ends here
index 8c61ee062cfeea4b11fe3ed5592cff920fc06731..a25230e6e61bc7a70a9683322fd456955460a1cb 100644 (file)
    '((ERROR) @font-lock-warning-face))
   "Tree-sitter font-lock settings for `yaml-ts-mode'.")
 
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.ya?ml\\'" . yaml-ts-mode))
-
 ;;;###autoload
 (define-derived-mode yaml-ts-mode text-mode "YAML"
   "Major mode for editing YAML, powered by tree-sitter."
 
     (treesit-major-mode-setup)))
 
+(if (treesit-ready-p 'yaml)
+    (add-to-list 'auto-mode-alist '("\\.ya?ml\\'" . yaml-ts-mode)))
+
 (provide 'yaml-ts-mode)
 
 ;;; yaml-ts-mode.el ends here