commit ab8bc93cd42233c59a187b99dfb011c6fc5b86f6 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Thu Aug 17 10:03:49 2023 +0800 ; Add tasks for the Android port * etc/PROBLEMS: Improve descriptions of issues with Droid Sans Mono and Anonymous Pro. Then, bring up the subject of CFF fonts and how they relate to CJK text. * etc/TODO: Detail that CFF support is desired. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 6fe0b93f538..265e28e5ddc 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -3353,7 +3353,7 @@ this and many other problems do not exist on the regular X builds. ** Text displayed in the default monospace font looks horrible. Droid Sans Mono (the default Monospace font which comes with Android) -comes with instruction code designed for Microsoft's proprietary +incorporates instruction code designed for Microsoft's proprietary TrueType font scaler. When this code is executed by Emacs to instruct a glyph containing more than one component, it tries to address "reference points" which are set to the values of two extra "phantom @@ -3398,6 +3398,11 @@ you are not seeing problems with character display, as the automatically generated instructions result in superior display results that are easier to read. +We have been told that the default Sans font under Android 2.3.7, +named "Droid Sans", also exhibits this problem. The procedure for +repairing the font is identical to the procedure outlined above, +albeit with "DroidSansMono" replaced by simply "DroidSans". + ** The "Anonymous Pro" font displays incorrectly. Glyph instruction code within the Anonymous Pro font relies on @@ -3407,14 +3412,15 @@ interpreter control registers after the execution of the font pre-program, which sets them to a value that is perpendicular to the horizontal plane of movement. -Since Emacs does not provide this "feature", various points within +Since Emacs does not provide this "feature", various points inside glyphs are moved vertically rather than horizontally when a glyph -program later executes an "MIRP" (Move Indirect Relative Point) -instruction. +program later executes an instruction such as "MIRP" (Move Indirect +Relative Point) that moves and measures points along the axis +specified by those registers. This can be remedied in two ways; the first (and the easiest) is to replace its instruction code with that supplied by "ttfautohint", as -depicted above. The second is to patch the instruction code within +depicted above. The second is to patch the instruction code inside the font itself, using the "ttx" utility: https://fonttools.readthedocs.io/en/latest/ttx.html @@ -3435,11 +3441,10 @@ then, find the end of the section labeled 'prep': and insert the following instruction immediately before the closing -'/assembly' tag: - - SVTCA[1] +'/assembly' tag, so as to reset the interpreter control registers back +to their default values prior to the completion of the pre-program: -(which stands for "Set Vector registers to Control Axis X") + SVTCA[1] /* Set Vector registers to Control Axis X */ Then, reassemble the font from the modified XML: @@ -3448,6 +3453,25 @@ Then, reassemble the font from the modified XML: which should produce a modified font by the name of Anonymous_Pro#1.ttf. +** CJK text does not display in Emacs, but does in other programs. + +When inserting CJK text into a buffer or visiting a file containing +CJK text, Emacs often fails to locate a suitable font. This problem +manifests itself as hollow squares with numbers and letters within +being displayed in lieu of the text itself. + +The reason for this is Emacs's absence of support for OpenType fonts +utilizing CFF (Compact Font Format) outlines, which the CJK fonts +bundled with Android have been distributed as since Android 7.0. + +The solution is to install a TrueType CJK font to the user fonts +directory detailed in the "Android Fonts" node of the Emacs manual. + +Introducing support for the byzantine CFF font format into the Android +port is a large undertaking that we are looking for volunteers to +perform. If you are interested in taking responsibility for this +task, please contact . + * Build-time problems ** Configuration diff --git a/etc/TODO b/etc/TODO index f097e76b917..a918f496863 100644 --- a/etc/TODO +++ b/etc/TODO @@ -1748,6 +1748,19 @@ The former is based on the GVFS archive backend, which makes it available on GNU/Linux only. That implementation has further drawbacks like it doesn't support to write into archives. +** Provide support for CFF outlines in the Android port. + +The file src/sfnt.c supplies the font backend for the Android port. +It is presently a self contained TrueType scaler, implementing both a +grayscale outline generator and an instruction code interpreter. + +Support for CFF (Compact Font Format) outlines will facilitate +utilizing fonts distributed as ".otf" files, a category that currently +encompasses all CJK and some Middle Eastern and Indic fonts +distributed with Android, obviating the present requirement for users +of such scripts to actively install TrueType versions of fonts +otherwise bundled with the system. + * Other known bugs ** 'make-frame' forgets unhandled parameters, at least for X11 frames commit f38bcf37dc47ce172c985d1c621df3583eaad46c Author: Spencer Baugh Date: Thu Aug 17 04:14:03 2023 +0300 (project-find-file): Allow current file name "other project"'s future history * lisp/progmodes/project.el (project-find-file): Allow using the relative file name of the current buffer in "other project" as well (bug#63829). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index d8b12c9c880..e1d14474323 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -994,7 +994,8 @@ project-find-file "Visit a file (with completion) in the current project. The filename at point (determined by `thing-at-point'), if any, -is available as part of \"future history\". +is available as part of \"future history\". If none, the current +buffer's file name is used. If INCLUDE-ALL is non-nil, or with prefix argument when called interactively, include all files under the project root, except @@ -1005,7 +1006,16 @@ project-find-file (dirs (list root))) (project-find-file-in (or (thing-at-point 'filename) - buffer-file-name) + (and buffer-file-name + (if-let (buffer-proj (and project-current-directory-override + (project-current nil default-directory))) + ;; Allow using the relative file name of the current + ;; buffer in "other project" as well. + (let ((buffer-root (project-root buffer-proj))) + ;; file-name-concat requires Emacs 28+ + (concat (file-name-as-directory root) + (file-relative-name buffer-file-name buffer-root))) + buffer-file-name))) dirs pr include-all))) ;;;###autoload commit 9dff654432ec79e9f3d75bc1b4fb869eeccfe213 Author: Dmitry Gutov Date: Thu Aug 17 04:08:03 2023 +0300 * src/fileio.c (Ffile_name_concat): Improve docstring. diff --git a/src/fileio.c b/src/fileio.c index 75bcdf091d8..869e1ea7e31 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -843,10 +843,10 @@ DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0, DEFUN ("file-name-concat", Ffile_name_concat, Sfile_name_concat, 1, MANY, 0, doc: /* Append COMPONENTS to DIRECTORY and return the resulting string. -Elements in COMPONENTS must be a string or nil. +Each element in COMPONENTS must be a string or nil. DIRECTORY or the non-final elements in COMPONENTS may or may not end with a slash -- if they don't end with a slash, a slash will be -inserted before contatenating. +inserted before concatenating. usage: (record DIRECTORY &rest COMPONENTS) */) (ptrdiff_t nargs, Lisp_Object *args) { commit 155154f6f118361b6c4a86160cae1be45bea0871 Author: Dmitry Gutov Date: Wed Aug 16 04:43:55 2023 +0300 ; * lisp/progmodes/project.el (project-find-file-in): Update docstring. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fe13f4ab114..d8b12c9c880 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1097,7 +1097,7 @@ project--read-file-absolute (defun project-find-file-in (suggested-filename dirs project &optional include-all) "Complete a file name in DIRS in PROJECT and visit the result. -SUGGESTED-FILENAME is a relative file name, or part of it, which +SUGGESTED-FILENAME is a file name, or part of it, which is used as part of \"future history\". If INCLUDE-ALL is non-nil, or with prefix argument when called commit 4509cda5c943964fc8a2983fd90f10b9c255f97a Author: Po Lu Date: Thu Aug 17 08:45:57 2023 +0800 Update Android port * configure.ac (emacs_cv_tputs_lib): Only circumvent termcap if Android windowing support is enabled. (bug#65340) * etc/PROBLEMS: Fix typo in section recouting problems with the Anonymous Pro font. * lisp/subr.el (event-start, event-end): Return the mouse position list tied to touchscreen-begin and end events. Reported by Stefan Monnier . * lisp/version.el (emacs-build-system, emacs-build-time) (emacs-repository-get-version, emacs-repository-get-branch): Bypass Android specific code on non-GUI builds running on Android. (bug#65340) * lisp/wid-edit.el (widget-event-point): Remove now redundant code. diff --git a/configure.ac b/configure.ac index 8120935978d..4cf6751ab82 100644 --- a/configure.ac +++ b/configure.ac @@ -5992,7 +5992,7 @@ AC_DEFUN # than to expect to find it in ncurses. # Also we need tputs and friends to be able to build at all. AC_CACHE_CHECK([for library containing tputs], [emacs_cv_tputs_lib], -[if test "${opsys}" = "mingw32" || test "$opsys" = "android"; then +[if test "${opsys}" = "mingw32" || test x"$REALLY_ANDROID" = "xyes"; then emacs_cv_tputs_lib='none required' else # curses precedes termcap because of AIX (Bug#9736#35) and OpenIndiana. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 6a4c8cdb34c..6fe0b93f538 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -3400,7 +3400,7 @@ results that are easier to read. ** The "Anonymous Pro" font displays incorrectly. -Glyphs instruction code within the Anonymous Pro font relies on +Glyph instruction code within the Anonymous Pro font relies on undocumented features of the Microsoft TrueType font scaler, namely that the scaler always resets the "projection" and "freedom" vector interpreter control registers after the execution of the font diff --git a/lisp/subr.el b/lisp/subr.el index 616f0a8dfb6..f6bf7988e9d 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1651,8 +1651,9 @@ event--posn-at-point (defun event-start (event) "Return the starting position of EVENT. -EVENT should be a mouse click, drag, or key press event. If -EVENT is nil, the value of `posn-at-point' is used instead. +EVENT should be a mouse click, drag, touch screen, or key press +event. If EVENT is nil, the value of `posn-at-point' is used +instead. The following accessor functions are used to access the elements of the position: @@ -1675,27 +1676,32 @@ event-start For more information, see Info node `(elisp)Click Events'." (declare (side-effect-free t)) - (or (and (consp event) - ;; Ignore touchscreen events. They store the posn in a - ;; different format, and can have multiple posns. - (not (memq (car event) '(touchscreen-begin - touchscreen-update - touchscreen-end))) - (nth 1 event)) - (event--posn-at-point))) + (if (or (eq (car event) 'touchscreen-begin) + (eq (car event) 'touchscreen-end)) + ;; Touch screen begin and end events save their information in a + ;; different format, where the mouse position list is the cdr of + ;; (nth 1 event). + (cdadr event) + (or (and (consp event) + ;; Ignore touchscreen update events. They store the posn + ;; in a different format, and can have multiple posns. + (not (eq (car event) 'touchscreen-update)) + (nth 1 event)) + (event--posn-at-point)))) (defun event-end (event) "Return the ending position of EVENT. -EVENT should be a click, drag, or key press event. +EVENT should be a click, drag, touch screen, or key press event. See `event-start' for a description of the value returned." (declare (side-effect-free t)) - (or (and (consp event) - (not (memq (car event) '(touchscreen-begin - touchscreen-update - touchscreen-end))) - (nth (if (consp (nth 2 event)) 2 1) event)) - (event--posn-at-point))) + (if (or (eq (car event) 'touchscreen-begin) + (eq (car event) 'touchscreen-end)) + (cdadr event) + (or (and (consp event) + (not (eq (car event) 'touchscreen-update)) + (nth (if (consp (nth 2 event)) 2 1) event)) + (event--posn-at-point)))) (defsubst event-click-count (event) "Return the multi-click count of EVENT, a click or drag event. diff --git a/lisp/version.el b/lisp/version.el index ca61f8cfeee..0eb4ea76f4f 100644 --- a/lisp/version.el +++ b/lisp/version.el @@ -61,13 +61,19 @@ emacs-minor-version (string-to-number (match-string 1 emacs-version))) "Minor version number of this version of Emacs.") -(defconst emacs-build-system (or (and (eq system-type 'android) +;; N.B. (featurep 'android) is tested for in addition to +;; `system-type', because that can also be Android on a TTY-only +;; Android build that doesn't employ the window system packaging +;; support. (bug#65319) +(defconst emacs-build-system (or (and (featurep 'android) + (eq system-type 'android) (android-read-build-system)) (system-name)) "Name of the system on which Emacs was built, or nil if not available.") (defconst emacs-build-time (if emacs-build-system - (or (and (eq system-type 'android) + (or (and (featurep 'android) + (eq system-type 'android) (android-read-build-time)) (current-time))) "Time at which Emacs was dumped out, or nil if not available.") @@ -183,7 +189,8 @@ emacs-repository-get-version Optional argument DIR is a directory to use instead of `source-directory'. Optional argument EXTERNAL is ignored." - (cond ((eq system-type 'android) + (cond ((and (featurep 'android) + (eq system-type 'android)) (emacs-repository-version-android)) (t (emacs-repository-version-git (or dir source-directory))))) @@ -229,7 +236,8 @@ emacs-repository-get-branch correspond to the running Emacs. Optional argument DIR is a directory to use instead of `source-directory'." - (cond ((eq system-type 'android) + (cond ((and (featurep 'android) + (eq system-type 'android)) (emacs-repository-branch-android)) (t (emacs-repository-branch-git (or dir source-directory))))) diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 9e7c31224e0..fabf590f6b8 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -64,12 +64,10 @@ ;;; Compatibility. -(defun widget-event-point (event) +(defsubst widget-event-point (event) "Character position of the end of event if that exists, or nil. EVENT can either be a mouse event or a touch screen event." - (if (eq (car-safe event) 'touchscreen-begin) - (posn-point (cdadr event)) - (posn-point (event-end event)))) + (posn-point (event-end event))) (defun widget-button-release-event-p (event) "Non-nil if EVENT is a mouse-button-release event object." commit cbe6b48b3620385a4c9eeb72b20d39cfe706da76 Author: Po Lu Date: Thu Aug 17 08:25:40 2023 +0800 Fix potential NULL pointer dereference * java/org/gnu/emacs/EmacsDialog.java (display): Initialize rc.thing to false. diff --git a/java/org/gnu/emacs/EmacsDialog.java b/java/org/gnu/emacs/EmacsDialog.java index e4ed2271741..2291207fbcc 100644 --- a/java/org/gnu/emacs/EmacsDialog.java +++ b/java/org/gnu/emacs/EmacsDialog.java @@ -394,6 +394,7 @@ else if (EmacsOpenActivity.currentActivity != null) final EmacsHolder rc; rc = new EmacsHolder (); + rc.thing = false; runnable = new Runnable () { @Override public void commit 898edb181698b29b1de48ab7d0793a2438188cd7 Author: Mattias Engdegård Date: Wed Aug 16 17:49:22 2023 +0200 tibetan.el: compute constants at compile time, optimise regexps * lisp/language/tibetan.el (tibetan-subjoined-transcription-alist) (tibetan-regexp, tibetan-precomposed-regexp) (tibetan-precomposition-rule-regexp): Evaluate at compile time. Use regexp-opt. diff --git a/lisp/language/tibetan.el b/lisp/language/tibetan.el index 31ff37016fe..21b3fc03417 100644 --- a/lisp/language/tibetan.el +++ b/lisp/language/tibetan.el @@ -126,6 +126,7 @@ tibetan-composable-pattern ;;; Definitions of conversion data. ;;; +(eval-and-compile ;;; alists for tibetan char <-> transcription conversion ;;; longer transcription should come first @@ -333,6 +334,7 @@ tibetan-precomposed-transcription-alist (defconst tibetan-subjoined-transcription-alist + (eval-when-compile (sort (copy-sequence '(("+k" . "ྐ") @@ -381,7 +383,7 @@ tibetan-subjoined-transcription-alist ("+Y" . "ྻ") ;; fixed form subscribed YA ("+R" . "ྼ") ;; fixed form subscribed RA )) - (lambda (x y) (> (length (car x)) (length (car y)))))) + (lambda (x y) (> (length (car x)) (length (car y))))))) ;;; ;;; alist for Tibetan base consonant <-> subjoined consonant conversion. @@ -557,32 +559,34 @@ tibetan-precomposition-rule-alist ("སྦ" . "") ("སྨ" . ""))) +) ; eval-and-compile + (defconst tibetan-regexp - (mapconcat (lambda (x) (regexp-quote (car x))) - (append tibetan-precomposed-transcription-alist - tibetan-consonant-transcription-alist - tibetan-vowel-transcription-alist - tibetan-modifier-transcription-alist - tibetan-subjoined-transcription-alist) - "\\|") + (eval-when-compile + (regexp-opt (mapcar #'car + (append tibetan-precomposed-transcription-alist + tibetan-consonant-transcription-alist + tibetan-vowel-transcription-alist + tibetan-modifier-transcription-alist + tibetan-subjoined-transcription-alist)))) "Regexp matching a Tibetan transcription of a composable Tibetan sequence. The result of matching is to be used for indexing alists at conversion from a roman transcription to the corresponding Tibetan character.") (defvar tibetan-precomposed-regexp (purecopy - (concat "^\\(" - (mapconcat #'car tibetan-precomposed-transcription-alist "\\|") - "\\)")) + (eval-when-compile + (concat "^" + (regexp-opt (mapcar #'car tibetan-precomposed-transcription-alist) + t)))) "Regexp string to match a romanized Tibetan complex consonant. The result of matching is to be used for indexing alists when the input key from an input method is converted to the corresponding precomposed glyph.") (defvar tibetan-precomposition-rule-regexp (purecopy - (concat "\\(" - (mapconcat #'car tibetan-precomposition-rule-alist "\\|") - "\\)")) + (eval-when-compile + (regexp-opt (mapcar #'car tibetan-precomposition-rule-alist) t))) "Regexp string to match a sequence of Tibetan consonantic components. That is, one base consonant and one or more subjoined consonants. The result of matching is to be used for indexing alist when the component commit 508d24c8b9aee2c2a4c78ccfef3b5f551a1b2115 Author: Stefan Kangas Date: Wed Aug 16 21:34:11 2023 +0200 ; Silence byte-compiler * test/src/comp-tests.el (native-comp-eln-load-path): Declare. diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el index 2fd70585628..4444ab61219 100644 --- a/test/src/comp-tests.el +++ b/test/src/comp-tests.el @@ -64,6 +64,7 @@ comp-deftest +(defvar native-comp-eln-load-path) (ert-deftest comp-tests-bootstrap () "Compile the compiler and load it to compile it-self. Check that the resulting binaries do not differ." commit d96dd127e392d05c2753908661d27760cedd5d2d Author: Stefan Kangas Date: Wed Aug 16 21:25:49 2023 +0200 Speed up dictionary--count-mode-buffers * lisp/net/dictionary.el (dictionary--count-mode-buffers): Make faster. Patch by Visuwesh . diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index f4a381db75d..58f36db2523 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -574,13 +574,13 @@ dictionary-ensure-buffer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun dictionary--count-mode-buffers () - "Return the number of buffers that " - (seq-reduce #'+ - (mapcar - (lambda (buf) - (with-current-buffer buf - (if (derived-mode-p 'dictionary-mode) 1 0))) - (buffer-list)) + (seq-reduce (lambda (count buf) + (if (provided-mode-derived-p + (buffer-local-value 'major-mode buf) + 'dictionary-mode) + (+ count 1) + count)) + (buffer-list) 0)) (defun dictionary-close (&rest _ignored) commit cf5ae0507e1a3aa956f0e588690371a63ab85e36 Author: Stefan Kangas Date: Wed Aug 16 09:14:49 2023 +0200 Add test for `calculator-exp` * test/lisp/calculator-tests.el (calculator-expt): New test. diff --git a/test/lisp/calculator-tests.el b/test/lisp/calculator-tests.el index 7ac3b9ba37a..8786d5c6c3b 100644 --- a/test/lisp/calculator-tests.el +++ b/test/lisp/calculator-tests.el @@ -47,5 +47,11 @@ calculator-test-calculator-string-to-number (let ((calculator-input-radix nil)) (should (equal (calculator-string-to-number str) expected))))))) +(ert-deftest calculator-expt () + (should (= (calculator-expt 2 -1) 0.5)) + (should (= (calculator-expt -2 2) 4)) + (should (= (calculator-expt -2 3) -8)) + (should (= (calculator-expt 2 64) 18446744073709551616))) + (provide 'calculator-tests) ;;; calculator-tests.el ends here commit 33d3e5c545f0e39e9f866ee47baad7995557e3f3 Author: Stefan Kangas Date: Wed Aug 16 09:14:02 2023 +0200 Make `term-mode` non-interactive * lisp/term.el (term-mode): Mark as non-interactive. diff --git a/lisp/term.el b/lisp/term.el index a80db33aab5..8f5f3de4531 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -1129,6 +1129,7 @@ term-mode \\{term-mode-map} Entry to this mode runs the hooks on `term-mode-hook'." + :interactive nil ;; we do not want indent to sneak in any tabs (setq indent-tabs-mode nil) (setq buffer-display-table term-display-table) commit ebe8871794d91606bc8429dca26825fae111d2c0 Author: Michael Albinus Date: Wed Aug 16 20:12:42 2023 +0200 ; * etc/NEWS: Fix typos. diff --git a/etc/NEWS b/etc/NEWS index 010d59401ff..808b5996729 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -70,9 +70,9 @@ example, as part of preview for iconified frames. --- ** New user option 'menu-bar-close-window'. -When non-nil, selecting Close from the File menu or clicking Close in -the tool bar will result in the current window being closed, if -possible. +When non-nil, selecting "Close" from the "File" menu or clicking +"Close" in the tool bar will result in the current window being +closed, if possible. +++ ** 'write-region-inhibit-fsync' now defaults to t in interactive mode, @@ -297,9 +297,8 @@ using this new option. (Or set 'display-buffer-alist' directly.) +++ *** New builtin Eshell command 'compile'. - This command runs another command, sending its output to a compilation -buffer when the command would output interatively. This can be useful +buffer when the command would output interactively. This can be useful when defining aliases so that they produce a compilation buffer when appropriate, but still allow piping the output elsewhere if desired. For more information, see the "(eshell) Built-ins" node in the Eshell @@ -656,12 +655,12 @@ of the accessibility of remote files can now time out if ** Notifications +++ -*** Allow to use Icon Naming Specification for app-icon +*** Allow to use Icon Naming Specification for ':app-icon'. You can use a symbol as the value for ':app-icon' to provide icon name without specifying a file, like this: - (notifications-notify - :title "I am playing music" :app-icon 'multimedia-player) + (notifications-notify + :title "I am playing music" :app-icon 'multimedia-player) ** Image Dired @@ -774,15 +773,15 @@ The compatibility aliases 'x-defined-colors', 'x-color-defined-p', 'x-color-values', and 'x-display-color-p' are now obsolete. +++ -** 'easy-mmode-define-{minor-mode,global-mode}' aliases are now obsolete. +** 'easy-mmode-define-{minor,global}-mode' aliases are now obsolete. Use 'define-minor-mode' and 'define-globalized-minor-mode' instead. * Lisp Changes in Emacs 30.1 ** 'defadvice' is marked as obsolete. -See (info "(elisp)Porting Old Advice") for help converting them -to use `advice-add` or `define-advice instead. +See the "(elisp) Porting Old Advice" node for help converting them +to use 'advice-add' or 'define-advice' instead. +++ ** New value 'if-regular' for the REPLACE argument to 'insert-file-contents'. @@ -793,7 +792,7 @@ rather than signaling an error. +++ ** New variable 'current-key-remap-sequence'. It is bound to the key sequence that caused a call to a function bound -within `function-key-map' or `input-decode-map' around those calls. +within 'function-key-map' or 'input-decode-map' around those calls. +++ ** New variables describing the names of built in programs. commit f09126bd903a5fa1658c1555402b6785692dac22 Author: Gregory Heytings Date: Wed Aug 16 17:46:16 2023 +0000 Improve 'emake --quieter' * admin/emake: Improve the output when the --quieter option is used. diff --git a/admin/emake b/admin/emake index 2badbe80358..c9e59d34067 100755 --- a/admin/emake +++ b/admin/emake @@ -138,14 +138,20 @@ The GNU allocators don't work|\ while read do C="" - (($NOCOLOR == 0)) && [[ "X${REPLY:0:1}" != "X " ]] && C="\033[1;31m" - (($NOCOLOR == 0)) && [[ "X${REPLY:0:3}" == "X " ]] && C="\033[1;31m" + E=0 + [ ! -v L ] && L=80 + [[ "X${REPLY:0:1}" != "X " ]] && E=1 + [[ "X${REPLY:0:3}" == "X " ]] && E=1 + (($NOCOLOR == 0)) && (($E == 1)) && C="\033[1;31m" + (($NOCOLOR == 0)) && (($E == 1)) && C="\033[1;31m" if (($QUIETER == 0)) then - [[ "X$C" == "X" ]] && printf "%s\n" "$REPLY" || printf "$C%s\033[0m\n" "$REPLY" + (($E == 0)) && printf "%s\n" "$REPLY" || printf "${C}%s\033[0m\n" "$REPLY" else - [[ "X$C" == "X" ]] && printf "%-80s\r" "$REPLY" || printf "$C%-80s\033[0m\n" "$REPLY" + (($E == 0)) && printf "%-${L}s\r" "$REPLY" || printf "${C}%-${L}s\033[0m\n" "$REPLY" fi + L=${#REPLY} + (($L < 80)) && L=80 done # If make failed, exit now with its error code. commit 19513a654e6cec0b8813c90a3f8216bb5e441baa Author: Michael Albinus Date: Wed Aug 16 19:31:05 2023 +0200 ; Fix last change * lisp/net/tramp-sh.el (tramp-bundle-read-file-names): Replace "echo -n" by "printf", it isn't portable. (Bug#65321) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 4e6ba6e38d7..0599f89655c 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1077,10 +1077,10 @@ tramp-bundle-read-file-names "echo \"(\" while read file; do quoted=`echo \"$file\" | sed -e \"s/\\\"/\\\\\\\\\\\\\\\\\\\"/\"` - echo -n \"(\\\"$quoted\\\"\" - if %s \"$file\"; then echo -n \" t\"; else echo -n \" nil\"; fi - if %s \"$file\"; then echo -n \" t\"; else echo -n \" nil\"; fi - if %s \"$file\"; then echo \" t)\"; else echo \" nil)\"; fi + printf \"(%%b\" \"\\\"$quoted\\\"\" + if %s \"$file\"; then printf \" %%b\" t; else printf \" %%b\" nil; fi + if %s \"$file\"; then printf \" %%b\" t; else printf \" %%b\" nil; fi + if %s \"$file\"; then printf \" %%b)\n\" t; else printf \" %%b)\n\" nil; fi done echo \")\"" "Script to check file attributes of a bundle of files. @@ -1088,7 +1088,8 @@ tramp-bundle-read-file-names existence, file readability, and file directory. Input shall be read via here-document, otherwise the command could exceed maximum length of command line. -Format specifiers \"%s\" are replaced before the script is used.") +Format specifiers \"%s\" are replaced before the script is used, +percent characters need to be doubled.") ;; New handlers should be added here. ;;;###tramp-autoload commit 647bcec4f537d49b7a1e6d200ec787fec11ed81a Author: Jim Porter Date: Sun Aug 13 12:33:17 2023 -0700 Show how to call an Elisp function of the same name as an Eshell built-in * doc/misc/eshell.texi (Built-ins): Expand documentation. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 211b13c995c..6890728a81d 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -409,8 +409,18 @@ Built-ins (These built-in commands are just ordinary Lisp functions whose names begin with @code{eshell/}.) In order to call the external variant of a built-in command @code{foo}, you could call @code{*foo}. Usually, -this should not be necessary. You can check what will be applied by -the @code{which} command: +this should not be necessary; if the Eshell version of a command +doesn't support a particular option, it will automatically invoke the +external command for you. + +Some built-in Eshell commands provide enhanced versions of regular +Emacs Lisp functions. If you want to call the regular Emacs Lisp +version, you can write your command in Lisp form (@pxref{Invocation}). +To call the regular version in command form, you can use +@code{funcall} or @code{apply}, e.g.@: @samp{funcall #'compile "make all"} +(@pxref{Calling Functions,,, elisp, GNU Emacs Lisp Reference Manual}). + +You can check what will be applied by the @code{which} command: @example ~ $ which ls @@ -420,14 +430,19 @@ Built-ins @end example If you want to discard a given built-in command, you could declare an -alias (@pxref{Aliases}). Example: +alias (@pxref{Aliases}). For example: @example -~ $ which sudo -eshell/sudo is a compiled Lisp function in `em-tramp.el'. -~ $ alias sudo '*sudo $@@*' -~ $ which sudo -sudo is an alias, defined as "*sudo $@@*" +@group +~ $ alias ls '*ls $@@*' +~ $ which ls +ls is an alias, defined as "*ls $@@*" +@end group +@group +~ $ alias compile 'apply #''compile $*' +~ $ which compile +ls is an alias, defined as "apply #'compile $*" +@end group @end example Some of the built-in commands have different behavior from their commit c4915678f3881765caac5036b1f20b02175469e3 Author: Jim Porter Date: Sun Aug 13 12:07:39 2023 -0700 Add 'compile' builtin command for Eshell * lisp/eshell/em-unix.el (eshell-compile, eshell/compile): New functions. (eshell/make, eshell-grep): Use 'eshell-compile'. (eshell/glimpse): It's no longer necessary to let-bind 'null-device'; 'eshell-grep' no longer calls 'grep' (the Lisp function), which needed 'null-device' to be nil for this case. * test/lisp/eshell/em-unix-tests.el: New file. * doc/misc/eshell.texi (Built-ins): Document the 'compile' builtin. * etc/NEWS: Announce this change (bug#65273). diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index ca31cb2589d..211b13c995c 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -523,6 +523,17 @@ Built-ins command @command{clear}, this command deletes content in the Eshell buffer. +@item compile +@cmindex compile +Run an external command, sending its output to a compilation buffer if +the command would output to the screen and is not part of a pipeline +or subcommand. This is particularly useful when defining aliases, so +that interactively, the output shows up in a compilation buffer, but +you can still pipe the output elsewhere if desired. For example, if +you have a grep-like command on your system, you might define an alias +for it like so: @samp{alias mygrep 'compile --mode=grep-mode -- mygrep +$*'}. + @item cp @cmindex cp Copy a file to a new location or copy multiple files to the same diff --git a/etc/NEWS b/etc/NEWS index 57f04609679..010d59401ff 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -295,6 +295,16 @@ using this new option. (Or set 'display-buffer-alist' directly.) ** Eshell ++++ +*** New builtin Eshell command 'compile'. + +This command runs another command, sending its output to a compilation +buffer when the command would output interatively. This can be useful +when defining aliases so that they produce a compilation buffer when +appropriate, but still allow piping the output elsewhere if desired. +For more information, see the "(eshell) Built-ins" node in the Eshell +manual. + +++ *** New splice operator for Eshell dollar expansions. Dollar expansions in Eshell now let you splice the elements of the diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index a8c86b925bc..509b2d31819 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el @@ -692,19 +692,56 @@ eshell/cat ;; special front-end functions for compilation-mode buffers +(defun eshell-compile (command args &optional method mode) + "Run an external COMMAND with ARGS using a compilation buffer when possible. +COMMAND should be a list of command-line arguments. By default, +if the command is outputting to the screen and is not part of a +pipeline or subcommand, open an compilation buffer to hold the +results; otherwise, write the output on stdout. + +If METHOD is `interactive', always open a compilation buffer. If +METHOD is `plain', always write to stdout. + +MODE, if specified, is the major mode to set in the compilation +buffer (see `compilation-start')." + (if (and (not (eq method 'interactive)) + (or (eq method 'plain) + eshell-in-pipeline-p + eshell-in-subcommand-p + (not (eshell-interactive-output-p)))) + (throw 'eshell-replace-command + (eshell-parse-command (concat "*" command) args)) + (compile + (mapconcat #'shell-quote-argument + (eshell-stringify-list (flatten-tree (cons command args))) + " ") + mode))) + +(defun eshell/compile (&rest args) + "Run an external COMMAND using a compilation buffer when possible. +See `eshell-compile'." + (eshell-eval-using-options + "compile" args + '((?m "mode" t mode "the mode to set in the compilation buffer") + (?i "interactive" 'interactive method "always open a compilation buffer") + (?p "plain" 'plain method "always write to stdout") + :usage "[-p | -i] [-m MODE] COMMAND... +Run COMMAND in a compilation buffer when outputting to the screen and +not part of a pipeline or subcommand." + :parse-leading-options-only) + (when (stringp mode) + (setq mode (intern mode))) + (eshell-compile (car args) (cdr args) method mode))) + +(put 'eshell/compile 'eshell-no-numeric-conversions t) + (defun eshell/make (&rest args) "Use `compile' to do background makes. Fallback to standard make when called synchronously." - (if (and eshell-current-subjob-p - (eshell-interactive-output-p)) - (let ((compilation-process-setup-function - (list 'lambda nil - (list 'setq 'process-environment - (list 'quote (eshell-copy-environment)))))) - (compile (concat "make " (eshell-flatten-and-stringify args)))) - (throw 'eshell-replace-command - (eshell-parse-command "*make" (eshell-stringify-list - (flatten-tree args)))))) + (eshell-compile "make" args + ;; Use plain output unless we're executing in the + ;; background. + (not eshell-current-subjob-p))) (put 'eshell/make 'eshell-no-numeric-conversions t) @@ -777,22 +814,10 @@ eshell-grep external command." (if (and maybe-use-occur eshell-no-grep-available) (eshell-poor-mans-grep args) - (if (or eshell-plain-grep-behavior - (not (and (eshell-interactive-output-p) - (not eshell-in-pipeline-p) - (not eshell-in-subcommand-p)))) - (throw 'eshell-replace-command - (eshell-parse-command (concat "*" command) - (eshell-stringify-list - (flatten-tree args)))) - (let* ((args (mapconcat 'identity - (mapcar 'shell-quote-argument - (eshell-stringify-list - (flatten-tree args))) - " ")) - (cmd (format "%s -n %s" command args)) - compilation-scroll-output) - (grep cmd))))) + (eshell-compile command (cons "-n" args) + (and eshell-plain-grep-behavior + 'interactive) + #'grep-mode))) (defun eshell/grep (&rest args) "Use Emacs grep facility instead of calling external grep." @@ -816,8 +841,7 @@ eshell/rgrep (defun eshell/glimpse (&rest args) "Use Emacs grep facility instead of calling external glimpse." - (let (null-device) - (eshell-grep "glimpse" (append '("-z" "-y") args)))) + (eshell-grep "glimpse" (append '("-z" "-y") args))) ;; completions rules for some common UNIX commands diff --git a/test/lisp/eshell/em-unix-tests.el b/test/lisp/eshell/em-unix-tests.el new file mode 100644 index 00000000000..d7b6c55fe45 --- /dev/null +++ b/test/lisp/eshell/em-unix-tests.el @@ -0,0 +1,68 @@ +;;; em-unix-tests.el --- em-unix test suite -*- lexical-binding:t -*- + +;; Copyright (C) 2023 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Tests for Eshell's implementation of various UNIX commands. + +;;; Code: + +(require 'ert) +(require 'em-unix) + +(require 'eshell-tests-helpers + (expand-file-name "eshell-tests-helpers" + (file-name-directory (or load-file-name + default-directory)))) + +;;; Tests: + +(ert-deftest em-unix-test/compile/interactive () + "Check that `eshell/compile' opens a compilation buffer interactively." + (skip-unless (executable-find "echo")) + (with-temp-eshell + (eshell-match-command-output "compile echo hello" + "#") + (with-current-buffer "*compilation*" + (forward-line 3) + (should (looking-at "echo hello"))))) + +(ert-deftest em-unix-test/compile/noninteractive () + "Check that `eshell/compile' writes to stdout noninteractively." + (skip-unless (executable-find "echo")) + (eshell-command-result-equal "compile echo hello" + "hello\n")) + +(ert-deftest em-unix-test/compile/pipeline () + "Check that `eshell/compile' writes to stdout from a pipeline." + (skip-unless (and (executable-find "echo") + (executable-find "cat"))) + (with-temp-eshell + (eshell-match-command-output "compile echo hello | *cat" + "\\`hello\n"))) + +(ert-deftest em-unix-test/compile/subcommand () + "Check that `eshell/compile' writes to stdout from a subcommand." + (skip-unless (and (executable-find "echo") + (executable-find "cat"))) + (with-temp-eshell + (eshell-match-command-output "echo ${compile echo hello}" + "\\`hello\n"))) + +;; em-unix-tests.el ends here commit b73ab54ae67fb6042faff251e7e08293a3d303ed Author: Gregory Heytings Date: Wed Aug 16 15:58:56 2023 +0000 Various improvements to 'emake' * admin/emake: Highlight the result of 'check-maybe' in red. Reindent a few lines. Add a line in the filters. Clarify the documentation. diff --git a/admin/emake b/admin/emake index 0aa1178768d..2badbe80358 100755 --- a/admin/emake +++ b/admin/emake @@ -19,13 +19,20 @@ # This script is meant to be used as ./admin/emake, and will compile # the Emacs tree with virtually all of the informational messages -# removed, and with errors/warnings highlighted in red. It'll give a -# quick overview to confirm that nothing has broken, for instance +# removed, and with errors/warnings highlighted in red. It will also +# run the test files belonging to files that have changed. It'll give +# a quick overview to confirm that nothing has broken, for instance # after doing a "git pull". It's not meant to be used during actual # development, because it removes so much information that commands # like `next-error' won't be able to jump to the source code where # errors are. +# It has a few options: +# with --no-color errors/warnings are not highlighted +# with --no-check test files are not run +# with --no-fast the FAST=true make variable is not set (see Makefile.in) +# with --quieter only errors/warnings remain visible + cores=1 # Determine the number of cores. @@ -96,6 +103,7 @@ GEN.*loaddefs|\ ^.Read INSTALL.REPO for more|\ ^Your system has the required tools.|\ ^Building aclocal.m4|\ +^Building 'aclocal.m4'|\ ^ Running 'autoreconf|\ ^You can now run './configure'|\ ^./configure|\ @@ -129,15 +137,15 @@ The GNU allocators don't work|\ " | \ while read do - C="" - (($NOCOLOR == 0)) && [[ "X${REPLY:0:1}" != "X " ]] && C="\033[1;31m" - (($NOCOLOR == 0)) && [[ "X${REPLY:0:3}" == "X " ]] && C="\033[1;31m" - if (($QUIETER == 0)) - then - [[ "X$C" == "X" ]] && printf "%s\n" "$REPLY" || printf "$C%s\033[0m\n" "$REPLY" - else - [[ "X$C" == "X" ]] && printf "%-80s\r" "$REPLY" || printf "$C%-80s\033[0m\n" "$REPLY" - fi + C="" + (($NOCOLOR == 0)) && [[ "X${REPLY:0:1}" != "X " ]] && C="\033[1;31m" + (($NOCOLOR == 0)) && [[ "X${REPLY:0:3}" == "X " ]] && C="\033[1;31m" + if (($QUIETER == 0)) + then + [[ "X$C" == "X" ]] && printf "%s\n" "$REPLY" || printf "$C%s\033[0m\n" "$REPLY" + else + [[ "X$C" == "X" ]] && printf "%-80s\r" "$REPLY" || printf "$C%-80s\033[0m\n" "$REPLY" + fi done # If make failed, exit now with its error code. @@ -149,4 +157,13 @@ done # changed since last time. make -j$cores check-maybe 2>&1 | \ sed -n '/contained unexpected results/,$p' | \ - grep -E --line-buffered -v "^make" + grep -E --line-buffered -v "^make" | \ +while read +do + if (($NOCOLOR == 0)) + then + printf "\033[1;31m%s\033[0m\n" "$REPLY" + else + printf "%s\n" "$REPLY" + fi +done commit 1e2d0775151f144830dfb9e9f1cd460f1e480270 Author: Gregory Heytings Date: Wed Aug 16 15:58:48 2023 +0000 Add a target to byte-compile all tests without running them * test/Makefile.in: Add a check-byte-compile target. * Makefile.in: Add the check-byte-compile target to CHECK_TARGETS. diff --git a/Makefile.in b/Makefile.in index b47e88f6970..fdd9353e254 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1116,7 +1116,7 @@ TAGS tags: $(MAKE) -C doc/lispref tags $(MAKE) -C doc/misc tags -CHECK_TARGETS = check check-maybe check-expensive check-all +CHECK_TARGETS = check check-maybe check-expensive check-all check-byte-compile .PHONY: $(CHECK_TARGETS) $(CHECK_TARGETS): all $(MAKE) -C test $@ diff --git a/test/Makefile.in b/test/Makefile.in index e2a14c4dd92..4e53efeb9a8 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -326,6 +326,9 @@ .PHONY: check-maybe: check-no-automated-subdir @${MAKE} check-doit SELECTOR="${SELECTOR_ACTUAL}" +check-byte-compile: + @${MAKE} $(ELFILES:.el=.elc) + ## Run the tests. .PHONY: check-doit ## We can't put LOGFILES as prerequisites, because that would stop the commit c287a0fdc7e3f70d819ef8efd1d7922b33df164c Author: Gregory Heytings Date: Wed Aug 16 15:58:39 2023 +0000 Simplify 'with-restriction' and 'without-restriction' * lisp/subr.el (with-restriction, without-restriction): Merge the bodies of the 'internal--with-restriction' and 'internal--without-restriction' function into the macros. The result is more efficient than a funcall. (internal--with-restriction, internal--without-restriction): Remove. Suggested by Mattias Engdegård. diff --git a/lisp/subr.el b/lisp/subr.el index 08e6f816dee..616f0a8dfb6 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4116,17 +4116,10 @@ with-restriction \(fn START END [:label LABEL] BODY)" (declare (indent 2) (debug t)) (if (eq (car rest) :label) - `(internal--with-restriction ,start ,end (lambda () ,@(cddr rest)) - ,(cadr rest)) - `(internal--with-restriction ,start ,end (lambda () ,@rest)))) - -(defun internal--with-restriction (start end body &optional label) - "Helper function for `with-restriction', which see." - (save-restriction - (if label - (internal--labeled-narrow-to-region start end label) - (narrow-to-region start end)) - (funcall body))) + `(save-restriction + (internal--labeled-narrow-to-region ,start ,end ,(cadr rest)) + ,@(cddr rest)) + `(save-restriction (narrow-to-region ,start ,end) ,@rest))) (defmacro without-restriction (&rest rest) "Execute BODY without restrictions. @@ -4139,17 +4132,8 @@ without-restriction \(fn [:label LABEL] BODY)" (declare (indent 0) (debug t)) (if (eq (car rest) :label) - `(internal--without-restriction (lambda () ,@(cddr rest)) - ,(cadr rest)) - `(internal--without-restriction (lambda () ,@rest)))) - -(defun internal--without-restriction (body &optional label) - "Helper function for `without-restriction', which see." - (save-restriction - (if label - (internal--labeled-widen label) - (widen)) - (funcall body))) + `(save-restriction (internal--labeled-widen ,(cadr rest)) ,@(cddr rest)) + `(save-restriction (widen) ,@rest))) (defun find-tag-default-bounds () "Determine the boundaries of the default tag, based on text at point. commit 9e9e11648d3d5514de85edfb69f0949a062f4716 Author: Gregory Heytings Date: Wed Aug 16 15:58:29 2023 +0000 Simplify 'without-restriction' This simplification is symmetrical to 01fb898420. * src/editfns.c: (Finternal__labeled_widen): Add a call to 'Fwiden', and rename from 'internal--unlabel-restriction'. (unwind_labeled_narrow_to_region): Use the renamed function, and remove the call to 'Fwiden'. (syms_of_editfns): Rename the symbol. * lisp/subr.el (internal--without-restriction): Use the renamed function. diff --git a/lisp/subr.el b/lisp/subr.el index 7fb5c4326d1..08e6f816dee 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4146,8 +4146,9 @@ without-restriction (defun internal--without-restriction (body &optional label) "Helper function for `without-restriction', which see." (save-restriction - (if label (internal--unlabel-restriction label)) - (widen) + (if label + (internal--labeled-widen label) + (widen)) (funcall body))) (defun find-tag-default-bounds () diff --git a/src/editfns.c b/src/editfns.c index a3e4ca12028..02fca3f5714 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2691,7 +2691,7 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region, labeled restriction was entered (which may be a narrowing that was set by the user and is visible on display). This alist is used internally by narrow-to-region, internal--labeled-narrow-to-region, - widen, internal--unlabel-restriction and save-restriction. For + widen, internal--labeled-widen and save-restriction. For efficiency reasons, an alist is used instead of a buffer-local variable: otherwise reset_outermost_restrictions, which is called during each redisplay cycle, would have to loop through all live @@ -2867,8 +2867,7 @@ labeled_restrictions_restore (Lisp_Object buf_and_restrictions) static void unwind_labeled_narrow_to_region (Lisp_Object label) { - Finternal__unlabel_restriction (label); - Fwiden (); + Finternal__labeled_widen (label); } /* Narrow current_buffer to BEGV-ZV with a restriction labeled with @@ -2991,7 +2990,7 @@ positions (integers or markers) bounding the text that should DEFUN ("internal--labeled-narrow-to-region", Finternal__labeled_narrow_to_region, Sinternal__labeled_narrow_to_region, 3, 3, 0, - doc: /* Restrict editing in this buffer to START-END, and label the restriction with LABEL. + doc: /* Restrict this buffer to START-END, and label the restriction with LABEL. This is an internal function used by `with-restriction'. */) (Lisp_Object start, Lisp_Object end, Lisp_Object label) @@ -3009,9 +3008,9 @@ DEFUN ("internal--labeled-narrow-to-region", Finternal__labeled_narrow_to_region return Qnil; } -DEFUN ("internal--unlabel-restriction", Finternal__unlabel_restriction, - Sinternal__unlabel_restriction, 1, 1, 0, - doc: /* If the current restriction is labeled with LABEL, remove its label. +DEFUN ("internal--labeled-widen", Finternal__labeled_widen, + Sinternal__labeled_widen, 1, 1, 0, + doc: /* Remove the current restriction if it is labeled with LABEL, and widen. This is an internal function used by `without-restriction'. */) (Lisp_Object label) @@ -3019,6 +3018,7 @@ DEFUN ("internal--unlabel-restriction", Finternal__unlabel_restriction, Lisp_Object buf = Fcurrent_buffer (); if (EQ (labeled_restrictions_peek_label (buf), label)) labeled_restrictions_pop (buf); + Fwiden (); return Qnil; } @@ -4958,7 +4958,7 @@ syms_of_editfns (void) defsubr (&Swiden); defsubr (&Snarrow_to_region); defsubr (&Sinternal__labeled_narrow_to_region); - defsubr (&Sinternal__unlabel_restriction); + defsubr (&Sinternal__labeled_widen); defsubr (&Ssave_restriction); defsubr (&Stranspose_regions); } commit d622602452cfcad01793e0f9340bdbe9034dc137 Author: Gregory Heytings Date: Wed Aug 16 15:58:25 2023 +0000 Fix combine-change-call * lisp/subr.el (combine-change-calls-1): Rewrite and document the part which creates the undo-list element. Fixes bug#60467 and bug#64989. diff --git a/lisp/subr.el b/lisp/subr.el index 58ec642dd92..7fb5c4326d1 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -5140,30 +5140,41 @@ combine-change-calls-1 (kill-local-variable 'before-change-functions)) (if local-acf (setq after-change-functions acf) (kill-local-variable 'after-change-functions)))) - (when (not (eq buffer-undo-list t)) - (let ((ap-elt - (list 'apply - (- end end-marker) - beg - (marker-position end-marker) - #'undo--wrap-and-run-primitive-undo - beg (marker-position end-marker) - ;; We will truncate this list by side-effect below. - buffer-undo-list)) - (ptr buffer-undo-list)) - (if (not (eq buffer-undo-list old-bul)) - (progn - (while (and (not (eq (cdr ptr) old-bul)) - ;; In case garbage collection has removed OLD-BUL. - (or (cdr ptr) - (progn - (message "combine-change-calls: buffer-undo-list broken") - nil))) - (setq ptr (cdr ptr))) - ;; Truncate the list that's in the `apply' entry. - (setcdr ptr nil) - (push ap-elt buffer-undo-list) - (setcdr buffer-undo-list old-bul))))) + ;; If buffer-undo-list is neither t (in which case undo + ;; information is not recorded) nor equal to buffer-undo-list + ;; before body was funcalled (in which case (funcall body) did + ;; not add items to buffer-undo-list) ... + (unless (or (eq buffer-undo-list t) + (eq buffer-undo-list old-bul)) + (let ((ptr buffer-undo-list) body-undo-list) + ;; ... then loop over buffer-undo-list, until the head of + ;; buffer-undo-list before body was funcalled is found, or + ;; ptr is nil (which may happen if garbage-collect has + ;; been called after (funcall body) and has removed + ;; entries of buffer-undo-list that were added by (funcall + ;; body)), and add these entries to body-undo-list. + (while (and ptr (not (eq ptr old-bul))) + (push (car ptr) body-undo-list) + (setq ptr (cdr ptr))) + (setq body-undo-list (nreverse body-undo-list)) + ;; Warn if garbage-collect has truncated buffer-undo-list + ;; behind our back. + (when (and old-bul (not ptr)) + (message + "combine-change-calls: buffer-undo-list has been truncated")) + ;; Add an (apply ...) entry to buffer-undo-list, using + ;; body-undo-list ... + (push (list 'apply + (- end end-marker) + beg + (marker-position end-marker) + #'undo--wrap-and-run-primitive-undo + beg (marker-position end-marker) + body-undo-list) + buffer-undo-list) + ;; ... and set the cdr of buffer-undo-list to + ;; buffer-undo-list before body was funcalled. + (setcdr buffer-undo-list old-bul))) (if (not inhibit-modification-hooks) (run-hook-with-args 'after-change-functions beg (marker-position end-marker) commit 1ad318cf2ae22d945f8bfcd61981d619467a36da Author: Mattias Engdegård Date: Wed Aug 16 14:57:48 2023 +0200 ob-tangle.el: fix unintended range in regexp * lisp/org/ob-tangle.el (org-babel-interpret-file-mode): Repair parts of regexp that should only match +, - and =. * lisp/files.el (file-modes-symbolic-to-number): Fix the same error in a doc string; this seems to be where the mistake originated. diff --git a/lisp/files.el b/lisp/files.el index 03675a34f3a..68c0a10792d 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -8553,7 +8553,7 @@ file-modes-number-to-symbolic (defun file-modes-symbolic-to-number (modes &optional from) "Convert symbolic file modes to numeric file modes. MODES is the string to convert, it should match -\"[ugoa]*([+-=][rwxXstugo]*)+,...\". +\"[ugoa]*([+=-][rwxXstugo]*)+,...\". See Info node `(coreutils)File permissions' for more information on this notation. FROM (or 0 if nil) gives the mode bits on which to base permissions if diff --git a/lisp/org/ob-tangle.el b/lisp/org/ob-tangle.el index 0b816a7c13c..a833037ca2b 100644 --- a/lisp/org/ob-tangle.el +++ b/lisp/org/ob-tangle.el @@ -357,7 +357,7 @@ org-babel-interpret-file-mode (error "File mode %S not recognized as a valid format." mode)) ((string-match-p "^o0?[0-7][0-7][0-7]$" mode) (string-to-number (replace-regexp-in-string "^o" "" mode) 8)) - ((string-match-p "^[ugoa]*\\(?:[+-=][rwxXstugo]*\\)+\\(,[ugoa]*\\(?:[+-=][rwxXstugo]*\\)+\\)*$" mode) + ((string-match-p "^[ugoa]*\\(?:[+=-][rwxXstugo]*\\)+\\(,[ugoa]*\\(?:[+=-][rwxXstugo]*\\)+\\)*$" mode) ;; Match regexp taken from `file-modes-symbolic-to-number'. (file-modes-symbolic-to-number mode org-babel-tangle-default-file-mode)) ((string-match-p "^[r-][w-][xs-][r-][w-][xs-][r-][w-][x-]$" mode) commit ca687839294b78800339b99b19a61cf098638dd8 Author: Mattias Engdegård Date: Wed Aug 16 13:53:33 2023 +0200 Fix Info parser regexp mistake * lisp/info.el (Info-split-parameter-string): The `\sX` syntax construct isn't valid inside character alternatives; follow the obvious intention. diff --git a/lisp/info.el b/lisp/info.el index 035dff66e75..463aea93376 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1587,7 +1587,7 @@ Info-split-parameter-string (let ((start 0) (parameter-alist)) (while (string-match - "\\s *\\([^=]+\\)=\\(?:\\([^\\s \"]+\\)\\|\\(?:\"\\(\\(?:[^\\\"]\\|\\\\[\\\"]\\)*\\)\"\\)\\)" + "\\s *\\([^=]+\\)=\\(?:\\([^\"[:space:]]+\\)\\|\\(?:\"\\(\\(?:[^\\\"]\\|\\\\[\\\"]\\)*\\)\"\\)\\)" parameter-string start) (setq start (match-end 0)) (push (cons (match-string 1 parameter-string) commit 5b879501339b9426661fbf2a783287ad0949e3d6 Author: Mattias Engdegård Date: Wed Aug 16 13:33:48 2023 +0200 Remedy wrong-looking \(:?...\) regexp constructs When we see \(:?...\) in a regexp it very much looks like a typo for a \(?:...\) construct and often is, so do something about all of these (one of which being another mistake). Doing so silences an optional relint check. * lisp/comint.el (comint-replace-by-expanded-history-before-point): * lisp/term.el (term-replace-by-expanded-history-before-point): Move :? out from capturing group where it does not need to be, to avoid confusion. * lisp/emacs-lisp/cl-indent.el (common-lisp-loop-part-indentation): A capturing group isn't needed here; turn it into simple bracketing. * lisp/progmodes/sql.el (sql--completion-table): Change :? into ?: which was clearly meant here. diff --git a/lisp/comint.el b/lisp/comint.el index 5161d01515c..777795bcb46 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -1440,7 +1440,7 @@ comint-replace-by-expanded-history-before-point (if dry-run (throw dry-run 'message)) (goto-char (match-end 0)) (message "Absolute reference cannot be expanded")) - ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?") + ((looking-at "!-\\([0-9]+\\):?\\([0-9^$*-]+\\)?") ;; Just a number of args from `number' lines backward. (if dry-run (throw dry-run 'history)) (let ((number (1- (string-to-number @@ -1464,7 +1464,7 @@ comint-replace-by-expanded-history-before-point t t) (message "History item: previous")) ((looking-at - "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?") + "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\):?\\([0-9^$*-]+\\)?") ;; Most recent input starting with or containing (possibly ;; protected) string, maybe just a number of args. Phew. (if dry-run (throw dry-run 'expand)) diff --git a/lisp/emacs-lisp/cl-indent.el b/lisp/emacs-lisp/cl-indent.el index 8920579755e..ee50f572157 100644 --- a/lisp/emacs-lisp/cl-indent.el +++ b/lisp/emacs-lisp/cl-indent.el @@ -192,7 +192,7 @@ common-lisp-loop-part-indentation (list (cond ((not (lisp-extended-loop-p (elt state 1))) (+ loop-indentation lisp-simple-loop-indentation)) - ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)") + ((looking-at "^\\s-*\\(?::?\\sw+\\|;\\)") (+ loop-indentation lisp-loop-keyword-indentation)) (t (+ loop-indentation lisp-loop-forms-indentation))) diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 89d62ab3a61..279285b9326 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@ -4033,7 +4033,7 @@ sql-completion-sqlbuf (defun sql--completion-table (string pred action) (when sql-completion-sqlbuf (with-current-buffer sql-completion-sqlbuf - (let ((schema (and (string-match "\\`\\(\\sw\\(:?\\sw\\|\\s_\\)*\\)[.]" string) + (let ((schema (and (string-match "\\`\\(\\sw\\(?:\\sw\\|\\s_\\)*\\)[.]" string) (downcase (match-string 1 string))))) ;; If we haven't loaded any object name yet, load local schema diff --git a/lisp/term.el b/lisp/term.el index 5d43ea56791..a80db33aab5 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -2067,7 +2067,7 @@ term-replace-by-expanded-history-before-point ;; We cannot know the interpreter's idea of input line numbers. (goto-char (match-end 0)) (message "Absolute reference cannot be expanded")) - ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?") + ((looking-at "!-\\([0-9]+\\):?\\([0-9^$*-]+\\)?") ;; Just a number of args from `number' lines backward. (let ((number (1- (string-to-number (buffer-substring (match-beginning 1) @@ -2090,7 +2090,7 @@ term-replace-by-expanded-history-before-point t t) (message "History item: previous")) ((looking-at - "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?") + "!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\):?\\([0-9^$*-]+\\)?") ;; Most recent input starting with or containing (possibly ;; protected) string, maybe just a number of args. Phew. (let* ((mb1 (match-beginning 1)) (me1 (match-end 1)) commit d6c473a91da3ce8decae03ed32b91affbb040890 Author: Po Lu Date: Wed Aug 16 22:05:47 2023 +0800 * etc/PROBLEMS: Document a problem with the Anonymous Pro font. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index e4bbfc8d286..6a4c8cdb34c 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -3398,6 +3398,56 @@ you are not seeing problems with character display, as the automatically generated instructions result in superior display results that are easier to read. +** The "Anonymous Pro" font displays incorrectly. + +Glyphs instruction code within the Anonymous Pro font relies on +undocumented features of the Microsoft TrueType font scaler, namely +that the scaler always resets the "projection" and "freedom" vector +interpreter control registers after the execution of the font +pre-program, which sets them to a value that is perpendicular to the +horizontal plane of movement. + +Since Emacs does not provide this "feature", various points within +glyphs are moved vertically rather than horizontally when a glyph +program later executes an "MIRP" (Move Indirect Relative Point) +instruction. + +This can be remedied in two ways; the first (and the easiest) is to +replace its instruction code with that supplied by "ttfautohint", as +depicted above. The second is to patch the instruction code within +the font itself, using the "ttx" utility: + + https://fonttools.readthedocs.io/en/latest/ttx.html + +First, convert the font to its XML representation: + + $ ttx Anonymous_Pro.ttf + +then, find the end of the section labeled 'prep': + + + + [...] + ROUND[01] /* Round */ + RTG[ ] /* RoundToGrid */ + WCVTP[ ] /* WriteCVTInPixels */ + + + +and insert the following instruction immediately before the closing +'/assembly' tag: + + SVTCA[1] + +(which stands for "Set Vector registers to Control Axis X") + +Then, reassemble the font from the modified XML: + + $ ttx Anonymous_Pro.ttx + +which should produce a modified font by the name of +Anonymous_Pro#1.ttf. + * Build-time problems ** Configuration commit dfe68f2a420e4d85ba2d1723bbdbf7f4bf1d71a6 Author: Eli Zaretskii Date: Wed Aug 16 16:10:55 2023 +0300 ; Fix byte-compiler warnings in comp.el * lisp/emacs-lisp/comp.el: Declare functions and variables defined in comp.c, to avoid byte-compiler warnings. (Bug#65250) diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index bb85ef2bc06..ad0077dadda 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -39,6 +39,23 @@ (require 'warnings) (require 'comp-cstr) +;; These variables and functions are defined in comp.c +(defvar native-comp-enable-subr-trampolines) +(defvar comp-installed-trampolines-h) +(defvar comp-subr-arities-h) +(defvar native-comp-eln-load-path) +(defvar comp-native-version-dir) +(defvar comp-deferred-pending-h) +(defvar comp--no-native-compile) + +(declare-function comp-el-to-eln-rel-filename "comp.c") +(declare-function native-elisp-load "comp.c") +(declare-function comp--release-ctxt "comp.c") +(declare-function comp--init-ctxt "comp.c") +(declare-function comp--compile-ctxt-to-file "comp.c") +(declare-function comp-el-to-eln-filename "comp.c") +(declare-function comp--install-trampoline "comp.c") + (defgroup comp nil "Emacs Lisp native compiler." :group 'lisp) commit 3d7041834f5b874119b7fd0f8024825e48ff636a Author: Eli Zaretskii Date: Wed Aug 16 16:06:20 2023 +0300 Revert "Fix slow "C-h f" in Emacs built without native compilation" This reverts commit 545f95d1a3213318389ecadc7cfff3f48b555b03. It is no longer needed, as comp.el and comp-cstr.el are now byte-compiled even if native-compilation is not built-in. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 81c58ba1998..135ee042dbf 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -715,8 +715,7 @@ help-fns--signature (unless (and (symbolp function) (get function 'reader-construct)) (insert high-usage "\n") - (when-let* ((res (and (native-comp-available-p) - (comp-function-type-spec function))) + (when-let* ((res (comp-function-type-spec function)) (type-spec (car res)) (kind (cdr res))) (insert (format commit 5e9711fe58cd3bd84523e6f2b8b69ab177c13227 Author: Po Lu Date: Wed Aug 16 20:35:08 2023 +0800 ; * etc/MACHINES (Android): Clarify a minor point. diff --git a/etc/MACHINES b/etc/MACHINES index 7e94140a251..c9f6ec265d8 100644 --- a/etc/MACHINES +++ b/etc/MACHINES @@ -147,7 +147,9 @@ the list at the end of this file. GUI capabilities provided by the Android port. We do not know exactly which configurations this works on, but the installation instructions for such a build should be the same as for any Unix - system. + system. (This does in turn imply that such a build must be carried + out on an Android device itself utilizing development tools provided + by third party package repositories.) * Obsolete platforms commit f2f2e6a082a541c60eb25ad6d30707e111082811 Author: Po Lu Date: Wed Aug 16 20:32:04 2023 +0800 Update Android port * configure.ac: Test for getpwent using gl_CHECK_FUNCS_ANDROID. (bug#65319) * etc/MACHINES (Android): Mention that a non-GUI build is also possible on Android. * lisp/loadup.el: Provide for regular builds on Android. (bug#65339) * lisp/wid-edit.el (widget-event-start): Remove function, since event-start now does the same thing. (widget-button--check-and-call-button, widget-button-click): Adjust correspondingly. Reported by Stefan Monnier . * src/sysdep.c (close_output_streams): Apply workarounds for the file descriptor sanitizer on all builds where __ANDROID__ is defined, not just Android port builds. (bug#65340) diff --git a/configure.ac b/configure.ac index 46347a12050..8120935978d 100644 --- a/configure.ac +++ b/configure.ac @@ -5846,11 +5846,14 @@ AC_DEFUN pthread_sigmask strsignal setitimer \ sendto recvfrom getsockname getifaddrs freeifaddrs \ gai_strerror sync \ -getpwent endpwent getgrent endgrent \ +endpwent getgrent endgrent \ renameat2 \ cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np \ pthread_set_name_np]) +# getpwent is not present in older versions of Android. (bug#65319) +gl_CHECK_FUNCS_ANDROID([getpwent], [[#include ]]) + if test "$ac_cv_func_cfmakeraw" != "yes"; then # On some systems (Android), cfmakeraw is inline, so AC_CHECK_FUNCS # cannot find it. Check if some code including termios.h and using diff --git a/etc/MACHINES b/etc/MACHINES index 751d59932c5..7e94140a251 100644 --- a/etc/MACHINES +++ b/etc/MACHINES @@ -143,6 +143,12 @@ the list at the end of this file. See the file java/INSTALL for detailed installation instructions. + It is also possible to build Emacs for Android systems without using + GUI capabilities provided by the Android port. We do not know + exactly which configurations this works on, but the installation + instructions for such a build should be the same as for any Unix + system. + * Obsolete platforms diff --git a/lisp/loadup.el b/lisp/loadup.el index 3ac1224a0ec..38fb0fc1fa9 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -566,7 +566,8 @@ comp-subr-arities-h -(if (eq system-type 'android) +(if (and (eq system-type 'android) + (featurep 'android)) (progn ;; Dumping Emacs on Android works slightly differently from ;; everywhere else. The first time Emacs starts, Emacs dumps @@ -631,7 +632,11 @@ comp-subr-arities-h ;; There's no point keeping old dumps around for ;; the binary used to build Lisp on the build ;; machine. - (featurep 'android) + (or (featurep 'android) + ;; And if this branch is reached with + ;; `system-type' set to Android, this is a + ;; regular Emacs TTY build. (bug#65339) + (eq system-type 'android)) ;; Don't bother adding another name if we're just ;; building bootstrap-emacs. (member dump-mode '("pbootstrap" "bootstrap")))) diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 47531113ba8..9e7c31224e0 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -1084,15 +1084,6 @@ widget-button-click-moves-point "If non-nil, `widget-button-click' moves point to a button after invoking it. If nil, point returns to its original position after invoking a button.") -(defun widget-event-start (event) - "Return the start of EVENT. -If EVENT is not a touchscreen event, simply return its -`event-start'. Otherwise, it is a touchscreen event, so return -the posn of its touchpoint." - (if (eq (car event) 'touchscreen-begin) - (cdadr event) - (event-start event))) - (defun widget-button--check-and-call-button (event button) "Call BUTTON if BUTTON is a widget and EVENT is correct for it. EVENT can either be a mouse event or a touchscreen-begin event. @@ -1106,9 +1097,9 @@ widget-button--check-and-call-button ;; in a save-excursion so that the click on the button ;; doesn't change point. (save-selected-window - (select-window (posn-window (widget-event-start event))) + (select-window (posn-window (event-start event))) (save-excursion - (goto-char (posn-point (widget-event-start event))) + (goto-char (posn-point (event-start event))) (let* ((overlay (widget-get button :button-overlay)) (pressed-face (or (widget-get button :pressed-face) widget-button-pressed-face)) @@ -1179,7 +1170,7 @@ widget-button-click (if (widget-event-point event) (let* ((mouse-1 (memq (event-basic-type event) '(mouse-1 down-mouse-1))) (pos (widget-event-point event)) - (start (widget-event-start event)) + (start (event-start event)) (button (get-char-property pos 'button (and (windowp (posn-window start)) (window-buffer (posn-window start)))))) diff --git a/src/sysdep.c b/src/sysdep.c index 0f8b70c8248..52fbfbd1eb1 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2972,14 +2972,16 @@ errwrite (void const *buf, ptrdiff_t nbuf) close_output_streams (void) { /* Android comes with some kind of ``file descriptor sanitizer'' - that aborts when stdout or stderr is closed. */ + that aborts when stdout or stderr is closed. (bug#65340) -#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY + Perform this unconditionally as long as __ANDROID__ is defined, + since the file descriptor sanitizer also applies to regular TTY + builds under Android. */ + +#ifdef __ANDROID__ fflush (stderr); fflush (stdout); - return; -#endif - +#else /* !__ANDROID__ */ if (close_stream (stdout) != 0) { emacs_perror ("Write error to standard output"); @@ -2993,6 +2995,7 @@ close_output_streams (void) ? fflush (stderr) != 0 || ferror (stderr) : close_stream (stderr) != 0)) _exit (EXIT_FAILURE); +#endif /* __ANDROID__ */ } #ifndef DOS_NT commit 22d031f644d38e385f422ffc4855385d9052659b Author: Michael Albinus Date: Wed Aug 16 11:48:28 2023 +0200 Fix infloop error in Tramp * lisp/net/tramp-sh.el (tramp-find-file-exists-command): Do not call `tramp-get-ls-command'. (Bug#65321) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 426682ddef1..4e6ba6e38d7 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -4255,8 +4255,10 @@ tramp-find-file-exists-command vec (format "%s %s" result existing)) (not (tramp-send-command-and-check vec (format "%s %s" result nonexistent))))) + ;; We cannot use `tramp-get-ls-command', this results in an infloop. + ;; (Bug#65321) (ignore-errors - (and (setq result (format "%s -d" (tramp-get-ls-command vec))) + (and (setq result (format "ls -d >%s" (tramp-get-remote-null-device vec))) (tramp-send-command-and-check vec (format "%s %s" result existing)) (not (tramp-send-command-and-check commit 2eaf1e3efcaa08cf2da6163a1e4360c605fa797c Author: Andrea Corallo Date: Wed Aug 16 10:18:20 2023 +0200 * lisp/Makefile.in (compile-targets): Always byte compile native comp. diff --git a/lisp/Makefile.in b/lisp/Makefile.in index 5af2168a827..c4dd1e7a1f3 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -351,11 +351,7 @@ .PHONY: # TARGETS is set dynamically in the recursive call from 'compile-main'. # Do not build comp.el unless necessary not to exceed max-lisp-eval-depth # in normal builds. -ifneq ($(HAVE_NATIVE_COMP),yes) -compile-targets: $(filter-out ./emacs-lisp/comp-cstr.elc,$(filter-out ./emacs-lisp/comp.elc,$(TARGETS))) -else compile-targets: $(TARGETS) -endif # Compile all the Elisp files that need it. Beware: it approximates # 'no-byte-compile', so watch out for false-positives! commit 3e51847801bd2c1631837dd13994b2fa0ace5233 Author: Po Lu Date: Wed Aug 16 16:12:54 2023 +0800 Improve java/DEBUG * etc/DEBUG: Significantly reword and expand section. (bug#65268) diff --git a/etc/DEBUG b/etc/DEBUG index 005117dcb82..7c54b488cad 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -1101,42 +1101,58 @@ from GDB commands to corresponding LLDB commands there. ** Debugging Emacs on Android. -Attaching GDB to Emacs running inside the Android application setup -requires a special script found in the java/ directory, and a suitable -GDB server binary to be present on the Android device, which is -present on the free versions of Android. Connecting to the device -also requires the `adb' (Android Debug Bridge) utility, and telling -the Android system to resume the Emacs process after startup requires -the Java debugger (jdb). +A script located in the java/ directory automates the procedures +necessary run Emacs under a Gdb session on an Android device connected +to a computer using USB. + +Its requirements are the `adb' (Android Debug Bridge) utility and the +Java debugger (jdb), utilized to cue the Android system to resume the +Emacs process after the debugger attaches. If all three of those tools are present, simply run (from the Emacs source directory): ../java/debug.sh -- [any extra arguments you wish to pass to gdb] -After which, upon waiting a while, the GDB prompt will show up. +Several lines of debug information will be printed, after which the +Gdb prompt should be displayed. -If Emacs crashes and "JNI ERROR" shows up in the Android system log, -then placing a breakpoint on: +If there is no Gdbserver binary present on the device, then specify +one to upload, like so: - break art::JavaVMExt::JniAbort + ../java/debug.sh --gdbserver /path/to/gdbserver -will let you find the source of the crash. +This Gdbserver should be statically linked or compiled using the +Android NDK, and must target the same architecture as the debugee +Emacs binary. Older versions of the Android NDK (such as r24) +distribute suitable Gdbserver binaries, usually located within -If there is no `gdbserver' binary present on the device, then you can -specify one to upload, like so: + prebuilt/android-/gdbserver/gdbserver - ../java/debug.sh --gdbserver /path/to/gdbserver +relative to the root of the NDK distribution. + +To attach Emacs to an existing process on a target device, use the +`--attach-existing' argument to debug.sh: + + ../java/debug.sh --attach-existing [other arguments] + +If multiple Emacs processes are running, debug.sh will display the +names and PIDs of each running process, and prompt for the process +that it should attach to. -In addition, when Emacs runs as a 64-bit process on a system -supporting both 64 and 32-bit binaries, you must specify the path to a -64-bit gdbserver binary. +After Emacs starts, type: + + (gdb) handle SIGUSR1 noprint pass + +to ignore the SIGUSR1 signal that is sent by the Android port's +`select' emulation. If this is overlooked, Emacs will stop each time +a windowing event is received, which is probably unwanted. On top of the debugging procedure described above, Android also -maintains a "logcat" buffer, where it prints backtraces after each -crash. Its contents are of interest when performing post-mortem -debugging after a crash, and can also be retrieved through the `adb' -tool, like so: +maintains a "logcat" buffer, where it prints backtraces during or +after each crash. Its contents are of interest when performing +post-mortem debugging after a crash, and can also be retrieved through +the `adb' tool, like so: $ adb logcat @@ -1246,11 +1262,23 @@ In such situations, the first line explains what infraction Emacs committed, while the ensuing ones print backtraces for each running Java thread at the time of the error. +If Emacs is executing on Android 5.0 and later, placing a breakpoint +on + + (gdb) break art::JavaVMExt::JniAbort + +will set a breakpoint that is hit each time such an error is detected. + Since the logcat output is always rapidly being amended, it is worth piping it to a file or shell command buffer, and then searching for keywords such as "AndroidRuntime", "Fatal signal", or "JNI DETECTED ERROR IN APPLICATION". +Once in a blue moon, it proves necessary to debug Java rather than C +code. To this end, the `--jdb' option will attach the Java debugger +instead of gdbserver. Lametably, it seems impossible to debug both C +and Java code in concert. + This file is part of GNU Emacs.