diff --git a/Makefile.in b/Makefile.in index 4f2f2f15c97..0b7c9680fe5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1030,6 +1030,9 @@ $(foreach dir,$(distclean_dirs),$(eval $(call submake_template,$(dir),distclean) distclean: $(distclean_dirs:=_distclean) clean-gsettings-schemas ${top_distclean} +ifeq ($(HAVE_NATIVE_COMP),yes) + rm -rf native-lisp +endif ### 'bootstrap-clean' ### Delete everything that can be reconstructed by 'make' and that diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index 2b03399b0a7..d1766026db2 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -329,15 +329,15 @@ version of the package, a newer version is also installed. @section Package Installation @findex package-install -@findex package-update -@findex package-update-all +@findex package-upgrade +@findex package-upgrade-all Packages are most conveniently installed using the package menu (@pxref{Package Menu}), but you can also use the command @kbd{M-x package-install}. This prompts for the name of a package with the @samp{available} status, then downloads and installs it. Similarly, -if you want to update a package, you can use the @kbd{M-x -package-update} command, and if you just want to update all the -packages, you can use the @kbd{M-x package-update-all} command. +if you want to upgrade a package, you can use the @kbd{M-x +package-upgrade} command, and if you want to upgrade all the packages, +you can use the @kbd{M-x package-upgrade-all} command. @cindex package requirements A package may @dfn{require} certain other packages to be installed, @@ -551,8 +551,8 @@ bugs. source code for a package directly from source. The command will also automatically ensure that all files are byte-compiled and auto-loaded, just like with a regular package. Packages installed this way behave -just like any other package. You can update them using -@code{package-update} or @code{package-update-all} and delete them +just like any other package. You can upgrade them using +@code{package-upgrade} or @code{package-upgrade-all} and delete them again using @code{package-delete}. They are even displayed in the regular package listing. If you just wish to clone the source of a package, without adding it to the package list, use diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi index fc5449b0e8d..4599b78ba56 100644 --- a/doc/misc/eglot.texi +++ b/doc/misc/eglot.texi @@ -1265,7 +1265,7 @@ is serialized by Eglot to the following JSON text: @chapter Troubleshooting Eglot @cindex troubleshooting Eglot -This section documents commands and variables that can be used to +This chapter documents commands and variables that can be used to troubleshoot Eglot problems. It also provides guidelines for reporting Eglot bugs in a way that facilitates their resolution. @@ -1275,6 +1275,8 @@ pop up special buffers that can be used to inspect the communications between the Eglot and language server. In many cases, this will indicate the problems or at least provide a hint. +@node Performance +@section Performance @cindex performance A common and easy-to-fix cause of performance problems is the length of the Eglot events buffer because it represent additional work that @@ -1289,6 +1291,30 @@ techniques to improve their performance. Often, this can be tweaked by changing the server configuration (@pxref{Advanced server configuration}). +@node Getting the latest version +@section Getting the latest version +@cindex updating Eglot + +To install the latest Eglot on an Emacs version that does not bundle +Eglot, use @kbd{M-x package-install}. + +Often, a newer Eglot version exists that has fixed a longstanding bug, +has more LSP features, or just better support for a particular +language server. Recent Eglot versions can self-update via the +command @kbd{M-x eglot-update}. This will replace any currently +installed version with the newest one available from the ELPA archives +configured in @code{package-archives}. + +You may update though other methods, such as @code{package-install}, +@code{use-package}, @code{list-packages} or the newer +@code{package-update}. However, do read the docstrings of these +commands, as some may not work in exactly the same way across Emacs +versions, meaning your configuration may be not portable. + +@node Reporting bugs +@section Reporting bugs +@cindex bug reports + If you think you have found a bug, we want to hear about it. Before reporting a bug, keep in mind that interaction with language servers represents a large quantity of unknown variables. Therefore, it is @@ -1332,6 +1358,10 @@ public Git repository. Include versions of the software used. The Emacs version can be obtained with @kbd{M-x emacs-version}. +We welcome bug reports about all Eglot versions, but it is helpful to +first check if the problem isn't already fixed in the latest version +(@pxref{Getting the latest version}). + It's also essential to include the version of ELPA packages that are explicitly or implicitly loaded. The optional but popular Company or Markdown packages are distributed as GNU ELPA packages, not to mention diff --git a/etc/NEWS.29 b/etc/NEWS.29 index 0eb5940dbca..ae4c5ffb842 100644 --- a/etc/NEWS.29 +++ b/etc/NEWS.29 @@ -1843,13 +1843,13 @@ this includes "binary" buffers like 'archive-mode' and 'image-mode'. ** Package +++ -*** New command 'package-update'. +*** New command 'package-upgrade'. This command allows you to upgrade packages without using 'M-x list-packages'. +++ -*** New command 'package-update-all'. -This command allows updating all packages without any queries. +*** New command 'package-upgrade-all'. +This command allows upgrading all packages without any queries. +++ *** New commands 'package-recompile' and 'package-recompile-all'. diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index a72bb084d31..83d697a2e90 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -24,7 +24,7 @@ ;; While packages managed by package.el use tarballs for distributing ;; the source code, this extension allows for packages to be fetched -;; and updated directly from a version control system. +;; and upgraded directly from a version control system. ;; ;; To install a package from source use `package-vc-install'. If you ;; aren't interested in activating a package, you can use @@ -672,19 +672,19 @@ installed package." #'string=))) ;;;###autoload -(defun package-vc-update-all () - "Attempt to update all installed VC packages." +(defun package-vc-upgrade-all () + "Attempt to upgrade all installed VC packages." (interactive) (dolist (package package-alist) (dolist (pkg-desc (cdr package)) (when (package-vc-p pkg-desc) - (package-vc-update pkg-desc)))) - (message "Done updating packages.")) + (package-vc-upgrade pkg-desc)))) + (message "Done upgrading packages.")) ;;;###autoload -(defun package-vc-update (pkg-desc) - "Attempt to update the package PKG-DESC." - (interactive (list (package-vc--read-package-desc "Update VC package: " t))) +(defun package-vc-upgrade (pkg-desc) + "Attempt to upgrade the package PKG-DESC." + (interactive (list (package-vc--read-package-desc "Upgrade VC package: " t))) ;; HACK: To run `package-vc--unpack-1' after checking out the new ;; revision, we insert a hook into `vc-post-command-functions', and ;; remove it right after it ran. To avoid running the hook multiple @@ -882,7 +882,7 @@ Rebuilding an installation means scraping for new autoload cookies, re-compiling Emacs Lisp files, building and installing any documentation, downloading any missing dependencies. This command does not fetch new revisions from a remote server. That -is the responsibility of `package-vc-update'. Interactively, +is the responsibility of `package-vc-upgrade'. Interactively, prompt for the name of the package to rebuild." (interactive (list (package-vc--read-package-desc "Rebuild package: " t))) (package-vc--unpack-1 pkg-desc (package-desc-dir pkg-desc))) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 240ea10cbfc..65bb226acb1 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2259,24 +2259,28 @@ had been enabled." (message "Package `%s' installed." name)) (message "`%s' is already installed" name)))) -(declare-function package-vc-update "package-vc" (pkg)) +(declare-function package-vc-upgrade "package-vc" (pkg)) ;;;###autoload -(defun package-update (name) - "Update package NAME if a newer version exists." +(defun package-upgrade (name) + "Upgrade package NAME if a newer version exists. + +Currently, packages which are part of the Emacs distribution +cannot be upgraded that way. Use `i' after `M-x list-packages' to +upgrade to an ELPA version first." (interactive (list (completing-read - "Update package: " (package--updateable-packages) nil t))) + "Upgrade package: " (package--upgradeable-packages) nil t))) (let* ((package (if (symbolp name) name (intern name))) (pkg-desc (cadr (assq package package-alist)))) (if (package-vc-p pkg-desc) - (package-vc-update pkg-desc) + (package-vc-upgrade pkg-desc) (package-delete pkg-desc 'force) (package-install package 'dont-select)))) -(defun package--updateable-packages () +(defun package--upgradeable-packages () ;; Initialize the package system to get the list of package ;; symbols for completion. (package--archives-initialize) @@ -2294,23 +2298,27 @@ had been enabled." package-alist))) ;;;###autoload -(defun package-update-all (&optional query) +(defun package-upgrade-all (&optional query) "Refresh package list and upgrade all packages. -If QUERY, ask the user before updating packages. When called -interactively, QUERY is always true." +If QUERY, ask the user before upgrading packages. When called +interactively, QUERY is always true. + +Currently, packages which are part of the Emacs distribution are +not upgraded that way. Use `i' after `M-x list-packages' to +upgrade to an ELPA version first." (interactive (list (not noninteractive))) (package-refresh-contents) - (let ((updateable (package--updateable-packages))) - (if (not updateable) - (message "No packages to update") + (let ((upgradeable (package--upgradeable-packages))) + (if (not upgradeable) + (message "No packages to upgrade") (when (and query (not (yes-or-no-p - (if (length= updateable 1) - "One package to update. Do it? " - (format "%s packages to update. Do it?" - (length updateable)))))) - (user-error "Updating aborted")) - (mapc #'package-update updateable)))) + (if (length= upgradeable 1) + "One package to upgrade. Do it? " + (format "%s packages to upgrade. Do it?" + (length upgradeable)))))) + (user-error "Upgrade aborted")) + (mapc #'package-upgrade upgradeable)))) (defun package--dependencies (pkg) "Return a list of all dependencies PKG has. diff --git a/lisp/leim/quail/greek.el b/lisp/leim/quail/greek.el index 107f4131e38..0829097af5f 100644 --- a/lisp/leim/quail/greek.el +++ b/lisp/leim/quail/greek.el @@ -1116,6 +1116,7 @@ nil t t nil nil nil nil nil nil nil t) ("'U" ?Ύ) ("`R" ?Ῥ) + ("(R" ?Ῥ) ("+`" ?῭) ; #x1fed ("+'" ?΅) ; #x1fee diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index bbc7979667c..353100ca1ce 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -357,7 +357,9 @@ PARENT, BOL, ARGS are the same as other anchor functions." "Indent rules supported by `c-ts-mode'. MODE is either `c' or `cpp'." (let ((common - `(((parent-is "translation_unit") column-0 0) + `((c-ts-mode--for-each-tail-body-matcher prev-line c-ts-mode-indent-offset) + + ((parent-is "translation_unit") column-0 0) ((query "(ERROR (ERROR)) @indent") column-0 0) ((node-is ")") parent 1) ((node-is "]") parent-bol 0) @@ -969,6 +971,81 @@ if `c-ts-mode-emacs-sources-support' is non-nil." (or (treesit-add-log-current-defun) (c-ts-mode--defun-name (c-ts-mode--emacs-defun-at-point)))) +;;; FOR_EACH_TAIL fix +;; +;; FOR_EACH_TAIL (and FOR_EACH_TAIL_SAFE) followed by a unbracketed +;; body will mess up the parser, which parses the thing as a function +;; declaration. We "fix" it by adding a shadow parser, emacs-c (which +;; is just c but under a different name). We use emacs-c to find each +;; FOR_EACH_TAIL with a unbracketed body, and set the ranges of the C +;; parser so that it skips those FOR_EACH_TAIL's. Note that we only +;; ignore FOR_EACH_TAIL's with a unbracketed body. Those with a +;; bracketed body parses more or less fine. + +(defvar c-ts-mode--for-each-tail-regexp + (rx "FOR_EACH_" (or "TAIL" "TAIL_SAFE" "ALIST_VALUE" + "LIVE_BUFFER" "FRAME")) + "A regexp matching all the FOR_EACH_TAIL variants.") + +(defun c-ts-mode--for-each-tail-body-matcher (_n _p bol &rest _) + "A matcher that matches the first line after a FOR_EACH_TAIL. +For BOL see `treesit-simple-indent-rules'." + (when c-ts-mode-emacs-sources-support + (save-excursion + (goto-char bol) + (forward-line -1) + (skip-chars-forward " \t") + (looking-at c-ts-mode--for-each-tail-regexp)))) + +(defvar c-ts-mode--emacs-c-range-query + (treesit-query-compile + 'emacs-c `(((declaration + type: (macro_type_specifier + name: (identifier) @_name) + @for-each-tail) + (:match ,c-ts-mode--for-each-tail-regexp + @_name)))) + "Query that finds the FOR_EACH_TAIL with a unbracketed body.") + +(defvar-local c-ts-mode--for-each-tail-ranges nil + "Ranges covering all the FOR_EACH_TAIL's in the buffer.") + +(defun c-ts-mode--reverse-ranges (ranges beg end) + "Reverse RANGES and return the new ranges between BEG and END. +Positions that were included RANGES are not in the returned +ranges, and vice versa. + +Return nil if RANGES is nil. This way, passing the returned +ranges to `treesit-parser-set-included-ranges' will make the +parser parse the whole buffer." + (if (null ranges) + nil + (let ((new-ranges nil) + (prev-end beg)) + (dolist (range ranges) + (when (< prev-end (car range)) + (push (cons prev-end (car range)) new-ranges)) + (setq prev-end (cdr range))) + (when (< prev-end end) + (push (cons prev-end end) new-ranges)) + (nreverse new-ranges)))) + +(defun c-ts-mode--emacs-set-ranges (beg end) + "Set ranges for the C parser to skip some FOR_EACH_TAIL's. +BEG and END are described in `treesit-range-rules'." + (let* ((c-parser (treesit-parser-create 'c)) + (old-ranges c-ts-mode--for-each-tail-ranges) + (new-ranges (treesit-query-range + 'emacs-c c-ts-mode--emacs-c-range-query beg end)) + (set-ranges (treesit--clip-ranges + (treesit--merge-ranges + old-ranges new-ranges beg end) + (point-min) (point-max))) + (reversed-ranges (c-ts-mode--reverse-ranges + set-ranges (point-min) (point-max)))) + (setq-local c-ts-mode--for-each-tail-ranges set-ranges) + (treesit-parser-set-included-ranges c-parser reversed-ranges))) + ;;; Modes (defvar-keymap c-ts-base-mode-map @@ -1101,6 +1178,17 @@ in your configuration." :after-hook (c-ts-mode-set-modeline) (when (treesit-ready-p 'c) + ;; Add a fake "emacs-c" language which is just C. Used for + ;; skipping FOR_EACH_TAIL, see `c-ts-mode--emacs-set-ranges'. + (setf (alist-get 'emacs-c treesit-load-name-override-list) + '("libtree-sitter-c" "tree_sitter_c")) + ;; If Emacs source support is enabled, make sure emacs-c parser is + ;; after c parser in the parser list. This way various tree-sitter + ;; functions will automatically use the c parser rather than the + ;; emacs-c parser. + (when c-ts-mode-emacs-sources-support + (treesit-parser-create 'emacs-c)) + (treesit-parser-create 'c) ;; Comments. (setq-local comment-start "/* ") @@ -1114,9 +1202,16 @@ in your configuration." (setq-local treesit-defun-tactic 'top-level) (treesit-major-mode-setup) + ;; Emacs source support: handle DEFUN and FOR_EACH_TAIL gracefully. (when c-ts-mode-emacs-sources-support (setq-local add-log-current-defun-function - #'c-ts-mode--emacs-current-defun-name)))) + #'c-ts-mode--emacs-current-defun-name) + + (setq-local treesit-range-settings + (treesit-range-rules 'c-ts-mode--emacs-set-ranges)) + + (setq-local treesit-language-at-point-function + (lambda (_pos) 'c))))) ;;;###autoload (define-derived-mode c++-ts-mode c-ts-base-mode "C++" diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 3134d55fc08..6ae27a13845 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -2002,6 +2002,16 @@ If it is activated, also signal textDocument/didOpen." (declare (obsolete info "1.10")) (interactive) (info "(eglot)")) +;;;###autoload +(defun eglot-update (&rest _) "Update Eglot." + (interactive) + (with-no-warnings + (require 'package) + (unless package-archive-contents (package-refresh-contents)) + (when-let ((existing (cadr (assoc 'eglot package-alist)))) + (package-delete existing t)) + (package-install (cadr (assoc 'eglot package-archive-contents))))) + (easy-menu-define eglot-menu nil "Eglot" `("Eglot" ;; Commands for getting information and customization. @@ -3129,8 +3139,7 @@ for which LSP on-type-formatting should be requested." (funcall snippet-fn (or insertText label)))) (when (cl-plusp (length additionalTextEdits)) (eglot--apply-text-edits additionalTextEdits))) - (eglot--signal-textDocument/didChange) - (eldoc))))))))) + (eglot--signal-textDocument/didChange))))))))) (defun eglot--hover-info (contents &optional _range) (mapconcat #'eglot--format-markup @@ -3743,7 +3752,19 @@ If NOERROR, return predicate, else erroring function." :success-fn (lambda (hints) (eglot--when-live-buffer buf (eglot--widening - (remove-overlays from to 'eglot--inlay-hint t) + ;; Overlays ending right at FROM with an + ;; `after-string' property logically belong to + ;; the (FROM TO) region. Likewise, such + ;; overlays ending at TO don't logically belong + ;; to it. + (dolist (o (overlays-in (1- from) to)) + (when (and (overlay-get o 'eglot--inlay-hint) + (cond ((eq (overlay-end o) from) + (overlay-get o 'after-string)) + ((eq (overlay-end o) to) + (overlay-get o 'before-string)) + (t))) + (delete-overlay o))) (mapc paint-hint hints)))) :deferred 'eglot--update-hints-1))) diff --git a/lisp/treesit.el b/lisp/treesit.el index b7af64ee8b5..1750929cc85 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -421,13 +421,16 @@ See `treesit-query-capture' for QUERY." (defun treesit-query-range (node query &optional beg end) "Query the current buffer and return ranges of captured nodes. -QUERY, NODE, BEG, END are the same as in -`treesit-query-capture'. This function returns a list -of (START . END), where START and END specifics the range of each -captured node. Capture names don't matter." +QUERY, NODE, BEG, END are the same as in `treesit-query-capture'. +This function returns a list of (START . END), where START and +END specifics the range of each captured node. Capture names +generally don't matter, but names that starts with an underscore +are ignored." (cl-loop for capture in (treesit-query-capture node query beg end) + for name = (car capture) for node = (cdr capture) + if (not (string-prefix-p "_" (symbol-name name))) collect (cons (treesit-node-start node) (treesit-node-end node)))) @@ -442,6 +445,9 @@ When updating the range of each parser in the buffer, range to the range spanned by captured nodes. QUERY must be a compiled query. +Capture names generally don't matter, but names that starts with +an underscore are ignored. + QUERY can also be a function, in which case it is called with 2 arguments, START and END. It should ensure parsers' ranges are correct in the region between START and END. @@ -461,6 +467,9 @@ like this: Each QUERY is a tree-sitter query in either the string, s-expression or compiled form. +Capture names generally don't matter, but names that starts with +an underscore are ignored. + For each QUERY, :KEYWORD and VALUE pairs add meta information to it. For example, diff --git a/src/image.c b/src/image.c index e78c0abb0db..8ee802a9d62 100644 --- a/src/image.c +++ b/src/image.c @@ -479,7 +479,8 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_X_WINDOWS Pixmap bitmap; - bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), + bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), + dpyinfo->root_window, bits, width, height); if (! bitmap) return -1; @@ -729,8 +730,10 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) filename = SSDATA (found); - result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), - filename, &width, &height, &bitmap, &xhot, &yhot); + result = XReadBitmapFile (FRAME_X_DISPLAY (f), + dpyinfo->root_window, + filename, &width, &height, &bitmap, + &xhot, &yhot); if (result != BitmapSuccess) return -1;