summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2023-04-15 13:05:04 -0400
committerEli Zaretskii <eliz@gnu.org>2023-04-15 13:05:04 -0400
commitbc61a1afdd6c3ba8a605ed46ae97b1e36b40f951 (patch)
tree2a1b5d52bdd74fe0a3d2098d526d862f0737c485
parenta85279f390523f0872a5462219941e440feb7393 (diff)
parentb7023da6627f911c087961d9d476b3eafabb7ae7 (diff)
downloademacs-bc61a1afdd6c3ba8a605ed46ae97b1e36b40f951.tar.gz
Merge from origin/emacs-29
b7023da6627 Make image-map bindings available on image links d9e96c029bb * CONTRIBUTE: Fix a typo 3f71a2a0cf6 ; * lisp/progmodes/c-ts-mode.el (treesit-node-next-siblin... adf9c956c28 Add to Eglot support for additional language-servers. b3603b84bd9 Partial support for DEFUN in c-ts-mode (bug#62825) # Conflicts: # lisp/progmodes/c-ts-mode.el
-rw-r--r--CONTRIBUTE2
-rw-r--r--lisp/net/eww.el2
-rw-r--r--lisp/net/shr.el2
-rw-r--r--lisp/progmodes/c-ts-mode.el127
-rw-r--r--lisp/progmodes/eglot.el6
5 files changed, 109 insertions, 30 deletions
diff --git a/CONTRIBUTE b/CONTRIBUTE
index f56ba1df630..464b800adfb 100644
--- a/CONTRIBUTE
+++ b/CONTRIBUTE
@@ -321,7 +321,7 @@ them right the first time, so here are guidelines for formatting them:
** Committing your changes.
When you commit changes, Git invokes several scripts that test the
-commit for validity, and may abort the commit of some of the tests
+commit for validity, and may abort the commit if some of the tests
fail. These scripts live in the '.git/hooks/' subdirectory of the
top-level directory of the repository, and they perform the following
tests:
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 11be20b68db..99450356b7c 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -326,7 +326,7 @@ parameter, and should return the (possibly) transformed URL."
"<mouse-2>" #'eww-follow-link)
(defvar-keymap eww-image-link-keymap
- :parent shr-map
+ :parent shr-image-map
"RET" #'eww-follow-link)
(defun eww-suggested-uris nil
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 9c2ae98d77e..4e44dfbef03 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -276,7 +276,7 @@ and other things:
(defvar-keymap shr-map
"a" #'shr-show-alt-text
- "i" #'shr-browse-image
+ "M-i" #'shr-browse-image
"z" #'shr-zoom-image
"TAB" #'shr-next-link
"C-M-i" #'shr-previous-link
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 5a38d714e5a..e93a0fec707 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -79,6 +79,7 @@
(declare-function treesit-node-type "treesit.c")
(declare-function treesit-node-prev-sibling "treesit.c")
(declare-function treesit-node-first-child-for-pos "treesit.c")
+(declare-function treesit-node-next-sibling "treesit.c")
;;; Custom variables
@@ -192,6 +193,10 @@ To set the default indent style globally, use
(c-ts-mode--get-indent-style
(if (derived-mode-p 'c-ts-mode) 'c 'cpp))))))
+(defvar c-ts-mode-emacs-devel nil
+ "If the value is t, enable Emacs source-specific features.
+This needs to be set before enabling `c-ts-mode'.")
+
;;; Syntax table
(defvar c-ts-mode--syntax-table
@@ -802,7 +807,14 @@ Return nil if NODE is not a defun node or doesn't have a name."
((or "struct_specifier" "enum_specifier"
"union_specifier" "class_specifier"
"namespace_definition")
- (treesit-node-child-by-field-name node "name")))
+ (treesit-node-child-by-field-name node "name"))
+ ;; DEFUNs in Emacs source.
+ ("expression_statement"
+ (let* ((call-exp-1 (treesit-node-child node 0))
+ (call-exp-2 (treesit-node-child call-exp-1 0))
+ (arg-list (treesit-node-child call-exp-2 1))
+ (name (treesit-node-child arg-list 1 t)))
+ name)))
t))
;;; Defun navigation
@@ -810,28 +822,29 @@ Return nil if NODE is not a defun node or doesn't have a name."
(defun c-ts-mode--defun-valid-p (node)
"Return non-nil if NODE is a valid defun node.
Ie, NODE is not nested."
- (not (or (and (member (treesit-node-type node)
- '("struct_specifier"
- "enum_specifier"
- "union_specifier"
- "declaration"))
- ;; If NODE's type is one of the above, make sure it is
- ;; top-level.
- (treesit-node-top-level
- node (rx (or "function_definition"
- "type_definition"
- "struct_specifier"
+ (or (c-ts-mode--emacs-defun-p node)
+ (not (or (and (member (treesit-node-type node)
+ '("struct_specifier"
"enum_specifier"
"union_specifier"
- "declaration"))))
+ "declaration"))
+ ;; If NODE's type is one of the above, make sure it is
+ ;; top-level.
+ (treesit-node-top-level
+ node (rx (or "function_definition"
+ "type_definition"
+ "struct_specifier"
+ "enum_specifier"
+ "union_specifier"
+ "declaration"))))
- (and (equal (treesit-node-type node) "declaration")
- ;; If NODE is a declaration, make sure it is not a
- ;; function declaration.
- (equal (treesit-node-type
- (treesit-node-child-by-field-name
- node "declarator"))
- "function_declarator")))))
+ (and (equal (treesit-node-type node) "declaration")
+ ;; If NODE is a declaration, make sure it is not a
+ ;; function declaration.
+ (equal (treesit-node-type
+ (treesit-node-child-by-field-name
+ node "declarator"))
+ "function_declarator"))))))
(defun c-ts-mode--defun-for-class-in-imenu-p (node)
"Check if NODE is a valid entry for the Class subindex.
@@ -871,17 +884,73 @@ the semicolon. This function skips the semicolon."
(setq parent (treesit-node-parent smallest-node)))))
(list node parent bol)))
+(defun c-ts-mode--emacs-defun-p (node)
+ "Return non-nil if NODE is a DEFUN in Emacs source files."
+ (and (equal (treesit-node-type node) "expression_statement")
+ (equal (treesit-node-text
+ (treesit-node-child-by-field-name
+ (treesit-node-child
+ (treesit-node-child node 0) 0)
+ "function")
+ t)
+ "DEFUN")))
+
+(defun c-ts-mode--emacs-defun-at-point (&optional range)
+ "Return the current defun node.
+
+This function recognizes DEFUNs in Emacs source files.
+
+Note that for the case of a DEFUN, it is made of two separate
+nodes, one for the declaration and one for the body, this
+function returns the declaration node.
+
+If RANGE is non-nil, return (BEG . END) where BEG end END
+encloses the whole defun. This solves the problem of only
+returning the declaration part for DEFUN."
+ (or (when-let ((node (treesit-defun-at-point)))
+ (if range
+ (cons (treesit-node-start node)
+ (treesit-node-end node))
+ node))
+ (and c-ts-mode-emacs-devel
+ (let ((candidate-1 ; For when point is in the DEFUN statement.
+ (treesit-node-prev-sibling
+ (treesit-node-top-level
+ (treesit-node-at (point))
+ "compound_statement")))
+ (candidate-2 ; For when point is in the body.
+ (treesit-node-top-level
+ (treesit-node-at (point))
+ "expression_statement")))
+ (when-let
+ ((node (or (and (c-ts-mode--emacs-defun-p candidate-1)
+ candidate-1)
+ (and (c-ts-mode--emacs-defun-p candidate-2)
+ candidate-2))))
+ (if range
+ (cons (treesit-node-start node)
+ (treesit-node-end
+ (treesit-node-next-sibling node)))
+ node))))))
+
(defun c-ts-mode-indent-defun ()
"Indent the current top-level declaration syntactically.
`treesit-defun-type-regexp' defines what constructs to indent."
(interactive "*")
(when-let ((orig-point (point-marker))
- (node (treesit-defun-at-point)))
- (indent-region (treesit-node-start node)
- (treesit-node-end node))
+ (range (c-ts-mode--emacs-defun-at-point t)))
+ (indent-region (car range) (cdr range))
(goto-char orig-point)))
+(defun c-ts-mode--emacs-current-defun-name ()
+ "Return the name of the current defun.
+This is used for `add-log-current-defun-function'. This
+recognizes DEFUN in Emacs sources, in addition to normal function
+definitions."
+ (or (treesit-add-log-current-defun)
+ (c-ts-mode--defun-name (c-ts-mode--emacs-defun-at-point))))
+
;;; Modes
(defvar-keymap c-ts-base-mode-map
@@ -1025,7 +1094,11 @@ in your configuration."
(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)
+
+ (when c-ts-mode-emacs-devel
+ (setq-local add-log-current-defun-function
+ #'c-ts-mode--emacs-current-defun-name))))
;;;###autoload
(define-derived-mode c++-ts-mode c-ts-base-mode "C++"
@@ -1067,8 +1140,10 @@ recommended to enable `electric-pair-mode' with this mode."
;; Font-lock.
(setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp))
-
- (treesit-major-mode-setup)))
+ (treesit-major-mode-setup)
+ (when c-ts-mode-emacs-devel
+ (setq-local add-log-current-defun-function
+ #'c-ts-mode--emacs-current-defun-name))))
(easy-menu-define c-ts-mode-menu (list c-ts-mode-map c++-ts-mode-map)
"Menu for `c-ts-mode' and `c++-ts-mode'."
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index c4f773c8426..24f2fda5ae5 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -250,7 +250,11 @@ chosen (interactively or automatically)."
("csharp-ls"))))
(purescript-mode . ("purescript-language-server" "--stdio"))
((perl-mode cperl-mode) . ("perl" "-MPerl::LanguageServer" "-e" "Perl::LanguageServer::run"))
- (markdown-mode . ("marksman" "server")))
+ (markdown-mode
+ . ,(eglot-alternatives
+ '(("marksman" "server")
+ ("vscode-markdown-language-server" "--stdio"))))
+ (graphviz-dot-mode . ("dot-language-server" "--stdio")))
"How the command `eglot' guesses the server to start.
An association list of (MAJOR-MODE . CONTACT) pairs. MAJOR-MODE
identifies the buffers that are to be managed by a specific