commit 9ad601e7d762f47d3469692b8135cc72b8301365 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Tue Jul 18 09:27:27 2023 +0800 Expose the ``cancellation'' of touch events to Lisp * doc/lispref/commands.texi (Touchscreen Events): * etc/NEWS: Describe new event parameter `canceled'. * src/keyboard.c (make_lispy_event) : If event->modifiers, set canceled to t. * src/termhooks.h (enum event_kind): Describe meaning of modifiers in TOUCHSCREEN_END_EVENTs. * src/xfns.c (setup_xi_event_mask): Select for XI_TouchOwnership. * src/xterm.c (xi_link_touch_point): Round X and Y and clear ownership. (xi_unlink_touch_point): Return 1 if the touch point is not owned by Emacs, 2 otherwise. (handle_one_xevent): Handle XI_TouchOwnership events and report ownership correctly. * src/xterm.h (enum xi_touch_ownership): New enum. Write commentary on XI touch sequence ownership. (struct xi_touch_point_t): Use integer X and Y. New field `ownership'. Adjust for alignment. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index cd1745614eb..037f42124cc 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2018,10 +2018,15 @@ Touchscreen Events up-to-date positions of each touch point currently on the touchscreen. @cindex @code{touchscreen-end} event -@item (touchscreen-end @var{point}) +@item (touchscreen-end @var{point} @var{canceled}) This event is sent when @var{point} is no longer present on the display, because another program took the grab, or because the user raised the finger from the touchscreen. + +@var{canceled} is non-@code{nil} if the touch sequence has been +intercepted by another program (such as the window manager), and Emacs +should undo or avoid any editing commands that would otherwise result +from the touch sequence. @end table @node Focus Events diff --git a/etc/NEWS b/etc/NEWS index 3cfc36e10da..c50f560282a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -615,6 +615,12 @@ provokes an error if used numerically. This user option names directories in which Emacs will treat all directory-local variables as safe. ++++ +** New parameter to 'touchscreen-end' events. +CANCEL non-nil establishes that the touch sequence has been +intercepted by programs such as window managers and should be ignored +with Emacs. + ** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill. ** Functions and variables to transpose sexps diff --git a/src/keyboard.c b/src/keyboard.c index b61b1766856..41cda2e65de 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6404,7 +6404,6 @@ make_lispy_event (struct input_event *event) } case TOUCHSCREEN_BEGIN_EVENT: - case TOUCHSCREEN_END_EVENT: { Lisp_Object x, y, id, position; struct frame *f = XFRAME (event->frame_or_window); @@ -6422,6 +6421,25 @@ make_lispy_event (struct input_event *event) Fcons (id, position)); } + case TOUCHSCREEN_END_EVENT: + { + Lisp_Object x, y, id, position; + struct frame *f = XFRAME (event->frame_or_window); + + id = event->arg; + x = event->x; + y = event->y; + + position = make_lispy_position (f, x, y, event->timestamp); + + return list3 (((event->kind + == TOUCHSCREEN_BEGIN_EVENT) + ? Qtouchscreen_begin + : Qtouchscreen_end), + Fcons (id, position), + event->modifiers ? Qt : Qnil); + } + case PINCH_EVENT: { Lisp_Object x, y, position; diff --git a/src/termhooks.h b/src/termhooks.h index ba04a6b7759..c8345c2715f 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -307,7 +307,11 @@ #define EMACS_TERMHOOKS_H In TOUCHSCREEN_BEGIN_EVENT and TOUCHSCREEN_END_EVENT, ARG is the unique ID of the touchpoint, and X and Y are the frame-relative - positions of the touchpoint. */ + positions of the touchpoint. + + In TOUCHSCREEN_END_EVENT, non-0 modifiers means that the + touchpoint has been canceled. (See (elisp)Touchscreen + Events.) */ , TOUCHSCREEN_UPDATE_EVENT , TOUCHSCREEN_BEGIN_EVENT diff --git a/src/xfns.c b/src/xfns.c index fd4807fd5f5..55bcfb8e20e 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4107,6 +4107,7 @@ setup_xi_event_mask (struct frame *f) XISetMask (m, XI_TouchBegin); XISetMask (m, XI_TouchUpdate); XISetMask (m, XI_TouchEnd); + XISetMask (m, XI_TouchOwnership); #if defined HAVE_XINPUT2_4 && defined USE_GTK3 if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4) diff --git a/src/xterm.c b/src/xterm.c index 5cc2dfdae1d..130a2c93b64 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5742,6 +5742,10 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid) #ifdef HAVE_XINPUT2_2 +/* Record a touch sequence with the identifier DETAIL from the given + FRAME on the specified DEVICE. Round X and Y and record them as + its current position. */ + static void xi_link_touch_point (struct xi_device_t *device, int detail, double x, double y, @@ -5751,19 +5755,28 @@ xi_link_touch_point (struct xi_device_t *device, touchpoint = xmalloc (sizeof *touchpoint); touchpoint->next = device->touchpoints; - touchpoint->x = x; - touchpoint->y = y; + touchpoint->x = lrint (x); + touchpoint->y = lrint (y); touchpoint->number = detail; touchpoint->frame = frame; + touchpoint->ownership = TOUCH_OWNERSHIP_NONE; device->touchpoints = touchpoint; } -static bool -xi_unlink_touch_point (int detail, - struct xi_device_t *device) +/* Free and remove the touch sequence with the identifier DETAIL. + DEVICE is the device in which the touch sequence should be + recorded. + + Value is 0 if no touch sequence by that identifier exists inside + DEVICE, 1 if a touch sequence has been found but is not owned by + Emacs, and 2 otherwise. */ + +static int +xi_unlink_touch_point (int detail, struct xi_device_t *device) { struct xi_touch_point_t *last, *tem; + enum xi_touch_ownership ownership; for (last = NULL, tem = device->touchpoints; tem; last = tem, tem = tem->next) @@ -5775,12 +5788,17 @@ xi_unlink_touch_point (int detail, else last->next = tem->next; + ownership = tem->ownership; xfree (tem); - return true; + + if (ownership == TOUCH_OWNERSHIP_SELF) + return 2; + + return 1; } } - return false; + return 0; } /* Unlink all touch points associated with the frame F. @@ -5813,6 +5831,10 @@ xi_unlink_touch_points (struct frame *f) } } +/* Return the data associated with a touch sequence DETAIL recorded by + `xi_link_touch_point' from DEVICE, or NULL if it can't be + found. */ + static struct xi_touch_point_t * xi_find_touch_point (struct xi_device_t *device, int detail) { @@ -24422,12 +24444,48 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto XI_OTHER; } + case XI_TouchOwnership: + { + struct xi_device_t *device; + struct xi_touch_point_t *touchpoint; + XITouchOwnershipEvent *event; + + /* All grabbing clients have decided to reject ownership + of this touch sequence. */ + + event = (XITouchOwnershipEvent *) xi_event; + device = xi_device_from_id (dpyinfo, event->deviceid); + + if (!device || device->use == XIMasterPointer) + goto XI_OTHER; + + touchpoint = xi_find_touch_point (device, event->touchid); + + if (!touchpoint) + goto XI_OTHER; + + /* As a result, Emacs should complete whatever editing + operations result from this touch sequence. */ + touchpoint->ownership = TOUCH_OWNERSHIP_SELF; + } + case XI_TouchUpdate: { struct xi_device_t *device, *source; struct xi_touch_point_t *touchpoint; Lisp_Object arg = Qnil; + /* If flags & TouchPendingEnd, the touch sequence has + already ended, but some grabbing clients remain + undecided as to whether they will obtain ownership of + the touch sequence. + + Wait for them to make their decision, resulting in + TouchOwnership and TouchEnd events being sent. */ + + if (xev->flags & XITouchPendingEnd) + goto XI_OTHER; + device = xi_device_from_id (dpyinfo, xev->deviceid); source = xi_device_from_id (dpyinfo, xev->sourceid); x_display_set_last_user_time (dpyinfo, xev->time, @@ -24439,7 +24497,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, detached, and master pointers may also represent dependent touch devices. */ - if (!device) + if (!device || device->use == XIMasterPointer) goto XI_OTHER; touchpoint = xi_find_touch_point (device, xev->detail); @@ -24447,12 +24505,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!touchpoint /* Don't send this event if nothing has changed either. */ - || (touchpoint->x == (int) xev->event_x - && touchpoint->y == (int) xev->event_y)) + || (touchpoint->x == lrint (xev->event_x) + && touchpoint->y == lrint (xev->event_y))) goto XI_OTHER; - touchpoint->x = xev->event_x; - touchpoint->y = xev->event_y; + touchpoint->x = lrint (xev->event_x); + touchpoint->y = lrint (xev->event_y); f = x_window_to_frame (dpyinfo, xev->event); @@ -24466,8 +24524,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, touchpoint; touchpoint = touchpoint->next) { if (touchpoint->frame == f) - arg = Fcons (list3i (lrint (touchpoint->x), - lrint (touchpoint->y), + arg = Fcons (list3i (touchpoint->x, touchpoint->y, lrint (touchpoint->number)), arg); } @@ -24484,7 +24541,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, case XI_TouchEnd: { struct xi_device_t *device, *source; - bool unlinked_p; + int state; device = xi_device_from_id (dpyinfo, xev->deviceid); source = xi_device_from_id (dpyinfo, xev->sourceid); @@ -24500,9 +24557,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!device || device->use == XIMasterPointer) goto XI_OTHER; - unlinked_p = xi_unlink_touch_point (xev->detail, device); + state = xi_unlink_touch_point (xev->detail, device); - if (unlinked_p) + if (state) { f = x_window_to_frame (dpyinfo, xev->event); @@ -24510,6 +24567,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, { inev.ie.kind = TOUCHSCREEN_END_EVENT; inev.ie.timestamp = xev->time; + inev.ie.modifiers = state != 2; XSETFRAME (inev.ie.frame_or_window, f); XSETINT (inev.ie.x, lrint (xev->event_x)); diff --git a/src/xterm.h b/src/xterm.h index 34a713ea2ca..c7db54e2bcf 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -255,19 +255,71 @@ #define MAX_CLIP_RECTS 2 #ifdef HAVE_XINPUT2_2 +/* Enum describing the ownership of a touch point. + + The input extension allows other clients to intercept touch + sequences destined for a client window through passively grabbing + for touch events on a parent window. + + When a passive touch grab for an XI_TouchBegin event activates, one + grabbing client is designated the ``owner'' of the touch sequence + started by the grabbed event. Touch events are then delivered to + both the grabbing client and other clients that have selected for + touch events on the subwindow. + + The X server will not deliver TouchEnd events to clients other than + the owner until one grabbing client decides to take over processing + the touch event sequence, or no more grabbing clients remain. + Instead, a TouchUpdate event with the TouchPendingEnd flag is sent, + and the TouchEnd event is postponed until the decision is made and + all XI_TouchOwnership events are sent. + + If the owner decides to take over processing the touch sequence, an + XI_TouchEnd event is delivered to all other clients receiving + events for the current touch sequence, who are then expected to + cancel or undo any actions which have taken place in reaction to + events from that sequence. + + If the owner decides to relinquish ownership over the touch + sequence, the X server looks for another grabbing client, and + transfers touch ownership to that client instead. Nothing changes + from the perspective of clients who have merely selected for events + from the subwindow, while an XI_TouchEnd event is delivered to the + old owner, and an XI_TouchOwnership event is delivered to the new + owner. + + If all grabbing clients reject ownership over the touch sequence, + the X server delivers an XI_TouchOwnership event to the client that + has selected for touch events on the subwindow, the only client + that will receive events for this touch sequence from this time + forward. */ + +enum xi_touch_ownership + { + /* Emacs doesn't own this touch sequence. */ + TOUCH_OWNERSHIP_NONE, + + /* Emacs owns this touch sequence. */ + TOUCH_OWNERSHIP_SELF, + }; + struct xi_touch_point_t { - /* The next touch point in this list. */ - struct xi_touch_point_t *next; - /* The touchpoint detail. */ int number; - /* The last known X and Y position of the touchpoint. */ - double x, y; + /* Whether or not Emacs has ``exclusive'' access to this touch + point. */ + enum xi_touch_ownership ownership; + + /* The last known rounded X and Y positions of the touchpoint. */ + int x, y; /* The frame associated with this touch point. */ struct frame *frame; + + /* The next touch point in this list. */ + struct xi_touch_point_t *next; }; #endif commit 2f48e488d4b2ce9e5261886f22c64c6892ac53ee Author: Dmitry Gutov Date: Tue Jul 18 03:49:44 2023 +0300 Delete vc-deduce-fileset-1, taking advantage of set-buffer * lisp/vc/vc.el (vc-deduce-fileset): Set buffer to the base buffer, if any (bug#63949). That's to replace the more complex previous strategy. vc-deduce-fileset is allowed to change the current buffer, so why not do it for that case. (vc-deduce-fileset-1): Delete, moving the meat of the logic back to vc-deduce-fileset. diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 6c3094719ed..be7fa46c28e 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1121,19 +1121,8 @@ vc-deduce-fileset the returned list. BEWARE: this function may change the current buffer." - (let (new-buf res) - (with-current-buffer (or (buffer-base-buffer) (current-buffer)) - (setq res - (vc-deduce-fileset-1 not-state-changing - allow-unregistered - state-model-only-files)) - (setq new-buf (current-buffer))) - (set-buffer new-buf) - res)) - -(defun vc-deduce-fileset-1 (not-state-changing - allow-unregistered - state-model-only-files) + (when (buffer-base-buffer) + (set-buffer (buffer-base-buffer))) (let (backend) (cond ((derived-mode-p 'vc-dir-mode) @@ -1158,7 +1147,7 @@ vc-deduce-fileset-1 (derived-mode-p 'diff-mode))))) (progn ;FIXME: Why not `with-current-buffer'? --Stef. (set-buffer vc-parent-buffer) - (vc-deduce-fileset-1 not-state-changing allow-unregistered state-model-only-files))) + (vc-deduce-fileset not-state-changing allow-unregistered state-model-only-files))) ((and (not buffer-file-name) (setq backend (vc-responsible-backend default-directory))) (list backend nil)) commit bec707da4dbcc64485ee5815d91f40d0babad3a9 Author: Juri Linkov Date: Mon Jul 17 20:56:29 2023 +0300 * lisp/bindings.el (mode--line-format-right-align): Add 'mode-line' face. Like in `tab-bar-format-align-right', use `add-face-text-property' to add 'mode-line' face on the `rest-str' string for `string-pixel-width' to calculate the correct pixel width (bug#62606). diff --git a/lisp/bindings.el b/lisp/bindings.el index f1a75b080be..0a0fef1b564 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -338,7 +338,10 @@ mode--line-format-right-align (let* ((rest (cdr (memq 'mode-line-format-right-align mode-line-format))) (rest-str (format-mode-line `("" ,@rest))) - (rest-width (string-pixel-width rest-str))) + (rest-width (progn + (add-face-text-property + 0 (length rest-str) 'mode-line t rest-str) + (string-pixel-width rest-str)))) (propertize " " 'display ;; The `right' spec doesn't work on TTY frames ;; when windows are split horizontally (bug#59620) commit 157e735ce89ede9cc939f4ed0f72c5af7ae60735 Author: Mattias Engdegård Date: Mon Jul 17 13:05:21 2023 +0200 Don't distort character ranges in rx translation The Emacs regexp engine interprets character ranges from ASCII to raw bytes, such as [a-\xfe], as not including non-ASCII Unicode at all; ranges from non-ACII Unicode to raw bytes, such as [ü-\x91], are ignored entirely. To make rx produce a translation that works as intended, split ranges that that go from ordinary characters to raw bytes. Such ranges may appear from set manipulation and regexp optimisation. * lisp/emacs-lisp/rx.el (rx--generate-alt): Split intervals that straddle the char-raw boundary when rendering a string regexp from an interval set. * test/lisp/emacs-lisp/rx-tests.el (rx-char-any-raw-byte): Add test cases. diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index e82490ffee5..f1eb3e308a2 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -484,6 +484,12 @@ rx--generate-alt (char-to-string (car item))) ((eq (1+ (car item)) (cdr item)) (string (car item) (cdr item))) + ;; Ranges that go between normal chars and raw bytes + ;; must be split to avoid being mutilated + ;; by Emacs's regexp parser. + ((<= (car item) #x3fff7f (cdr item)) + (string (car item) ?- #x3fff7f + #x3fff80 ?- (cdr item))) (t (string (car item) ?- (cdr item))))) items nil) diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 028250b7352..995d297ff08 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -98,7 +98,17 @@ rx-char-any-raw-byte "[\177Å\211\326-\377]")) ;; Split range; \177-\377ÿ should not be optimized to \177-\377. (should (equal (rx (any "\177-\377" ?ÿ)) - "[\177ÿ\200-\377]"))) + "[\177ÿ\200-\377]")) + ;; Range between normal chars and raw bytes: must be split to be parsed + ;; correctly by the Emacs regexp engine. + (should (equal + (rx (any (0 . #x3fffff)) (any (?G . #x3fff9a)) (any (?Ü . #x3ffff2))) + "[\0-\x3fff7f\x80-\xff][G-\x3fff7f\x80-\x9a][Ü-\x3fff7f\x80-\xf2]")) + ;; As above but with ranges in string form. For historical reasons, + ;; we special-case ASCII-to-raw ranges to exclude non-ASCII unicode. + (should (equal + (rx (any "\x00-\xff") (any "G-\x9a") (any "Ü-\xf2")) + "[\0-\x7f\x80-\xff][G-\x7f\x80-\x9a][Ü-\x3fff7f\x80-\xf2]"))) (ert-deftest rx-any () (should (equal (rx (any ?A (?C . ?D) "F-H" "J-L" "M" "N-P" "Q" "RS")) commit 7446a8c34e2b793df52dbf56b630e20f8c10568c Author: Brian Leung Date: Mon Jul 17 14:29:18 2023 +0100 Eglot: check correct capability name in eglot-imenu (bug#64682) * lisp/progmodes/eglot.el (eglot-imenu): Declare the correct name of the server capability providing textDocument/documentSymbol. Without this change, eglot-imenu always aborts even when used with servers supporting textDocument/documentSymbol. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 8ac21638a5b..1df3a8844f8 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -3367,7 +3367,7 @@ eglot--imenu-DocumentSymbol (cl-defun eglot-imenu () "Eglot's `imenu-create-index-function'. Returns a list as described in docstring of `imenu--index-alist'." - (unless (eglot--server-capable :textDocument/documentSymbol) + (unless (eglot--server-capable :documentSymbolProvider) (cl-return-from eglot-imenu)) (let* ((res (eglot--request (eglot--current-server-or-lose) :textDocument/documentSymbol commit ac566bcdee31a260cbdce336e76f20a317b6dd06 Author: Po Lu Date: Mon Jul 17 20:42:56 2023 +0800 Don't deliver touch or pinch events from master or slave devices * src/xfns.c (setup_xi_event_mask): Select for gesture events on only master devices if safe. * src/xterm.c (handle_one_xevent): Deliver touchscreen events only from direct slave devices, and gesture events only from master pointers. diff --git a/src/xfns.c b/src/xfns.c index 5c9f58e3a96..fd4807fd5f5 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4036,7 +4036,7 @@ setup_xi_event_mask (struct frame *f) selected->mask = ((unsigned char *) selected) + sizeof *selected; selected->mask_len = l; selected->deviceid = XIAllMasterDevices; -#endif +#endif /* !HAVE_XINPUT2_1 */ mask.mask = m = alloca (l); memset (m, 0, l); @@ -4056,7 +4056,19 @@ setup_xi_event_mask (struct frame *f) XISetMask (m, XI_FocusOut); XISetMask (m, XI_KeyPress); XISetMask (m, XI_KeyRelease); -#endif +#endif /* !USE_GTK */ +#if defined HAVE_XINPUT2_4 + if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4) + { + /* Select for gesture events. Since this configuration doesn't + use GTK 3, Emacs is the only code that can change the XI + event mask, and can safely select for gesture events on + master pointers only. */ + XISetMask (m, XI_GesturePinchBegin); + XISetMask (m, XI_GesturePinchUpdate); + XISetMask (m, XI_GesturePinchEnd); + } +#endif /* HAVE_XINPUT2_4 */ XISelectEvents (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &mask, 1); @@ -4065,7 +4077,7 @@ setup_xi_event_mask (struct frame *f) to get the event mask from the X server. */ #ifndef HAVE_XINPUT2_1 memcpy (selected->mask, m, l); -#endif +#endif /* !HAVE_XINPUT2_1 */ memset (m, 0, l); #endif /* !HAVE_GTK3 */ @@ -4080,35 +4092,45 @@ setup_xi_event_mask (struct frame *f) FRAME_OUTER_WINDOW (f), &mask, 1); memset (m, 0, l); -#endif +#endif /* USE_X_TOOLKIT */ #ifdef HAVE_XINPUT2_2 if (FRAME_DISPLAY_INFO (f)->xi2_version >= 2) { + /* Select for touch events from all devices. + + Emacs will only process touch events originating + from slave devices, as master pointers may also + represent dependent touch devices. */ mask.deviceid = XIAllDevices; XISetMask (m, XI_TouchBegin); XISetMask (m, XI_TouchUpdate); XISetMask (m, XI_TouchEnd); -#ifdef HAVE_XINPUT2_4 + +#if defined HAVE_XINPUT2_4 && defined USE_GTK3 if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4) { + /* Now select for gesture events from all pointer devices. + Emacs will only handle gesture events from the master + pointer, but cannot afford to overwrite the event mask + set by GDK. */ + XISetMask (m, XI_GesturePinchBegin); XISetMask (m, XI_GesturePinchUpdate); XISetMask (m, XI_GesturePinchEnd); } -#endif +#endif /* HAVE_XINPUT2_4 && USE_GTK3 */ - XISelectEvents (FRAME_X_DISPLAY (f), - FRAME_X_WINDOW (f), + XISelectEvents (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &mask, 1); } -#endif +#endif /* HAVE_XINPUT2_2 */ #ifndef HAVE_XINPUT2_1 FRAME_X_OUTPUT (f)->xi_masks = selected; FRAME_X_OUTPUT (f)->num_xi_masks = 1; -#endif +#endif /* HAVE_XINPUT2_1 */ unblock_input (); } diff --git a/src/xterm.c b/src/xterm.c index 9ecead03b08..5cc2dfdae1d 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -24259,7 +24259,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_display_set_last_user_time (dpyinfo, xev->time, xev->send_event, true); - if (!device) + /* Don't process touch sequences from this device if + it's a master pointer. Touch sequences aren't + canceled by the X server if a slave device is + detached, and master pointers may also represent + dependent touch devices. */ + + if (!device || device->use == XIMasterPointer) goto XI_OTHER; if (xi_find_touch_point (device, xev->detail)) @@ -24427,12 +24433,22 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_display_set_last_user_time (dpyinfo, xev->time, xev->send_event, true); + /* Don't process touch sequences from this device if + it's a master pointer. Touch sequences aren't + canceled by the X server if a slave device is + detached, and master pointers may also represent + dependent touch devices. */ + if (!device) goto XI_OTHER; touchpoint = xi_find_touch_point (device, xev->detail); - if (!touchpoint) + if (!touchpoint + /* Don't send this event if nothing has changed + either. */ + || (touchpoint->x == (int) xev->event_x + && touchpoint->y == (int) xev->event_y)) goto XI_OTHER; touchpoint->x = xev->event_x; @@ -24475,7 +24491,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_display_set_last_user_time (dpyinfo, xev->time, xev->send_event, true); - if (!device) + /* Don't process touch sequences from this device if + it's a master pointer. Touch sequences aren't + canceled by the X server if a slave device is + detached, and master pointers may also represent + dependent touch devices. */ + + if (!device || device->use == XIMasterPointer) goto XI_OTHER; unlinked_p = xi_unlink_touch_point (xev->detail, device); @@ -24543,7 +24565,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_display_set_last_user_time (dpyinfo, pev->time, pev->send_event, true); - if (!device) + if (!device || device->use != XIMasterPointer) goto XI_OTHER; #ifdef HAVE_XWIDGETS commit 91424cb9aded01bc14912dcf037f7aa0e11c97d8 Author: Robert Pluim Date: Mon Jul 17 10:10:48 2023 +0200 Fix eshell.texi markup * doc/misc/eshell.texi (Aliases): Add missing @end table. (Bug#64674) diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 099bf3e9809..9b9268ae4ea 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -1092,6 +1092,8 @@ Aliases @kbd{alias mcd 'mkdir $1 && cd $1'} would cause @kbd{mcd foo} to create and switch to a directory called @samp{foo}. +@end table + @node Remote Access @section Remote Access @cmindex remote access commit fcf9e91f448fb3de43af049a15d716ee37bf9185 Author: Marc van der Wal Date: Mon Jul 17 10:56:06 2023 +0200 Check correct bit for DNS truncation * lisp/net/dns.el (dns-read): The TC bit is the second bit, not the third bit. (Bug#64678) Copyright-paperwork-exempt: yes diff --git a/lisp/net/dns.el b/lisp/net/dns.el index 1e320a2124a..42e7fb415d3 100644 --- a/lisp/net/dns.el +++ b/lisp/net/dns.el @@ -212,7 +212,7 @@ dns-read spec)) (push (list 'authoritative-p (if (zerop (logand byte (ash 1 2))) nil t)) spec) - (push (list 'truncated-p (if (zerop (logand byte (ash 1 2))) nil t)) + (push (list 'truncated-p (if (zerop (logand byte (ash 1 1))) nil t)) spec) (push (list 'recursion-desired-p (if (zerop (logand byte (ash 1 0))) nil t)) spec)) commit 9d332c49933331c9b2f9fe8e403a20fddd8062b6 Author: Eli Zaretskii Date: Mon Jul 17 14:36:44 2023 +0300 ; * lisp/files.el (create-file-buffer): Add commentary. diff --git a/lisp/files.el b/lisp/files.el index 0c08250a7e9..f8867432000 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2094,7 +2094,7 @@ create-file-buffer To avoid confusion when visiting a file whose name begins with a space, this function prepends a \"|\" to the final result if necessary." (let* ((lastname (file-name-nondirectory (directory-file-name filename))) - (lastname (if (string= lastname "") + (lastname (if (string= lastname "") ; FILENAME is a root directory filename lastname)) (lastname (cond ((not (and uniquify-trailing-separator-p commit 5b6b95dbf8de1aa0cbcb0f1b6f3c4debcc20296b Author: Eli Zaretskii Date: Mon Jul 17 14:34:35 2023 +0300 ; * lisp/files.el (create-file-buffer): Fix last change (bug#62732). diff --git a/lisp/files.el b/lisp/files.el index 4b65ff10b68..0c08250a7e9 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2094,6 +2094,8 @@ create-file-buffer To avoid confusion when visiting a file whose name begins with a space, this function prepends a \"|\" to the final result if necessary." (let* ((lastname (file-name-nondirectory (directory-file-name filename))) + (lastname (if (string= lastname "") + filename lastname)) (lastname (cond ((not (and uniquify-trailing-separator-p (file-directory-p filename))) commit 207cd4c23570dc1cb1fdb57a70c67a3be5cefe33 Author: Stefan Monnier Date: Sun Jul 16 21:12:20 2023 -0400 xdisp.c: Improve doc of `redisplay` flags a bit diff --git a/src/window.h b/src/window.h index 2f793ebe438..9da6126c321 100644 --- a/src/window.h +++ b/src/window.h @@ -1114,9 +1114,11 @@ #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ extern Lisp_Object echo_area_window; -/* Non-zero if we should redraw the mode lines on the next redisplay. +/* Non-zero if we should redraw the mode line*s* on the next redisplay. Usually set to a unique small integer so we can track the main causes of - full redisplays in `redisplay--mode-lines-cause'. */ + full redisplays in `redisplay--mode-lines-cause'. + Here "mode lines" includes other elements not coming from the buffer's + text, such as header-lines, tab lines, frame names, menu-bars, .... */ extern int update_mode_lines; @@ -1134,6 +1136,11 @@ #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ extern void wset_redisplay (struct window *w); extern void fset_redisplay (struct frame *f); extern void bset_redisplay (struct buffer *b); + +/* Routines to indicate that the mode-lines might need to be redisplayed. + Just as for `update_mode_lines`, this includes other elements not coming + from the buffer's text, such as header-lines, tab lines, frame names, + menu-bars, .... */ extern void bset_update_mode_line (struct buffer *b); extern void wset_update_mode_line (struct window *w); /* Call this to tell redisplay to look for other windows than selected-window diff --git a/src/xdisp.c b/src/xdisp.c index a3464c2c375..5d94dc003f3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -16490,8 +16490,9 @@ redisplay_internal (void) enum {MAX_GARBAGED_FRAME_RETRIES = 2 }; int garbaged_frame_retries = 0; - /* True means redisplay has to consider all windows on all - frames. False, only selected_window is considered. */ + /* False means that only the selected_window needs to be updated. + True means that other windows may need to be updated as well, + so we need to consult `needs_no_update` for all windows. */ bool consider_all_windows_p; /* True means redisplay has to redisplay the miniwindow. */ commit a65ece8b2011bd69922262a6fbcf68c2e2c2a717 Author: Eli Zaretskii Date: Sun Jul 16 12:15:24 2023 +0300 Fix Wdired with relative and abbreviated file names * lisp/wdired.el (wdired-finish-edit): Support Dired buffers where 'dired-directory' is a list made of relative or abbreviated file names. (Bug#64606) diff --git a/lisp/wdired.el b/lisp/wdired.el index 5c745cc9aab..7b9c75d36b1 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -556,8 +556,24 @@ wdired-finish-edit ;; been modified with their new name keeping ;; the ones that are unmodified at the same place. (cl-loop for f in (cdr dired-directory) - collect (or (assoc-default f files-renamed) - f)))))) + collect + (or (assoc-default f files-renamed) + ;; F could be relative or + ;; abbreviated, whereas + ;; files-renamed always consists + ;; of absolute file names. + (let ((relative + (not (file-name-absolute-p f))) + (match + (assoc-default (expand-file-name f) + files-renamed))) + (cond + ;; If it was relative, convert + ;; the new name back to relative. + ((and match relative) + (file-relative-name match)) + (t match))) + f)))))) ;; Re-sort the buffer. (revert-buffer) (let ((inhibit-read-only t)) commit c5fa58cbc4a33a0a65494b9ab2e35d4f30ab849b Merge: f17bdee79b1 16f3a09e8db Author: Eli Zaretskii Date: Sat Jul 15 15:11:43 2023 -0400 Merge from origin/emacs-29 16f3a09e8db ; * lisp/simple.el (kill-new): Fix a typo. (Bug#64423) d78e670237b ; * src/lisp.h: Improve commentary for XIL, XLI, XLP (bug... commit 16f3a09e8dba33b2e3d7505862e7fc99952edcae Author: Eli Zaretskii Date: Sat Jul 15 22:08:52 2023 +0300 ; * lisp/simple.el (kill-new): Fix a typo. (Bug#64423) diff --git a/lisp/simple.el b/lisp/simple.el index 65af1d02a1e..86f65d9d98e 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5624,7 +5624,7 @@ kill-new ;; interrupt this. If they interrupt it, we want to continue ;; so we become selection owner, so this doesn't stay slow. (if (eq (window-system) 'x) - (ignore-error 'quit (funcall interprogram-paste-function)) + (ignore-error quit (funcall interprogram-paste-function)) (funcall interprogram-paste-function))))) (when interprogram-paste (setq interprogram-paste commit f17bdee79b1987f23f61719a827934e678ec0ba5 Author: Stefan Monnier Date: Sat Jul 15 11:41:32 2023 -0400 sgml-mode.el: Cosmetic fixes * lisp/textmodes/sgml-mode.el: Prefer #' to quote function names. (sgml-font-lock-keywords-1, sgml-font-lock-syntactic-face): Refer to font-lock faces rather than their variables. (sgml-mode-facemenu-add-face-function): Remove redundant arg to `mapconcat`. (sgml-electric-tag-pair-before-change-function): Remove left-over debugging messages (bug#64636). diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index b4f5ebf5cd0..d80cdc34775 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -66,7 +66,7 @@ sgml-attribute-offset " :version "25.1" :type 'integer - :safe 'integerp) + :safe #'integerp) (defcustom sgml-xml-mode nil "When non-nil, tag insertion functions will be XML-compliant. @@ -81,7 +81,7 @@ 'sgml-transformation (defcustom sgml-transformation-function 'identity "Default value for `skeleton-transformation-function' in SGML mode." :type 'function - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :set (lambda (sym val) (set-default sym val) (mapc (lambda (buff) @@ -120,40 +120,40 @@ sgml-quick-keys (defvar sgml-mode-map (let ((map (make-keymap))) ;`sparse' doesn't allow binding to charsets. - (define-key map "\C-c\C-i" 'sgml-tags-invisible) - (define-key map "/" 'sgml-slash) - (define-key map "\C-c\C-n" 'sgml-name-char) - (define-key map "\C-c\C-t" 'sgml-tag) - (define-key map "\C-c\C-a" 'sgml-attributes) - (define-key map "\C-c\C-b" 'sgml-skip-tag-backward) - (define-key map [?\C-c left] 'sgml-skip-tag-backward) - (define-key map "\C-c\C-f" 'sgml-skip-tag-forward) - (define-key map [?\C-c right] 'sgml-skip-tag-forward) - (define-key map "\C-c\C-d" 'sgml-delete-tag) - (define-key map "\C-c\^?" 'sgml-delete-tag) - (define-key map "\C-c?" 'sgml-tag-help) - (define-key map "\C-c]" 'sgml-close-tag) - (define-key map "\C-c/" 'sgml-close-tag) + (define-key map "\C-c\C-i" #'sgml-tags-invisible) + (define-key map "/" #'sgml-slash) + (define-key map "\C-c\C-n" #'sgml-name-char) + (define-key map "\C-c\C-t" #'sgml-tag) + (define-key map "\C-c\C-a" #'sgml-attributes) + (define-key map "\C-c\C-b" #'sgml-skip-tag-backward) + (define-key map [?\C-c left] #'sgml-skip-tag-backward) + (define-key map "\C-c\C-f" #'sgml-skip-tag-forward) + (define-key map [?\C-c right] #'sgml-skip-tag-forward) + (define-key map "\C-c\C-d" #'sgml-delete-tag) + (define-key map "\C-c\^?" #'sgml-delete-tag) + (define-key map "\C-c?" #'sgml-tag-help) + (define-key map "\C-c]" #'sgml-close-tag) + (define-key map "\C-c/" #'sgml-close-tag) ;; Redundant keybindings, for consistency with TeX mode. - (define-key map "\C-c\C-o" 'sgml-tag) - (define-key map "\C-c\C-e" 'sgml-close-tag) + (define-key map "\C-c\C-o" #'sgml-tag) + (define-key map "\C-c\C-e" #'sgml-close-tag) - (define-key map "\C-c8" 'sgml-name-8bit-mode) - (define-key map "\C-c\C-v" 'sgml-validate) + (define-key map "\C-c8" #'sgml-name-8bit-mode) + (define-key map "\C-c\C-v" #'sgml-validate) (when sgml-quick-keys - (define-key map "&" 'sgml-name-char) - (define-key map "<" 'sgml-tag) - (define-key map " " 'sgml-auto-attributes) - (define-key map ">" 'sgml-maybe-end-tag) + (define-key map "&" #'sgml-name-char) + (define-key map "<" #'sgml-tag) + (define-key map " " #'sgml-auto-attributes) + (define-key map ">" #'sgml-maybe-end-tag) (when (memq ?\" sgml-specials) - (define-key map "\"" 'sgml-name-self)) + (define-key map "\"" #'sgml-name-self)) (when (memq ?' sgml-specials) - (define-key map "'" 'sgml-name-self))) + (define-key map "'" #'sgml-name-self))) (let ((c 127) (map (nth 1 map))) (while (< (setq c (1+ c)) 256) - (aset map c 'sgml-maybe-name-self))) + (aset map c #'sgml-maybe-name-self))) map) "Keymap for SGML mode. See also `sgml-specials'.") @@ -312,28 +312,28 @@ sgml-namespace-face ;; internal (defconst sgml-font-lock-keywords-1 - `((,(concat "<\\([!?]" sgml-name-re "\\)") 1 font-lock-keyword-face) + `((,(concat "<\\([!?]" sgml-name-re "\\)") 1 'font-lock-keyword-face) ;; We could use the simpler "\\(" sgml-namespace-re ":\\)?" instead, ;; but it would cause a bit more backtracking in the re-matcher. (,(concat "]*\\)?>\\([^<]+\\)") '(3 (cdr (assoc-string (match-string 1) sgml-tag-face-alist t)) prepend)))))) @@ -346,8 +346,8 @@ sgml-font-lock-keywords (defun sgml-font-lock-syntactic-face (state) "`font-lock-syntactic-face-function' for `sgml-mode'." ;; Don't use string face outside of tags. - (cond ((and (nth 9 state) (nth 3 state)) font-lock-string-face) - ((nth 4 state) font-lock-comment-face))) + (cond ((and (nth 9 state) (nth 3 state)) 'font-lock-string-face) + ((nth 4 state) 'font-lock-comment-face))) (defvar-local sgml--syntax-propertize-ppss nil) @@ -511,7 +511,7 @@ sgml-xml-guess (looking-at "\\s-*<\\?xml") (when (re-search-forward (eval-when-compile - (mapconcat 'identity + (mapconcat #'identity '("")) (reverse tag-face) "")) - (mapconcat (lambda (f) (concat "<" f ">")) tag-face "")) + (mapconcat (lambda (f) (concat "")) (reverse tag-face))) + (mapconcat (lambda (f) (concat "<" f ">")) tag-face)) ((and (consp face) (consp (car face)) (null (cdr face)) @@ -593,7 +593,8 @@ sgml-mode (setq-local tildify-space-string (if (equal (decode-coding-string (encode-coding-string " " buffer-file-coding-system) - buffer-file-coding-system) " ") + buffer-file-coding-system) + " ") " " " ")) ;; FIXME: Use the fact that we're parsing the document already ;; rather than using regex-based filtering. @@ -616,12 +617,12 @@ sgml-mode \[ \t]*")) (setq-local paragraph-separate (concat paragraph-start "$")) (setq-local adaptive-fill-regexp "[ \t]*") - (add-hook 'fill-nobreak-predicate 'sgml-fill-nobreak nil t) - (setq-local indent-line-function 'sgml-indent-line) + (add-hook 'fill-nobreak-predicate #'sgml-fill-nobreak nil t) + (setq-local indent-line-function #'sgml-indent-line) (setq-local comment-start "") - (setq-local comment-indent-function 'sgml-comment-indent) - (setq-local comment-line-break-function 'sgml-comment-indent-new-line) + (setq-local comment-indent-function #'sgml-comment-indent) + (setq-local comment-line-break-function #'sgml-comment-indent-new-line) (setq-local skeleton-further-elements '((completion-ignore-case t))) (setq-local skeleton-end-newline nil) (setq-local skeleton-end-hook @@ -637,7 +638,7 @@ sgml-mode . sgml-font-lock-syntactic-face))) (setq-local syntax-propertize-function #'sgml-syntax-propertize) (setq-local syntax-ppss-table sgml-tag-syntax-table) - (setq-local facemenu-add-face-function 'sgml-mode-facemenu-add-face-function) + (setq-local facemenu-add-face-function #'sgml-mode-facemenu-add-face-function) (when (sgml-xml-guess) (setq-local sgml-xml-mode t)) (unless sgml-xml-mode @@ -997,9 +998,7 @@ sgml-electric-tag-pair-before-change-function (point)))) (or (not endp) (eq (char-after cl-end) ?>))) (when clones - (message "sgml-electric-tag-pair-before-change-function: deleting old OLs") - (mapc 'delete-overlay clones)) - (message "sgml-electric-tag-pair-before-change-function: new clone") + (mapc #'delete-overlay clones)) (text-clone-create cl-start cl-end 'spread "[[:alnum:]-_.:]+") (setq sgml-electric-tag-pair-overlays (append (get-char-property (point) 'text-clones) @@ -1021,13 +1020,13 @@ sgml-electric-tag-pair-mode (if sgml-electric-tag-pair-mode (progn (add-hook 'before-change-functions - 'sgml-electric-tag-pair-before-change-function + #'sgml-electric-tag-pair-before-change-function nil t) (unless sgml-electric-tag-pair-timer (setq sgml-electric-tag-pair-timer - (run-with-idle-timer 5 'repeat 'sgml-electric-tag-pair-flush-overlays)))) + (run-with-idle-timer 5 'repeat #'sgml-electric-tag-pair-flush-overlays)))) (remove-hook 'before-change-functions - 'sgml-electric-tag-pair-before-change-function + #'sgml-electric-tag-pair-before-change-function t) ;; We leave the timer running for other buffers. )) @@ -1781,8 +1780,8 @@ sgml-parse-dtd (push (match-string-no-properties 1) empty)) ((string= (match-string 2) "O") (push (match-string-no-properties 1) unclosed)))) - (setq empty (sort (mapcar 'downcase empty) 'string<)) - (setq unclosed (sort (mapcar 'downcase unclosed) 'string<)) + (setq empty (sort (mapcar #'downcase empty) #'string<)) + (setq unclosed (sort (mapcar #'downcase unclosed) #'string<)) (list empty unclosed))) ;;; HTML mode @@ -1801,41 +1800,41 @@ html-quick-keys (defvar html-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map sgml-mode-map) - (define-key map "\C-c6" 'html-headline-6) - (define-key map "\C-c5" 'html-headline-5) - (define-key map "\C-c4" 'html-headline-4) - (define-key map "\C-c3" 'html-headline-3) - (define-key map "\C-c2" 'html-headline-2) - (define-key map "\C-c1" 'html-headline-1) - (define-key map "\C-c\r" 'html-paragraph) - (define-key map "\C-c\n" 'html-line) - (define-key map "\C-c\C-c-" 'html-horizontal-rule) - (define-key map "\C-c\C-co" 'html-ordered-list) - (define-key map "\C-c\C-cu" 'html-unordered-list) - (define-key map "\C-c\C-cr" 'html-radio-buttons) - (define-key map "\C-c\C-cc" 'html-checkboxes) - (define-key map "\C-c\C-cl" 'html-list-item) - (define-key map "\C-c\C-ch" 'html-href-anchor) - (define-key map "\C-c\C-cf" 'html-href-anchor-file) - (define-key map "\C-c\C-cn" 'html-name-anchor) - (define-key map "\C-c\C-c#" 'html-id-anchor) - (define-key map "\C-c\C-ci" 'html-image) + (define-key map "\C-c6" #'html-headline-6) + (define-key map "\C-c5" #'html-headline-5) + (define-key map "\C-c4" #'html-headline-4) + (define-key map "\C-c3" #'html-headline-3) + (define-key map "\C-c2" #'html-headline-2) + (define-key map "\C-c1" #'html-headline-1) + (define-key map "\C-c\r" #'html-paragraph) + (define-key map "\C-c\n" #'html-line) + (define-key map "\C-c\C-c-" #'html-horizontal-rule) + (define-key map "\C-c\C-co" #'html-ordered-list) + (define-key map "\C-c\C-cu" #'html-unordered-list) + (define-key map "\C-c\C-cr" #'html-radio-buttons) + (define-key map "\C-c\C-cc" #'html-checkboxes) + (define-key map "\C-c\C-cl" #'html-list-item) + (define-key map "\C-c\C-ch" #'html-href-anchor) + (define-key map "\C-c\C-cf" #'html-href-anchor-file) + (define-key map "\C-c\C-cn" #'html-name-anchor) + (define-key map "\C-c\C-c#" #'html-id-anchor) + (define-key map "\C-c\C-ci" #'html-image) (when html-quick-keys - (define-key map "\C-c-" 'html-horizontal-rule) - (define-key map "\C-cd" 'html-div) - (define-key map "\C-co" 'html-ordered-list) - (define-key map "\C-cu" 'html-unordered-list) - (define-key map "\C-cr" 'html-radio-buttons) - (define-key map "\C-cc" 'html-checkboxes) - (define-key map "\C-cl" 'html-list-item) - (define-key map "\C-ch" 'html-href-anchor) - (define-key map "\C-cf" 'html-href-anchor-file) - (define-key map "\C-cn" 'html-name-anchor) - (define-key map "\C-c#" 'html-id-anchor) - (define-key map "\C-ci" 'html-image) - (define-key map "\C-cs" 'html-span)) - (define-key map "\C-c\C-s" 'html-autoview-mode) - (define-key map "\C-c\C-v" 'browse-url-of-buffer) + (define-key map "\C-c-" #'html-horizontal-rule) + (define-key map "\C-cd" #'html-div) + (define-key map "\C-co" #'html-ordered-list) + (define-key map "\C-cu" #'html-unordered-list) + (define-key map "\C-cr" #'html-radio-buttons) + (define-key map "\C-cc" #'html-checkboxes) + (define-key map "\C-cl" #'html-list-item) + (define-key map "\C-ch" #'html-href-anchor) + (define-key map "\C-cf" #'html-href-anchor-file) + (define-key map "\C-cn" #'html-name-anchor) + (define-key map "\C-c#" #'html-id-anchor) + (define-key map "\C-ci" #'html-image) + (define-key map "\C-cs" #'html-span)) + (define-key map "\C-c\C-s" #'html-autoview-mode) + (define-key map "\C-c\C-v" #'browse-url-of-buffer) (define-key map "\M-o" 'facemenu-keymap) map) "Keymap for commands for use in HTML mode.") @@ -2405,7 +2404,7 @@ html-mode (lambda () (char-before (match-end 0)))) (setq-local add-log-current-defun-function #'html-current-defun-name) (setq-local sentence-end-base "[.?!][]\"'”)}]*\\(<[^>]*>\\)*") - (add-hook 'completion-at-point-functions 'html-mode--complete-at-point nil t) + (add-hook 'completion-at-point-functions #'html-mode--complete-at-point nil t) (when (fboundp 'libxml-parse-html-region) (defvar css-class-list-function) @@ -2413,7 +2412,7 @@ html-mode (defvar css-id-list-function) (setq-local css-id-list-function #'html-current-buffer-ids)) - (setq imenu-create-index-function 'html-imenu-index) + (setq imenu-create-index-function #'html-imenu-index) (yank-media-handler 'text/html #'html-mode--html-yank-handler) (yank-media-handler "image/.*" #'html-mode--image-yank-handler) commit d78e670237bc735e0804a91b3cb4fc962317ad8a Author: Eli Zaretskii Date: Sat Jul 15 13:04:41 2023 +0300 ; * src/lisp.h: Improve commentary for XIL, XLI, XLP (bug#64645). diff --git a/src/lisp.h b/src/lisp.h index e8b9a795e3c..740e031e865 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -331,7 +331,14 @@ #define LISP_WORDS_ARE_POINTERS (EMACS_INT_MAX == INTPTR_MAX) see these functions for commentary. */ /* Convert among the various Lisp-related types: I for EMACS_INT, L - for Lisp_Object, P for void *. */ + for Lisp_Object, P for void *. + + These use the following mnemonics: + + XLI: Lisp_Object to Integer; + XIL: Integer to Lisp_Object; + XLP: Lisp_Object to Pointer. */ + #if !CHECK_LISP_OBJECT_TYPE # if LISP_WORDS_ARE_POINTERS # define lisp_h_XLI(o) ((EMACS_INT) (o)) commit 3cf2ab21f2c2fd5d8444d179ba1908d897b3eb25 Author: Eli Zaretskii Date: Sat Jul 15 12:49:09 2023 +0300 ; * src/comp.c (CALL0I): Ifdef away, as it's now unused. diff --git a/src/comp.c b/src/comp.c index 3c63cad18c7..1bde4ae5821 100644 --- a/src/comp.c +++ b/src/comp.c @@ -502,9 +502,11 @@ #define SECOND(x) \ #define THIRD(x) \ XCAR (XCDR (XCDR (x))) +#if 0 /* unused for now */ /* Like call0 but stringify and intern. */ #define CALL0I(fun) \ CALLN (Ffuncall, intern_c_string (STR (fun))) +#endif /* Like call1 but stringify and intern. */ #define CALL1I(fun, arg) \ commit 77fa417d108fbc4bb6b1017120eca958785becaa Merge: f2a8e4ceb48 d09de2f49d7 Author: Eli Zaretskii Date: Sat Jul 15 05:30:28 2023 -0400 Merge from origin/emacs-29 d09de2f49d7 Ignore quit while getting interprogram paste in kill-new afdf54a5313 * lisp/progmodes/gdb-mi.el: Fix interactive invocation of... b54febef5d7 Fix NetBSD build with and without ncurses c5fb7301599 ; * lisp/paren.el (show-paren-function): Fix last change ... ea696ea4b9a ; Fix last change. b0181dafb9e Improve documentation of 'enable-local-variables' in Emac... eb7c45ca43f ; Fix copy-paste in Widget Manual (Bug#64610) aedbc3006e1 ; * doc/misc/eshell.texi (Aliases): Remove stray "@end ta... 673992d28e2 ; * lisp/progmodes/sql.el (sql-interactive-mode): Remove ... commit f2a8e4ceb48c12a32cdc63931f9625a0df3c4ff6 Merge: 748d2ed5158 6a360b08405 Author: Eli Zaretskii Date: Sat Jul 15 05:30:28 2023 -0400 ; Merge from origin/emacs-29 The following commits were skipped: 6a360b08405 ; * doc/misc/eshell.texi (Variables): Add missing index f... f529bf52eb5 ; * doc/misc/eshell.texi (Invocation): Whitespace cleanup. 3a703545798 Add documentation about remote access in Eshell 7640835ae03 ; * doc/misc/eshell.texi: Fix last change. e79306fb467 ; * doc/misc/eshell.texi: Fix typos and clean up unclear ... 9f6d79dd967 Document some missing Eshell commands 951671b0e10 Document optional Eshell modules 7c417b2ae55 Correct the Eshell documentation about how to write new m... 6c3fe42bde1 Restructure Eshell extension modules documentation 4e204b56186 ; * doc/misc/eshell.texi (Bugs and ideas): Remove impleme... commit 748d2ed5158ebde03094aaf6956b39e5b96b70c7 Merge: d49669e5d3d 7ac947f34c7 Author: Eli Zaretskii Date: Sat Jul 15 05:30:14 2023 -0400 Merge from origin/emacs-29 7ac947f34c7 ; * src/lisp.h (struct Lisp_Overlay): Update commentary (... 9bc93c7996c Replace duplicate text from epa.texi by a reference 74cc1d27f1f Add basic usage information and fix references f24bdbfaf57 Add concept index, title-case structure titles 0165b50b0ff ; * lisp/emacs-lisp/lisp.el (raise-sexp): Fix typo in doc... 4cf33b6bd02 ; * doc/misc/modus-themes.org: Fix whitespace (bug#64548). 4821da1ad7f Fix show-paren-mode when the parentheses is partially vis... 419b4d44914 ; Improve documentation of with-restriction be34e8294af ; * admin/git-bisect-start: Update failing commits 8e06809fccd Merge branch 'scratch/bug64391' into emacs-29 dbac8076057 * lisp/net/tramp.el (tramp-get-buffer-string): Stabilize. 01fb898420f Simplify after adding internal function to enter a labele... b741dc7fcde Add internal function to enter a labeled restriction # Conflicts: # doc/misc/modus-themes.org commit d49669e5d3ddb80c6c722af1097a485ccc867bbe Merge: b5bbb29634e a82486e5a4e Author: Eli Zaretskii Date: Sat Jul 15 05:28:16 2023 -0400 ; Merge from origin/emacs-29 The following commit was skipped: a82486e5a4e Fix stale cache in Tramp (don't merge) commit b5bbb29634eca42582c01e2fd30c867d22f53298 Merge: a047fb8494c 01fb898420f Author: Eli Zaretskii Date: Sat Jul 15 05:28:16 2023 -0400 Merge from origin/emacs-29 01fb898420f Simplify after adding internal function to enter a labele... b741dc7fcde Add internal function to enter a labeled restriction commit d09de2f49d708f73e7397273a254a7775c294d05 Author: Spencer Baugh Date: Sat Jul 8 12:36:22 2023 -0400 Ignore quit while getting interprogram paste in kill-new On X, if the current selection owner is not responding to selection requests, the user may want to take ownership of the selection. The obvious way to do this is to kill some text (which a user might also be doing just as part of normal editing at the time the selection owner becomes nonresponsive). However, if save-interprogram-paste-before-kill is non-nil, then killing text will hang until the user quits, and this quit will abort the entire kill-new, preventing the user from taking ownership of the selection. Now instead if the user quits while we are attempting to retrieve the selection from hanging owner, we will proceed to take ownership of the selection as normal, resolving the problem. (One example of a selction owner that might not be responding to selection requests is another instance of Emacs itself; while Emacs is blocked in call-process or Lisp execution, it currently does not respond to selection requests.) * lisp/simple.el (kill-new): Ignore quit while getting interprogram paste (bug#64423) diff --git a/lisp/simple.el b/lisp/simple.el index 406f1008df3..65af1d02a1e 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5618,8 +5618,14 @@ kill-new (if (fboundp 'menu-bar-update-yank-menu) (menu-bar-update-yank-menu string (and replace (car kill-ring))))) (when save-interprogram-paste-before-kill - (let ((interprogram-paste (and interprogram-paste-function - (funcall interprogram-paste-function)))) + (let ((interprogram-paste + (and interprogram-paste-function + ;; On X, the selection owner might be slow, so the user might + ;; interrupt this. If they interrupt it, we want to continue + ;; so we become selection owner, so this doesn't stay slow. + (if (eq (window-system) 'x) + (ignore-error 'quit (funcall interprogram-paste-function)) + (funcall interprogram-paste-function))))) (when interprogram-paste (setq interprogram-paste (if (listp interprogram-paste) commit afdf54a5313ec898b6045e48eb6dce7d4abfa565 Author: Wang Diancheng Date: Fri Jul 14 11:06:32 2023 +0800 * lisp/progmodes/gdb-mi.el: Fix interactive invocation of 'gud-go'. Bug#64590. Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 4ad73823b64..d4e17554d94 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -988,7 +988,7 @@ gdb "\C-u" "Continue to current line or address.") (gud-def gud-go (progn - (when arg + (when (and current-prefix-arg arg) (gud-call (concat "-exec-arguments " (read-string "Arguments to exec-run: ")))) (gud-call commit a047fb8494c203bd8f416e7ee9f77ad8dcb03631 Author: Matthias Meulien Date: Thu Jul 13 22:47:01 2023 +0200 Fix "Improve Python imports management commands" * lisp/progmodes/python.el (python--list-imports): Prefer to use an exit status >1. (python--list-imports-check-status): New function to check status of Python script. (python--do-isort): Fix wrong status check introduced with 6295d7abdd4. (Bug#64406) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 4291ab03ca6..a23339a2180 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -6451,9 +6451,9 @@ python--list-imports try: from isort import find_imports_in_stream, find_imports_in_paths except ModuleNotFoundError: - exit(1) -except ImportError: exit(2) +except ImportError: + exit(3) query, files, result = argv[1] or None, argv[2:], {} @@ -6484,6 +6484,17 @@ python--import-sources (project-files proj)) (list default-directory))) +(defun python--list-imports-check-status (status) + (unless (eq 0 status) + (let* ((details + (cond + ((eq 2 status) " (maybe isort is missing?)") + ((eq 3 status) " (maybe isort version is older than 5.7.0?)") + (t ""))) + (msg + (concat "%s exited with status %s" details))) + (error msg python-interpreter status)))) + (defun python--list-imports (name source) "List all Python imports matching NAME in SOURCE. If NAME is nil, list all imports. SOURCE can be a buffer or a @@ -6507,13 +6518,7 @@ python--list-imports (or name "") (mapcar #'file-local-name source))))) lines) - (cond - ((eq 1 status) - (error "%s exited with status %s (maybe isort is missing?)" - python-interpreter status)) - ((eq 2 status) - (error "%s exited with status %s (maybe isort version is <5.7.0?)" - python-interpreter status))) + (python--list-imports-check-status status) (goto-char (point-min)) (while (not (eobp)) (push (buffer-substring-no-properties (point) (pos-eol)) @@ -6556,13 +6561,9 @@ python--do-isort nil (list temp nil) nil "-m" "isort" "-" args)) (tick (buffer-chars-modified-tick))) - (cond - ((eq 1 status) + (unless (eq 0 status) (error "%s exited with status %s (maybe isort is missing?)" python-interpreter status)) - ((eq 2 status) - (error "%s exited with status %s (maybe isort version is <5.7.0?)" - python-interpreter status))) (replace-buffer-contents temp) (not (eq tick (buffer-chars-modified-tick))))))))) commit b54febef5d735efdc907c5e5cd016bed74e338a8 Author: Valtteri Vuorikoski Date: Thu Jul 13 12:35:51 2023 +0300 Fix NetBSD build with and without ncurses * configure.ac (netbsd): Don't set TERMINFO=no unless the termcap library is either -ltermcap or -lcurses. This prevents aborts because on recent versions of NetBSD libtermcap is actually a symlink to libterminfo. (Bug#64577) Copyright-paperwork-exempt: yes diff --git a/configure.ac b/configure.ac index 19575e80cf4..df74f8cd2f8 100644 --- a/configure.ac +++ b/configure.ac @@ -5212,7 +5212,11 @@ AC_DEFUN ;; netbsd) - if test "x$LIBS_TERMCAP" != "x-lterminfo"; then + # NetBSD versions prior to 6.0 lack native terminfo, but have a + # tputs() built on top of termcap in these libraries. Use native + # termcap instead in this case. NetBSD >= 6.0 has native terminfo + # implementation in -lterminfo. + if test "x$LIBS_TERMCAP" = "x-ltermcap" -o "x$LIBS_TERMCAP" = "x-lcurses"; then TERMINFO=no LIBS_TERMCAP="-ltermcap" fi commit 300f9d23c13232cf20978aa619c3758ad49fa184 Author: Spencer Baugh Date: Sun Jul 9 12:16:28 2023 -0400 ; Fix last change (bug#64533) * lisp/progmodes/which-func.el (which-func-display): Fix quoting in the doc string. * etc/NEWS: Announce 'which-func-display'. diff --git a/etc/NEWS b/etc/NEWS index d7f5fdc4cbb..3cfc36e10da 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -264,6 +264,13 @@ docstring, or a comment, or (re)indents the surrounding defun if point is not in a comment or a string. It is by default bound to 'M-q' in 'prog-mode' and all its descendants. ++++ +*** Which Function Mode can now display function names on the header line. +The new user option 'which-func-display' allows choosing where the +function name is displayed. The default is 'mode' to display in the +mode line. 'header' will display in the header line; +'mode-and-header' displays in both the header line and mode line. + ** Tramp +++ diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el index 631d47bb729..09d0250515f 100644 --- a/lisp/progmodes/which-func.el +++ b/lisp/progmodes/which-func.el @@ -89,8 +89,8 @@ which-func-non-auto-modes (defcustom which-func-display 'mode "Where to display the function name. -If 'mode, display in the mode line. If 'header, display in the -header line. If 'mode-and-header, display in both." +If `mode', display in the mode line. If `header', display in the +header line. If `mode-and-header', display in both." :type '(choice (const :tag "Display in mode line" mode) (const :tag "Display in header line" header) (const :tag "Display in both header and mode line" commit dcad72a779bc4d5d8878c53b4b8bee13e316c9b4 Author: Spencer Baugh Date: Sun Jul 9 12:16:28 2023 -0400 Support displaying function name in the header line In some languages, the function name as displayed in the mode-line by which-func-mode can be quite long. It's useful to be able to display it in the header-line instead. Let's support that. * lisp/progmodes/which-func.el (which-func-display) (which-func--use-header-line, which-func--use-mode-line): Add. (Bug#64533) (which-func-try-to-enable): Support 'which-func--use-header-line'. (which-func--disable): Add, to support 'which-func--use-header-line'. (which-func-ff-hook, which-func-update-1): Use 'which-func--disable'. diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index 953de2e4786..40746e03ecc 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -396,8 +396,8 @@ Which Function @cindex current function name in mode line Which Function mode is a global minor mode (@pxref{Minor Modes}) -which displays the current function name in the mode line, updating it -as you move around in a buffer. +which displays the current function name in the mode line or header +line, updating it as you move around in a buffer. @findex which-function-mode @vindex which-func-modes @@ -410,6 +410,12 @@ Which Function @code{t} (which means to support all available major modes) to a list of major mode names. +@vindex which-func-display + By default, Which Function mode displays the current function name +using the mode line. Customize @code{which-func-display} to +@code{header}, @code{mode}, or @code{mode-and-header} to use the +header line, mode line, or both, respectively. + @node Program Indent @section Indentation for Programs @cindex indentation for programs diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el index 09937a60988..631d47bb729 100644 --- a/lisp/progmodes/which-func.el +++ b/lisp/progmodes/which-func.el @@ -86,6 +86,17 @@ which-func-non-auto-modes activation of Which Function until Imenu is used for the first time." :type '(repeat (symbol :tag "Major mode"))) +(defcustom which-func-display 'mode + "Where to display the function name. + +If 'mode, display in the mode line. If 'header, display in the +header line. If 'mode-and-header, display in both." + :type '(choice (const :tag "Display in mode line" mode) + (const :tag "Display in header line" header) + (const :tag "Display in both header and mode line" + mode-and-header)) + :version "30.1") + (defcustom which-func-maxout 500000 "Don't automatically compute the Imenu menu if buffer is this big or bigger. Zero means compute the Imenu menu regardless of size. @@ -184,17 +195,35 @@ which-func-current ;;;###autoload (put 'which-func-current 'risky-local-variable t) (defvar-local which-func-mode nil - "Non-nil means display current function name in mode line. + "Non-nil means display current function name in mode or header line. This makes a difference only if variable `which-function-mode' is non-nil.") +(defvar-local which-func--use-header-line nil + "If non-nil, display the function name in the header line.") + +(defvar-local which-func--use-mode-line nil + "If non-nil, display the function name in the mode line.") + (add-hook 'after-change-major-mode-hook #'which-func-ff-hook t) (defun which-func-try-to-enable () (unless (or (not which-function-mode) (local-variable-p 'which-func-mode)) (setq which-func-mode (or (eq which-func-modes t) - (member major-mode which-func-modes))))) + (member major-mode which-func-modes))) + (setq which-func--use-mode-line + (member which-func-display '(mode mode-and-header))) + (setq which-func--use-header-line + (member which-func-display '(header mode-and-header))) + (when (and which-func-mode which-func--use-header-line) + (add-to-list 'header-line-format '("" which-func-format " "))))) + +(defun which-func--disable () + (when (and which-func-mode which-func--use-header-line) + (setq header-line-format + (delete '("" which-func-format " ") header-line-format))) + (setq which-func-mode nil)) (defun which-func-ff-hook () "`after-change-major-mode-hook' for Which Function mode. @@ -210,10 +239,10 @@ which-func-ff-hook (setq imenu--index-alist (save-excursion (funcall imenu-create-index-function)))) (imenu-unavailable - (setq which-func-mode nil)) + (which-func--disable)) (error (message "which-func-ff-hook error: %S" err) - (setq which-func-mode nil)))) + (which-func--disable)))) (defun which-func-update () "Update the Which-Function mode display in the current window." @@ -231,7 +260,7 @@ which-func-update-1 (puthash window current which-func-table) (force-mode-line-update))) (error - (setq which-func-mode nil) + (which-func--disable) (error "Error in which-func-update: %S" info)))))) (defvar which-func-update-timer nil) @@ -241,7 +270,8 @@ which-func-update-timer (add-to-list 'mode-line-misc-info '(which-function-mode ;Only display if mode is enabled. (which-func-mode ;Only display if buffer supports it. - ("" which-func-format " "))))) + (which-func--use-mode-line + ("" which-func-format " ")))))) ;; This is the name people would normally expect. ;;;###autoload commit 3021a0656f31c03ebfcaf535e54605c76acf23b6 Author: Łukasz Stelmach Date: Tue Jun 13 13:26:39 2023 +0200 Show SHA-256 digest of a public key in 'nsm-format-certificate' * lisp/net/nsm.el (nsm-format-certificate): Show public key digest (SHA-256 if available). Displaying the digest enables users to verify the certificate with other tools like 'gnutls-cli' which present much more detailed information. * src/gnutls (emacs_gnutls_certificate_details): Export SHA-256 public key digest if supported by GnuTLS. (Bug#64043) diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index dc04bf50c24..7cbeb48f5be 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -1030,10 +1030,14 @@ nsm-format-certificate " Hostname:" (nsm-certificate-part (plist-get cert :subject) "CN" t) "\n") (when (and (plist-get cert :public-key-algorithm) - (plist-get cert :signature-algorithm)) + (plist-get cert :signature-algorithm) + (or (plist-get cert :public-key-id-sha256) + (plist-get cert :public-key-id))) (insert " Public key:" (plist-get cert :public-key-algorithm) - ", signature: " (plist-get cert :signature-algorithm) "\n")) + ", signature: " (plist-get cert :signature-algorithm) "\n" + " Public key ID:" (or (plist-get cert :public-key-id-sha256) + (plist-get cert :public-key-id)) "\n")) (when (and (plist-get status :key-exchange) (plist-get status :cipher) (plist-get status :mac) diff --git a/src/gnutls.c b/src/gnutls.c index 8f0e2d01703..e3f1093d977 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -51,6 +51,10 @@ # define HAVE_GNUTLS_ETM_STATUS # endif +# if GNUTLS_VERSION_NUMBER >= 0x030401 +# define HAVE_GNUTLS_KEYID_USE_SHA256 +# endif + # if GNUTLS_VERSION_NUMBER < 0x030600 # define HAVE_GNUTLS_COMPRESSION_GET # endif @@ -1278,6 +1282,23 @@ emacs_gnutls_certificate_details (gnutls_x509_crt_t cert) xfree (buf); } +#ifdef HAVE_GNUTLS_KEYID_USE_SHA256 + /* Public key ID, SHA-256 version. */ + buf_size = 0; + err = gnutls_x509_crt_get_key_id (cert, GNUTLS_KEYID_USE_SHA256, NULL, &buf_size); + check_memory_full (err); + if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) + { + void *buf = xmalloc (buf_size); + err = gnutls_x509_crt_get_key_id (cert, GNUTLS_KEYID_USE_SHA256, buf, &buf_size); + check_memory_full (err); + if (err >= GNUTLS_E_SUCCESS) + res = nconc2 (res, list2 (intern (":public-key-id-sha256"), + gnutls_hex_string (buf, buf_size, "sha256:"))); + xfree (buf); + } +#endif + /* Certificate fingerprint. */ buf_size = 0; err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1, commit c5fb7301599dc249a877ce65175f2dbc3355b2ec Author: Eli Zaretskii Date: Sat Jul 15 10:21:07 2023 +0300 ; * lisp/paren.el (show-paren-function): Fix last change (bug#64547). diff --git a/lisp/paren.el b/lisp/paren.el index 54a2c23f17f..6296d7e67fa 100644 --- a/lisp/paren.el +++ b/lisp/paren.el @@ -515,10 +515,9 @@ show-paren-function ;; ...or partially visible, and the ;; invisible part is less than 1/4th ;; of the default font height - (or (< (length part) 4) - (and + (and (>= (length part) 4) (< (nth 2 part) dfh4) - (< (nth 3 part) dfh4))))))) + (< (nth 3 part) dfh4)))))) (let ((context (blink-paren-open-paren-line-string openparen)) (message-log-max nil)) commit ea696ea4b9a9e8bc059e4bdb4cdbb935bf7f12f0 Author: Eli Zaretskii Date: Fri Jul 14 20:33:29 2023 +0300 ; Fix last change. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 9bbef7dd508..e56b1fe964c 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1350,10 +1350,10 @@ Safe File Variables which specifies the behavior described above. If it is @code{nil}, Emacs simply ignores all file local variables. @code{:safe} means use only the safe values and ignore the rest. @code{:all} instructs Emacs -to set all file local variables (we advise not to use it permanently). -Any other value says to query you about each file that has local -variables, without trying to determine whether the values are known to -be safe. +to set all file local variables regardless of whether their value is +safe or not (we advise not to use this permanently). Any other value +says to query you about each file that has local variables, without +trying to determine whether the values are known to be safe. @vindex enable-local-eval @vindex safe-local-eval-forms commit b0181dafb9ee9eb6786128e44a5a4164de1ae8c2 Author: YugaEgo Date: Fri Jul 14 18:49:36 2023 +0300 Improve documentation of 'enable-local-variables' in Emacs manual * doc/emacs/custom.texi (Safe File Variables): Document ':all'. (Bug#64621) diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 87290734cc9..9bbef7dd508 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1349,9 +1349,11 @@ Safe File Variables way Emacs processes local variables. Its default value is @code{t}, which specifies the behavior described above. If it is @code{nil}, Emacs simply ignores all file local variables. @code{:safe} means use -only the safe values and ignore the rest. Any other value says to -query you about each file that has local variables, without trying to -determine whether the values are known to be safe. +only the safe values and ignore the rest. @code{:all} instructs Emacs +to set all file local variables (we advise not to use it permanently). +Any other value says to query you about each file that has local +variables, without trying to determine whether the values are known to +be safe. @vindex enable-local-eval @vindex safe-local-eval-forms commit eb7c45ca43f3cd30a03898f36dfb6a4afb6106ec Author: Mauro Aranda Date: Fri Jul 14 07:41:58 2023 -0300 ; Fix copy-paste in Widget Manual (Bug#64610) diff --git a/doc/misc/widget.texi b/doc/misc/widget.texi index 4ac57a95a43..13b37ab5b54 100644 --- a/doc/misc/widget.texi +++ b/doc/misc/widget.texi @@ -1600,9 +1600,7 @@ Defining New Widgets @item :value-to-external Function to convert the value to the external format. The function takes two arguments, a widget and an internal value, and returns the -external value. The function is called on the present @code{:value} -when the widget is created, and on any value set later with -@code{widget-value-set}. +external value. @vindex create@r{ keyword} @item :create commit aedbc3006e13722fe0ab55a1e2fee1eb43dbd96c Author: Eli Zaretskii Date: Fri Jul 14 08:32:57 2023 +0300 ; * doc/misc/eshell.texi (Aliases): Remove stray "@end table". diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 73cb2a2a7ed..e659adfe83d 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -1053,8 +1053,6 @@ Aliases @kbd{alias mcd 'mkdir $1 && cd $1'} would cause @kbd{mcd foo} to create and switch to a directory called @samp{foo}. -@end table - @node Remote Access @section Remote Access @cmindex remote access commit 673992d28e2b8d3502c015c7c1b800332e268a62 Author: YugaEgo Date: Thu Jul 13 22:50:27 2023 +0300 ; * lisp/progmodes/sql.el (sql-interactive-mode): Remove FIXME (bug#64602). diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index c6667c075f6..89d62ab3a61 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@ -4200,7 +4200,7 @@ sql-mode (put 'sql-interactive-mode 'mode-class 'special) (put 'sql-interactive-mode 'custom-mode-group 'SQL) -;; FIXME: Why not use `define-derived-mode'? + (define-derived-mode sql-interactive-mode comint-mode "SQLi[?]" "Major mode to use a SQL interpreter interactively. commit 6a360b08405daa2d6f30f497c9f0315f4c5baf67 Author: Jim Porter Date: Thu Jul 13 09:10:57 2023 -0700 ; * doc/misc/eshell.texi (Variables): Add missing index for $INSIDE_EMACS Do not merge to master. On master, this was fixed by 0bb8a011d57. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 9141063408b..73cb2a2a7ed 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -1019,6 +1019,7 @@ Variables copied to the environment, so external commands invoked from Eshell can consult them to do the right thing. +@vindex $INSIDE_EMACS @item $INSIDE_EMACS This variable indicates to external commands that they are being invoked from within Emacs so they can adjust their behavior if commit f529bf52eb5fcec7377307ac94ad3191156019b0 Author: Michael Albinus Date: Tue Jul 11 12:18:31 2023 +0200 ; * doc/misc/eshell.texi (Invocation): Whitespace cleanup. Do not merge to master. This is a backport of 04710bd01b2. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index e05c1fc5baa..9141063408b 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -267,7 +267,7 @@ Invocation @vindex eshell-prefer-lisp-functions If you would prefer to use ordinary Lisp functions over external programs, set the option @code{eshell-prefer-lisp-functions} to -@code{t}. This will swap the lookup order of the last two items. You +@code{t}. This will swap the lookup order of the last two items. You can also force Eshell to look for a command as an external program by prefixing its name with @kbd{*}, like @code{*@var{command}} (@pxref{Built-ins}). commit 3a70354579819f883032fbf862d95f9f17649719 Author: Jim Porter Date: Sun Jul 9 12:04:01 2023 -0700 Add documentation about remote access in Eshell Do not merge to master. This is a backport of 438921161ac. * doc/misc/eshell.texi (Invocation): Mention the '*' prefix. (Remote Access): New section... (Commands): ... link to it. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 3d859124b50..e05c1fc5baa 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -207,6 +207,7 @@ Commands * Built-ins:: * Variables:: * Aliases:: +* Remote Access:: * History:: * Completion:: * Control Flow:: @@ -266,7 +267,10 @@ Invocation @vindex eshell-prefer-lisp-functions If you would prefer to use ordinary Lisp functions over external programs, set the option @code{eshell-prefer-lisp-functions} to -@code{t}. This will swap the lookup order of the last two items. +@code{t}. This will swap the lookup order of the last two items. You +can also force Eshell to look for a command as an external program by +prefixing its name with @kbd{*}, like @code{*@var{command}} +(@pxref{Built-ins}). You can also group command forms together into a subcommand with curly braces (@code{@{@}}). This lets you use the output of a subcommand as @@ -1048,6 +1052,33 @@ Aliases @kbd{alias mcd 'mkdir $1 && cd $1'} would cause @kbd{mcd foo} to create and switch to a directory called @samp{foo}. +@end table + +@node Remote Access +@section Remote Access +@cmindex remote access + +Since Eshell uses Emacs facilities for most of its functionality, you +can access remote hosts transparently. To connect to a remote host, +simply @code{cd} into it: + +@example +~ $ cd /ssh:user@@remote: +/ssh:user@@remote:~ $ +@end example + +Additionally, built-in Eshell commands (@pxref{Built-ins}) and +ordinary Lisp functions accept remote file names, so you can access +them even without explicitly connecting first. For example, to print +the contents of a remote file, you could type @samp{cat +/ssh:user@@remote:~/output.log}. However, this means that when using +built-in commands or Lisp functions from a remote directory, you must +be careful about specifying absolute file names: @samp{cat +/var/output.log} will always print the contents of your @emph{local} +@file{/var/output.log}, even from a remote directory. If you find +this behavior annoying, you can enable the optional electric forward +slash module (@pxref{Electric forward slash}). + @node History @section History @cmindex history commit 7640835ae036560dbe4cda4b39f60c20dfc8c57d Author: Jim Porter Date: Sat Jul 8 12:13:22 2023 -0700 ; * doc/misc/eshell.texi: Fix last change. Do not merge to master. This is a backport of 8c5fef4eb30. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 9b87cc44647..3d859124b50 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -338,7 +338,7 @@ Arguments Inside of double quotes, most characters have no special meaning. However, @samp{\}, @samp{"}, and @samp{$} are still special; to escape them, use backslash as above. Thus, if the value of the variable -@var{answer} is @code{42}, then @code{"The answer is: \"$answer\""} +@var{answer} is @code{42}, then @code{"The answer is: \"$@var{answer}\""} returns the string @code{The answer is: "42"}. However, when escaping characters with no special meaning, the result is the full @code{\@var{c}} sequence. For example, @code{"foo\bar"} means the @@ -2073,12 +2073,12 @@ Extra built-in commands @item ff @cmindex ff Shorthand for the the function @code{find-name-dired} (@pxref{Dired -and Find, , , elisp, The Emacs Lisp Reference Manual}). +and Find, , , emacs, The Emacs Editor}). @item gf @cmindex gf Shorthand for the the function @code{find-grep-dired} (@pxref{Dired -and Find, , , elisp, The Emacs Lisp Reference Manual}). +and Find, , , emacs, The Emacs Editor}). @item intersection @cmindex intersection commit e79306fb467e02ddfc10cad312600771e9b17a3f Author: Jim Porter Date: Fri Jul 7 18:19:08 2023 -0700 ; * doc/misc/eshell.texi: Fix typos and clean up unclear wording. Do not merge to master. This is a backport of 118582efb30. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 58b8e4365d9..9b87cc44647 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -65,10 +65,10 @@ Top Eshell is a shell-like command interpreter implemented in Emacs Lisp. It invokes no external processes except for those requested by the user. It is intended to be an alternative to the IELM (@pxref{Lisp -Interaction, Emacs Lisp Interaction, , emacs, The Emacs Editor}) -REPL@footnote{Short for ``Read-Eval-Print Loop''.} for Emacs -@emph{and} with an interface similar to command shells such as -@command{bash}, @command{zsh}, @command{rc}, or @command{4dos}. +Interaction, , , emacs, The Emacs Editor}) REPL@footnote{Short for +``Read-Eval-Print Loop''.} for Emacs @emph{and} with an interface +similar to command shells such as @command{bash}, @command{zsh}, +@command{rc}, or @command{4dos}. @c This manual is updated to release 2.4 of Eshell. @insertcopying @@ -217,7 +217,7 @@ Invocation @section Invocation Eshell is both a command shell and an Emacs Lisp @acronym{REPL}. As a result, you can invoke commands in two different ways: in @dfn{command -form} or in @dfn{lisp form}. +form} or in @dfn{Lisp form}. You can use the semicolon (@code{;}) to separate multiple command invocations on a single line, executing each in turn. You can also @@ -313,9 +313,9 @@ Arguments (1 2 3) @end example -Additionally, many built-in Eshell commands (@pxref{Built-ins, Eshell -commands}) will flatten the arguments they receive, so passing a list -as an argument will ``spread'' the elements into multiple arguments: +Additionally, many built-in Eshell commands (@pxref{Built-ins}) will +flatten the arguments they receive, so passing a list as an argument +will ``spread'' the elements into multiple arguments: @example ~ $ printnl (list 1 2) 3 @@ -393,17 +393,20 @@ Arguments @item # Return the process named @var{name}. This is equivalent to -@samp{$(get-process "@var{name}")} (@pxref{Process Information, , , +@samp{$(get-process "@var{name}")} (@pxref{Process Information, , , elisp, The Emacs Lisp Reference Manual}). @end table @node Built-ins @section Built-in commands -Several commands are built-in in Eshell. In order to call the -external variant of a built-in command @code{foo}, you could call -@code{*foo}. Usually, this should not be necessary. You can check -what will be applied by the @code{which} command: +Eshell provides a number of built-in commands, many of them +implementing common command-line utilities, but enhanced for Eshell. +(These built-in commands are just ordinary Lisp functions whose names +begin with @code{eshell/}.) In order to call the external variant of +a built-in command @code{foo}, you could call @code{*foo}. Usually, +this should not be necessary. You can check what will be applied by +the @code{which} command: @example ~ $ which ls @@ -1015,7 +1018,9 @@ Variables @item $INSIDE_EMACS This variable indicates to external commands that they are being invoked from within Emacs so they can adjust their behavior if -necessary. Its value is @code{@var{emacs-version},eshell}. +necessary. By default, its value is +@code{@var{emacs-version},eshell}. Other parts of Emacs, such as +Tramp, may add extra information to this value. @end table @@ -1097,11 +1102,11 @@ Completion for the built-in functions and some common external commands, and you can define your own for any command. -Eshell completion also works for lisp forms and glob patterns. If the point is -on a lisp form, then @key{TAB} will behave similarly to completion in -@code{elisp-mode} and @code{lisp-interaction-mode}. For glob patterns, the -pattern will be removed from the input line, and replaced by the -completion. +Eshell completion also works for Lisp forms and glob patterns. If the +point is on a Lisp form, then @key{TAB} will behave similarly to +completion in @code{elisp-mode} and @code{lisp-interaction-mode}. For +glob patterns, the pattern will be removed from the input line, and +replaced by the completion. If you want to see the entire list of possible completions (e.g. when it's below the @code{completion-cycle-threshold}), press @kbd{M-?}. @@ -1120,7 +1125,7 @@ Completion @node Control Flow @section Control Flow -Because Eshell commands can not (easily) be combined with lisp forms, +Because Eshell commands can not (easily) be combined with Lisp forms, Eshell provides command-oriented control flow statements for convenience. @@ -1272,8 +1277,8 @@ Dollars Expansion @item a sequence Expands to the element at the (zero-based) index @var{i} of the -sequence (@pxref{Sequences Arrays Vectors, Sequences, , elisp, The -Emacs Lisp Reference Manual}). +sequence (@pxref{Sequences Arrays Vectors, , , elisp, The Emacs Lisp +Reference Manual}). @item a string Split the string at whitespace, and then expand to the @var{i}th @@ -1325,8 +1330,8 @@ Globbing systems. You can control this behavior via the @code{eshell-glob-case-insensitive} option. You can further customize the syntax and behavior of globbing in Eshell via the Customize group -``eshell-glob'' (@pxref{Easy Customization, , , emacs, The GNU Emacs -Manual}). +@code{eshell-glob} (@pxref{Easy Customization, , , emacs, The GNU +Emacs Manual}). @table @samp @@ -1424,7 +1429,7 @@ Argument Predication and Modification @code{[@dots{}]}, @code{<@dots{}>}, or @code{@{@dots{}@}}. You can customize the syntax and behavior of predicates and modifiers -in Eshell via the Customize group ``eshell-pred'' (@pxref{Easy +in Eshell via the Customize group @code{eshell-pred} (@pxref{Easy Customization, , , emacs, The GNU Emacs Manual}). @menu @@ -1720,26 +1725,26 @@ Redirection Redirect output to @var{dest}, appending it to the existing contents of @var{dest}. -@item >>> @var{buffer} -@itemx @var{fd}>>> @var{buffer} +@item >>> @var{dest} +@itemx @var{fd}>>> @var{dest} Redirect output to @var{dest}, inserting it at the current mark if @var{dest} is a buffer, at the beginning of the file if @var{dest} is a file, or otherwise behaving the same as @code{>>}. -@item &> @var{file} -@itemx >& @var{file} +@item &> @var{dest} +@itemx >& @var{dest} Redirect both standard output and standard error to @var{dest}, overwriting its contents with the new output. -@item &>> @var{file} -@itemx >>& @var{file} +@item &>> @var{dest} +@itemx >>& @var{dest} Redirect both standard output and standard error to @var{dest}, appending it to the existing contents of @var{dest}. -@item &>>> @var{file} -@itemx >>>& @var{file} +@item &>>> @var{dest} +@itemx >>>& @var{dest} Redirect both standard output and standard error to @var{dest}, -inserting it like with @code{>>> @var{file}}. +inserting it like with @code{>>> @var{dest}}. @item >&@var{other-fd} @itemx @var{fd}>&@var{other-fd} @@ -2365,10 +2370,6 @@ Bugs and ideas @item Support zsh's ``Parameter Expansion'' syntax, i.e., @samp{$@{@var{name}:-@var{val}@}} -@item Write an @command{info} alias that can take arguments - -So that the user can enter @samp{info chmod}, for example. - @item Create a mode @code{eshell-browse} It would treat the Eshell buffer as an outline. Collapsing the outline commit 9f6d79dd967294317aa51801c5edaaf30f644120 Author: Jim Porter Date: Fri Jul 7 17:30:26 2023 -0700 Document some missing Eshell commands Do not merge to master. This is a backport of f7a899d7ca0. * doc/misc/eshell.texi (Built-ins): Document 'eshell-debug'. (Extra built-in commands): Document 'count', 'ff', and 'gf'. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 9680d246af9..58b8e4365d9 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -575,6 +575,14 @@ Built-ins command does not yet support running commands with a modified environment. +@item eshell-debug +@cmindex eshell-debug +Toggle debugging information for Eshell itself. You can pass this +command the argument @code{errors} to enable/disable Eshell trapping +errors when evaluating commands, or the argument @code{commands} to +show/hide command execution progress in the buffer @code{*eshell last +cmd*}. + @item exit @cmindex exit Exit Eshell and save the history. By default, this command kills the @@ -2046,11 +2054,27 @@ Extra built-in commands @table @code +@item count +@cmindex count +A wrapper around the function @code{cl-count} (@pxref{Searching +Sequences,,, cl, GNU Emacs Common Lisp Emulation}). This command can +be used for comparing lists of strings. + @item expr @cmindex expr An implementation of @command{expr} using the Calc package. @xref{Top,,, calc, The GNU Emacs Calculator}. +@item ff +@cmindex ff +Shorthand for the the function @code{find-name-dired} (@pxref{Dired +and Find, , , elisp, The Emacs Lisp Reference Manual}). + +@item gf +@cmindex gf +Shorthand for the the function @code{find-grep-dired} (@pxref{Dired +and Find, , , elisp, The Emacs Lisp Reference Manual}). + @item intersection @cmindex intersection A wrapper around the function @code{cl-intersection} (@pxref{Lists as commit 951671b0e106a921154aff879d04969df9045dc4 Author: Jim Porter Date: Fri May 12 20:03:48 2023 -0700 Document optional Eshell modules Do not merge to master. This is a backport of 77f13edab0f. * doc/misc/eshell.texi (Built-ins): Move disabled-by-default commands to... (Tramp extensions, Extra built-in commands): ...here (Optional modules, Key rebinding, Smart scrolling): Add documentation. (Bug and ideas): Documentation is no longer incomplete! diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index cff7c594d96..9680d246af9 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -586,14 +586,6 @@ Built-ins Set environment variables using input like Bash's @command{export}, as in @samp{export @var{var1}=@var{val1} @var{var2}=@var{val2} @dots{}}. -@item expr -@cmindex expr -An implementation of @command{expr} using the Calc package. -@xref{Top,,, calc, The GNU Emacs Calculator}. - -This command can be loaded as part of the eshell-xtra module, which is -disabled by default. - @item grep @cmindex grep @itemx agrep @@ -626,15 +618,6 @@ Built-ins reader. @xref{Misc Help, , , emacs, The GNU Emacs Manual}. -@item intersection -@cmindex intersection -A wrapper around the function @code{cl-intersection} (@pxref{Lists as -Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command -can be used for comparing lists of strings. - -This command can be loaded as part of the eshell-xtra module, which is -disabled by default. - @item jobs @cmindex jobs List subprocesses of the Emacs process, if any, using the function @@ -704,15 +687,6 @@ Built-ins Display Man pages using the Emacs @code{man} command. @xref{Man Page, , , emacs, The GNU Emacs Manual}. -@item mismatch -@cmindex mismatch -A wrapper around the function @code{cl-mismatch} (@pxref{Searching -Sequences,,, cl, GNU Emacs Common Lisp Emulation}). This command can -be used for comparing lists of strings. - -This command can be loaded as part of the eshell-xtra module, which is -disabled by default. - @item mkdir @cmindex mkdir Make new directories. @@ -769,24 +743,6 @@ Built-ins @cmindex rmdir Removes directories if they are empty. -@item set-difference -@cmindex set-difference -A wrapper around the function @code{cl-set-difference} (@pxref{Lists as -Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command -can be used for comparing lists of strings. - -This command can be loaded as part of the eshell-xtra module, which is -disabled by default. - -@item set-exclusive-or -@cmindex set-exclusive-or -A wrapper around the function @code{cl-set-exclusive-or} (@pxref{Lists -as Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command can be -used for comparing lists of strings. - -This command can be loaded as part of the eshell-xtra module, which is -disabled by default. - @item set @cmindex set Set variable values, using the function @code{set} like a command @@ -806,27 +762,6 @@ Built-ins confused with the command @command{.}, which sources a file in the current environment. -@item su -@cmindex su -@itemx sudo -@cmindex sudo -@itemx doas -@cmindex doas -Uses TRAMP's @command{su}, @command{sudo}, or @command{doas} method -@pxref{Inline methods, , , tramp} to run a command via @command{su}, -@command{sudo}, or @command{doas}. These commands are in the -eshell-tramp module, which is disabled by default. - - -@item substitute -@cmindex substitute -A wrapper around the function @code{cl-substitute} (@pxref{Sequence -Functions,,, cl, GNU Emacs Common Lisp Emulation}). This command can -be used for comparing lists of strings. - -This command can be loaded as part of the eshell-xtra module, which is -disabled by default. - @item time @cmindex time Show the time elapsed during a command's execution. @@ -836,15 +771,6 @@ Built-ins Set or view the default file permissions for newly created files and directories. -@item union -@cmindex union -A wrapper around the function @code{cl-union} (@pxref{Lists as Sets,,, -cl, GNU Emacs Common Lisp Emulation}). This command can be used for -comparing lists of strings. - -This command can be loaded as part of the eshell-xtra module, which is -disabled by default. - @item unset @cmindex unset Unset one or more variables. As with @command{set}, a variable name @@ -1957,7 +1883,10 @@ Extension modules @node Optional modules @section Optional modules -This section is not yet written. +In addition to the various modules enabled by default (documented +above), Eshell provides several other modules which are @emph{not} +enabled by default. If you want to enable these, you can add them to +@code{eshell-modules-list}. @menu * Key rebinding:: @@ -1970,12 +1899,66 @@ Optional modules @node Key rebinding @subsection Key rebinding -This section is not yet written. +This module allows for special keybindings that only take effect +while the point is in a region of input text. The default keybindings +mimic the bindings used in other shells when the user is editing new +input text. To enable this module, add @code{eshell-rebind} to +@code{eshell-modules-list}. + +For example, it binds @kbd{C-a} to move to the beginning of the input +text, @kbd{C-u} to kill the current input text, and @kbd{C-w} to +@code{backward-kill-word}. If the history module is enabled, it also +binds @kbd{C-p} and @kbd{C-n} to move through the input history. + +If @code{eshell-confine-point-to-input} is non-@code{nil}, this module +prevents certain commands from causing the point to leave the input +area, such as @code{backward-word}, @code{previous-line}, etc. @node Smart scrolling @subsection Smart scrolling -This section is not yet written. +This module combines the facility of normal, modern shells with some +of the edit/review concepts inherent in the design of Plan 9's 9term. +To enable it, add @code{eshell-smart} to @code{eshell-modules-list}. + +@itemize @bullet +@item +When you invoke a command, it is assumed that you want to read the +output of that command. + +@item +If the output is not what you wanted, it is assumed that you will want +to edit, and then resubmit a refined version of that command. + +@item +If the output is valid, pressing any self-inserting character key will +jump to end of the buffer and insert that character, in order to begin +entry of a new command. + +@item +If you show an intention to edit the previous command -- by moving +around within it -- then the next self-inserting characters will +insert *there*, instead of at the bottom of the buffer. + +@item +If you show an intention to review old commands, such as @kbd{M-p} or +@kbd{M-r}, point will jump to the bottom of the buffer before invoking +that command. + +@item +If none of the above has happened yet (i.e.@: your point is just +sitting on the previous command), you can use @kbd{SPC} and +@kbd{BACKSPACE} (or @kbd{Delete}) to page forward and backward +@emph{through the output of the last command only}. It will constrain +the movement of the point and window so that the maximum amount of +output is always displayed at all times. + +@item +While output is being generated from a command, the window will be +constantly reconfigured (until it would otherwise make no difference) +in order to always show you the most output from the command possible. +This happens if you change window sizes, scroll, etc. +@end itemize @node Electric forward slash @subsection Electric forward slash @@ -2035,12 +2018,76 @@ Electric forward slash @node Tramp extensions @subsection Tramp extensions -This section is not yet written. +This module adds built-in commands that use Tramp to handle running +other commands as different users, replacing the corresponding +external commands. To enable it, add @code{eshell-tramp} to +@code{eshell-modules-list}. -@node Extra built-in functions -@subsection Extra built-in functions +@table @code + +@item su +@cmindex su +@itemx sudo +@cmindex sudo +@itemx doas +@cmindex doas +Uses TRAMP's @command{su}, @command{sudo}, or @command{doas} method +(@pxref{Inline methods, , , tramp, The Tramp Manual}) to run a command +via @command{su}, @command{sudo}, or @command{doas}. -This section is not yet written. +@end table + +@node Extra built-in commands +@subsection Extra built-in commands + +This module provides several extra built-in commands documented below, +primarily for working with lists of strings in Eshell. To enable it, +add @code{eshell-xtra} to @code{eshell-modules-list}. + +@table @code + +@item expr +@cmindex expr +An implementation of @command{expr} using the Calc package. +@xref{Top,,, calc, The GNU Emacs Calculator}. + +@item intersection +@cmindex intersection +A wrapper around the function @code{cl-intersection} (@pxref{Lists as +Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command +can be used for comparing lists of strings. + +@item mismatch +@cmindex mismatch +A wrapper around the function @code{cl-mismatch} (@pxref{Searching +Sequences,,, cl, GNU Emacs Common Lisp Emulation}). This command can +be used for comparing lists of strings. + +@item set-difference +@cmindex set-difference +A wrapper around the function @code{cl-set-difference} (@pxref{Lists +as Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command can be +used for comparing lists of strings. + +@item set-exclusive-or +@cmindex set-exclusive-or +A wrapper around the function @code{cl-set-exclusive-or} (@pxref{Lists +as Sets,,, cl, GNU Emacs Common Lisp Emulation}). This command can be +used for comparing lists of strings. + +@item substitute +@cmindex substitute +A wrapper around the function @code{cl-substitute} (@pxref{Sequence +Functions,,, cl, GNU Emacs Common Lisp Emulation}). This command can +be used for comparing lists of strings. + +@item union +@cmindex union +A wrapper around the function @code{cl-union} (@pxref{Lists as Sets,,, +cl, GNU Emacs Common Lisp Emulation}). This command can be used for +comparing lists of strings. + +@end table @node Writing a module @section Writing a module @@ -2092,8 +2139,6 @@ Bugs and ideas which is the version included with Emacs 22. @table @asis -@item Documentation incomplete - @item Differentiate between aliases and functions Allow for a Bash-compatible syntax, such as: commit 7c417b2ae555c8b07c4eb440a2c798826842c636 Author: Jim Porter Date: Fri May 12 20:11:01 2023 -0700 Correct the Eshell documentation about how to write new modules * doc/misc/eshell.texi (Writing a module): Fix the documentation. 'eshell-defgroup' doesn't exist anymore. Do not merge to master. This is a backport of 77f13edab0f. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 44eb438cfd9..cff7c594d96 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -2045,23 +2045,27 @@ Extra built-in functions @node Writing a module @section Writing a module -An Eshell module is defined the same as any other library but one requirement: the -module must define a Customize@footnote{@xref{Customization, , , -elisp, The Emacs Lisp Reference Manual}.} -group using @code{eshell-defgroup} (in place of @code{defgroup}) with -@code{eshell-module} as the parent group.@footnote{If the module has -no user-customizable options, then there is no need to define it as an -Eshell module.} You also need to load the following as shown: +An Eshell module is defined the same as any other library but with two +additional requirements: first, the module's source file should be +named @file{em-@var{name}.el}; second, the module must define an +autoloaded Customize group (@pxref{Customization, , , elisp, The Emacs +Lisp Reference Manual}) with @code{eshell-module} as the parent group. +In order to properly autoload this group, you should wrap its +definition with @code{progn} as follows: @example -(eval-when-compile - (require 'cl-lib) - (require 'esh-mode) - (require 'eshell)) - -(require 'esh-util) +;;;###autoload +(progn +(defgroup eshell-my-module nil + "My module lets you do very cool things in Eshell." + :tag "My module" + :group 'eshell-module)) @end example +Even if you don't have any Customize options in your module, you +should still define the group so that Eshell can include your module +in the Customize interface for @code{eshell-modules-list}. + @node Bugs and ideas @chapter Bugs and ideas @cindex reporting bugs and ideas commit 6c3fe42bde137f7e1da54acef423c4335105b1cc Author: Jim Porter Date: Sun Jan 29 19:59:56 2023 -0800 Restructure Eshell extension modules documentation This adds a section for documenting all the optional modules. Do not merge to master. This is a backport of f2981a1681d. * doc/misc/eshell.texi (Extension modules): Move explanation about writing modules to... (Writing a module): ... here. (Module testing): Remove. Testing an Eshell module doesn't require any special documentation. (Key binding, Smart scrolling, Electric forward slash): Move under... (Optional modules): ... here. (Directory handling, Terminal emulation): Remove. These modules are enabled by default, and so are documented above. (Tramp extensions, Extra built-in commands): New sections. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 7d42aa62850..44eb438cfd9 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -1947,66 +1947,38 @@ Extension modules Eshell provides a facility for defining extension modules so that they can be disabled and enabled without having to unload and reload them, and to provide a common parent Customize group for the -modules.@footnote{ERC provides a similar module facility.} An Eshell -module is defined the same as any other library but one requirement: the -module must define a Customize@footnote{@xref{Customization, , , -elisp, The Emacs Lisp Reference Manual}.} -group using @code{eshell-defgroup} (in place of @code{defgroup}) with -@code{eshell-module} as the parent group.@footnote{If the module has -no user-customizable options, then there is no need to define it as an -Eshell module.} You also need to load the following as shown: - -@example -(eval-when-compile - (require 'cl-lib) - (require 'esh-mode) - (require 'eshell)) - -(require 'esh-util) -@end example +modules.@footnote{ERC provides a similar module facility.} @menu +* Optional modules:: * Writing a module:: -* Module testing:: -* Directory handling:: -* Key rebinding:: -* Smart scrolling:: -* Terminal emulation:: -* Electric forward slash:: @end menu -@node Writing a module -@section Writing a module - -This section is not yet written. - -@node Module testing -@section Module testing +@node Optional modules +@section Optional modules This section is not yet written. -@node Directory handling -@section Directory handling - -This section is not yet written. +@menu +* Key rebinding:: +* Smart scrolling:: +* Electric forward slash:: +* Tramp extensions:: +* Extra built-in commands:: +@end menu @node Key rebinding -@section Key rebinding +@subsection Key rebinding This section is not yet written. @node Smart scrolling -@section Smart scrolling - -This section is not yet written. - -@node Terminal emulation -@section Terminal emulation +@subsection Smart scrolling This section is not yet written. @node Electric forward slash -@section Electric forward slash +@subsection Electric forward slash To help with supplying absolute file name arguments to remote commands, you can add the @code{eshell-elecslash} module to @@ -2060,6 +2032,36 @@ Electric forward slash @code{|} and @code{;}, the electric forward slash is active only within the first command. +@node Tramp extensions +@subsection Tramp extensions + +This section is not yet written. + +@node Extra built-in functions +@subsection Extra built-in functions + +This section is not yet written. + +@node Writing a module +@section Writing a module + +An Eshell module is defined the same as any other library but one requirement: the +module must define a Customize@footnote{@xref{Customization, , , +elisp, The Emacs Lisp Reference Manual}.} +group using @code{eshell-defgroup} (in place of @code{defgroup}) with +@code{eshell-module} as the parent group.@footnote{If the module has +no user-customizable options, then there is no need to define it as an +Eshell module.} You also need to load the following as shown: + +@example +(eval-when-compile + (require 'cl-lib) + (require 'esh-mode) + (require 'eshell)) + +(require 'esh-util) +@end example + @node Bugs and ideas @chapter Bugs and ideas @cindex reporting bugs and ideas commit 4e204b561865327d4a928751b83c3a9ff4fe1a1e Author: Jim Porter Date: Sun Jan 29 18:29:02 2023 -0800 ; * doc/misc/eshell.texi (Bugs and ideas): Remove implemented feature. Do not merge to master. This is a backport of 194de36ca9f. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 1789cded9d3..7d42aa62850 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -2157,8 +2157,6 @@ Bugs and ideas @item Implement @samp{-r}, @samp{-n} and @samp{-s} switches for @command{cp} -@item Make @kbd{M-5 M-x eshell} switch to ``*eshell<5>*'', creating if need be - @item @samp{mv @var{dir} @var{file}.tar} does not remove directories This is because the tar option --remove-files doesn't do so. Should it commit 7ac947f34c745c61f8acc1fe2452a2c720d57a0d Author: Eli Zaretskii Date: Thu Jul 13 11:33:54 2023 +0300 ; * src/lisp.h (struct Lisp_Overlay): Update commentary (bug#64580). diff --git a/src/lisp.h b/src/lisp.h index bf91a1559bf..e8b9a795e3c 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2594,20 +2594,14 @@ SXHASH_REDUCE (EMACS_UINT x) ptrdiff_t bytepos; } GCALIGNED_STRUCT; -/* START and END are markers in the overlay's buffer, and - PLIST is the overlay's property list. */ struct Lisp_Overlay /* An overlay's real data content is: - plist - - buffer (really there are two buffer pointers, one per marker, - and both points to the same buffer) - - insertion type of both ends (per-marker fields) - - start & start byte (of start marker) - - end & end byte (of end marker) - - next (singly linked list of overlays) - - next fields of start and end markers (singly linked list of markers). - I.e. 9words plus 2 bits, 3words of which are for external linked lists. -*/ + - buffer + - itree node + - start buffer position (field of the itree node) + - end buffer position (field of the itree node) + - insertion types of both ends (fields of the itree node). */ { union vectorlike_header header; Lisp_Object plist; commit 9bc93c7996c314eb915561f4bc7391d3709cd168 Author: Jens Schmidt Date: Tue Jul 11 21:57:31 2023 +0200 Replace duplicate text from epa.texi by a reference * doc/misc/auth.texi (GnuPG and EasyPG Assistant Configuration): Replace duplicate text from epa.texi by a reference to that. (Bug#64154) diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi index 03484950e01..7b4e8fcfb39 100644 --- a/doc/misc/auth.texi +++ b/doc/misc/auth.texi @@ -675,43 +675,12 @@ GnuPG and EasyPG Assistant Configuration read the GnuPG encrypted @file{.gpg} file first, before the unencrypted file. -There is an option @code{auto-encryption-mode} to automatically -decrypt @file{*.gpg} files. It is enabled by default. - -If you want your GnuPG passwords to be cached, set up @code{gpg-agent} -or EasyPG Assistant -(@pxref{Caching Passphrases, , Caching Passphrases, epa}). - -To quick start, here are some questions: - -@itemize -@item -Do you use GnuPG version 2 instead of GnuPG version 1? -@item -Do you use symmetric encryption rather than public key encryption? -@item -Do you want to use gpg-agent? -@end itemize - -Here are configurations depending on your answers: - -@multitable {111} {222} {333} {configuration configuration configuration} -@item @b{1} @tab @b{2} @tab @b{3} @tab Configuration -@item Yes @tab Yes @tab Yes @tab Set up gpg-agent. -@item Yes @tab Yes @tab No @tab You can't, without gpg-agent. -@item Yes @tab No @tab Yes @tab Set up gpg-agent. -@item Yes @tab No @tab No @tab You can't, without gpg-agent. -@item No @tab Yes @tab Yes @tab Set up elisp passphrase cache. -@item No @tab Yes @tab No @tab Set up elisp passphrase cache. -@item No @tab No @tab Yes @tab Set up gpg-agent. -@item No @tab No @tab No @tab You can't, without gpg-agent. -@end multitable - -To set up gpg-agent, follow the instruction in GnuPG manual -(@pxref{Invoking GPG-AGENT, , Invoking GPG-AGENT, gnupg}). - -To set up elisp passphrase cache, set -@code{epa-file-cache-passphrase-for-symmetric-encryption}. +The EasyPG Assistant, which comes bundled with Emacs, handles +decryption of encrypted files automatically, see @ref{Top, , Top, epa, +EasyPG Assistant User's Manual}. It is an Emacs user interface to +@acronym{GnuPG, GNU Privacy Guard}, see @ref{Top, , Top, gnupg, Using +the GNU Privacy Guard}. To get started with these quickly, see +@ref{Quick start, , Quick Start, epa, EasyPG Assistant User's Manual}. @node GNU Free Documentation License @appendix GNU Free Documentation License commit 74cc1d27f1f10b9fca033318c59b52354dffe61c Author: Jens Schmidt Date: Sun Jul 9 16:17:27 2023 +0200 Add basic usage information and fix references * doc/misc/epa.texi (Top): Add menu entry for new node GnuPG Pinentry. (Quick Start): Add information on and reference to basic GnuPG configuration. (Encrypting/decrypting gpg files): Add usage information. (GnuPG version compatibility): Update version information. (GnuPG Pinentry): Add new node. (Caching Passphrases): Describe mandatory gpg-agent usage for GnuPG 2.0 and later. (Overview, Encrypting/decrypting gpg files, GnuPG version compatibility) (Caching Passphrases, Bug Reports): Fix references, terminology, mark-up, and index entries. (Bug#64154) diff --git a/doc/misc/epa.texi b/doc/misc/epa.texi index edfe37de816..917fd588593 100644 --- a/doc/misc/epa.texi +++ b/doc/misc/epa.texi @@ -70,6 +70,7 @@ Top * Quick start:: * Commands:: * GnuPG version compatibility:: +* GnuPG Pinentry:: * Caching Passphrases:: * Bug Reports:: * GNU Free Documentation License:: The license for this documentation. @@ -83,7 +84,8 @@ Overview @chapter Overview @cindex features of easypg assistant -EasyPG Assistant provides the following features. +EasyPG Assistant is an Emacs frontend application to @acronym{GnuPG, +GNU Privacy Guard} that provides the following features: @itemize @bullet @item Key management. @@ -97,6 +99,22 @@ Overview @node Quick start @chapter Quick Start @cindex introduction to easypg assistant +@cindex gnupg documentation +@cindex documentation on gnupg +@cindex configuration of gnupg +@cindex introduction to gnupg + +You can use EasyPG Assistant without any Emacs or GnuPG configuration +whatsoever, for example to encrypt and decrypt files automatically +with symmetric encryption, see @ref{Encrypting/decrypting gpg files}. +However, to use the full set of EasyPG Assistant's functions you +should have at least some minimum GnuPG configuration in place. + +John Michael Ashley's GNU Privacy Handbook, available online as part +of @uref{https://gnupg.org/documentation/guides.html, the GnuPG user +guides}, provides an introduction to GnuPG use and configuration. In +contrast to that, the GnuPG manual (@pxref{Top, , Top, gnupg, Using +the GNU Privacy Guard}) is more of a reference manual. EasyPG Assistant commands are prefixed by @samp{epa-}. For example, @@ -410,6 +428,44 @@ Encrypting/decrypting gpg files Similarly, when you save the buffer to a @file{foo.gpg} file, encrypted data is written. +When you save a buffer to an encrypted file for the first time, EasyPG +Assistant presents you a list of keys in a buffer @file{*Keys*} where +you can select recipients for encryption. @xref{Key management}, for +a description of the format of that buffer. You can streamline this +recipient selection step by customizing variables +@code{epa-file-encrypt-to} and @code{epa-file-select-keys} described +further below in this section. + +@cindex symmetric encryption, passphrase entry for +If you do not select any recipient during this step, EasyPG Assistant +uses symmetric encryption. As a consequence, you have to enter the +passphrase twice for every buffer save and every so often for file +reads, since the GnuPG Agent caches your passphrase for file reads at +least for some time, but not for buffer saves. @xref{Caching +Passphrases}, for more information. + +@cindex public key encryption, passphrase entry for +If you have created your own keypair@footnote{For encryption and +decryption of files you do not intend to share, you do not have to use +an email address as recipient during creation of the keypair. You can +also use some free-form string that gives information on the use of +the keypair, like @code{backup} or @code{account database}.}, you can +select that as recipient, and EasyPG Assistant will use public key +encryption for that file. Since GnuPG performs encryption with your +public key, it does not prompt for a passphrase for the buffer save, +but it will prompt for your passphrase for file reads every now and +then, depending on the GnuPG Agent cache configuration. + +@cindex tempory files created by easypg assistant +To encrypt and decrypt files as described above EasyPG Assistant under +certain circumstances uses intermediate tempory files that contain the +plain-text contents of the files it processes. EasyPG Assistant +creates them below the directory returned by function +@code{temporary-file-directory} (@pxref{Unique File Names, , +Generating Unique File Names, elisp, GNU Emacs Lisp Reference +Manual}). If you want to be sure not to leave any plain-text traces, +use an encrypted file systems at least for that directory. + The file name pattern for encrypted files can be controlled by @code{epa-file-name-regexp}. @@ -446,11 +502,11 @@ Encrypting/decrypting gpg files Control whether or not to pop up the key selection dialog. @end defvar -For frequently visited files, it might be a good idea to tell Emacs -which encryption method should be used through @xref{File Variables, , -, emacs, the Emacs Manual}. Use the @code{epa-file-encrypt-to} local -variable for this. @vindex epa-file-encrypt-to +For frequently visited files, it might be a good idea to tell Emacs +which encryption method should be used through file variables +(@pxref{File Variables, , Local Variables in Files, emacs, The Emacs +Editor}). Use the @code{epa-file-encrypt-to} local variable for this. For example, if you want an Elisp file to be encrypted with a public key associated with an email address @samp{ueno@@unixuser.org}, @@ -478,6 +534,11 @@ Encrypting/decrypting gpg files @defvar epa-file-cache-passphrase-for-symmetric-encryption If non-@code{nil}, cache passphrase for symmetric encryption. The default value is @code{nil}. + +For security reasons, this option is turned off by default and not +recommended to be used. Instead, consider using the GnuPG Agent, which +in many cases can do the same job, and does it in a safer way. +@xref{Caching Passphrases}, for more information. @end defvar @defvar epa-file-inhibit-auto-save @@ -507,10 +568,17 @@ GnuPG version compatibility @cindex version compatibility with gnupg @cindex compatibility with gnupg -As of February 2016, there are three active branches of GnuPG: 2.1, -2.0, and 1.4. All those branches should work flawlessly with Emacs -with basic use-cases. They have, however, some incompatible -characteristics, which might be visible when used from Emacs. +As of June 2023, there are three active branches of GnuPG: 2.4, 2.2, +and 1.4. GnuPG versions 2.4.1 and later suffer from +@uref{https://dev.gnupg.org/T6481, GnuPG bug T6481} and are hardly +usable with Emacs. There is a patch for that bug available at least +for GnuPG version 2.4.1, which your operating system or distribution +might provide already. GnuPG 1.4 is considered a legacy version. + +Besides that, all of those branches mentioned above should work +flawlessly with Emacs with basic use-cases. They have, however, some +incompatible characteristics, which might be visible when used from +Emacs. @itemize @item @@ -519,23 +587,91 @@ GnuPG version compatibility @item GnuPG 2.1 uses a fixed address for the Unix domain socket used to -communicate with gpg-agent. The @code{GPG_AGENT_INFO} environment -variable, which is used by GnuPG 2.0 and 1.4, is ignored. That means, -if your system has both GnuPG 2.1 and 1.4, the gpg command from GnuPG -1.4 is not able to use gpg-agent provided by 2.1 (at least out of box). +communicate with @command{gpg-agent}. The @code{GPG_AGENT_INFO} +environment variable, which is used by GnuPG 2.0 and 1.4, is ignored. +That means, if your system has both GnuPG 2.1 and 1.4, the gpg command +from GnuPG 1.4 is not able to use @command{gpg-agent} provided by 2.1 +(at least out of box). @item GnuPG 2.1 (2.1.5 or later) has a mechanism to direct the Pinentry -password prompt to the Emacs minibuffer@footnote{To enable this -feature, add @samp{allow-emacs-pinentry} to -@file{~/.gnupg/gpg-agent.conf} and let gpg-agent reload the -configuration, with: @samp{gpgconf --reload gpg-agent}}, which would -be useful when you use Emacs remotely or from a text-only terminal. -That feature is not available in other versions, and more -specifically, with 2.0 (as of 2.0.29), there is no way to avoid the -graphical prompt. +password prompt to the Emacs minibuffer. @xref{GnuPG Pinentry}. @end itemize +@node GnuPG Pinentry +@chapter GnuPG Pinentry +@cindex gnupg pinentry +@cindex pinentry provided by gnupg + +An important component of the GnuPG suite is the Pinentry, which +allows for secure entry of passphrases requested by GnuPG. GnuPG +delivers various different programs as Pinentry, ranging from bland +TTY-only @command{pinentry-tty} to fancy graphical dialogs for various +desktop environments, like @command{pinentry-gnome3}. Your operating +system usually determines which of these is used by default. + +Note that the selection of a concrete Pinentry program determines only +@emph{how} GnuPG queries for passphrases and not @emph{how often}. +For the latter question see @ref{Caching Passphrases}. + +@cindex pinentry, emacs as +With some configuration Emacs can also play the role of a Pinentry. +The most natural choice, available with GnuPG 2.1.5 and later, is to +use Emacs itself as Pinentry for requests that are triggered by Emacs. +For example, if you open a file whose name ends with @file{.gpg} using +automatic decryption, you most likely also want to enter the +passphrase for that request in Emacs. + +@cindex loopback pinentry +This so called @dfn{loopback Pinentry} has the added benefit that it +works also when you use Emacs remotely or from a text-only terminal. +To enable it: + +@enumerate +@item +@vindex allow-loopback-pinentry +Ensure that option @code{allow-loopback-pinentry} is configured for +@command{gpg-agent}, which should be the default. @xref{Agent +Options, , Option Summary, gnupg, Using the GNU Privacy Guard}. + +@item +@vindex epg-pinentry-mode +Customize variable @code{epg-pinentry-mode} to @code{loopback} in +Emacs. +@end enumerate + +There are other options available to use Emacs as Pinentry, you might +come across a Pinentry called @command{pinentry-emacs} or +@command{gpg-agent} option @code{allow-emacs-pinentry}. However, +these are considered insecure or semi-obsolete and might not be +supported by your operating system or distribution. For example, +Debian GNU/Linux supports only the loopback Pinentry described above. + +@ignore +In case somebody requests these: + +Use Emacs for all GnuPG requests: + +Make @command{pinentry-emacs} the default Pinentry by means of your +operating system. Install package @file{pinentry.el} from GNU ELPA +and execute @kbd{M-x pinentry-start} to start the Emacs Pinentry +service. @emph{All} GnuPG passphrase requests should then result in a +minibuffer prompt in the running Emacs. If Emacs or the Emacs +Pinentry service are not running, passphrase requests fail. + +Use Emacs for all GnuPG requests with other Pinentry as fallback: + +Ensure the other Pinentry supports Emacs; @command{pinentry-curses} +does, for example. Configure @command{gpg-agent} option +@code{allow-emacs-pinentry}. Set environment variable +@code{INSIDE_EMACS} for the calling process. Install package +@file{pinentry.el}. Now if Emacs is running and @kbd{M-x +pinentry-start} has been executed, all GnuPG passphrase requests +should result in a minibuffer prompt in the running Emacs. If Emacs +or the Emacs Pinentry service are not running, GnuPG uses the other +Pinentry instead. +@end ignore + @node Caching Passphrases @chapter Caching Passphrases @cindex caching passphrases @@ -545,35 +681,33 @@ Caching Passphrases Typing passphrases is a troublesome task if you frequently open and close the same file. GnuPG and EasyPG Assistant provide mechanisms to remember your passphrases for a limited time. Using these, you only -need to re-enter the passphrase occasionally. -However, the configuration is a bit -confusing since it depends on your GnuPG installation@xref{GnuPG -version compatibility}, encryption method (symmetric or public key), -and whether or not you want to use gpg-agent. Here are some -questions: +need to re-enter the passphrase occasionally. However, the +configuration is a bit confusing since it depends on your GnuPG +installation (@pxref{GnuPG version compatibility}), encryption method +(symmetric or public key), and whether or not you want to use +GnuPG Agent. As an additional constraint, use of the GnuPG Agent is +mandatory for GnuPG 2.0 and later. Here are some questions: @enumerate -@item Do you use GnuPG version 2.1 or 2.0 instead of GnuPG version 1.4? +@item Do you use GnuPG version 2.0 or later instead of GnuPG version 1.4? @item Do you use symmetric encryption rather than public key encryption? -@item Do you want to use gpg-agent? +@item Do you want to use GnuPG Agent? @end enumerate Here are configurations depending on your answers: @multitable {111} {222} {333} {configuration configuration configuration} @item @b{1} @tab @b{2} @tab @b{3} @tab Configuration -@item Yes @tab Yes @tab Yes @tab Set up gpg-agent. -@item Yes @tab Yes @tab No @tab You can't, without gpg-agent. -@item Yes @tab No @tab Yes @tab Set up gpg-agent. -@item Yes @tab No @tab No @tab You can't, without gpg-agent. -@item No @tab Yes @tab Yes @tab Set up elisp passphrase cache. -@item No @tab Yes @tab No @tab Set up elisp passphrase cache. -@item No @tab No @tab Yes @tab Set up gpg-agent. -@item No @tab No @tab No @tab You can't, without gpg-agent. +@item Yes @tab Yes @tab Must @tab Set up GnuPG Agent. +@item Yes @tab No @tab Must @tab Set up GnuPG Agent. +@item No @tab Yes @tab Yes @tab Set up elisp passphrase cache. +@item No @tab Yes @tab No @tab Set up elisp passphrase cache. +@item No @tab No @tab Yes @tab Set up GnuPG Agent. +@item No @tab No @tab No @tab You can't, without GnuPG Agent. @end multitable -To set up gpg-agent, follow the instruction in GnuPG manual. -@pxref{Invoking GPG-AGENT, , Invoking GPG-AGENT, gnupg}. +To set up GnuPG Agent, follow the instruction in @ref{Invoking +GPG-AGENT, , , gnupg, Using the GNU Privacy Guard}. To set up elisp passphrase cache, set @code{epa-file-cache-passphrase-for-symmetric-encryption}. @@ -586,8 +720,8 @@ Bug Reports Bugs and problems with EasyPG Assistant are actively worked on by the Emacs development team. Feature requests and suggestions are also -more than welcome. Use @kbd{M-x report-emacs-bug}, @pxref{Bugs, , -Bugs, emacs, Reporting Bugs}. +more than welcome. Use @kbd{M-x report-emacs-bug}, see @ref{Bugs, , +Reporting Bugs, emacs, The Emacs Editor}. When submitting a bug report, please try to describe in excruciating detail the steps required to reproduce the problem. Also try to commit f24bdbfaf572557620610a0587b2b17a6e1f3df0 Author: Jens Schmidt Date: Sun Jul 2 13:39:48 2023 +0200 Add concept index, title-case structure titles * doc/misc/epa.texi (Top, Overview, Commands, Key management) (Cryptographic operations on regions, Cryptographic operations on files) (Dired integration, Mail-mode integration) (Encrypting/decrypting gpg files, Querying a key server) (GnuPG version compatibility, Caching Passphrases) (GNU Free Documentation License): Add concept index, title-case structure titles. (Bug#64154) diff --git a/doc/misc/epa.texi b/doc/misc/epa.texi index 6f63a3d7ba0..edfe37de816 100644 --- a/doc/misc/epa.texi +++ b/doc/misc/epa.texi @@ -43,7 +43,10 @@ @contents @node Top -@top EasyPG Assistant user's manual +@top EasyPG Assistant User's Manual +@cindex easypg assistant +@cindex gnu privacy guard +@cindex gnupg EasyPG Assistant is an Emacs user interface to GNU Privacy Guard (GnuPG, @pxref{Top, , Top, gnupg, Using the GNU Privacy Guard}). @@ -56,6 +59,12 @@ Top @insertcopying @end ifnottex +@c Unfortunately the node names of this manual are not very consistent +@c w.r.t. their case. However, case is significant in node names, so +@c we probably better should not change these to not break any +@c external references. Things are more relaxed for structure titles, +@c so we consistently updated them to title-case. + @menu * Overview:: * Quick start:: @@ -64,6 +73,7 @@ Top * Caching Passphrases:: * Bug Reports:: * GNU Free Documentation License:: The license for this documentation. +* Concept Index:: * Key Index:: * Function Index:: * Variable Index:: @@ -71,6 +81,7 @@ Top @node Overview @chapter Overview +@cindex features of easypg assistant EasyPG Assistant provides the following features. @@ -84,7 +95,8 @@ Overview @end itemize @node Quick start -@chapter Quick start +@chapter Quick Start +@cindex introduction to easypg assistant EasyPG Assistant commands are prefixed by @samp{epa-}. For example, @@ -118,7 +130,11 @@ Commands @end menu @node Key management -@section Key management +@section Key Management +@cindex key management + +@cindex key ring, browsing +@cindex browse key ring Probably the first step of using EasyPG Assistant is to browse your keyring. @kbd{M-x epa-list-keys} is corresponding to @samp{gpg --list-keys} from the command line. @@ -157,6 +173,7 @@ Key management Fingerprint: 9003 D76B 73B7 4A8A E588 10AF 4447 461B 2A9B EA2D @end example +@cindex private key ring, browsing @noindent To browse your private keyring, use @kbd{M-x epa-list-secret-keys}. @@ -172,12 +189,14 @@ Key management Below are other commands related to key management. Some of them take a file as input/output, and others take the current region. +@cindex insert keys @deffn Command epa-insert-keys keys Insert selected @var{keys} after the point. It will let you select keys before insertion. By default, it will encode keys in the OpenPGP armor format. @end deffn +@cindex import keys @deffn Command epa-import-keys file Import keys from @var{file} to your keyring. @end deffn @@ -195,14 +214,18 @@ Key management applies @code{epa-import-keys-region} to each of them. @end deffn +@cindex delete keys @deffn Command epa-delete-keys allow-secret Delete selected keys. If @var{allow-secret} is non-@code{nil}, it also delete the secret keys. @end deffn @node Cryptographic operations on regions -@section Cryptographic operations on regions +@section Cryptographic Operations on Regions +@cindex cryptographic operations on regions +@cindex region operations, cryptographic +@cindex decrypt region @deffn Command epa-decrypt-region start end Decrypt the current region between @var{start} and @var{end}. It replaces the region with the decrypted text. @@ -216,6 +239,7 @@ Cryptographic operations on regions command does not alter the original text around armors. @end deffn +@cindex verify region @deffn Command epa-verify-region start end Verify the current region between @var{start} and @var{end}. It sends the verification result to the minibuffer or a popup window. It @@ -231,6 +255,7 @@ Cryptographic operations on regions not alter the original text around OpenPGP cleartext blocks. @end deffn +@cindex sign region @deffn Command epa-sign-region start end signers type Sign the current region between @var{start} and @var{end}. By default, it creates a cleartext signature. If a prefix argument is @@ -238,6 +263,7 @@ Cryptographic operations on regions type. @end deffn +@cindex encrypt region @deffn Command epa-encrypt-region start end recipients sign signers Encrypt the current region between @var{start} and @var{end}. It will let you select recipients. If a prefix argument is given, it will @@ -246,28 +272,37 @@ Cryptographic operations on regions @end deffn @node Cryptographic operations on files -@section Cryptographic operations on files +@section Cryptographic Operations on Files +@cindex cryptographic operations on files +@cindex file operations, cryptographic +@cindex decrypt file @deffn Command epa-decrypt-file file &optional output Decrypt @var{file}. If you do not specify the name @var{output} to use for the decrypted file, this function prompts for the value to use. @end deffn +@cindex verify file @deffn Command epa-verify-file file Verify @var{file}. @end deffn +@cindex sign file @deffn Command epa-sign-file file signers type Sign @var{file}. If a prefix argument is given, it will let you select signing keys, and then a signature type. @end deffn +@cindex encrypt file @deffn Command epa-encrypt-file file recipients Encrypt @var{file}. It will let you select recipients. @end deffn @node Dired integration -@section Dired integration +@section Dired Integration +@cindex dired integration +@cindex directory operations +@cindex multiple file operations EasyPG Assistant extends Dired Mode for GNU Emacs to allow users to easily do cryptographic operations on files. For example, @@ -306,7 +341,9 @@ Dired integration @end table @node Mail-mode integration -@section Mail-mode integration +@section Mail-Mode Integration +@cindex mail-mode integration +@cindex sending signed/encrypted mails EasyPG Assistant provides a minor mode @code{epa-mail-mode} to help user compose inline OpenPGP messages. Inline OpenPGP is a traditional @@ -361,7 +398,12 @@ Mail-mode integration @end table @node Encrypting/decrypting gpg files -@section Encrypting/decrypting gpg files +@section Encrypting and Decrypting gpg Files +@cindex encrypting gpg files +@cindex decrypting gpg files +@cindex gpg files, encrypting and decrypting +@cindex automatic file encryption and decryption + By default, every file whose name ends with @file{.gpg} will be treated as encrypted. That is, when you open such a file, the decrypted text is inserted in the buffer rather than encrypted one. @@ -444,7 +486,9 @@ Encrypting/decrypting gpg files @end defvar @node Querying a key server -@section Querying a key server +@section Querying a Key Server +@cindex query key server +@cindex key server, querying The @code{epa-search-keys} command can be used to query a @acronym{GPG} key server. Emacs will then pop up a buffer that lists @@ -457,9 +501,11 @@ Querying a key server The @code{epa-keyserver} variable says which server to query. - @node GnuPG version compatibility -@chapter GnuPG version compatibility +@chapter GnuPG Version Compatibility +@cindex gnupg version compatibility +@cindex version compatibility with gnupg +@cindex compatibility with gnupg As of February 2016, there are three active branches of GnuPG: 2.1, 2.0, and 1.4. All those branches should work flawlessly with Emacs @@ -492,6 +538,9 @@ GnuPG version compatibility @node Caching Passphrases @chapter Caching Passphrases +@cindex caching passphrases +@cindex entering passphrases +@cindex passphrases, entering and caching Typing passphrases is a troublesome task if you frequently open and close the same file. GnuPG and EasyPG Assistant provide mechanisms to @@ -532,6 +581,8 @@ Caching Passphrases @node Bug Reports @chapter Bug Reports +@cindex bug reports +@cindex reporting bugs Bugs and problems with EasyPG Assistant are actively worked on by the Emacs development team. Feature requests and suggestions are also @@ -556,6 +607,10 @@ GNU Free Documentation License @appendix GNU Free Documentation License @include doclicense.texi +@node Concept Index +@unnumbered Concept Index +@printindex cp + @node Key Index @unnumbered Key Index @printindex ky commit 0165b50b0ffed5224162eed705287937489fcace Author: Eli Zaretskii Date: Wed Jul 12 15:19:10 2023 +0300 ; * lisp/emacs-lisp/lisp.el (raise-sexp): Fix typo in doc string. diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index b91d56cfb4f..17d58b1e3c6 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -887,7 +887,7 @@ raise-sexp "Raise N sexps one level higher up the tree. This function removes the sexp enclosing the form which follows -point, and then re-inserts N sexps that originally followe point, +point, and then re-inserts N sexps that originally followed point, thus raising those N sexps one level up. Interactively, N is the numeric prefix argument, and defaults to 1. commit 4cf33b6bd02b868ebbf112da7926d7c3c64517ce Author: Stephen Berman Date: Mon Jul 10 12:20:10 2023 +0200 ; * doc/misc/modus-themes.org: Fix whitespace (bug#64548). diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org index 4bf78379c10..8cfa22df923 100644 --- a/doc/misc/modus-themes.org +++ b/doc/misc/modus-themes.org @@ -1,23 +1,23 @@ -#+title: Modus themes for GNU Emacs -#+author: Protesilaos Stavrou -#+email: info@protesilaos.com -#+language: en -#+options: ':t toc:nil author:t email:t num:t -#+startup: content -#+macro: stable-version 3.0.0 -#+macro: release-date 2022-10-28 -#+macro: development-version 3.1.0-dev -#+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ -#+macro: space @@texinfo:@: @@ -#+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@ -#+texinfo_filename: modus-themes.info -#+texinfo_dir_category: Emacs misc features -#+texinfo_dir_title: Modus Themes: (modus-themes) -#+texinfo_dir_desc: Elegant, highly legible and customizable themes -#+texinfo_header: @set MAINTAINERSITE @uref{https://protesilaos.com,maintainer webpage} -#+texinfo_header: @set MAINTAINER Protesilaos Stavrou -#+texinfo_header: @set MAINTAINEREMAIL @email{info@protesilaos.com} -#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:info@protesilaos.com,contact the maintainer} +#+title: Modus themes for GNU Emacs +#+author: Protesilaos Stavrou +#+email: info@protesilaos.com +#+language: en +#+options: ':t toc:nil author:t email:t num:t +#+startup: content +#+macro: stable-version 3.0.0 +#+macro: release-date 2022-10-28 +#+macro: development-version 3.1.0-dev +#+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ +#+macro: space @@texinfo:@: @@ +#+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@ +#+texinfo_filename: modus-themes.info +#+texinfo_dir_category: Emacs misc features +#+texinfo_dir_title: Modus Themes: (modus-themes) +#+texinfo_dir_desc: Elegant, highly legible and customizable themes +#+texinfo_header: @set MAINTAINERSITE @uref{https://protesilaos.com,maintainer webpage} +#+texinfo_header: @set MAINTAINER Protesilaos Stavrou +#+texinfo_header: @set MAINTAINEREMAIL @email{info@protesilaos.com} +#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:info@protesilaos.com,contact the maintainer} #+texinfo: @insertcopying commit 4821da1ad7fe0f30cb4d41669ad2db8652fcfa79 Author: Eli Zaretskii Date: Mon Jul 10 17:15:21 2023 +0300 Fix show-paren-mode when the parentheses is partially visible * lisp/paren.el (show-paren-function): Support the case where the open paren is partially visible, but enough so to not consider it "off-screen". (Bug#64547) diff --git a/lisp/paren.el b/lisp/paren.el index 4c91fd29490..54a2c23f17f 100644 --- a/lisp/paren.el +++ b/lisp/paren.el @@ -506,7 +506,19 @@ show-paren-function (when (and show-paren-context-when-offscreen (not (eql show-paren--last-pos (point))) (< there-beg here-beg) - (not (pos-visible-in-window-p openparen))) + ;; Either OPENPAREN position is fully visible... + (not (or (pos-visible-in-window-p openparen) + (let ((dfh4 (* 0.25 (default-font-height))) + (part + (pos-visible-in-window-p openparen + nil t))) + ;; ...or partially visible, and the + ;; invisible part is less than 1/4th + ;; of the default font height + (or (< (length part) 4) + (and + (< (nth 2 part) dfh4) + (< (nth 3 part) dfh4))))))) (let ((context (blink-paren-open-paren-line-string openparen)) (message-log-max nil)) commit 419b4d44914701cedf308df58c3e5789715c87e7 Author: Gregory Heytings Date: Sun Jul 9 19:27:12 2023 +0000 ; Improve documentation of with-restriction * lisp/subr.el (with-restriction): * doc/lispref/positions.texi (Narrowing): Make it clear that the argument is evaluated and that the result of the evaluation must not be nil. diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index e74a165b9ed..3d769bfe78a 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -1169,7 +1169,8 @@ Narrowing @cindex labeled narrowing @cindex labeled restriction -When the optional argument @var{label}, a symbol, is present, the +When the optional argument @var{label}, which is evaluated to get the +label to use and must yield a non-@code{nil} value, is present, the narrowing is @dfn{labeled}. A labeled narrowing differs from a non-labeled one in several ways: diff --git a/lisp/subr.el b/lisp/subr.el index 0b397b7bebf..43cf4572fe2 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3964,11 +3964,11 @@ with-restriction The current restrictions, if any, are restored upon return. -When the optional :label LABEL argument is present, in which -LABEL is a symbol, inside BODY, `narrow-to-region' and `widen' -can be used only within the START and END limits. To gain access -to other portions of the buffer, use `without-restriction' with the -same LABEL argument. +When the optional LABEL argument, which is evaluated to get the +label to use and must yield a non-nil value, is present, inside +BODY, `narrow-to-region' and `widen' can be used only within the +START and END limits. To gain access to other portions of the +buffer, use `without-restriction' with the same LABEL argument. \(fn START END [:label LABEL] BODY)" (declare (indent 2) (debug t)) @@ -3990,9 +3990,8 @@ without-restriction The current restrictions, if any, are restored upon return. -When the optional :label LABEL argument is present, the -restrictions set by `with-restriction' with the same LABEL argument -are lifted. +When the optional LABEL argument is present, the restrictions set +by `with-restriction' with the same LABEL argument are lifted. \(fn [:label LABEL] BODY)" (declare (indent 0) (debug t)) commit be34e8294affeaa3e1d92731b9a75fc62fbdca15 Author: Gregory Heytings Date: Sun Jul 9 16:08:02 2023 +0000 ; * admin/git-bisect-start: Update failing commits diff --git a/admin/git-bisect-start b/admin/git-bisect-start index f4ffb8f33b6..9de4d547323 100755 --- a/admin/git-bisect-start +++ b/admin/git-bisect-start @@ -82,7 +82,7 @@ done # SKIP-BRANCH 58cc931e92ece70c3e64131ee12a799d65409100 ## The list below is the exhaustive list of all commits between Dec 1 -## 2016 and Jun 8 2023 on which building Emacs with the default +## 2016 and Jul 8 2023 on which building Emacs with the default ## options, on a GNU/Linux computer and with GCC, fails. It is ## possible (though unlikely) that building Emacs with non-default ## options, with other compilers, or on other platforms, would succeed @@ -1735,3 +1735,25 @@ $REAL_GIT bisect skip $(cat $0 | grep '^# SKIP-SINGLE ' | sed 's/^# SKIP-SINGLE # SKIP-SINGLE 348e4504c6d5588443809ec28da3c3c693368e16 # SKIP-SINGLE 970f94a2dd8bc4be4d71f1075421093ca6f87d28 # SKIP-SINGLE 6b2c8dc9050c5c0514fa404733ce1d4a37d00e39 +# SKIP-SINGLE 6c3e65a75f582ca007a7fbcc4b866680e3b0e626 +# SKIP-SINGLE 8e8667246a4c06c8362515cbd6bead889babb748 +# SKIP-SINGLE bb4b511c4c63762bfd3b96623323a882cc57ecb6 +# SKIP-SINGLE 567258ab4309a7406cd4087d28cd0e820b17e157 +# SKIP-SINGLE 5fa9458511a17ff79a822e5cf8cc00f7bfb89364 +# SKIP-SINGLE 6d55d93379fa531f81327be6e506610474846758 +# SKIP-SINGLE eedb7111185569e426726fe15242f8ba08f89b31 +# SKIP-SINGLE 4c2cc21354a500b0fc48994b7b60648ef5f00a2d +# SKIP-SINGLE d7168e8575794b7af4e7e2bde51ca0663bbc2eac +# SKIP-SINGLE aad13e61dbf949ca6dea1ff492baca82f40a5738 +# SKIP-SINGLE 184106be2678f18ae90ccd35d69c2ccd61198b0a +# SKIP-SINGLE dfba4347c71d70b8357979ff0fb4bb070b0ed60c +# SKIP-SINGLE a19beb4ad43fe8225d384fc64e2406b7d24621a5 +# SKIP-SINGLE 77c2f05d773271cb59ebfd994b06a4075cacbfa8 +# SKIP-SINGLE ff5caf68c936ec90825efc4fd878d13703fb0400 +# SKIP-SINGLE 1c499c18afd6a709272fe60a540a27093e589fff +# SKIP-SINGLE 5b7e999e24f6cd446961ac441f69af021528623b +# SKIP-SINGLE 9c2cbfa49db96eae95bb40c5fc3ce7f09781a97d +# SKIP-SINGLE 375dac936fcca902874ecfd1c57b713581641725 +# SKIP-SINGLE 0a35c991c19a6dd0a707f2baa868f8989242c3ab +# SKIP-SINGLE e2ee646b162b87e832c8032b9d90577bd21f21f8 +# SKIP-SINGLE 35d2fe176cb438d55552cacbdf25c3692c054d51 commit 8e06809fccd9ead51e6df5b03847abe3748df76e Merge: dbac8076057 01fb898420f Author: Gregory Heytings Date: Sat Jul 8 19:30:17 2023 +0000 Merge branch 'scratch/bug64391' into emacs-29 commit dbac807605732426e75f1886c2f340d1194013c9 Author: Michael Albinus Date: Sat Jul 8 15:43:41 2023 +0200 * lisp/net/tramp.el (tramp-get-buffer-string): Stabilize. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 20678ec8d1a..29361f8a113 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1960,11 +1960,10 @@ tramp-get-buffer-string "Return contents of BUFFER. If BUFFER is not a buffer or a buffer name, return the contents of `current-buffer'." - (or (let ((buf (or buffer (current-buffer)))) - (when (bufferp buf) - (with-current-buffer (or buffer (current-buffer)) - (substring-no-properties (buffer-string))))) - "")) + (with-current-buffer + (if (or (bufferp buffer) (and (stringp buffer) (get-buffer buffer))) + buffer (current-buffer)) + (substring-no-properties (buffer-string)))) (defun tramp-debug-buffer-name (vec) "A name for the debug buffer for VEC." commit a82486e5a4e1ea3abb5afb6f279b22c44f0218d8 Author: Michael Albinus Date: Sat Jul 8 15:43:21 2023 +0200 Fix stale cache in Tramp (don't merge) * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-directly): Flush cache in time. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 48ba3d09e3e..502040902e1 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2338,6 +2338,11 @@ tramp-do-copy-or-rename-file-directly ;; Save exit. (ignore-errors (delete-file tmpfile))))))))) + ;; When newname did exist, we have wrong cached values. + (when t2 + (with-parsed-tramp-file-name newname v2 + (tramp-flush-file-properties v2 v2-localname))) + ;; Set the time and mode. Mask possible errors. (ignore-errors (when keep-date commit 01fb898420fe8260a1adc267993549a93b901cd8 Author: Gregory Heytings Date: Thu Jul 6 17:04:55 2023 +0000 Simplify after adding internal function to enter a labeled restriction * src/editfns.c: (Finternal__labeled_narrow_to_region): Merge the code of Finternal__label_restriction into this function. (Finternal__label_restriction): Remove this function. (syms_of_editfns): Remove the 'outermost-restriction' buffer local variable, which is not used anymore, and the symbol of 'internal--label-restriction'. (Fwiden): Remove the call to reset the 'outermost-restriction' buffer local variable. diff --git a/src/editfns.c b/src/editfns.c index 49c5c1f7b2f..211f1a03bee 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2682,11 +2682,12 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region, records the restriction bounds that were current when the first labeled restriction was entered (which may be a narrowing that was set by the user and is visible on display). This alist is used - internally by narrow-to-region, widen, internal--label-restriction, - internal--unlabel-restriction and save-restriction. For efficiency - reasons, an alist is used instead of a buffer-local variable: - otherwise reset_outermost_restrictions, which is called during each - redisplay cycle, would have to loop through all live buffers. */ + internally by narrow-to-region, internal--labeled-narrow-to-region, + widen, internal--unlabel-restriction and save-restriction. For + efficiency reasons, an alist is used instead of a buffer-local + variable: otherwise reset_outermost_restrictions, which is called + during each redisplay cycle, would have to loop through all live + buffers. */ static Lisp_Object labeled_restrictions; /* Add BUF with its list of labeled RESTRICTIONS in the @@ -2884,7 +2885,6 @@ DEFUN ("widen", Fwiden, Swiden, 0, 0, "", `without-restriction' with the same label. */) (void) { - Fset (Qoutermost_restriction, Qnil); Lisp_Object buf = Fcurrent_buffer (); Lisp_Object label = labeled_restrictions_peek_label (buf); @@ -2981,20 +2981,18 @@ positions (integers or markers) bounding the text that should return Qnil; } -DEFUN ("internal--label-restriction", Finternal__label_restriction, - Sinternal__label_restriction, 1, 1, 0, - doc: /* Label the current restriction with LABEL. +DEFUN ("internal--labeled-narrow-to-region", Finternal__labeled_narrow_to_region, + Sinternal__labeled_narrow_to_region, 3, 3, 0, + doc: /* Restrict editing in this buffer to START-END, and label the restriction with LABEL. This is an internal function used by `with-restriction'. */) - (Lisp_Object label) + (Lisp_Object start, Lisp_Object end, Lisp_Object label) { Lisp_Object buf = Fcurrent_buffer (); - Lisp_Object outermost_restriction - = buffer_local_value (Qoutermost_restriction, buf); - /* If internal--label-restriction is ever called without being - preceded by narrow-to-region, do nothing. */ - if (NILP (outermost_restriction)) - return Qnil; + Lisp_Object outermost_restriction = list3 (Qoutermost_restriction, + Fpoint_min_marker (), + Fpoint_max_marker ()); + Fnarrow_to_region (start, end); if (NILP (labeled_restrictions_peek_label (buf))) labeled_restrictions_push (buf, outermost_restriction); labeled_restrictions_push (buf, list3 (label, @@ -3003,24 +3001,6 @@ DEFUN ("internal--label-restriction", Finternal__label_restriction, return Qnil; } -DEFUN ("internal--labeled-narrow-to-region", Finternal__labeled_narrow_to_region, - Sinternal__labeled_narrow_to_region, 3, 3, 0, - doc: /* Restrict editing to START-END, and label the restriction with LABEL. - -This is an internal function used by `with-restriction'. */) - (Lisp_Object start, Lisp_Object end, Lisp_Object label) -{ - /* Record the accessible range of the buffer when narrow-to-region - is called, that is, before applying the narrowing. That - information is used only by internal--label-restriction. */ - Fset (Qoutermost_restriction, list3 (Qoutermost_restriction, - Fpoint_min_marker (), - Fpoint_max_marker ())); - Fnarrow_to_region (start, end); - Finternal__label_restriction (label); - return Qnil; -} - DEFUN ("internal--unlabel-restriction", Finternal__unlabel_restriction, Sinternal__unlabel_restriction, 1, 1, 0, doc: /* If the current restriction is labeled with LABEL, remove its label. @@ -4875,10 +4855,6 @@ syms_of_editfns (void) it to be non-nil. */); binary_as_unsigned = false; - DEFVAR_LISP ("outermost-restriction", Voutermost_restriction, - doc: /* Outermost narrowing bounds, if any. Internal use only. */); - Voutermost_restriction = Qnil; - Fmake_variable_buffer_local (Qoutermost_restriction); DEFSYM (Qoutermost_restriction, "outermost-restriction"); Funintern (Qoutermost_restriction, Qnil); @@ -4973,7 +4949,6 @@ syms_of_editfns (void) defsubr (&Sdelete_and_extract_region); defsubr (&Swiden); defsubr (&Snarrow_to_region); - defsubr (&Sinternal__label_restriction); defsubr (&Sinternal__labeled_narrow_to_region); defsubr (&Sinternal__unlabel_restriction); defsubr (&Ssave_restriction); commit b741dc7fcde0c601a01470655ceaeeef854ac32e Author: Gregory Heytings Date: Thu Jul 6 17:04:53 2023 +0000 Add internal function to enter a labeled restriction * src/editfns.c (Finternal__labeled_narrow_to_region): New function. A specific function is necessary to avoid unnecessary slowdowns when 'narrow-to-region'/'widen' are called in a loop. (Fnarrow_to_region): Remove the call to Fset, which has been moved into Finternal__labeled_narrow_to_region. (labeled_narrow_to_region): Use the new function. (syms_of_editfns): Add the symbol of the new function. * lisp/subr.el (internal--with-restriction): Use the new function. diff --git a/lisp/subr.el b/lisp/subr.el index 85adef5b689..0b397b7bebf 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3980,8 +3980,9 @@ with-restriction (defun internal--with-restriction (start end body &optional label) "Helper function for `with-restriction', which see." (save-restriction - (narrow-to-region start end) - (if label (internal--label-restriction label)) + (if label + (internal--labeled-narrow-to-region start end label) + (narrow-to-region start end)) (funcall body))) (defmacro without-restriction (&rest rest) diff --git a/src/editfns.c b/src/editfns.c index a1e48daf6c6..49c5c1f7b2f 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2868,8 +2868,7 @@ unwind_labeled_narrow_to_region (Lisp_Object label) labeled_narrow_to_region (Lisp_Object begv, Lisp_Object zv, Lisp_Object label) { - Fnarrow_to_region (begv, zv); - Finternal__label_restriction (label); + Finternal__labeled_narrow_to_region (begv, zv, label); record_unwind_protect (restore_point_unwind, Fpoint_marker ()); record_unwind_protect (unwind_labeled_narrow_to_region, label); } @@ -2967,13 +2966,6 @@ positions (integers or markers) bounding the text that should if (e > zv_charpos) e = zv_charpos; } - /* Record the accessible range of the buffer when narrow-to-region - is called, that is, before applying the narrowing. That - information is used only by internal--label-restriction. */ - Fset (Qoutermost_restriction, list3 (Qoutermost_restriction, - Fpoint_min_marker (), - Fpoint_max_marker ())); - if (BEGV != s || ZV != e) current_buffer->clip_changed = 1; @@ -3011,6 +3003,24 @@ DEFUN ("internal--label-restriction", Finternal__label_restriction, return Qnil; } +DEFUN ("internal--labeled-narrow-to-region", Finternal__labeled_narrow_to_region, + Sinternal__labeled_narrow_to_region, 3, 3, 0, + doc: /* Restrict editing to START-END, and label the restriction with LABEL. + +This is an internal function used by `with-restriction'. */) + (Lisp_Object start, Lisp_Object end, Lisp_Object label) +{ + /* Record the accessible range of the buffer when narrow-to-region + is called, that is, before applying the narrowing. That + information is used only by internal--label-restriction. */ + Fset (Qoutermost_restriction, list3 (Qoutermost_restriction, + Fpoint_min_marker (), + Fpoint_max_marker ())); + Fnarrow_to_region (start, end); + Finternal__label_restriction (label); + return Qnil; +} + DEFUN ("internal--unlabel-restriction", Finternal__unlabel_restriction, Sinternal__unlabel_restriction, 1, 1, 0, doc: /* If the current restriction is labeled with LABEL, remove its label. @@ -4964,6 +4974,7 @@ syms_of_editfns (void) defsubr (&Swiden); defsubr (&Snarrow_to_region); defsubr (&Sinternal__label_restriction); + defsubr (&Sinternal__labeled_narrow_to_region); defsubr (&Sinternal__unlabel_restriction); defsubr (&Ssave_restriction); defsubr (&Stranspose_regions);