commit cc9188b1900079f87d76cc8b7493d64a9ccd9d36 (HEAD, refs/remotes/origin/master) Author: Roland Winkler Date: Thu Nov 14 23:26:23 2024 -0600 New user option bibtex-entry-ask-for-key diff --git a/etc/NEWS b/etc/NEWS index 634b1e89ab8..fae573ed9de 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -618,6 +618,12 @@ functionality of the standard 'xref' commands in TeX buffers. You can restore the standard 'etags' backend with the 'M-x xref-etags-mode' toggle. +** BibTeX mode + +--- +*** New user option 'bibtex-entry-ask-for-key'. +When enabled, 'bibtex-entry' asks for a key. + ** Midnight mode --- diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index cbcea8af012..99a97c9bb8d 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -1377,6 +1377,12 @@ and must return a string (the key to use)." :version "28.1" :type 'function) +(defcustom bibtex-entry-ask-for-key t + "If non-nil, `bibtex-entry' asks for a key." + :group 'bibtex + :version "31.1" + :type 'boolean) + (defcustom bibtex-entry-offset 0 "Offset for BibTeX entries. Added to the value of all other variables which determine columns." @@ -3852,7 +3858,8 @@ is non-nil." (let ((completion-ignore-case t)) (list (completing-read "Entry Type: " bibtex-entry-alist nil t nil 'bibtex-entry-type-history)))) - (let ((key (if bibtex-maintain-sorted-entries + (let ((key (if (and bibtex-maintain-sorted-entries + bibtex-entry-ask-for-key) (bibtex-read-key (format "%s key: " entry-type)))) (field-list (bibtex-field-list entry-type))) (unless (bibtex-prepare-new-entry (list key nil entry-type)) commit df288d2e4148e6e72f21752a510f98536e7705ac Author: Jim Porter Date: Thu Nov 7 10:08:33 2024 -0800 Don't clobber stickiness text properties when printing Eshell prompt * lisp/eshell/em-prompt.el (eshell--append-text-property): New function... (eshell-emit-prompt): ... use it. * test/lisp/eshell/em-prompt-tests.el (em-prompt-test/field-properties/merge-stickiness): New test. (em-prompt-test/field-properties, em-prompt-test/after-failure): Reorder stickiness values (bug#74230). diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el index de62b5c7d97..37970ac0ba5 100644 --- a/lisp/eshell/em-prompt.el +++ b/lisp/eshell/em-prompt.el @@ -119,6 +119,19 @@ arriving, or after." (add-hook 'eshell-post-command-hook 'eshell-emit-prompt nil t) (eshell-prompt-mode))) +(defun eshell--append-text-property (start end prop value &optional object) + "Append to a text property from START to END. +PROP is the text property to append to, and VALUE is the list of +property values to append. OBJECT is the object to propertize, as with +`put-text-property' (which see)." + (let (next) + (while (< start end) + (setq next (next-single-property-change start prop object end)) + (put-text-property start next prop + (append (get-text-property start prop object) value) + object) + (setq start next)))) + (defun eshell-emit-prompt () "Emit a prompt if eshell is being used interactively." (when (boundp 'ansi-color-context-region) @@ -126,19 +139,16 @@ arriving, or after." (run-hooks 'eshell-before-prompt-hook) (if (not eshell-prompt-function) (set-marker eshell-last-output-end (point)) - (let ((prompt (funcall eshell-prompt-function))) - (add-text-properties - 0 (length prompt) - (if eshell-highlight-prompt - '( read-only t - field prompt - font-lock-face eshell-prompt - front-sticky (read-only field font-lock-face) - rear-nonsticky (read-only field font-lock-face)) - '( field prompt - front-sticky (field) - rear-nonsticky (field))) - prompt) + (let* ((prompt (funcall eshell-prompt-function)) + (len (length prompt)) + (sticky-props '(field))) + (put-text-property 0 len 'field 'prompt prompt) + (when eshell-highlight-prompt + (add-text-properties + 0 len '(read-only t font-lock-face eshell-prompt) prompt) + (setq sticky-props `(read-only font-lock-face . ,sticky-props))) + (eshell--append-text-property 0 len 'front-sticky sticky-props prompt) + (eshell--append-text-property 0 len 'rear-nonsticky sticky-props prompt) (eshell-interactive-filter nil prompt))) (run-hooks 'eshell-after-prompt-hook)) diff --git a/test/lisp/eshell/em-prompt-tests.el b/test/lisp/eshell/em-prompt-tests.el index fbadade061f..1c6e8e02293 100644 --- a/test/lisp/eshell/em-prompt-tests.el +++ b/test/lisp/eshell/em-prompt-tests.el @@ -57,8 +57,8 @@ 'read-only t 'field 'prompt 'font-lock-face 'eshell-prompt - 'front-sticky '(read-only field font-lock-face) - 'rear-nonsticky '(read-only field font-lock-face)))) + 'front-sticky '(read-only font-lock-face field) + 'rear-nonsticky '(read-only font-lock-face field)))) (should (equal last-input "echo hello\n")) (should (equal-including-properties last-output @@ -88,6 +88,33 @@ This tests the case when `eshell-highlight-prompt' is nil." (apply #'propertize "hello\n" eshell-command-output-properties))))))) +(ert-deftest em-prompt-test/field-properties/merge-stickiness () + "Check that stickiness properties are properly merged on Eshell prompts." + (let ((eshell-prompt-function + (lambda () + (concat (propertize (eshell/pwd) 'front-sticky '(front)) + (propertize "$ " 'rear-nonsticky '(rear)))))) + (with-temp-eshell + (eshell-insert-command "echo hello") + (let ((last-prompt (field-string (1- eshell-last-input-start)))) + (should (equal-including-properties + last-prompt + (concat + (propertize + (directory-file-name default-directory) + 'read-only t + 'field 'prompt + 'font-lock-face 'eshell-prompt + 'front-sticky '(front read-only font-lock-face field) + 'rear-nonsticky '(read-only font-lock-face field)) + (propertize + "$ " + 'read-only t + 'field 'prompt + 'font-lock-face 'eshell-prompt + 'front-sticky '(read-only font-lock-face field) + 'rear-nonsticky '(rear read-only font-lock-face field))))))))) + (ert-deftest em-prompt-test/after-failure () "Check that current prompt shows the exit code of the last failed command." (with-temp-eshell @@ -104,8 +131,8 @@ This tests the case when `eshell-highlight-prompt' is nil." 'read-only t 'field 'prompt 'font-lock-face 'eshell-prompt - 'front-sticky '(read-only field font-lock-face) - 'rear-nonsticky '(read-only field font-lock-face))))))) + 'front-sticky '(read-only font-lock-face field) + 'rear-nonsticky '(read-only font-lock-face field))))))) ;; Prompt navigation commit e30c83e166634e8cdfc9577b982deb7cc2619067 Merge: 6d42c70fd3e b83a45eab53 Author: Michael Albinus Date: Thu Nov 14 17:29:37 2024 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit 6d42c70fd3e2e63c8f993a10c83dee7425f185d5 Author: Michael Albinus Date: Thu Nov 14 17:29:07 2024 +0100 Fix errors in Tramp's password cache expiration * doc/misc/tramp.texi (Password handling): Mention expiration of cached passwords when a session timeout happens. * lisp/net/tramp-adb.el (tramp-adb-maybe-open-connection): Rename file property "process-attributes" to connection property " process-attributes". * lisp/net/tramp.el (tramp-read-passwd): * lisp/net/tramp-sh.el (tramp-maybe-open-connection): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-send-command): Rename connection property "password-vector" to "pw-vector". * lisp/net/tramp-sh.el (tramp-maybe-open-connection): Use connection property "hop-vector". * lisp/net/tramp.el (tramp-get-process-attributes) (tramp-handle-list-system-processes): Rename file property "process-attributes" to connection property " process-attributes". (tramp-compute-multi-hops): Check for `tramp-sh-file-name-handler-p', it works only for this. (tramp-action-password, tramp-process-actions): Use connection property "hop-vector". (tramp-read-passwd, tramp-clear-passwd): Rewrite. (Bug#74105) diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 05bd62b7714..d429ef33780 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2258,6 +2258,12 @@ this interactively. @vindex auth-source-do-cache Set @code{auth-source-do-cache} to @code{nil} to disable password caching. +For connections which use a session-timeout, like @option{sudo}, +@option{doas} and @option{run0}, the password cache is expired by +@value{tramp} when the session expires (@pxref{Predefined connection +information}). However, this makes only sense if the password cannot +be retrieved from a persistent authentication file or store. + @node Connection caching @section Reusing connection related information diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 4210d1247a8..7fbb2332e89 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -1106,7 +1106,8 @@ connection if a previous connection has died for some reason." ;; Maybe we know already that "su" is not supported. We cannot ;; use a connection property, because we have not checked yet ;; whether it is still the same device. - (when (and user (not (tramp-get-file-property vec "/" "su-command-p" t))) + (when + (and user (not (tramp-get-connection-property vec " su-command-p" t))) (tramp-error vec 'file-error "Cannot switch to user `%s'" user)) (unless (process-live-p p) @@ -1191,7 +1192,7 @@ connection if a previous connection has died for some reason." (unless (tramp-adb-send-command-and-check vec nil) (delete-process p) ;; Do not flush, we need the nil value. - (tramp-set-file-property vec "/" "su-command-p" nil) + (tramp-set-connection-property vec " su-command-p" nil) (tramp-error vec 'file-error "Cannot switch to user `%s'" user))) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 8f66b9f030e..0182c8f8eb8 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -5246,9 +5246,10 @@ connection if a previous connection has died for some reason." (setq r-shell t))) (setq current-host l-host) - ;; Set password prompt vector. + ;; Set hop and password prompt vector. + (tramp-set-connection-property p "hop-vector" hop) (tramp-set-connection-property - p "password-vector" + p "pw-vector" (if (tramp-get-method-parameter hop 'tramp-password-previous-hop) (let ((pv (copy-tramp-file-name previous-hop))) @@ -5304,6 +5305,8 @@ connection if a previous connection has died for some reason." tramp-actions-before-shell connection-timeout)) ;; Next hop. + (tramp-flush-connection-property p "hop-vector") + (tramp-flush-connection-property p "pw-vector") (setq options "" target-alist (cdr target-alist) previous-hop hop))) diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index af5cb8e4bdc..bd10a0eb922 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -785,7 +785,7 @@ in case of error, t otherwise." ;; Avoid process status message in output buffer. (set-process-sentinel p #'ignore) (tramp-post-process-creation p vec) - (tramp-set-connection-property p "password-vector" tramp-sudoedit-null-hop) + (tramp-set-connection-property p "pw-vector" tramp-sudoedit-null-hop) (tramp-process-actions p vec nil tramp-sudoedit-sudo-actions) (tramp-message vec 6 "%s\n%s" (process-exit-status p) (buffer-string)) (prog1 diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index dbec3d5807e..6d384d97db6 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4707,7 +4707,7 @@ Parsing the remote \"ps\" output is controlled by It is not guaranteed, that all process attributes as described in `process-attributes' are returned. The additional attribute `pid' shall be returned always." - (with-tramp-file-property vec "/" "process-attributes" + (with-tramp-connection-property vec " process-attributes" (ignore-errors (with-temp-buffer (hack-connection-local-variables-apply @@ -4754,7 +4754,7 @@ It is not guaranteed, that all process attributes as described in (defun tramp-handle-list-system-processes () "Like `list-system-processes' for Tramp files." (let ((v (tramp-dissect-file-name default-directory))) - (tramp-flush-file-property v "/" "process-attributes") + (tramp-flush-connection-property v " process-attributes") (mapcar (lambda (x) (cdr (assq 'pid x))) (tramp-get-process-attributes v)))) (defun tramp-get-lock-file (file) @@ -4962,74 +4962,74 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.") (item vec) choices proxy) - ;; Ad-hoc proxy definitions. - (tramp-add-hops vec) - - ;; Look for proxy hosts to be passed. - (setq choices tramp-default-proxies-alist) - (while choices - (setq item (pop choices) - proxy (eval (nth 2 item) t)) - (when (and - ;; Host. - (string-match-p - (or (eval (nth 0 item) t) "") - (or (tramp-file-name-host-port (car target-alist)) "")) - ;; User. - (string-match-p - (or (eval (nth 1 item) t) "") - (or (tramp-file-name-user-domain (car target-alist)) ""))) - (if (null proxy) - ;; No more hops needed. - (setq choices nil) - ;; Replace placeholders. The proxy could contain "%" which - ;; is not intended as format character, for example in - ;; USER%DOMAIN or POD%NAMESPACE. - (setq proxy - (replace-regexp-in-string - (rx "%" (group (= 2 alnum))) "%%\\1" proxy) - proxy - (format-spec - proxy - (format-spec-make - ?u (or (tramp-file-name-user (car target-alist)) "") - ?h (or (tramp-file-name-host (car target-alist)) "")))) - (with-parsed-tramp-file-name proxy l - ;; Add the hop. - (push l target-alist) - ;; Start next search. - (setq choices tramp-default-proxies-alist))))) - - ;; Foreign and out-of-band methods are not supported for multi-hops. - (when (cdr target-alist) - (setq choices target-alist) - (while (setq item (pop choices)) - (unless (tramp-multi-hop-p item) - (setq tramp-default-proxies-alist saved-tdpa) - (tramp-user-error - vec "Method `%s' is not supported for multi-hops" - (tramp-file-name-method item))))) - - ;; Some methods ("su", "sg", "sudo", "doas", "run0", "ksu") do not - ;; use the host name in their command template. In this case, the - ;; remote file name must use either a local host name (first hop), - ;; or a host name matching the previous hop. - (let ((previous-host (or tramp-local-host-regexp ""))) - (setq choices target-alist) - (while (setq item (pop choices)) - (let ((host (tramp-file-name-host item))) - (unless - (or - ;; The host name is used for the remote shell command. - (member - "%h" (flatten-tree - (tramp-get-method-parameter item 'tramp-login-args))) - ;; The host name must match previous hop. - (string-match-p previous-host host)) + ;; `tramp-compute-multi-hops' could be called also for other file + ;; name handlers, for example in `tramp-clear-passwd'. + (when (tramp-sh-file-name-handler-p vec) + + ;; Ad-hoc proxy definitions. + (tramp-add-hops vec) + + ;; Look for proxy hosts to be passed. + (setq choices tramp-default-proxies-alist) + (while choices + (setq item (pop choices) + proxy (eval (nth 2 item) t)) + (when (and + ;; Host. + (string-match-p + (or (eval (nth 0 item) t) "") + (or (tramp-file-name-host-port (car target-alist)) "")) + ;; User. + (string-match-p + (or (eval (nth 1 item) t) "") + (or (tramp-file-name-user-domain (car target-alist)) ""))) + (if (null proxy) + ;; No more hops needed. + (setq choices nil) + ;; Replace placeholders. + (setq proxy + (format-spec + proxy + (format-spec-make + ?u (or (tramp-file-name-user (car target-alist)) "") + ?h (or (tramp-file-name-host (car target-alist)) "")))) + (with-parsed-tramp-file-name proxy l + ;; Add the hop. + (push l target-alist) + ;; Start next search. + (setq choices tramp-default-proxies-alist))))) + + ;; Foreign and out-of-band methods are not supported for + ;; multi-hops. + (when (cdr target-alist) + (setq choices target-alist) + (while (setq item (pop choices)) + (unless (tramp-multi-hop-p item) (setq tramp-default-proxies-alist saved-tdpa) (tramp-user-error - vec "Host name `%s' does not match `%s'" host previous-host)) - (setq previous-host (rx bol (literal host) eol))))) + vec "Method `%s' is not supported for multi-hops" + (tramp-file-name-method item))))) + + ;; Some methods ("su", "sg", "sudo", "doas", "run0", "ksu") do + ;; not use the host name in their command template. In this + ;; case, the remote file name must use either a local host name + ;; (first hop), or a host name matching the previous hop. + (let ((previous-host (or tramp-local-host-regexp ""))) + (setq choices target-alist) + (while (setq item (pop choices)) + (let ((host (tramp-file-name-host item))) + (unless + (or + ;; The host name is used for the remote shell command. + (member + "%h" (flatten-tree + (tramp-get-method-parameter item 'tramp-login-args))) + ;; The host name must match previous hop. + (string-match-p previous-host host)) + (setq tramp-default-proxies-alist saved-tdpa) + (tramp-user-error + vec "Host name `%s' does not match `%s'" host previous-host)) + (setq previous-host (rx bol (literal host) eol)))))) ;; Result. target-alist)) @@ -5694,7 +5694,11 @@ of." ;; Sometimes, the process returns a new password request ;; immediately after rejecting the previous (wrong) one. (unless (or tramp-password-prompt-not-unique - (tramp-get-connection-property vec " first-password-request")) + (tramp-get-connection-property + (tramp-get-connection-property + proc "hop-vector" + (process-get proc 'tramp-vector)) + " first-password-request")) (tramp-clear-passwd vec)) (goto-char (point-min)) (tramp-check-for-regexp proc tramp-process-action-regexp) @@ -5897,10 +5901,10 @@ because the shell prompt has been detected), it shall throw a result. The symbol `ok' means that all ACTIONs have been performed successfully. Any other value means an error." ;; Enable `auth-source', unless "emacs -Q" has been called. We must - ;; use the "password-vector" property in case we have several hops. + ;; use the "hop-vector" property in case we have several hops. (tramp-set-connection-property (tramp-get-connection-property - proc "password-vector" (process-get proc 'tramp-vector)) + proc "hop-vector" (process-get proc 'tramp-vector)) " first-password-request" tramp-cache-read-persistent-data) (save-restriction (with-tramp-progress-reporter @@ -6843,15 +6847,16 @@ Consults the auth-source package." ;; adapt `default-directory'. (Bug#39389, Bug#39489) (default-directory tramp-compat-temporary-file-directory) (case-fold-search t) - ;; In tramp-sh.el, we must use "password-vector" due to - ;; multi-hop. - (vec (tramp-get-connection-property - proc "password-vector" (process-get proc 'tramp-vector))) - (key (tramp-make-tramp-file-name vec 'noloc)) - (method (tramp-file-name-method vec)) - (user-domain (or (tramp-file-name-user-domain vec) - (tramp-get-connection-property key "login-as"))) - (host-port (tramp-file-name-host-port vec)) + ;; In tramp-sh.el, we must use "hop-vector" and "pw-vector" + ;; due to multi-hop. + (vec (process-get proc 'tramp-vector)) + (hop-vec (tramp-get-connection-property proc "hop-vector" vec)) + (pw-vec (tramp-get-connection-property proc "pw-vector" hop-vec)) + (key (tramp-make-tramp-file-name pw-vec 'noloc)) + (method (tramp-file-name-method pw-vec)) + (user-domain (or (tramp-file-name-user-domain pw-vec) + (tramp-get-connection-property pw-vec "login-as"))) + (host-port (tramp-file-name-host-port pw-vec)) (pw-prompt (string-trim-left (or prompt @@ -6860,29 +6865,23 @@ Consults the auth-source package." (if (string-match-p "passphrase" (match-string 1)) (match-string 0) (format "%s for %s " (capitalize (match-string 1)) key)))))) + ;; If there is no user name, `:create' triggers to ask for. + ;; We suppress it. + (pw-spec (list :max 1 :user user-domain :host host-port :port method + :require (cons :secret (and user-domain '(:user))) + :create (and user-domain t))) (auth-source-creation-prompts `((secret . ,pw-prompt))) ;; Use connection-local value. (auth-sources (buffer-local-value 'auth-sources (process-buffer proc))) auth-info auth-passwd tramp-dont-suspend-timers) (unwind-protect - ;; We cannot use `with-parsed-tramp-file-name', because it - ;; expands the file name. (or (setq tramp-password-save-function nil) - ;; See if auth-sources contains something useful. + ;; See if `auth-sources' contains something useful. (ignore-errors - (and auth-sources - (tramp-get-connection-property vec " first-password-request") - ;; Try with Tramp's current method. If there is no - ;; user name, `:create' triggers to ask for. We - ;; suppress it. - (setq auth-info - (car - (auth-source-search - :max 1 :user user-domain :host host-port :port method - :require (cons :secret (and user-domain '(:user))) - :create (and user-domain t))) + (and (tramp-get-connection-property hop-vec " first-password-request") + (setq auth-info (car (apply #'auth-source-search pw-spec)) tramp-password-save-function (plist-get auth-info :save-function) auth-passwd @@ -6890,12 +6889,19 @@ Consults the auth-source package." ;; Try the password cache. (with-tramp-suspended-timers - (setq auth-passwd (password-read pw-prompt key) + (setq auth-passwd + (password-read + pw-prompt (auth-source-format-cache-entry pw-spec)) tramp-password-save-function - (lambda () (password-cache-add key auth-passwd))) + (when auth-source-do-cache + (lambda () + (password-cache-add + (auth-source-format-cache-entry pw-spec) auth-passwd)))) auth-passwd)) - (tramp-set-connection-property vec " first-password-request" nil)))) + ;; Remember the values. + (tramp-set-connection-property hop-vec " pw-spec" pw-spec) + (tramp-set-connection-property hop-vec " first-password-request" nil)))) (defun tramp-read-passwd-without-cache (proc &optional prompt) "Read a password from user (compat function)." @@ -6912,17 +6918,11 @@ Consults the auth-source package." (defun tramp-clear-passwd (vec) "Clear password cache for connection related to VEC." (declare (tramp-suppress-trace t)) - (let ((method (tramp-file-name-method vec)) - (user-domain (tramp-file-name-user-domain vec)) - (host-port (tramp-file-name-host-port vec)) - (hop (tramp-file-name-hop vec))) - (when hop - ;; Clear also the passwords of the hops. - (tramp-clear-passwd (tramp-dissect-hop-name hop))) - (auth-source-forget - `(:max 1 ,(and user-domain :user) ,user-domain - :host ,host-port :port ,method)) - (password-cache-remove (tramp-make-tramp-file-name vec 'noloc)))) + (when-let* ((hop (cadr (reverse (tramp-compute-multi-hops vec))))) + ;; Clear also the passwords of the hops. + (tramp-clear-passwd hop)) + (when-let* ((pw-spec (tramp-get-connection-property vec " pw-spec"))) + (auth-source-forget pw-spec))) (defun tramp-time-diff (t1 t2) "Return the difference between the two times, in seconds. commit b83a45eab53b8e6d8f3be45c0acb9a42a5262cb0 Author: Cecilio Pardo Date: Thu Nov 14 09:55:56 2024 +0100 Fix drag-n-drop on MS-Windows * src/w32fns.c (struct w32_drop_target): New member 'ref_count'. (w32_drop_target_AddRef): Increment reference count. (w32_drop_target_Release): Decrement reference count, and free the target only if the reference count is zero. (w32_createwindow): Initialize reference count. (Bug#74312) diff --git a/src/w32fns.c b/src/w32fns.c index 1bd3d5099e2..e2455b9271e 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -2562,6 +2562,7 @@ struct w32_drop_target { /* i_drop_target must be the first member. */ IDropTarget i_drop_target; HWND hwnd; + int ref_count; }; static HRESULT STDMETHODCALLTYPE @@ -2573,13 +2574,16 @@ w32_drop_target_QueryInterface (IDropTarget *t, REFIID ri, void **r) static ULONG STDMETHODCALLTYPE w32_drop_target_AddRef (IDropTarget *This) { - return 1; + struct w32_drop_target *target = (struct w32_drop_target *) This; + return ++target->ref_count; } static ULONG STDMETHODCALLTYPE w32_drop_target_Release (IDropTarget *This) { struct w32_drop_target *target = (struct w32_drop_target *) This; + if (--target->ref_count > 0) + return target->ref_count; free (target->i_drop_target.lpVtbl); free (target); return 0; @@ -2770,6 +2774,7 @@ w32_createwindow (struct frame *f, int *coords) if (vtbl != NULL) { drop_target->hwnd = hwnd; + drop_target->ref_count = 0; drop_target->i_drop_target.lpVtbl = vtbl; vtbl->QueryInterface = w32_drop_target_QueryInterface; vtbl->AddRef = w32_drop_target_AddRef; commit 70273dc9f7e01e5330abedb44b1c3e46430fbc69 Merge: 3e86231b54f 5b19ca56f1d Author: Michael Albinus Date: Thu Nov 14 16:52:59 2024 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit 3e86231b54ffed7f242c334f96923cff376a197f Merge: 32f070fa3df f69f54c454e Author: Michael Albinus Date: Thu Nov 14 16:51:20 2024 +0100 Merge from origin/emacs-30 f69f54c454e Improve font-locking and indentation in 'php-ts-mode' 27aacbd172f Fix some 'lua-ts-mode' options (Bug#74235) a0613372a7b ; Update the xwidgets-on-NS text due to fixing bug#60703 d5928325045 Improve comment indenting in 'lua-ts-mode' 6bc44ccf287 Update 'xref-num-matches-found' when reverting *xref* buffer 8afcfed825a * lisp/files.el (require-with-check): Fix last fix (bug#7... 3496234c8ed lisp/files.el (require-with-check): Fix bug#74091. 90c97d3fac9 Fix handling of permanent-local variables in 'kill-all-lo... c96e5760907 Precise password cache in Tramp 3954e8d9bbe Fix picture-mode with full-width characters 7dabfe9465c Fix movement to the left in picture-mode # Conflicts: # lisp/net/tramp.el commit 5b19ca56f1d91a65c0068160790e2cb512bb2067 Author: Spencer Baugh Date: Tue Oct 29 12:16:31 2024 -0400 Preserve selected candidate across *Completions* update When *Completions* is updated and point was on some completion candidate, move point to the same candidate after the update. Also, a selected completion in *Completions* is now always highlighted, even if it was selected by the user or other code moving point rather than by minibuffer-next-completion, because cursor-face-highlight-nonselected-window is now set in completion-setup-function. Other completion UIs (e.g. ido, vertico, etc) effectively have this behavior: whenever they update the list of completions, they preserve whatever candidate is selected. This matters a lot when completions are auto-updated, but is still useful without auto-updating. Including this behavior is a step towards supporting auto-updating in the default completion UI. * lisp/minibuffer.el (minibuffer-completion-help): Preserve the selected completion candidate across updates. (bug#74019) (minibuffer-hide-completions): Move point to BOB. (minibuffer-next-completion): Don't set cursor-face-highlight-nonselected-window. * lisp/simple.el (completions--start-of-candidate-at) (choose-completion): Extract the current-completion-finding code into a separate function. (completion-setup-function): Set cursor-face-highlight-nonselected-window. * etc/NEWS: Announce new behavior. diff --git a/etc/NEWS b/etc/NEWS index 86476270782..634b1e89ab8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -86,6 +86,14 @@ different values for completion-affecting variables like applies for the styles configuration in 'completion-category-overrides' and 'completion-category-defaults'. +--- +*** Selected completion candidate is preserved across *Completions* updates. +When point is on a completion candidate in the *Completions* buffer +(because of 'minibuffer-next-completion' or for any other reason), point +will still be on that candidate after *Completions* is updated with a +new list of completions. The candidate is automatically deselected when +the *Completions* buffer is hidden. + ** Windows +++ diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 44d07557f48..9b498615926 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2624,6 +2624,12 @@ The candidate will still be chosen by `choose-completion' unless (sort-fun (completion-metadata-get all-md 'display-sort-function)) (group-fun (completion-metadata-get all-md 'group-function)) (mainbuf (current-buffer)) + (current-candidate-and-offset + (when-let* ((buffer (get-buffer "*Completions*")) + (window (get-buffer-window buffer 0))) + (with-current-buffer buffer + (when-let* ((beg (completions--start-of-candidate-at (window-point window)))) + (cons (get-text-property beg 'completion--string) (- (point) beg)))))) ;; If the *Completions* buffer is shown in a new ;; window, mark it as softly-dedicated, so bury-buffer in ;; minibuffer-hide-completions will know whether to @@ -2647,7 +2653,7 @@ The candidate will still be chosen by `choose-completion' unless ,(when temp-buffer-resize-mode '(preserve-size . (nil . t))) (body-function - . ,#'(lambda (_window) + . ,#'(lambda (window) (with-current-buffer mainbuf (when completion-auto-deselect (add-hook 'after-change-functions #'completions--after-change nil t)) @@ -2737,7 +2743,16 @@ The candidate will still be chosen by `choose-completion' unless (if (eq (car bounds) (length result)) 'exact 'finished)))))) - (display-completion-list completions nil group-fun))))) + (display-completion-list completions nil group-fun) + (when current-candidate-and-offset + (with-current-buffer standard-output + (when-let* ((match (text-property-search-forward + 'completion--string (car current-candidate-and-offset) t))) + (goto-char (prop-match-beginning match)) + ;; Preserve the exact offset for the sake of + ;; `choose-completion-deselect-if-after'. + (forward-char (cdr current-candidate-and-offset)) + (set-window-point window (point))))))))) nil))) nil)) @@ -2746,8 +2761,12 @@ The candidate will still be chosen by `choose-completion' unless ;; FIXME: We could/should use minibuffer-scroll-window here, but it ;; can also point to the minibuffer-parent-window, so it's a bit tricky. (interactive) - (let ((win (get-buffer-window "*Completions*" 0))) - (if win (with-selected-window win (bury-buffer))))) + (when-let* ((win (get-buffer-window "*Completions*" 0))) + (with-selected-window win + ;; Move point off any completions, so we don't move point there + ;; again the next time `minibuffer-completion-help' is called. + (goto-char (point-min)) + (bury-buffer)))) (defun exit-minibuffer () "Terminate this minibuffer argument." @@ -4905,8 +4924,6 @@ insert the selected completion candidate to the minibuffer." (interactive "p") (let ((auto-choose minibuffer-completion-auto-choose)) (with-minibuffer-completions-window - (when completions-highlight-face - (setq-local cursor-face-highlight-nonselected-window t)) (if vertical (next-line-completion (or n 1)) (next-completion (or n 1))) diff --git a/lisp/simple.el b/lisp/simple.el index 2ffd6e86e56..3a142ef14b3 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10246,6 +10246,23 @@ Also see the `completion-auto-wrap' variable." This makes `completions--deselect' effective.") +(defun completions--start-of-candidate-at (position) + "Return the start position of the completion candidate at POSITION." + (save-excursion + (goto-char position) + (let (beg) + (cond + ((and (not (eobp)) + (get-text-property (point) 'completion--string)) + (setq beg (1+ (point)))) + ((and (not (bobp)) + (get-text-property (1- (point)) 'completion--string)) + (setq beg (point)))) + (when beg + (or (previous-single-property-change + beg 'completion--string) + beg))))) + (defun choose-completion (&optional event no-exit no-quit) "Choose the completion at point. If EVENT, use EVENT's position to determine the starting position. @@ -10269,21 +10286,11 @@ minibuffer, but don't quit the completions window." (or (get-text-property (posn-point (event-start event)) 'completion--string) (error "No completion here")) - (save-excursion - (goto-char (posn-point (event-start event))) - (let (beg) - (cond - ((and (not (eobp)) - (get-text-property (point) 'completion--string)) - (setq beg (1+ (point)))) - ((and (not (bobp)) - (get-text-property (1- (point)) 'completion--string)) - (setq beg (point))) - (t (error "No completion here"))) - (setq beg (or (previous-single-property-change - beg 'completion--string) - beg)) - (get-text-property beg 'completion--string)))))) + (if-let* ((candidate-start + (completions--start-of-candidate-at + (posn-point (event-start event))))) + (get-text-property candidate-start 'completion--string) + (error "No completion here"))))) (unless (buffer-live-p buffer) (error "Destination buffer is dead")) @@ -10451,6 +10458,8 @@ Called from `temp-buffer-show-hook'." (let ((base-position completion-base-position) (insert-fun completion-list-insert-choice-function)) (completion-list-mode) + (when completions-highlight-face + (setq-local cursor-face-highlight-nonselected-window t)) (setq-local completion-base-position base-position) (setq-local completion-list-insert-choice-function insert-fun)) (setq-local completion-reference-buffer mainbuf) commit 32f070fa3dfccd29abad6e7566ed9121e3f1da39 Author: john muhl Date: Sat Oct 19 18:25:41 2024 -0500 Add song viewer to 'mpc' (Bug#74200) * lisp/mpc.el (mpc-describe-song): New command. (mpc-mode-map): Bind "d" to 'mpc-describe-song'. (mpc-mode-menu): Add menu item. (mpc-secs-to-time): Ensure secs argument is an integer. (mpc-song-viewer-empty, mpc-song-viewer-tag): (mpc-song-viewer-value): New face. (mpc-song-viewer-tags): New option. diff --git a/etc/NEWS b/etc/NEWS index c2dccec9548..86476270782 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -659,11 +659,20 @@ a desktop notification when the song changes, using customized using the new user options 'mpc-notifications-title' and 'mpc-notifications-body'. +--- *** New user option 'mpc-crossfade-time'. When non-nil, MPC will crossfade between songs for the specified number of seconds. Crossfading can be toggled using the command 'mpc-toggle-crossfade' or from the MPC menu. +--- +*** New command 'mpc-describe-song'. +This command displays information about the currently playing song or +song at point in the MPC-Songs buffer. The list of tags to display can +be customized using the new user option 'mpc-song-viewer-tags' and the +appearance of the list with the new faces 'mpc-song-viewer-tag', +'mpc-song-viewer-value', and 'mpc-song-viewer-empty'. + ** VC --- diff --git a/lisp/mpc.el b/lisp/mpc.el index 0a43b09c11d..a0ecb21e454 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el @@ -63,7 +63,7 @@ ;; e.g. filename regexp -> compilation flag ;; - window/buffer management. ;; - menubar, tooltips, ... -;; - add mpc-describe-song, mpc-describe-album, ... +;; - add mpc-describe-album, ... ;; - add import/export commands (especially export to an MP3 player). ;; - add a real notion of album (as opposed to just album-name): ;; if all songs with same album-name have same artist -> it's an album @@ -95,6 +95,8 @@ (require 'notifications) +(require 'vtable) + (defgroup mpc () "Client for the Music Player Daemon (mpd)." :prefix "mpc-" @@ -978,11 +980,15 @@ If PLAYLIST is t or nil or missing, use the main playlist." :version "28.1") (defun mpc-secs-to-time (secs) + "Convert SECS from a string, integer or float value to a time string." ;; We could use `format-seconds', but it doesn't seem worth the trouble ;; because we'd still need to check (>= secs (* 60 100)) since the special ;; %z only allows us to drop the large units for small values but ;; not to drop the small units for large values. (if (stringp secs) (setq secs (string-to-number secs))) + ;; Ensure secs is an integer. The Time tag has been deprecated by MPD + ;; and its replacement (the duration tag) includes fractional seconds. + (if (floatp secs) (setq secs (round secs))) (if (>= secs (* 60 100)) ;More than 100 minutes. (format "%dh%02d" ;"%d:%02d:%02d" (/ secs 3600) (% (/ secs 60) 60)) ;; (% secs 60) @@ -1180,7 +1186,8 @@ string POST." ">" #'mpc-next "<" #'mpc-prev "g" #'mpc-seek-current - "o" #'mpc-goto-playing-song) + "o" #'mpc-goto-playing-song + "d" #'mpc-describe-song) (easy-menu-define mpc-mode-menu mpc-mode-map "Menu for MPC mode." @@ -1189,6 +1196,7 @@ string POST." ["Next Track" mpc-next] ;FIXME: Add ⇥ there? ["Previous Track" mpc-prev] ;FIXME: Add ⇤ there? ["Seek Within Track" mpc-seek-current] + ["Song Details" mpc-describe-song] "--" ["Repeat Playlist" mpc-toggle-repeat :style toggle :selected (member '(repeat . "1") mpc-status)] @@ -2862,6 +2870,98 @@ will be used. See `mpc-format' for the definition of FORMAT-SPEC." :app-icon icon :replaces-id mpc--notifications-id)))) +;;; Song Viewer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defface mpc-song-viewer-value + '((t (:inherit vtable))) + "Face for tag values in the MPC song viewer.") + +(defface mpc-song-viewer-tag + '((t (:inherit (mpc-song-viewer-value bold)))) + "Face for tag types in the MPC song viewer.") + +(defface mpc-song-viewer-empty + '((t (:inherit (mpc-song-viewer-value italic shadow)))) + "Face for empty tag values in the MPC song viewer.") + +(defcustom mpc-song-viewer-tags + '("Title" "Artist" "Album" "Performer" "Composer" + "Date" "Duration" "Disc" "Track" "Genre" "File") + "The list of tags to display with `mpc-describe-song'. + +The list of supported tags are available by evaluating +`mpc-cmd-tagtypes'. In addition to the standard MPD tags: Bitrate, +Duration, File, and Format are also supported." + :version "31.1" + :type '(repeat string)) + +(defun mpc-describe-song (file) + "Show details of the selected song or FILE in the MPC song viewer. + +If there is no song at point then information about the currently +playing song is displayed." + (interactive + ;; Handle being called from the context menu. In that case you want + ;; to see details for the song you clicked on to invoke the menu not + ;; whatever `point' happens to be on at that time. + (list (when-let* ((event last-nonmenu-event) + ((listp event)) + (position (nth 1 (event-start event)))) + (get-text-property position 'mpc-file)))) + (let ((tags (or (when (and file (stringp file)) + (mpc-proc-cmd-to-alist (list "search" "file" file))) + (when-let* (((string= (buffer-name) "*MPC-Songs*")) + (file (get-text-property (point) 'mpc-file))) + (mpc-proc-cmd-to-alist (list "search" "file" file))) + (when (assoc 'file mpc-status) mpc-status))) + (buffer "*MPC Song Viewer*")) + (when tags + (with-current-buffer (get-buffer-create buffer) + (special-mode) + (visual-line-mode) + (let ((inhibit-read-only t)) + (erase-buffer) + (make-vtable + :columns '(( :name "Tag" + :align right + :min-width 3 + :displayer + (lambda (tag &rest _) + (propertize tag 'face 'mpc-song-viewer-tag))) + ( :name "Value" + :align left + :min-width 5 + :displayer + (lambda (value &rest _) + (if (and value (not (string-blank-p value))) + (propertize value 'face 'mpc-song-viewer-value) + (propertize "empty" 'face 'mpc-song-viewer-empty))))) + :objects (mapcar + (lambda (tag) + (pcase tag + ("Bitrate" + (list tag (let ((bitrate (alist-get 'bitrate tags))) + (when bitrate + (format "%s kpbs" bitrate))))) + ("Duration" (list tag (mpc-secs-to-time + (alist-get 'duration tags)))) + ("File" (list tag (alist-get 'file tags))) + ;; Concatenate all the values of tags which may + ;; occur multiple times. + ((or "Composer" "Genre" "Performer") + (list tag (mapconcat + (lambda (val) (cdr val)) + (seq-filter + (lambda (val) (eq (car val) (intern tag))) + tags) + "; "))) + (_ (list tag (alist-get (intern tag) tags))))) + mpc-song-viewer-tags)) + (goto-char (point-min)))) + (pop-to-buffer buffer '((display-buffer-reuse-window + display-buffer-same-window) + (reusable-frames . t)))))) + ;;; Toplevel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defcustom mpc-frame-alist '((name . "MPC") (tool-bar-lines . 1) commit f69f54c454eb3c0f8ff8c55cfd2b7832ea1709cf (refs/remotes/origin/emacs-30) Author: Vincenzo Pupillo Date: Thu Nov 7 12:55:50 2024 +0100 Improve font-locking and indentation in 'php-ts-mode' * lisp/progmodes/php-ts-mode.el (php-ts-mode--language-source-alist): Updated to latest version of PHP grammar. (php-ts-mode--indent-styles): 'namespace_use_declaration' is now correctly indented. (php-ts-mode--operators): Support of the "argument unpacking operator". (php-ts-mode--font-lock-settings): 'nullsafe_member_call_expression' is now highlighted correctly. (php-ts-mode--comment-indent-new-line): Delete trailing whitespace before inserting newline (see bug#73900 for more information). Bug#74239 diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index 14a487d3f7a..d8a3f60508b 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -84,7 +84,7 @@ ;;; Install treesitter language parsers (defvar php-ts-mode--language-source-alist - '((php . ("https://github.com/tree-sitter/tree-sitter-php" "v0.23.4" "php/src")) + '((php . ("https://github.com/tree-sitter/tree-sitter-php" "v0.23.5" "php/src")) (phpdoc . ("https://github.com/claytonrcarter/tree-sitter-phpdoc")) (html . ("https://github.com/tree-sitter/tree-sitter-html" "v0.23.0")) (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript" "v0.23.0")) @@ -640,6 +640,7 @@ characters of the current line." ((query "(class_interface_clause (qualified_name) @indent)") parent-bol php-ts-mode-indent-offset) ((parent-is "class_declaration") parent-bol 0) + ((parent-is "namespace_use_declaration") parent-bol php-ts-mode-indent-offset) ((parent-is "namespace_use_group") parent-bol php-ts-mode-indent-offset) ((parent-is "function_definition") parent-bol 0) ((parent-is "member_call_expression") first-sibling php-ts-mode-indent-offset) @@ -781,7 +782,7 @@ characters of the current line." '("--" "**=" "*=" "/=" "%=" "+=" "-=" ".=" "<<=" ">>=" "&=" "^=" "|=" "??" "??=" "||" "&&" "|" "^" "&" "==" "!=" "<>" "===" "!==" "<" ">" "<=" ">=" "<=>" "<<" ">>" "+" "-" "." "*" "**" "/" "%" - "->" "?->") + "->" "?->" "...") "PHP operators for tree-sitter font-locking.") (defconst php-ts-mode--predefined-constant @@ -993,7 +994,7 @@ characters of the current line." (member_call_expression name: (_) @font-lock-function-call-face) (nullsafe_member_call_expression - name: (_) @font-lock-constant-face)) + name: (_) @font-lock-function-call-face)) :language 'php :feature 'argument @@ -1266,8 +1267,14 @@ less common PHP-style # comment. SOFT works the same as in (line-end-position) t nil)) (let ((offset (- (match-beginning 0) (line-beginning-position))) - (comment-prefix (match-string 0))) - (if soft (insert-and-inherit ?\n) (newline 1)) + (comment-prefix (match-string 0)) + (insert-line-break + (lambda () + (delete-horizontal-space) + (if soft + (insert-and-inherit ?\n) + (newline 1))))) + (funcall insert-line-break) (delete-region (line-beginning-position) (point)) (insert (make-string offset ?\s) commit 27aacbd172f3b94926073250ef81a226616d1e45 Author: john muhl Date: Sat Nov 9 11:01:45 2024 -0600 Fix some 'lua-ts-mode' options (Bug#74235) * lisp/progmodes/lua-ts-mode.el (lua-ts-luacheck-program): (lua-ts-inferior-program): Switch to 'file' type and remove 'nil' as a choice. (lua-ts-inferior-lua): Ensure 'lua-ts-inferior-program' is set. diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index 836a62b2dac..e5a2fafd279 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -72,7 +72,7 @@ (defcustom lua-ts-luacheck-program "luacheck" "Location of the Luacheck program." - :type '(choice (const :tag "None" nil) string) + :type 'file :version "30.1") (defcustom lua-ts-inferior-buffer "*Lua*" @@ -83,7 +83,7 @@ (defcustom lua-ts-inferior-program "lua" "Program to run in the inferior Lua process." - :type '(choice (const :tag "None" nil) string) + :type 'file :version "30.1") (defcustom lua-ts-inferior-options '("-i") @@ -643,47 +643,49 @@ Calls REPORT-FN directly." (defun lua-ts-inferior-lua () "Run a Lua interpreter in an inferior process." (interactive) - (unless (comint-check-proc lua-ts-inferior-buffer) - (apply #'make-comint-in-buffer - (string-replace "*" "" lua-ts-inferior-buffer) - lua-ts-inferior-buffer - lua-ts-inferior-program - lua-ts-inferior-startfile - lua-ts-inferior-options) - (when lua-ts-inferior-history + (if (not lua-ts-inferior-program) + (user-error "You must set `lua-ts-inferior-program' to use this command") + (unless (comint-check-proc lua-ts-inferior-buffer) + (apply #'make-comint-in-buffer + (string-replace "*" "" lua-ts-inferior-buffer) + lua-ts-inferior-buffer + lua-ts-inferior-program + lua-ts-inferior-startfile + lua-ts-inferior-options) + (when lua-ts-inferior-history (set-process-sentinel (get-buffer-process lua-ts-inferior-buffer) 'lua-ts-inferior--write-history)) - (with-current-buffer lua-ts-inferior-buffer - (setq-local comint-input-ignoredups t - comint-input-ring-file-name lua-ts-inferior-history - comint-prompt-read-only t - comint-prompt-regexp (rx-to-string `(: bol - ,lua-ts-inferior-prompt - (1+ space)))) - (comint-read-input-ring t) - (add-hook 'comint-preoutput-filter-functions - (lambda (string) - (if (equal string (concat lua-ts-inferior-prompt-continue " ")) - string - (concat - ;; Filter out the extra prompt characters that - ;; accumulate in the output when sending regions - ;; to the inferior process. - (replace-regexp-in-string (rx-to-string - `(: bol - (* ,lua-ts-inferior-prompt - (? ,lua-ts-inferior-prompt) - (1+ space)) - (group (* nonl)))) - "\\1" string) - ;; Re-add the prompt for the next line. - lua-ts-inferior-prompt " "))) - nil t))) - (select-window (display-buffer lua-ts-inferior-buffer - '((display-buffer-reuse-window - display-buffer-pop-up-window) - (reusable-frames . t)))) - (get-buffer-process (current-buffer))) + (with-current-buffer lua-ts-inferior-buffer + (setq-local comint-input-ignoredups t + comint-input-ring-file-name lua-ts-inferior-history + comint-prompt-read-only t + comint-prompt-regexp (rx-to-string `(: bol + ,lua-ts-inferior-prompt + (1+ space)))) + (comint-read-input-ring t) + (add-hook 'comint-preoutput-filter-functions + (lambda (string) + (if (equal string (concat lua-ts-inferior-prompt-continue " ")) + string + (concat + ;; Filter out the extra prompt characters that + ;; accumulate in the output when sending regions + ;; to the inferior process. + (replace-regexp-in-string + (rx-to-string `(: bol + (* ,lua-ts-inferior-prompt + (? ,lua-ts-inferior-prompt) + (1+ space)) + (group (* nonl)))) + "\\1" string) + ;; Re-add the prompt for the next line. + lua-ts-inferior-prompt " "))) + nil t))) + (select-window (display-buffer lua-ts-inferior-buffer + '((display-buffer-reuse-window + display-buffer-pop-up-window) + (reusable-frames . t)))) + (get-buffer-process (current-buffer)))) (defun lua-ts-send-buffer () "Send current buffer to the inferior Lua process." commit a0613372a7bbc19f87f19c49153eca262eb750c1 Author: Andrew De Angelis Date: Sun Nov 10 10:13:17 2024 -0500 ; Update the xwidgets-on-NS text due to fixing bug#60703 * etc/TODO: Update the xwidgets-on-NS text (bug#74295). diff --git a/etc/TODO b/etc/TODO index 21c85216964..b60e1198a0a 100644 --- a/etc/TODO +++ b/etc/TODO @@ -943,13 +943,13 @@ This sections contains features found in other official Emacs ports. Emacs 25 has support for xwidgets, a system to include WebKit widgets into an Emacs buffer. -They work on NS, but not very well. For example, trying to display a -xwidget in the "killed" state will make Emacs crash. This is because -the NS code has not been updated to keep with recent changes to the -X11 and GTK code. +They work on NS, but not very well. This is because the NS code has +not been updated to keep with recent changes to the X11 and GTK code. -Many features such as xwidget-webkit-edit-mode do not work correctly -on NS either. +Many features do not work correctly on NS, such as: + - xwidget-webkit-edit-mode + - xwidget-webkit-isearch-mode + - xwidget-webkit-browse-history. **** Respect 'frame-inhibit-implied-resize' When the variable 'frame-inhibit-implied-resize' is non-nil, frames commit d592832504554c6ee30bea263e55dc84feaec18d Author: john muhl Date: Sun Nov 10 11:26:33 2024 -0600 Improve comment indenting in 'lua-ts-mode' * lisp/progmodes/lua-ts-mode.el (lua-ts--simple-indent-rules): Align single line comments with the surrounding context. (lua-ts--comment-first-sibling-matcher): Check that comment is the first sibling. (lua-ts--multi-line-comment-start): New function. * test/lisp/progmodes/lua-ts-mode-resources/indent.erts: Add tests. (Bug#74298) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index 4ea453c9b65..836a62b2dac 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -289,7 +289,8 @@ values of OVERRIDE." (defvar lua-ts--simple-indent-rules `((lua - ((or (node-is "comment") + ((or (and (node-is "comment") (parent-is "chunk")) + lua-ts--multi-line-comment-start (parent-is "comment_content") (parent-is "string_content") (node-is "]]")) @@ -473,9 +474,10 @@ values of OVERRIDE." (= 1 (length (cadr sparse-tree))))) (defun lua-ts--comment-first-sibling-matcher (node &rest _) - "Matches if NODE if it's previous sibling is a comment." + "Matches NODE if its previous sibling is a comment." (let ((sibling (treesit-node-prev-sibling node))) - (equal "comment" (treesit-node-type sibling)))) + (and (= 0 (treesit-node-index sibling t)) + (equal "comment" (treesit-node-type sibling))))) (defun lua-ts--top-level-function-call-matcher (node &rest _) "Matches if NODE is within a top-level function call." @@ -508,6 +510,15 @@ values of OVERRIDE." (line-beginning-position)) (point)))) +(defun lua-ts--multi-line-comment-start (node &rest _) + "Matches if NODE is the beginning of a multi-line comment." + (and node + (equal "comment" (treesit-node-type node)) + (save-excursion + (goto-char (treesit-node-start node)) + (forward-char 2) ; Skip the -- part. + (looking-at "\\[\\[")))) + (defvar lua-ts--syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?+ "." table) diff --git a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts index ba7bad1b452..b0ece4cc261 100644 --- a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts +++ b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts @@ -360,6 +360,10 @@ multi-line ]] return true end + + --[[ +Long comment. + ]] =-= --[[ Multi-line @@ -373,6 +377,44 @@ multi-line ]] return true end + + --[[ +Long comment. + ]] +=-=-= + +Name: Comment Indent + +=-= +local fn1 = function (a, b) +-- comment +return a + b +end + +local tb1 = { + first = 1, +-- comment + second = 2, +} + +local tb9 = { one = 1, +-- comment + two = 2 } +=-= +local fn1 = function (a, b) + -- comment + return a + b +end + +local tb1 = { + first = 1, + -- comment + second = 2, +} + +local tb9 = { one = 1, + -- comment + two = 2 } =-=-= Name: Argument Indent commit 6bc44ccf287a398d47563ddf60d13784cd64720f Author: Eshel Yaron Date: Mon Nov 11 19:45:10 2024 +0100 Update 'xref-num-matches-found' when reverting *xref* buffer * lisp/progmodes/xref.el (xref--insert-xrefs): Update 'xref-num-matches-found' here... (xref--show-xref-buffer): ...instead of here (bug#74313). diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 5ecb8664da0..125616398f0 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1140,6 +1140,7 @@ XREF-ALIST is of the form ((GROUP . (XREF ...)) ...), where GROUP is a string for decoration purposes and XREF is an `xref-item' object." (require 'compile) ; For the compilation faces. + (setq xref-num-matches-found 0) (cl-loop for (group . xrefs) in xref-alist for max-line = (cl-loop for xref in xrefs maximize (xref-location-line @@ -1159,6 +1160,7 @@ GROUP is a string for decoration purposes and XREF is an (xref--insert-propertized '(face xref-file-header xref-group t) group "\n") (dolist (xref xrefs) + (cl-incf xref-num-matches-found) (pcase-let (((cl-struct xref-item summary location) xref)) (let* ((line (xref-location-line location)) (prefix @@ -1248,7 +1250,6 @@ Return an alist of the form ((GROUP . (XREF ...)) ...)." (xref--ensure-default-directory dd (current-buffer)) (xref--xref-buffer-mode) (xref--show-common-initialize xref-alist fetcher alist) - (setq xref-num-matches-found (length xrefs)) (setq mode-line-process (list xref-mode-line-matches)) (pop-to-buffer (current-buffer)) (setq buf (current-buffer))) commit 8afcfed825ae60c8947c41d84b431b21f32b2714 Author: Stefan Monnier Date: Wed Nov 13 11:39:05 2024 -0500 * lisp/files.el (require-with-check): Fix last fix (bug#74289) diff --git a/lisp/files.el b/lisp/files.el index 898f9d23cf8..63a08ce5b22 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1275,7 +1275,7 @@ NOERROR is equal to `reload'), or otherwise emit a warning." (res (require feature filename (if (eq noerror 'reload) nil noerror)))) ;; If the `feature' was not yet provided, `require' just loaded the right ;; file, so we're done. - (when (eq lh load-history) + (when (and res (eq lh load-history)) ;; If `require' did nothing, we need to make sure that was warranted. (let* ((fn (locate-file (or filename (symbol-name feature)) load-path (get-load-suffixes) nil @@ -1288,11 +1288,10 @@ NOERROR is equal to `reload'), or otherwise emit a warning." ;; we did load "it". (bug#74040) ;; So use a "permissive" search which doesn't pay attention to ;; differences between file extensions. - (prefix (when fn - (if (string-match - (concat (regexp-opt (get-load-suffixes)) "\\'") fn) - (concat (substring fn 0 (match-beginning 0)) ".") - fn))) + (prefix (if (string-match + (concat (regexp-opt (get-load-suffixes)) "\\'") fn) + (concat (substring fn 0 (match-beginning 0)) ".") + fn)) (lh load-history)) (while (and lh (let ((file (car-safe (car lh)))) (not (and file (string-prefix-p prefix file))))) commit 3496234c8ed10a14f740199722ec727bd43c82d3 Author: Stefan Monnier Date: Sun Nov 10 16:50:36 2024 -0500 lisp/files.el (require-with-check): Fix bug#74091. diff --git a/lisp/files.el b/lisp/files.el index c3fce9f15f9..898f9d23cf8 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1280,7 +1280,7 @@ NOERROR is equal to `reload'), or otherwise emit a warning." (let* ((fn (locate-file (or filename (symbol-name feature)) load-path (get-load-suffixes) nil )) ;; load-prefer-newer - ;; We used to look for `fn' in `load-history' with `assoc' + ;; We used to look for `fn' in `load-history' with `assoc' ;; which works in most cases, but in some cases (e.g. when ;; `load-prefer-newer' is set) `locate-file' can return a ;; different file than the file that `require' would load, @@ -1288,10 +1288,11 @@ NOERROR is equal to `reload'), or otherwise emit a warning." ;; we did load "it". (bug#74040) ;; So use a "permissive" search which doesn't pay attention to ;; differences between file extensions. - (prefix (if (string-match - (concat (regexp-opt (get-load-suffixes)) "\\'") fn) - (concat (substring fn 0 (match-beginning 0)) ".") - fn)) + (prefix (when fn + (if (string-match + (concat (regexp-opt (get-load-suffixes)) "\\'") fn) + (concat (substring fn 0 (match-beginning 0)) ".") + fn))) (lh load-history)) (while (and lh (let ((file (car-safe (car lh)))) (not (and file (string-prefix-p prefix file))))) commit 90c97d3fac989f3048fda4a30a626bec2c3301c5 Author: Eli Zaretskii Date: Sun Nov 10 20:49:45 2024 +0200 Fix handling of permanent-local variables in 'kill-all-local-variables' The original implementation went too far and caused unexpected results. * src/buffer.c (reset_buffer_local_variables): Second argument is now 'int', and can be 0, 1, or 2. (Fkill_all_local_variables): Call 'reset_buffer_local_variables' with 2nd argument 2 if KILL-PERMANENT is non-nil. (Bug#74091) diff --git a/src/buffer.c b/src/buffer.c index 744b0ef5548..995984e3e72 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -113,7 +113,7 @@ static int last_per_buffer_idx; static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3); -static void reset_buffer_local_variables (struct buffer *, bool); +static void reset_buffer_local_variables (struct buffer *, int); /* Alist of all buffer names vs the buffers. This used to be a Lisp-visible variable, but is no longer, to prevent lossage @@ -1112,10 +1112,11 @@ reset_buffer (register struct buffer *b) Instead, use Fkill_all_local_variables. If PERMANENT_TOO, reset permanent buffer-local variables. - If not, preserve those. */ + If not, preserve those. PERMANENT_TOO = 2 means ignore + the permanent-local property of non-builtin variables. */ static void -reset_buffer_local_variables (struct buffer *b, bool permanent_too) +reset_buffer_local_variables (struct buffer *b, int permanent_too) { int offset, i; @@ -1141,7 +1142,7 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) bset_invisibility_spec (b, Qt); /* Reset all (or most) per-buffer variables to their defaults. */ - if (permanent_too) + if (permanent_too == 1) bset_local_var_alist (b, Qnil); else { @@ -1170,7 +1171,7 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) swap_in_global_binding (XSYMBOL (sym)); } - if (!NILP (prop)) + if (!NILP (prop) && !permanent_too) { /* If permanent-local, keep it. */ last = tmp; @@ -3001,7 +3002,7 @@ the normal hook `change-major-mode-hook'. */) /* Actually eliminate all local bindings of this buffer. */ - reset_buffer_local_variables (current_buffer, !NILP (kill_permanent)); + reset_buffer_local_variables (current_buffer, !NILP (kill_permanent) ? 2 : 0); /* Force mode-line redisplay. Useful here because all major mode commands call this function. */ commit c96e57609076c4d5627e698a6f12a731a77c365e Author: Michael Albinus Date: Sun Nov 10 12:35:15 2024 +0100 Precise password cache in Tramp * doc/misc/tramp.texi (Password handling): Describe auth-source-cache-expiry and auth-source-do-cache instead of password-cache-expiry and password-cache. (Bug#74105) * lisp/net/tramp.el (tramp-read-passwd): Check for `auth-sources' being non-nil. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 9895b3c6fce..0d7f9c11a6b 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2194,14 +2194,18 @@ like this: @value{tramp} can cache passwords as entered and reuse when needed for the same user or host name independent of the access method. -@vindex password-cache-expiry -@code{password-cache-expiry} sets the duration (in seconds) the -passwords are remembered. Passwords are never saved permanently nor -can they extend beyond the lifetime of the current Emacs session. Set -@code{password-cache-expiry} to @code{nil} to disable expiration. - -@vindex password-cache -Set @code{password-cache} to @code{nil} to disable password caching. +@vindex auth-source-cache-expiry +@code{auth-source-cache-expiry}@footnote{It overrides +@code{password-cache-expiry}.} sets the duration (in seconds) the +passwords are remembered. Set @code{auth-source-cache-expiry} to +@code{nil} to disable expiration. + +Cached passwords are never saved permanently nor can they extend +beyond the lifetime of the current Emacs session unless you confirm +this interactively. + +@vindex auth-source-do-cache +Set @code{auth-source-do-cache} to @code{nil} to disable password caching. @node Connection caching diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 22b3ef84626..8e98f805234 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -6819,7 +6819,8 @@ Consults the auth-source package." (setq tramp-password-save-function nil) ;; See if auth-sources contains something useful. (ignore-errors - (and (tramp-get-connection-property vec "first-password-request") + (and auth-sources + (tramp-get-connection-property vec "first-password-request") ;; Try with Tramp's current method. If there is no ;; user name, `:create' triggers to ask for. We ;; suppress it. commit 3954e8d9bbed902e750c9e0647c6527ae32523b9 Author: Eli Zaretskii Date: Sun Nov 10 11:48:34 2024 +0200 Fix picture-mode with full-width characters * lisp/textmodes/picture.el (picture-insert): Don't rely on 'move-to-column' to move to the column that is its argument: this might be false when full-width characters are involved. diff --git a/lisp/textmodes/picture.el b/lisp/textmodes/picture.el index 08bb12cd80c..1435ea2c4e2 100644 --- a/lisp/textmodes/picture.el +++ b/lisp/textmodes/picture.el @@ -257,12 +257,14 @@ Use \"\\[command-apropos] picture-movement\" to see commands which control motio (> width 1) (< (abs picture-horizontal-step) 2)) (* picture-horizontal-step 2) - picture-horizontal-step))) + picture-horizontal-step)) + actual-col) (while (> arg 0) (setq arg (1- arg)) (if (/= picture-desired-column (current-column)) - (move-to-column picture-desired-column t)) - (let ((col (+ picture-desired-column width))) + (setq actual-col (move-to-column picture-desired-column t)) + (setq actual-col picture-desired-column)) + (let ((col (+ actual-col width))) (or (eolp) (let ((pos (point)) (col0 (current-column)) commit 7dabfe9465c623043e4ea1abe618a6169c155d04 Author: Eli Zaretskii Date: Sun Nov 10 10:56:40 2024 +0200 Fix movement to the left in picture-mode * lisp/textmodes/picture.el (picture-insert): Measure width by counting columns on display, not by using 'string-width', because the latter is inaccurate when TABs are involved. (Bug#74255) diff --git a/lisp/textmodes/picture.el b/lisp/textmodes/picture.el index adb06cb6a29..08bb12cd80c 100644 --- a/lisp/textmodes/picture.el +++ b/lisp/textmodes/picture.el @@ -264,9 +264,14 @@ Use \"\\[command-apropos] picture-movement\" to see commands which control motio (move-to-column picture-desired-column t)) (let ((col (+ picture-desired-column width))) (or (eolp) - (let ((pos (point))) - (move-to-column col t) - (let ((old-width (string-width (buffer-substring pos (point))))) + (let ((pos (point)) + (col0 (current-column)) + col1) + (setq col1 (move-to-column col t)) + ;; We count columns, not width, because move-to-column + ;; could insert TABs, which width depends on horizontal + ;; position. + (let ((old-width (- (max col0 col1) (min col0 col1)))) (delete-region pos (point)) (when (> old-width width) (insert-char ? (- old-width width))