commit a837c59d9eca748e3895ae09e82373531222aef6 (HEAD, refs/remotes/origin/master) Merge: 86d128c6c3 9183d1672c Author: Stefan Kangas Date: Tue Jul 12 06:30:35 2022 +0200 Merge from origin/emacs-28 9183d1672c ; * etc/PROBLEMS: Give a URL for bug#50666. 1f508a8b6f etc/PROBLEMS: Describe issues with native compilation on C... 84a5d47125 ; Fix last change 0461021893 ; * lisp/emacs-lisp/comp.el (native-comp-speed): Explain t... 876317271b * lisp/find-dired.el (find-dired): Doc fix; add crossrefer... commit 86d128c6c3acca1665addc65aa43ff80572f46e8 Author: Po Lu Date: Tue Jul 12 10:47:23 2022 +0800 Try to save selections from being disowned during frame deletion * lisp/cus-start.el (standard): Add `x-auto-preserve-selections'. * src/xselect.c (x_clear_frame_selections): Collect deleted selections into a variable and preserve them. * src/xterm.c (x_preserve_selections): New function. (syms_of_xterm): New variable `x-auto-preserve-selections'. * src/xterm.h: Update prototypes. diff --git a/etc/NEWS b/etc/NEWS index bf36316890..c2900b0bc4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2448,6 +2448,15 @@ be kept aligned with the buffer contents when the user switches This minor mode makes Emacs deactivate the mark in all buffers when the primary selection is obtained by another program. +--- +** On X, Emacs will try to preserve selection ownership when a frame is deleted. +This means that if you make Emacs the owner of a selection, such as by +selecting some text into the clipboard or primary selection, and then +delete the current frame, you will still be able to insert the +contents of that selection into other programs as long as another +frame is open on the same display. This behavior can be disabled by +setting the variable 'x-auto-preserve-selections' to nil. + +++ ** New predicate 'char-uppercase-p'. This returns non-nil if its argument its an uppercase character. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index ca2fca4eb7..df919fd715 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -834,6 +834,7 @@ since it could result in memory overflow and make Emacs crash." (x-scroll-event-delta-factor mouse float "29.1") (x-gtk-use-native-input keyboard boolean "29.1") (x-dnd-disable-motif-drag dnd boolean "29.1") + (x-auto-preserve-selections x boolean "29.1") ;; xselect.c (x-select-enable-clipboard-manager killing boolean "24.1") ;; xsettings.c @@ -874,6 +875,8 @@ since it could result in memory overflow and make Emacs crash." (equal "x-scroll-event-delta-factor" (symbol-name symbol)) (equal "x-dnd-disable-motif-drag" + (symbol-name symbol)) + (equal "x-auto-preserve-selections" (symbol-name symbol))) (featurep 'x)) ((string-match "\\`x-" (symbol-name symbol)) diff --git a/src/xselect.c b/src/xselect.c index 25a75aec91..baab2c5c18 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -1091,20 +1091,23 @@ x_handle_selection_event (struct selection_input_event *event) void x_clear_frame_selections (struct frame *f) { - Lisp_Object frame; - Lisp_Object rest; + Lisp_Object frame, rest, lost; struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); struct terminal *t = dpyinfo->terminal; XSETFRAME (frame, f); + lost = Qnil; /* Delete elements from the beginning of Vselection_alist. */ while (CONSP (t->Vselection_alist) && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist))))))) { - /* Run the `x-lost-selection-functions' abnormal hook. */ - CALLN (Frun_hook_with_args, Qx_lost_selection_functions, - Fcar (Fcar (t->Vselection_alist))); + if (!x_auto_preserve_selections) + /* Run the `x-lost-selection-functions' abnormal hook. */ + CALLN (Frun_hook_with_args, Qx_lost_selection_functions, + Fcar (Fcar (t->Vselection_alist))); + else + lost = Fcons (Fcar (t->Vselection_alist), lost); tset_selection_alist (t, XCDR (t->Vselection_alist)); } @@ -1114,11 +1117,18 @@ x_clear_frame_selections (struct frame *f) if (CONSP (XCDR (rest)) && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest)))))))) { - CALLN (Frun_hook_with_args, Qx_lost_selection_functions, - XCAR (XCAR (XCDR (rest)))); + if (!x_auto_preserve_selections) + CALLN (Frun_hook_with_args, Qx_lost_selection_functions, + XCAR (XCAR (XCDR (rest)))); + else + lost = Fcons (XCAR (XCDR (rest)), lost); + XSETCDR (rest, XCDR (XCDR (rest))); break; } + + if (x_auto_preserve_selections) + x_preserve_selections (dpyinfo, lost); } /* True if any properties for DISPLAY and WINDOW diff --git a/src/xterm.c b/src/xterm.c index 2b83efb228..f86e4708ec 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -27951,6 +27951,62 @@ x_uncatch_errors_for_lisp (struct x_display_info *dpyinfo) x_stop_ignoring_errors (dpyinfo); } +/* Preserve the selections in LOST in another frame on DPYINFO. LOST + is a list of local selections that were lost, due to their frame + being deleted. */ + +void +x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost) +{ + Lisp_Object tail, frame, new_owner, tem; + Time timestamp; + Window owner; + + new_owner = Qnil; + + FOR_EACH_FRAME (tail, frame) + { + if (FRAME_X_P (XFRAME (frame)) + && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) + { + new_owner = frame; + break; + } + } + + tail = lost; + + FOR_EACH_TAIL_SAFE (tail) + { + tem = XCAR (tail); + + /* The selection is really lost (since we cannot find a new + owner), so run the appropriate hooks. */ + if (NILP (new_owner)) + CALLN (Frun_hook_with_args, Qx_lost_selection_functions, + XCAR (tem)); + else + { + CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp); + + /* This shouldn't be able to signal any errors, despite the + call to `x_check_errors' inside. */ + x_own_selection (XCAR (tem), XCAR (XCDR (tem)), + new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))), + timestamp); + + /* Now check if we still don't own that selection, which can + happen if another program set itself as the owner. */ + owner = XGetSelectionOwner (dpyinfo->display, + symbol_to_x_atom (dpyinfo, XCAR (tem))); + + if (owner != FRAME_X_WINDOW (XFRAME (new_owner))) + CALLN (Frun_hook_with_args, Qx_lost_selection_functions, + XCAR (tem)); + } + } +} + void syms_of_xterm (void) { @@ -28265,4 +28321,11 @@ reply from the X server, and signal any errors that occurred while executing the protocol request. Otherwise, errors will be silently ignored without waiting, which is generally faster. */); x_fast_protocol_requests = false; + + DEFVAR_BOOL ("x-auto-preserve-selections", x_auto_preserve_selections, + doc: /* Whether or not to transfer selection ownership when deleting a frame. +When non-nil, deleting a frame that is currently the owner of a +selection will cause its ownership to be transferred to another frame +on the same display. */); + x_auto_preserve_selections = true; } diff --git a/src/xterm.h b/src/xterm.h index a1ddf13463..9b91ee4556 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1643,6 +1643,7 @@ extern void xic_set_statusarea (struct frame *); extern void xic_set_xfontset (struct frame *, const char *); extern bool x_defined_color (struct frame *, const char *, Emacs_Color *, bool, bool); +extern void x_preserve_selections (struct x_display_info *, Lisp_Object); #ifdef HAVE_X_I18N extern void free_frame_xic (struct frame *); # if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT commit 7ac313ea87b4761baf975718e4fa3200f61a0ad9 Author: Stefan Kangas Date: Tue Jul 12 01:43:50 2022 +0200 ; * lisp/textmodes/rst.el: Delete stale comment. diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el index ecc3f25935..10313e9939 100644 --- a/lisp/textmodes/rst.el +++ b/lisp/textmodes/rst.el @@ -3569,8 +3569,6 @@ Region is from BEG to END. With WITH-EMPTY prefix empty lines too." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Font lock -;; FIXME: The obsolete variables need to disappear. - ;; The following versions have been done inside Emacs and should not be ;; replaced by `:package-version' attributes until a change. commit 93727d243a39890d8ccbe39854a69bf24e149256 Author: Stefan Kangas Date: Mon Jul 11 22:32:36 2022 +0200 * lisp/mail/mail-utils.el (mail-string-delete): Make obsolete. diff --git a/lisp/mail/mail-utils.el b/lisp/mail/mail-utils.el index 9ea2cc92e9..63752f953a 100644 --- a/lisp/mail/mail-utils.el +++ b/lisp/mail/mail-utils.el @@ -59,7 +59,7 @@ also the To field, unless this would leave an empty To field." (defun mail-string-delete (string start end) "Return a string containing all of STRING except the part from START (inclusive) to END (exclusive)." - ;; FIXME: This is not used anywhere. Make obsolete? + (declare (obsolete substring "29.1")) (if (null end) (substring string 0 start) (concat (substring string 0 start) (substring string end nil)))) commit 9183d1672c65da62e482c55d93b97cd15e4d0ef0 (refs/remotes/origin/emacs-28) Author: Eli Zaretskii Date: Mon Jul 11 21:24:33 2022 +0300 ; * etc/PROBLEMS: Give a URL for bug#50666. diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 68617cd994..262a1dc0ff 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -2911,7 +2911,8 @@ that you not build Emacs with native compilation on 32-bit Cygwin. Indeed, the configure script will not allow this unless you use the --with-cygwin32-native-compilation option. -See bug#50666 for further discussion. +See bug#50666 (https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50666) +for further discussion. * Runtime problems specific to macOS commit 1f508a8b6f738b9d242a9cc7b69861e84ca5d4dc Author: Ken Brown Date: Mon Jul 11 13:03:32 2022 -0400 etc/PROBLEMS: Describe issues with native compilation on Cygwin diff --git a/etc/PROBLEMS b/etc/PROBLEMS index f935b9c930..68617cd994 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -2849,6 +2849,71 @@ please call support for your X-server and see if you can get a fix. If you do, please send it to bug-gnu-emacs@gnu.org so we can list it here. +* Runtime problems specific to Cygwin + +** Fork failures in a build with native compilation + +To prevent fork failures, shared libraries on Cygwin need to be +rebased occasionally, for the reasons explained here: + + https://cygwin.com/cygwin-ug-net/highlights.html#ov-hi-process-problems + +This includes the .eln files produced by an Emacs built with native +compilation. + +Rebasing is handled by Cygwin's autorebase postinstall script every +time you run the Cygwin setup program (which you should do with no +Cygwin processes running). This script knows about the .eln files +installed in the standard places (e.g., +/usr/lib/emacs/28.1/native-lisp), but it does not know about those in +your user cache (e.g., /home//.emacs.d/eln-cache). In order +for these to be automatically rebased, you must create a file + + /var/lib/rebase/userpath.d/ + +with one line for each directory containing .eln files. If you are +running an installed Emacs, it should suffice to list your cache +directory. For example, if there is an Emacs user "kbrown", then +there should be a file + + /var/lib/rebase/userpath.d/kbrown + +containing the single line + + /home/kbrown/.emacs.d/eln-cache + +If you are running an Emacs that you have built but not installed, +then you will need an additional line giving the path to the +native-lisp subdirectory of your build directory. + +If more than one user will be using Emacs on your system, there should +be a file like this for each user. + +Rebasing is not currently done when new .eln files are created, so +fork failures are still possible between runs of Cygwin's setup +program. If you ever see a fork failure whose error message refers to +a .eln file, you should be able to fix it temporarily by exiting emacs +and issuing the command + + find ~/.emacs.d/eln-cache -name '*.eln' | rebase -O -T - + +This is called an "ephemeral" rebase. Again, if you are running an +Emacs that has not been installed, you need to add the native-lisp +subdirectory of your build directory to this command. Alternatively, +stop all Cygwin processes and run Cygwin's setup program to let the +autorebase postinstall script run. + +It is hoped that the measures above will make native compilation +usable on 64-bit Cygwin, with only an occasional minor annoyance. In +the 32-bit case, however, the limited address space makes frequent +fork failures extremely likely. It is therefore strongly recommended +that you not build Emacs with native compilation on 32-bit Cygwin. +Indeed, the configure script will not allow this unless you use the +--with-cygwin32-native-compilation option. + +See bug#50666 for further discussion. + + * Runtime problems specific to macOS ** Error message when opening Emacs on macOS commit 9fe663530c56d3c952e5f3c709d57301c3c076e9 Author: Stefan Kangas Date: Mon Jul 11 17:59:25 2022 +0200 Prefer defvar-keymap in thumbs.el * lisp/thumbs.el (thumbs-mode-map, thumbs-view-image-mode-map): Prefer defvar-keymap. diff --git a/lisp/thumbs.el b/lisp/thumbs.el index 158597d7c8..3b31f1d809 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el @@ -704,27 +704,25 @@ ACTION and ARG should be a valid convert command." ;; thumbs-mode -(defvar thumbs-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [return] 'thumbs-find-image-at-point) - (define-key map [mouse-2] 'thumbs-mouse-find-image) - (define-key map [(meta return)] 'thumbs-find-image-at-point-other-window) - (define-key map [(control return)] 'thumbs-set-image-at-point-to-root-window) - (define-key map [delete] 'thumbs-delete-images) - (define-key map [right] 'thumbs-forward-char) - (define-key map [left] 'thumbs-backward-char) - (define-key map [up] 'thumbs-backward-line) - (define-key map [down] 'thumbs-forward-line) - (define-key map "+" 'thumbs-show-more-images) - (define-key map "d" 'thumbs-dired) - (define-key map "m" 'thumbs-mark) - (define-key map "u" 'thumbs-unmark) - (define-key map "R" 'thumbs-rename-images) - (define-key map "x" 'thumbs-delete-images) - (define-key map "s" 'thumbs-show-name) - (define-key map "q" 'thumbs-kill-buffer) - map) - "Keymap for `thumbs-mode'.") +(defvar-keymap thumbs-mode-map + :doc "Keymap for `thumbs-mode'." + "" #'thumbs-find-image-at-point + "" #'thumbs-mouse-find-image + "M-" #'thumbs-find-image-at-point-other-window + "C-" #'thumbs-set-image-at-point-to-root-window + "" #'thumbs-delete-images + "" #'thumbs-forward-char + "" #'thumbs-backward-char + "" #'thumbs-backward-line + "" #'thumbs-forward-line + "+" #'thumbs-show-more-images + "d" #'thumbs-dired + "m" #'thumbs-mark + "u" #'thumbs-unmark + "R" #'thumbs-rename-images + "x" #'thumbs-delete-images + "s" #'thumbs-show-name + "q" #'thumbs-kill-buffer) (put 'thumbs-mode 'mode-class 'special) (define-derived-mode thumbs-mode @@ -732,22 +730,20 @@ ACTION and ARG should be a valid convert command." "Preview images in a thumbnails buffer." (setq buffer-read-only t)) -(defvar thumbs-view-image-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [prior] 'thumbs-previous-image) - (define-key map [next] 'thumbs-next-image) - (define-key map "^" 'thumbs-display-thumbs-buffer) - (define-key map "-" 'thumbs-shrink-image) - (define-key map "+" 'thumbs-enlarge-image) - (define-key map "<" 'thumbs-rotate-left) - (define-key map ">" 'thumbs-rotate-right) - (define-key map "e" 'thumbs-emboss-image) - (define-key map "r" 'thumbs-resize-image) - (define-key map "s" 'thumbs-save-current-image) - (define-key map "q" 'thumbs-kill-buffer) - (define-key map "w" 'thumbs-set-root) - map) - "Keymap for `thumbs-view-image-mode'.") +(defvar-keymap thumbs-view-image-mode-map + :doc "Keymap for `thumbs-view-image-mode'." + "" #'thumbs-previous-image + "" #'thumbs-next-image + "^" #'thumbs-display-thumbs-buffer + "-" #'thumbs-shrink-image + "+" #'thumbs-enlarge-image + "<" #'thumbs-rotate-left + ">" #'thumbs-rotate-right + "e" #'thumbs-emboss-image + "r" #'thumbs-resize-image + "s" #'thumbs-save-current-image + "q" #'thumbs-kill-buffer + "w" #'thumbs-set-root) ;; thumbs-view-image-mode (put 'thumbs-view-image-mode 'mode-class 'special) commit 871db806e686236d76e8ddbf3b11dc4bbdc0b91e Author: Mattias Engdegård Date: Mon Jul 11 17:31:38 2022 +0200 Remove obsolete uses of obsolete functions * src/minibuf.c (minibuf_conform_representation): Remove. (Ftry_completion): Don't call it. (Ftest_completion): Don't use the obsolete Fstring_make_unibyte or Fstring_make_multibyte; they don't serve any useful purpose here. We don't try to equate unibyte and multibyte raw bytes in symbol lookups elsewhere and there is no reason to do it here. diff --git a/src/minibuf.c b/src/minibuf.c index 0fba334b22..bedc564480 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1545,18 +1545,6 @@ function, instead of the usual behavior. */) return unbind_to (count, result); } -static Lisp_Object -minibuf_conform_representation (Lisp_Object string, Lisp_Object basis) -{ - if (STRING_MULTIBYTE (string) == STRING_MULTIBYTE (basis)) - return string; - - if (STRING_MULTIBYTE (string)) - return Fstring_make_unibyte (string); - else - return Fstring_make_multibyte (string); -} - static bool match_regexps (Lisp_Object string, Lisp_Object regexps, bool ignore_case) @@ -1817,7 +1805,7 @@ or from one of the possible completions. */) don't change the case of what the user typed. */ if (completion_ignore_case && bestmatchsize == SCHARS (string) && SCHARS (bestmatch) > bestmatchsize) - return minibuf_conform_representation (string, bestmatch); + return string; /* Return t if the supplied string is an exact match (counting case); it does not require any change to be made. */ @@ -2090,19 +2078,6 @@ the values STRING, PREDICATE and `lambda'. */) SSDATA (string), SCHARS (string), SBYTES (string)); - if (!SYMBOLP (tem)) - { - if (STRING_MULTIBYTE (string)) - string = Fstring_make_unibyte (string); - else - string = Fstring_make_multibyte (string); - - tem = oblookup (collection, - SSDATA (string), - SCHARS (string), - SBYTES (string)); - } - if (completion_ignore_case && !SYMBOLP (tem)) { for (i = ASIZE (collection) - 1; i >= 0; i--) commit ac0027f6a5480bd4739fdf71413a19012f400483 Author: Stefan Kangas Date: Mon Jul 11 17:21:23 2022 +0200 Remove dead branch from substitute-command-keys * lisp/help.el (substitute-command-keys): Remove dead branch; where-is-internal will follow any remaps for us. Note also that the test case for remapping still pass. diff --git a/lisp/help.el b/lisp/help.el index d7ee1a84a4..abe17fa4ce 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1192,14 +1192,6 @@ Otherwise, return a new string." (let* ((fun (intern (buffer-substring (point) (1- end-point)))) (key (with-current-buffer orig-buf (where-is-internal fun keymap t)))) - ;; If this a command remap, we need to follow it. - (when (and (vectorp key) - (> (length key) 1) - (eq (aref key 0) 'remap) - (symbolp (aref key 1))) - (setq fun (aref key 1)) - (setq key (with-current-buffer orig-buf - (where-is-internal fun keymap t)))) (if (not key) ;; Function is not on any key. (let ((op (point))) commit f9e4b2d3ce6ce091d19467e95d26125ac52beb7d Author: Lars Ingebrigtsen Date: Mon Jul 11 16:29:58 2022 +0200 Make `g' in `vc-annotate' not bug out * lisp/vc/vc-annotate.el (vc-annotate): Don't bug out on `g' (bug#48359). diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el index 4a511f1f68..1f19c4cfe2 100644 --- a/lisp/vc/vc-annotate.el +++ b/lisp/vc/vc-annotate.el @@ -451,7 +451,8 @@ should be applied to the background or to the foreground." (setq-local vc-annotate-backend backend) (setq-local vc-annotate-parent-file file) (setq-local vc-annotate-parent-rev rev) - (setq-local vc-annotate-parent-display-mode display-mode)))) + (setq-local vc-annotate-parent-display-mode display-mode) + (kill-local-variable 'revert-buffer-function)))) (with-current-buffer temp-buffer-name (vc-run-delayed commit b2e6e9558165eff1d6e51fb48cbfbc8c5f7bc1ca Author: Lars Ingebrigtsen Date: Mon Jul 11 16:05:08 2022 +0200 Only reset buffer-local buffer-stale-function in make-indirect-buffer * src/buffer.c (Fmake_indirect_buffer): Don't set the global buffer-stale-function (bug#48348). diff --git a/src/buffer.c b/src/buffer.c index 509ce51b55..a6d3604065 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -911,7 +911,8 @@ does not run the hooks `kill-buffer-hook', set_buffer_internal_1 (b); Fset (intern ("buffer-save-without-query"), Qnil); Fset (intern ("buffer-file-number"), Qnil); - Fset (intern ("buffer-stale-function"), Qnil); + if (!NILP (Flocal_variable_p (Qbuffer_stale_function, base_buffer))) + Fset (Qbuffer_stale_function, Qbuffer_stale__default_function); /* Cloned buffers need extra setup, to do things such as deep variable copies for list variables that might be mangled due to destructive operations in the indirect buffer. */ @@ -6478,5 +6479,8 @@ will run for `clone-indirect-buffer' calls as well. */); DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save"); + DEFSYM (Qbuffer_stale_function, "buffer-stale-function"); + DEFSYM (Qbuffer_stale__default_function, "buffer-stale--default-function"); + Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); } commit 84a5d47125072d8a47dcaa4b1d46331936fb1335 Author: Eli Zaretskii Date: Mon Jul 11 16:52:03 2022 +0300 ; Fix last change * doc/lispref/compile.texi (Native-Compilation Variables): Explain better what the value -1 of 'native-comp-speed' means. diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi index 2b6ec849d2..335200469b 100644 --- a/doc/lispref/compile.texi +++ b/doc/lispref/compile.texi @@ -983,7 +983,9 @@ Its value should be a number between @minus{}1 and 3. Values between 0 and 3 specify the optimization levels equivalent to the corresponding compiler @option{-O0}, @option{-O1}, etc.@: command-line options of the compiler. The value @minus{}1 means disable -native-compilation; functions and files will be only byte-compiled. +native-compilation: functions and files will be only byte-compiled; +however, the @file{*.eln} files will still be produced, they will just +contain the compiled code in bytecode form. The default value is 2. @end defopt commit 04610218939e377b4fe2992e1f5571e34ccd7e1a Author: Eli Zaretskii Date: Mon Jul 11 16:48:24 2022 +0300 ; * lisp/emacs-lisp/comp.el (native-comp-speed): Explain the -1 value. diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index a363bed364..7d09d2425b 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -45,7 +45,9 @@ (defcustom native-comp-speed 2 "Optimization level for native compilation, a number between -1 and 3. - -1 functions are kept in bytecode form and no native compilation is performed. + -1 functions are kept in bytecode form and no native compilation is performed + (but *.eln files are still produced, and include the compiled code in + bytecode form). 0 native compilation is performed with no optimizations. 1 light optimizations. 2 max optimization level fully adherent to the language semantic. commit 1e6a36361d824831107bb95b825c5698a7a07b5f Author: Lars Ingebrigtsen Date: Mon Jul 11 15:38:59 2022 +0200 Document the recent add-global-abbrev change * doc/emacs/abbrevs.texi (Defining Abbrevs): Document that you can use the active region. diff --git a/doc/emacs/abbrevs.texi b/doc/emacs/abbrevs.texi index 07f66ec10a..77f40c7df2 100644 --- a/doc/emacs/abbrevs.texi +++ b/doc/emacs/abbrevs.texi @@ -106,8 +106,10 @@ taken as the expansion. For example, to define the abbrev @samp{foo} as mentioned above, insert the text @samp{find outer otter} and then type @kbd{C-u 3 C-x a g f o o @key{RET}}. - An argument of zero to @kbd{C-x a g} means to use the contents of the -region as the expansion of the abbrev being defined. + If you're using @code{transient-mark-mode} (which is the default), +the active region will be used as the expansion of the abbrev being +defined. If not, an argument of zero to @kbd{C-x a g} means to use +the contents of the region. @kindex C-x a l @findex add-mode-abbrev commit ce31339c8369f6d16d5a7b1e8769670891c57f97 Author: Lars Ingebrigtsen Date: Mon Jul 11 15:34:07 2022 +0200 Make add-mode-abbrev use the active region * lisp/abbrev.el (add-mode-abbrev, add-global-abbrev): Document it. (add-abbrev): If there's an active region, use that as the expansion (bug#56496). diff --git a/lisp/abbrev.el b/lisp/abbrev.el index 21aa3311d6..718938df0c 100644 --- a/lisp/abbrev.el +++ b/lisp/abbrev.el @@ -292,8 +292,11 @@ The saved abbrevs are written to the file specified by (defun add-mode-abbrev (arg) "Define a mode-specific abbrev whose expansion is the last word before point. +If there's an active region, use that as the expansion. + Prefix argument ARG says how many words before point to use for the expansion; zero means the entire region is the expansion. + A negative ARG means to undefine the specified abbrev. This command reads the abbreviation from the minibuffer. @@ -303,7 +306,7 @@ if the abbreviation is already in the buffer, use that command to define a mode-specific abbrev by specifying its expansion in the minibuffer. Don't use this function in a Lisp program; use `define-abbrev' instead." - (interactive "p") + (interactive "P") (add-abbrev (if only-global-abbrevs global-abbrev-table @@ -313,8 +316,11 @@ Don't use this function in a Lisp program; use `define-abbrev' instead." (defun add-global-abbrev (arg) "Define a global (all modes) abbrev whose expansion is last word before point. +If there's an active region, use that as the expansion. + Prefix argument ARG says how many words before point to use for the expansion; zero means the entire region is the expansion. + A negative ARG means to undefine the specified abbrev. This command reads the abbreviation from the minibuffer. @@ -324,15 +330,21 @@ if the abbreviation is already in the buffer, use that command to define a global abbrev by specifying its expansion in the minibuffer. Don't use this function in a Lisp program; use `define-abbrev' instead." - (interactive "p") + (interactive "P") (add-abbrev global-abbrev-table "Global" arg)) (defun add-abbrev (table type arg) - (let ((exp (and (>= arg 0) - (buffer-substring-no-properties - (point) - (if (= arg 0) (mark) - (save-excursion (forward-word (- arg)) (point)))))) + (let ((exp + (cond + ((or (and (null arg) (use-region-p)) + (zerop (prefix-numeric-value arg))) + (buffer-substring-no-properties (region-beginning) (region-end))) + ((> (prefix-numeric-value arg) 0) + (buffer-substring-no-properties + (point) + (save-excursion + (forward-word (- (prefix-numeric-value arg))) + (point)))))) name) (setq name (read-string (format (if exp "%s abbrev that expands into \"%s\": " commit b3fd71ed10139ca37b78234def000b76dfb95516 Author: Stefan Kangas Date: Mon Jul 11 15:05:56 2022 +0200 ; * etc/NEWS: Announce obsoletion of rlogin.el. diff --git a/etc/NEWS b/etc/NEWS index afe0f115c5..bf36316890 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -321,6 +321,10 @@ the major mode according to 'initial-major-mode', like at Emacs startup. Previously, these functions ignored 'initial-scratch-message' and left "*scratch*" in 'fundamental-mode'. +--- +** The rlogin.el library is now obsolete. +Use something like `M-x shell RET ssh RET' instead. + * Changes in Emacs 29.1 commit cd5a8f9cc1eea80ad15285929559aa5d4eb11321 Author: Stefan Kangas Date: Mon Jul 11 13:56:28 2022 +0200 * lisp/obsolete/rlogin.el: Add "Obsolete-since" line. diff --git a/lisp/obsolete/rlogin.el b/lisp/obsolete/rlogin.el index a6d0edae07..6a06300ae3 100644 --- a/lisp/obsolete/rlogin.el +++ b/lisp/obsolete/rlogin.el @@ -4,6 +4,7 @@ ;; Author: Noah Friedman ;; Keywords: unix, comm +;; Obsolete-since: 29.1 ;; This file is part of GNU Emacs. @@ -22,6 +23,9 @@ ;;; Commentary: +;; This library is obsolete. +;; See: https://debbugs.gnu.org/56461 + ;; Support for remote logins using `rlogin'. ;; This program is layered on top of shell.el; the code here only accounts ;; for the variations needed to handle a remote process, e.g. directory @@ -34,11 +38,6 @@ ;;; Code: -;; FIXME? -;; Maybe this file should be obsolete. -;; https://lists.gnu.org/r/emacs-devel/2013-02/msg00517.html -;; It only adds rlogin-directory-tracking-mode. Is that useful? - (require 'comint) (require 'shell) commit 512e1db7ba08e0fb53d1e8584ed16974e65cd835 Author: Stefan Kangas Date: Mon Jul 11 13:55:41 2022 +0200 Make net/rlogin.el obsolete * lisp/net/rlogin.el: Move from here... * lisp/obsolete/rlogin.el: ...to here. (Bug#56461) diff --git a/lisp/net/rlogin.el b/lisp/obsolete/rlogin.el similarity index 100% rename from lisp/net/rlogin.el rename to lisp/obsolete/rlogin.el commit 899616108b075417778a049ff0fb2fc864cec942 Author: Stefan Kangas Date: Mon Jul 11 14:56:48 2022 +0200 * src/.lldbinit: Fix copyright year. diff --git a/src/.lldbinit b/src/.lldbinit index 617d63958b..358cea5f8b 100644 --- a/src/.lldbinit +++ b/src/.lldbinit @@ -1,5 +1,5 @@ # -*- mode: shell-script -*- -# Copyright (C) 1992-1998, 2000-2022 Free Software Foundation, Inc. +# Copyright (C) 2022 Free Software Foundation, Inc. # # This file is part of GNU Emacs. # commit 4e8448b4bc5aae297c053080bc04208f5a0793e8 Author: Lars Ingebrigtsen Date: Mon Jul 11 14:51:34 2022 +0200 Allow commands that call `yes-or-no-p' to be repeatable again * lisp/subr.el (y-or-n-p): Enable commands that call this function to be repeatable (bug#45999). This stopped working after this function started using read-from-minibuffer. * src/fns.c (Fyes_or_no_p): Ditto. diff --git a/lisp/subr.el b/lisp/subr.el index f8b386e563..ef2edcff10 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3482,8 +3482,11 @@ like) while `y-or-n-p' is running)." (format "(y, n or %s) " (key-description (vector help-char))) - "(y or n) " - ))))))) + "(y or n) ")))))) + ;; Preserve the actual command that eventually called + ;; `y-or-n-p' (otherwise `repeat' will be repeating + ;; `exit-minibuffer'). + (real-this-command real-this-command)) (cond (noninteractive (setq prompt (funcall padded prompt)) diff --git a/src/fns.c b/src/fns.c index eb83471649..1f57e675b1 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2975,6 +2975,9 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) specpdl_ref count = SPECPDL_INDEX (); specbind (Qenable_recursive_minibuffers, Qt); + /* Preserve the actual command that eventually called `yes-or-no-p' + (otherwise `repeat' will be repeating `exit-minibuffer'). */ + specbind (Qreal_this_command, Vreal_this_command); while (1) { @@ -6129,4 +6132,6 @@ The same variable also affects the function `read-answer'. */); defsubr (&Sbuffer_hash); defsubr (&Slocale_info); defsubr (&Sbuffer_line_statistics); + + DEFSYM (Qreal_this_command, "real-this-command"); } commit 4c41cef353cc68bbe432dc32fe9edffbea71dc6b Author: Stefan Kangas Date: Mon Jul 11 14:29:33 2022 +0200 Move EIEIO autoloads to the common loaddefs.el * lisp/emacs-lisp/eieio-core.el: * lisp/emacs-lisp/eieio-custom.el: * lisp/emacs-lisp/eieio-opt.el: * lisp/obsolete/eieio-compat.el: Remove generated-autoload-file setting and don't require eieio-loaddefs.el. diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 25f2dd4098..5e7b5cbfb2 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -32,7 +32,6 @@ ;;; Code: (require 'cl-lib) -(require 'eieio-loaddefs nil t) ;;; ;; A few functions that are better in the official EIEIO src, but diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 4b8b4275f1..0bec3bb0d5 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -467,8 +467,4 @@ Return the symbol for the group, or nil." (provide 'eieio-custom) -;; Local variables: -;; generated-autoload-file: "eieio-loaddefs.el" -;; End: - ;;; eieio-custom.el ends here diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index 72108f807f..5f67263f17 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -348,8 +348,4 @@ INDENT is the current indentation level." (provide 'eieio-opt) -;; Local variables: -;; generated-autoload-file: "eieio-loaddefs.el" -;; End: - ;;; eieio-opt.el ends here diff --git a/lisp/obsolete/eieio-compat.el b/lisp/obsolete/eieio-compat.el index 2ac75293fc..ead9352695 100644 --- a/lisp/obsolete/eieio-compat.el +++ b/lisp/obsolete/eieio-compat.el @@ -253,11 +253,6 @@ Summary: (declare (obsolete eieio-defclass-internal "25.1")) (eval `(defclass ,cname ,superclasses ,slots ,@options))) - -;; Local Variables: -;; generated-autoload-file: "eieio-loaddefs.el" -;; End: - (provide 'eieio-compat) ;;; eieio-compat.el ends here commit 7af425f87bf9866c60ac134cbb6aa9eb0c61f8af Author: Gerd Möllmann Date: Sun Jul 10 13:35:32 2022 +0200 Support for debugging Emacs with LLDB * (src/.lldbinit): New file. * (etc/emacs_lldb.py): Module loaded from .lldbinit. diff --git a/etc/DEBUG b/etc/DEBUG index 7d2f810d07..df289310f9 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -1036,6 +1036,42 @@ recovering the contents of Emacs buffers from a core dump file. You might also find those commands useful for displaying the list of buffers in human-readable format from within the debugger. +*** Debugging Emacs with LLDB + +On systems where GDB is not available, like macOS with M1 chip, you +can also use LLDB for Emacs debugging. + +To start LLDB to debug Emacs, you can simply type "lldb ./emacs RET" +at the shell prompt in directory of the Emacs executable, usually the +'src' sub-directory of the Emacs tree). + +When you debug Emacs with LLDB, you should start LLDB in the directory +where the Emacs executable was built. That directory has an .lldbinit +file that loads a Python module emacs_lldb.py from the 'etc' directory +of the Emacs source tree. The Python module defines "user-defined" +commands for debugging Emacs. + +LLDB by default does not automatically load .lldbinit files in the +current directory. The simplest way to fix this is to add the +following line to your ~/.lldbinit file (creating such a file if it +doesn't already exist): + + settings set target.load-cwd-lldbinit true + +Alternatively, you can type "lldb --local-lldbinit ./emacs RET". + +If everything worked, you should see something like "Emacs debugging +support has been installed" after starting LLDB. You can see which +Emacs-specific commands are defined with + + (lldb) help + +User-defined commands for Emacs debugging start with an "x". + +Please refer to the LLDB reference on the web for more information +about LLDB. If you already know GDB, you will also find a mapping +from GDB commands to corresponding LLDB commands there. + This file is part of GNU Emacs. diff --git a/etc/emacs_lldb.py b/etc/emacs_lldb.py new file mode 100644 index 0000000000..4e0b20c8a5 --- /dev/null +++ b/etc/emacs_lldb.py @@ -0,0 +1,173 @@ +# Copyright (C) 2022 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, 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 . + +# Load this module in LLDB with +# +# (lldb) command script import emacs_lldb +# +# Available commands start with 'x' and can be seen with +# +# (lldb) help + +import lldb + + +######################################################################## +# Utilties +######################################################################## + +# Return the Lisp_Type of Lisp_Object OBJ. +def get_lisp_type(obj): + int_value = obj.GetValueAsUnsigned() + return obj.GetFrame().EvaluateExpression( + f"(enum Lisp_Type) ((EMACS_INT) {int_value} " + "& (1 << GCTYPEBITS) - 1)") + +# Return the Lisp_Type or pseudo-vector type of OBJ. +def get_lisp_type_or_vectorlike(obj): + lisp_type = get_lisp_type(obj) + if enumerator_name(lisp_type) == "Lisp_Vectorlike": + vector = get_lisp_pointer(obj, "struct Lisp_Vector") + header_size = vector.GetValueForExpressionPath( + "->header.size").GetValueAsUnsigned() + frame = obj.GetFrame() + pseudo = frame.EvaluateExpression( + f"{header_size} & PSEUDOVECTOR_FLAG") + if pseudo.GetValueAsUnsigned() != 0: + return frame.EvaluateExpression( + f"(enum pvec_type) (({header_size} " + "& More_Lisp_Bits::PVEC_TYPE_MASK) " + ">> More_Lisp_Bits::PSEUDOVECTOR_AREA_BITS)") + return frame.EvaluateExpression("pvec_type::PVEC_NORMAL_VECTOR") + return lisp_type + +# Return Lisp_Object OBJ as pointer to TYP *. +def get_lisp_pointer(obj, typ): + return obj.GetFrame().EvaluateExpression( + f"({typ}*) (((EMACS_INT) {obj.GetValueAsUnsigned()}) & VALMASK)") + +# Return Lisp_Object OBJ as pointer to Lisp_Symbol. +def get_lisp_symbol(obj): + ptr = get_lisp_pointer(obj, "char") + offset = ptr.GetValueAsUnsigned() + return obj.GetFrame().EvaluateExpression( + f"(struct Lisp_Symbol *) ((char *) &lispsym + {offset})") + +# Return Lisp_Object OBJ as pointer to Lisp_String +def get_lisp_string(obj): + return get_lisp_pointer(obj, "struct Lisp_String") + +# Return the string data of Lisp_Object OBJ which denotes a Lisp_String. +def get_lisp_string_data(obj): + string = get_lisp_string(obj) + return string.GetValueForExpressionPath("->u.s.data") + +# Assuming OBJ denotes a Lisp_Symbol, return the name of the symbol. +def get_lisp_symbol_name(obj): + sym = get_lisp_symbol(obj) + name = sym.GetValueForExpressionPath("->u.s.name") + return get_lisp_string_data(name) + +# Return a string for the enuerator ENUM. +def enumerator_name(enum): + enumerators = enum.GetType().GetEnumMembers() + return enumerators[enum.GetValueAsUnsigned()].GetName() + + +######################################################################## +# LLDB Commands +######################################################################## + +def xbacktrace(debugger, command, ctx, result, internal_dict): + """Print Emacs Lisp backtrace""" + frame = ctx.GetFrame() + n = frame.EvaluateExpression( + "current_thread->m_specpdl_ptr - current_thread->m_specpdl") + for i in reversed(range(0, n.GetValueAsUnsigned())): + s = frame.EvaluateExpression(f"current_thread->m_specpdl[{i}]") + kind = enumerator_name(s.GetChildMemberWithName("kind")) + if kind == "SPECPDL_BACKTRACE": + function = s.GetValueForExpressionPath(".bt.function") + function_type = enumerator_name(get_lisp_type(function)) + if function_type == "Lisp_Symbol": + sym_name = get_lisp_symbol_name(function) + result.AppendMessage(str(sym_name)) + elif function_type == "Lisp_Vectorlike": + subtype = get_lisp_type_or_vectorlike(function) + result.AppendMessage(str(subtype)) + else: + result.AppendMessage(function_type) + +def xdebug_print(debugger, command, result, internal_dict): + """Print Lisp_Objects using safe_debug_print()""" + debugger.HandleCommand(f"expr safe_debug_print({command})") + + +######################################################################## +# Formatters +######################################################################## + +# Return a type summary for Lisp_Objects. +def format_Lisp_Object(obj, internal_dict): + lisp_type = get_lisp_type_or_vectorlike(obj) + kind = enumerator_name(lisp_type) + summary = "-> " + if kind == "PVEC_FRAME": + ptr = get_lisp_pointer(obj, "struct frame") + summary += str(ptr) + elif kind == "PVEC_WINDOW": + ptr = get_lisp_pointer(obj, "struct window") + summary += str(ptr) + return summary + + +######################################################################## +# Initialization +######################################################################## + +# Define Python FUNCTION as an LLDB command. +def define_command (debugger, function): + lldb_command = function.__name__ + python_function = __name__ + "." + function.__name__ + interpreter = debugger.GetCommandInterpreter() + def define(overwrite): + res = lldb.SBCommandReturnObject() + interpreter.HandleCommand(f"command script add " + f"{overwrite} " + f"--function {python_function} " + f"{lldb_command}", + res) + return res.Succeeded() + if not define("--overwrite"): + define("") + +# Define Python FUNCTION as an LLDB type formatter. +def define_formatter(debugger, regex, function): + python_function = __name__ + "." + function.__name__ + debugger.HandleCommand(f"type summary add " + f"--cascade true " + f'--regex "{regex}" ' + f"--python-function {python_function}") + +# This function is called by LLDB to initialize the module. +def __lldb_init_module(debugger, internal_dict): + define_command(debugger, xbacktrace) + define_command(debugger, xdebug_print) + define_formatter(debugger, "Lisp_Object", format_Lisp_Object) + print('Emacs debugging support has been installed.') + +# end. diff --git a/src/.lldbinit b/src/.lldbinit new file mode 100644 index 0000000000..617d63958b --- /dev/null +++ b/src/.lldbinit @@ -0,0 +1,33 @@ +# -*- mode: shell-script -*- +# Copyright (C) 1992-1998, 2000-2022 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, 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 . +# +# Use 'lldb --local-init' or add to your ~/.lldbinit the line +# +# settings set target.load-cwd-lldbinit true +# +# Emacs-specific commands start with 'x'. Type 'help' to see all +# commands. Type 'help ' to see help for a command +# . + +# Make Python find our files +script -- sys.path.append('../etc') + +# Load our Python files +command script import emacs_lldb + +# end. commit d9732425a6b339d83332f265da32fc3802357701 Author: Stefan Kangas Date: Mon Jul 11 14:03:25 2022 +0200 Don't create unused file rmail-loaddefs.el * lisp/mail/undigest.el: Remove 'generated-autoload-file' local variable. (Bug#56491) diff --git a/lisp/mail/undigest.el b/lisp/mail/undigest.el index c6d29bc4e7..cdb1bec478 100644 --- a/lisp/mail/undigest.el +++ b/lisp/mail/undigest.el @@ -378,8 +378,4 @@ forwarded with `rmail-enable-mime-composing' set to nil." (provide 'undigest) -;; Local Variables: -;; generated-autoload-file: "rmail-loaddefs.el" -;; End: - ;;; undigest.el ends here commit 5990da629074b09212d7dea31811d0429e3e2fb8 Author: Mattias Engdegård Date: Mon Jul 11 13:43:34 2022 +0200 Simplify str_to_multibyte and related code * src/character.h (str_to_multibyte): * src/character.c (str_to_multibyte): Remove `nbytes` argument; return it instead. Copy forwards. * src/fns.c (concat_to_string, Fstring_make_multibyte): Use str_to_multibyte. (string_make_multibyte): Remove. (string_to_multibyte): * src/print.c (print_string): Adapt calls. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 352ac40663..b7147a7f50 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1288,8 +1288,6 @@ See Info node `(elisp) Integer Basics'." form)) ;; Fixme: delete-char -> delete-region (byte-coded) -;; optimize string-as-unibyte, string-as-multibyte, string-make-unibyte, -;; string-make-multibyte for constant args. (put 'set 'byte-optimizer #'byte-optimize-set) (defun byte-optimize-set (form) diff --git a/src/character.c b/src/character.c index 841e46c091..968daccafa 100644 --- a/src/character.c +++ b/src/character.c @@ -666,26 +666,26 @@ count_size_as_multibyte (const unsigned char *str, ptrdiff_t len) } -/* Convert unibyte text at SRC of NCHARS bytes to a multibyte text - at DST of NBYTES bytes, that contains the same single-byte characters. */ -void +/* Convert unibyte text at SRC of NCHARS chars to a multibyte text + at DST, that contains the same single-byte characters. + Return the number of bytes written at DST. */ +ptrdiff_t str_to_multibyte (unsigned char *dst, const unsigned char *src, - ptrdiff_t nchars, ptrdiff_t nbytes) + ptrdiff_t nchars) { - const unsigned char *s = src + nchars; - unsigned char *d = dst + nbytes; + unsigned char *d = dst; for (ptrdiff_t i = 0; i < nchars; i++) { - unsigned char c = *--s; + unsigned char c = src[i]; if (c <= 0x7f) - *--d = c; + *d++ = c; else { - *--d = 0x80 + (c & 0x3f); - *--d = 0xc0 + ((c >> 6) & 1); + *d++ = 0xc0 + ((c >> 6) & 1); + *d++ = 0x80 + (c & 0x3f); } } - eassert (d == dst && s == src); + return d - dst; } /* Arrange multibyte text at STR of LEN bytes as a unibyte text. It diff --git a/src/character.h b/src/character.h index 36e2b06ee1..6d0f035c2b 100644 --- a/src/character.h +++ b/src/character.h @@ -567,8 +567,8 @@ extern int translate_char (Lisp_Object, int c); extern ptrdiff_t count_size_as_multibyte (const unsigned char *, ptrdiff_t); extern ptrdiff_t str_as_multibyte (unsigned char *, ptrdiff_t, ptrdiff_t, ptrdiff_t *); -extern void str_to_multibyte (unsigned char *dst, const unsigned char *src, - ptrdiff_t nchars, ptrdiff_t nbytes); +extern ptrdiff_t str_to_multibyte (unsigned char *dst, const unsigned char *src, + ptrdiff_t nchars); extern ptrdiff_t str_as_unibyte (unsigned char *, ptrdiff_t); extern ptrdiff_t strwidth (const char *, ptrdiff_t); extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int, diff --git a/src/fns.c b/src/fns.c index 7d8f957ef9..eb83471649 100644 --- a/src/fns.c +++ b/src/fns.c @@ -856,9 +856,8 @@ concat_to_string (ptrdiff_t nargs, Lisp_Object *args) else { /* Copy a single-byte string to a multibyte string. */ - toindex_byte += copy_text (SDATA (arg), - SDATA (result) + toindex_byte, - nchars, 0, 1); + toindex_byte += str_to_multibyte (SDATA (result) + toindex_byte, + SDATA (arg), nchars); } toindex += nchars; } @@ -1205,37 +1204,6 @@ string_byte_to_char (Lisp_Object string, ptrdiff_t byte_index) return i; } -/* Convert STRING to a multibyte string. */ - -static Lisp_Object -string_make_multibyte (Lisp_Object string) -{ - unsigned char *buf; - ptrdiff_t nbytes; - Lisp_Object ret; - USE_SAFE_ALLOCA; - - if (STRING_MULTIBYTE (string)) - return string; - - nbytes = count_size_as_multibyte (SDATA (string), - SCHARS (string)); - /* If all the chars are ASCII, they won't need any more bytes - once converted. In that case, we can return STRING itself. */ - if (nbytes == SBYTES (string)) - return string; - - buf = SAFE_ALLOCA (nbytes); - copy_text (SDATA (string), buf, SBYTES (string), - 0, 1); - - ret = make_multibyte_string ((char *) buf, SCHARS (string), nbytes); - SAFE_FREE (); - - return ret; -} - - /* Convert STRING (if unibyte) to a multibyte string without changing the number of characters. Characters 0x80..0xff are interpreted as raw bytes. */ @@ -1254,7 +1222,7 @@ string_to_multibyte (Lisp_Object string) return make_multibyte_string (SSDATA (string), nbytes, nbytes); Lisp_Object ret = make_uninit_multibyte_string (nchars, nbytes); - str_to_multibyte (SDATA (ret), SDATA (string), nchars, nbytes); + str_to_multibyte (SDATA (ret), SDATA (string), nchars); return ret; } @@ -1299,7 +1267,17 @@ string the same way whether it is unibyte or multibyte.) */) { CHECK_STRING (string); - return string_make_multibyte (string); + if (STRING_MULTIBYTE (string)) + return string; + + ptrdiff_t nchars = SCHARS (string); + ptrdiff_t nbytes = count_size_as_multibyte (SDATA (string), nchars); + if (nbytes == nchars) + return string; + + Lisp_Object ret = make_uninit_multibyte_string (nchars, nbytes); + str_to_multibyte (SDATA (ret), SDATA (string), nchars); + return ret; } DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte, diff --git a/src/print.c b/src/print.c index 9a31e386f5..b5a621f80a 100644 --- a/src/print.c +++ b/src/print.c @@ -467,7 +467,7 @@ print_string (Lisp_Object string, Lisp_Object printcharfun) if (chars < bytes) { newstr = make_uninit_multibyte_string (chars, bytes); - str_to_multibyte (SDATA (newstr), SDATA (string), chars, bytes); + str_to_multibyte (SDATA (newstr), SDATA (string), chars); string = newstr; } } commit 050252043fe85e12412de311a08f0159cd89e92a Author: Stefan Kangas Date: Mon Jul 11 13:47:08 2022 +0200 Doc fix; don't mention rlogin * doc/emacs/misc.texi (Remote Host): * doc/misc/eshell.texi (Bugs and ideas): Don't mention rlogin. (Bug#56461) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 9709c6ddc1..841a285520 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -1643,11 +1643,11 @@ interface is similar to the @code{more} program. @cindex remote host @cindex connecting to remote host @cindex Telnet -@cindex Rlogin +@cindex SSH You can login to a remote computer, using whatever commands you -would from a regular terminal (e.g., using the @command{ssh} or -@command{telnet} or @code{rlogin} commands), from a Term window. +would from a regular terminal (e.g., the @command{ssh} command), from +a Term window. A program that asks you for a password will normally suppress echoing of the password, so the password will not show up in the diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 2e3ba4c273..6a348f37dc 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -2077,11 +2077,10 @@ it). @item Make the shell spawning commands be visual -That is, make (@command{su}, @command{bash}, @command{telnet}, -@command{rlogin}, @command{rsh}, etc.)@: be part of -@code{eshell-visual-commands}. The only exception is if the shell is -being used to invoke a single command. Then, the behavior should be -based on what that command is. +That is, make (@command{su}, @command{bash}, @command{ssh}, etc.)@: be +part of @code{eshell-visual-commands}. The only exception is if the +shell is being used to invoke a single command. Then, the behavior +should be based on what that command is. @item Create a smart viewing command named @command{open} commit 6f57fb71a50a8b2ac8163828a2cecb394bb52d06 Author: Po Lu Date: Mon Jul 11 19:36:01 2022 +0800 Improve behavior of `lost-selection-mode' with multiple buffers * etc/NEWS: Announce new hook `post-select-region-hook'. * lisp/select.el (lost-selection-last-region-buffer): New variable. (lost-selection-post-select-region-function): New function. Deactivate the mark if the buffer changed. (lost-selection-mode): Add new hook. * src/keyboard.c (command_loop_1): Run that hook when appropriate. (syms_of_keyboard): New hook `post-select-region-hook'. diff --git a/etc/NEWS b/etc/NEWS index 526bda283c..afe0f115c5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2665,6 +2665,10 @@ them towards or away from each other. This hook is run before 'x-popup-menu' is about to display a deck-of-cards menu on screen. +** New hook 'post-select-region-hook'. +This hook is run immediately after 'select-active-regions' causes the +region to be set as the primary selection. + ** New function 'buffer-match-p'. Check if a buffer satisfies some condition. Some examples for conditions can be regular expressions that match a buffer name, a diff --git a/lisp/select.el b/lisp/select.el index 6002b2615e..2d501f207f 100644 --- a/lisp/select.el +++ b/lisp/select.el @@ -479,6 +479,24 @@ are not available to other programs." ;; Minor mode to make losing ownership of PRIMARY behave more like ;; other X programs. +(defvar lost-selection-last-region-buffer nil + "The last buffer from which the region was selected.") + +(defun lost-selection-post-select-region-function (_text) + "Handle the region being selected into PRIMARY. +If the current buffer is different from the last buffer, +deactivate the mark in every other buffer. +TEXT is ignored." + (when (not (eq lost-selection-last-region-buffer + (current-buffer))) + (dolist (buffer (buffer-list)) + (unless (or (string-match-p "^ " + (buffer-name buffer)) + (eq buffer (current-buffer))) + (with-current-buffer buffer + (deactivate-mark t)))) + (setq lost-selection-last-region-buffer (current-buffer)))) + (defun lost-selection-function (selection) "Handle losing of ownership of SELECTION. If SELECTION is `PRIMARY', deactivate the mark in every @@ -496,22 +514,32 @@ non-temporary buffer." When this is enabled, selecting some text in another program will cause the mark to be deactivated in all buffers, mimicking the -behavior of most X Windows programs." +behavior of most X Windows programs. + +Selecting text in a buffer that ends up changing the primary +selection will also cause the mark to be deactivated in all other +buffers." :global t :group 'x (if lost-selection-mode - (cond ((featurep 'x) (add-hook 'x-lost-selection-functions - #'lost-selection-function)) - ((featurep 'pgtk) (add-hook 'pgtk-lost-selection-functions - #'lost-selection-function)) - ((featurep 'haiku) (add-hook 'haiku-lost-selection-functions - #'lost-selection-function))) + (progn + (cond ((featurep 'x) (add-hook 'x-lost-selection-functions + #'lost-selection-function)) + ((featurep 'pgtk) (add-hook 'pgtk-lost-selection-functions + #'lost-selection-function)) + ((featurep 'haiku) (add-hook 'haiku-lost-selection-functions + #'lost-selection-function))) + (add-hook 'post-select-region-hook + #'lost-selection-post-select-region-function)) (cond ((featurep 'x) (remove-hook 'x-lost-selection-functions #'lost-selection-function)) ((featurep 'pgtk) (remove-hook 'pgtk-lost-selection-functions #'lost-selection-function)) ((featurep 'haiku) (remove-hook 'haiku-lost-selection-functions - #'lost-selection-function))))) + #'lost-selection-function))) + (remove-hook 'post-select-region-hook + #'lost-selection-post-select-region-function) + (setq lost-selection-last-region-buffer nil))) ;; Functions to convert the selection into various other selection types. diff --git a/src/keyboard.c b/src/keyboard.c index 7c13ac9611..1d505c13be 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1590,9 +1590,12 @@ command_loop_1 (void) { Lisp_Object txt = call1 (Vregion_extract_function, Qnil); + if (XFIXNUM (Flength (txt)) > 0) /* Don't set empty selections. */ call2 (Qgui_set_selection, QPRIMARY, txt); + + CALLN (Frun_hook_with_args, Qpost_select_region_hook, txt); } if (current_buffer != prev_buffer || MODIFF != prev_modiff) @@ -12080,6 +12083,9 @@ syms_of_keyboard (void) DEFSYM (Qpre_command_hook, "pre-command-hook"); DEFSYM (Qpost_command_hook, "post-command-hook"); + /* Hook run after the region is selected. */ + DEFSYM (Qpost_select_region_hook, "post-select-region-hook"); + DEFSYM (Qundo_auto__add_boundary, "undo-auto--add-boundary"); DEFSYM (Qundo_auto__undoably_changed_buffers, "undo-auto--undoably-changed-buffers"); @@ -13028,6 +13034,12 @@ not recorded. The non-nil value countermands `inhibit--record-char', which see. */); record_all_keys = false; + DEFVAR_LISP ("post-select-region-hook", Vpost_select_region_hook, + doc: /* Abnormal hook run after the region is selected. +This usually happens as a result of `select-active-regions'. The hook +is called with one argument, the string that was selected. */);; + Vpost_select_region_hook = Qnil; + pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); } commit 2f823ffd28d064fc8c1a3947e74c512b577863c6 Author: Lars Ingebrigtsen Date: Mon Jul 11 13:34:35 2022 +0200 Fix crm.el compilation warning * lisp/emacs-lisp/crm.el (crm-default-separator): Move to avoid compilation warning. diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el index 9c49e09578..6d4b29b552 100644 --- a/lisp/emacs-lisp/crm.el +++ b/lisp/emacs-lisp/crm.el @@ -77,6 +77,8 @@ ;;; Code: +(define-obsolete-variable-alias 'crm-default-separator 'crm-separator "29.1") + (defvar crm-separator "[ \t]*,[ \t]*" "Separator regexp used for separating strings in `completing-read-multiple'. It should be a regexp that does not match the list of completion candidates.") @@ -294,8 +296,6 @@ with empty strings removed." ;(completing-read my-prompt my-table nil t) ;(completing-read my-prompt my-table nil "match") -(define-obsolete-variable-alias 'crm-default-separator 'crm-separator "29.1") - (provide 'crm) ;;; crm.el ends here commit 061de95d5951642d19cc9445ddbe063e1e2019bb Author: Lars Ingebrigtsen Date: Mon Jul 11 13:19:48 2022 +0200 Don't call home from test/src/process-tests.el * test/src/process-tests.el (process-num-processors): Move from here... * test/manual/process-callout-tests.el: ... to here (bug#55858). diff --git a/test/manual/process-callout-tests.el b/test/manual/process-callout-tests.el new file mode 100644 index 0000000000..0bb960cf90 --- /dev/null +++ b/test/manual/process-callout-tests.el @@ -0,0 +1,64 @@ +;;; process-callout-tests.el --- Testing the process facilities -*- lexical-binding: t -*- + +;; Copyright (C) 2022 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: + +;; + +;;; Code: + +(require 'cl-lib) +(require 'ert) + +;;; This test is here in test/manual instead of +;;; test/src/process-tests.el for two reasons: The test suite +;;; shouldn't "call home" automatically, because that's against our +;;; privacy principles, and as a practical matter, the server may have +;;; problems, and that shouldn't trigger a test error. + +(ert-deftest process-async-https-with-delay () + "Bug#49449: asynchronous TLS connection with delayed completion." + (skip-unless (and internet-is-working (gnutls-available-p))) + (let* ((status nil) + (buf (url-http + #s(url "https" nil nil "elpa.gnu.org" nil + "/packages/archive-contents" nil nil t silent t t) + (lambda (s) (setq status s)) + '(nil) nil 'tls))) + (unwind-protect + (progn + ;; Busy-wait for 1 s to allow for the TCP connection to complete. + (let ((delay 1.0) + (t0 (float-time))) + (while (< (float-time) (+ t0 delay)))) + ;; Wait for the entire operation to finish. + (let ((limit 4.0) + (t0 (float-time))) + (while (and (null status) + (< (float-time) (+ t0 limit))) + (sit-for 0.1))) + (should status) + (should-not (plist-get status ':error)) + (should buf) + (should (> (buffer-size buf) 0)) + ) + (when buf + (kill-buffer buf))))) + +;;; process-callout-tests.el ends here diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 824c6da119..f1ed7e18d5 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -909,35 +909,6 @@ Return nil if FILENAME doesn't exist." ;; ...and the change description should be "interrupt". (should (equal '("interrupt\n") events))))) -(ert-deftest process-async-https-with-delay () - "Bug#49449: asynchronous TLS connection with delayed completion." - (skip-unless (and internet-is-working (gnutls-available-p))) - (let* ((status nil) - (buf (url-http - #s(url "https" nil nil "elpa.gnu.org" nil - "/packages/archive-contents" nil nil t silent t t) - (lambda (s) (setq status s)) - '(nil) nil 'tls))) - (unwind-protect - (progn - ;; Busy-wait for 1 s to allow for the TCP connection to complete. - (let ((delay 1.0) - (t0 (float-time))) - (while (< (float-time) (+ t0 delay)))) - ;; Wait for the entire operation to finish. - (let ((limit 4.0) - (t0 (float-time))) - (while (and (null status) - (< (float-time) (+ t0 limit))) - (sit-for 0.1))) - (should status) - (should-not (plist-get status ':error)) - (should buf) - (should (> (buffer-size buf) 0)) - ) - (when buf - (kill-buffer buf))))) - (ert-deftest process-num-processors () "Sanity checks for num-processors." (should (equal (num-processors) (num-processors))) commit 215a700751f88bba18989e340181361a484d5b3a Author: Visuwesh Date: Mon Jul 11 12:57:34 2022 +0200 Make mouse-2 respect delete-selection mode * lisp/delsel.el: Make the mouse yank commands delete-selection-mode aware (bug#56421). diff --git a/lisp/delsel.el b/lisp/delsel.el index 5310328e5f..723a52b17d 100644 --- a/lisp/delsel.el +++ b/lisp/delsel.el @@ -300,6 +300,9 @@ to `delete-selection-mode'." (put 'yank-pop 'delete-selection 'yank) (put 'yank-from-kill-ring 'delete-selection 'yank) (put 'clipboard-yank 'delete-selection 'yank) +(put 'mouse-yank-primary 'delete-selection 'yank) +(put 'mouse-yank-secondary 'delete-selection 'yank) +(put 'mouse-yank-at-click 'delete-selection 'yank) (put 'insert-register 'delete-selection t) ;; delete-backward-char and delete-forward-char already delete the selection by ;; default, but not delete-char. commit ade7a212a882540178d9504e7e0bd3be3bf1fd41 Author: Stefan Kangas Date: Mon Jul 11 12:41:50 2022 +0200 * lisp/emacs-lisp/package.el (define-package): Make obsolete. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 8d0d5d57a2..00beee811b 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -720,8 +720,7 @@ REQUIREMENTS is a list of dependencies on other packages. where OTHER-VERSION is a string. EXTRA-PROPERTIES is currently unused." - (declare (indent defun)) - ;; FIXME: Placeholder! Should we keep it? + (declare (obsolete nil "29.1") (indent defun)) (error "Don't call me!")) commit c0ced4e49989b98035729b46693a56c5f168d8bf Author: Po Lu Date: Mon Jul 11 18:48:12 2022 +0800 Prevent setting user time if the WM doesn't support it * src/xterm.c (x_update_frame_user_time_window): Don't set _NET_WM_USER_TIME if it's not supported by the window manager. diff --git a/src/xterm.c b/src/xterm.c index 39ce415472..2b83efb228 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7117,7 +7117,8 @@ x_update_frame_user_time_window (struct frame *f) output = FRAME_X_OUTPUT (f); dpyinfo = FRAME_DISPLAY_INFO (f); - if (!NILP (Vx_no_window_manager)) + if (!NILP (Vx_no_window_manager) + || !x_wm_supports (f, dpyinfo->Xatom_net_wm_user_time)) { if (output->user_time_window != None && output->user_time_window != FRAME_OUTER_WINDOW (f)) commit 25dd4f169d939295e76b8eb1c2fae2e3c15a191b Author: Mattias Engdegård Date: Mon Jul 11 12:19:18 2022 +0200 Add test for the gradle-android compilation message pattern * etc/compilation.txt (symbol): Add example. * test/lisp/progmodes/compile-tests.el (compile-tests--test-regexps-data): (compile-test-error-regexps): Add test case (bug#56249). diff --git a/etc/compilation.txt b/etc/compilation.txt index 111b2a37dc..fc254dd3d7 100644 --- a/etc/compilation.txt +++ b/etc/compilation.txt @@ -193,6 +193,15 @@ symbol: gradle-kotlin e: /src/Test.kt: (34, 15): foo: bar w: /src/Test.kt: (34, 15): foo: bar +* Gradle Android resource linking + +symbol: gradle-android + +Execution failed for task ':app:processDebugResources'. +> A failure occurred while executing com.android.build.gradle.internal.res.LinkApplicationAndroidResourcesTask$TaskAction + > Android resource linking failed + ERROR:/Users/salutis/src/AndroidSchemeExperiment/app/build/intermediates/incremental/debug/mergeDebugResources/stripped.dir/layout/item.xml:3: AAPT: error: '16dpw' is incompatible with attribute padding (attr) dimension. + * IAR Systems C Compiler diff --git a/test/lisp/progmodes/compile-tests.el b/test/lisp/progmodes/compile-tests.el index 774370be4c..36bdbe4c91 100644 --- a/test/lisp/progmodes/compile-tests.el +++ b/test/lisp/progmodes/compile-tests.el @@ -260,6 +260,9 @@ "e: e:\\src\\Test.kt: (34, 15): foo: bar" 4 15 34 "e:\\src\\Test.kt" 2) (gradle-kotlin "w: e:\\src\\Test.kt: (11, 98): foo: bar" 4 98 11 "e:\\src\\Test.kt" 1) + (gradle-android + " ERROR:/Users/salutis/src/AndroidSchemeExperiment/app/build/intermediates/incremental/debug/mergeDebugResources/stripped.dir/layout/item.xml:3: AAPT: error: '16dpw' is incompatible with attribute padding (attr) dimension." + 1 nil 3 "/Users/salutis/src/AndroidSchemeExperiment/app/build/intermediates/incremental/debug/mergeDebugResources/stripped.dir/layout/item.xml" 2) ;; Guile (guile-file "In foo.scm:\n" 1 nil nil "foo.scm") (guile-line " 63:4 [call-with-prompt prompt0 ...]" 1 4 63 nil) @@ -492,7 +495,7 @@ The test data is in `compile-tests--test-regexps-data'." (compilation-num-warnings-found 0) (compilation-num-infos-found 0)) (mapc #'compile--test-error-line compile-tests--test-regexps-data) - (should (eq compilation-num-errors-found 97)) + (should (eq compilation-num-errors-found 98)) (should (eq compilation-num-warnings-found 35)) (should (eq compilation-num-infos-found 28))))) commit 7ae7a95e803aa898d31673d552f254092ce202b1 Author: Daniel Martín Date: Sun Jul 10 22:36:28 2022 +0200 Fix memory leak in ns_draw_relief * src/nsterm.h (struct ns_output): New fields to store the relief colors. * src/nsterm.m (ns_setup_relief_colors): New function to keep the relief colors as part of the ns_output structure. (ns_draw_relief): Remove static local variables. Assigning them to nil caused a memory leak of NSColor instances (bug#56462). Call ns_setup_relief_colors instead. diff --git a/src/nsterm.h b/src/nsterm.h index 7a097b3248..2a4c7571a3 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -927,6 +927,9 @@ struct ns_output NSColor *cursor_color; NSColor *foreground_color; NSColor *background_color; + NSColor *relief_background_color; + NSColor *light_relief_color; + NSColor *dark_relief_color; EmacsToolbar *toolbar; #else void *view; @@ -934,6 +937,9 @@ struct ns_output void *cursor_color; void *foreground_color; void *background_color; + void *relief_background_color; + void *light_relief_color; + void *dark_relief_color; void *toolbar; #endif diff --git a/src/nsterm.m b/src/nsterm.m index 7f232e7292..8e0c4b84f0 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3475,6 +3475,35 @@ larger if there are taller display elements (e.g., characters } } +/* Set up colors for the relief lines around glyph string S. */ + +static void +ns_setup_relief_colors (struct glyph_string *s) +{ + struct ns_output *di = FRAME_OUTPUT_DATA (s->f); + NSColor *color; + + if (s->face->use_box_color_for_shadows_p) + color = [NSColor colorWithUnsignedLong: s->face->box_color]; + else + color = [NSColor colorWithUnsignedLong: s->face->background]; + + if (s->hl == DRAW_CURSOR) + color = FRAME_CURSOR_COLOR (s->f); + + if (color == nil) + color = [NSColor grayColor]; + + if (color != di->relief_background_color) + { + [di->relief_background_color release]; + di->relief_background_color = [color retain]; + [di->light_relief_color release]; + di->light_relief_color = [[color highlightWithLevel: 0.4] retain]; + [di->dark_relief_color release]; + di->dark_relief_color = [[color shadowWithLevel: 0.4] retain]; + } +} static void ns_draw_relief (NSRect outer, int hthickness, int vthickness, char raised_p, @@ -3486,40 +3515,13 @@ larger if there are taller display elements (e.g., characters of some sides not being drawn, and because the rect will be filled. -------------------------------------------------------------------------- */ { - static NSColor *baseCol, *lightCol, *darkCol; - NSColor *newBaseCol; NSRect inner; - NSBezierPath *p; - - baseCol = nil; - lightCol = nil; - newBaseCol = nil; - p = nil; + NSBezierPath *p = nil; NSTRACE ("ns_draw_relief"); /* set up colors */ - - if (s->face->use_box_color_for_shadows_p) - newBaseCol = [NSColor colorWithUnsignedLong: s->face->box_color]; - else - newBaseCol = [NSColor colorWithUnsignedLong: s->face->background]; - - if (s->hl == DRAW_CURSOR) - newBaseCol = FRAME_CURSOR_COLOR (s->f); - - if (newBaseCol == nil) - newBaseCol = [NSColor grayColor]; - - if (newBaseCol != baseCol) /* TODO: better check */ - { - [baseCol release]; - baseCol = [newBaseCol retain]; - [lightCol release]; - lightCol = [[baseCol highlightWithLevel: 0.4] retain]; - [darkCol release]; - darkCol = [[baseCol shadowWithLevel: 0.4] retain]; - } + ns_setup_relief_colors (s); /* Calculate the inner rectangle. */ inner = outer; @@ -3542,7 +3544,9 @@ larger if there are taller display elements (e.g., characters if (bottom_p) inner.size.height -= hthickness; - [(raised_p ? lightCol : darkCol) set]; + struct ns_output *di = FRAME_OUTPUT_DATA (s->f); + + [(raised_p ? di->light_relief_color : di->dark_relief_color) set]; if (top_p || left_p) { @@ -3564,7 +3568,7 @@ larger if there are taller display elements (e.g., characters [p fill]; } - [(raised_p ? darkCol : lightCol) set]; + [(raised_p ? di->dark_relief_color : di->light_relief_color) set]; if (bottom_p || right_p) { @@ -3626,7 +3630,7 @@ larger if there are taller display elements (e.g., characters NSMaxY (outer) - 0.5)]; } - [darkCol set]; + [di->dark_relief_color set]; [p stroke]; if (vthickness > 1 && hthickness > 1) commit bebf39f292f1963ab980497248a18d8035708d1a Author: Lars Ingebrigtsen Date: Mon Jul 11 12:18:04 2022 +0200 Autoload named-let * lisp/emacs-lisp/subr-x.el (named-let): Autoload `named-let' for easier use (bug#56473). diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 5159e8784a..5037ae47e8 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -290,6 +290,7 @@ it makes no sense to convert it to a string using (set-buffer source-buffer) (replace-buffer-contents tmp-buffer max-secs max-costs))))))))) +;;;###autoload (defmacro named-let (name bindings &rest body) "Looping construct taken from Scheme. Like `let', bind variables in BINDINGS and then evaluate BODY, commit 8ab9102950e9476c0d0d1cbecfd7c1dd22141a5f Author: Lars Ingebrigtsen Date: Mon Jul 11 12:15:04 2022 +0200 Fix `M-x lisp-fill-paragraph' * lisp/emacs-lisp/lisp-mode.el (lisp-fill-paragraph): Fix filling when called directly with `M-x lisp-fill-paragraph' instead of via `M-q' (bug#56476). diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 68528e199f..c906ee6e31 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -1466,7 +1466,10 @@ and initial semicolons." emacs-lisp-docstring-fill-column fill-column))) (let ((ppss (syntax-ppss)) - (start (point))) + (start (point)) + ;; Avoid recursion if we're being called directly with + ;; `M-x lisp-fill-paragraph' in an `emacs-lisp-mode' buffer. + (fill-paragraph-function t)) (save-excursion (save-restriction ;; If we're not inside a string, then do very basic commit 693929bf48be866763edd5bc2b6e2745bec134cf Author: Stefan Kangas Date: Sun Dec 26 21:59:16 2021 +0100 Make crm-default-separator obsolete as per FIXME * lisp/emacs-lisp/crm.el (crm-default-separator): Make into obsolete variable alias for crm-separator. (crm-separator): Update docstring for above change. diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el index 9d9c91e510..9c49e09578 100644 --- a/lisp/emacs-lisp/crm.el +++ b/lisp/emacs-lisp/crm.el @@ -77,15 +77,9 @@ ;;; Code: -;; FIXME I don't see that this needs to exist as a separate variable. -;; crm-separator should suffice. -(defconst crm-default-separator "[ \t]*,[ \t]*" - "Default value of `crm-separator'.") - -(defvar crm-separator crm-default-separator +(defvar crm-separator "[ \t]*,[ \t]*" "Separator regexp used for separating strings in `completing-read-multiple'. -It should be a regexp that does not match the list of completion candidates. -The default value is `crm-default-separator'.") +It should be a regexp that does not match the list of completion candidates.") (defvar-keymap crm-local-completion-map :doc "Local keymap for minibuffer multiple input with completion. @@ -300,6 +294,8 @@ with empty strings removed." ;(completing-read my-prompt my-table nil t) ;(completing-read my-prompt my-table nil "match") +(define-obsolete-variable-alias 'crm-default-separator 'crm-separator "29.1") + (provide 'crm) ;;; crm.el ends here commit d8225e9fa1e68ff4e38f149838ae0a72853b2f2b Author: Manuel Giraud Date: Mon Jul 11 12:09:13 2022 +0200 ; * lwlib/xlwmenu.c (make_shadow_gcs): Remove "a = a" pattern. * lwlib/xlwmenu.c (make_shadow_gcs): Remove code that sets a value to itself (bug#56479). diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index eba85631bd..68f49e646d 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -1753,13 +1753,9 @@ make_shadow_gcs (XlwMenuWidget mw) if (mw->menu.top_shadow_color == -1) mw->menu.top_shadow_color = mw->core.background_pixel; - else - mw->menu.top_shadow_color = mw->menu.top_shadow_color; if (mw->menu.bottom_shadow_color == -1) mw->menu.bottom_shadow_color = mw->menu.foreground; - else - mw->menu.bottom_shadow_color = mw->menu.bottom_shadow_color; if (mw->menu.top_shadow_color == mw->core.background_pixel || mw->menu.top_shadow_color == mw->menu.foreground) commit 876317271b5a92c1d243d4654d4e594d6be70814 Author: Stefan Kangas Date: Mon Jul 11 11:51:16 2022 +0200 * lisp/find-dired.el (find-dired): Doc fix; add crossreference. diff --git a/lisp/find-dired.el b/lisp/find-dired.el index c67138a800..e4cd6078ec 100644 --- a/lisp/find-dired.el +++ b/lisp/find-dired.el @@ -167,7 +167,12 @@ except that the car of the variable `find-ls-option' specifies what to use in place of \"-ls\" as the final argument. Collect output in the \"*Find*\" buffer. To kill the job before -it finishes, type \\[kill-find]." +it finishes, type \\[kill-find]. + +For more information on how to write valid find expressions for +ARGS, see Info node `(find) Finding Files'. If you are not +using GNU findutils (on macOS and *BSD systems), see instead the +man page for \"find\"." (interactive (list (read-directory-name "Run find in directory: " nil "" t) (read-string "Run find (with args): " find-args '(find-args-history . 1)))) commit 99adfafdfc040dac11e2af1a59c445af1fa60445 Author: Stefan Kangas Date: Mon Jul 11 11:17:09 2022 +0200 Re-add comment on autoloading cookies in preloaded files This comment was removed in 2009, but it is useful to explain why we are keeping these autoload cookies. * lisp/bindings.el: * lisp/font-core.el: * lisp/format.el: * lisp/international/mule-cmds.el: Re-add comment on autoloading. * lisp/font-core.el (font-lock-defaults): Re-add autoload cookie, despite the fact that this file is preloaded. diff --git a/lisp/bindings.el b/lisp/bindings.el index ec9b219fc0..14ab69b8f0 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -230,6 +230,7 @@ mnemonics of the following coding systems: (:propertize ("" (:eval (if (frame-parameter nil 'client) "@" ""))) help-echo ,(purecopy "emacsclient frame"))) "Mode line construct for identifying emacsclient frames.") +;; Autoload if this file no longer dumped. ;;;###autoload (put 'mode-line-client 'risky-local-variable t) diff --git a/lisp/font-core.el b/lisp/font-core.el index db07aa011c..f92d1e3830 100644 --- a/lisp/font-core.el +++ b/lisp/font-core.el @@ -66,6 +66,8 @@ Other variables include that for syntactic keyword fontification, functions, `font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function', `font-lock-fontify-region-function', `font-lock-unfontify-region-function', and `font-lock-inhibit-thing-lock'.") +;; Autoload if this file no longer dumped. +;;;###autoload (put 'font-lock-defaults 'risky-local-variable t) (defvar font-lock-function 'font-lock-default-function diff --git a/lisp/format.el b/lisp/format.el index 6c7524891e..2c368b8f9c 100644 --- a/lisp/format.el +++ b/lisp/format.el @@ -139,6 +139,7 @@ MODE-FN, if specified, is called when visiting a file with that format. PRESERVE, if non-nil, means that `format-write-file' should not remove this format from `buffer-file-format'.") +;; Autoload if this file no longer dumped. ;;;###autoload (put 'format-alist 'risky-local-variable t) diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 48c8d2b081..df1c06ec27 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -1411,6 +1411,7 @@ This function is called with no argument.") Each element has the form: (INPUT-METHOD LANGUAGE-ENV ACTIVATE-FUNC TITLE DESCRIPTION ARGS...) See the function `register-input-method' for the meanings of the elements.") +;; Autoload if this file no longer dumped. ;;;###autoload (put 'input-method-alist 'risky-local-variable t) commit da3f3dd0910fae20df47e723088d737aaf0a88c7 Author: Stefan Kangas Date: Mon Jul 11 10:33:45 2022 +0200 Prefer :risky defcustom keyword * lisp/align.el (align-region-separate, align-rules-list) (align-exclude-rules-list, align-vhdl-rules-list): * lisp/bindings.el (mode-line-percent-position): * lisp/filesets.el (filesets-menu-cache-file, filesets-commands) (filesets-external-viewers, filesets-ingroup-patterns) (filesets-data): * lisp/hi-lock.el (hi-lock-file-patterns-policy): * lisp/mail/mailalias.el (mail-complete-alist) (mail-directory-process, mail-directory-stream) (mail-directory-parser): * lisp/mail/rmail.el (rmail-confirm-expunge): * lisp/mail/sendmail.el (mail-signature): * lisp/mail/supercite.el (sc-cite-frame-alist) (sc-uncite-frame-alist, sc-recite-frame-alist) (sc-default-cite-frame, sc-default-uncite-frame) (sc-default-recite-frame, sc-attrib-selection-list) (sc-rewrite-header-list): * lisp/progmodes/make-mode.el (makefile-special-targets-list): * lisp/so-long.el (so-long-action-alist): * lisp/textmodes/sgml-mode.el (sgml-tag-alist): Prefer defcustom :risky keyword argument to directly setting the 'risky-local-variable' symbol property. diff --git a/lisp/align.el b/lisp/align.el index 1ee6bb0cac..be70f8f9d4 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -86,10 +86,9 @@ ;; '((my-rule ;; (regexp . "Sample"))) ;; :type align-rules-list-type +;; :risky t ;; :group 'my-package) ;; -;; (put 'my-align-rules-list 'risky-local-variable t) -;; ;; (add-to-list 'align-dq-string-modes 'my-package-mode) ;; (add-to-list 'align-open-comment-modes 'my-package-mode) ;; @@ -319,10 +318,9 @@ The possible settings for `align-region-separate' are: ; (const largest) (regexp :tag "Regexp defines section boundaries") (function :tag "Function defines section boundaries")) + :risky t :group 'align) -(put 'align-region-separate 'risky-local-variable t) - (defvar align-rules-list-type '(repeat (cons @@ -699,10 +697,9 @@ The following attributes are meaningful: (see the documentation of that variable for possible values), and any separation argument passed to `align'." :type align-rules-list-type + :risky t :group 'align) -(put 'align-rules-list 'risky-local-variable t) - (defvar align-exclude-rules-list-type '(repeat (cons @@ -770,10 +767,9 @@ The following attributes are meaningful: "A list describing text that should be excluded from alignment. See the documentation for `align-rules-list' for more info." :type align-exclude-rules-list-type + :risky t :group 'align) -(put 'align-exclude-rules-list 'risky-local-variable t) - ;;; Internal Variables: (defvar-local align-mode-rules-list nil @@ -823,8 +819,8 @@ See the variable `align-exclude-rules-list' for more details.") (regexp . "\\(\\s-+\\)use\\s-+entity"))) "Alignment rules for `vhdl-mode'. See `align-rules-list' for more info." :type align-rules-list-type + :risky t :group 'align) -(put 'align-vhdl-rules-list 'risky-local-variable t) (make-obsolete-variable 'align-vhdl-rules-list "no longer used." "27.1") (defun align-set-vhdl-rules () diff --git a/lisp/bindings.el b/lisp/bindings.el index 0cf1834a4f..ec9b219fc0 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1,7 +1,6 @@ ;;; bindings.el --- define standard key bindings and some variables -*- lexical-binding: t; -*- -;; Copyright (C) 1985-1987, 1992-1996, 1999-2022 Free Software -;; Foundation, Inc. +;; Copyright (C) 1985-2022 Free Software Foundation, Inc. ;; Maintainer: emacs-devel@gnu.org ;; Keywords: internal @@ -458,8 +457,8 @@ displayed in `mode-line-position', a component of the default (const :tag "\"%q\": Offsets of both top and bottom of window" (6 "%q"))) :version "26.1" + :risky t :group 'mode-line) -(put 'mode-line-percent-position 'risky-local-variable t) (defcustom mode-line-position-line-format '(" L%l") "Format used to display line numbers in the mode line. diff --git a/lisp/filesets.el b/lisp/filesets.el index b1829793f1..a8d837e7e1 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -326,8 +326,8 @@ See `easy-menu-add-item' for documentation." Set this to \"\", to disable caching of menus. Don't forget to check out `filesets-menu-ensure-use-cached'." :set #'filesets-set-default - :type 'file) -(put 'filesets-menu-cache-file 'risky-local-variable t) + :type 'file + :risky t) (defcustom filesets-menu-cache-contents '(filesets-be-docile-flag @@ -546,6 +546,7 @@ function that returns one) to be run on a filesets' files. The argument or <> (quoted) will be replaced with the filename." :set #'filesets-set-default+ + :risky t :type '(repeat :tag "Commands" (list :tag "Definition" :value ("") (string "Name") @@ -561,8 +562,7 @@ the filename." (string :tag "Quoted File Name" :value "<>") (function :tag "Function" - :value nil)))))) -(put 'filesets-commands 'risky-local-variable t) + :value nil)))))) (defcustom filesets-external-viewers (let @@ -651,6 +651,7 @@ In order to view pdf or rtf files in an Emacs buffer, you could use these: (and (filesets-which-command-p \"rtf2htm\") (filesets-which-command-p \"w3m\"))))))" :set #'filesets-set-default + :risky t :type '(repeat :tag "Viewer" (list :tag "Definition" :value ("^.+\\.suffix$" "") @@ -707,7 +708,6 @@ In order to view pdf or rtf files in an Emacs buffer, you could use these: (const :format "" :value :capture-output) (boolean :tag "Boolean"))))))) -(put 'filesets-external-viewers 'risky-local-variable t) (defcustom filesets-ingroup-patterns '(("^.+\\.tex$" t @@ -848,6 +848,7 @@ With duplicates removed, it would be: M + A - X B" :set #'filesets-set-default + :risky t :type '(repeat :tag "Include" (list @@ -894,7 +895,6 @@ With duplicates removed, it would be: :value (:preprocess) (const :format "" :value :preprocess) (function :tag "Function")))))))) -(put 'filesets-ingroup-patterns 'risky-local-variable t) (defcustom filesets-data nil "Fileset definitions. @@ -965,6 +965,7 @@ is used. Before using :ingroup, make sure that the file type is already defined in `filesets-ingroup-patterns'." :set #'filesets-data-set-default + :risky t :type '(repeat (cons :tag "Fileset" (string :tag "Name" :value "") @@ -1021,7 +1022,6 @@ defined in `filesets-ingroup-patterns'." :value (:open) (const :format "" :value :open) (function :tag "Function"))))))) -(put 'filesets-data 'risky-local-variable t) (defcustom filesets-query-user-limit 15 diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el index b56f26d529..a45e74eca2 100644 --- a/lisp/hi-lock.el +++ b/lisp/hi-lock.el @@ -128,11 +128,10 @@ patterns." (const :tag "Ask about file patterns" ask) (function :tag "Function to check file patterns")) :group 'hi-lock + ;; It can have a function value. + :risky t :version "22.1") -;; It can have a function value. -(put 'hi-lock-file-patterns-policy 'risky-local-variable t) - (defcustom hi-lock-auto-select-face nil "When nil, highlighting commands prompt for the face to use. When non-nil, highlighting command determine the faces to use diff --git a/lisp/mail/mailalias.el b/lisp/mail/mailalias.el index c97786190c..57fb1117b6 100644 --- a/lisp/mail/mailalias.el +++ b/lisp/mail/mailalias.el @@ -74,8 +74,8 @@ When t this still needs to be initialized.") The expression may reference the variable `pattern' which will hold the string being completed." :type 'alist + :risky t :group 'mailalias) -(put 'mail-complete-alist 'risky-local-variable t) ;;;###autoload (defcustom mail-complete-style 'angles @@ -121,8 +121,8 @@ or like this: (remote-shell-program \"HOST\" \"-n\" \"COMMAND \\='^\" pattern \"\\='\")" :type 'sexp + :risky t :group 'mailalias) -(put 'mail-directory-process 'risky-local-variable t) (defcustom mail-directory-stream nil "List of (HOST SERVICE) for stream connection to mail directory." @@ -132,8 +132,8 @@ or like this: (string :tag "Service name")) (plist :inline t :tag "Additional open-network-stream parameters"))) + :risky t :group 'mailalias) -(put 'mail-directory-stream 'risky-local-variable t) (defcustom mail-directory-parser nil "How to interpret the output of `mail-directory-function'. @@ -143,8 +143,8 @@ Three types of values are possible: - regexp means first \\(grouping\\) in successive matches is name - function called at beginning of buffer that returns an alist of names" :type '(choice (const nil) regexp function) + :risky t :group 'mailalias) -(put 'mail-directory-parser 'risky-local-variable t) ;; Internal variables. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index a970ab2a76..71eda7cd2b 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -448,8 +448,8 @@ as argument, to ask the user that question." (const :tag "Confirm with y-or-n-p" y-or-n-p) (const :tag "Confirm with yes-or-no-p" yes-or-no-p)) :version "21.1" + :risky t :group 'rmail-files) -(put 'rmail-confirm-expunge 'risky-local-variable t) ;;;###autoload (defvar rmail-mode-hook nil diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index 6afadca6bb..8cb079f7fb 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el @@ -372,8 +372,8 @@ and should insert whatever you want to insert." :type '(choice (const :tag "None" nil) (const :tag "Use `.signature' file" t) (string :tag "String to insert") - (sexp :tag "Expression to evaluate"))) -(put 'mail-signature 'risky-local-variable t) + (sexp :tag "Expression to evaluate")) + :risky t) ;;;###autoload (defcustom mail-signature-file (purecopy "~/.signature") diff --git a/lisp/mail/supercite.el b/lisp/mail/supercite.el index 5dc5ee38ff..f320246f2d 100644 --- a/lisp/mail/supercite.el +++ b/lisp/mail/supercite.el @@ -146,8 +146,8 @@ a variable whose value is a citation frame." :type '(repeat (list symbol (repeat (cons regexp (choice (repeat (repeat sexp)) symbol))))) + :risky t :group 'supercite-frames) -(put 'sc-cite-frame-alist 'risky-local-variable t) (defcustom sc-uncite-frame-alist '() "Alist for frame selection during unciting. @@ -155,8 +155,8 @@ See the variable `sc-cite-frame-alist' for details." :type '(repeat (list symbol (repeat (cons regexp (choice (repeat (repeat sexp)) symbol))))) + :risky t :group 'supercite-frames) -(put 'sc-uncite-frame-alist 'risky-local-variable t) (defcustom sc-recite-frame-alist '() "Alist for frame selection during reciting. @@ -164,8 +164,8 @@ See the variable `sc-cite-frame-alist' for details." :type '(repeat (list symbol (repeat (cons regexp (choice (repeat (repeat sexp)) symbol))))) + :risky t :group 'supercite-frames) -(put 'sc-recite-frame-alist 'risky-local-variable t) (defcustom sc-default-cite-frame '(;; initialize fill state and temporary variables when entering @@ -211,8 +211,8 @@ See the variable `sc-cite-frame-alist' for details." (end (sc-fill-if-different ""))) "Default REGI frame for citing a region." :type '(repeat (repeat sexp)) + :risky t :group 'supercite-frames) -(put 'sc-default-cite-frame 'risky-local-variable t) (defcustom sc-default-uncite-frame '(;; do nothing on a blank line @@ -221,8 +221,8 @@ See the variable `sc-cite-frame-alist' for details." ((sc-cite-regexp) (sc-uncite-line))) "Default REGI frame for unciting a region." :type '(repeat (repeat sexp)) + :risky t :group 'supercite-frames) -(put 'sc-default-uncite-frame 'risky-local-variable t) (defcustom sc-default-recite-frame '(;; initialize fill state when entering frame @@ -237,8 +237,8 @@ See the variable `sc-cite-frame-alist' for details." (end (sc-fill-if-different ""))) "Default REGI frame for reciting a region." :type '(repeat (repeat sexp)) + :risky t :group 'supercite-frames) -(put 'sc-default-recite-frame 'risky-local-variable t) (defcustom sc-cite-region-limit t "This variable controls automatic citation of yanked text. @@ -428,8 +428,8 @@ to be consulted during attribution selection." (repeat (cons regexp (choice (sexp :tag "List to eval") string))))) + :risky t :group 'supercite-attr) -(put 'sc-attrib-selection-list 'risky-local-variable t) (defcustom sc-attribs-preselect-hook nil "Hook to run before selecting an attribution." @@ -483,8 +483,8 @@ The variable `sc-preferred-header-style' controls which function in this list is chosen for automatic reference header insertions. Electric reference mode will cycle through this list of functions." :type '(repeat sexp) + :risky t :group 'supercite) -(put 'sc-rewrite-header-list 'risky-local-variable t) (defcustom sc-titlecue-regexp "\\s +-+\\s +" "Regular expression describing the separator between names and titles. diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index bd01786e08..cbbcf1c2b7 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el @@ -220,8 +220,8 @@ to MODIFY A FILE WITHOUT YOUR CONFIRMATION when \"it seems necessary\"." "List of special targets. You will be offered to complete on one of those in the minibuffer whenever you enter a \".\" at the beginning of a line in `makefile-mode'." - :type '(repeat string)) -(put 'makefile-special-targets-list 'risky-local-variable t) + :type '(repeat string) + :risky t) (defcustom makefile-runtime-macros-list '(("@") ("&") (">") ("<") ("*") ("^") ("+") ("?") ("%") ("$")) diff --git a/lisp/so-long.el b/lisp/so-long.el index 4950f0adb5..82ce2e1755 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -684,8 +684,8 @@ subsequently called." (function :tag "Action") (function :tag "Revert"))) :set #'so-long--action-alist-setter + :risky t :package-version '(so-long . "1.0")) -(put 'so-long-action-alist 'risky-local-variable t) (defcustom so-long-action 'so-long-mode "The action taken by `so-long' when long lines are detected. diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 13ff3dcab6..8f9b603ef5 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -480,8 +480,8 @@ The attribute alist is made up as ATTRIBUTERULE is a list of optionally t (no value when no input) followed by an optional alist of possible values." :type '(repeat (cons (string :tag "Tag Name") - (repeat :tag "Tag Rule" sexp)))) -(put 'sgml-tag-alist 'risky-local-variable t) + (repeat :tag "Tag Rule" sexp))) + :risky t) (defcustom sgml-tag-help '(("!" . "Empty declaration for comment") commit 69b68099ecfb053ac77e0a954ab7467c440321ff Author: Mattias Engdegård Date: Mon Jul 11 10:34:40 2022 +0200 Simplify and speed up string-to-multibyte * src/character.h (str_to_multibyte): * src/character.c (str_to_multibyte): Change signature and simplify; the conversion is no longer done in-place. * src/fns.c (string_to_multibyte): Drop temporary buffer and memcpy; adapt to new str_to_multibyte signature. * src/print.c (print_string): Drop memcpy; adapt call to str_to_multibyte. * test/src/fns-tests.el (fns--string-to-unibyte): Rename to... (fns--string-to-unibyte-multibyte): ... this and strengthen, so that the test covers string-to-multibyte reasonably well. diff --git a/src/character.c b/src/character.c index d12df23f8e..841e46c091 100644 --- a/src/character.c +++ b/src/character.c @@ -666,35 +666,26 @@ count_size_as_multibyte (const unsigned char *str, ptrdiff_t len) } -/* Convert unibyte text at STR of BYTES bytes to a multibyte text - that contains the same single-byte characters. It actually - converts all 8-bit characters to multibyte forms. It is assured - that we can use LEN bytes at STR as a work area and that is - enough. */ - -ptrdiff_t -str_to_multibyte (unsigned char *str, ptrdiff_t len, ptrdiff_t bytes) +/* Convert unibyte text at SRC of NCHARS bytes to a multibyte text + at DST of NBYTES bytes, that contains the same single-byte characters. */ +void +str_to_multibyte (unsigned char *dst, const unsigned char *src, + ptrdiff_t nchars, ptrdiff_t nbytes) { - unsigned char *p = str, *endp = str + bytes; - unsigned char *to; - - while (p < endp && *p < 0x80) p++; - if (p == endp) - return bytes; - to = p; - bytes = endp - p; - endp = str + len; - memmove (endp - bytes, p, bytes); - p = endp - bytes; - while (p < endp) + const unsigned char *s = src + nchars; + unsigned char *d = dst + nbytes; + for (ptrdiff_t i = 0; i < nchars; i++) { - int c = *p++; - - if (c >= 0x80) - c = BYTE8_TO_CHAR (c); - to += CHAR_STRING (c, to); + unsigned char c = *--s; + if (c <= 0x7f) + *--d = c; + else + { + *--d = 0x80 + (c & 0x3f); + *--d = 0xc0 + ((c >> 6) & 1); + } } - return (to - str); + eassert (d == dst && s == src); } /* Arrange multibyte text at STR of LEN bytes as a unibyte text. It diff --git a/src/character.h b/src/character.h index 2ca935ba04..36e2b06ee1 100644 --- a/src/character.h +++ b/src/character.h @@ -567,7 +567,8 @@ extern int translate_char (Lisp_Object, int c); extern ptrdiff_t count_size_as_multibyte (const unsigned char *, ptrdiff_t); extern ptrdiff_t str_as_multibyte (unsigned char *, ptrdiff_t, ptrdiff_t, ptrdiff_t *); -extern ptrdiff_t str_to_multibyte (unsigned char *, ptrdiff_t, ptrdiff_t); +extern void str_to_multibyte (unsigned char *dst, const unsigned char *src, + ptrdiff_t nchars, ptrdiff_t nbytes); extern ptrdiff_t str_as_unibyte (unsigned char *, ptrdiff_t); extern ptrdiff_t strwidth (const char *, ptrdiff_t); extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int, diff --git a/src/fns.c b/src/fns.c index 61ed01eee4..7d8f957ef9 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1237,33 +1237,24 @@ string_make_multibyte (Lisp_Object string) /* Convert STRING (if unibyte) to a multibyte string without changing - the number of characters. Characters 0200 through 0237 are - converted to eight-bit characters. */ + the number of characters. Characters 0x80..0xff are interpreted as + raw bytes. */ Lisp_Object string_to_multibyte (Lisp_Object string) { - unsigned char *buf; - ptrdiff_t nbytes; - Lisp_Object ret; - USE_SAFE_ALLOCA; - if (STRING_MULTIBYTE (string)) return string; - nbytes = count_size_as_multibyte (SDATA (string), SBYTES (string)); + ptrdiff_t nchars = SCHARS (string); + ptrdiff_t nbytes = count_size_as_multibyte (SDATA (string), nchars); /* If all the chars are ASCII, they won't need any more bytes once converted. */ - if (nbytes == SBYTES (string)) + if (nbytes == nchars) return make_multibyte_string (SSDATA (string), nbytes, nbytes); - buf = SAFE_ALLOCA (nbytes); - memcpy (buf, SDATA (string), SBYTES (string)); - str_to_multibyte (buf, nbytes, SBYTES (string)); - - ret = make_multibyte_string ((char *) buf, SCHARS (string), nbytes); - SAFE_FREE (); - + Lisp_Object ret = make_uninit_multibyte_string (nchars, nbytes); + str_to_multibyte (SDATA (ret), SDATA (string), nchars, nbytes); return ret; } diff --git a/src/print.c b/src/print.c index 4d7e42df1e..9a31e386f5 100644 --- a/src/print.c +++ b/src/print.c @@ -467,8 +467,7 @@ print_string (Lisp_Object string, Lisp_Object printcharfun) if (chars < bytes) { newstr = make_uninit_multibyte_string (chars, bytes); - memcpy (SDATA (newstr), SDATA (string), chars); - str_to_multibyte (SDATA (newstr), bytes, chars); + str_to_multibyte (SDATA (newstr), SDATA (string), chars, bytes); string = newstr; } } diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index 0119e31df1..20074ca0d2 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -1344,18 +1344,24 @@ (should (equal (plist-member plist (copy-sequence "a") #'equal) '("a" "c"))))) -(ert-deftest fns--string-to-unibyte () - (dolist (str '("" "a" "abc" "a\x00\x7fz" "a\xaa\xbbz ""\x80\xdd\xff")) +(ert-deftest fns--string-to-unibyte-multibyte () + (dolist (str (list "" "a" "abc" "a\x00\x7fz" "a\xaa\xbbz" "\x80\xdd\xff" + (apply #'unibyte-string (number-sequence 0 255)))) (ert-info ((prin1-to-string str) :prefix "str: ") (should-not (multibyte-string-p str)) (let* ((u (string-to-unibyte str)) ; should be identity (m (string-to-multibyte u)) ; lossless conversion - (uu (string-to-unibyte m))) ; also lossless + (mm (string-to-multibyte m)) ; should be identity + (uu (string-to-unibyte m)) ; also lossless + (ml (mapcar (lambda (c) (if (<= c #x7f) c (+ c #x3fff00))) u))) (should-not (multibyte-string-p u)) (should (multibyte-string-p m)) + (should (multibyte-string-p mm)) (should-not (multibyte-string-p uu)) (should (equal str u)) - (should (equal str uu))))) + (should (equal m mm)) + (should (equal str uu)) + (should (equal (append m nil) ml))))) (should-error (string-to-unibyte "å")) (should-error (string-to-unibyte "ABC∀BC"))) commit 96846877930f580e122e9af85b4653918c542f89 Author: Manuel Giraud Date: Sun Jul 10 15:01:55 2022 +0200 Rename 'longlines-breakpoint-chars' to 'longlines-break-chars' * etc/NEWS: * lisp/longlines.el (longlines-break-chars): Rename 'longlines-breakpoint-chars' to 'longlines-break-chars' (bug#56335). diff --git a/etc/NEWS b/etc/NEWS index 660ea7d720..526bda283c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -463,8 +463,8 @@ previous behavior). The default is nil, which inhibits recording of passwords. +++ -** New user option 'longlines-breakpoint-chars'. -This is a string containing chars that could be used as breakpoint in +** New user option 'longlines-break-chars'. +This is a string containing chars that could be used as break point in longlines mode. +++ diff --git a/lisp/longlines.el b/lisp/longlines.el index 6dc2f61ed9..4ad2cab2b2 100644 --- a/lisp/longlines.el +++ b/lisp/longlines.el @@ -72,8 +72,9 @@ You can also enable the display temporarily, using the command This is used when `longlines-show-hard-newlines' is on." :type 'string) -(defcustom longlines-breakpoint-chars " ;,|" +(defcustom longlines-break-chars " ;,|" "A bag of separator chars for longlines." + :version "29.1" :type 'string) ;;; Internal variables @@ -303,8 +304,8 @@ not need to be wrapped, move point to the next line and return t." If the line should not be broken, return nil; point remains on the line." (move-to-column target-column) - (let ((non-breakpoint-re (format "[^%s]" longlines-breakpoint-chars))) - (if (and (re-search-forward non-breakpoint-re (line-end-position) t 1) + (let ((non-break-re (format "[^%s]" longlines-break-chars))) + (if (and (re-search-forward non-break-re (line-end-position) t 1) (> (current-column) target-column)) ;; This line is too long. Can we break it? (or (longlines-find-break-backward) @@ -314,17 +315,17 @@ line." (defun longlines-find-break-backward () "Move point backward to the first available breakpoint and return t. If no breakpoint is found, return nil." - (let ((breakpoint-re (format "[%s]" longlines-breakpoint-chars))) - (when (and (re-search-backward breakpoint-re (line-beginning-position) t 1) + (let ((break-re (format "[%s]" longlines-break-chars))) + (when (and (re-search-backward break-re (line-beginning-position) t 1) (save-excursion - (skip-chars-backward longlines-breakpoint-chars + (skip-chars-backward longlines-break-chars (line-beginning-position)) (null (bolp)))) (forward-char 1) (if (and fill-nobreak-predicate (run-hook-with-args-until-success 'fill-nobreak-predicate)) (progn - (skip-chars-backward longlines-breakpoint-chars + (skip-chars-backward longlines-break-chars (line-beginning-position)) (longlines-find-break-backward)) t)))) @@ -332,10 +333,10 @@ If no breakpoint is found, return nil." (defun longlines-find-break-forward () "Move point forward to the first available breakpoint and return t. If no break point is found, return nil." - (let ((breakpoint-re (format "[%s]" longlines-breakpoint-chars))) - (and (re-search-forward breakpoint-re (line-end-position) t 1) + (let ((break-re (format "[%s]" longlines-break-chars))) + (and (re-search-forward break-re (line-end-position) t 1) (progn - (skip-chars-forward longlines-breakpoint-chars (line-end-position)) + (skip-chars-forward longlines-break-chars (line-end-position)) (null (eolp))) (if (and fill-nobreak-predicate (run-hook-with-args-until-success 'fill-nobreak-predicate))