From ca44ea18ef2738b4f2e8c72058a12dc82ba13c65 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 30 Jan 2021 16:15:00 +0200 Subject: Improve documentation of auto-resize-tool/tab-bars * src/xdisp.c (syms_of_xdisp) : Doc fix. (Bug#46178) --- src/xdisp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xdisp.c b/src/xdisp.c index cac3195170c..77c9af747c3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -34742,7 +34742,8 @@ of your window manager. */); This dynamically changes the tab-bar's height to the minimum height that is needed to make all tab-bar items visible. If value is `grow-only', the tab-bar's height is only increased -automatically; to decrease the tab-bar height, use \\[recenter]. */); +automatically; to decrease the tab-bar height, use \\[recenter], +after setting `recenter-redisplay' to the value of t. */); Vauto_resize_tab_bars = Qt; DEFVAR_BOOL ("auto-raise-tab-bar-buttons", auto_raise_tab_bar_buttons_p, @@ -34754,7 +34755,8 @@ automatically; to decrease the tab-bar height, use \\[recenter]. */); This dynamically changes the tool-bar's height to the minimum height that is needed to make all tool-bar items visible. If value is `grow-only', the tool-bar's height is only increased -automatically; to decrease the tool-bar height, use \\[recenter]. */); +automatically; to decrease the tool-bar height, use \\[recenter], +after setting `recenter-redisplay' to the value of t. */); Vauto_resize_tool_bars = Qt; DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p, -- cgit v1.3 From 3555657585bb2c1809fa6abff7f565a8c7f226eb Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sat, 30 Jan 2021 15:59:13 +0100 Subject: Remove unused argument from set_frame_menubar (Bug#45759) * src/w32menu.c (set_frame_menubar): * src/xmenu.c (set_frame_menubar): Remove unused argument. All callers updated. --- src/frame.h | 2 +- src/w32fns.c | 2 +- src/w32menu.c | 10 ++++------ src/xdisp.c | 2 +- src/xmenu.c | 14 ++++++-------- 5 files changed, 13 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/frame.h b/src/frame.h index 9b0852c7b9c..21148fe94c9 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1707,7 +1707,7 @@ extern Lisp_Object gui_display_get_resource (Display_Info *, Lisp_Object component, Lisp_Object subclass); -extern void set_frame_menubar (struct frame *f, bool first_time, bool deep_p); +extern void set_frame_menubar (struct frame *f, bool deep_p); extern void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); extern void free_frame_menubar (struct frame *); extern bool frame_ancestor_p (struct frame *af, struct frame *df); diff --git a/src/w32fns.c b/src/w32fns.c index e93a0b85d93..5704f1d3c33 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1637,7 +1637,7 @@ w32_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) if (!old) /* Make menu bar when there was none. Emacs 25 waited until the next redisplay for this to take effect. */ - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); else { /* Remove menu bar. */ diff --git a/src/w32menu.c b/src/w32menu.c index 8bf0c462030..3bf76663947 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -155,7 +155,7 @@ w32_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents) void w32_activate_menubar (struct frame *f) { - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); /* Lock out further menubar changes while active. */ f->output_data.w32->menubar_active = 1; @@ -258,12 +258,10 @@ menubar_selection_callback (struct frame *f, void * client_data) } -/* Set the contents of the menubar widgets of frame F. - The argument FIRST_TIME is currently ignored; - it is set the first time this is called, from initialize_frame_menubar. */ +/* Set the contents of the menubar widgets of frame F. */ void -set_frame_menubar (struct frame *f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool deep_p) { HMENU menubar_widget = f->output_data.w32->menubar_widget; Lisp_Object items; @@ -511,7 +509,7 @@ initialize_frame_menubar (struct frame *f) /* This function is called before the first chance to redisplay the frame. It has to be, so the frame will have the right size. */ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); - set_frame_menubar (f, true, true); + set_frame_menubar (f, true); } /* Get rid of the menu bar of frame F, and free its storage. diff --git a/src/xdisp.c b/src/xdisp.c index 11b9e1becfd..32b359098aa 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12876,7 +12876,7 @@ update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run) the selected frame should be allowed to set it. */ if (f == SELECTED_FRAME ()) #endif - set_frame_menubar (f, false, false); + set_frame_menubar (f, false); } else /* On a terminal screen, the menu bar is an ordinary screen diff --git a/src/xmenu.c b/src/xmenu.c index ea3813a64e2..a83fffbf1ce 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -289,7 +289,7 @@ DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_i block_input (); if (FRAME_EXTERNAL_MENU_BAR (f)) - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); menubar = FRAME_X_OUTPUT (f)->menubar_widget; if (menubar) @@ -368,7 +368,7 @@ If FRAME is nil or not given, use the selected frame. */) f = decode_window_system_frame (frame); if (FRAME_EXTERNAL_MENU_BAR (f)) - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); menubar = FRAME_X_OUTPUT (f)->menubar_widget; if (menubar) @@ -433,7 +433,7 @@ x_activate_menubar (struct frame *f) return; #endif - set_frame_menubar (f, false, true); + set_frame_menubar (f, true); block_input (); popup_activated_flag = 1; #ifdef USE_GTK @@ -677,12 +677,10 @@ apply_systemfont_to_menu (struct frame *f, Widget w) #endif -/* Set the contents of the menubar widgets of frame F. - The argument FIRST_TIME is currently ignored; - it is set the first time this is called, from initialize_frame_menubar. */ +/* Set the contents of the menubar widgets of frame F. */ void -set_frame_menubar (struct frame *f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool deep_p) { xt_or_gtk_widget menubar_widget, old_widget; #ifdef USE_X_TOOLKIT @@ -1029,7 +1027,7 @@ initialize_frame_menubar (struct frame *f) /* This function is called before the first chance to redisplay the frame. It has to be, so the frame will have the right size. */ fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f))); - set_frame_menubar (f, true, true); + set_frame_menubar (f, true); } -- cgit v1.3 From 419a33eb1dd37fe529e756e04253ff1c9ad2eeb1 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 30 Jan 2021 21:13:53 +0200 Subject: Fix NS build broken by a recent change * src/nsmenu.m (set_frame_menubar, Fns_reset_menu): Adapt to recent changes in set_frame_menubar. (Bug#45759) --- src/nsmenu.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nsmenu.m b/src/nsmenu.m index f8219d27026..24aa5a0ac11 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -405,7 +405,7 @@ ns_update_menubar (struct frame *f, bool deep_p) frame's menus have changed, and the *step representation should be updated from Lisp. */ void -set_frame_menubar (struct frame *f, bool first_time, bool deep_p) +set_frame_menubar (struct frame *f, bool deep_p) { ns_update_menubar (f, deep_p); } @@ -1795,7 +1795,7 @@ DEFUN ("ns-reset-menu", Fns_reset_menu, Sns_reset_menu, 0, 0, 0, doc: /* Cause the NS menu to be re-calculated. */) (void) { - set_frame_menubar (SELECTED_FRAME (), 1, 0); + set_frame_menubar (SELECTED_FRAME (), 0); return Qnil; } -- cgit v1.3 From 636ef445af03a564ad431648cda34d78d0cb807c Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Sat, 30 Jan 2021 21:16:35 +0000 Subject: With minibuffer-follows-selected-frame `hybrid', preserve recursive Mbuffers ...when enable-recursive-minibuffers is non-nil, and several minibuffers are activated from different frames. Also set the major mode of a reused active minibuffer to `fundamental-mode' - up till now it's been minibuffer-inactive-mode. * src/minibuf.c (read_minibuf): with the indicated settings of variables, "stack up" all containing minibuffers on the mini-window of the current frame. Delete another, now superfluous such stacking up. (set_minibuffer_mode): New function. (get_minibuffer): Call the above new function (twice), in place of inline code, ensuring active minibuffers are never left in minibuffer-inactive-mode. --- src/minibuf.c | 60 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/minibuf.c b/src/minibuf.c index 5df10453739..0221f388dda 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -594,6 +594,18 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, record_unwind_protect (restore_buffer, Fcurrent_buffer ()); choose_minibuf_frame (); + mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); + + if (minibuf_level > 1 + && minibuf_moves_frame_when_opened () + && !minibuf_follows_frame ()) + { + EMACS_INT i; + + /* Stack up the existing minibuffers on the current mini-window */ + for (i = 1; i < minibuf_level; i++) + set_window_buffer (minibuf_window, nth_minibuffer (i), 0, 0); + } record_unwind_protect_void (choose_minibuf_frame); @@ -602,7 +614,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, /* If the minibuffer window is on a different frame, save that frame's configuration too. */ - mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); if (!EQ (mini_frame, selected_frame)) record_unwind_protect (restore_window_configuration, Fcons (/* Arrange for the frame later to be @@ -745,17 +756,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, } } - if (minibuf_moves_frame_when_opened ()) - { - EMACS_INT i; - - /* Stack up all the (recursively) open minibuffers on the selected - mini_window. */ - for (i = 1; i < minibuf_level; i++) - set_window_buffer (XFRAME (mini_frame)->minibuffer_window, - nth_minibuffer (i), 0, 0); - } - /* Display this minibuffer in the proper window. */ /* Use set_window_buffer instead of Fset_window_buffer (see discussion of bug#11984, bug#12025, bug#12026). */ @@ -926,6 +926,31 @@ nth_minibuffer (EMACS_INT depth) return XCAR (tail); } +/* Set the major mode of the minibuffer BUF, depending on DEPTH, the + minibuffer depth. */ + +static void +set_minibuffer_mode (Lisp_Object buf, EMACS_INT depth) +{ + ptrdiff_t count = SPECPDL_INDEX (); + + record_unwind_current_buffer (); + Fset_buffer (buf); + if (depth > 0) + { + if (!NILP (Ffboundp (intern ("fundamental-mode")))) + call0 (intern ("fundamental-mode")); + } + else + { + if (!NILP (Ffboundp (intern ("minibuffer-inactive-mode")))) + call0 (intern ("minibuffer-inactive-mode")); + else + Fkill_all_local_variables (); + } + buf = unbind_to (count, buf); +} + /* Return a buffer to be used as the minibuffer at depth `depth'. depth = 0 is the lowest allowed argument, and that is the value used for nonrecursive minibuffer invocations. */ @@ -946,7 +971,7 @@ get_minibuffer (EMACS_INT depth) char name[sizeof name_fmt + INT_STRLEN_BOUND (EMACS_INT)]; AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, depth)); buf = Fget_buffer_create (lname, Qnil); - + set_minibuffer_mode (buf, depth); /* Although the buffer's name starts with a space, undo should be enabled in it. */ Fbuffer_enable_undo (buf); @@ -955,19 +980,12 @@ get_minibuffer (EMACS_INT depth) } else { - ptrdiff_t count = SPECPDL_INDEX (); /* We have to empty both overlay lists. Otherwise we end up with overlays that think they belong to this buffer while the buffer doesn't know about them any more. */ delete_all_overlays (XBUFFER (buf)); reset_buffer (XBUFFER (buf)); - record_unwind_current_buffer (); - Fset_buffer (buf); - if (!NILP (Ffboundp (intern ("minibuffer-inactive-mode")))) - call0 (intern ("minibuffer-inactive-mode")); - else - Fkill_all_local_variables (); - buf = unbind_to (count, buf); + set_minibuffer_mode (buf, depth); } return buf; -- cgit v1.3 From 9c7543417306752683faacd1436f9748a6f4f616 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 30 Jan 2021 10:53:12 +0000 Subject: Fix build failure on macOS 10.7 (bug#46036) * src/nsfns.m (ns_set_represented_filename): Define the NSNumber in a more compatible manner. --- src/nsfns.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nsfns.m b/src/nsfns.m index 5a9ad18a12f..5f223669397 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -493,7 +493,7 @@ ns_set_represented_filename (struct frame *f) #if defined (NS_IMPL_COCOA) && defined (MAC_OS_X_VERSION_10_7) /* Work around for Mach port leaks on macOS 10.15 (bug#38618). */ NSURL *fileURL = [NSURL fileURLWithPath:fstr isDirectory:NO]; - NSNumber *isUbiquitousItem = @YES; + NSNumber *isUbiquitousItem = [NSNumber numberWithBool:YES]; [fileURL getResourceValue:(id *)&isUbiquitousItem forKey:NSURLIsUbiquitousItemKey error:nil]; -- cgit v1.3 From 5cf9b915fa3557b4cd9e36ef8068d40b68ee485a Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 31 Jan 2021 08:46:02 +0100 Subject: execute-kbd-macro doc string clarification * src/macros.c (Fexecute_kbd_macro): Mention that the buffer is (potentially) changed (bug#37396). --- src/macros.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/macros.c b/src/macros.c index c8ce94e63b1..60d0766a754 100644 --- a/src/macros.c +++ b/src/macros.c @@ -279,7 +279,10 @@ its function definition is used. COUNT is a repeat count, or nil for once, or 0 for infinite loop. Optional third arg LOOPFUNC may be a function that is called prior to -each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */) +each iteration of the macro. Iteration stops if LOOPFUNC returns nil. + +The buffer shown in the currently selected window will be made the current +buffer before the macro is executed. */) (Lisp_Object macro, Lisp_Object count, Lisp_Object loopfunc) { Lisp_Object final; -- cgit v1.3 From 427d4b3c69f9d2fd8473189564dc1e96b27937ff Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Sun, 31 Jan 2021 17:24:23 +0000 Subject: Minimise the time Vminibuffer_list is in an inconsistent state (src/minibuf.c) src/minibuf.c (get_minibuffer): Move the XSETCAR which writes the new minibuffer into Vminibuffer_list to immediately after the MB's creation, so that the list is in a consistent state before calling fundamental-mode or minibuffer-inactive-mode. --- src/minibuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/minibuf.c b/src/minibuf.c index 0221f388dda..949c3d989d5 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -971,12 +971,12 @@ get_minibuffer (EMACS_INT depth) char name[sizeof name_fmt + INT_STRLEN_BOUND (EMACS_INT)]; AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, depth)); buf = Fget_buffer_create (lname, Qnil); + /* Do this before set_minibuffer_mode. */ + XSETCAR (tail, buf); set_minibuffer_mode (buf, depth); /* Although the buffer's name starts with a space, undo should be enabled in it. */ Fbuffer_enable_undo (buf); - - XSETCAR (tail, buf); } else { -- cgit v1.3 From f215332c8be43ef0dc838e2a63012aba791818c2 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Mon, 1 Feb 2021 01:43:29 +0100 Subject: Add cross-references to defvar-local * src/data.c (Fmake_variable_buffer_local): * src/eval.c (Fdefvar): Add cross-references to 'defvar-local'. --- src/data.c | 4 +++- src/eval.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/data.c b/src/data.c index 35a6890b9bd..38cde0ff8b2 100644 --- a/src/data.c +++ b/src/data.c @@ -1819,7 +1819,9 @@ a variable local to the current buffer for one particular use, use while setting up a new major mode, unless they have a `permanent-local' property. -The function `default-value' gets the default value and `set-default' sets it. */) +The function `default-value' gets the default value and `set-default' sets it. + +See also `defvar-local'. */) (register Lisp_Object variable) { struct Lisp_Symbol *sym; diff --git a/src/eval.c b/src/eval.c index 5bf3faebc85..3aff3b56d52 100644 --- a/src/eval.c +++ b/src/eval.c @@ -818,6 +818,8 @@ The optional argument DOCSTRING is a documentation string for the variable. To define a user option, use `defcustom' instead of `defvar'. + +To define a buffer-local variable, use `defvar-local'. usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) (Lisp_Object args) { -- cgit v1.3 From d987ca6f2267f5107a3e543fca4e8eaca983afa6 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Mon, 1 Feb 2021 06:12:15 +0100 Subject: Remove another variable obsolete since Emacs 23.2 * src/keymap.c (syms_of_keymap, Fdefine_key): * lisp/subr.el (define-key-rebound-commands): Remove variable obsolete since Emacs 23.2. --- etc/NEWS | 5 +++-- lisp/subr.el | 1 - src/keymap.c | 9 --------- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/etc/NEWS b/etc/NEWS index 29499639e70..fc3a3dafb8d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2108,8 +2108,9 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. 'completion-base-size', 'completion-common-substring', 'crm-minibuffer-complete', 'crm-minibuffer-complete-and-exit', 'crm-minibuffer-completion-help', 'custom-mode', 'custom-mode-hook', -'define-mode-overload-implementation', 'detect-coding-with-priority', -'dirtrack-debug', 'dirtrack-debug-toggle', 'dynamic-completion-table', +'define-key-rebound-commands', 'define-mode-overload-implementation', +'detect-coding-with-priority', 'dirtrack-debug', +'dirtrack-debug-toggle', 'dynamic-completion-table', 'easy-menu-precalculate-equivalent-keybindings', 'epa-display-verify-result', 'epg-passphrase-callback-function', 'eshell-report-bug', 'eval-next-after-load', 'exchange-dot-and-mark', diff --git a/lisp/subr.el b/lisp/subr.el index a85f41d7d77..6e52bd20df2 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1694,7 +1694,6 @@ be a list of the form returned by `event-start' and `event-end'." ;;;; Obsolescence declarations for variables, and aliases. -(make-obsolete-variable 'define-key-rebound-commands nil "23.2") (make-obsolete-variable 'redisplay-end-trigger-functions 'jit-lock-register "23.1") (make-obsolete-variable 'deferred-action-list 'post-command-hook "24.1") (make-obsolete-variable 'deferred-action-function 'post-command-hook "24.1") diff --git a/src/keymap.c b/src/keymap.c index de9b2b58c5e..782931fadff 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1065,9 +1065,6 @@ binding KEY to DEF is added at the front of KEYMAP. */) if (length == 0) return Qnil; - if (SYMBOLP (def) && !EQ (Vdefine_key_rebound_commands, Qt)) - Vdefine_key_rebound_commands = Fcons (def, Vdefine_key_rebound_commands); - int meta_bit = (VECTORP (key) || (STRINGP (key) && STRING_MULTIBYTE (key)) ? meta_modifier : 0x80); @@ -3132,12 +3129,6 @@ syms_of_keymap (void) pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" "))); staticpro (&exclude_keys); - DEFVAR_LISP ("define-key-rebound-commands", Vdefine_key_rebound_commands, - doc: /* List of commands given new key bindings recently. -This is used for internal purposes during Emacs startup; -don't alter it yourself. */); - Vdefine_key_rebound_commands = Qt; - DEFVAR_LISP ("minibuffer-local-map", Vminibuffer_local_map, doc: /* Default keymap to use when reading from the minibuffer. */); Vminibuffer_local_map = Fmake_sparse_keymap (Qnil); -- cgit v1.3 From e38e7b7bc121b96649518e5e986bba23697abc2d Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 1 Feb 2021 17:04:17 +0100 Subject: Make syntax errors say the line/column they appear at * src/lisp.h: Add count_lines prototype. * src/lread.c (invalid_syntax_lisp): New function (bug#36970). (invalid_syntax): Extend function to take a readcharfun parameter. (read_emacs_mule_char, character_name_to_code): Pass in. (read_escape, invalid_radix_integer, read1): Ditto. * src/xdisp.c (count_lines): Add a more succinct shim over display_count_lines. --- src/lisp.h | 1 + src/lread.c | 100 ++++++++++++++++++++++++++++++++++++------------------------ src/xdisp.c | 9 ++++++ 3 files changed, 70 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/lisp.h b/src/lisp.h index f6588685443..409a1e70608 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3734,6 +3734,7 @@ extern void message_log_maybe_newline (void); extern void update_echo_area (void); extern void truncate_echo_area (ptrdiff_t); extern void redisplay (void); +extern ptrdiff_t count_lines (ptrdiff_t start_byte, ptrdiff_t end_byte); void set_frame_cursor_types (struct frame *, Lisp_Object); extern void syms_of_xdisp (void); diff --git a/src/lread.c b/src/lread.c index 72b68df6631..5d1676b0c9c 100644 --- a/src/lread.c +++ b/src/lread.c @@ -537,6 +537,34 @@ readbyte_from_string (int c, Lisp_Object readcharfun) } +/* Signal Qinvalid_read_syntax error. + S is error string of length N (if > 0) */ + +static AVOID +invalid_syntax_lisp (Lisp_Object s, Lisp_Object readcharfun) +{ + if (BUFFERP (readcharfun)) + { + xsignal1 (Qinvalid_read_syntax, + CALLN (Fformat, build_string ("%s (line %d, column %d)"), + s, + /* We should already be in the readcharfun + buffer when this error is called, so no need + to switch to it first. */ + make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1), + make_fixnum (current_column ()))); + } + else + xsignal1 (Qinvalid_read_syntax, s); +} + +static AVOID +invalid_syntax (const char *s, Lisp_Object readcharfun) +{ + invalid_syntax_lisp (build_string (s), readcharfun); +} + + /* Read one non-ASCII character from INFILE. The character is encoded in `emacs-mule' and the first byte is already read in C. */ @@ -594,8 +622,7 @@ read_emacs_mule_char (int c, int (*readbyte) (int, Lisp_Object), Lisp_Object rea } c = DECODE_CHAR (charset, code); if (c < 0) - Fsignal (Qinvalid_read_syntax, - list1 (build_string ("invalid multibyte form"))); + invalid_syntax ("invalid multibyte form", readcharfun); return c; } @@ -2330,16 +2357,6 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end) } -/* Signal Qinvalid_read_syntax error. - S is error string of length N (if > 0) */ - -static AVOID -invalid_syntax (const char *s) -{ - xsignal1 (Qinvalid_read_syntax, build_string (s)); -} - - /* Use this for recursive reads, in contexts where internal tokens are not allowed. */ @@ -2353,8 +2370,8 @@ read0 (Lisp_Object readcharfun) if (!c) return val; - xsignal1 (Qinvalid_read_syntax, - Fmake_string (make_fixnum (1), make_fixnum (c), Qnil)); + invalid_syntax_lisp (Fmake_string (make_fixnum (1), make_fixnum (c), Qnil), + readcharfun); } /* Grow a read buffer BUF that contains OFFSET useful bytes of data, @@ -2384,7 +2401,8 @@ grow_read_buffer (char *buf, ptrdiff_t offset, /* Return the scalar value that has the Unicode character name NAME. Raise 'invalid-read-syntax' if there is no such character. */ static int -character_name_to_code (char const *name, ptrdiff_t name_len) +character_name_to_code (char const *name, ptrdiff_t name_len, + Lisp_Object readcharfun) { /* For "U+XXXX", pass the leading '+' to string_to_number to reject monstrosities like "U+-0000". */ @@ -2400,7 +2418,7 @@ character_name_to_code (char const *name, ptrdiff_t name_len) { AUTO_STRING (format, "\\N{%s}"); AUTO_STRING_WITH_LEN (namestr, name, name_len); - xsignal1 (Qinvalid_read_syntax, CALLN (Fformat, format, namestr)); + invalid_syntax_lisp (CALLN (Fformat, format, namestr), readcharfun); } return XFIXNUM (code); @@ -2619,7 +2637,7 @@ read_escape (Lisp_Object readcharfun, bool stringp) { c = READCHAR; if (c != '{') - invalid_syntax ("Expected opening brace after \\N"); + invalid_syntax ("Expected opening brace after \\N", readcharfun); char name[UNICODE_CHARACTER_NAME_LENGTH_BOUND + 1]; bool whitespace = false; ptrdiff_t length = 0; @@ -2634,8 +2652,9 @@ read_escape (Lisp_Object readcharfun, bool stringp) { AUTO_STRING (format, "Invalid character U+%04X in character name"); - xsignal1 (Qinvalid_read_syntax, - CALLN (Fformat, format, make_fixed_natnum (c))); + invalid_syntax_lisp (CALLN (Fformat, format, + make_fixed_natnum (c)), + readcharfun); } /* Treat multiple adjacent whitespace characters as a single space character. This makes it easier to use @@ -2651,15 +2670,15 @@ read_escape (Lisp_Object readcharfun, bool stringp) whitespace = false; name[length++] = c; if (length >= sizeof name) - invalid_syntax ("Character name too long"); + invalid_syntax ("Character name too long", readcharfun); } if (length == 0) - invalid_syntax ("Empty character name"); + invalid_syntax ("Empty character name", readcharfun); name[length] = '\0'; /* character_name_to_code can invoke read1, recursively. This is why read1's buffer is not static. */ - return character_name_to_code (name, length); + return character_name_to_code (name, length, readcharfun); } default: @@ -2697,10 +2716,11 @@ enum { stackbufsize = max (64, + INT_STRLEN_BOUND (EMACS_INT) + 1)) }; static void -invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)]) +invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)], + Lisp_Object readcharfun) { sprintf (stackbuf, invalid_radix_integer_format, radix); - invalid_syntax (stackbuf); + invalid_syntax (stackbuf, readcharfun); } /* Read an integer in radix RADIX using READCHARFUN to read @@ -2760,7 +2780,7 @@ read_integer (Lisp_Object readcharfun, int radix, UNREAD (c); if (valid != 1) - invalid_radix_integer (radix, stackbuf); + invalid_radix_integer (radix, stackbuf, readcharfun); *p = '\0'; return unbind_to (count, string_to_number (read_buffer, radix, NULL)); @@ -2896,7 +2916,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) return ht; } UNREAD (c); - invalid_syntax ("#"); + invalid_syntax ("#", readcharfun); } if (c == '^') { @@ -2948,9 +2968,9 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) } return tbl; } - invalid_syntax ("#^^"); + invalid_syntax ("#^^", readcharfun); } - invalid_syntax ("#^"); + invalid_syntax ("#^", readcharfun); } if (c == '&') { @@ -2973,7 +2993,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) version. */ && ! (XFIXNAT (length) == (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR))) - invalid_syntax ("#&..."); + invalid_syntax ("#&...", readcharfun); val = make_uninit_bool_vector (XFIXNAT (length)); data = bool_vector_uchar_data (val); @@ -2984,7 +3004,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) &= (1 << (XFIXNUM (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; return val; } - invalid_syntax ("#&..."); + invalid_syntax ("#&...", readcharfun); } if (c == '[') { @@ -3002,7 +3022,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) && VECTORP (AREF (tmp, COMPILED_CONSTANTS))) || CONSP (AREF (tmp, COMPILED_BYTECODE))) && FIXNATP (AREF (tmp, COMPILED_STACK_DEPTH)))) - invalid_syntax ("Invalid byte-code object"); + invalid_syntax ("Invalid byte-code object", readcharfun); if (STRINGP (AREF (tmp, COMPILED_BYTECODE)) && STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE))) @@ -3044,7 +3064,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) /* Read the string itself. */ tmp = read1 (readcharfun, &ch, 0); if (ch != 0 || !STRINGP (tmp)) - invalid_syntax ("#"); + invalid_syntax ("#", readcharfun); /* Read the intervals and their properties. */ while (1) { @@ -3059,7 +3079,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (ch == 0) plist = read1 (readcharfun, &ch, 0); if (ch) - invalid_syntax ("Invalid string property list"); + invalid_syntax ("Invalid string property list", readcharfun); Fset_text_properties (beg, end, plist, tmp); } @@ -3207,7 +3227,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (c == 'r' || c == 'R') { if (! (2 <= n && n <= 36)) - invalid_radix_integer (n, stackbuf); + invalid_radix_integer (n, stackbuf, readcharfun); return read_integer (readcharfun, n, stackbuf); } @@ -3301,7 +3321,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) return read_integer (readcharfun, 2, stackbuf); UNREAD (c); - invalid_syntax ("#"); + invalid_syntax ("#", readcharfun); case ';': while ((c = READCHAR) >= 0 && c != '\n'); @@ -3373,7 +3393,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) if (ok) return make_fixnum (c); - invalid_syntax ("?"); + invalid_syntax ("?", readcharfun); } case '"': @@ -3459,7 +3479,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) /* Any modifiers remaining are invalid. */ if (modifiers) - invalid_syntax ("Invalid modifier in string"); + invalid_syntax ("Invalid modifier in string", readcharfun); p += CHAR_STRING (ch, (unsigned char *) p); } else @@ -3999,7 +4019,7 @@ read_list (bool flag, Lisp_Object readcharfun) { if (ch == ']') return val; - invalid_syntax (") or . in a vector"); + invalid_syntax (") or . in a vector", readcharfun); } if (ch == ')') return val; @@ -4079,9 +4099,9 @@ read_list (bool flag, Lisp_Object readcharfun) return val; } - invalid_syntax (". in wrong context"); + invalid_syntax (". in wrong context", readcharfun); } - invalid_syntax ("] in a list"); + invalid_syntax ("] in a list", readcharfun); } tem = list1 (elt); if (!NILP (tail)) diff --git a/src/xdisp.c b/src/xdisp.c index 32b359098aa..efca6f641fb 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -26969,6 +26969,15 @@ decode_mode_spec (struct window *w, register int c, int field_width, return ""; } +/* Return the number of lines between start_byte and end_byte in the + current buffer. */ + +ptrdiff_t +count_lines (ptrdiff_t start_byte, ptrdiff_t end_byte) +{ + ptrdiff_t ignored; + return display_count_lines (start_byte, end_byte, ZV, &ignored); +} /* Count up to COUNT lines starting from START_BYTE. COUNT negative means count lines back from START_BYTE. But don't go beyond -- cgit v1.3 From 56804edc835b5b48f3bd6f89763c13d5e3ae3124 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 2 Feb 2021 09:26:02 +0100 Subject: Fix up invalid_syntax error signalling * src/lread.c (invalid_syntax_lisp): Instead of putting the line/column in a string, signal an error containing the numbers as data. This allows for easier post-processing and is how other similar errors (like (forward-sexp 1)) do it. --- src/lread.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/lread.c b/src/lread.c index 5d1676b0c9c..b33a312299f 100644 --- a/src/lread.c +++ b/src/lread.c @@ -545,14 +545,13 @@ invalid_syntax_lisp (Lisp_Object s, Lisp_Object readcharfun) { if (BUFFERP (readcharfun)) { - xsignal1 (Qinvalid_read_syntax, - CALLN (Fformat, build_string ("%s (line %d, column %d)"), - s, - /* We should already be in the readcharfun - buffer when this error is called, so no need - to switch to it first. */ - make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1), - make_fixnum (current_column ()))); + xsignal (Qinvalid_read_syntax, + list3 (s, + /* We should already be in the readcharfun + buffer when this error is called, so no need + to switch to it first. */ + make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1), + make_fixnum (current_column ()))); } else xsignal1 (Qinvalid_read_syntax, s); -- cgit v1.3 From 914cb7a1d666a87994e0492635f262396a839d4c Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 4 Feb 2021 18:00:29 +0200 Subject: Fix 'window-text-pixel-size' for short spans of text * src/xdisp.c (Fwindow_text_pixel_size): Support the use case where FROM and TO belong to the same screen line. Reported by Yuan Fu . --- src/xdisp.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xdisp.c b/src/xdisp.c index eb3f221df80..426c874cdb5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10714,8 +10714,23 @@ include the height of both, if present, in the return value. */) same directionality. */ it.bidi_p = false; + /* Start at the beginning of the line containing FROM. Otherwise + IT.current_x will be incorrectly set to zero at some arbitrary + non-zero X coordinate. */ + reseat_at_previous_visible_line_start (&it); + it.current_x = it.hpos = 0; + if (IT_CHARPOS (it) != start) + move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS); + + /* Now move to TO. */ + int start_x = it.current_x; int move_op = MOVE_TO_POS | MOVE_TO_Y; int to_x = -1; + it.current_y = 0; + /* If FROM is on a newline, pretend that we start at the beginning + of the next line, because the newline takes no place on display. */ + if (FETCH_BYTE (start) == '\n') + it.current_x = 0; if (!NILP (x_limit)) { it.last_visible_x = max_x; @@ -10758,6 +10773,12 @@ include the height of both, if present, in the return value. */) x = max_x; } + /* If text spans more than one screen line, we don't need to adjust + the x-span for start_x, since the second and subsequent lines + will begin at zero X coordinate. */ + if (it.current_y > 0) + start_x = 0; + /* Subtract height of header-line which was counted automatically by start_display. */ y = it.current_y + it.max_ascent + it.max_descent @@ -10786,7 +10807,7 @@ include the height of both, if present, in the return value. */) if (old_b) set_buffer_internal (old_b); - return Fcons (make_fixnum (x), make_fixnum (y)); + return Fcons (make_fixnum (x - start_x), make_fixnum (y)); } /*********************************************************************** -- cgit v1.3 From a2d7f3f171386f39a55f73988f94b1f4c94d8a6b Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 4 Feb 2021 19:35:07 +0200 Subject: Avoid overwriting minibuffer prompt by keystrokes echo * src/lread.c (Fread_char, Fread_event, Fread_char_exclusive): Call cancel_echoing to make sure the prompt is not obscured by keystrokes echo. (Bug#46243) --- src/lread.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lread.c b/src/lread.c index b33a312299f..010194c34ea 100644 --- a/src/lread.c +++ b/src/lread.c @@ -804,7 +804,10 @@ If `inhibit-interaction' is non-nil, this function will signal an barf_if_interaction_inhibited (); if (! NILP (prompt)) - message_with_string ("%s", prompt, 0); + { + cancel_echoing (); + message_with_string ("%s", prompt, 0); + } val = read_filtered_event (1, 1, 1, ! NILP (inherit_input_method), seconds); return (NILP (val) ? Qnil @@ -839,7 +842,10 @@ If `inhibit-interaction' is non-nil, this function will signal an barf_if_interaction_inhibited (); if (! NILP (prompt)) - message_with_string ("%s", prompt, 0); + { + cancel_echoing (); + message_with_string ("%s", prompt, 0); + } return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method), seconds); } @@ -875,7 +881,10 @@ If `inhibit-interaction' is non-nil, this function will signal an barf_if_interaction_inhibited (); if (! NILP (prompt)) - message_with_string ("%s", prompt, 0); + { + cancel_echoing (); + message_with_string ("%s", prompt, 0); + } val = read_filtered_event (1, 1, 0, ! NILP (inherit_input_method), seconds); -- cgit v1.3 From 764db69dd06b794074561e3830fdf02e67698445 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 5 Feb 2021 14:24:01 +0200 Subject: Fix last change in 'window-text-pixel-size' * src/xdisp.c (Fwindow_text_pixel_size): Fix last change: preserve the original Y coordinate after start_display, instead of zeroing it out. Reported by martin rudalics . --- src/xdisp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xdisp.c b/src/xdisp.c index 426c874cdb5..4db981aa655 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10706,6 +10706,7 @@ include the height of both, if present, in the return value. */) itdata = bidi_shelve_cache (); start_display (&it, w, startp); + int start_y = it.current_y; /* It makes no sense to measure dimensions of region of text that crosses the point where bidi reordering changes scan direction. By using unidirectional movement here we at least support the use @@ -10726,7 +10727,7 @@ include the height of both, if present, in the return value. */) int start_x = it.current_x; int move_op = MOVE_TO_POS | MOVE_TO_Y; int to_x = -1; - it.current_y = 0; + it.current_y = start_y; /* If FROM is on a newline, pretend that we start at the beginning of the next line, because the newline takes no place on display. */ if (FETCH_BYTE (start) == '\n') -- cgit v1.3 From 07ead60a822580b1dd3d8b3a5f6730d486b57cb3 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 5 Feb 2021 14:27:46 +0200 Subject: ; * src/xdisp.c (Fwindow_text_pixel_size): Another minor fix. --- src/xdisp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/xdisp.c b/src/xdisp.c index 4db981aa655..764735769b4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10777,7 +10777,7 @@ include the height of both, if present, in the return value. */) /* If text spans more than one screen line, we don't need to adjust the x-span for start_x, since the second and subsequent lines will begin at zero X coordinate. */ - if (it.current_y > 0) + if (it.current_y > start_y) start_x = 0; /* Subtract height of header-line which was counted automatically by -- cgit v1.3 From a6f23c226e601d6682f057056fe4c7a069a9f69a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 5 Feb 2021 22:04:15 +0200 Subject: ; * src/xdisp.c (Fwindow_text_pixel_size): Fix comment. --- src/xdisp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xdisp.c b/src/xdisp.c index 764735769b4..1815f986781 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10780,8 +10780,8 @@ include the height of both, if present, in the return value. */) if (it.current_y > start_y) start_x = 0; - /* Subtract height of header-line which was counted automatically by - start_display. */ + /* Subtract height of header-line and tab-line which was counted + automatically by start_display. */ y = it.current_y + it.max_ascent + it.max_descent - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w); /* Don't return more than Y-LIMIT. */ -- cgit v1.3 From b84b8dff709fd80ee124565222f333f53351ab4a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 6 Feb 2021 11:54:08 +0200 Subject: Fix copying text properties in 'format' * src/editfns.c (styled_format): Fix accounting for text properties that come from the format string. (Bug#46317) * test/src/editfns-tests.el (format-properties): Add new tests for bug#46317. --- src/editfns.c | 10 +++++++++- test/src/editfns-tests.el | 22 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/editfns.c b/src/editfns.c index e3285494c14..991f79abac7 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3134,6 +3134,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) char *format_start = SSDATA (args[0]); bool multibyte_format = STRING_MULTIBYTE (args[0]); ptrdiff_t formatlen = SBYTES (args[0]); + bool fmt_props = string_intervals (args[0]); /* Upper bound on number of format specs. Each uses at least 2 chars. */ ptrdiff_t nspec_bound = SCHARS (args[0]) >> 1; @@ -3406,13 +3407,20 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) convbytes += padding; if (convbytes <= buf + bufsize - p) { + /* If the format spec has properties, we should account + for the padding on the left in the info[] array. */ + if (fmt_props) + spec->start = nchars; if (! minus_flag) { memset (p, ' ', padding); p += padding; nchars += padding; } - spec->start = nchars; + /* If the properties will come from the argument, we + don't extend them to the left due to padding. */ + if (!fmt_props) + spec->start = nchars; if (p > buf && multibyte diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index 64f9137865b..dcec971c12e 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el @@ -106,7 +106,27 @@ #("foobar" 3 6 (face error)))) (should (ert-equal-including-properties (format (concat "%s " (propertize "%s" 'face 'error)) "foo" "bar") - #("foo bar" 4 7 (face error))))) + #("foo bar" 4 7 (face error)))) + ;; Bug #46317 + (let ((s (propertize "X" 'prop "val"))) + (should (ert-equal-including-properties + (format (concat "%3s/" s) 12) + #(" 12/X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%3S/" s) 12) + #(" 12/X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%3d/" s) 12) + #(" 12/X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%-3s/" s) 12) + #("12 /X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%-3S/" s) 12) + #("12 /X" 4 5 (prop "val")))) + (should (ert-equal-including-properties + (format (concat "%-3d/" s) 12) + #("12 /X" 4 5 (prop "val")))))) ;; Tests for bug#5131. (defun transpose-test-reverse-word (start end) -- cgit v1.3