Merge from origin/emacs-29

5303152872 Revert "Fix treesit-node-field-name and friends (bug#66674)"
fa0bb88302 ; * src/buffer.c (syms_of_buffer) <default-directory>: Do...
44517037ae ; Fix typo
ccf46acefd ; Fix last change.
c86b039dff ; * etc/DEBUG: Improve advice for debugging native-compil...
9afba605bb Explain status "r" in `epa-list-keys`
6271422196 ; * lisp/dired.el (dired--make-directory-clickable): Refo...
fcbb004489 Fix mouse clicks on directory line in Dired
be8a7155b4 Fix 'split-root-window-right' and 'split-root-window-below'
eb19984c4d Mark icalendar.el as maintained by emacs-devel
03dc914fd3 ; Fix footnotes in ELisp Intro manual
ceacf75395 Fix usage of `setq-default' and offer more suggestions
2701da0eee Fix python-ts-mode triple quote syntax (bug#67262)
683c7c9687 Increment parser timestamp when narrowing changes (bug#67...
8ae42c825e ruby-ts-mode: Fix indentation for string_array closer
9cfa498e0a treesit-major-mode-setup: Use 'treesit--syntax-propertize...
da2e440462 ruby-ts-mode: Fix an out-of-bounds error with heredoc at eob
6ea507296a Correctly refontify changed region in tree-sitter modes (...
This commit is contained in:
Eli Zaretskii 2023-12-30 04:51:17 -05:00
commit 3b7198dc47
15 changed files with 175 additions and 48 deletions

View file

@ -16892,8 +16892,14 @@ remember to look here to remind myself.
@node Text and Auto-fill
@section Text and Auto Fill Mode
Now we come to the part that turns on Text mode and
Auto Fill mode.
Now we come to the part that turns on Text mode and Auto Fill
mode@footnote{
This section suggests settings that are more suitable for writers.
For programmers, the default mode will be set to the corresponding
prog-mode automatically based on the type of the file. And it's
perfectly fine if you want to keep the fundamental mode as the default
mode.
}.
@smallexample
@group
@ -16945,21 +16951,26 @@ Here is the line again; how does it work?
@cindex Text Mode turned on
@smallexample
(setq major-mode 'text-mode)
(setq-default major-mode 'text-mode)
@end smallexample
@noindent
This line is a short, but complete Emacs Lisp expression.
We are already familiar with @code{setq}. It sets the following
variable, @code{major-mode}, to the subsequent value, which is
@code{text-mode}. The single-quote before @code{text-mode} tells
Emacs to deal directly with the @code{text-mode} symbol, not with
whatever it might stand for. @xref{setq, , Setting the Value of
a Variable}, for a reminder of how @code{setq} works. The main point
is that there is no difference between the procedure you use to set
a value in your @file{.emacs} file and the procedure you use anywhere
else in Emacs.
We are already familiar with @code{setq}. We use a similar macro
@code{setq-default} to set the following variable,
@code{major-mode}@footnote{
We use @code{setq-default} here because @code{text-mode} is
buffer-local. If we use @code{setq}, it will only apply to the
current buffer, whereas using @code{setq-default} will also apply to
newly created buffers. This is not recommended for programmers.
}, to the subsequent value, which is @code{text-mode}. The
single-quote before @code{text-mode} tells Emacs to deal directly with
the @code{text-mode} symbol, not with whatever it might stand for.
@xref{setq, , Setting the Value of a Variable}, for a reminder of how
@code{setq} works. The main point is that there is no difference
between the procedure you use to set a value in your @file{.emacs}
file and the procedure you use anywhere else in Emacs.
@need 800
Here is the next line:

View file

@ -729,7 +729,7 @@ has over @code{cl-case}
;; symbol
('success (message "Done!"))
('would-block (message "Sorry, can't do it now"))
('read-only (message "The shmliblick is read-only"))
('read-only (message "The schmilblick is read-only"))
('access-denied (message "You do not have the needed rights"))
@end group
@group

View file

@ -1071,8 +1071,8 @@ This function returns the field name of the @var{n}'th child of
@var{node}. It returns @code{nil} if there is no @var{n}'th child, or
the @var{n}'th child doesn't have a field name.
Note that @var{n} counts named nodes only, and @var{n} can be
negative, e.g., @minus{}1 represents the last child.
Note that @var{n} counts both named and anonymous children, and
@var{n} can be negative, e.g., @minus{}1 represents the last child.
@end defun
@defun treesit-node-child-count node &optional named

View file

@ -605,7 +605,17 @@ recommend to follow the procedure below to try to identify the cause:
. Reduce the problematic .el file to the minimum by bisection, and
try identifying the function that causes the problem.
. Reduce the problematic function to the minimal code that still
. Try natively compiling the problematic file with
'native-comp-speed' set to 1 or even zero. If doing that solves
the problem, you can use
(declare (speed 1))
at the beginning of the body of suspected function(s) to change
'native-comp-speed' only for those functions -- this could help you
identify the function(s) which cause(s) the problem.
. Reduce the problematic function(s) to the minimal code that still
reproduces the problem.
. Study the problem's artifacts, like Lisp or C backtraces, to try

View file

@ -3,6 +3,7 @@
;; Copyright (C) 2002-2023 Free Software Foundation, Inc.
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Maintainer: emacs-devel@gnu.org
;; Created: August 2002
;; Keywords: calendar
;; Human-Keywords: calendar, diary, iCalendar, vCalendar

View file

@ -2017,9 +2017,22 @@ mouse-2: visit this file in other window"
keymap ,(let* ((current-dir dir)
(click (lambda ()
(interactive)
(if (assoc current-dir dired-subdir-alist)
(dired-goto-subdir current-dir)
(dired current-dir)))))
(cond
((assoc current-dir dired-subdir-alist)
(dired-goto-subdir current-dir))
;; If there is a wildcard chars
;; in the directory name, don't
;; use the alternate file machinery
;; which tries to keep only one
;; dired buffer open at once.
;;
;; FIXME: Is this code path reachable?
((insert-directory-wildcard-in-dir-p
current-dir)
(dired current-dir))
(t
(dired--find-possibly-alternative-file
current-dir))))))
(define-keymap
"<mouse-2>" click
"<follow-link>" 'mouse-face

View file

@ -384,7 +384,7 @@ DOC is documentation text to insert at the start."
(epa--list-keys name nil
"The letters at the start of a line have these meanings.
e expired key. n never trust. m trust marginally. u trust ultimately.
f trust fully (keys you have signed, usually).
f trust fully (keys you have signed, usually). r revoked key.
q trust status questionable. - trust status unspecified.
See GPG documentation for more explanation.
\n"))

View file

@ -1238,6 +1238,21 @@ For NODE, OVERRIDE, START, END, and ARGS, see
(treesit-node-start node) (treesit-node-end node)
'font-lock-variable-use-face override start end)))
(defun python--treesit-syntax-propertize (start end)
"Propertize triple-quote strings between START and END."
(save-excursion
(goto-char start)
(while (re-search-forward (rx (or "\"\"\"" "'''")) end t)
(let ((node (treesit-node-at (point))))
;; The triple quotes surround a non-empty string.
(when (equal (treesit-node-type node) "string_content")
(let ((start (treesit-node-start node))
(end (treesit-node-end node)))
(put-text-property (1- start) start
'syntax-table (string-to-syntax "|"))
(put-text-property end (min (1+ end) (point-max))
'syntax-table (string-to-syntax "|"))))))))
;;; Indentation
@ -6854,6 +6869,8 @@ implementations: `python-mode' and `python-ts-mode'."
#'python--treesit-defun-name)
(treesit-major-mode-setup)
(setq-local syntax-propertize-function #'python--treesit-syntax-propertize)
(python-skeleton-add-menu-items)
(when python-indent-guess-indent-offset

View file

@ -753,8 +753,9 @@ a statement container is a node that matches
((match "}" "hash") ruby-ts--parent-call-or-bol 0)
((parent-is "hash") ruby-ts--parent-call-or-bol ruby-indent-level)
((match "]" "array") ruby-ts--parent-call-or-bol 0)
((parent-is "array") ruby-ts--parent-call-or-bol ruby-indent-level)
((match "]" "^array") ruby-ts--parent-call-or-bol 0)
((parent-is "^array") ruby-ts--parent-call-or-bol ruby-indent-level)
((match ")" "string_array") ruby-ts--parent-call-or-bol 0)
((parent-is "pair") ruby-ts--parent-call-or-bol 0)
@ -1063,8 +1064,9 @@ leading double colon is not added."
('heredoc
(put-text-property (treesit-node-start node) (1+ (treesit-node-start node))
'syntax-table (string-to-syntax "\""))
(put-text-property (treesit-node-end node) (1+ (treesit-node-end node))
'syntax-table (string-to-syntax "\"")))
(when (< (treesit-node-end node) (point-max))
(put-text-property (treesit-node-end node) (1+ (treesit-node-end node))
'syntax-table (string-to-syntax "\""))))
('percent
;; FIXME: Put the first one on the first paren in both %Q{} and %().
;; That would stop electric-pair-mode from pairing, though. Hmm.
@ -1192,20 +1194,8 @@ leading double colon is not added."
(treesit-major-mode-setup)
(treesit-parser-add-notifier (car (treesit-parser-list))
#'ruby-ts--parser-after-change)
(setq-local syntax-propertize-function #'ruby-ts--syntax-propertize))
(defun ruby-ts--parser-after-change (ranges parser)
;; Make sure we re-syntax-propertize the full node that is being
;; edited. This is most pertinent to multi-line complex nodes such
;; as heredocs.
(when ranges
(with-current-buffer (treesit-parser-buffer parser)
(syntax-ppss-flush-cache (cl-loop for r in ranges
minimize (car r))))))
(if (treesit-ready-p 'ruby)
;; Copied from ruby-mode.el.
(add-to-list 'auto-mode-alist

View file

@ -385,7 +385,6 @@ If NAMED is non-nil, collect named child only."
"Return the index of NODE in its parent.
If NAMED is non-nil, count named child only."
(let ((count 0))
;; TODO: Use next-sibling as it's more efficient.
(while (setq node (treesit-node-prev-sibling node named))
(cl-incf count))
count))
@ -393,7 +392,7 @@ If NAMED is non-nil, count named child only."
(defun treesit-node-field-name (node)
"Return the field name of NODE as a child of its parent."
(when-let ((parent (treesit-node-parent node))
(idx (treesit-node-index node t)))
(idx (treesit-node-index node)))
(treesit-node-field-name-for-child parent idx)))
(defun treesit-node-get (node instructions)
@ -1331,6 +1330,72 @@ parser notifying of the change."
(with-silent-modifications
(put-text-property (car range) (cdr range) 'fontified nil)))))
(defvar-local treesit--syntax-propertize-start nil
"If non-nil, next `syntax-propertize' should start at this position.
When tree-sitter parser reparses, it calls
`treesit--syntax-propertize-notifier' with the affected region,
and that function sets this variable to the start of the affected
region.")
(defun treesit--syntax-propertize-notifier (ranges parser)
"Sets `treesit--syntax-propertize-start' to the smallest start.
Specifically, the smallest start position among all the ranges in
RANGES for PARSER."
(with-current-buffer (treesit-parser-buffer parser)
(when-let* ((range-starts (mapcar #'car ranges))
(min-range-start
(seq-reduce
#'min (cdr range-starts) (car range-starts))))
(if (null treesit--syntax-propertize-start)
(setq treesit--syntax-propertize-start min-range-start)
(setq treesit--syntax-propertize-start
(min treesit--syntax-propertize-start min-range-start))))))
(defvar-local treesit--pre-redisplay-tick nil
"The last `buffer-chars-modified-tick' that we've processed.
Because `pre-redisplay-functions' could be called multiple times
during a single command loop, we use this variable to debounce
calls to `treesit--pre-redisplay'.")
(defun treesit--pre-redisplay (&rest _)
"Force reparse and consequently run all notifiers.
One of the notifiers is `treesit--font-lock-notifier', which will
mark the region whose syntax has changed to \"need to refontify\".
For example, when the user types the final slash of a C block
comment /* xxx */, not only do we need to fontify the slash, but
also the whole block comment, which previously wasn't fontified
as comment due to incomplete parse tree."
(unless (eq treesit--pre-redisplay-tick (buffer-chars-modified-tick))
;; `treesit-update-ranges' will force the host language's parser to
;; reparse and set correct ranges for embedded parsers. Then
;; `treesit-parser-root-node' will force those parsers to reparse.
(treesit-update-ranges)
;; Force repase on _all_ the parsers might not be necessary, but
;; this is probably the most robust way.
(dolist (parser (treesit-parser-list))
(treesit-parser-root-node parser))
(setq treesit--pre-redisplay-tick (buffer-chars-modified-tick))))
(defun treesit--pre-syntax-ppss (start end)
"Force reparse and consequently run all notifiers.
Similar to font-lock, we want to update the `syntax' text
property before `syntax-ppss' starts working on the text. We
also want to extend the to-be-propertized region to include the
whole region affected by the last reparse.
START and END mark the current to-be-propertized region."
(treesit--pre-redisplay)
(let ((new-start treesit--syntax-propertize-start))
(if (and new-start (< new-start start))
(progn
(setq treesit--syntax-propertize-start nil)
(cons new-start end))
nil)))
;;; Indent
(define-error 'treesit-indent-error
@ -2853,7 +2918,14 @@ before calling this function."
(treesit-font-lock-recompute-features)
(dolist (parser (treesit-parser-list))
(treesit-parser-add-notifier
parser #'treesit--font-lock-notifier)))
parser #'treesit--font-lock-notifier))
(add-hook 'pre-redisplay-functions #'treesit--pre-redisplay 0 t))
;; Syntax
(dolist (parser (treesit-parser-list))
(treesit-parser-add-notifier
parser #'treesit--syntax-propertize-notifier))
(add-hook 'syntax-propertize-extend-region-functions
#'treesit--pre-syntax-ppss 0 t)
;; Indent.
(when treesit-simple-indent-rules
(setq-local treesit-simple-indent-rules

View file

@ -5737,7 +5737,8 @@ The current window configuration is retained in the top window,
the lower window takes up the whole width of the frame. SIZE is
handled as in `split-window-below', and interactively is the
prefix numeric argument."
(interactive "p")
(interactive `(,(when current-prefix-arg
(prefix-numeric-value current-prefix-arg))))
(split-window-below size (frame-root-window)))
(defun split-window-right (&optional size window-to-split)
@ -5777,7 +5778,8 @@ The current window configuration is retained within the left
window, and a new window is created on the right, taking up the
whole height of the frame. SIZE is treated as by
`split-window-right' and interactively, is the prefix numeric argument."
(interactive "p")
(interactive `(,(when current-prefix-arg
(prefix-numeric-value current-prefix-arg))))
(split-window-right size (frame-root-window)))
;;; Balancing windows.

View file

@ -5367,8 +5367,8 @@ visual lines rather than logical lines. See the documentation of
Qstringp,
doc: /* Name of default directory of current buffer.
It should be an absolute directory name; on GNU and Unix systems,
these names start with `/' or `~' and end with `/'.
To interactively change the default directory, use command `cd'. */);
these names start with "/" or "~" and end with "/".
To interactively change the default directory, use the command `cd'. */);
DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function),
Qnil,

View file

@ -948,7 +948,10 @@ treesit_sync_visible_region (Lisp_Object parser)
this function is called), we need to reparse. */
if (visible_beg != BUF_BEGV_BYTE (buffer)
|| visible_end != BUF_ZV_BYTE (buffer))
XTS_PARSER (parser)->need_reparse = true;
{
XTS_PARSER (parser)->need_reparse = true;
XTS_PARSER (parser)->timestamp++;
}
/* Before we parse or set ranges, catch up with the narrowing
situation. We change visible_beg and visible_end to match
@ -1722,6 +1725,7 @@ buffer. */)
ranges);
XTS_PARSER (parser)->need_reparse = true;
XTS_PARSER (parser)->timestamp++;
return Qnil;
}
@ -2066,8 +2070,9 @@ DEFUN ("treesit-node-field-name-for-child",
Return nil if there's no Nth child, or if it has no field.
If NODE is nil, return nil.
Note that N counts named nodes only. Also, N could be negative, e.g.,
-1 represents the last child. */)
N counts all children, i.e., named ones and anonymous ones.
N could be negative, e.g., -1 represents the last child. */)
(Lisp_Object node, Lisp_Object n)
{
if (NILP (node))
@ -2081,7 +2086,7 @@ Note that N counts named nodes only. Also, N could be negative, e.g.,
/* Process negative index. */
if (idx < 0)
idx = ts_node_named_child_count (treesit_node) + idx;
idx = ts_node_child_count (treesit_node) + idx;
if (idx < 0)
return Qnil;
if (idx > UINT32_MAX)

View file

@ -61,7 +61,9 @@ struct Lisp_TS_Parser
/* Re-parsing an unchanged buffer is not free for tree-sitter, so we
only make it re-parse when need_reparse == true. That usually
means some change is made in the buffer. But others could set
this field to true to force tree-sitter to re-parse. */
this field to true to force tree-sitter to re-parse. When you
set this to true, you should _always_ also increment
timestamp. */
bool need_reparse;
/* These two positions record the buffer byte position (1-based) of
the "visible region" that tree-sitter sees. Before re-parse, we

View file

@ -85,6 +85,10 @@
foo(foo, :bar =>
tee)
foo = %w[
asd
]
# Local Variables:
# mode: ruby-ts
# ruby-after-operator-indent: t