Merge from origin/emacs-29

96ea27278b ; Fix c-ts-mode indent test
d963a8f135 Make c-ts-mode indent tests side-effect-free
8a6bdf88b4 Call treesit_record_change in insert_from_gap_1
a2b77c79dc Use c-ts-common-statement-offset for closing brackets too
74e715cb72 ; Go back to original point when filling comments in c-ts...
b8009bbf2d ; Fix error where we pass t to treesit-node-type in c-ts-...
88ccf78b20 ; * src/treesit.c (treesit_predicate_match): Simplify las...
20454128b8 Minor improvements in sqlite.c
3b3c47d977 (treesit_predicate_match): Match node text against regexp...
e8334781c9 Improve documentation of gdb-mi's dedicated windows
c498884059 Avoid spurious pause in kill-ring-save (Bug#60841)
382ab516ce Change the default of 'treesit-defun-tactic' for 'c-ts-mode'
4d3428e95a Fix docstring fontification of CL's 'defstruct'
1c125baa3f Teach 'hs-minor-mode' about tree-sitter based modes
2de0ab5cbd ; Doc fixes in keymap.el
c6660a6d6d Improve documentation of 'repeat-mode' and related variables
be304bb328 ; * etc/NEWS: Mention the 'utf-8-auto' bugfix (bug#60750).

# Conflicts:
#	etc/NEWS
This commit is contained in:
Stefan Kangas 2023-02-03 06:30:24 +01:00
commit ac7ec87a7a
24 changed files with 380 additions and 175 deletions

View file

@ -0,0 +1,50 @@
NOTES ON TREESIT_RECORD_CHANGE
It is vital that Emacs informs tree-sitter of every change made to the
buffer, lest tree-sitter's parse tree would be corrupted/out of sync.
All buffer changes in Emacs are made through functions in insdel.c
(and casefiddle.c), I augmented functions in those files with calls to
treesit_record_change. Below is a manifest of all the relavent
functions in insdel.c as of Emacs 29:
Function Calls
----------------------------------------------------------------------
copy_text (*1)
insert insert_1_both
insert_and_inherit insert_1_both
insert_char insert
insert_string insert
insert_before_markers insert_1_both
insert_before_markers_and_inherit insert_1_both
insert_1_both treesit_record_change
insert_from_string insert_from_string_1
insert_from_string_before_markers insert_from_string_1
insert_from_string_1 treesit_record_change
insert_from_gap_1 treesit_record_change
insert_from_gap insert_from_gap_1
insert_from_buffer treesit_record_change
insert_from_buffer_1 (used by insert_from_buffer) (*2)
replace_range treesit_record_change
replace_range_2 (caller needs to call treesit_r_c)
del_range del_range_1
del_range_1 del_range_2
del_range_byte del_range_2
del_range_both del_range_2
del_range_2 treesit_record_change
(*1) This functions is used only to copy from string to string when
used outside of insdel.c, and when used inside insdel.c, the caller
calls treesit_record_change.
(*2) This function is a static function, and insert_from_buffer is its
only caller. So it should be fine to call treesit_record_change in
insert_from_buffer but not insert_from_buffer_1. I also left a
reminder comment.
As for casefiddle.c, do_casify_unibyte_region and
do_casify_multibyte_region modifies buffer, but they are static
functions and are called by casify_region, which calls
treesit_record_change. Other higher-level functions calls
casify_region to do the work.

View file

@ -890,17 +890,37 @@ subsequent @kbd{z} repeats it once again.
@findex describe-repeat-maps @findex describe-repeat-maps
@vindex repeat-exit-key @vindex repeat-exit-key
@vindex repeat-exit-timeout @vindex repeat-exit-timeout
Also you can activate @code{repeat-mode} that temporarily enables a You can also activate @code{repeat-mode} which allows repeating
transient mode with short keys after a limited number of commands. commands bound to sequences of two or more keys by typing a single
Currently supported shorter key sequences are @kbd{C-x u u} instead of character. For example, after typing @w{@kbd{C-x u}} (@code{undo},
@kbd{C-x u C-x u} to undo many changes, @kbd{C-x o o} instead of @pxref{Undo}) to undo the most recent edits, you can undo many more
@kbd{C-x o C-x o} to switch several windows, @kbd{C-x @{ @{ @} @} ^ ^ edits by typing @w{@kbd{u u u@dots{}}}. Similarly, type @w{@kbd{C-x o
v v} to resize the selected window interactively, @kbd{M-g n n p p} to o o@dots{}}} instead of @w{@kbd{C-x o C-x o C-x o@dots{}}} to switch
navigate @code{next-error} matches, @kbd{C-x ] ] [ [} to navigate to the window several windows away. This works by entering a
through pages, and other keys listed by @code{describe-repeat-maps}. transient repeating mode after you type the full key sequence that
Any other key exits transient mode and then is executed normally. The invokes the command; the single-key shortcuts are shown in the echo
user option @code{repeat-exit-key} defines an additional key to exit area.
this transient mode. Also it's possible to break the repetition chain
automatically after some idle time by customizing the user option Only some commands support repetition in @code{repeat-mode}; type
@w{@kbd{M-x describe-repeat-maps @key{RET}}} to see which ones.
The single-character shortcuts enabled by the transient repeating mode
do not need to be identical: for example, after typing @w{@kbd{C-x
@{}}, either @kbd{@{} or @kbd{@}} or @kbd{^} or @kbd{v}, or any series
that mixes these characters in any order, will resize the selected
window in respective ways. Similarly, after @w{@kbd{M-g n}} or
@kbd{M-g p}, typing any sequence of @kbd{n} and/or @kbd{p} in any mix
will repeat @code{next-error} and @code{previous-error} to navigate in
a @file{*compilation*} or @file{*grep*} buffer (@pxref{Compilation
Mode}).
Typing any key other than those defined to repeat the previous command
exits the transient repeating mode, and then the key you typed is
executed normally. You can also define a key which will exit the
transient repeating mode @emph{without} executing the key which caused
the exit. To this end, customize the user option
@code{repeat-exit-key} to name a key; one natural value is @key{RET}.
Finally, it's possible to break the repetition chain automatically
after some amount of idle time: customize the user option
@code{repeat-exit-timeout} to specify the idle time in seconds after @code{repeat-exit-timeout} to specify the idle time in seconds after
which this transient mode will be turned off. which this transient repetition mode will be turned off automatically.

View file

@ -961,9 +961,7 @@ the fringe of a source buffer to set a breakpoint there.
@vindex gud-gdb-command-name @vindex gud-gdb-command-name
To run GDB using just the GUD interaction buffer interface, without To run GDB using just the GUD interaction buffer interface, without
these additional features, use @kbd{M-x gud-gdb} (@pxref{Starting these additional features, use @kbd{M-x gud-gdb} (@pxref{Starting
GUD}). You must use this if you want to debug multiple programs GUD}).
within one Emacs session, as that is currently unsupported by @kbd{M-x
gdb}.
Internally, @kbd{M-x gdb} informs GDB that its screen size is Internally, @kbd{M-x gdb} informs GDB that its screen size is
unlimited; for correct operation, you must not change GDB's screen unlimited; for correct operation, you must not change GDB's screen
@ -1051,9 +1049,9 @@ to restore only when @code{gdb-show-main} is non-@code{nil}.
You may also specify additional GDB-related buffers to display, You may also specify additional GDB-related buffers to display,
either in the same frame or a different one. Select the buffers you either in the same frame or a different one. Select the buffers you
want by typing @kbd{M-x gdb-display-@var{buffertype}-buffer} or want by typing @kbd{M-x gdb-display-@var{buffertype}-buffer} or
@kbd{M-x gdb-frame-@var{buffertype}-buffer}, where @var{buffertype} @kbd{M-x gdb-frame-@var{buffertype}-buffer}, where @var{buffertype} is
is the relevant buffer type, such as @samp{breakpoints}. You can do the relevant buffer type, such as @samp{breakpoints} or @samp{io}.
the same with the menu bar, with the @samp{GDB-Windows} and You can do the same from the menu bar, with the @samp{GDB-Windows} and
@samp{GDB-Frames} sub-menus of the @samp{GUD} menu. @samp{GDB-Frames} sub-menus of the @samp{GUD} menu.
@vindex gdb-max-source-window-count @vindex gdb-max-source-window-count
@ -1273,10 +1271,14 @@ non-@code{nil} value.
@node Other GDB Buffers @node Other GDB Buffers
@subsubsection Other GDB Buffers @subsubsection Other GDB Buffers
Other buffers provided by @kbd{M-x gdb} whose display you can
optionally request include:
@table @asis @table @asis
@findex gdb-display-locals-buffer
@item Locals Buffer @item Locals Buffer
This buffer displays the values of local variables of the current This buffer displays the values of local variables of the current
frame for simple data types (@pxref{Frame Info, Frame Info, stack frame for simple data types (@pxref{Frame Info, Frame Info,
Information on a frame, gdb, The GNU debugger}). Press @key{RET} or Information on a frame, gdb, The GNU debugger}). Press @key{RET} or
click @kbd{mouse-2} on the value if you want to edit it. click @kbd{mouse-2} on the value if you want to edit it.
@ -1286,20 +1288,35 @@ you can examine the value of the local variable at point by typing
GDB, use @key{RET} or @kbd{mouse-2} on the type description GDB, use @key{RET} or @kbd{mouse-2} on the type description
(@samp{[struct/union]} or @samp{[array]}). @xref{Watch Expressions}. (@samp{[struct/union]} or @samp{[array]}). @xref{Watch Expressions}.
@item Registers Buffer To display the Locals buffer, type @kbd{M-x gdb-display-locals-buffer}.
@findex toggle-gdb-all-registers
This buffer displays the values held by the registers
(@pxref{Registers,,, gdb, The GNU debugger}). Press @key{RET} or
click @kbd{mouse-2} on a register if you want to edit its value. With
GDB 6.4 or later, recently changed register values display with
@code{font-lock-warning-face}.
@findex gdb-display-io-buffer
@item I/O Buffer
If the program you are debugging uses standard input and output
streams for interaction with the user, or emits a significant amount
of output to its standard output, you may wish to separate its I/O
from interaction with GDB. Use the command @w{@kbd{M-x
gdb-display-io-buffer}} to show a window with a buffer to which Emacs
redirects the input and output from the program you are debugging.
@findex gdb-display-registers-buffer
@item Registers Buffer
This buffer displays the values held by the registers
(@pxref{Registers,,, gdb, The GNU debugger}). Request the display of
this buffer with the command @kbd{M-x gdb-display-registers-buffer}.
Press @key{RET} or click @kbd{mouse-2} on a register if you want to
edit its value. With GDB 6.4 or later, recently changed register
values display with @code{font-lock-warning-face}.
@findex gdb-display-disassembly-buffer
@item Assembler Buffer @item Assembler Buffer
The assembler buffer displays the current frame as machine code. An The assembler buffer displays the current frame as machine code. An
arrow points to the current instruction, and you can set and remove arrow points to the current instruction, and you can set and remove
breakpoints as in a source buffer. Breakpoint icons also appear in breakpoints as in a source buffer. Breakpoint icons also appear in
the fringe or margin. the fringe or margin. To request the display of this buffer, use
@kbd{M-x gdb-display-disassembly-buffer}.
@findex gdb-display-memory-buffer
@item Memory Buffer @item Memory Buffer
The memory buffer lets you examine sections of program memory The memory buffer lets you examine sections of program memory
(@pxref{Memory, Memory, Examining memory, gdb, The GNU debugger}). (@pxref{Memory, Memory, Examining memory, gdb, The GNU debugger}).
@ -1307,7 +1324,8 @@ Click @kbd{mouse-1} on the appropriate part of the header line to
change the starting address or number of data items that the buffer change the starting address or number of data items that the buffer
displays. Alternatively, use @kbd{S} or @kbd{N} respectively. Click displays. Alternatively, use @kbd{S} or @kbd{N} respectively. Click
@kbd{mouse-3} on the header line to select the display format or unit @kbd{mouse-3} on the header line to select the display format or unit
size for these data items. size for these data items. Use @w{@kbd{M-x
gdb-display-memory-buffer}} to request display of this buffer.
@end table @end table
When @code{gdb-many-windows} is non-@code{nil}, the locals buffer When @code{gdb-many-windows} is non-@code{nil}, the locals buffer

View file

@ -563,6 +563,20 @@ The variable 'font-lock-support-mode' is occasionally useful for
debugging purposes. It is now a regular variable (instead of a user debugging purposes. It is now a regular variable (instead of a user
option) and can be set to nil to disable Just-in-time Lock mode. option) and can be set to nil to disable Just-in-time Lock mode.
+++
** The 'utf-8-auto' coding-system now produces BOM on encoding.
This is actually a bugfix, since this is how 'utf-8-auto' was
documented from day one; it just didn't behave according to
documentation. It turns out some Lisp programs were using this
coding-system on the wrong assumption that the "auto" part means some
automagic handling of the end-of-line (EOL) format conversion; those
program will now start to fail, because BOM signature in UTF-8 encoded
text is rarely expected. That is the reason we mention this bugfix
here.
In general, this coding-system should probably never be used for
encoding, only for decoding.
* Changes in Emacs 29.1 * Changes in Emacs 29.1
@ -1339,6 +1353,18 @@ dragged.
Customize this option to limit the number of entries in the menu Customize this option to limit the number of entries in the menu
"Edit → Paste from Kill Menu". The default is 60. "Edit → Paste from Kill Menu". The default is 60.
---
** New user option 'copy-region-blink-predicate'.
By default, when copying a region with 'kill-ring-save', Emacs only
blinks point and mark when the region is not denoted visually, that
is, when either the region is inactive, or the 'region' face is
indistinguishable from the 'default' face.
Users who would rather enable blinking unconditionally can now set
this user option to 'always'. To disable blinking unconditionally,
either set this option to 'ignore', or set 'copy-region-blink-delay'
to 0.
+++ +++
** Performing a pinch gesture on a touchpad now increases the text scale. ** Performing a pinch gesture on a touchpad now increases the text scale.

View file

@ -1011,7 +1011,7 @@ if `inhibit-field-text-motion' is non-nil."
;; no idea whereas to bind it. Any suggestion welcome. -stef ;; no idea whereas to bind it. Any suggestion welcome. -stef
;; (define-key ctl-x-map "U" 'undo-only) ;; (define-key ctl-x-map "U" 'undo-only)
(defvar-keymap undo-repeat-map (defvar-keymap undo-repeat-map
:doc "Keymap to repeat undo key sequences \\`C-x u u'. Used in `repeat-mode'." :doc "Keymap to repeat `undo' commands. Used in `repeat-mode'."
:repeat t :repeat t
"u" #'undo) "u" #'undo)
@ -1108,7 +1108,7 @@ if `inhibit-field-text-motion' is non-nil."
(define-key ctl-x-map "`" 'next-error) (define-key ctl-x-map "`" 'next-error)
(defvar-keymap next-error-repeat-map (defvar-keymap next-error-repeat-map
:doc "Keymap to repeat `next-error' key sequences. Used in `repeat-mode'." :doc "Keymap to repeat `next-error' and `previous-error'. Used in `repeat-mode'."
:repeat t :repeat t
"n" #'next-error "n" #'next-error
"M-n" #'next-error "M-n" #'next-error
@ -1470,7 +1470,7 @@ if `inhibit-field-text-motion' is non-nil."
(define-key ctl-x-map "]" 'forward-page) (define-key ctl-x-map "]" 'forward-page)
(defvar-keymap page-navigation-repeat-map (defvar-keymap page-navigation-repeat-map
:doc "Keymap to repeat page navigation key sequences. Used in `repeat-mode'." :doc "Keymap to repeat `forward-page' and `backward-page'. Used in `repeat-mode'."
:repeat t :repeat t
"]" #'forward-page "]" #'forward-page
"[" #'backward-page) "[" #'backward-page)

View file

@ -182,6 +182,7 @@ to a package-local <package>-loaddefs.el file.")
;; CL ;; CL
(put 'defconstant 'doc-string-elt 3) (put 'defconstant 'doc-string-elt 3)
(put 'defparameter 'doc-string-elt 3) (put 'defparameter 'doc-string-elt 3)
(put 'defstruct 'doc-string-elt 2)
(defvar lisp-doc-string-elt-property 'doc-string-elt (defvar lisp-doc-string-elt-property 'doc-string-elt
"The symbol property that holds the docstring position info.") "The symbol property that holds the docstring position info.")

View file

@ -304,7 +304,16 @@ If the optional argument FRAME is given, report on face FACE in that frame.
If FRAME is t, report on the defaults for face FACE (for new frames). If FRAME is t, report on the defaults for face FACE (for new frames).
If FRAME is omitted or nil, use the selected frame." If FRAME is omitted or nil, use the selected frame."
(let ((attrs (let ((attrs
(delq :inherit (mapcar 'car face-attribute-name-alist))) ;; The _value_ of :inherit teaches us nothing about how FACE
;; looks compared to the default face. Instead, we will ask
;; `face-attribute' to take inheritance into account when
;; examining other attributes.
(delq :inherit
;; A difference in extension past EOL only matters when
;; relevant attributes (such as :background) also
;; differ from the default; otherwise this difference
;; is a false positive.
(delq :extend (mapcar 'car face-attribute-name-alist))))
(differs nil)) (differs nil))
(while (and attrs (not differs)) (while (and attrs (not differs))
(let* ((attr (pop attrs)) (let* ((attr (pop attrs))

View file

@ -290,26 +290,26 @@ See `kbd' for a descripion of KEYS."
res))) res)))
(defun key-valid-p (keys) (defun key-valid-p (keys)
"Say whether KEYS is a valid key. "Return non-nil if KEYS, a string, is a valid key sequence.
A key is a string consisting of one or more key strokes. KEYS should be a string consisting of one or more key strokes,
The key strokes are separated by single space characters. with a single space character separating one key stroke from another.
Each key stroke is either a single character, or the name of an Each key stroke is either a single character, or the name of an
event, surrounded by angle brackets. In addition, any key stroke event, surrounded by angle brackets <like-this>. In addition, any
may be preceded by one or more modifier keys. Finally, a limited key stroke may be preceded by one or more modifier keys. Finally,
number of characters have a special shorthand syntax. a limited number of characters have a special shorthand syntax.
Here's some example key sequences. Here are some example of valid key sequences.
\"f\" (the key `f') \"f\" (the key `f')
\"S o m\" (a three key sequence of the keys `S', `o' and `m') \"S o m\" (a three-key sequence of the keys `S', `o' and `m')
\"C-c o\" (a two key sequence of the keys `c' with the control modifier \"C-c o\" (a two-key sequence: the key `c' with the control modifier
and then the key `o') followed by the key `o')
\"H-<left>\" (the key named \"left\" with the hyper modifier) \"H-<left>\" (the function key named \"left\" with the hyper modifier)
\"M-RET\" (the \"return\" key with a meta modifier) \"M-RET\" (the \"return\" key with a meta modifier)
\"C-M-<space>\" (the \"space\" key with both the control and meta modifiers) \"C-M-<space>\" (the \"space\" key with both the control and meta modifiers)
These are the characters that have shorthand syntax: These are the characters that have special shorthand syntax:
NUL, RET, TAB, LFD, ESC, SPC, DEL. NUL, RET, TAB, LFD, ESC, SPC, DEL.
Modifiers have to be specified in this order: Modifiers have to be specified in this order:
@ -358,7 +358,7 @@ which is
This function creates a `keyboard-translate-table' if necessary This function creates a `keyboard-translate-table' if necessary
and then modifies one entry in it. and then modifies one entry in it.
Both KEY and TO are strings that satisfy `key-valid-p'." Both KEY and TO should be specified by strings that satisfy `key-valid-p'."
(declare (compiler-macro (declare (compiler-macro
(lambda (form) (keymap--compile-check from to) form))) (lambda (form) (keymap--compile-check from to) form)))
(keymap--check from) (keymap--check from)
@ -369,7 +369,7 @@ Both KEY and TO are strings that satisfy `key-valid-p'."
(aset keyboard-translate-table (key-parse from) (key-parse to))) (aset keyboard-translate-table (key-parse from) (key-parse to)))
(defun keymap-lookup (keymap key &optional accept-default no-remap position) (defun keymap-lookup (keymap key &optional accept-default no-remap position)
"Return the binding for command KEY. "Return the binding for command KEY in KEYMAP.
KEY is a string that satisfies `key-valid-p'. KEY is a string that satisfies `key-valid-p'.
If KEYMAP is nil, look up in the current keymaps. If non-nil, it If KEYMAP is nil, look up in the current keymaps. If non-nil, it
@ -391,15 +391,15 @@ in the current keymaps. However, if the optional third argument
NO-REMAP is non-nil, `keymap-lookup' returns the unmapped NO-REMAP is non-nil, `keymap-lookup' returns the unmapped
command. command.
If KEY is a key sequence initiated with the mouse, the used keymaps If KEY is a mouse gesture, the keymaps used depend on the clicked
will depend on the clicked mouse position with regard to the buffer mouse position with regards to the buffer, and local keymaps, if any,
and possible local keymaps on strings. on display and overlay strings.
If the optional argument POSITION is non-nil, it specifies a mouse If the optional argument POSITION is non-nil, it specifies a mouse
position as returned by `event-start' and `event-end', and the lookup position as returned by `event-start' and `event-end', and the lookup
occurs in the keymaps associated with it instead of KEY. It can also occurs in the keymaps associated with it instead of KEY. It can also
be a number or marker, in which case the keymap properties at the be a number or marker, in which case the keymap properties at the
specified buffer position instead of point are used." specified buffer position are used instead of point."
(declare (compiler-macro (lambda (form) (keymap--compile-check key) form))) (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
(keymap--check key) (keymap--check key)
(when (and keymap position) (when (and keymap position)
@ -475,7 +475,7 @@ If MESSAGE (and interactively), message the result."
(defun define-keymap (&rest definitions) (defun define-keymap (&rest definitions)
"Create a new keymap and define KEY/DEFINITION pairs as key bindings. "Create a new keymap and define KEY/DEFINITION pairs as key bindings.
The new keymap is returned. Return the new keymap.
Options can be given as keywords before the KEY/DEFINITION Options can be given as keywords before the KEY/DEFINITION
pairs. Available keywords are: pairs. Available keywords are:

View file

@ -194,7 +194,8 @@ comment."
(when end-marker (when end-marker
(goto-char end-marker) (goto-char end-marker)
(delete-region (point) (+ end-len (point))) (delete-region (point) (+ end-len (point)))
(insert (make-string end-len ?\s)))))) (insert (make-string end-len ?\s)))
(goto-char orig-point))))
(defun c-ts-common-comment-setup () (defun c-ts-common-comment-setup ()
"Set up local variables for C-like comment. "Set up local variables for C-like comment.
@ -280,7 +281,7 @@ special handling from our bracket-counting indent algorithm.
This can be nil, meaning such special handling is not needed.") This can be nil, meaning such special handling is not needed.")
(defun c-ts-common-statement-offset (node parent &rest _) (defun c-ts-common-statement-offset (node parent bol &rest _)
"This anchor is used for children of a statement inside a block. "This anchor is used for children of a statement inside a block.
This function basically counts the number of block nodes (i.e., This function basically counts the number of block nodes (i.e.,
@ -292,18 +293,21 @@ To support GNU style, on each block level, this function also
checks whether the opening bracket { is on its own line, if so, checks whether the opening bracket { is on its own line, if so,
it adds an extra level, except for the top-level. it adds an extra level, except for the top-level.
PARENT is NODE's parent." PARENT is NODE's parent, BOL is the beginning of non-whitespace
characters on the current line."
(let ((level 0)) (let ((level 0))
;; If NODE is a opening/closing bracket on its own line, take off
;; one level because the code below assumes NODE is a statement
;; _inside_ a {} block.
(when (and node
(or (string-match-p c-ts-common-indent-block-type-regexp
(treesit-node-type node))
(save-excursion (goto-char bol) (looking-at-p "}"))))
(cl-decf level))
;; If point is on an empty line, NODE would be nil, but we pretend ;; If point is on an empty line, NODE would be nil, but we pretend
;; there is a statement node. ;; there is a statement node.
(when (null node) (when (null node)
(setq node t)) (setq node t))
;; If NODE is a opening bracket on its own line, take off one
;; level because the code below assumes NODE is a statement
;; _inside_ a {} block.
(when (string-match-p c-ts-common-indent-block-type-regexp
(treesit-node-type node))
(cl-decf level))
;; Go up the tree and compute indent level. ;; Go up the tree and compute indent level.
(while (if (eq node t) (while (if (eq node t)
(setq node parent) (setq node parent)
@ -321,9 +325,9 @@ PARENT is NODE's parent."
(treesit-node-parent node)))) (treesit-node-parent node))))
;; Case (2). ;; Case (2).
(and parent-type (and parent-type
(or (string-match-p (string-match-p
c-ts-common-indent-block-type-regexp c-ts-common-indent-block-type-regexp
parent-type)))) parent-type)))
nil) nil)
;; Add a level. ;; Add a level.
((looking-back (rx bol (* whitespace)) ((looking-back (rx bol (* whitespace))
@ -350,13 +354,6 @@ the bracket in the body."
(1+ level) (1+ level)
level))) level)))
(defun c-ts-mode--close-bracket-offset (node parent &rest _)
"Offset for the closing bracket, NODE.
It's basically one level less that the statements in the block.
PARENT is NODE's parent."
(- (c-ts-common-statement-offset node parent)
(symbol-value c-ts-common-indent-offset)))
(provide 'c-ts-common) (provide 'c-ts-common)
;;; c-ts-common.el ends here ;;; c-ts-common.el ends here

View file

@ -100,12 +100,11 @@ the value of SYM in `c-ts-mode' and `c++-ts-mode' buffers to VAL."
(setq-local treesit-simple-indent-rules (setq-local treesit-simple-indent-rules
(treesit--indent-rules-optimize (treesit--indent-rules-optimize
(c-ts-mode--get-indent-style (c-ts-mode--get-indent-style
(if (eq major-mode 'c-ts-mode) 'c 'cpp)))))) (if (derived-mode-p 'c-ts-mode) 'c 'cpp))))))
res) res)
(let ((buffer (car buffers))) (let ((buffer (car buffers)))
(with-current-buffer buffer (with-current-buffer buffer
;; FIXME: Should we use `derived-mode-p' here? (if (derived-mode-p 'c-ts-mode 'c++-ts-mode)
(if (or (eq major-mode 'c-ts-mode) (eq major-mode 'c++-ts-mode))
(loop (append res (list buffer)) (cdr buffers)) (loop (append res (list buffer)) (cdr buffers))
(loop res (cdr buffers)))))))) (loop res (cdr buffers))))))))
@ -134,24 +133,33 @@ MODE is either `c' or `cpp'."
(alist-get c-ts-mode-indent-style (c-ts-mode--indent-styles mode))))) (alist-get c-ts-mode-indent-style (c-ts-mode--indent-styles mode)))))
`((,mode ,@style)))) `((,mode ,@style))))
(defun c-ts-mode-set-style () (defun c-ts-mode--prompt-for-style ()
"Set the indent style of C/C++ modes globally. "Prompt for a indent style and return the symbol for it."
(let ((mode (if (derived-mode-p 'c-ts-mode) 'c 'c++)))
(intern
(completing-read
"Style: "
(mapcar #'car (c-ts-mode--indent-styles mode))
nil t nil nil "gnu"))))
(defun c-ts-mode-set-style (style)
"Set the indent style of C/C++ modes globally to STYLE.
This changes the current indent style of every C/C++ buffer and This changes the current indent style of every C/C++ buffer and
the default C/C++ indent style in this Emacs session." the default C/C++ indent style in this Emacs session."
(interactive) (interactive (list (c-ts-mode--prompt-for-style)))
;; FIXME: Should we use `derived-mode-p' here? (c-ts-mode--indent-style-setter 'c-ts-mode-indent-style style))
(or (eq major-mode 'c-ts-mode) (eq major-mode 'c++-ts-mode)
(error "Buffer %s is not a c-ts-mode (c-ts-mode-set-style)" (defun c-ts-mode-set-local-style (style)
(buffer-name))) "Set the C/C++ indent style of the current buffer to STYLE."
(c-ts-mode--indent-style-setter (interactive (list (c-ts-mode--prompt-for-style)))
'c-ts-mode-indent-style (if (not (derived-mode-p 'c-ts-mode 'c++-ts-mode))
;; NOTE: We can probably use the interactive form for this. (user-error "The current buffer is not in `c-ts-mode' nor `c++-ts-mode'")
(intern (setq-local c-ts-mode-indent-style style)
(completing-read (setq treesit-simple-indent-rules
"Select style: " (treesit--indent-rules-optimize
(mapcar #'car (c-ts-mode--indent-styles (if (eq major-mode 'c-ts-mode) 'c 'cpp))) (c-ts-mode--get-indent-style
nil t nil nil "gnu")))) (if (derived-mode-p 'c-ts-mode) 'c 'cpp))))))
;;; Syntax table ;;; Syntax table
@ -254,12 +262,16 @@ MODE is either `c' or `cpp'."
;; int[5] a = { 0, 0, 0, 0 }; ;; int[5] a = { 0, 0, 0, 0 };
((parent-is "initializer_list") parent-bol c-ts-mode-indent-offset) ((parent-is "initializer_list") parent-bol c-ts-mode-indent-offset)
;; Statement in enum.
((parent-is "enumerator_list") point-min c-ts-common-statement-offset) ((parent-is "enumerator_list") point-min c-ts-common-statement-offset)
;; Statement in struct and union.
((parent-is "field_declaration_list") point-min c-ts-common-statement-offset) ((parent-is "field_declaration_list") point-min c-ts-common-statement-offset)
;; {} blocks. ;; Statement in {} blocks.
((node-is "}") point-min c-ts-mode--close-bracket-offset)
((parent-is "compound_statement") point-min c-ts-common-statement-offset) ((parent-is "compound_statement") point-min c-ts-common-statement-offset)
;; Closing bracket.
((node-is "}") point-min c-ts-common-statement-offset)
;; Opening bracket.
((node-is "compound_statement") point-min c-ts-common-statement-offset) ((node-is "compound_statement") point-min c-ts-common-statement-offset)
,@(when (eq mode 'cpp) ,@(when (eq mode 'cpp)
@ -824,6 +836,8 @@ in your configuration."
(c-ts-mode--get-indent-style 'c)) (c-ts-mode--get-indent-style 'c))
;; Font-lock. ;; Font-lock.
(setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c)) (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c))
;; Navigation.
(setq-local treesit-defun-tactic 'top-level)
(treesit-major-mode-setup))) (treesit-major-mode-setup)))
;;;###autoload ;;;###autoload

View file

@ -256,10 +256,14 @@ This has effect only if `search-invisible' is set to `open'."
(defvar hs-special-modes-alist (defvar hs-special-modes-alist
(mapcar #'purecopy (mapcar #'purecopy
'((c-mode "{" "}" "/[*/]" nil nil) '((c-mode "{" "}" "/[*/]" nil nil)
(c-ts-mode "{" "}" "/[*/]" nil nil)
(c++-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil)
(c++-ts-mode "{" "}" "/[*/]" nil nil)
(bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
(java-mode "{" "}" "/[*/]" nil nil) (java-mode "{" "}" "/[*/]" nil nil)
(java-ts-mode "{" "}" "/[*/]" nil nil)
(js-mode "{" "}" "/[*/]" nil) (js-mode "{" "}" "/[*/]" nil)
(js-ts-mode "{" "}" "/[*/]" nil)
(mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil) (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil)
;; Add more support here. ;; Add more support here.
)) ))

View file

@ -209,9 +209,6 @@ values of OVERRIDE"
(treesit-fontify-with-override (max plus-1 start) (min node-end end) (treesit-fontify-with-override (max plus-1 start) (min node-end end)
font-lock-comment-face override))) 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) (defun ruby-ts--font-lock-settings (language)
"Tree-sitter font-lock settings for Ruby." "Tree-sitter font-lock settings for Ruby."
(treesit-font-lock-rules (treesit-font-lock-rules
@ -340,7 +337,7 @@ values of OVERRIDE"
:language language :language language
:feature 'builtin-function :feature 'builtin-function
`((((identifier) @font-lock-builtin-face) `((((identifier) @font-lock-builtin-face)
(:pred ruby-ts--builtin-method-p @font-lock-builtin-face))) (:match ,ruby-ts--builtin-methods @font-lock-builtin-face)))
;; Yuan recommends also putting method definitions into the ;; Yuan recommends also putting method definitions into the
;; 'function' category (thus keeping it in both). I've opted to ;; 'function' category (thus keeping it in both). I've opted to

View file

@ -349,7 +349,7 @@ For example, you can set it to <return> like `isearch-exit'."
:version "28.1") :version "28.1")
(defcustom repeat-exit-timeout nil (defcustom repeat-exit-timeout nil
"Break the repetition chain of keys after specified timeout. "Break the repetition chain of keys after specified amount of idle time.
When a number, exit the transient repeating mode after idle time When a number, exit the transient repeating mode after idle time
of the specified number of seconds. of the specified number of seconds.
You can also set the property `repeat-exit-timeout' on the command symbol. You can also set the property `repeat-exit-timeout' on the command symbol.
@ -380,12 +380,12 @@ This property can override the value of this variable."
(defcustom repeat-check-key t (defcustom repeat-check-key t
"Whether to check that the last key exists in the repeat map. "Whether to check that the last key exists in the repeat map.
When non-nil and the last typed key (with or without modifiers) When non-nil, and the last typed key (with or without modifiers)
doesn't exist in the keymap attached by the `repeat-map' property, doesn't exist in the keymap specified by the `repeat-map' property
then don't activate that keymap for the next command. So only the of the command, don't activate that keymap for the next command.
same keys among repeatable keys are allowed in the repeating sequence. Thus, when this is non-nil, only the same keys among repeatable
For example, with a non-nil value, only \\`C-x u u' repeats undo, keys are allowed in the repeating sequence. For example, with a
whereas \\`C-/ u' doesn't. non-nil value, only \\`C-x u u' repeats undo, whereas \\`C-/ u' doesn't.
You can also set the property `repeat-check-key' on the command symbol. You can also set the property `repeat-check-key' on the command symbol.
This property can override the value of this variable. This property can override the value of this variable.
@ -398,7 +398,7 @@ but the property value is `t', then check the last key."
(defcustom repeat-echo-function #'repeat-echo-message (defcustom repeat-echo-function #'repeat-echo-message
"Function to display a hint about available keys. "Function to display a hint about available keys.
Function is called after every repeatable command with one argument: The function is called after every repeatable command with one argument:
a repeating map, or nil after deactivating the transient repeating mode. a repeating map, or nil after deactivating the transient repeating mode.
You can use `add-function' for multiple functions simultaneously." You can use `add-function' for multiple functions simultaneously."
:type '(choice (const :tag "Show hints in the echo area" :type '(choice (const :tag "Show hints in the echo area"
@ -422,8 +422,12 @@ the map can't be set on the command symbol property `repeat-map'.")
;;;###autoload ;;;###autoload
(define-minor-mode repeat-mode (define-minor-mode repeat-mode
"Toggle Repeat mode. "Toggle Repeat mode.
When Repeat mode is enabled, and the command symbol has the property named When Repeat mode is enabled, certain commands bound to multi-key
`repeat-map', this map is activated temporarily for the next command. sequences can be repeated by typing a single key, after typing the
full key sequence once.
The commands which can be repeated like that are those whose symbol
has the property `repeat-map' which specifies a keymap of single
keys for repeating.
See `describe-repeat-maps' for a list of all repeatable commands." See `describe-repeat-maps' for a list of all repeatable commands."
:global t :group 'repeat :global t :group 'repeat
(if (not repeat-mode) (if (not repeat-mode)
@ -459,7 +463,7 @@ See `describe-repeat-maps' for a list of all repeatable commands."
rep-map)))) rep-map))))
(defun repeat-check-key (key map) (defun repeat-check-key (key map)
"Check if the last key is suitable to activate the repeating MAP." "Check if the last KEY is suitable for activating the repeating MAP."
(let* ((prop (repeat--command-property 'repeat-check-key)) (let* ((prop (repeat--command-property 'repeat-check-key))
(check-key (unless (eq prop 'no) (or prop repeat-check-key)))) (check-key (unless (eq prop 'no) (or prop repeat-check-key))))
(or (not check-key) (or (not check-key)
@ -471,7 +475,7 @@ See `describe-repeat-maps' for a list of all repeatable commands."
"Previous minibuffer state.") "Previous minibuffer state.")
(defun repeat-check-map (map) (defun repeat-check-map (map)
"Decides whether MAP can be used for the next command." "Decide whether MAP can be used for the next command."
(and map (and map
;; Detect changes in the minibuffer state to allow repetitions ;; Detect changes in the minibuffer state to allow repetitions
;; in the same minibuffer, but not when the minibuffer is activated ;; in the same minibuffer, but not when the minibuffer is activated
@ -547,7 +551,7 @@ This function can be used to force exit of repetition while it's active."
(setq repeat-exit-function nil))) (setq repeat-exit-function nil)))
(defun repeat-echo-message-string (keymap) (defun repeat-echo-message-string (keymap)
"Return a string with a list of repeating keys." "Return a string with the list of repeating keys in KEYMAP."
(let (keys) (let (keys)
(map-keymap (lambda (key cmd) (and cmd (push key keys))) keymap) (map-keymap (lambda (key cmd) (and cmd (push key keys))) keymap)
(format-message "Repeat with %s%s" (format-message "Repeat with %s%s"
@ -565,7 +569,8 @@ This function can be used to force exit of repetition while it's active."
"")))) ""))))
(defun repeat-echo-message (keymap) (defun repeat-echo-message (keymap)
"Display available repeating keys in the echo area." "Display in the echo area the repeating keys defined by KEYMAP.
See `repeat-echo-function' to enable/disable."
(let ((message-log-max nil)) (let ((message-log-max nil))
(if keymap (if keymap
(let ((message (repeat-echo-message-string keymap))) (let ((message (repeat-echo-message-string keymap)))
@ -586,7 +591,9 @@ This function can be used to force exit of repetition while it's active."
"String displayed in the mode line in repeating mode.") "String displayed in the mode line in repeating mode.")
(defun repeat-echo-mode-line (keymap) (defun repeat-echo-mode-line (keymap)
"Display the repeat indicator in the mode line." "Display the repeat indicator in the mode line.
KEYMAP should be non-nil, but is otherwise ignored.
See `repeat-echo-function' to enable/disable."
(if keymap (if keymap
(unless (assq 'repeat-in-progress mode-line-modes) (unless (assq 'repeat-in-progress mode-line-modes)
(add-to-list 'mode-line-modes (list 'repeat-in-progress (add-to-list 'mode-line-modes (list 'repeat-in-progress
@ -596,9 +603,11 @@ This function can be used to force exit of repetition while it's active."
(declare-function help-fns--analyze-function "help-fns" (function)) (declare-function help-fns--analyze-function "help-fns" (function))
(defun describe-repeat-maps () (defun describe-repeat-maps ()
"Describe mappings of commands repeatable by symbol property `repeat-map'. "Describe transient keymaps installed for repeating multi-key commands.
If `repeat-mode' is enabled, these keymaps determine which single key These keymaps enable repetition of commands bound to multi-key
can be used to repeat a command invoked via a full key sequence." sequences by typing just one key, when `repeat-mode' is enabled.
Commands that can be repeated this way must have their symbol
to have the `repeat-map' property whose value specified a keymap."
(interactive) (interactive)
(require 'help-fns) (require 'help-fns)
(let ((help-buffer-under-preparation t)) (let ((help-buffer-under-preparation t))
@ -613,7 +622,9 @@ can be used to repeat a command invoked via a full key sequence."
(with-help-window (help-buffer) (with-help-window (help-buffer)
(with-current-buffer standard-output (with-current-buffer standard-output
(setq-local outline-regexp "[*]+") (setq-local outline-regexp "[*]+")
(insert "A list of keymaps used by commands with the symbol property `repeat-map'.\n") (insert "\
A list of keymaps and their single-key shortcuts for repeating commands.
Click on a keymap to see the commands repeatable by the keymap.\n")
(dolist (keymap (sort keymaps (lambda (a b) (dolist (keymap (sort keymaps (lambda (a b)
(when (and (symbolp (car a)) (when (and (symbolp (car a))

View file

@ -5871,6 +5871,25 @@ The value 0 disables blinking."
:group 'killing :group 'killing
:version "28.1") :version "28.1")
(defcustom copy-region-blink-predicate #'region-indistinguishable-p
"Whether the cursor must be blinked after a copy.
When this condition holds, and the copied region fits in the
current window, `kill-ring-save' will blink the cursor between
point and mark for `copy-region-blink-delay' seconds."
:type '(radio (function-item region-indistinguishable-p)
(function-item :doc "Always blink point and mark." always)
(function-item :doc "Never blink point and mark." ignore)
(function :tag "Other predicate function"))
:group 'killing
:version "29.1")
(defun region-indistinguishable-p ()
"Whether the current region is not denoted visually.
This holds when the region is inactive, or when the `region' face
cannot be distinguished from the `default' face."
(not (and (region-active-p)
(face-differs-from-default-p 'region))))
(defun indicate-copied-region (&optional message-len) (defun indicate-copied-region (&optional message-len)
"Indicate that the region text has been copied interactively. "Indicate that the region text has been copied interactively.
If the mark is visible in the selected window, blink the cursor between If the mark is visible in the selected window, blink the cursor between
@ -5891,8 +5910,7 @@ of this sample text; it defaults to 40."
;; was selected. Don't do it if the region is highlighted. ;; was selected. Don't do it if the region is highlighted.
(when (and (numberp copy-region-blink-delay) (when (and (numberp copy-region-blink-delay)
(> copy-region-blink-delay 0) (> copy-region-blink-delay 0)
(or (not (region-active-p)) (funcall copy-region-blink-predicate))
(not (face-background 'region nil t))))
;; Swap point and mark. ;; Swap point and mark.
(set-marker (mark-marker) (point) (current-buffer)) (set-marker (mark-marker) (point) (current-buffer))
(goto-char mark) (goto-char mark)

View file

@ -2653,14 +2653,14 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
(keymap-set tab-prefix-map "t" #'other-tab-prefix) (keymap-set tab-prefix-map "t" #'other-tab-prefix)
(defvar-keymap tab-bar-switch-repeat-map (defvar-keymap tab-bar-switch-repeat-map
:doc "Keymap to repeat tab switch key sequences \\`C-x t o o O'. :doc "Keymap to repeat tab switch commands `tab-next' and `tab-previous'.
Used in `repeat-mode'." Used in `repeat-mode'."
:repeat t :repeat t
"o" #'tab-next "o" #'tab-next
"O" #'tab-previous) "O" #'tab-previous)
(defvar-keymap tab-bar-move-repeat-map (defvar-keymap tab-bar-move-repeat-map
:doc "Keymap to repeat tab move key sequences \\`C-x t m m M'. :doc "Keymap to repeat tab move commands `tab-move' and `tab-bar-move-tab-backward'.
Used in `repeat-mode'." Used in `repeat-mode'."
:repeat t :repeat t
"m" #'tab-move "m" #'tab-move

View file

@ -10567,8 +10567,7 @@ displaying that processes's buffer."
(define-key ctl-x-4-map "4" 'other-window-prefix) (define-key ctl-x-4-map "4" 'other-window-prefix)
(defvar-keymap other-window-repeat-map (defvar-keymap other-window-repeat-map
:doc "Keymap to repeat `other-window' key sequences. :doc "Keymap to repeat `other-window'. Used in `repeat-mode'."
Used in `repeat-mode'."
:repeat t :repeat t
"o" #'other-window "o" #'other-window
"O" (lambda () "O" (lambda ()
@ -10578,6 +10577,8 @@ Used in `repeat-mode'."
(defvar-keymap resize-window-repeat-map (defvar-keymap resize-window-repeat-map
:doc "Keymap to repeat window resizing commands. :doc "Keymap to repeat window resizing commands.
Repeatable commands are `enlarge-window' and `shrink-window',
and also `enlarge-window-horizontally' and `shrink-window-horizontally'.
Used in `repeat-mode'." Used in `repeat-mode'."
:repeat t :repeat t
;; Standard keys: ;; Standard keys:

View file

@ -1101,6 +1101,10 @@ insert_from_gap_1 (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
eassert (NILP (BVAR (current_buffer, enable_multibyte_characters)) eassert (NILP (BVAR (current_buffer, enable_multibyte_characters))
? nchars == nbytes : nchars <= nbytes); ? nchars == nbytes : nchars <= nbytes);
#ifdef HAVE_TREE_SITTER
ptrdiff_t ins_bytepos = GPT_BYTE;
#endif
GAP_SIZE -= nbytes; GAP_SIZE -= nbytes;
if (! text_at_gap_tail) if (! text_at_gap_tail)
{ {
@ -1115,6 +1119,12 @@ insert_from_gap_1 (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
/* Put an anchor to ensure multi-byte form ends at gap. */ /* Put an anchor to ensure multi-byte form ends at gap. */
if (GAP_SIZE > 0) *(GPT_ADDR) = 0; if (GAP_SIZE > 0) *(GPT_ADDR) = 0;
eassert (GPT <= GPT_BYTE); eassert (GPT <= GPT_BYTE);
#ifdef HAVE_TREE_SITTER
eassert (nbytes >= 0);
eassert (ins_bytepos >= 0);
treesit_record_change (ins_bytepos, ins_bytepos, ins_bytepos + nbytes);
#endif
} }
/* Insert a sequence of NCHARS chars which occupy NBYTES bytes /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
@ -1150,12 +1160,6 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
current_buffer, 0); current_buffer, 0);
} }
#ifdef HAVE_TREE_SITTER
eassert (nbytes >= 0);
eassert (ins_bytepos >= 0);
treesit_record_change (ins_bytepos, ins_bytepos, ins_bytepos + nbytes);
#endif
if (ins_charpos < PT) if (ins_charpos < PT)
adjust_point (nchars, nbytes); adjust_point (nchars, nbytes);
@ -1191,6 +1195,9 @@ insert_from_buffer (struct buffer *buf,
#endif #endif
} }
/* NOTE: If we ever make insert_from_buffer_1 public, make sure to
move the call to treesit_record_change into it. */
static void static void
insert_from_buffer_1 (struct buffer *buf, insert_from_buffer_1 (struct buffer *buf,
ptrdiff_t from, ptrdiff_t nchars, bool inherit) ptrdiff_t from, ptrdiff_t nchars, bool inherit)

View file

@ -4801,6 +4801,9 @@ extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t *); ptrdiff_t, ptrdiff_t *);
extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t *); ptrdiff_t, ptrdiff_t *);
extern EMACS_INT search_buffer (Lisp_Object, ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t, EMACS_INT,
int, Lisp_Object, Lisp_Object, bool);
extern void syms_of_search (void); extern void syms_of_search (void);
extern void clear_regexp_cache (void); extern void clear_regexp_cache (void);

View file

@ -68,9 +68,6 @@ static EMACS_INT simple_search (EMACS_INT, unsigned char *, ptrdiff_t,
static EMACS_INT boyer_moore (EMACS_INT, unsigned char *, ptrdiff_t, static EMACS_INT boyer_moore (EMACS_INT, unsigned char *, ptrdiff_t,
Lisp_Object, Lisp_Object, ptrdiff_t, Lisp_Object, Lisp_Object, ptrdiff_t,
ptrdiff_t, int); ptrdiff_t, int);
static EMACS_INT search_buffer (Lisp_Object, ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t, EMACS_INT, int,
Lisp_Object, Lisp_Object, bool);
Lisp_Object re_match_object; Lisp_Object re_match_object;
@ -1510,7 +1507,7 @@ search_buffer_non_re (Lisp_Object string, ptrdiff_t pos,
return result; return result;
} }
static EMACS_INT EMACS_INT
search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
ptrdiff_t lim, ptrdiff_t lim_byte, EMACS_INT n, ptrdiff_t lim, ptrdiff_t lim_byte, EMACS_INT n,
int RE, Lisp_Object trt, Lisp_Object inverse_trt, bool posix) int RE, Lisp_Object trt, Lisp_Object inverse_trt, bool posix)

View file

@ -399,7 +399,7 @@ row_to_value (sqlite3_stmt *stmt)
int len = sqlite3_column_count (stmt); int len = sqlite3_column_count (stmt);
Lisp_Object values = Qnil; Lisp_Object values = Qnil;
for (int i = 0; i < len; ++i) for (int i = len - 1; i >= 0; i--)
{ {
Lisp_Object v = Qnil; Lisp_Object v = Qnil;
@ -434,7 +434,7 @@ row_to_value (sqlite3_stmt *stmt)
values = Fcons (v, values); values = Fcons (v, values);
} }
return Fnreverse (values); return values;
} }
static Lisp_Object static Lisp_Object
@ -718,11 +718,15 @@ Only modules on Emacs' list of allowed modules can be loaded. */)
#endif /* HAVE_SQLITE3_LOAD_EXTENSION */ #endif /* HAVE_SQLITE3_LOAD_EXTENSION */
DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0, DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0,
doc: /* Return the next result set from SET. */) doc: /* Return the next result set from SET.
Return nil when the statement has finished executing successfully. */)
(Lisp_Object set) (Lisp_Object set)
{ {
check_sqlite (set, true); check_sqlite (set, true);
if (XSQLITE (set)->eof)
return Qnil;
int ret = sqlite3_step (XSQLITE (set)->stmt); int ret = sqlite3_step (XSQLITE (set)->stmt);
if (ret != SQLITE_ROW && ret != SQLITE_OK && ret != SQLITE_DONE) if (ret != SQLITE_ROW && ret != SQLITE_OK && ret != SQLITE_DONE)
xsignal1 (Qsqlite_error, build_string (sqlite3_errmsg (XSQLITE (set)->db))); xsignal1 (Qsqlite_error, build_string (sqlite3_errmsg (XSQLITE (set)->db)));

View file

@ -2470,13 +2470,42 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures)
build_string ("The second argument to `match' should " build_string ("The second argument to `match' should "
"be a capture name, not a string")); "be a capture name, not a string"));
Lisp_Object text = treesit_predicate_capture_name_to_text (capture_name, Lisp_Object node = treesit_predicate_capture_name_to_node (capture_name,
captures); captures);
if (fast_string_match (regexp, text) >= 0) struct buffer *old_buffer = current_buffer;
return true; struct buffer *buffer = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer);
else set_buffer_internal (buffer);
return false;
TSNode treesit_node = XTS_NODE (node)->node;
ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg;
uint32_t start_byte_offset = ts_node_start_byte (treesit_node);
uint32_t end_byte_offset = ts_node_end_byte (treesit_node);
ptrdiff_t start_byte = visible_beg + start_byte_offset;
ptrdiff_t end_byte = visible_beg + end_byte_offset;
ptrdiff_t start_pos = BYTE_TO_CHAR (start_byte);
ptrdiff_t end_pos = BYTE_TO_CHAR (end_byte);
ptrdiff_t old_begv = BEGV;
ptrdiff_t old_begv_byte = BEGV_BYTE;
ptrdiff_t old_zv = ZV;
ptrdiff_t old_zv_byte = ZV_BYTE;
BEGV = start_pos;
BEGV_BYTE = start_byte;
ZV = end_pos;
ZV_BYTE = end_byte;
ptrdiff_t val = search_buffer (regexp, start_pos, start_byte,
end_pos, end_byte, 1, 1, Qnil, Qnil, false);
BEGV = old_begv;
BEGV_BYTE = old_begv_byte;
ZV = old_zv;
ZV_BYTE = old_zv_byte;
set_buffer_internal (old_buffer);
return (val > 0);
} }
/* Handles predicate (#pred FN ARG...). Return true if FN returns /* Handles predicate (#pred FN ARG...). Return true if FN returns

View file

@ -2780,8 +2780,7 @@ merge_face_ref (struct window *w,
else if (EQ (keyword, QCstipple)) else if (EQ (keyword, QCstipple))
{ {
#if defined (HAVE_WINDOW_SYSTEM) #if defined (HAVE_WINDOW_SYSTEM)
Lisp_Object pixmap_p = Fbitmap_spec_p (value); if (NILP (value) || !NILP (Fbitmap_spec_p (value)))
if (!NILP (pixmap_p))
to[LFACE_STIPPLE_INDEX] = value; to[LFACE_STIPPLE_INDEX] = value;
else else
err = true; err = true;

View file

@ -1,9 +1,9 @@
Code: Code:
(lambda () (lambda ()
(setq indent-tabs-mode nil)
(setq c-ts-mode-indent-offset 2)
(setq c-ts-mode-indent-style 'bsd)
(c-ts-mode) (c-ts-mode)
(setq-local indent-tabs-mode nil)
(setq-local c-ts-mode-indent-offset 2)
(c-ts-mode-set-local-style 'bsd)
(indent-region (point-min) (point-max))) (indent-region (point-min) (point-max)))
Point-Char: | Point-Char: |

View file

@ -1,9 +1,9 @@
Code: Code:
(lambda () (lambda ()
(setq indent-tabs-mode nil)
(setq c-ts-mode-indent-offset 2)
(setq c-ts-mode-indent-style 'gnu)
(c-ts-mode) (c-ts-mode)
(setq-local indent-tabs-mode nil)
(setq-local c-ts-mode-indent-offset 2)
(c-ts-mode-set-local-style 'gnu)
(indent-region (point-min) (point-max))) (indent-region (point-min) (point-max)))
Point-Char: | Point-Char: |
@ -135,32 +135,6 @@ int main() {
} }
=-=-= =-=-=
Name: Bracket-less Block-Statement (Linux Style) (bug#61026)
=-=-=
int main() {
while (true)
if (true) {
puts ("Hello");
}
for (int i=0;
i<5;
i++)
if (true) {
puts ("Hello");
}
do
if (true) {
puts ("Hello");
}
while (true);
if (true)
if (true) {
puts ("Hello");
}
}
=-=-=
Name: Multiline Parameter List (bug#60398) Name: Multiline Parameter List (bug#60398)
=-= =-=
@ -219,10 +193,10 @@ line 2
Code: Code:
(lambda () (lambda ()
(setq indent-tabs-mode nil)
(setq c-ts-mode-indent-offset 8)
(setq c-ts-mode-indent-style 'linux)
(c-ts-mode) (c-ts-mode)
(setq-local indent-tabs-mode nil)
(setq-local c-ts-mode-indent-offset 8)
(c-ts-mode-set-local-style 'linux)
(indent-region (point-min) (point-max))) (indent-region (point-min) (point-max)))
Name: Labels (Linux Style) Name: Labels (Linux Style)
@ -244,3 +218,29 @@ label:
} }
} }
=-=-= =-=-=
Name: Bracket-less Block-Statement (Linux Style) (bug#61026)
=-=-=
int main() {
while (true)
if (true) {
puts ("Hello");
}
for (int i=0;
i<5;
i++)
if (true) {
puts ("Hello");
}
do
if (true) {
puts ("Hello");
}
while (true);
if (true)
if (true) {
puts ("Hello");
}
}
=-=-=