Merge from origin/emacs-29

b3de81a6ee MH-E: handle removal of mhparam libdir from nmh 1.8
d63e1a8951 Use point-min to anchor top-level constructs (bug#60602)
3479333778 * lisp/org/ob-ruby.el: Fix outdated comments.
472f142598 ; ruby-ts-mode: Add a Version tag
0cf053648a ; ruby-ts-mode: Update font-lock features list in Commentary
67ee627c38 (project-try-vc): Add string-start and string-end anchors...
06953fc8e1 Make `keymap-set-after' work for menus
dcd59457b4 Use `key-parse' in `keymap-lookup'
8904a26a9d Improve `keymap-set-after' documentation
c7e02eaa3d Handle after arg correctly in `keymap-set-after'
628b624176 Don't load erc-goodies atop erc.el
40cf494b7c ; * etc/NEWS: Fix typos.
6b2f85caa6 Make tree-sitter based modes optional
b56cf28b32 ; (ruby-ts--predefined-variables): Make it a little shorter
d94dc606a0 ruby-ts-mode: Claw back half of the performance drop from...
d0d3451409 (ruby-ts-mode): Rename 'builtin-functions' to 'builtin-fu...
d66ac5285f ruby-ts-mode: Highlight builtin methods
370b1ac99e ; ruby-ts-mode.el: Add customize-group mention to commentary
7b7b2b9513 Fix c-ts-mode indent (bug#60873)
7ca71d66dc Fix various problems in treesit-explore-mode (bug#60800)
b7d6bb47ee ; * lisp/treesit.el (treesit-font-lock-fontify-region): M...
0c6bfeddb2 ; Update tree-sitter major mode manual
c289786886 ; Add commentary and dostring in c-ts-mode

# Conflicts:
#	etc/NEWS
#	lisp/progmodes/c-ts-mode.el
#	lisp/progmodes/go-ts-mode.el
This commit is contained in:
Stefan Kangas 2023-01-23 01:34:39 +01:00
commit 0805972e4c
27 changed files with 469 additions and 219 deletions

View file

@ -1378,7 +1378,8 @@ Binding Conventions}).
or if @var{key} is not a valid key.
@var{key} is a string representing a single key or a series of key
strokes. Key strokes are separated by a single space character.
strokes, and must satisfy @code{key-valid-p}. Key strokes are
separated by a single space character.
Each key stroke is either a single character, or the name of an
event, surrounded by angle brackets. In addition, any key stroke
@ -1413,6 +1414,7 @@ The only keys that have a special shorthand syntax are @kbd{NUL},
The modifiers have to be specified in alphabetical order:
@samp{A-C-H-M-S-s}, which is @samp{Alt-Control-Hyper-Meta-Shift-super}.
@findex keymap-set
@defun keymap-set keymap key binding
This function sets the binding for @var{key} in @var{keymap}. (If
@var{key} is more than one event long, the change is actually made
@ -3079,13 +3081,13 @@ the menu. To put it elsewhere in the menu, use @code{keymap-set-after}:
@defun keymap-set-after map key binding &optional after
Define a binding in @var{map} for @var{key}, with value @var{binding},
just like @code{define-key}, but position the binding in @var{map} after
the binding for the event @var{after}. The argument @var{key} should be
of length one---a vector or string with just one element. But
@var{after} should be a single event type---a symbol or a character, not
a sequence. The new binding goes after the binding for @var{after}. If
@var{after} is @code{t} or is omitted, then the new binding goes last, at
the end of the keymap. However, new bindings are added before any
inherited keymap.
the binding for the event @var{after}. The argument @var{key} should
represent a single menu item or key, and @var{after} should be a
single event type---a symbol or a character, not a sequence. The new
binding goes after the binding for @var{after}. If @var{after} is
@code{t} or is omitted, then the new binding goes last, at the end of
the keymap. However, new bindings are added before any inherited
keymap.
Here is an example:

View file

@ -1692,26 +1692,48 @@ integration for a major mode.
A major mode supporting tree-sitter features should roughly follow
this pattern:
@c FIXME: Update this part once we settle on the exact format.
@example
@group
(define-derived-mode woomy-mode prog-mode "Woomy"
"A mode for Woomy programming language."
;; Shared setup.
...
(cond
;; Tree-sitter setup.
((treesit-ready-p 'woomy)
(when (treesit-ready-p 'woomy)
(setq-local treesit-variables ...)
(treesit-major-mode-setup))
;; Non-tree-sitter setup.
(t
...)))
...
(treesit-major-mode-setup)))
@end group
@end example
First, the major mode should use @code{treesit-ready-p} to determine
whether tree-sitter can be activated in this mode.
@code{treesit-ready-p} automatically emits a warning if conditions for
enabling tree-sitter aren't met.
If a tree-sitter major mode shares setup with their ``native''
counterpart, they can create a ``base mode'' that contains the common
setup, like this:
@example
@group
(define-derived-mode woomy--base-mode prog-mode "Woomy"
"An internal mode for Woomy programming language."
(common-setup)
...)
@end group
@group
(define-derived-mode woomy-mode woomy--base-mode "Woomy"
"A mode for Woomy programming language."
(native-setup)
...)
@end group
@group
(define-derived-mode woomy-ts-mode woomy--base-mode "Woomy"
"A mode for Woomy programming language."
(when (treesit-ready-p 'woomy)
(setq-local treesit-variables ...)
...
(treesit-major-mode-setup)))
@end group
@end example
@defun treesit-ready-p language &optional quiet
This function checks for conditions for activating tree-sitter. It
@ -1722,15 +1744,12 @@ language grammar for @var{language} is available on the system
This function emits a warning if tree-sitter cannot be activated. If
@var{quiet} is @code{message}, the warning is turned into a message;
if @var{quiet} is @code{nil}, no warning or message is displayed.
if @var{quiet} is @code{t}, no warning or message is displayed.
If all the necessary conditions are met, this function returns
non-@code{nil}; otherwise it returns @code{nil}.
@end defun
Next, the major mode should set up tree-sitter variables and call
@code{treesit-major-mode-setup}.
@defun treesit-major-mode-setup
This function activates some tree-sitter features for a major mode.

View file

@ -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,11 @@ 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 +3288,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'.

View file

@ -61,7 +61,6 @@
(load "erc-loaddefs" 'noerror 'nomessage)
(require 'erc-networks)
(require 'erc-goodies)
(require 'erc-backend)
(require 'cl-lib)
(require 'format-spec)
@ -7386,4 +7385,6 @@ Customize `erc-url-connect-function' to override this."
(provide 'erc)
;; FIXME this is a temporary stopgap for Emacs 29.
(require 'erc-goodies)
;;; erc.el ends here

View file

@ -186,10 +186,17 @@ a menu, so this function is not useful for non-menu keymaps."
(declare (indent defun)
(compiler-macro (lambda (form) (keymap--compile-check key) form)))
(keymap--check key)
(when after
(keymap--check after))
(when (eq after t) (setq after nil)) ; nil and t are treated the same
(when (stringp after)
(keymap--check after)
(setq after (key-parse after)))
;; If we're binding this key to another key, then parse that other
;; key, too.
(when (stringp definition)
(keymap--check definition)
(setq definition (key-parse definition)))
(define-key-after keymap (key-parse key) definition
(and after (key-parse after))))
after))
(defun key-parse (keys)
"Convert KEYS to the internal Emacs key representation.
@ -404,7 +411,7 @@ specified buffer position instead of point are used."
(symbolp value))
(or (command-remapping value) value)
value))
(key-binding (kbd key) accept-default no-remap position)))
(key-binding (key-parse key) accept-default no-remap position)))
(defun keymap-local-lookup (keys &optional accept-default)
"Return the binding for command KEYS in current local keymap only.

View file

@ -764,6 +764,8 @@ This assumes that a temporary buffer is set up."
;; Sample '-version' outputs:
;; mhparam -- nmh-1.1-RC1 [compiled on chaak at Fri Jun 20 11:03:28 PDT 2003]
;; install-mh -- nmh-1.7.1 built October 26, 2019 on build-server-000
;; "libdir" was deprecated in nmh-1.7 in favor of "libexecdir", and
;; removed completely in nmh-1.8.
(let ((install-mh (expand-file-name "install-mh" dir)))
(when (mh-file-command-p install-mh)
(erase-buffer)
@ -774,7 +776,8 @@ This assumes that a temporary buffer is set up."
(mh-progs dir))
`(,version
(variant nmh)
(mh-lib-progs ,(mh-profile-component "libdir"))
(mh-lib-progs ,(or (mh-profile-component "libdir")
(mh-profile-component "libexecdir")))
(mh-lib ,(mh-profile-component "etcdir"))
(mh-progs ,dir)
(flists ,(file-exists-p

View file

@ -29,11 +29,10 @@
;; - ruby and irb executables :: https://www.ruby-lang.org/
;;
;; - ruby-mode :: Can be installed through ELPA, or from
;; https://github.com/eschulte/rinari/raw/master/util/ruby-mode.el
;; - ruby-mode :: Comes with Emacs.
;;
;; - inf-ruby mode :: Can be installed through ELPA, or from
;; https://github.com/eschulte/rinari/raw/master/util/inf-ruby.el
;; https://raw.githubusercontent.com/nonsequitur/inf-ruby/master/inf-ruby.el
;;; Code:

View file

@ -24,6 +24,58 @@
;;; Commentary:
;;
;; This package provides major modes for C and C++, plus some handy
;; functions that are useful generally to major modes for C-like
;; languages.
;;
;; This package provides `c-ts-mode' for C, `c++-ts-mode' for C++, and
;; `c-or-c++-ts-mode' which automatically chooses the right mode for
;; C/C++ header files.
;;
;; To use these modes by default, assuming you have the respective
;; tree-sitter grammars available, do one of the following:
;;
;; - If you have both C and C++ grammars installed, add
;;
;; (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:
;;
;; - Use `c-ts-mode-comment-setup' to setup comment variables and
;; filling.
;;
;; - Use simple-indent matcher `c-ts-mode--looking-at-star' and anchor
;; `c-ts-mode--comment-start-after-first-star' for indenting block
;; comments. See `c-ts-mode--indent-styles' for example.
;;
;; - Use variable `c-ts-mode-indent-block-type-regexp' with indent
;; offset c-ts-mode--statement-offset for indenting statements.
;; Again, see `c-ts-mode--indent-styles' for example.
;;; Code:
@ -115,7 +167,7 @@ delimiters < and >'s."
"Indent rules supported by `c-ts-mode'.
MODE is either `c' or `cpp'."
(let ((common
`(((parent-is "translation_unit") parent-bol 0)
`(((parent-is "translation_unit") point-min 0)
((node-is ")") parent 1)
((node-is "]") parent-bol 0)
((node-is "else") parent-bol 0)
@ -257,7 +309,18 @@ PARENT is NODE's parent."
(cl-incf level)
(save-excursion
(goto-char (treesit-node-start node))
(cond ((bolp) nil)
;; Add an extra level if the opening bracket is on its own
;; line, except (1) it's at top-level, or (2) it's immedate
;; parent is another block.
(cond ((bolp) nil) ; Case (1).
((let ((parent-type (treesit-node-type
(treesit-node-parent node))))
;; Case (2).
(and parent-type
(string-match-p c-ts-mode-indent-block-type-regexp
parent-type)))
nil)
;; Add a level.
((looking-back (rx bol (* whitespace))
(line-beginning-position))
(cl-incf level))))))
@ -967,7 +1030,16 @@ Set up:
This mode is independent from the classic cc-mode.el based
`c-mode', so configuration variables of that mode, like
`c-basic-offset', don't affect this mode."
`c-basic-offset', doesn't affect this mode.
To use tree-sitter C/C++ modes by default, evaluate
(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))
in your configuration."
:group 'c
(when (treesit-ready-p 'c)
@ -984,7 +1056,20 @@ This mode is independent from the classic cc-mode.el based
;;;###autoload
(define-derived-mode c++-ts-mode c-ts-base-mode "C++"
"Major mode for editing C++, powered by tree-sitter."
"Major mode for editing C++, powered by tree-sitter.
This mode is independent from the classic cc-mode.el based
`c++-mode', so configuration variables of that mode, like
`c-basic-offset', don't affect this mode.
To use tree-sitter C/C++ modes by default, evaluate
(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))
in your configuration."
:group 'c++
(when (treesit-ready-p 'cpp)
@ -1050,6 +1135,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)

View 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

View 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.
@ -946,7 +943,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)

View 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."
@ -176,6 +170,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

View file

@ -174,9 +174,6 @@
'((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))
(defvar-keymap go-ts-mode-map
:doc "Keymap used in Go mode, powered by tree-sitter"
:parent prog-mode-map
@ -233,6 +230,9 @@
(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."
@ -378,9 +378,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."
@ -409,6 +406,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

View file

@ -69,7 +69,7 @@
(defvar java-ts-mode--indent-rules
`((java
((parent-is "program") parent-bol 0)
((parent-is "program") point-min 0)
((node-is "}") (and parent parent-bol) 0)
((node-is ")") parent-bol 0)
((node-is "]") parent-bol 0)
@ -359,6 +359,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

View file

@ -3903,7 +3903,10 @@ See `treesit-sexp-type-regexp' for more information.")
"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"

View file

@ -162,6 +162,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

View file

@ -1,7 +1,7 @@
;;; project.el --- Operations on the current project -*- lexical-binding: t; -*-
;; Copyright (C) 2015-2023 Free Software Foundation, Inc.
;; Version: 0.9.4
;; Version: 0.9.5
;; Package-Requires: ((emacs "26.1") (xref "1.4.0"))
;; This is a GNU ELPA :core package. Avoid using functionality that
@ -514,11 +514,14 @@ project backend implementation of `project-external-roots'.")
(lambda (b) (assoc-default b backend-markers-alist))
vc-handled-backends)))
(marker-re
(mapconcat
(lambda (m) (format "\\(%s\\)" (wildcard-to-regexp m)))
(append backend-markers
(project--value-in-dir 'project-vc-extra-root-markers dir))
"\\|"))
(concat
"\\`"
(mapconcat
(lambda (m) (format "\\(%s\\)" (wildcard-to-regexp m)))
(append backend-markers
(project--value-in-dir 'project-vc-extra-root-markers dir))
"\\|")
"\\'"))
(locate-dominating-stop-dir-regexp
(or vc-ignore-dir-regexp locate-dominating-stop-dir-regexp))
last-matches

View 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

View file

@ -141,6 +141,81 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
It should match the part after \"def\" and until \"=\".")
(defconst ruby-builtin-methods-with-reqs
'( ;; built-in methods on Kernel
"at_exit"
"autoload"
"autoload?"
"callcc"
"catch"
"eval"
"exec"
"format"
"lambda"
"load"
"loop"
"open"
"p"
"printf"
"proc"
"putc"
"require"
"require_relative"
"spawn"
"sprintf"
"syscall"
"system"
"throw"
"trace_var"
"trap"
"untrace_var"
"warn"
;; keyword-like private methods on Module
"alias_method"
"attr"
"attr_accessor"
"attr_reader"
"attr_writer"
"define_method"
"extend"
"include"
"module_function"
"prepend"
"private_class_method"
"private_constant"
"public_class_method"
"public_constant"
"refine"
"using")
"List of built-in methods that require at least one argument.")
(defconst ruby-builtin-methods-no-reqs
'("__callee__"
"__dir__"
"__method__"
"abort"
"binding"
"block_given?"
"caller"
"exit"
"exit!"
"fail"
"fork"
"global_variables"
"local_variables"
"print"
"private"
"protected"
"public"
"puts"
"raise"
"rand"
"readline"
"readlines"
"sleep"
"srand")
"List of built-in methods that only have optional arguments.")
(defvar ruby-use-smie t)
(make-obsolete-variable 'ruby-use-smie nil "28.1")
@ -2292,84 +2367,13 @@ It will be properly highlighted even when the call omits parens.")
;; Core methods that have required arguments.
(,(concat
ruby-font-lock-keyword-beg-re
(regexp-opt
'( ;; built-in methods on Kernel
"at_exit"
"autoload"
"autoload?"
"callcc"
"catch"
"eval"
"exec"
"format"
"lambda"
"load"
"loop"
"open"
"p"
"printf"
"proc"
"putc"
"require"
"require_relative"
"spawn"
"sprintf"
"syscall"
"system"
"throw"
"trace_var"
"trap"
"untrace_var"
"warn"
;; keyword-like private methods on Module
"alias_method"
"attr"
"attr_accessor"
"attr_reader"
"attr_writer"
"define_method"
"extend"
"include"
"module_function"
"prepend"
"private_class_method"
"private_constant"
"public_class_method"
"public_constant"
"refine"
"using")
'symbols))
(regexp-opt ruby-builtin-methods-with-reqs 'symbols))
(1 (unless (looking-at " *\\(?:[]|,.)}=]\\|$\\)")
font-lock-builtin-face)))
;; Kernel methods that have no required arguments.
(,(concat
ruby-font-lock-keyword-beg-re
(regexp-opt
'("__callee__"
"__dir__"
"__method__"
"abort"
"binding"
"block_given?"
"caller"
"exit"
"exit!"
"fail"
"fork"
"global_variables"
"local_variables"
"print"
"private"
"protected"
"public"
"puts"
"raise"
"rand"
"readline"
"readlines"
"sleep"
"srand")
'symbols))
(regexp-opt ruby-builtin-methods-no-reqs 'symbols))
(1 font-lock-builtin-face))
;; Here-doc beginnings.
(,ruby-here-doc-beg-re

View file

@ -5,6 +5,7 @@
;; Author: Perry Smith <pedz@easesoftware.com>
;; Created: December 2022
;; Keywords: ruby languages tree-sitter
;; Version: 0.2
;; This file is part of GNU Emacs.
@ -50,11 +51,11 @@
;; Currently tree treesit-font-lock-feature-list is set with the
;; following levels:
;; 1: comment method-definition
;; 1: comment method-definition parameter-definition
;; 2: keyword regexp string type
;; 3: builtin-variable builtin-constant constant
;; 3: builtin-variable builtin-constant builtin-function
;; delimiter escape-sequence
;; global instance
;; constant global instance
;; interpolation literal symbol assignment
;; 4: bracket error function operator punctuation
@ -71,6 +72,8 @@
;; ruby-ts-mode tries to adhere to the indentation related user
;; options from ruby-mode, such as ruby-indent-level,
;; ruby-indent-tabs-mode, and so on.
;;
;; Type 'M-x customize-group RET ruby RET' to see the options.
;; * IMenu
;; * Navigation
@ -114,21 +117,30 @@
"Ruby's punctuation characters.")
(defvar ruby-ts--predefined-constants
(rx (or "ARGF" "ARGV" "DATA" "ENV" "RUBY_COPYRIGHT"
(rx string-start
(or "ARGF" "ARGV" "DATA" "ENV" "RUBY_COPYRIGHT"
"RUBY_DESCRIPTION" "RUBY_ENGINE" "RUBY_ENGINE_VERSION"
"RUBY_PATCHLEVEL" "RUBY_PLATFORM" "RUBY_RELEASE_DATE"
"RUBY_REVISION" "RUBY_VERSION" "STDERR" "STDIN" "STDOUT"
"TOPLEVEL_BINDING"))
"TOPLEVEL_BINDING")
string-end)
"Ruby predefined global constants.")
(defvar ruby-ts--predefined-variables
(rx (or "$!" "$@" "$~" "$&" "$" "$" "$+" "$=" "$/" "$\\" "$," "$;"
(rx string-start
(or "$!" "$@" "$~" "$&" "$" "$" "$+" "$=" "$/" "$\\" "$," "$;"
"$." "$<" "$>" "$_" "$*" "$$" "$?" "$:" "$LOAD_PATH"
"$LOADED_FEATURES" "$DEBUG" "$FILENAME" "$stderr" "$stdin"
"$stdout" "$VERBOSE" "$-a" "$-i" "$-l" "$-p"
(seq "$" (+ digit))))
"$0" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9")
string-end)
"Ruby predefined global variables.")
(defvar ruby-ts--builtin-methods
(format "\\`%s\\'" (regexp-opt (append ruby-builtin-methods-no-reqs
ruby-builtin-methods-with-reqs)))
"Ruby built-in methods.")
(defconst ruby-ts--class-or-module-regex
(rx string-start
(or "class" "module" "singleton_class")
@ -197,6 +209,9 @@ values of OVERRIDE"
(treesit-fontify-with-override (max plus-1 start) (min node-end end)
font-lock-comment-face override)))
(defun ruby-ts--builtin-method-p (node)
(string-match-p ruby-ts--builtin-methods (treesit-node-text node t)))
(defun ruby-ts--font-lock-settings (language)
"Tree-sitter font-lock settings for Ruby."
(treesit-font-lock-rules
@ -322,6 +337,11 @@ values of OVERRIDE"
(in_clause
pattern: (identifier) @font-lock-variable-name-face))
:language language
:feature 'builtin-function
`((((identifier) @font-lock-builtin-face)
(:pred ruby-ts--builtin-method-p @font-lock-builtin-face)))
;; Yuan recommends also putting method definitions into the
;; 'function' category (thus keeping it in both). I've opted to
;; just use separate categories for them -- dgutov.
@ -535,7 +555,7 @@ a statement container is a node that matches
(let ((common
`(
;; Slam all top level nodes to the left margin
((parent-is "program") parent 0)
((parent-is "program") point-min 0)
;; Do not indent here docs or the end. Not sure why it
;; takes the grand-parent but ok fine.
@ -1034,14 +1054,28 @@ leading double colon is not added."
(setq-local treesit-font-lock-feature-list
'(( comment method-definition parameter-definition)
( keyword regexp string type)
( builtin-variable builtin-constant constant
( builtin-variable builtin-constant builtin-function
delimiter escape-sequence
global instance
constant global instance
interpolation literal symbol assignment)
( bracket error function operator punctuation)))
(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

View 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

View file

@ -69,7 +69,7 @@
"Rules used for indentation.
Argument LANGUAGE is either `typescript' or `tsx'."
`((,language
((parent-is "program") parent-bol 0)
((parent-is "program") point-min 0)
((node-is "}") parent-bol 0)
((node-is ")") parent-bol 0)
((node-is "]") parent-bol 0)
@ -360,12 +360,6 @@ See `treesit-sentence-type-regexp' for more information.")
"Nodes that designate sexps in TypeScript.
See `treesit-sexp-type-regexp' for more information.")
;;;###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."
@ -432,6 +426,9 @@ See `treesit-sexp-type-regexp' for more information.")
(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."
@ -479,6 +476,9 @@ See `treesit-sexp-type-regexp' for more information.")
(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

View 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"

View 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

View file

@ -117,9 +117,6 @@
'((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."
@ -146,6 +143,9 @@
(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

View file

@ -987,7 +987,8 @@ If LOUDLY is non-nil, display some debugging information."
(end-time (current-time)))
;; If for any query the query time is strangely long,
;; switch to fast mode (see comments above).
(when (and (> (time-to-seconds
(when (and (null treesit--font-lock-fast-mode)
(> (time-to-seconds
(time-subtract end-time start-time))
0.01))
(if (> treesit--font-lock-fast-mode-grace-count 0)
@ -2702,6 +2703,11 @@ leaves point at the end of the last line of NODE."
(when (not named)
(overlay-put ov 'face 'treesit-explorer-anonymous-node)))))
(defun treesit--explorer-kill-explorer-buffer ()
"Kill the explorer buffer of this buffer."
(when (buffer-live-p treesit--explorer-buffer)
(kill-buffer treesit--explorer-buffer)))
(define-derived-mode treesit--explorer-tree-mode special-mode
"TS Explorer"
"Mode for displaying syntax trees for `treesit-explore-mode'."
@ -2713,30 +2719,46 @@ Pops up a window showing the syntax tree of the source in the
current buffer in real time. The corresponding node enclosing
the text in the active region is highlighted in the explorer
window."
:lighter " TSplay"
:lighter " TSexplore"
(if treesit-explore-mode
(progn
(unless (buffer-live-p treesit--explorer-buffer)
(setq-local treesit--explorer-buffer
(get-buffer-create
(format "*tree-sitter explorer for %s*"
(buffer-name))))
(setq-local treesit--explorer-language
(intern (completing-read
(let ((language (intern (completing-read
"Language: "
(mapcar #'treesit-parser-language
(treesit-parser-list)))))
(with-current-buffer treesit--explorer-buffer
(treesit--explorer-tree-mode)))
(display-buffer treesit--explorer-buffer
(cons nil '((inhibit-same-window . t))))
(treesit--explorer-refresh)
(add-hook 'post-command-hook
#'treesit--explorer-post-command 0 t)
(setq-local treesit--explorer-last-node nil))
(treesit-parser-list))))))
(if (not (treesit-language-available-p language))
(user-error "Cannot find tree-sitter grammar for %s: %s"
language (cdr (treesit-language-available-p
language t)))
;; Create explorer buffer.
(unless (buffer-live-p treesit--explorer-buffer)
(setq-local treesit--explorer-buffer
(get-buffer-create
(format "*tree-sitter explorer for %s*"
(buffer-name))))
(setq-local treesit--explorer-language language)
(with-current-buffer treesit--explorer-buffer
(treesit--explorer-tree-mode)))
(display-buffer treesit--explorer-buffer
(cons nil '((inhibit-same-window . t))))
(treesit--explorer-refresh)
;; Setup variables and hooks.
(add-hook 'post-command-hook
#'treesit--explorer-post-command 0 t)
(add-hook 'kill-buffer-hook
#'treesit--explorer-kill-explorer-buffer 0 t)
(setq-local treesit--explorer-last-node nil)
;; Tell `desktop-save' to not save explorer buffers.
(when (boundp 'desktop-modes-not-to-save)
(unless (memq 'treesit--explorer-tree-mode
desktop-modes-not-to-save)
(push 'treesit--explorer-tree-mode
desktop-modes-not-to-save)))))
;; Turn off explore mode.
(remove-hook 'post-command-hook
#'treesit--explorer-post-command t)
(kill-buffer treesit--explorer-buffer)))
(remove-hook 'post-command-hook
#'treesit--explorer-kill-explorer-buffer t)
(treesit--explorer-kill-explorer-buffer)))
;;; Install & build language grammar

View file

@ -92,6 +92,19 @@ int main()
}
=-=-=
Name: Concecutive blocks (GNU Style) (bug#60873)
=-=
int
main (int argc,
char *argv[])
{
{
int i = 0;
}
}
=-=-=
Name: Multiline Parameter List (bug#60398)
=-=

View file

@ -226,6 +226,7 @@ commit 86c19714b097aa477d339ed99ffb5136c755a046."
(defun keymap-tests--command-1 () (interactive) nil)
(defun keymap-tests--command-2 () (interactive) nil)
(defun keymap-tests--command-3 () (interactive) nil)
(put 'keymap-tests--command-1 :advertised-binding [?y])
(ert-deftest keymap-where-is-internal ()
@ -430,6 +431,38 @@ g .. h foo
(make-non-key-event 'keymap-tests-event)
(should (equal (where-is-internal 'keymap-tests-command) '([3 103]))))
(ert-deftest keymap-set-consistency ()
(let ((k (make-sparse-keymap)))
;; `keymap-set' returns the binding, `keymap-set-after' doesn't,
;; so we need to check for nil. <sigh>
(should (keymap-set k "a" "a"))
(should (equal (keymap-lookup k "a") (key-parse "a")))
(should-not (keymap-set-after k "b" "b"))
(should (equal (keymap-lookup k "b") (key-parse "b")))
(should-not (keymap-set-after k "d" "d" t))
(should (equal (keymap-lookup k "d") (key-parse "d")))
(should-not (keymap-set-after k "e" "e" nil))
(should (equal (keymap-lookup k "e") (key-parse "e")))
;; This doesn't fail, but it does not add the 'f' binding after 'a'
(should-not (keymap-set-after k "f" "f" "a"))
(should (equal (keymap-lookup k "f") (key-parse "f")))))
(ert-deftest keymap-set-after-menus ()
(let ((map (make-sparse-keymap)))
(keymap-set map "<cmd1>"
'(menu-item "Run Command 1" keymap-tests--command-1
:help "Command 1 Help"))
(keymap-set-after map "<cmd2>"
'(menu-item "Run Command 2" keymap-tests--command-2
:help "Command 2 Help"))
(keymap-set-after map "<cmd3>"
'(menu-item "Run Command 3" keymap-tests--command-3
:help "Command 3 Help")
'cmd1)
(should (equal (caadr map) 'cmd1))
(should (equal (caaddr map) 'cmd3))
(should (equal (caar (last map)) 'cmd2))))
(ert-deftest keymap-test-duplicate-definitions ()
"Check that defvar-keymap rejects duplicate key definitions."
(should-error