commit 5a7c46355be1b5a9a8dbfb36ba44969963a3f558 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Wed Mar 27 10:03:15 2024 +0800 Remove IME_FLAG_FORCE_ASCII from password input IME flags * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection): Passwords might also be non-ASCII, and this flag apparently requests an IME limited to ASCII characters, rather than just capable of ASCII input. diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 5b922212c0b..109208b2518 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java @@ -843,10 +843,7 @@ else if (child.getVisibility () != GONE) info.imeOptions |= EditorInfo.IME_ACTION_DONE; if (mode == EmacsService.IC_MODE_PASSWORD) - { - info.imeOptions |= EditorInfo.IME_FLAG_FORCE_ASCII; - info.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD; - } + info.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD; /* Set the initial selection fields. */ info.initialSelStart = selection[0]; commit 48b6e6bd80f2783c6320db1f7e8fb0b3f44e2e9d Author: Stefan Monnier Date: Tue Mar 26 17:41:42 2024 -0400 * lisp/help.el (help-function-arglist): Don't `substitute-command-keys` diff --git a/lisp/help.el b/lisp/help.el index bafe6032942..1ef46e394f3 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -2353,7 +2353,7 @@ the same names as used in the original source code, when possible." ((or (and (byte-code-function-p def) (integerp (aref def 0))) (subrp def) (module-function-p def)) (or (when preserve-names - (let* ((doc (condition-case nil (documentation def) (error nil))) + (let* ((doc (condition-case nil (documentation def 'raw) (error nil))) (docargs (if doc (car (help-split-fundoc doc nil)))) (arglist (if docargs (cdar (read-from-string (downcase docargs))))) commit e5d824b632a68430535f6e94d911871eb0f3f772 Author: Stefan Monnier Date: Tue Mar 26 17:27:29 2024 -0400 cl-preloaded.el: Partly revert last change The change caused type-check errors in auth-source where they use `:type function` constraints on object slots and expect those to be able to hold symbols. * lisp/emacs-lisp/cl-preloaded.el (function): Revert last change. * test/src/data-tests.el (data-tests--cl-type-of): Use `cl-functionp` rather than `functionp` to test `function`. diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el index 6128db05c61..260478c3a39 100644 --- a/lisp/emacs-lisp/cl-preloaded.el +++ b/lisp/emacs-lisp/cl-preloaded.el @@ -436,7 +436,11 @@ For this build of Emacs it's %dbit." (car car) (cdr cdr)) (cl--define-built-in-type function (atom) "Abstract supertype of function values." - :predicate cl-functionp) + ;; FIXME: Historically, (cl-typep FOO 'function) called `functionp', + ;; so while `cl-functionp' would be the more correct predicate, it + ;; would breaks existing code :-( + ;; :predicate cl-functionp + ) (cl--define-built-in-type compiled-function (function) "Abstract type of functions that have been compiled.") (cl--define-built-in-type byte-code-function (compiled-function) diff --git a/test/src/data-tests.el b/test/src/data-tests.el index 753d74c02ec..a1959f62fd3 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el @@ -870,7 +870,9 @@ comparing the subr with a much slower Lisp implementation." native-comp-unit interpreted-function tree-sitter-compiled-query tree-sitter-node tree-sitter-parser)))) - (should-not (cl-typep val subtype)))))))) + (cond + ((eq subtype 'function) (cl-functionp val)) + (t (should-not (cl-typep val subtype)))))))))) ;;; data-tests.el ends here commit ed85132740b39c147647be1831abb64a3f514d57 Author: Alan Mackenzie Date: Tue Mar 26 20:59:43 2024 +0000 CC Mode: Handle C++20's if consteval * lisp/progmodes/cc-engine.el (c-after-conditional): Handle the new keyword in place of a paren sexp after `if'. * lisp/progmodes/cc-langs.el (c-negation-op-re) (c-paren-clause-kwds, c-paren-clause-key) (c-block-stmt-with-kwds, c-block-stmt-with-key): New lang-consts/vars. * if-11.cc, if-11.res: New test files. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index ea4ee3d7b7c..8c505e9556a 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -12346,13 +12346,21 @@ comment at the start of cc-engine.el for more info." (zerop (c-backward-token-2 1 t lim)) t) (or (looking-at c-block-stmt-1-key) - (and (eq (char-after) ?\() - (zerop (c-backward-token-2 1 t lim)) - (if (looking-at c-block-stmt-hangon-key) - (zerop (c-backward-token-2 1 t lim)) - t) - (or (looking-at c-block-stmt-2-key) - (looking-at c-block-stmt-1-2-key)))) + (or + (and + (eq (char-after) ?\() + (zerop (c-backward-token-2 1 t lim)) + (if (looking-at c-block-stmt-hangon-key) + (zerop (c-backward-token-2 1 t lim)) + t) + (or (looking-at c-block-stmt-2-key) + (looking-at c-block-stmt-1-2-key))) + (and (looking-at c-paren-clause-key) + (zerop (c-backward-token-2 1 t lim)) + (if (looking-at c-negation-op-re) + (zerop (c-backward-token-2 1 t lim)) + t) + (looking-at c-block-stmt-with-key)))) (point)))) (defun c-after-special-operator-id (&optional lim) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index ae2389c75c2..06b919f26fd 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -1599,6 +1599,12 @@ operators." (c-lang-defvar c-assignment-op-regexp (c-lang-const c-assignment-op-regexp)) +(c-lang-defconst c-negation-op-re + ;; Regexp matching the negation operator. + t "!\\([^=]\\|$\\)") + +(c-lang-defvar c-negation-op-re (c-lang-const c-negation-op-re)) + (c-lang-defconst c-arithmetic-operators "List of all arithmetic operators, including \"+=\", etc." ;; Note: in the following, there are too many operators for AWK and IDL. @@ -3163,6 +3169,30 @@ Keywords here should also be in `c-block-stmt-1-kwds'." (c-lang-const c-block-stmt-2-kwds))))) (c-lang-defvar c-opt-block-stmt-key (c-lang-const c-opt-block-stmt-key)) +(c-lang-defconst c-paren-clause-kwds + "Keywords which can stand in the place of paren sexps in conditionals. +This applies only to conditionals in `c-block-stmt-with-kwds'." + t nil + c++ '("consteval")) + +(c-lang-defconst c-paren-clause-key + ;; Regexp matching a keyword in `c-paren-clause-kwds'. + t (c-make-keywords-re t + (c-lang-const c-paren-clause-kwds))) +(c-lang-defvar c-paren-clause-key (c-lang-const c-paren-clause-key)) + +(c-lang-defconst c-block-stmt-with-kwds + "Statement keywords which can be followed by a keyword instead of a parens. +Such a keyword is a member of `c-paren-clause-kwds." + t nil + c++ '("if")) + +(c-lang-defconst c-block-stmt-with-key + ;; Regexp matching a keyword in `c-block-stmt-with-kwds'. + t (c-make-keywords-re t + (c-lang-const c-block-stmt-with-kwds))) +(c-lang-defvar c-block-stmt-with-key (c-lang-const c-block-stmt-with-key)) + (c-lang-defconst c-simple-stmt-kwds "Statement keywords followed by an expression or nothing." t '("break" "continue" "goto" "return") commit 004f2493a542dd0b804a30e97fc612884ca440f4 Author: Stefan Monnier Date: Tue Mar 26 13:14:15 2024 -0400 cl-preloaded.el: Fix the type lattice We generally want types to form not just a DAG but a lattice. If objects can be both `keyword` and `symbol-with-pos`, this means there should be a more precise type describing this intersection. If we ever find the need for such a refinement, we could add such a `keyword-with-pos` type, but here I took the simpler route of treating `keyword` not as a proper built-in type but as a second-class type like `natnum`. While fixing this problem, also fix the problem we had where `functionp` was not quite adequate to characterize objects of type `function`, by introducing a new predicate `cl-functionp` for that. * lisp/emacs-lisp/cl-preloaded.el (cl-functionp): New function. (function): Use it. (keyword): Don't declare it as a built-in type. (user-ptrp): Remove redundant declaration. * lisp/emacs-lisp/cl-generic.el (cl--generic--unreachable-types): Delete constant. (cl-generic-generalizers): Remove corresponding test. * lisp/emacs-lisp/cl-macs.el (cl-deftype-satisfies): Add entry for `keyword` type. * lisp/emacs-lisp/comp.el (comp-known-predicates): Fix type for negative result of `characterp`. Remove duplicate `numberp` entry. Fix types for `keywordp` now that `keyword` is not a built-in type any more. * test/src/data-tests.el (data-tests--cl-type-of): Add a few cases. Remove workaround for `function`. diff --git a/etc/NEWS b/etc/NEWS index 73af6ab773e..25c4efa590f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1700,9 +1700,11 @@ This function is like 'type-of' except that it sometimes returns a more precise type. For example, for nil and t it returns 'null' and 'boolean' respectively, instead of just 'symbol'. -** New function `primitive-function-p`. -This is like `subr-primitive-p` except that it returns t only if the -argument is a function rather than a special-form. +** New functions `primitive-function-p` and `cl-functionp`. +`primitive-function-p` is like `subr-primitive-p` except that it returns +t only if the argument is a function rather than a special-form, +and `cl-functionp` is like `functionp` except it return nil +for lists and symbols. ** Built-in types have now corresponding classes. At the Lisp level, this means that things like (cl-find-class 'integer) diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 62abe8d1589..8bda857afdd 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -1332,11 +1332,6 @@ These match if the argument is `eql' to VAL." ;;; Dispatch on "normal types". -(defconst cl--generic--unreachable-types - ;; FIXME: Try to make that list empty? - '(keyword) - "Built-in classes on which we cannot dispatch for technical reasons.") - (defun cl--generic-type-specializers (tag &rest _) (and (symbolp tag) (let ((class (cl--find-class tag))) @@ -1350,14 +1345,12 @@ These match if the argument is `eql' to VAL." (cl-defmethod cl-generic-generalizers :extra "typeof" (type) "Support for dispatch on types. This currently works for built-in types and types built on top of records." - ;; FIXME: Add support for other types accepted by `cl-typep' such - ;; as `character', `face', `function', ... + ;; FIXME: Add support for other "types" accepted by `cl-typep' such + ;; as `character', `face', `keyword', ...? (or (and (symbolp type) (not (eq type t)) ;; Handled by the `t-generalizer'. (let ((class (cl--find-class type))) - (when (memq type cl--generic--unreachable-types) - (error "Dispatch on %S is currently not supported" type)) (memq (type-of class) '(built-in-class cl-structure-class eieio--class))) (list cl--generic-typeof-generalizer)) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index ab31946d8ab..051cd992fc1 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3467,6 +3467,7 @@ Of course, we really can't know that for sure, so it's just a heuristic." '((base-char . characterp) ;Could be subtype of `fixnum'. (character . natnump) ;Could be subtype of `fixnum'. (command . commandp) ;Subtype of closure & subr. + (keyword . keywordp) ;Would need `keyword-with-pos`. (natnum . natnump) ;Subtype of fixnum & bignum. (real . numberp) ;Not clear where it would fit. )) diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el index 35a8d79a1cd..6128db05c61 100644 --- a/lisp/emacs-lisp/cl-preloaded.el +++ b/lisp/emacs-lisp/cl-preloaded.el @@ -349,6 +349,14 @@ The `slots' (and hence `index-table') are currently unused." ;; so the DAG of OClosure types is "orthogonal" to the distinction ;; between interpreted and compiled functions. +(defun cl-functionp (object) + "Return non-nil if OBJECT is a member of type `function'. +This is like `functionp' except that it returns nil for all lists and symbols, +regardless if `funcall' would accept to call them." + (memq (cl-type-of object) + '(primitive-function subr-native-elisp module-function + interpreted-function byte-code-function))) + (cl--define-built-in-type t nil "Abstract supertype of everything.") (cl--define-built-in-type atom t "Abstract supertype of anything but cons cells." :predicate atom) @@ -356,11 +364,9 @@ The `slots' (and hence `index-table') are currently unused." (cl--define-built-in-type tree-sitter-compiled-query atom) (cl--define-built-in-type tree-sitter-node atom) (cl--define-built-in-type tree-sitter-parser atom) -(declare-function user-ptrp "data.c") (when (fboundp 'user-ptrp) (cl--define-built-in-type user-ptr atom nil - ;; FIXME: Shouldn't it be called - ;; `user-ptr-p'? + ;; FIXME: Shouldn't it be called `user-ptr-p'? :predicate user-ptrp)) (cl--define-built-in-type font-object atom) (cl--define-built-in-type font-entity atom) @@ -410,8 +416,6 @@ The `slots' (and hence `index-table') are currently unused." The size depends on the Emacs version and compilation options. For this build of Emacs it's %dbit." (1+ (logb (1+ most-positive-fixnum))))) -(cl--define-built-in-type keyword (symbol) - "Type of those symbols whose first char is `:'.") (cl--define-built-in-type boolean (symbol) "Type of the canonical boolean values, i.e. either nil or t.") (cl--define-built-in-type symbol-with-pos (symbol) @@ -431,7 +435,8 @@ For this build of Emacs it's %dbit." ;; Example of slots we could document. (car car) (cdr cdr)) (cl--define-built-in-type function (atom) - "Abstract supertype of function values.") + "Abstract supertype of function values." + :predicate cl-functionp) (cl--define-built-in-type compiled-function (function) "Abstract type of functions that have been compiled.") (cl--define-built-in-type byte-code-function (compiled-function) diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 9976a58f893..2544be85bb2 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -193,13 +193,14 @@ Useful to hook into pass checkers.") ;; cl-macs.el. We can't use `cl-deftype-satisfies' directly as the ;; relation type <-> predicate is not bijective (bug#45576). (defconst comp-known-predicates + ;; FIXME: Auto-generate (most of) it from `cl-deftype-satifies'? '((arrayp array) (atom atom) (bool-vector-p bool-vector) (booleanp boolean) (bufferp buffer) (char-table-p char-table) - (characterp fixnum) + (characterp fixnum t) (consp cons) (floatp float) (framep frame) @@ -207,14 +208,13 @@ Useful to hook into pass checkers.") (hash-table-p hash-table) (integer-or-marker-p integer-or-marker) (integerp integer) - (keywordp keyword) + (keywordp symbol t) (listp list) (markerp marker) (natnump (integer 0 *)) (null null) (number-or-marker-p number-or-marker) (numberp number) - (numberp number) (obarrayp obarray) (overlayp overlay) (processp process) diff --git a/test/src/data-tests.el b/test/src/data-tests.el index daa49e671b5..753d74c02ec 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el @@ -845,10 +845,12 @@ comparing the subr with a much slower Lisp implementation." ;; Note: This doesn't work for list/vector structs since those types ;; are too difficult/unreliable to detect (so `cl-type-of' only says ;; it's a `cons' or a `vector'). - (dolist (val (list -2 10 (expt 2 128) nil t 'car + (dolist (val (list -2 10 (expt 2 128) nil t 'car :car (symbol-function 'car) (symbol-function 'progn) - (position-symbol 'car 7))) + (eval '(lambda (x) (+ x 1)) t) + (position-symbol 'car 7) + (position-symbol :car 7))) (let* ((type (cl-type-of val)) (class (cl-find-class type)) (alltypes (cl--class-allparents class)) @@ -858,19 +860,17 @@ comparing the subr with a much slower Lisp implementation." (dolist (parent alltypes) (should (cl-typep val parent)) (dolist (subtype (cl--class-children (cl-find-class parent))) - (unless (memq subtype alltypes) - (unless (memq subtype - ;; FIXME: Some types don't have any associated - ;; predicate, - '( font-spec font-entity font-object - finalizer condvar terminal - native-comp-unit interpreted-function - tree-sitter-compiled-query - tree-sitter-node tree-sitter-parser - ;; `functionp' also matches things of type - ;; `symbol' and `cons'. - function)) - (should-not (cl-typep val subtype))))))))) + (when (and (not (memq subtype alltypes)) + (built-in-class-p (cl-find-class subtype)) + (not (memq subtype + ;; FIXME: Some types don't have any associated + ;; predicate, + '( font-spec font-entity font-object + finalizer condvar terminal + native-comp-unit interpreted-function + tree-sitter-compiled-query + tree-sitter-node tree-sitter-parser)))) + (should-not (cl-typep val subtype)))))))) ;;; data-tests.el ends here commit 351d98535dc10f8338b8a418e331cc0af488087b Author: Eli Zaretskii Date: Tue Mar 26 14:24:16 2024 +0200 ; Fix recently-changed documentation * src/buffer.c (syms_of_buffer) : * doc/lispref/commands.texi (Misc Events): Fix wording and punctuation of the documentation. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 9ecdd23716c..4fe4969c0db 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2477,10 +2477,10 @@ be sent whenever the input method wants to insert a new line. @item password This is largely identical to @code{action}, but also requests an input -method capable of inserting ASCII characters and instructs it not to -save input in locations from whence it might be subsequently retrieved -by features of the input method unfit to handle sensitive information, -such as text suggestions. +method capable of inserting ASCII characters, and instructs it not to +save input in locations from which it might be subsequently retrieved +by features of the input method that cannot handle sensitive +information, such as text suggestions. @item t This, or any other value, means that the input method will be enabled diff --git a/src/buffer.c b/src/buffer.c index 9f954e1aba9..291c7d3f911 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5901,24 +5901,27 @@ Use Custom to set this variable and update the display. */); Qnil, doc: /* How the on screen keyboard's input method should insert in this buffer. -When nil, the input method will be disabled and an ordinary keyboard +If nil, the input method will be disabled and an ordinary keyboard will be displayed in its place. -When the symbol `action', the input method will insert text directly, but -will send `return' key events instead of inserting new line characters. -Any other value means that the input method will insert text directly. +If the value is the symbol `action', the input method will insert text +directly, but will send `return' key events instead of inserting new +line characters. + +If the value is the symbol `password', an input method capable of ASCII +input will be enabled, and will not save the entered text where it will +be retrieved for text suggestions or other features not suitable for +handling sensitive information, in addition to reporting `return' as +when `action'. -When the symbol `password', an input method capable of ASCII input will -be enabled, and will not save entered text where it will be retrieved -for text suggestions or other features not suited to handling sensitive -information, in addition to reporting `return' as when `action'. +Any other value means that the input method will insert text directly. If you need to make non-buffer local changes to this variable, use `overriding-text-conversion-style', which see. This variable does not take immediate effect when set; rather, it takes effect upon the next redisplay after the selected window or -buffer changes. */); +its buffer changes. */); DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions, doc: /* List of functions called with no args to query before killing a buffer. commit 8cc67dbcec0753c5579e63bf82bfe247debe222c Author: Andrea Corallo Date: Tue Mar 26 11:14:08 2024 +0100 Fix native comp prediction on null functionp tested objects * lisp/emacs-lisp/comp.el (comp-known-predicates) (comp-known-predicates-h): Update. (comp--pred-to-pos-cstr, comp--pred-to-neg-cstr): New functions. (comp--add-cond-cstrs): Make use of them. * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a test. diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 4ddf90349d1..9976a58f893 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -193,49 +193,52 @@ Useful to hook into pass checkers.") ;; cl-macs.el. We can't use `cl-deftype-satisfies' directly as the ;; relation type <-> predicate is not bijective (bug#45576). (defconst comp-known-predicates - '((arrayp . array) - (atom . atom) - (bool-vector-p . bool-vector) - (booleanp . boolean) - (bufferp . buffer) - (char-table-p . char-table) - (characterp . fixnum) - (consp . cons) - (floatp . float) - (framep . frame) - (functionp . (or function symbol cons)) - (hash-table-p . hash-table) - (integer-or-marker-p . integer-or-marker) - (integerp . integer) - (keywordp . keyword) - (listp . list) - (markerp . marker) - (natnump . (integer 0 *)) - (null . null) - (number-or-marker-p . number-or-marker) - (numberp . number) - (numberp . number) - (obarrayp . obarray) - (overlayp . overlay) - (processp . process) - (sequencep . sequence) - (stringp . string) - (subrp . subr) - (symbol-with-pos-p . symbol-with-pos) - (symbolp . symbol) - (vectorp . vector) - (windowp . window)) - "Alist predicate -> matched type specifier.") + '((arrayp array) + (atom atom) + (bool-vector-p bool-vector) + (booleanp boolean) + (bufferp buffer) + (char-table-p char-table) + (characterp fixnum) + (consp cons) + (floatp float) + (framep frame) + (functionp (or function symbol cons) (not function)) + (hash-table-p hash-table) + (integer-or-marker-p integer-or-marker) + (integerp integer) + (keywordp keyword) + (listp list) + (markerp marker) + (natnump (integer 0 *)) + (null null) + (number-or-marker-p number-or-marker) + (numberp number) + (numberp number) + (obarrayp obarray) + (overlayp overlay) + (processp process) + (sequencep sequence) + (stringp string) + (subrp subr) + (symbol-with-pos-p symbol-with-pos) + (symbolp symbol) + (vectorp vector) + (windowp window)) + "(PREDICATE TYPE-IF-SATISFIED ?TYPE-IF-NOT-SATISFIED).") (defconst comp-known-predicates-h (cl-loop with comp-ctxt = (make-comp-cstr-ctxt) with h = (make-hash-table :test #'eq) - for (pred . type-spec) in comp-known-predicates - for cstr = (comp-type-spec-to-cstr type-spec) - do (puthash pred cstr h) + for (pred . type-specs) in comp-known-predicates + for pos-cstr = (comp-type-spec-to-cstr (car type-specs)) + for neg-cstr = (if (length> type-specs 1) + (comp-type-spec-to-cstr (cl-second type-specs)) + (comp-cstr-negation-make pos-cstr)) + do (puthash pred (cons pos-cstr neg-cstr) h) finally return h) - "Hash table function -> `comp-constraint'.") + "Hash table FUNCTION -> (POS-CSTR . NEG-CSTR).") (defun comp--known-predicate-p (predicate) "Return t if PREDICATE is known." @@ -243,10 +246,14 @@ Useful to hook into pass checkers.") (gethash predicate (comp-cstr-ctxt-pred-type-h comp-ctxt))) t)) -(defun comp--pred-to-cstr (predicate) - "Given PREDICATE, return the corresponding constraint." - ;; FIXME: Unify those two hash tables? - (or (gethash predicate comp-known-predicates-h) +(defun comp--pred-to-pos-cstr (predicate) + "Given PREDICATE, return the corresponding positive constraint." + (or (car-safe (gethash predicate comp-known-predicates-h)) + (gethash predicate (comp-cstr-ctxt-pred-type-h comp-ctxt)))) + +(defun comp--pred-to-neg-cstr (predicate) + "Given PREDICATE, return the corresponding negative constraint." + (or (cdr-safe (gethash predicate comp-known-predicates-h)) (gethash predicate (comp-cstr-ctxt-pred-type-h comp-ctxt)))) (defconst comp-symbol-values-optimizable '(most-positive-fixnum @@ -2033,7 +2040,6 @@ TARGET-BB-SYM is the symbol name of the target block." (cond-jump ,cmp-res ,(pred comp-mvar-p) . ,blocks)) (cl-loop with target-mvar = (comp--cond-cstrs-target-mvar op (car insns-seq) b) - with cstr = (comp--pred-to-cstr fun) for branch-target-cell on blocks for branch-target = (car branch-target-cell) for negated in '(t nil) @@ -2041,7 +2047,10 @@ TARGET-BB-SYM is the symbol name of the target block." do (let ((block-target (comp--add-cond-cstrs-target-block b branch-target))) (setf (car branch-target-cell) (comp-block-name block-target)) - (comp--emit-assume 'and target-mvar cstr block-target negated)) + (comp--emit-assume 'and target-mvar (if negated + (comp--pred-to-neg-cstr fun) + (comp--pred-to-pos-cstr fun)) + block-target nil)) finally (cl-return-from in-the-basic-block))) ;; Match predicate on the negated branch (unless). (`((set ,(and (pred comp-mvar-p) cmp-res) @@ -2052,7 +2061,6 @@ TARGET-BB-SYM is the symbol name of the target block." (cond-jump ,neg-cmp-res ,(pred comp-mvar-p) . ,blocks)) (cl-loop with target-mvar = (comp--cond-cstrs-target-mvar op (car insns-seq) b) - with cstr = (comp--pred-to-cstr fun) for branch-target-cell on blocks for branch-target = (car branch-target-cell) for negated in '(nil t) @@ -2060,7 +2068,10 @@ TARGET-BB-SYM is the symbol name of the target block." do (let ((block-target (comp--add-cond-cstrs-target-block b branch-target))) (setf (car branch-target-cell) (comp-block-name block-target)) - (comp--emit-assume 'and target-mvar cstr block-target negated)) + (comp--emit-assume 'and target-mvar (if negated + (comp--pred-to-neg-cstr fun) + (comp--pred-to-pos-cstr fun)) + block-target nil)) finally (cl-return-from in-the-basic-block)))) (setf prev-insns-seq insns-seq)))) diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el index fbcb6ca9560..b2fd2f68826 100644 --- a/test/src/comp-tests.el +++ b/test/src/comp-tests.el @@ -1496,7 +1496,14 @@ Return a list of results." (if (comp-foo-p x) x (error ""))) - 'comp-foo))) + 'comp-foo) + + ;; 80 + ((defun comp-tests-ret-type-spec-f (x) + (if (functionp x) + (error "") + x)) + '(not function)))) (defun comp-tests-define-type-spec-test (number x) `(comp-deftest ,(intern (format "ret-type-spec-%d" number)) () commit b7b9a0a5c1afae07b8168e85dcf1fc37d29e98ef Author: Po Lu Date: Tue Mar 26 10:54:39 2024 +0800 Prevent focus "stalemates" on Android * java/org/gnu/emacs/EmacsActivity.java (invalidateFocus1): New argument resetWhenChildless. (invalidateFocus): If a toplevel window has no focus window, transfer focus to the toplevel itself. diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java index 06b9c0f005d..6ab6a709bef 100644 --- a/java/org/gnu/emacs/EmacsActivity.java +++ b/java/org/gnu/emacs/EmacsActivity.java @@ -84,7 +84,7 @@ public class EmacsActivity extends Activity }; public static void - invalidateFocus1 (EmacsWindow window) + invalidateFocus1 (EmacsWindow window, boolean resetWhenChildless) { if (window.view.isFocused ()) focusedWindow = window; @@ -92,7 +92,18 @@ public class EmacsActivity extends Activity synchronized (window.children) { for (EmacsWindow child : window.children) - invalidateFocus1 (child); + invalidateFocus1 (child, false); + + /* If no focused window was previously detected among WINDOW's + children and RESETWHENCHILDLESS is set (implying it is a + toplevel window), request that it be focused, to avoid + creating a situation where no windows exist focused or can be + transferred the input focus by user action. */ + if (focusedWindow == null && resetWhenChildless) + { + window.view.requestFocus (); + focusedWindow = window; + } } } @@ -110,7 +121,7 @@ public class EmacsActivity extends Activity for (EmacsActivity activity : focusedActivities) { if (activity.window != null) - invalidateFocus1 (activity.window); + invalidateFocus1 (activity.window, focusedWindow == null); } /* Send focus in- and out- events to the previous and current commit 728bf2c9e5353e68b16808ae455223549c16efc6 Author: Po Lu Date: Tue Mar 26 10:11:26 2024 +0800 Prevent passwords from being recorded during text conversion * doc/lispref/commands.texi (Misc Events): Document new value of text-conversion-style. * java/org/gnu/emacs/EmacsService.java (EmacsService) : New constant. * java/org/gnu/emacs/EmacsView.java (onCreateInputConnection): Set TYPE_TEXT_VARIATION_PASSWORD and IME_FLAG_FORCE_ASII if mode is IC_MODE_PASSWORD. * lisp/subr.el (read-passwd): Set text-conversion-style to `password'. * src/androidgui.h (enum android_ic_mode): New value ANDROID_IC_MODE_PASSWORD. * src/androidterm.c (android_reset_conversion): Handle `password'. * src/buffer.c (syms_of_buffer) <&BVAR (current_buffer, text_conversion_style)>: Update doc string. * src/textconv.c (syms_of_textconv) : New DEFSYM. : Fix typos in doc string. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 6c8d42337d0..9ecdd23716c 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2464,7 +2464,7 @@ buffer-local variable @code{text-conversion-style}, which determines how an input method that wishes to make edits to buffer contents will behave. -This variable can have one of three values: +This variable can have one of four values: @table @code @item nil @@ -2475,6 +2475,13 @@ events will be sent instead of text conversion events. This means that the input method will be enabled, but @key{RET} will be sent whenever the input method wants to insert a new line. +@item password +This is largely identical to @code{action}, but also requests an input +method capable of inserting ASCII characters and instructs it not to +save input in locations from whence it might be subsequently retrieved +by features of the input method unfit to handle sensitive information, +such as text suggestions. + @item t This, or any other value, means that the input method will be enabled and make edits followed by @code{text-conversion} events. diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 4e863c750d3..446cd26a3dd 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -114,9 +114,10 @@ public final class EmacsService extends Service private ContentResolver resolver; /* Keep this in synch with androidgui.h. */ - public static final int IC_MODE_NULL = 0; - public static final int IC_MODE_ACTION = 1; - public static final int IC_MODE_TEXT = 2; + public static final int IC_MODE_NULL = 0; + public static final int IC_MODE_ACTION = 1; + public static final int IC_MODE_TEXT = 2; + public static final int IC_MODE_PASSWORD = 3; /* Display metrics used by font backends. */ public DisplayMetrics metrics; diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 8398e4b784c..5b922212c0b 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java @@ -838,9 +838,16 @@ else if (child.getVisibility () != GONE) EmacsNative.requestSelectionUpdate (window.handle); } - if (mode == EmacsService.IC_MODE_ACTION) + if (mode == EmacsService.IC_MODE_ACTION + || mode == EmacsService.IC_MODE_PASSWORD) info.imeOptions |= EditorInfo.IME_ACTION_DONE; + if (mode == EmacsService.IC_MODE_PASSWORD) + { + info.imeOptions |= EditorInfo.IME_FLAG_FORCE_ASCII; + info.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD; + } + /* Set the initial selection fields. */ info.initialSelStart = selection[0]; info.initialSelEnd = selection[1]; diff --git a/lisp/subr.el b/lisp/subr.el index 3de4412637f..90dbfc75d52 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3405,6 +3405,10 @@ with Emacs. Do not call it directly in your own packages." (+ i beg) (+ 1 i beg) 'help-echo "C-u: Clear password\nTAB: Toggle password visibility")))) +;; Actually in textconv.c. +(defvar overriding-text-conversion-style) +(declare-function set-text-conversion-style "textconv.c") + (defun read-passwd (prompt &optional confirm default) "Read a password, prompting with PROMPT, and return it. If optional CONFIRM is non-nil, read the password twice to make sure. @@ -3445,7 +3449,8 @@ by doing (clear-string STRING)." (add-hook 'post-command-hook #'read-passwd--hide-password nil t)) (unwind-protect (let ((enable-recursive-minibuffers t) - (read-hide-char (or read-hide-char ?*))) + (read-hide-char (or read-hide-char ?*)) + (overriding-text-conversion-style 'password)) (read-string prompt nil t default)) ; t = "no history" (when (buffer-live-p minibuf) (with-current-buffer minibuf @@ -3457,7 +3462,10 @@ by doing (clear-string STRING)." #'read-passwd--hide-password 'local) (kill-local-variable 'post-self-insert-hook) ;; And of course, don't keep the sensitive data around. - (erase-buffer)))))))) + (erase-buffer) + ;; Then restore the previous text conversion style. + (when (fboundp 'set-text-conversion-style) + (set-text-conversion-style text-conversion-style))))))))) (defvar read-number-history nil "The default history for the `read-number' function.") @@ -3867,10 +3875,6 @@ confusing to some users.") from--tty-menu-p) ; invoked via TTY menu use-dialog-box))) -;; Actually in textconv.c. -(defvar overriding-text-conversion-style) -(declare-function set-text-conversion-style "textconv.c") - (defun y-or-n-p (prompt) "Ask user a \"y or n\" question. Return t if answer is \"y\" and nil if it is \"n\". diff --git a/src/androidgui.h b/src/androidgui.h index d89aee51055..f941c7cc577 100644 --- a/src/androidgui.h +++ b/src/androidgui.h @@ -618,9 +618,10 @@ enum android_lookup_status enum android_ic_mode { - ANDROID_IC_MODE_NULL = 0, - ANDROID_IC_MODE_ACTION = 1, - ANDROID_IC_MODE_TEXT = 2, + ANDROID_IC_MODE_NULL = 0, + ANDROID_IC_MODE_ACTION = 1, + ANDROID_IC_MODE_TEXT = 2, + ANDROID_IC_MODE_PASSWORD = 3, }; enum android_stack_mode diff --git a/src/androidterm.c b/src/androidterm.c index ba9b6d3b8a9..c920375fdbe 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -6276,6 +6276,8 @@ android_reset_conversion (struct frame *f) if (NILP (style) || conversion_disabled_p ()) mode = ANDROID_IC_MODE_NULL; + else if (EQ (style, Qpassword)) + mode = ANDROID_IC_MODE_PASSWORD; else if (EQ (style, Qaction) || EQ (f->selected_window, f->minibuffer_window)) mode = ANDROID_IC_MODE_ACTION; diff --git a/src/buffer.c b/src/buffer.c index 07d19dfc078..9f954e1aba9 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5900,12 +5900,19 @@ Use Custom to set this variable and update the display. */); text_conversion_style), Qnil, doc: /* How the on screen keyboard's input method should insert in this buffer. + When nil, the input method will be disabled and an ordinary keyboard will be displayed in its place. + When the symbol `action', the input method will insert text directly, but will send `return' key events instead of inserting new line characters. Any other value means that the input method will insert text directly. +When the symbol `password', an input method capable of ASCII input will +be enabled, and will not save entered text where it will be retrieved +for text suggestions or other features not suited to handling sensitive +information, in addition to reporting `return' as when `action'. + If you need to make non-buffer local changes to this variable, use `overriding-text-conversion-style', which see. diff --git a/src/textconv.c b/src/textconv.c index 0941848dd09..9625c884e16 100644 --- a/src/textconv.c +++ b/src/textconv.c @@ -2318,6 +2318,7 @@ void syms_of_textconv (void) { DEFSYM (Qaction, "action"); + DEFSYM (Qpassword, "password"); DEFSYM (Qtext_conversion, "text-conversion"); DEFSYM (Qpush_mark, "push-mark"); DEFSYM (Qunderline, "underline"); @@ -2325,7 +2326,7 @@ syms_of_textconv (void) "overriding-text-conversion-style"); DEFVAR_LISP ("text-conversion-edits", Vtext_conversion_edits, - doc: /* List of buffers that were last edited as result of text conversion. + doc: /* List of buffers last edited as a result of text conversion. This list can be used while handling a `text-conversion' event to determine which changes have taken place. commit 7fba25cf5344f5c3507aedf59e6ae099e7662508 Author: Eli Zaretskii Date: Mon Mar 25 15:51:07 2024 +0200 Fix removal of bookmark's fringe mark in Info and Dired * lisp/bookmark.el (bookmark-buffer-file-name): Support Info buffers. (bookmark--remove-fringe-mark): Call 'bookmark-buffer-file-name' instead of using 'buffer-file-name', which could be nil. (Bug#69974) diff --git a/lisp/bookmark.el b/lisp/bookmark.el index 60dd61a5ac8..bf2357207d8 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -515,10 +515,11 @@ See user option `bookmark-fringe-mark'." (non-essential t) overlays found temp) (when (and pos filename) - (setq filename (expand-file-name filename)) + (setq filename (abbreviate-file-name (expand-file-name filename))) (dolist (buf (buffer-list)) (with-current-buffer buf - (when (equal filename buffer-file-name) + (when (equal filename + (ignore-errors (bookmark-buffer-file-name))) (setq overlays (save-excursion (goto-char pos) @@ -1192,6 +1193,8 @@ it to the name of the bookmark currently being set, advancing (if (stringp dired-directory) dired-directory (car dired-directory))) + ((and (boundp 'Info-current-file) (stringp Info-current-file)) + Info-current-file) (t (error "Buffer not visiting a file or directory"))))) (defvar bookmark--watch-already-asked-mtime nil commit a79b424f7fdecf577e46c5fea6ee3d921e606596 Author: Eli Zaretskii Date: Mon Mar 25 14:53:23 2024 +0200 Document the 'I' command in buffer-menu * doc/emacs/buffers.texi (Several Buffers): Document 'I'. Fix indexing. (List Buffers): Mention 'I'. (Bug#69987) * etc/NEWS: Mark 'I' as documented. diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi index 00160afd844..2786ff6ad65 100644 --- a/doc/emacs/buffers.texi +++ b/doc/emacs/buffers.texi @@ -223,8 +223,10 @@ the directory @file{~/cvs/emacs/src/}. You can list only buffers that are visiting files by giving the command a prefix argument, as in @kbd{C-u C-x C-b}. - @code{list-buffers} omits buffers whose names begin with a space, -unless they visit files: such buffers are used internally by Emacs. + By default, @code{list-buffers} omits buffers whose names begin with a +space, unless they visit files: such buffers are used internally by +Emacs (but the @kbd{I} command countermands that, @pxref{Several +Buffers}). @node Misc Buffer @section Miscellaneous Buffer Operations @@ -401,57 +403,57 @@ cursor motion commands can be used in this buffer. The following commands apply to the buffer described on the current line: @table @kbd -@item d @findex Buffer-menu-delete @kindex d @r{(Buffer Menu)} +@item d Flag the buffer for deletion (killing), then move point to the next line (@code{Buffer-menu-delete}). The deletion flag is indicated by the character @samp{D} on the line, before the buffer name. The deletion occurs only when you type the @kbd{x} command (see below). -@item C-d @findex Buffer-menu-delete-backwards @kindex C-d @r{(Buffer Menu)} +@item C-d Like @kbd{d}, but move point up instead of down (@code{Buffer-menu-delete-backwards}). -@item s @findex Buffer-menu-save @kindex s @r{(Buffer Menu)} +@item s Flag the buffer for saving (@code{Buffer-menu-save}). The save flag is indicated by the character @samp{S} on the line, before the buffer name. The saving occurs only when you type @kbd{x}. You may request both saving and deletion for the same buffer. -@item x @findex Buffer-menu-execute @kindex x @r{(Buffer Menu)} +@item x Perform all flagged deletions and saves (@code{Buffer-menu-execute}). -@item u @findex Buffer-menu-unmark @kindex u @r{(Buffer Menu)} +@item u Remove all flags from the current line, and move down (@code{Buffer-menu-unmark}). With a prefix argument, moves up after removing the flags. -@item @key{DEL} @findex Buffer-menu-backup-unmark @kindex DEL @r{(Buffer Menu)} +@item @key{DEL} Move to the previous line and remove all flags on that line (@code{Buffer-menu-backup-unmark}). -@item M-@key{DEL} @findex Buffer-menu-unmark-all-buffers @kindex M-DEL @r{(Buffer Menu)} +@item M-@key{DEL} Remove a particular flag from all lines (@code{Buffer-menu-unmark-all-buffers}). This asks for a single character, and unmarks buffers marked with that character; typing @key{RET} removes all marks. -@item U @findex Buffer-menu-unmark-all @kindex U @r{(Buffer Menu)} +@item U Remove all flags from all the lines (@code{Buffer-menu-unmark-all}). @end table @@ -465,21 +467,21 @@ the current line. They also accept a numeric argument as a repeat count. @table @kbd -@item ~ @findex Buffer-menu-not-modified @kindex ~ @r{(Buffer Menu)} +@item ~ Mark the buffer as unmodified (@code{Buffer-menu-not-modified}). @xref{Save Commands}. -@item % @findex Buffer-menu-toggle-read-only @kindex % @r{(Buffer Menu)} +@item % Toggle the buffer's read-only status (@code{Buffer-menu-toggle-read-only}). @xref{Misc Buffer}. -@item t @findex Buffer-menu-visit-tags-table @kindex t @r{(Buffer Menu)} +@item t Visit the buffer as a tags table (@code{Buffer-menu-visit-tags-table}). @xref{Select Tags Table}. @end table @@ -487,63 +489,63 @@ Visit the buffer as a tags table The following commands are used to select another buffer or buffers: @table @kbd -@item q @findex quit-window @kindex q @r{(Buffer Menu)} +@item q Quit the Buffer Menu (@code{quit-window}). The most recent formerly visible buffer is displayed in its place. -@item @key{RET} -@itemx f @findex Buffer-menu-this-window @kindex f @r{(Buffer Menu)} @kindex RET @r{(Buffer Menu)} +@item @key{RET} +@itemx f Select this line's buffer, replacing the @file{*Buffer List*} buffer in its window (@code{Buffer-menu-this-window}). -@item o @findex Buffer-menu-other-window @kindex o @r{(Buffer Menu)} +@item o Select this line's buffer in another window, as if by @kbd{C-x 4 b}, leaving @file{*Buffer List*} visible (@code{Buffer-menu-other-window}). -@item C-o @findex Buffer-menu-switch-other-window @kindex C-o @r{(Buffer Menu)} +@item C-o Display this line's buffer in another window, without selecting it (@code{Buffer-menu-switch-other-window}). -@item 1 @findex Buffer-menu-1-window @kindex 1 @r{(Buffer Menu)} +@item 1 Select this line's buffer in a full-frame window (@code{Buffer-menu-1-window}). -@item 2 @findex Buffer-menu-2-window @kindex 2 @r{(Buffer Menu)} +@item 2 Set up two windows on the current frame, with this line's buffer selected in one, and a previously current buffer (aside from @file{*Buffer List*}) in the other (@code{Buffer-menu-2-window}). -@item b @findex Buffer-menu-bury @kindex b @r{(Buffer Menu)} +@item b Bury this line's buffer (@code{Buffer-menu-bury}) (i.e., move it to the end of the buffer list). -@item m @findex Buffer-menu-mark @kindex m @r{(Buffer Menu)} +@item m Mark this line's buffer to be displayed in another window if you exit with the @kbd{v} command (@code{Buffer-menu-mark}). The display flag is indicated by the character @samp{>} at the beginning of the line. (A single buffer may not have both deletion and display flags.) -@item v @findex Buffer-menu-select @kindex v @r{(Buffer Menu)} +@item v Select this line's buffer, and also display in other windows any buffers flagged with the @kbd{m} command (@code{Buffer-menu-select}). If you have not flagged any buffers, this command is equivalent to @@ -553,31 +555,37 @@ If you have not flagged any buffers, this command is equivalent to The following commands affect the entire buffer list: @table @kbd -@item S @findex tabulated-list-sort @kindex S @r{(Buffer Menu)} +@item S Sort the Buffer Menu entries according to their values in the column at point. With a numeric prefix argument @var{n}, sort according to the @var{n}-th column (@code{tabulated-list-sort}). -@item @} @kindex @} @r{(Buffer Menu)} @findex tabulated-list-widen-current-column +@item @} Widen the current column width by @var{n} (the prefix numeric argument) characters. -@item @{ @kindex @{ @r{(Buffer Menu)} @findex tabulated-list-narrow-current-column +@item @{ Narrow the current column width by @var{n} (the prefix numeric argument) characters. -@item T @findex Buffer-menu-toggle-files-only @kindex T @r{(Buffer Menu)} +@item T Delete, or reinsert, lines for non-file buffers (@code{Buffer-menu-toggle-files-only}). This command toggles the inclusion of such buffers in the buffer list. + +@findex Buffer-menu-toggle-internal +@kindex I @r{(Buffer Menu)} +@item I +Toggle display of internal buffers, those whose names begin with a +space. @end table Normally, the buffer @file{*Buffer List*} is not updated diff --git a/etc/NEWS b/etc/NEWS index 19588fe8eeb..73af6ab773e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1453,7 +1453,7 @@ chat buffers use by default. It controls how buffers are divided into groups that are displayed with headings using Outline minor mode. ---- ++++ *** New command 'Buffer-menu-toggle-internal'. This command toggles the display of internal buffers in Buffer Menu mode; that is, buffers not visiting a file and whose names start with a space. commit f54b1d9f7b7a977ee4856c778a309c900ce9e8fa Author: Juri Linkov Date: Mon Mar 25 09:45:08 2024 +0200 * lisp/vc/diff-mode.el (diff-setup-buffer-type): Remove "\n" from regexp. Remove extra "\n" from the end of the "diff --git.*" part of 'diff-outline-regexp' because "\n" is not used in outline-regexp and causes problems in such cases like when killing hunks in the diff buffer with outline-minor-mode that loses the outline icons because outline--fix-buttons-after-change and outline--fix-up-all-buttons are limited to the single line and can't match an outline line with a regexp that ends with "\n". diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 0f393ba86a2..66043059d14 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -1619,7 +1619,7 @@ modified lines of the diff." nil))) (when (eq diff-buffer-type 'git) (setq diff-outline-regexp - (concat "\\(^diff --git.*\n\\|" diff-hunk-header-re "\\)"))) + (concat "\\(^diff --git.*\\|" diff-hunk-header-re "\\)"))) (setq-local outline-level #'diff--outline-level) (setq-local outline-regexp diff-outline-regexp)) commit c2bb763580f94f39e7290e6c47d09ede185c3818 Merge: ba96c4ec56a 83a6e80d66a Author: Po Lu Date: Mon Mar 25 15:43:01 2024 +0800 Merge remote-tracking branch 'savannah/master' into master-android-1 commit ba96c4ec56a9978fce155c0af34a0412aee817b2 Author: Po Lu Date: Mon Mar 25 15:42:23 2024 +0800 Port restart-emacs to Android 4.3 and earlier * java/org/gnu/emacs/EmacsService.java (restartEmacs): Run Emacs from an alarm if required. diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 07bfb525be9..4e863c750d3 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -46,9 +46,11 @@ import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.ExtractedText; +import android.app.AlarmManager; import android.app.Notification; -import android.app.NotificationManager; import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.app.Service; import android.content.ClipboardManager; @@ -724,11 +726,29 @@ invocation of app_process (through android-emacs) can restartEmacs () { Intent intent; + PendingIntent pending; + AlarmManager manager; intent = new Intent (this, EmacsActivity.class); intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - startActivity (intent); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) + startActivity (intent); + else + { + /* Experimentation has established that Android 4.3 and earlier + versions do not attempt to recreate a process when it crashes + immediately after requesting that an intent for itself be + started. Schedule an intent to start some time after Emacs + exits instead. */ + + pending = PendingIntent.getActivity (this, 0, intent, 0); + manager = (AlarmManager) getSystemService (Context.ALARM_SERVICE); + manager.set (AlarmManager.RTC, System.currentTimeMillis () + 100, + pending); + } + System.exit (0); }