commit aefcccc1d411c973a3275959d7fa340d77f9157e (HEAD, refs/remotes/origin/master) Author: Jim Porter Date: Sat Jun 15 16:59:11 2024 -0700 Fix Eshell "which" test on MS-Windows * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/which/plain/external-program): Compare the file name case-insensitively on case-insensitive file systems. * test/lisp/eshell/eshell-tests-helpers.el (eshell-command-result--equal): Revert to the previous implementation. diff --git a/test/lisp/eshell/esh-cmd-tests.el b/test/lisp/eshell/esh-cmd-tests.el index 166a0ba1fff..70e1901c169 100644 --- a/test/lisp/eshell/esh-cmd-tests.el +++ b/test/lisp/eshell/esh-cmd-tests.el @@ -538,8 +538,16 @@ NAME is the name of the test case." (ert-deftest esh-cmd-test/which/plain/external-program () "Check that `which' finds external programs." (skip-unless (executable-find "sh")) - (eshell-command-result-equal "which sh" - (concat (executable-find "sh") "\n"))) + (ert-info (#'eshell-get-debug-logs :prefix "Command logs: ") + (let ((actual (eshell-test-command-result "which sh")) + (expected (concat (executable-find "sh") "\n"))) + ;; Eshell handles the casing of the PATH differently from + ;; `executable-find'. This means that the results may not match + ;; exactly on case-insensitive file systems (e.g. when using + ;; MS-Windows), so compare case-insensitively there. + (should (if (file-name-case-insensitive-p actual) + (string-equal-ignore-case actual expected) + (string-equal actual expected)))))) (ert-deftest esh-cmd-test/which/plain/not-found () "Check that `which' reports an error for not-found commands." diff --git a/test/lisp/eshell/eshell-tests-helpers.el b/test/lisp/eshell/eshell-tests-helpers.el index acbe57a7283..bfd829c95e9 100644 --- a/test/lisp/eshell/eshell-tests-helpers.el +++ b/test/lisp/eshell/eshell-tests-helpers.el @@ -179,12 +179,7 @@ inserting the command." (defun eshell-command-result--equal (_command actual expected) "Compare the ACTUAL result of a COMMAND with its EXPECTED value." - (or (equal actual expected) - ;; Compare case-isensitively on case-insensitive filesystems. - (and (memq system-type '(windows-nt ms-dos)) - (stringp actual) - (stringp expected) - (string-equal-ignore-case actual expected)))) + (equal actual expected)) (defun eshell-command-result--equal-explainer (command actual expected) "Explain the result of `eshell-command-result--equal'." commit 8d60b6bab8b95e4f3b350a8b093e8f60e3f83f69 Author: Po Lu Date: Sun Jun 16 11:35:44 2024 +0800 Simplify bitmap reallocation on Android * java/org/gnu/emacs/EmacsView.java: Update outdated commentary. (handleDirtyBitmap): Don't copy contents of the previous bitmap to the new. (onLayout): Unconditionally expose upon layout changes. diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 4a505b3c0dc..78d1ef785da 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java @@ -49,11 +49,13 @@ /* This is an Android view which has a back and front buffer. When swapBuffers is called, the back buffer is swapped to the front - buffer, and any damage is invalidated. frontBitmap and backBitmap - are modified and used both from the UI and the Emacs thread. As a - result, there is a lock held during all drawing operations. + buffer, and any damage is invalidated. A front buffer bitmap defined + in EmacsSurfaceView, and the write buffer in this file, are modified + and used both from the UI and the Emacs thread. As a result, there + is a lock held during all drawing operations. - It is also a ViewGroup, as it also lays out children. */ + It is also a ViewGroup, so that it may also manage the layout of its + children. */ public final class EmacsView extends ViewGroup implements ViewTreeObserver.OnGlobalLayoutListener @@ -204,19 +206,19 @@ public final class EmacsView extends ViewGroup rectangle ID. */ lastClipSerial = 0; - /* Copy over the contents of the old bitmap. */ - if (oldBitmap != null) - canvas.drawBitmap (oldBitmap, 0f, 0f, new Paint ()); - + /* Clear the bitmap reallocation flag. */ bitmapDirty = false; - /* Explicitly free the old bitmap's memory. */ - + /* Explicitly free the old bitmap's memory. The bitmap might + continue to be referenced by canvas or JNI objects returned by + getBitmap or getCanvas, but the underlying storage will not be + released until such references disappear. See + BitmapWrapper::freePixels in hwui/jni/Bitmap.cpp. */ if (oldBitmap != null) oldBitmap.recycle (); - /* Some Android versions still don't free the bitmap until the - next GC. */ + /* Some Android versions still refuse to release the bitmap until + the next GC. */ Runtime.getRuntime ().gc (); } @@ -367,13 +369,10 @@ else if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.AT_MOST if (changed) { + /* Expose the window upon a change in the view's size that + prompts the creation of a new bitmap. */ explicitlyDirtyBitmap (); - - /* Expose the window upon a change in the view's size. */ - - if (right - left > oldMeasuredWidth - || bottom - top > oldMeasuredHeight) - needExpose = true; + needExpose = true; /* This might return NULL if this view is not attached. */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) commit 3241d6cfbfeca48fbd5dc12dbf56c21688e9dce4 Author: Po Lu Date: Sun Jun 16 10:55:43 2024 +0800 Document unavailability of color fonts on Android * doc/emacs/android.texi (Android Fonts): Document absence of support for color fonts. diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi index 09b7762ed03..606c5e719cb 100644 --- a/doc/emacs/android.texi +++ b/doc/emacs/android.texi @@ -1038,10 +1038,10 @@ home directory. Emacs assumes there will always be a font named ``Droid Sans Mono'', and then defaults to using this font. These fonts are then displayed by the @code{sfnt-android} font driver. - This font driver is presently without support for OpenType fonts; -hence, only a subset of the fonts installed on any given system are -available to Emacs. If you are interested in lifting this limitation, -please contact @email{emacs-devel@@gnu.org}. + This font driver is presently without support for OpenType or color +fonts; hence, only a subset of the fonts installed on any given system +are available to Emacs. If you are interested in lifting this +limitation, please contact @email{emacs-devel@@gnu.org}. If the @code{sfnt-android} font driver fails to find any fonts at all, Emacs falls back to the @code{android} font driver. This is a commit 65b7f87a31da2e78285c5eb1ee2b2b38fc349361 Author: James Thomas Date: Tue Jun 11 03:00:33 2024 +0530 Account for duplicate removal on restoring eww-history-position * lisp/net/eww.el (eww-desktop-misc-data): Add :history-position (eww-restore-desktop): Use it. (desktop-locals-to-save): Remove the raw variable. diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 977210e9cc8..fd8f80065b1 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -2754,11 +2754,20 @@ Only the properties listed in `eww-desktop-data-save' are included. Generally, the list should not include the (usually overly large) :dom, :source and :text properties." (let ((history (mapcar #'eww-desktop-data-1 - (cons eww-data eww-history)))) - (list :history (if eww-desktop-remove-duplicates - (cl-remove-duplicates - history :test #'eww-desktop-history-duplicate) - history)))) + (cons eww-data eww-history))) + (posn eww-history-position) rval) + (list :history + (if eww-desktop-remove-duplicates + (prog1 + (setq + rval (cl-remove-duplicates + history :test #'eww-desktop-history-duplicate)) + (setq posn + (cl-position + (elt history eww-history-position) + rval :test #'eq))) + history) + :history-position posn))) (defun eww-restore-desktop (file-name buffer-name misc-data) "Restore an eww buffer from its desktop file record. @@ -2772,7 +2781,8 @@ Otherwise, the restored buffer will contain a prompt to do so by using (setq eww-history (cdr (plist-get misc-data :history)) eww-data (or (car (plist-get misc-data :history)) ;; backwards compatibility - (list :url (plist-get misc-data :uri)))) + (list :url (plist-get misc-data :uri))) + eww-history-position (plist-get misc-data :history-position)) (unless file-name (when (plist-get eww-data :url) (cl-case eww-restore-desktop @@ -2784,8 +2794,6 @@ Otherwise, the restored buffer will contain a prompt to do so by using ;; . (current-buffer))) -(add-to-list 'desktop-locals-to-save - 'eww-history-position) (add-to-list 'desktop-buffer-mode-handlers '(eww-mode . eww-restore-desktop)) commit 2c201bbba5c43328979bf139330684cacfa074f3 Author: Eli Zaretskii Date: Sat Jun 15 22:20:56 2024 +0300 Fix em-extpipe-tests on MS-Windows * test/lisp/eshell/em-extpipe-tests.el (em-extpipe-test-14): Fix test on MS-Windows (bug#71446). diff --git a/test/lisp/eshell/em-extpipe-tests.el b/test/lisp/eshell/em-extpipe-tests.el index 610e3d41524..c5f1301cd3b 100644 --- a/test/lisp/eshell/em-extpipe-tests.el +++ b/test/lisp/eshell/em-extpipe-tests.el @@ -181,7 +181,11 @@ (skip-unless (executable-find "tac")) (should-parse '(eshell-named-command "sh" (list "-c" "tac Date: Sat Jun 15 18:57:29 2024 +0200 Fix 'wrong-type-argument' in 'php-ts-mode--webserver-read-args' Prevents php-ts-mode--webserver-read-args from throwing an error if the current buffer is not associated with a file. * lisp/progmodes/php-ts-mode.el (php-ts-mode--webserver-read-args): Use 'default-directory if' the current buffer is not associated with a file. (Bug#71574) (php-ts-mode-run-php-webserver): Fix doc string. diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index f6b805f7e8e..64138db9dc8 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -1467,7 +1467,7 @@ for PORT, HOSTNAME, DOCUMENT-ROOT and ROUTER-SCRIPT." (derived-mode-add-parents 'php-ts-mode '(php-mode)) (defun php-ts-mode--webserver-read-args (&optional type) - "Helper for php-ts-mode-run-php-webserver. + "Helper for `php-ts-mode-run-php-webserver'. The optional TYPE can be the symbol \"port\", \"hostname\", \"document-root\" or \"router-script\", otherwise it requires all of them." (let ((ask-port (lambda () @@ -1477,11 +1477,15 @@ The optional TYPE can be the symbol \"port\", \"hostname\", \"document-root\" or (ask-document-root (lambda () (expand-file-name (read-directory-name "Document root: " - (file-name-directory (buffer-file-name)))))) + (file-name-directory + (or (buffer-file-name) + default-directory)))))) (ask-router-script (lambda () (expand-file-name (read-file-name "Router script: " - (file-name-directory (buffer-file-name))))))) + (file-name-directory + (or (buffer-file-name) + default-directory))))))) (cl-case type (port (funcall ask-port)) (hostname (funcall ask-hostname)) commit 0910f6fe3f701caa478d4aa08d9667316050b977 Author: Kyle Meyer Date: Sat Jun 15 14:25:35 2024 -0400 Update to Org 9.7.4-7-g165319 diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 32e56cba82c..edeb7d3ab6c 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -28,6 +28,15 @@ constant. If you still want to use python-mode with ob-python, you might consider [[https://gitlab.com/jackkamm/ob-python-mode-mode][ob-python-mode-mode]], where the code to support python-mode has been ported to. +*** It is no longer possible to reveal hidden parts of the links during isearch + +Org 9.6 introduced support for searching hidden parts of the links. + +Unfortunately, we had to drop this support because its implementation +turned out to be unreliable for many users. Proper implementation +would require patching =isearch.el= and possibly a number of external +libraries implementing isearch equivalents. It cannot be done on Org +side alone. *** =ox-latex=: ~org-latex-line-break-safe~ is deprecated @@ -1719,6 +1728,9 @@ to the Org behavior. The new features and changes are listed below. **** Hidden parts of the links can now be searched and revealed during isearch +[2024-06-09 Sun] Since Org 9.7, this is no longer working. See +changes for Org 9.7. + In the past, hidden parts of the links could not be searched using isearch (=C-s=). Now, they are searchable by default. The hidden match is also revealed temporarily during isearch. diff --git a/etc/refcards/orgcard.tex b/etc/refcards/orgcard.tex index 4d605fe7704..3967459fd81 100644 --- a/etc/refcards/orgcard.tex +++ b/etc/refcards/orgcard.tex @@ -1,5 +1,5 @@ % Reference Card for Org Mode -\def\orgversionnumber{9.7.3} +\def\orgversionnumber{9.7.4} \def\versionyear{2024} % latest update \input emacsver.tex diff --git a/lisp/org/ob-C.el b/lisp/org/ob-C.el index d13c65d260a..f7735ee72bb 100644 --- a/lisp/org/ob-C.el +++ b/lisp/org/ob-C.el @@ -482,7 +482,7 @@ int get_column_num (int nbcols, const char** header, const char* column) (defun org-babel-C-header-to-C (head type) "Convert an elisp list of header table into a C or D vector specifying a variable with the name of the table." - (message "%S" type) + (unless noninteractive (message "%S" type)) (let ((table (car head)) (headers (cdr head)) (typename (pcase type diff --git a/lisp/org/ob-awk.el b/lisp/org/ob-awk.el index 9577a39ee67..d94da405f0d 100644 --- a/lisp/org/ob-awk.el +++ b/lisp/org/ob-awk.el @@ -61,7 +61,7 @@ "Execute a block of Awk code BODY with org-babel. PARAMS is a plist of src block parameters . This function is called by `org-babel-execute-src-block'." - (message "Executing Awk source code block") + (unless noninteractive (message "Executing Awk source code block")) (let* ((result-params (cdr (assq :result-params params))) (cmd-line (cdr (assq :cmd-line params))) (in-file (cdr (assq :in-file params))) diff --git a/lisp/org/ob-clojure.el b/lisp/org/ob-clojure.el index 4a54acc51b3..c7ebbbb95e9 100644 --- a/lisp/org/ob-clojure.el +++ b/lisp/org/ob-clojure.el @@ -130,7 +130,7 @@ (defcustom ob-clojure-cli-command (when-let (cmd (executable-find "clojure")) (concat cmd " -M")) "Clojure CLI command used by the Clojure `clojure-cli' backend." - :type 'string + :type '(choice string (const nil)) :group 'org-babel :package-version '(Org . "9.7")) diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index d1984b2d6fe..db75f1f0ad5 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -855,8 +855,9 @@ guess will be made." (forward-line) (skip-chars-forward " \t") (let ((result (org-babel-read-result))) - (message (format "Cached: %s" - (replace-regexp-in-string "%" "%%" (format "%S" result)))) + (unless noninteractive + (message (format "Cached: %s" + (replace-regexp-in-string "%" "%%" (format "%S" result))))) result))) ((org-babel-confirm-evaluate info) (let* ((lang (nth 0 info)) @@ -879,21 +880,26 @@ guess will be made." result exec-start-time) (unless (fboundp cmd) (error "No org-babel-execute function for %s!" lang)) - (message "Executing %s %s %s..." - (capitalize lang) - (pcase executor-type - ('src-block "code block") - ('inline-src-block "inline code block") - ('babel-call "call") - ('inline-babel-call "inline call") - (e (symbol-name e))) - (let ((name (nth 4 info))) - (if name - (format "(%s)" name) - (format "at position %S" (nth 5 info))))) + (unless noninteractive + (message "Executing %s %s %s..." + (capitalize lang) + (pcase executor-type + ('src-block "code block") + ('inline-src-block "inline code block") + ('babel-call "call") + ('inline-babel-call "inline call") + (e (symbol-name e))) + (let ((name (nth 4 info))) + (if name + (format "(%s)" name) + (format "at position %S" (nth 5 info)))))) (setq exec-start-time (current-time) result - (let ((r (save-current-buffer (funcall cmd body params)))) + (let ((r + ;; Code block may move point in the buffer. + ;; Make sure that the point remains on the + ;; code block. + (save-excursion (funcall cmd body params)))) (if (and (eq (cdr (assq :result-type params)) 'value) (or (member "vector" result-params) (member "table" result-params)) @@ -2758,18 +2764,19 @@ INFO may provide the values of these header arguments (in the (not (and (listp result) (member "append" result-params)))) (indent-rigidly beg end indent)) - (let ((time-info - ;; Only show the time when something other than - ;; 0s will be shown, i.e. check if the time is at - ;; least half of the displayed precision. - (if (and exec-time (> (float-time exec-time) 0.05)) - (format " (took %.1fs)" (float-time exec-time)) - ""))) - (if (null result) - (if (member "value" result-params) - (message "Code block returned no value%s." time-info) - (message "Code block produced no output%s." time-info)) - (message "Code block evaluation complete%s." time-info)))) + (unless noninteractive + (let ((time-info + ;; Only show the time when something other than + ;; 0s will be shown, i.e. check if the time is at + ;; least half of the displayed precision. + (if (and exec-time (> (float-time exec-time) 0.05)) + (format " (took %.1fs)" (float-time exec-time)) + ""))) + (if (null result) + (if (member "value" result-params) + (message "Code block returned no value%s." time-info) + (message "Code block produced no output%s." time-info)) + (message "Code block evaluation complete%s." time-info))))) (when end (set-marker end nil)) (when outside-scope (narrow-to-region visible-beg visible-end)) (set-marker visible-beg nil) diff --git a/lisp/org/ob-ditaa.el b/lisp/org/ob-ditaa.el index ba8e65394f9..715d8ddf07e 100644 --- a/lisp/org/ob-ditaa.el +++ b/lisp/org/ob-ditaa.el @@ -113,8 +113,9 @@ This function is called by `org-babel-execute-src-block'." (unless (file-exists-p org-ditaa-jar-path) (error "Could not find ditaa.jar at %s" org-ditaa-jar-path)) (with-temp-file in-file (insert body)) - (message cmd) (shell-command cmd) - (when pdf-cmd (message pdf-cmd) (shell-command pdf-cmd)) + (unless noninteractive (message cmd)) + (shell-command cmd) + (when pdf-cmd (unless noninteractive (message pdf-cmd)) (shell-command pdf-cmd)) nil)) ;; signal that output has already been written to file (defun org-babel-prep-session:ditaa (_session _params) diff --git a/lisp/org/ob-exp.el b/lisp/org/ob-exp.el index 657cb2b5265..5516530c5b7 100644 --- a/lisp/org/ob-exp.el +++ b/lisp/org/ob-exp.el @@ -265,8 +265,9 @@ this template." (if (not (eq type 'babel-call)) (progn (skip-chars-forward " \t") (point)) - (skip-chars-forward " \r\t\n") - (line-beginning-position))))) + (unless (eobp) + (skip-chars-forward " \r\t\n") + (line-beginning-position)))))) ((not rep) ;; Replacement code cannot be determined. ;; Leave the code block as is. @@ -291,8 +292,9 @@ this template." (cond ((not replacement) (goto-char end)) ((equal replacement "") (goto-char end) - (skip-chars-forward " \r\t\n") - (forward-line 0) + (unless (eobp) + (skip-chars-forward " \r\t\n") + (forward-line 0)) (delete-region begin (point))) (t (if (org-src-preserve-indentation-p element) diff --git a/lisp/org/ob-gnuplot.el b/lisp/org/ob-gnuplot.el index dc5cd0e5217..956763c587e 100644 --- a/lisp/org/ob-gnuplot.el +++ b/lisp/org/ob-gnuplot.el @@ -210,7 +210,7 @@ This function is called by `org-babel-execute-src-block'." (let ((script-file (org-babel-temp-file "gnuplot-script-"))) (with-temp-file script-file (insert (concat body "\n"))) - (message "gnuplot \"%s\"" script-file) + (unless noninteractive (message "gnuplot \"%s\"" script-file)) (setq output (shell-command-to-string (format @@ -219,7 +219,7 @@ This function is called by `org-babel-execute-src-block'." script-file (if (member system-type '(cygwin windows-nt ms-dos)) t nil))))) - (message "%s" output)) + (unless noninteractive (message "%s" output))) (with-temp-buffer (insert (concat body "\n")) (gnuplot-mode) @@ -232,7 +232,7 @@ This function is called by `org-babel-execute-src-block'." "Prepare SESSION according to the header arguments in PARAMS." (let* ((session (org-babel-gnuplot-initiate-session session)) (var-lines (org-babel-variable-assignments:gnuplot params))) - (message "%S" session) + (unless noninteractive (message "%S" session)) (org-babel-comint-in-buffer session (dolist (var-line var-lines) (insert var-line) diff --git a/lisp/org/ob-groovy.el b/lisp/org/ob-groovy.el index 908df93372a..d87ef4bb657 100644 --- a/lisp/org/ob-groovy.el +++ b/lisp/org/ob-groovy.el @@ -52,7 +52,7 @@ parameters may be used, like groovy -v" (defun org-babel-execute:groovy (body params) "Execute Groovy BODY according to PARAMS. This function is called by `org-babel-execute-src-block'." - (message "Executing Groovy source code block") + (unless noninteractive (message "Executing Groovy source code block")) (let* ((processed-params (org-babel-process-params params)) (session (org-babel-groovy-initiate-session (nth 0 processed-params))) (result-params (nth 2 processed-params)) diff --git a/lisp/org/ob-lilypond.el b/lisp/org/ob-lilypond.el index 35df76fc964..a8d85ce7c85 100644 --- a/lisp/org/ob-lilypond.el +++ b/lisp/org/ob-lilypond.el @@ -41,7 +41,7 @@ (declare-function org-fold-show-all "org-fold" (&optional types)) (add-to-list 'org-babel-tangle-lang-exts '("LilyPond" . "ly")) -(add-to-list 'org-src-lang-modes '("lilypond" . "LilyPond")) +(add-to-list 'org-src-lang-modes '("lilypond" . LilyPond)) (defvar org-babel-default-header-args:lilypond '() "Default header arguments for lilypond code blocks. diff --git a/lisp/org/ob-maxima.el b/lisp/org/ob-maxima.el index ef875cfe8a9..681154adfbf 100644 --- a/lisp/org/ob-maxima.el +++ b/lisp/org/ob-maxima.el @@ -131,7 +131,7 @@ Return nil if LINE is zero-length or it matches a regexp in (defun org-babel-execute:maxima (body params) "Execute Maxima BODY according to PARAMS. This function is called by `org-babel-execute-src-block'." - (message "Executing Maxima source code block") + (unless noninteractive (message "Executing Maxima source code block")) (let ((result-params (split-string (or (cdr (assq :results params)) ""))) (result (let* ((cmdline (or (cdr (assq :cmdline params)) "")) @@ -151,7 +151,7 @@ This function is called by `org-babel-execute-src-block'." (format "(linenum:0, %s(%S))$" batch/load in-file)) cmdline))) (with-temp-file in-file (insert (org-babel-maxima-expand body params))) - (message cmd) + (unless noninteractive (message cmd)) ;; " | grep -v batch | grep -v 'replaced' | sed '/^$/d' " (let ((raw (org-babel-eval cmd ""))) (mapconcat diff --git a/lisp/org/ob-screen.el b/lisp/org/ob-screen.el index ffb66d65967..a56afc7050e 100644 --- a/lisp/org/ob-screen.el +++ b/lisp/org/ob-screen.el @@ -52,7 +52,7 @@ In case you want to use a different screen than one selected by your $PATH") (defun org-babel-execute:screen (body params) "Send BODY via screen to a terminal using Babel, according to PARAMS. \"default\" session is used when none is specified in the PARAMS." - (message "Sending source code block to interactive terminal session...") + (unless noninteractive (message "Sending source code block to interactive terminal session...")) (save-window-excursion (let* ((session (cdr (assq :session params))) (socket (org-babel-screen-session-socketname session))) diff --git a/lisp/org/ob-sed.el b/lisp/org/ob-sed.el index fa6a2bb199d..83d9684ade2 100644 --- a/lisp/org/ob-sed.el +++ b/lisp/org/ob-sed.el @@ -65,7 +65,7 @@ BODY is the source inside a sed source block and PARAMS is an association list over the source block configurations. This function is called by `org-babel-execute-src-block'." - (message "Executing sed source code block") + (unless noninteractive (message "Executing sed source code block")) (let* ((result-params (cdr (assq :result-params params))) (cmd-line (cdr (assq :cmd-line params))) (in-file (cdr (assq :in-file params))) diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el index 6603b5e017a..f10e36937d3 100644 --- a/lisp/org/org-capture.el +++ b/lisp/org/org-capture.el @@ -408,8 +408,7 @@ you can escape ambiguous cases with a backward slash, e.g., \\%i." (let ((file-variants '(choice :tag "Filename " (file :tag "Literal") (function :tag "Function") - (variable :tag "Variable") - (sexp :tag "Form")))) + (variable :tag "Variable")))) `(repeat (choice :value ("" "" entry (file "~/org/notes.org") "") (list :tag "Multikey description" @@ -452,12 +451,12 @@ you can escape ambiguous cases with a backward slash, e.g., \\%i." (list :tag "File & function" (const :format "" file+function) ,file-variants - (sexp :tag " Function")) + (function :tag " Function")) (list :tag "Current clocking task" (const :format "" clock)) (list :tag "Function" (const :format "" function) - (sexp :tag " Function"))) + (function :tag " Function"))) (choice :tag "Template " (string) (list :tag "File" diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el index 5555bb1bc3d..c6fd507b08b 100644 --- a/lisp/org/org-clock.el +++ b/lisp/org/org-clock.el @@ -2048,28 +2048,31 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes." (cond ((and (eq element-type 'clock) (match-end 2)) ;; Two time stamps. - (let* ((timestamp (org-element-property :value element)) - (ts (float-time - (org-encode-time - (list 0 - (org-element-property :minute-start timestamp) - (org-element-property :hour-start timestamp) - (org-element-property :day-start timestamp) - (org-element-property :month-start timestamp) - (org-element-property :year-start timestamp) - nil -1 nil)))) - (te (float-time - (org-encode-time - (list 0 - (org-element-property :minute-end timestamp) - (org-element-property :hour-end timestamp) - (org-element-property :day-end timestamp) - (org-element-property :month-end timestamp) - (org-element-property :year-end timestamp) - nil -1 nil)))) - (dt (- (if tend (min te tend) te) - (if tstart (max ts tstart) ts)))) - (when (> dt 0) (cl-incf t1 (floor dt 60))))) + (condition-case nil + (let* ((timestamp (org-element-property :value element)) + (ts (float-time + (org-encode-time + (list 0 + (org-element-property :minute-start timestamp) + (org-element-property :hour-start timestamp) + (org-element-property :day-start timestamp) + (org-element-property :month-start timestamp) + (org-element-property :year-start timestamp) + nil -1 nil)))) + (te (float-time + (org-encode-time + (list 0 + (org-element-property :minute-end timestamp) + (org-element-property :hour-end timestamp) + (org-element-property :day-end timestamp) + (org-element-property :month-end timestamp) + (org-element-property :year-end timestamp) + nil -1 nil)))) + (dt (- (if tend (min te tend) te) + (if tstart (max ts tstart) ts)))) + (when (> dt 0) (cl-incf t1 (floor dt 60)))) + (error + (org-display-warning (format "org-clock-sum: Ignoring invalid %s" (org-current-line-string)))))) ((match-end 4) ;; A naked time. (setq t1 (+ t1 (string-to-number (match-string 5)) diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el index d6620f9627f..41c26ad72fe 100644 --- a/lisp/org/org-compat.el +++ b/lisp/org/org-compat.el @@ -251,6 +251,17 @@ removed." default))) ": "))) +(if (fboundp 'list-of-strings-p) + (defalias 'org-list-of-strings-p #'list-of-strings-p) + ;; From Emacs subr.el. +;;;###autoload + (defun org-list-of-strings-p (object) + "Return t if OBJECT is nil or a list of strings." + (declare (pure t) (side-effect-free error-free)) + (while (and (consp object) (stringp (car object))) + (setq object (cdr object))) + (null object))) + ;;; Emacs < 27.1 compatibility diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el index b15f0b69d98..191bb5698d1 100644 --- a/lisp/org/org-element.el +++ b/lisp/org/org-element.el @@ -1188,7 +1188,7 @@ parse properties for property drawer at point." (property-name-symbol (intern property-name)) (property-value (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring (- (match-beginning 3) begin) (- (match-end 3) begin)))) (cond @@ -1355,7 +1355,7 @@ Throw `:org-element-deferred-retry' signal at the end." (title-end (point)) (raw-value (org-element-deferred-create - nil #'org-element--headline-raw-value + t #'org-element--headline-raw-value (- title-start begin) (- title-end begin)))) (org-element-put-property headline :raw-value raw-value) (org-element-put-property headline :level level) @@ -1386,12 +1386,12 @@ Throw `:org-element-deferred-retry' signal at the end." (defconst org-element--headline-parse-title-raw (org-element-deferred-create - nil #'org-element--headline-parse-title t) + t #'org-element--headline-parse-title t) "Constant holding deferred value for raw headline `:title' property.") (defconst org-element--headline-parse-title-parse (org-element-deferred-create - nil #'org-element--headline-parse-title nil) + t #'org-element--headline-parse-title nil) "Constant holding deferred value for parsed headline `:title' property.") (defconst org-element--headline-deferred @@ -2414,7 +2414,7 @@ Assume point is at comment block beginning." (if (eobp) (point) (line-beginning-position)))) (value (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring (- contents-begin begin) (- contents-end begin)))) (org-element-create @@ -2532,7 +2532,7 @@ Return a new syntax node of `example-block' type containing `:begin', (contents-begin (line-beginning-position 2)) (value (org-element-deferred-create - nil #'org-element--unescape-substring + t #'org-element--unescape-substring (- contents-begin begin) (- contents-end begin))) (pos-before-blank (progn (goto-char contents-end) @@ -2612,7 +2612,7 @@ Assume point is at export-block beginning." (if (eobp) (point) (line-beginning-position)))) (value (org-element-deferred-create - nil #'org-element--unescape-substring + t #'org-element--unescape-substring (- contents-begin begin) (- contents-end begin)))) (org-element-create @@ -2800,7 +2800,7 @@ Assume point is at the beginning of the latex environment." (begin (car affiliated)) (value (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring (- code-begin begin) (- code-end begin))) (end (progn (skip-chars-forward " \r\t\n" limit) @@ -3059,7 +3059,7 @@ Assume point is at the beginning of the block." ;; Retrieve code. (value (org-element-deferred-create - nil #'org-element--unescape-substring + t #'org-element--unescape-substring (- (line-beginning-position 2) begin) (- contents-end begin))) (pos-before-blank (progn (goto-char contents-end) @@ -3159,7 +3159,7 @@ Assume point is at the beginning of the table." :contents-end (and (eq type 'org) table-end) :value (and (eq type 'table.el) (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring (- table-begin begin) (- table-end begin))) :post-blank (count-lines pos-before-blank end) @@ -3322,7 +3322,7 @@ Assume point is at first MARK." (list :value (and (memq type '(code verbatim)) (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring (- contents-begin origin) (- contents-end origin)))) (list :contents-begin contents-begin @@ -3572,7 +3572,7 @@ Assume point is at the beginning of the snippet." (value (when contents-end (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring (- contents-begin begin) (- contents-end begin)))) (post-blank (skip-chars-forward " \t")) @@ -3667,7 +3667,7 @@ Assume point is at the beginning of the babel call." (replace-regexp-in-string "\n[ \t]*" " " (org-trim p))))) (value (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring 0 (- (point) begin))) (post-blank (skip-chars-forward " \t")) (end (point))) @@ -3801,7 +3801,7 @@ Assume point is at the beginning of the LaTeX fragment." 'latex-fragment (list :value (org-element-deferred-create - nil #'org-element--substring + t #'org-element--substring 0 (- after-fragment begin)) :begin begin :end end diff --git a/lisp/org/org-fold-core.el b/lisp/org/org-fold-core.el index 664846a619c..8372b86b087 100644 --- a/lisp/org/org-fold-core.el +++ b/lisp/org/org-fold-core.el @@ -641,13 +641,14 @@ This function is mostly intended to be used in `clone-indirect-buffer-hook'." ;; Add current buffer to the list of indirect buffers in the base buffer. (when (buffer-base-buffer) - (with-current-buffer (buffer-base-buffer) - (setq-local org-fold-core--indirect-buffers - (let (bufs) - (org-fold-core-cycle-over-indirect-buffers - (push (current-buffer) bufs)) - (push (current-buffer) bufs) - (delete-dups bufs))))) + (let ((new-buffer (current-buffer))) + (with-current-buffer (buffer-base-buffer) + (setq-local org-fold-core--indirect-buffers + (let (bufs) + (org-fold-core-cycle-over-indirect-buffers + (push (current-buffer) bufs)) + (push new-buffer bufs) + (delete-dups bufs)))))) (when (and (buffer-base-buffer) (eq org-fold-core-style 'text-properties) (not (memql 'ignore-indirect org-fold-core--optimise-for-huge-buffers))) diff --git a/lisp/org/org-lint.el b/lisp/org/org-lint.el index aed774ee2de..2d87ae270c4 100644 --- a/lisp/org/org-lint.el +++ b/lisp/org/org-lint.el @@ -388,14 +388,24 @@ called with one argument, the key used for comparison." (dolist (e originals reports) (funcall make-report (cdr e) (car e))))) (defun org-lint-misplaced-heading (ast) - "Check for accidentally misplaced heading lines." + "Check for accidentally misplaced heading lines. +Example: +** Heading 1 +** Heading 2** Oops heading 3 +** Heading 4" (org-with-point-at ast (goto-char (point-min)) (let (result) ;; Heuristics for 2+ level heading not at bol. (while (re-search-forward (rx (not (any "*\n\r ,")) ;; Not a bol; not escaped ,** heading; not " *** words" "*" (1+ "*") " ") nil t) - (unless (org-at-block-p) ; Inside a block, where the chances to have heading a slim. + ;; Limit false-positive rate by only complaining about + ;; ** Heading** Heading and + ;; ** Oops heading + ;; Paragraph** Oops heading + (when (org-element-type-p + (org-element-at-point) + '(paragraph headline)) (push (list (match-beginning 0) "Possibly misplaced heading line") result))) result))) diff --git a/lisp/org/org-num.el b/lisp/org/org-num.el index aebfef05079..a8fcf333361 100644 --- a/lisp/org/org-num.el +++ b/lisp/org/org-num.el @@ -144,7 +144,7 @@ control tag inheritance." :group 'org-appearance :package-version '(Org . "9.3") :type '(repeat (string :tag "Tag")) - :safe (lambda (val) (and (listp val) (cl-every #'stringp val)))) + :safe #'org-list-of-strings-p) ;;;###autoload (defcustom org-num-skip-unnumbered nil diff --git a/lisp/org/org-persist.el b/lisp/org/org-persist.el index c855c6604ba..52f4b0eef27 100644 --- a/lisp/org/org-persist.el +++ b/lisp/org/org-persist.el @@ -416,7 +416,7 @@ FORMAT and ARGS are passed to `message'." (defun org-persist--read-elisp-file (&optional buffer-or-file) "Read elisp data from BUFFER-OR-FILE or current buffer." (let (;; UTF-8 is explicitly used in `org-persist--write-elisp-file'. - (coding-system-for-read 'utf-8) + (coding-system-for-read 'emacs-internal) (buffer-or-file (or buffer-or-file (current-buffer)))) (with-temp-buffer (if (bufferp buffer-or-file) @@ -464,7 +464,7 @@ FORMAT and ARGS are passed to `message'." (let ((write-region-inhibit-fsync t) ;; We set UTF-8 here and in `org-persist--read-elisp-file' ;; to avoid the overhead from `find-auto-coding'. - (coding-system-for-write 'utf-8) + (coding-system-for-write 'emacs-internal) (print-circle (not no-circular)) print-level print-length diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el index d152fbfe8b1..262bd462814 100644 --- a/lisp/org/org-src.el +++ b/lisp/org/org-src.el @@ -241,8 +241,8 @@ but the mode to use is `tuareg-mode'." :package-version '(Org . "9.7") :type '(repeat (cons - (string "Language name") - (symbol "Major mode")))) + (string :tag "Language name") + (symbol :tag "Major mode")))) (defcustom org-src-block-faces nil "Alist of faces to be used for source-block. diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 37ce91570d2..4a2623b5538 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -5477,14 +5477,16 @@ a radio table." (goto-char (org-table-begin)) (let (rtn) (forward-line -1) - (while (looking-at "[ \t]*#\\+ORGTBL[: \t][ \t]*SEND[ \t]+\\([^ \t\r\n]+\\)[ \t]+\\([^ \t\r\n]+\\)\\([ \t]+.*\\)?") - (let ((name (org-no-properties (match-string 1))) - (transform (intern (match-string 2))) - (params (if (match-end 3) - (read (concat "(" (match-string 3) ")"))))) - (push (list :name name :transform transform :params params) - rtn) - (forward-line -1))) + (catch :bob + (while (looking-at "[ \t]*#\\+ORGTBL[: \t][ \t]*SEND[ \t]+\\([^ \t\r\n]+\\)[ \t]+\\([^ \t\r\n]+\\)\\([ \t]+.*\\)?") + (let ((name (org-no-properties (match-string 1))) + (transform (intern (match-string 2))) + (params (if (match-end 3) + (read (concat "(" (match-string 3) ")"))))) + (push (list :name name :transform transform :params params) + rtn) + (when (bobp) (throw :bob nil)) + (forward-line -1)))) rtn))) (defun orgtbl-send-replace-tbl (name text) diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index 4697e39a8dd..6bef3101bbe 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -5,13 +5,13 @@ (defun org-release () "The release version of Org. Inserted by installing Org mode or when a release is made." - (let ((org-release "9.7.3")) + (let ((org-release "9.7.4")) org-release)) ;;;###autoload (defun org-git-version () "The Git version of Org mode. Inserted by installing Org or when a release is made." - (let ((org-git-version "release_9.7.3")) + (let ((org-git-version "release_9.7.4-7-g165319")) org-git-version)) (provide 'org-version) diff --git a/lisp/org/org.el b/lisp/org/org.el index ff5b63212e0..2be404e368e 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -9,7 +9,7 @@ ;; URL: https://orgmode.org ;; Package-Requires: ((emacs "26.1")) -;; Version: 9.7.3 +;; Version: 9.7.4 ;; This file is part of GNU Emacs. ;; @@ -16981,10 +16981,11 @@ buffer boundaries with possible narrowing." (t nil)))) (defun org-image--align (link) - "Determine the alignment of the image link. + "Determine the alignment of the image LINK. +LINK is a link object. In decreasing order of priority, this is controlled: -- Per image by the value of `:center' or ``:align' in the +- Per image by the value of `:center' or `:align' in the affiliated keyword `#+attr_org'. - By the `#+attr_html' or `#+attr_latex` keywords with valid `:center' or `:align' values. @@ -16998,15 +16999,16 @@ will cause it to be right-aligned. A value of \"left\" or nil implies no special alignment." (let ((par (org-element-lineage link 'paragraph))) ;; Only align when image is not surrounded by paragraph text: - (when (and (= (org-element-begin link) + (when (and par ; when image is not in paragraph, but in table/headline/etc, do not align + (= (org-element-begin link) (save-excursion (goto-char (org-element-contents-begin par)) (skip-chars-forward "\t ") (point))) ;account for leading space ;before link (<= (- (org-element-contents-end par) - (org-element-end link)) - 1)) ;account for trailing newline + (org-element-end link)) + 1)) ;account for trailing newline ;at end of paragraph (save-match-data ;; Look for a valid ":center t" or ":align left|center|right" @@ -20871,11 +20873,25 @@ When nil, use `org-attach-method'." (defvar org-attach-method) (defun org--dnd-rmc (prompt choices) + "Display a menu or dialog and select with PROMPT among CHOICES. +PROMPT is the prompt string. CHOICES is a list of choices. Each +choice is a list of (key description value). VALUE from the selected +choice is returned." (if (null (and ;; Emacs <=28 does not have `use-dialog-box-p'. (fboundp 'use-dialog-box-p) (use-dialog-box-p))) - (caddr (read-multiple-choice prompt choices)) + (progn + (setq choices + (mapcar + (pcase-lambda (`(,key ,message ,val)) + ;; `read-multiple-choice' expects VAL to be a long + ;; description of the choice - string or nil. Move VAL + ;; further, so that it is not seen by the extended + ;; help in `read-multiple-choice'. + (list key message nil val)) + choices)) + (nth 3 (read-multiple-choice prompt choices))) (setq choices (mapcar (pcase-lambda (`(_key ,message ,val)) @@ -20939,15 +20955,18 @@ SEPARATOR is the string to insert after each link." ('private (or org-yank-dnd-default-attach-method org-attach-method))))) (if separatep - (funcall - (pcase method - ('cp #'copy-file) - ('mv #'rename-file) - ('ln #'add-name-to-file) - ('lns #'make-symbolic-link)) - filename - (expand-file-name (file-name-nondirectory filename) - org-yank-image-save-method)) + (progn + (unless (file-directory-p org-yank-image-save-method) + (make-directory org-yank-image-save-method t)) + (funcall + (pcase method + ('cp #'copy-file) + ('mv #'rename-file) + ('ln #'add-name-to-file) + ('lns #'make-symbolic-link)) + filename + (expand-file-name (file-name-nondirectory filename) + org-yank-image-save-method))) (org-attach-attach filename nil method)) (insert (org-link-make-string diff --git a/lisp/org/ox.el b/lisp/org/ox.el index 1c52ca2905e..35bbf84a0ca 100644 --- a/lisp/org/ox.el +++ b/lisp/org/ox.el @@ -1398,8 +1398,7 @@ external parameters overriding Org default settings, but still inferior to file-local settings." ;; First install #+BIND variables since these must be set before ;; global options are read. - (dolist (pair (org-export--list-bound-variables)) - (set (make-local-variable (car pair)) (nth 1 pair))) + (org-export--set-variables (org-export--list-bound-variables)) ;; Get and prioritize export options... (org-combine-plists ;; ... from global variables... @@ -2585,7 +2584,7 @@ Return the updated communication channel." (defun org-export--set-variables (variable-alist) "Set buffer-local variables according to VARIABLE-ALIST in current buffer." (pcase-dolist (`(,var . ,val) variable-alist) - (set (make-local-variable var) val))) + (set (make-local-variable var) (car val)))) (cl-defun org-export-copy-buffer (&key to-buffer drop-visibility drop-narrowing drop-contents @@ -6672,7 +6671,7 @@ and `org-export-to-file' for more specialized functions." (with-temp-message "Initializing asynchronous export process" (let ((copy-fun (org-element--generate-copy-script (current-buffer))) (temp-file (make-temp-file "org-export-process"))) - (let ((coding-system-for-write 'utf-8-emacs-unix)) + (let ((coding-system-for-write 'emacs-internal)) (write-region ;; Null characters (from variable values) are inserted ;; within the file. As a consequence, coding system for commit 03ad06737bd229a731ee1d36e245daf34fd7a73b Author: Jim Porter Date: Sat Jun 15 11:27:07 2024 -0700 ; Improve last change * test/lisp/eshell/esh-proc-tests.el (esh-proc-test/kill-pipeline): Fix check of exit message and ensure we have only one prompt. diff --git a/test/lisp/eshell/esh-proc-tests.el b/test/lisp/eshell/esh-proc-tests.el index 68945cb5b0a..643cb8b125a 100644 --- a/test/lisp/eshell/esh-proc-tests.el +++ b/test/lisp/eshell/esh-proc-tests.el @@ -23,6 +23,7 @@ (require 'ert) (require 'esh-mode) (require 'eshell) +(require 'em-prompt) ; For `eshell-previous-prompt' (require 'eshell-tests-helpers (expand-file-name "eshell-tests-helpers" @@ -297,11 +298,17 @@ prompt. See bug#54136." (let ((output-start (eshell-beginning-of-output))) (eshell-kill-process) (eshell-wait-for-subprocess t) + ;; We expect at most one exit message here (from the tail + ;; process). If the tail process has time to exit normally + ;; after we kill the head, then we'll see no exit message. (should (string-match-p - ;; "interrupt" is for MS-Windows. - (rx bos (or "interrupt" "killed" "killed: 9" "") eol) + (rx bos (? (or "interrupt" (seq "killed" (* nonl))) "\n") eos) (buffer-substring-no-properties - output-start (eshell-end-of-output)))))))) + output-start (eshell-end-of-output)))) + ;; Make sure Eshell only emitted one prompt by going back one + ;; prompt and checking the command input. + (eshell-previous-prompt) + (should (string-prefix-p "sh -c" (field-string))))))) (ert-deftest esh-proc-test/kill-pipeline-head () "Test that killing the first process in a pipeline doesn't commit 7df855cdfe617614dbe23fb0302a647ee23589ea Author: Jim Porter Date: Sat Jun 15 11:06:58 2024 -0700 ; Add command logging to some more Eshell tests * test/lisp/eshell/esh-proc-tests.el (esh-proc-test/kill-pipeline) (esh-proc-test/kill-pipeline-head): Write debug logs on failure. diff --git a/test/lisp/eshell/esh-proc-tests.el b/test/lisp/eshell/esh-proc-tests.el index bb78f1786dd..68945cb5b0a 100644 --- a/test/lisp/eshell/esh-proc-tests.el +++ b/test/lisp/eshell/esh-proc-tests.el @@ -290,17 +290,18 @@ prompt. See bug#54136." ;; fine elsewhere. (skip-when (getenv "EMACS_EMBA_CI")) (with-temp-eshell - (eshell-insert-command - (concat "sh -c 'while true; do echo y; sleep 1; done' | " - "sh -c 'while true; do read NAME; done'")) - (let ((output-start (eshell-beginning-of-output))) - (eshell-kill-process) - (eshell-wait-for-subprocess t) - (should (string-match-p - ;; "interrupt\n" is for MS-Windows. - (rx (or "interrupt\n" "killed\n" "killed: 9\n" "")) - (buffer-substring-no-properties - output-start (eshell-end-of-output))))))) + (ert-info (#'eshell-get-debug-logs :prefix "Command logs: ") + (eshell-insert-command + (concat "sh -c 'while true; do echo y; sleep 1; done' | " + "sh -c 'while true; do read NAME; done'")) + (let ((output-start (eshell-beginning-of-output))) + (eshell-kill-process) + (eshell-wait-for-subprocess t) + (should (string-match-p + ;; "interrupt" is for MS-Windows. + (rx bos (or "interrupt" "killed" "killed: 9" "") eol) + (buffer-substring-no-properties + output-start (eshell-end-of-output)))))))) (ert-deftest esh-proc-test/kill-pipeline-head () "Test that killing the first process in a pipeline doesn't @@ -309,15 +310,16 @@ write the exit status to the pipe. See bug#54136." (executable-find "echo") (executable-find "sleep"))) (with-temp-eshell - (eshell-insert-command - (concat "sh -c 'while true; do sleep 1; done' | " - "sh -c 'while read NAME; do echo =${NAME}=; done'")) - (let ((output-start (eshell-beginning-of-output))) - (kill-process (eshell-head-process)) - (eshell-wait-for-subprocess t) - (should (equal (buffer-substring-no-properties - output-start (eshell-end-of-output)) - ""))))) + (ert-info (#'eshell-get-debug-logs :prefix "Command logs: ") + (eshell-insert-command + (concat "sh -c 'while true; do sleep 1; done' | " + "sh -c 'while read NAME; do echo =${NAME}=; done'")) + (let ((output-start (eshell-beginning-of-output))) + (kill-process (eshell-head-process)) + (eshell-wait-for-subprocess t) + (should (equal (buffer-substring-no-properties + output-start (eshell-end-of-output)) + "")))))) ;; Remote processes commit 1bc093e33cb60eb85efe6a61d42d7ea58b40fa57 Merge: 9b2e1b5e16c 59261e6f4fe Author: Eli Zaretskii Date: Sat Jun 15 13:06:09 2024 -0400 Merge from origin/emacs-29 59261e6f4fe Fix auth-info-password 778f8c793d1 ; * lisp/mail/rmail.el (rmail-get-new-mail-hook): Doc fix. e6044b29e65 ; Minor fixes in ELisp manual commit 9b2e1b5e16c233cf5ea039e17175580793a4e5ef Author: Eli Zaretskii Date: Sat Jun 15 20:03:39 2024 +0300 Avoid byte-compilation warnings in php-ts-mode * lisp/progmodes/php-ts-mode.el (treesit-search-forward) (treesit-node-prev-sibling, treesit-node-first-child-for-pos): Declare. diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index fc029a17120..f6b805f7e8e 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -76,6 +76,9 @@ (declare-function treesit-parser-included-ranges "treesit.c") (declare-function treesit-parser-list "treesit.c") (declare-function treesit-parser-language "treesit.c") +(declare-function treesit-search-forward "treesit.c") +(declare-function treesit-node-prev-sibling "treesit.c") +(declare-function treesit-node-first-child-for-pos "treesit.c") ;;; Install treesitter language parsers (defvar php-ts-mode--language-source-alist commit 83182b2c4a4e039884ee54ddce6e657f4fb888eb Author: Eshel Yaron Date: Sat Jun 15 18:48:34 2024 +0200 Honor 'Info-additional-directory-list' in 'C-h R' completion * lisp/info.el (info--manual-names): Take into account 'Info-additional-directory-list', in addition to 'Info-directory-list'. (Bug#71368) diff --git a/lisp/info.el b/lisp/info.el index c2c393cb243..d151c6365b8 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -5675,7 +5675,9 @@ completion alternatives to currently visited manuals." (all-completions "" (apply-partially #'Info-read-node-name-2 - Info-directory-list + (append + Info-directory-list + Info-additional-directory-list) (mapcar #'car Info-suffix-list)))))))) (provide 'info) commit 2d67ea86320c6adbb95a1a94a47037cb3d62dec1 Author: Eli Zaretskii Date: Sat Jun 15 19:47:44 2024 +0300 ; * doc/emacs/package.texi (Package Files): Fix wording. diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index fd445805068..22d91b6dbe1 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -566,7 +566,7 @@ the command @kbd{M-x package-install-file}. @vindex package-user-dir Once installed, the contents of a package are placed in a subdirectory of @file{~/.emacs.d/elpa/} (you can change the name of -that directory by changing the variable @code{package-user-dir}). The +that directory by customizing the variable @code{package-user-dir}). The package subdirectory is named @file{@var{name}-@var{version}}, where @var{name} is the package name and @var{version} is its version string. commit 9e8c0ec9918af12aafa1063ad3bc3f9f1d180e6f Author: Eli Zaretskii Date: Sat Jun 15 16:20:01 2024 +0300 Fix problem with recently-added defcustom's * lisp/progmodes/php-ts-mode.el (php-ts-mode-php-config) (php-ts-mode-ws-port, php-ts-mode-ws-document-root) (php-ts-mode-ws-workers): Fix :type and :safe attributes. (Bug#71566) diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index 6a576d9c7c5..fc029a17120 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -130,7 +130,7 @@ If nil the default one is used to run the embedded webserver or inferior PHP process." :tag "PHP Init file" :version "30.1" - :type 'file) + :type '(choice (const :tag "Default init file" nil) file)) (defcustom php-ts-mode-ws-hostname "localhost" "The hostname that will be served by the PHP built-in webserver. @@ -146,23 +146,23 @@ See `https://www.php.net/manual/en/features.commandline.webserver.php'." If nil `php-ts-mode-run-php-webserver' will ask you for the port number." :tag "PHP built-in web server port" :version "30.1" - :type 'integer - :safe 'integerp) + :type '(choice (const :tag "Ask which port to use" nil) integer) + :safe 'integer-or-null-p) (defcustom php-ts-mode-ws-document-root nil "The root of the documents that the PHP built-in webserver will serve. If nil `php-ts-mode-run-php-webserver' will ask you for the document root." :tag "PHP built-in web server document root" :version "30.1" - :type 'directory) + :type '(choice (const :tag "Ask for document root" nil) directory)) (defcustom php-ts-mode-ws-workers nil "The number of workers the PHP built-in webserver will fork. Useful for testing code against multiple simultaneous requests." :tag "PHP built-in number of workers" :version "30.1" - :type 'integer - :safe 'integerp) + :type '(choice (const :tag "No workers" nil) integer) + :safe 'integer-or-null-p) (defcustom php-ts-mode-inferior-php-buffer "*PHP*" "Name of the inferior PHP buffer." diff --git a/lisp/subr.el b/lisp/subr.el index e478c0e3349..ab388630a91 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4460,6 +4460,12 @@ or byte-code." (or (and (subrp object) (not (eq 'unevalled (cdr (subr-arity object))))) (byte-code-function-p object))) +(defun integer-or-null-p (object) + "Return non-nil if OBJECT is either an integer or nil. +Otherwise, return nil." + (declare (pure t) (side-effect-free error-free)) + (or (integerp object) (null object))) + (defun field-at-pos (pos) "Return the field at position POS, taking stickiness etc into account." (declare (important-return-value t)) commit 2cbea4f35cbfb25f53f23ebba81ffe89ce77b136 Author: Eli Zaretskii Date: Sat Jun 15 15:59:55 2024 +0300 Better documentation of 'emacs-internal' encoding * doc/lispref/nonascii.texi (Coding System Basics): Recommend 'emacs-internal' encoding for caching. diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi index 9a160ba0730..1c5cc0e20b4 100644 --- a/doc/lispref/nonascii.texi +++ b/doc/lispref/nonascii.texi @@ -1135,7 +1135,10 @@ conversion happens, but different in that the result is multibyte data. The name @code{emacs-internal} is an alias for @code{utf-8-emacs-unix} (so it forces no conversion of end-of-line, unlike @code{utf-8-emacs}, which can decode all 3 kinds of -end-of-line conventions). +end-of-line conventions). Since this coding system can represent all +the characters supported by Emacs in its buffers and strings, we +recommend using it whenever saving text for internal purposes, such as +caching. @defun coding-system-get coding-system property This function returns the specified property of the coding system commit d802e56182042e32a56ef8515f9ef01c0633be1e Author: Eli Zaretskii Date: Sat Jun 15 15:02:11 2024 +0300 ; * lisp/textmodes/ispell.el (ispell-aspell-find-dictionary): Doc fix. diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 607322b29a9..caf59995c01 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -859,9 +859,9 @@ Assumes that value contains no whitespace." (car (split-string (buffer-string))))) (defun ispell-aspell-find-dictionary (dict-name) - "For Aspell dictionary DICT-NAME, return a list of parameters. + "Return the list of parameters for an Aspell dictionary DICT-NAME. List format is that of `ispell-dictionary-base-alist' elements. Return -nil if no associated data file is found." +nil if no associated data file is found for the dictionary." ;; Make sure `ispell-aspell-dict-dir' is defined (or ispell-aspell-dict-dir (setq ispell-aspell-dict-dir commit d05f473285de734fd1a30a7ee69f36303d5ecb7c Author: Arash Esbati Date: Thu Jun 13 11:46:09 2024 +0200 ; Fix some docstrings. (bug#71532) diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 67be936ca24..607322b29a9 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -219,8 +219,9 @@ This is also used by `ispell-lookup-words' and `ispell-complete-word'." :type '(choice file (const :tag "None" nil))) (defcustom ispell-complete-word-dict nil - "Plain word-list dictionary used for word completion if -different from `ispell-alternate-dictionary'. + "Plain word-list dictionary used for word completion. +This word-list is used if it is different from +`ispell-alternate-dictionary'. This is also used by `ispell-lookup-words' and `ispell-complete-word'." :type '(choice file (const :tag "None" nil))) @@ -639,8 +640,8 @@ this would require some extra guessing in `ispell-aspell-find-dictionary'.") ("slovenian" "sl_SI") ("svenska" "sv_SE") ("hebrew" "he_IL")) - "Alist with known matching locales for standard dict names in -`ispell-dictionary-base-alist'.") + "Alist with known matching locales for standard dict names. +Standard dict names are defined in `ispell-dictionary-base-alist'.") ;;; ********************************************************************** @@ -759,14 +760,16 @@ Otherwise return the library directory name, if that is defined." ,@body)) (defun ispell-call-process (&rest args) - "Like `call-process', but defend against bad `default-directory'." + "Like `call-process', but defend against bad `default-directory'. +ARGS are passed to `call-process'." (ispell-with-safe-default-directory - (apply 'call-process args))) + (apply #'call-process args))) (defun ispell-call-process-region (&rest args) - "Like `call-process-region', but defend against bad `default-directory'." + "Like `call-process-region', but defend against bad `default-directory'. +ARGS are passed to `call-process'." (ispell-with-safe-default-directory - (apply 'call-process-region args))) + (apply #'call-process-region args))) (defvar ispell-debug-buffer) @@ -856,10 +859,9 @@ Assumes that value contains no whitespace." (car (split-string (buffer-string))))) (defun ispell-aspell-find-dictionary (dict-name) - "For Aspell dictionary DICT-NAME, return a list of parameters if an -associated data file is found or nil otherwise. List format is that -of `ispell-dictionary-base-alist' elements." - + "For Aspell dictionary DICT-NAME, return a list of parameters. +List format is that of `ispell-dictionary-base-alist' elements. Return +nil if no associated data file is found." ;; Make sure `ispell-aspell-dict-dir' is defined (or ispell-aspell-dict-dir (setq ispell-aspell-dict-dir @@ -1614,8 +1616,8 @@ a `~' followed by an extended-character mode -- such as `~.tex'. The last occurring definition in the buffer will be used.") (defun ispell--\\w-filter (char) - "Return CHAR in a string when CHAR doesn't have \"word\" syntax, -nil otherwise. CHAR must be a character." + "Return CHAR as a string when CHAR doesn't have \"word\" syntax. +CHAR must be a valid character. Return nil otherwise." (let ((str (string char))) (and (not (string-match "\\w" str)) @@ -3891,7 +3893,8 @@ Otherwise, it must be a function which is called to get the limit.") (defun ispell-mime-multipartp (&optional limit) - "Return multipart message start boundary or nil if none." + "Return the start boundary of a multipart message, or nil if none. +LIMIT is passed to `re-search-forward', which see." ;; caller must ensure `case-fold-search' is set to t (and (re-search-forward commit 45a191738c661d6161ec82a4664bf8bee387219c Author: Eli Zaretskii Date: Sat Jun 15 14:55:31 2024 +0300 Fix doc strings in ispell.el * lisp/textmodes/ispell.el (ispell-check-version) (ispell-get-casechars, ispell-get-not-casechars) (ispell-get-otherchars, ispell-get-many-otherchars-p) (ispell-get-ispell-args, ispell-get-extended-character-mode) (ispell-get-coding-system, ispell-word, ispell-get-word) (ispell-pdict-save, ispell-command-loop, ispell-help) (ispell-filter, ispell-highlight-spelling-error) (ispell-change-dictionary, ispell-region, ispell-ignore-fcc) (ispell-get-line, ispell-message): Doc fixes (bug#71532) diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index f523df9881e..67be936ca24 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -649,8 +649,8 @@ this would require some extra guessing in `ispell-aspell-find-dictionary'.") (defun ispell-check-version (&optional interactivep) "Ensure that `ispell-program-name' is valid and has the correct version. -Returns version number if called interactively. -Otherwise returns the library directory name, if that is defined." +Return version number if called interactively, or if INTERACTIVEP is non-nil. +Otherwise return the library directory name, if that is defined." ;; This is a little wasteful as we actually launch ispell twice: once ;; to make sure it's the right version, and once for real. But people ;; get confused by version mismatches *all* the time (and I've got the @@ -1517,23 +1517,30 @@ This is passed to the Ispell process using the `-p' switch.") (decode-coding-string str (ispell-get-coding-system) t)))) (defun ispell-get-casechars () + "Return CASECHARS of a dictionary." (ispell-get-decoded-string 1)) (defun ispell-get-not-casechars () + "Return NOT-CASECHARS of a dictionary." (ispell-get-decoded-string 2)) (defun ispell-get-otherchars () + "Return OTHERCHARS of a dictionary." (ispell-get-decoded-string 3)) (defun ispell-get-many-otherchars-p () + "Return MANY-OTHERCHARS of a dictionary." (nth 4 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist) (assoc ispell-current-dictionary ispell-dictionary-alist)))) (defun ispell-get-ispell-args () + "Return ARGS of a dictionary." (nth 5 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist) (assoc ispell-current-dictionary ispell-dictionary-alist)))) (defun ispell-get-extended-character-mode () + "Return extended character mode of a dictionary." (if ispell-really-hunspell ;; hunspell treats ~word as ordinary words nil ;; in pipe mode. Disable extended-char-mode (nth 6 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist) (assoc ispell-current-dictionary ispell-dictionary-alist))))) (defun ispell-get-coding-system () + "Return encoding of a dictionary." (nth 7 (or (assoc ispell-current-dictionary ispell-local-dictionary-alist) (assoc ispell-current-dictionary ispell-dictionary-alist)))) @@ -1909,6 +1916,7 @@ resume interrupted spell-checking of a buffer or region. Interactively, in Transient Mark mode when the mark is active, call `ispell-region' to check the active region for spelling errors. +Non-interactively, this happens if REGION is non-nil. Word syntax is controlled by the definition of the chosen dictionary, which is in `ispell-local-dictionary-alist' or `ispell-dictionary-alist'. @@ -2053,7 +2061,9 @@ many times (see the doc string of `ispell-dictionary-alist' for details about otherchars). Word syntax is controlled by the definition of the chosen dictionary, -which is in `ispell-local-dictionary-alist' or `ispell-dictionary-alist'." +which is in `ispell-local-dictionary-alist' or `ispell-dictionary-alist'. +EXTRA-OTHERCHARS, if non-nil, is the set of extra characters to add +to the dictionary's OTHERCHARS." (ispell-set-spellchecker-params) ; Initialize variables and dicts alists (let* ((ispell-casechars (ispell-get-casechars)) (ispell-not-casechars (ispell-get-not-casechars)) @@ -2117,7 +2127,11 @@ which is in `ispell-local-dictionary-alist' or `ispell-dictionary-alist'." ;;;###autoload (defun ispell-pdict-save (&optional no-query force-save) "Check to see if the personal dictionary has been modified. -If so, ask if it needs to be saved." +If so, ask if it needs to be saved. +If NO-QUERY is non-nil, save the personal dictionary without asking. +Interactively, if `ispell-silently-savep' is non-nil, don't ask. +If FORCE-SAVE is non-nil, suggest to save the personal dictionary even +if not modified; this always happens interactively." (interactive (list ispell-silently-savep t)) (if (and ispell-pdict-modified-p (listp ispell-pdict-modified-p)) (setq ispell-pdict-modified-p (car ispell-pdict-modified-p))) @@ -2136,19 +2150,20 @@ It is called once per iteration, before displaying a prompt to the user.") (defun ispell-command-loop (miss guess word start end) - "Display possible corrections from list MISS. + "Display possible corrections from MISS using GUESS for WORD in START..END. +MISS lists possible corrections. GUESS lists possibly valid affix construction of WORD. -Returns nil to keep word. -Returns 0 to insert locally into buffer-local dictionary. -Returns string for new chosen word. -Returns list for new replacement word (will be rechecked). - Query-replace when list length is 2. - Automatic query-replace when second element is `query-replace'. -Highlights the word, which is assumed to run from START to END. +Return nil to keep the word unchanged. +Return 0 to insert locally into buffer-local dictionary. +Return a string for the chosen replacement word. +Return a list for new replacement word (will be rechecked). + Use `query-replace' when list length is 2. + Automatic `query-replace' when second element is `query-replace'. +Highlight the word, which is assumed to run from START to END. Global `ispell-pdict-modified-p' becomes a list where the only value indicates whether the dictionary has been modified when option `a' or `i' is used. -Global `ispell-quit' set to start location to continue spell session." +Global `ispell-quit' is set to start location to continue spell session." (let ((count ?0) (choices miss) (window-min-height (min window-min-height @@ -2433,23 +2448,23 @@ Global `ispell-quit' set to start location to continue spell session." Selections are: \\`0'..\\`9' Replace the word with a digit offered in the *Choices* buffer. -\\`SPC' Accept word this time. -\\`i' Accept word and insert into private dictionary. -\\`a' Accept word for this session. -\\`A' Accept word and place in `buffer-local dictionary'. -\\`r' Replace word with typed-in value. Rechecked. -\\`R' Replace word with typed-in value. Query-replaced in buffer. Rechecked. -\\`?' Show these commands. -\\`x' Exit spelling buffer. Move cursor to original point. -\\`X' Exit spelling buffer. Leaves cursor at the current point, and permits - the aborted check to be completed later. -\\`q' Quit spelling session (Kills ispell process). -\\`l' Look up typed-in replacement in alternate dictionary. Wildcards okay. -\\`u' Like \\`i', but the word is lower-cased first. -\\`m' Place typed-in value in personal dictionary, then recheck current word. -\\`C-l' Redraw screen. -\\`C-r' Recursive edit. -\\`C-z' Suspend Emacs or iconify frame." +\\`SPC' Accept word this time. +\\`i' Accept word and insert into private dictionary. +\\`a' Accept word for this session. +\\`A' Accept word and place in `buffer-local dictionary'. +\\`r' Replace word with typed-in value. Rechecked. +\\`R' Replace word with typed-in value. Query-replaced in buffer. Rechecked. +\\`?' Show these commands. +\\`x' Exit spelling buffer. Move cursor to original point. +\\`X' Exit spelling buffer. Leaves cursor at the current point, and permits + the aborted check to be completed later. +\\`q' Quit spelling session (Kills ispell process). +\\`l' Look up typed-in replacement in alternate dictionary. Wildcards okay. +\\`u' Like \\`i', but the word is lower-cased first. +\\`m' Place typed-in value in personal dictionary, then recheck current word. +\\`C-l' Redraw screen. +\\`C-r' Recursive edit. +\\`C-z' Suspend Emacs or iconify frame." (if (equal ispell-help-in-bufferp 'electric) (progn @@ -2600,7 +2615,9 @@ this function signals an error." ;; in this case treats the next input received as fresh input. (defun ispell-filter (_process output) - "Output filter function for ispell, grep, and look." + "Filter function for ispell, grep, and look, process OUTPUT from subprocess. +OUTPUT can contain multiple lines, part of a single line, or both. +OUTPUT must end with a newline." (let ((start 0) (continue t) end) @@ -2705,6 +2722,10 @@ The variable `ispell-highlight-face' selects the face to use for highlighting." (defun ispell-highlight-spelling-error (start end &optional highlight refresh) + "Highlight spelling error between START and END. +Optional argument HIGHLIGHT, if non-nil, means to highlight mis-spelling. +See `ispell-highlight-spelling-error-generic' for the meaning of optional +argument REFRESH, which is passed to that function as the 4th argument." (if (display-color-p) (ispell-highlight-spelling-error-overlay start end highlight) (ispell-highlight-spelling-error-generic start end highlight refresh))) @@ -3020,10 +3041,10 @@ With CLEAR, buffer session localwords are cleaned." ;;;###autoload (defun ispell-change-dictionary (dict &optional arg) "Change to dictionary DICT for Ispell. -With a prefix arg, set it \"globally\", for all buffers. -Without a prefix arg, set it \"locally\", just for this buffer. +If ARG is non-nil (interactively, the prefix arg), set it \"globally\", +for all buffers. Otherwise, set it \"locally\", just for this buffer. -By just answering RET you can find out what the current dictionary is." +By just answering RET you can find out the name of the current dictionary." (interactive (list (completing-read "Use new dictionary (RET for current, SPC to complete): " @@ -3086,7 +3107,7 @@ when needed." ;;;###autoload (defun ispell-region (reg-start reg-end &optional recheckp shift) - "Interactively check a region for spelling errors. + "Interactively check region between REG-START and REG-END for spelling errors. Leave the mark at the last misspelled word that the user was queried about. Return nil if spell session was terminated, otherwise returns shift offset @@ -3341,10 +3362,12 @@ Must be called after `ispell-buffer-local-parsing' due to dependence on mode." (defun ispell-ignore-fcc (start end) - "Delete the Fcc: message header when large attachments are included. -Return value nil if file with large attachments is saved. + "Query whether to delete Fcc header due to attachment between START and END. +Query the user whether Fcc header should be deleted when large attachments are +included in the message. +Return nil if email with large attachments should be saved. This can be used to avoid multiple questions for multiple large attachments. -Returns point to starting location afterwards." +Return point to starting location afterwards." (let ((result t)) (if (and ispell-checking-message ispell-message-fcc-skip) (if (< ispell-message-fcc-skip (- end start)) @@ -3420,8 +3443,8 @@ Point is placed at end of skipped region." (defun ispell-get-line (start end in-comment) - "Grab the next line of data. -Returns a string with the line data." + "Grab the next line of text between START and END. +Return a string with the line data." (let ((ispell-casechars (ispell-get-casechars)) string) (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS @@ -3892,10 +3915,12 @@ Otherwise, it must be a function which is called to get the limit.") (defun ispell-mime-skip-part (boundary) - "Move point across header, or entire MIME part if message is encoded. + "Move point across text that matches BOUNDARY, or across entire message. +BOUNDARY, if non-nil, specifies the part of the message to skip, either +the header, or entire MIME part if the message is encoded. All specified types except `7bit' `8bit' and `quoted-printable' are considered encoded and therefore skipped. See rfc 1521, 2183, ... -If no boundary is given, then entire message is skipped. +If BOUNDARY is nil, the entire message is skipped. This starts one line ABOVE the MIME content messages, on the boundary marker, for operation with the generic region-skipping code. @@ -3976,7 +4001,7 @@ in your init file: (add-hook \\='mail-send-hook #\\='ispell-message) (add-hook \\='mh-before-send-letter-hook #\\='ispell-message) -You can bind this to the key C-c i in GNUS or mail by adding to +You can bind this to a key in GNUS or mail by adding to `news-reply-mode-hook' or `mail-mode-hook' the following lambda expression: (lambda () (local-set-key \"\\C-ci\" \\='ispell-message))" (interactive) commit c637adbf32f2566b739eb96e68546201c55540af Author: Ashwin Kafle Date: Thu Jun 13 16:06:38 2024 +0545 Fix calc-trail-here for first line of trail. * lisp/calc/calc.el(calc-trail-here): Change 'or' to 'and' since (bobp) can return true even if the buffer is not empty. (Bug#71533) diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index e6448625cee..f92e4958e33 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el @@ -2184,7 +2184,7 @@ the United States." (beginning-of-line) (if (eobp) (forward-line -1)) - (if (or (bobp) (eobp)) + (if (and (bobp) (eobp)) (setq overlay-arrow-position nil) ; trail is empty (set-marker calc-trail-pointer (point) (current-buffer)) (setq calc-trail-overlay (concat (buffer-substring (point) commit af6e7ed4c1aa5fae34eda3507a4baf8b52c97312 Author: kobarity Date: Wed Jun 12 01:09:21 2024 +0900 Allow escape sequences in Python prompts * lisp/progmodes/python.el (python-shell-prompt-detect): Use Python's json package if available, and remove escape sequences in prompts. * test/lisp/progmodes/python-tests.el (python-tests-interpreter-2-6-higher-p): New predicate function. (python-shell-prompt-detect-7): New test. (Bug#71440) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 2664d71d358..ca5ecfab6ea 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -3104,8 +3104,13 @@ detection and just returns nil." (let* ((code (concat "import sys\n" "ps = [getattr(sys, 'ps%s' % i, '') for i in range(1,4)]\n" + "try:\n" + " import json\n" + " ps_json = '\\n' + json.dumps(ps)\n" + "except ImportError:\n" ;; JSON is built manually for compatibility - "ps_json = '\\n[\"%s\", \"%s\", \"%s\"]\\n' % tuple(ps)\n" + " ps_json = '\\n[\"%s\", \"%s\", \"%s\"]\\n' % tuple(ps)\n" + "\n" "print (ps_json)\n" "sys.exit(0)\n")) (interpreter python-shell-interpreter) @@ -3168,7 +3173,7 @@ detection and just returns nil." "Or alternatively in:\n" " + `python-shell-prompt-input-regexps'\n" " + `python-shell-prompt-output-regexps'"))) - prompts)))) + (mapcar #'ansi-color-filter-apply prompts))))) (defun python-shell-prompt-validate-regexps () "Validate all user provided regexps for prompts. diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 31b1c80a571..9eef82e9c90 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -3820,6 +3820,17 @@ This function is intended to be used as the PRED argument of (when (string= (car (split-string (cdr info) "\\.")) "3") (car info))) +(defun python-tests-interpreter-2-6-higher-p (info) + "Check if the interpreter major version in INFO is 2.6 or higher. +This function is intended to be used as the PRED argument of +`python-tests-get-shell-interpreter'." + (let* ((version (split-string (cdr info) "\\.")) + (major (string-to-number (car version))) + (minor (string-to-number (cadr version)))) + (when (or (>= major 3) + (and (= major 2) (>= minor 6))) + (car info)))) + (ert-deftest python-shell-get-process-name-1 () "Check process name calculation sans `buffer-file-name'." (python-tests-with-temp-buffer @@ -4353,6 +4364,23 @@ and `python-shell-interpreter-args' in the new shell buffer." (should (not (get-buffer "*Warnings*")))) (ignore-errors (delete-file startup-file)))))) +(ert-deftest python-shell-prompt-detect-7 () + "Check prompt autodetection with escape sequences. Bug#71440." + (python-tests-with-shell-interpreter + #'python-tests-interpreter-2-6-higher-p + (let* ((process-environment process-environment) + (startup-code (concat "import sys\n" + "sys.ps1 = '\033[32mpy> \033[0m'\n" + "sys.ps2 = '\033[32m..> \033[0m'\n" + "sys.ps3 = '\033[32mout \033[0m'\n")) + (startup-file (python-shell--save-temp-file startup-code))) + (unwind-protect + (progn + (setenv "PYTHONSTARTUP" startup-file) + (should python-shell-prompt-detect-enabled) + (should (equal (python-shell-prompt-detect) '("py> " "..> " "out ")))) + (ignore-errors (delete-file startup-file)))))) + (ert-deftest python-shell-prompt-validate-regexps-1 () "Check `python-shell-prompt-input-regexps' are validated." (let* ((python-shell-prompt-input-regexps '("\\(")) commit ffa349f983fa5c754fd7751c0757f6c704fbfe5a Author: Eli Zaretskii Date: Sat Jun 15 13:04:12 2024 +0300 Fix 'reindent-then-newline-and-indent' with 'abbrev-mode' * lisp/simple.el (reindent-then-newline-and-indent): Use a marker for the initial position. (Bug#71459) diff --git a/lisp/simple.el b/lisp/simple.el index 74115be2778..b48f46fc711 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -915,7 +915,9 @@ In programming language modes, this is the same as TAB. In some text modes, where TAB inserts a tab, this indents to the column specified by the function `current-left-margin'." (interactive "*") - (let ((pos (point)) + ;; Use a marker because the call to 'newline' below could insert some + ;; text, e.g., if 'abbrev-mode' is turned on. + (let ((pos (point-marker)) (electric-indent-mode nil)) ;; Be careful to insert the newline before indenting the line. ;; Otherwise, the indentation might be wrong. commit 6d12157fa85a12208555e291321af97a09243962 Author: Eli Zaretskii Date: Sat Jun 15 11:37:34 2024 +0300 Prevent deletion of separator in *edit string* buffer * lisp/textmodes/string-edit.el (string-edit): Make the separator line read-only. (Bug#71405) diff --git a/lisp/textmodes/string-edit.el b/lisp/textmodes/string-edit.el index cafed5a1e16..936618dddaa 100644 --- a/lisp/textmodes/string-edit.el +++ b/lisp/textmodes/string-edit.el @@ -58,7 +58,8 @@ Also see `read-string-from-buffer'." (list 'intangible t 'face 'string-edit-prompt 'read-only t)) - (insert (propertize (make-separator-line) 'rear-nonsticky t)) + (insert (propertize (make-separator-line) + 'read-only t 'rear-nonsticky t)) (add-text-properties (point-min) (point) (list 'string-edit--prompt t)))) (let ((start (point))) commit 988203fe980e3c80f736ad0b6aae9f288ebfa0f1 Author: Eli Zaretskii Date: Sat Jun 15 11:08:22 2024 +0300 Fix electric-pair-mode when characters are bound to non-ASCII keys * src/cmds.c (Fself_insert_command): Record the argument C in 'last-command-event'. (Bug#71337) diff --git a/src/cmds.c b/src/cmds.c index f7a3f9e7ac6..ba5cef9dd48 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -278,6 +278,8 @@ a non-nil value for the inserted character. At the end, it runs /* Backward compatibility. */ if (NILP (c)) c = last_command_event; + else + last_command_event = c; if (XFIXNUM (n) < 0) error ("Negative repetition argument %"pI"d", XFIXNUM (n)); @@ -288,14 +290,15 @@ a non-nil value for the inserted character. At the end, it runs /* Barf if the key that invoked this was not a character. */ if (!CHARACTERP (c)) bitch_at_user (); - else { - int character = translate_char (Vtranslation_table_for_input, - XFIXNUM (c)); - int val = internal_self_insert (character, XFIXNAT (n)); - if (val == 2) - Fset (Qundo_auto__this_command_amalgamating, Qnil); - frame_make_pointer_invisible (SELECTED_FRAME ()); - } + else + { + int character = translate_char (Vtranslation_table_for_input, + XFIXNUM (c)); + int val = internal_self_insert (character, XFIXNAT (n)); + if (val == 2) + Fset (Qundo_auto__this_command_amalgamating, Qnil); + frame_make_pointer_invisible (SELECTED_FRAME ()); + } return Qnil; } commit 59261e6f4fef0ec03c8127b29fe107ed19280a3b (refs/remotes/origin/emacs-29) Author: Michael Albinus Date: Wed Jun 12 10:24:34 2024 +0200 Fix auth-info-password * lisp/auth-source.el (auth-info-password): :secret can be a cascaded function. diff --git a/lisp/auth-source.el b/lisp/auth-source.el index 5969cdbf9f8..4dcf7d73717 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -874,9 +874,9 @@ while \(:host t) would find all host entries." (defun auth-info-password (auth-info) "Return the :secret password from the AUTH-INFO." (let ((secret (plist-get auth-info :secret))) - (if (functionp secret) - (funcall secret) - secret))) + (while (functionp secret) + (setq secret (funcall secret))) + secret)) (defun auth-source-pick-first-password (&rest spec) "Pick the first secret found by applying `auth-source-search' to SPEC." commit 778f8c793d1c621fc8219644797ef44425bf0bb4 Author: Eli Zaretskii Date: Sun Jun 9 20:56:39 2024 +0300 ; * lisp/mail/rmail.el (rmail-get-new-mail-hook): Doc fix. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 5747091c498..34724c5d204 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -462,7 +462,9 @@ as argument, to ask the user that question." "List of functions to call when Rmail is invoked.") (defvar rmail-get-new-mail-hook nil - "List of functions to call when Rmail has retrieved new mail.") + "List of functions to call when Rmail has retrieved new mail. +The functions are called in `rmail-buffer' narrowed to include +only the new email messages, with point at the first new mail.") ;;;###autoload (defcustom rmail-show-message-hook nil commit e6044b29e65d3639c267bf4753391c7cc57106cf Author: Eli Zaretskii Date: Sat Jun 8 21:06:51 2024 +0300 ; Minor fixes in ELisp manual * doc/lispref/searching.texi (Regexp Search): Caveat about using 'search-spaces-regexp'. (Bug#71429) * doc/lispref/help.texi (Keys in Documentation): Fix markup. diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index f3c916a9ecc..dd51e32f8ad 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -334,6 +334,9 @@ stands for a key sequence that will invoke @var{command}, or @samp{M-x @item \@{@var{mapvar}@} stands for a summary of the keymap which is the value of the variable @var{mapvar}. The summary is made using @code{describe-bindings}. +The summary will normally exclude meny bindings, but if the +@var{include-menus} argument to @code{substitute-command-keys} is +non-@code{nil}, the menu bindings will be included. @item \<@var{mapvar}> stands for no text itself. It is used only for a side effect: it @@ -384,11 +387,6 @@ given a special face @code{help-key-binding}, but if the optional argument @var{no-face} is non-@code{nil}, the function doesn't add this face to the produced string. -@defun substitute-quotes string -This function works like @code{substitute-command-keys}, but only -replaces quote characters. -@end defun - @cindex advertised binding If a command has multiple bindings, this function normally uses the first one it finds. You can specify one particular key binding by @@ -440,6 +438,11 @@ The keymap description will normally exclude menu items, but if @end group @end smallexample +@defun substitute-quotes string +This function works like @code{substitute-command-keys}, but only +replaces quote characters. +@end defun + There are other special conventions for the text in documentation strings---for instance, you can refer to functions, variables, and sections of this manual. @xref{Documentation Tips}, for details. diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index c697c929b6a..3022d127c13 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -2190,7 +2190,11 @@ this regular expression. However, spaces inside of constructs such as Since this variable affects all regular expression search and match constructs, you should bind it temporarily for as small as possible -a part of the code. +a part of the code, and only where the Lisp code affected by the +binding performs searches whose regexp was produced from interactive +user input. In other words, this variable should only be used to tell +regexp search primitives how to interpret whitespace typed by the +user. @end defvar @node POSIX Regexps