commit 218d2d1509673d8bc67014558a31f5d0da1be5c6 (HEAD, refs/remotes/origin/master) Author: Michael Albinus Date: Sun Jun 6 08:38:40 2021 +0200 * lisp/net/tramp.el (tramp-error): Make it a defun. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 4fd7a322d4..838464e88b 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2048,7 +2048,7 @@ function is meant for debugging purposes." (put #'tramp-backtrace 'tramp-suppress-trace t) -(defsubst tramp-error (vec-or-proc signal fmt-string &rest arguments) +(defun tramp-error (vec-or-proc signal fmt-string &rest arguments) "Emit an error. VEC-OR-PROC identifies the connection to use, SIGNAL is the signal identifier to be raised, remaining arguments passed to commit 45d711a356b4c5e75d0b6e4391313ca34f57b4bb Author: João Távora Date: Sat Jun 5 21:46:59 2021 +0100 Consider environment vars in Fido's directory-aware RET binding Fixes: bug#48782 * lisp/icomplete.el (icomplete-fido-ret): Consider environment variables in dir expansion. diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 03a191cb0b..08b4ef2030 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -331,7 +331,8 @@ require user confirmation." (file-name-directory (icomplete--field-string)))) (current (car completion-all-sorted-completions)) (probe (and dir current - (expand-file-name (directory-file-name current) dir)))) + (expand-file-name (directory-file-name current) + (substitute-env-vars dir))))) (cond ((and probe (file-directory-p probe) (not (string= current "./"))) (icomplete-force-complete)) (t commit 4fda37fc7d83a555c597269954b5717b874cf2ee Author: Alex Bochannek Date: Sat Jun 5 22:29:09 2021 +0200 Fix Gnus summary exclusion when everything matches * lisp/gnus/gnus-sum.el (gnus-summary-limit-to-recipient): * lisp/gnus/gnus-sum.el (gnus-summary-limit-to-subject): (gnus-summary-limit-to-address, gnus-summary-limit-to-extra): Don't claim that there aren't any matches when everything matches an exclusion (bug#48834). diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 48794ceb3f..3279c3221e 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -8247,7 +8247,7 @@ If NOT-MATCHING, excluding articles that have subjects that match a regexp." (let ((articles (gnus-summary-find-matching (or header "subject") subject 'all nil nil not-matching))) - (unless articles + (unless (or articles not-matching) (error "Found no matches for \"%s\"" subject)) (gnus-summary-limit articles)) (gnus-summary-position-point)))) @@ -8318,7 +8318,7 @@ To and Cc headers are checked. You need to include them in (and (memq a to) a)) cc) (nconc to cc)))) - (unless articles + (unless (or articles not-matching) (error "Found no matches for \"%s\"" recipient)) (gnus-summary-limit articles)) (gnus-summary-position-point)))) @@ -8374,7 +8374,7 @@ in `nnmail-extra-headers'." (nconc (if (eq to t) nil to) (if (eq cc t) nil cc) from)))) - (unless articles + (unless (or articles not-matching) (error "Found no matches for \"%s\"" address)) (gnus-summary-limit articles)) (gnus-summary-position-point)))) @@ -8465,7 +8465,7 @@ articles that are younger than AGE days." (let ((articles (gnus-summary-find-matching (cons 'extra header) regexp 'all nil nil not-matching))) - (unless articles + (unless (or articles not-matching) (error "Found no matches for \"%s\"" regexp)) (gnus-summary-limit articles)) (gnus-summary-position-point)))) commit c9424189fc85140e376812d9b4bc4e6420d64976 Author: Stefan Monnier Date: Sat Jun 5 11:57:57 2021 -0400 * src/keyboard.c (read_decoded_event_from_main_queue): Fix paren typo diff --git a/src/keyboard.c b/src/keyboard.c index c63826e34d..051f2f8b38 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2262,7 +2262,7 @@ read_decoded_event_from_main_queue (struct timespec *end_time, (meta_key == 3 && c < 0x100 && (c & 0x80)) ? meta_modifier : 0; - events[i] = make_fixnum ((c & ~0x80) | modifier; + events[i] = make_fixnum ((c & ~0x80) | modifier); } } } commit e490ffcf953cd2a82aef86e05da24352db5d4568 Author: Stefan Monnier Date: Thu Jun 3 18:05:01 2021 -0400 * lisp/mpc.el (mpc-intersection): Fix commit 1760029b0927242 diff --git a/lisp/mpc.el b/lisp/mpc.el index 9addb70f56..ab572aa539 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el @@ -125,14 +125,13 @@ (unless (member elem seen) (push elem res))))) (nreverse res))) -(defun mpc-intersection (l1 l2 &optional selectfun) +(defun mpc-intersection (l1 l2 selectfun) "Return L1 after removing all elements not found in L2. -If SELECTFUN is non-nil, elements aren't compared directly, but instead +Elements aren't compared directly, but instead they are passed through SELECTFUN before comparison." - (when selectfun - (setq l1 (mapcar selectfun l1)) - (setq l2 (mapcar selectfun l2))) - (seq-intersection l1 l2)) + (seq-intersection l1 l2 (lambda (x y) + (equal (funcall selectfun x) + (funcall selectfun y))))) (defun mpc-event-set-point (event) (condition-case nil (posn-set-point (event-end event)) commit 58de11fe1339a1248f9b0bccb3a3601a9d8f56c6 Author: Eli Zaretskii Date: Sat Jun 5 17:17:17 2021 +0300 Document the last change * doc/lispref/os.texi (Input Modes): Document the changes in the values of the META flag. * etc/NEWS: Call out the change in input-meta-mode. diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 37fde0a953..242c5ed152 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -2369,11 +2369,17 @@ has no effect except in @sc{cbreak} mode. The argument @var{meta} controls support for input character codes above 127. If @var{meta} is @code{t}, Emacs converts characters with -the 8th bit set into Meta characters. If @var{meta} is @code{nil}, +the 8th bit set into Meta characters, before it decodes them as needed +(@pxref{Terminal I/O Encoding}). If @var{meta} is @code{nil}, Emacs disregards the 8th bit; this is necessary when the terminal uses -it as a parity bit. If @var{meta} is neither @code{t} nor @code{nil}, -Emacs uses all 8 bits of input unchanged. This is good for terminals -that use 8-bit character sets. +it as a parity bit. If @var{meta} is the symbol @code{encoded}, Emacs +first decodes the characters using all the 8 bits of each byte, and +then converts the decoded single-byte characters into Meta characters +if they have their eighth bit set. Finally, if @var{meta} is neither +@code{t} nor @code{nil} nor @code{encoded}, Emacs uses all 8 bits of +input unchanged, both before and after decoding them. This is good +for terminals that use 8-bit character sets and don't encode the Meta +modifier as the eighth bit. If @var{quit-char} is non-@code{nil}, it specifies the character to use for quitting. Normally this character is @kbd{C-g}. @@ -2398,9 +2404,11 @@ flow control for output to the terminal. This value is meaningful only when @var{interrupt} is @code{nil}. @item meta is @code{t} if Emacs treats the eighth bit of input characters as -the meta bit; @code{nil} means Emacs clears the eighth bit of every -input character; any other value means Emacs uses all eight bits as the -basic character code. +the Meta bit before decoding input; @code{encoded} if Emacs treats the +eighth bit of the decoded single-byte characters as the Meta bit; +@code{nil} if Emacs clears the eighth bit of every input character; +any other value means Emacs uses all eight bits as the basic character +code. @item quit is the character Emacs currently uses for quitting, usually @kbd{C-g}. @end table diff --git a/etc/NEWS b/etc/NEWS index e782603f0b..7d53eafbae 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -295,6 +295,17 @@ default, 9.5 MiB). Press '?' or 'C-h' in that prompt to read more about the different options to visit a file, how you can disable the prompt, and how you can tweak the file size threshold. ++++ +** Improved support for terminal emulators that encode the Meta flag. +Some terminal emulators set the 8th bit of Meta characters, and then +encode the resulting character code as if it were non-ASCII character +above codepoint 127. Previously, the only way of using these in Emacs +was to set up the terminal emulator to use the ESC characters to send +Meta characters to Emacs, e.g., send "ESC x" when the user types +'M-x'. You can now avoid the need for this setup of such terminal +emulators by using the new input-meta-mode with the special value +'encoded' with these terminal emulators. + * Editing Changes in Emacs 28.1 commit 515eb6989575dc1d8e8f996ec65494e637f24ffe Author: Max Mikhanosha Date: Sat Jun 5 16:57:43 2021 +0300 Support terminal emulators that encode the Meta modifier as 8th bit See discussion starting at https://lists.gnu.org/archive/html/emacs-devel/2021-06/msg00034.html for the details. * src/keyboard.c (read_decoded_event_from_main_queue): For raw-text encoed input, if Meta bit is encoded, apply the Meta modifier to single-byte characters that have the 0x80 bit set. For input encoded otherwise, if the Meta bit is encoded, remove the 0x80 bit after decoding the characters. (tty_read_avail_input): Reset the 0x80 bit only if Meta bit is not encoded. (Fset_input_meta_mode): Support 'encoded' as the value of META. (Fset_input_mode): Document 'encoded' for META. (Fcurrent_input_mode): Support and document 'encoded' as the value of META. (syms_of_keyboard): DEFSYM 'encoded'. diff --git a/src/keyboard.c b/src/keyboard.c index d2facc2364..c63826e34d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2254,8 +2254,17 @@ read_decoded_event_from_main_queue (struct timespec *end_time, { int i; if (meta_key != 2) - for (i = 0; i < n; i++) - events[i] = make_fixnum (XFIXNUM (events[i]) & ~0x80); + { + for (i = 0; i < n; i++) + { + int c = XFIXNUM (events[i]); + int modifier = + (meta_key == 3 && c < 0x100 && (c & 0x80)) + ? meta_modifier + : 0; + events[i] = make_fixnum ((c & ~0x80) | modifier; + } + } } else { @@ -2264,7 +2273,7 @@ read_decoded_event_from_main_queue (struct timespec *end_time, int i; for (i = 0; i < n; i++) src[i] = XFIXNUM (events[i]); - if (meta_key != 2) + if (meta_key < 2) /* input-meta-mode is t or nil */ for (i = 0; i < n; i++) src[i] &= ~0x80; coding->destination = dest; @@ -2282,7 +2291,18 @@ read_decoded_event_from_main_queue (struct timespec *end_time, eassert (coding->carryover_bytes == 0); n = 0; while (n < coding->produced_char) - events[n++] = make_fixnum (string_char_advance (&p)); + { + int c = string_char_advance (&p); + if (meta_key == 3) + { + int modifier + = (c < 0x100 && (c & 0x80) + ? meta_modifier + : 0); + c = (c & ~0x80) | modifier; + } + events[n++] = make_fixnum (c); + } } } } @@ -7068,7 +7088,7 @@ tty_read_avail_input (struct terminal *terminal, buf.modifiers = 0; if (tty->meta_key == 1 && (cbuf[i] & 0x80)) buf.modifiers = meta_modifier; - if (tty->meta_key != 2) + if (tty->meta_key < 2) cbuf[i] &= ~0x80; buf.code = cbuf[i]; @@ -11075,7 +11095,10 @@ See also `current-input-mode'. */) DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0, doc: /* Enable or disable 8-bit input on TERMINAL. If META is t, Emacs will accept 8-bit input, and interpret the 8th -bit as the Meta modifier. +bit as the Meta modifier before it decodes the characters. + +If META is `encoded', Emacs will interpret the 8th bit of single-byte +characters after decoding the characters. If META is nil, Emacs will ignore the top bit, on the assumption it is parity. @@ -11104,6 +11127,8 @@ See also `current-input-mode'. */) new_meta = 0; else if (EQ (meta, Qt)) new_meta = 1; + else if (EQ (meta, Qencoded)) + new_meta = 3; else new_meta = 2; @@ -11166,6 +11191,8 @@ Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal (no effect except in CBREAK mode). Third arg META t means accept 8-bit input (for a Meta key). META nil means ignore the top bit, on the assumption it is parity. + META `encoded' means accept 8-bit input and interpret Meta after + decoding the input characters. Otherwise, accept 8-bit input and don't use the top bit for Meta. Optional fourth arg QUIT if non-nil specifies character to use for quitting. See also `current-input-mode'. */) @@ -11186,9 +11213,12 @@ The value is a list of the form (INTERRUPT FLOW META QUIT), where nil, Emacs is using CBREAK mode. FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the terminal; this does not apply if Emacs uses interrupt-driven input. - META is t if accepting 8-bit input with 8th bit as Meta flag. - META nil means ignoring the top bit, on the assumption it is parity. - META is neither t nor nil if accepting 8-bit input and using + META is t if accepting 8-bit unencoded input with 8th bit as Meta flag. + META is `encoded' if accepting 8-bit encoded input with 8th bit as + Meta flag which has to be interpreted after decoding the input. + META is nil if ignoring the top bit of input, on the assumption that + it is a parity bit. + META is neither t nor nil if accepting 8-bit input and using all 8 bits as the character code. QUIT is the character Emacs currently uses to quit. The elements of this list correspond to the arguments of @@ -11204,7 +11234,9 @@ The elements of this list correspond to the arguments of flow = FRAME_TTY (sf)->flow_control ? Qt : Qnil; meta = (FRAME_TTY (sf)->meta_key == 2 ? make_fixnum (0) - : (CURTTY ()->meta_key == 1 ? Qt : Qnil)); + : (CURTTY ()->meta_key == 1 + ? Qt + : (CURTTY ()->meta_key == 3 ? Qencoded : Qnil))); } else { @@ -11695,6 +11727,7 @@ syms_of_keyboard (void) } } DEFSYM (Qno_record, "no-record"); + DEFSYM (Qencoded, "encoded"); button_down_location = make_nil_vector (5); staticpro (&button_down_location); commit f93f3b80dde20a0c643b011d1bf78e34860870a2 Author: Eli Zaretskii Date: Sat Jun 5 14:16:06 2021 +0300 Fix slow operation of 'string-width' * src/composite.c (find_automatic_composition): Accept one additional argument BACKLIM; don't look back in buffer or string farther than that. Add an assertion for BACKLIM. (composition_adjust_point, Ffind_composition_internal): Callers adjusted. * src/composite.h (find_automatic_composition): Adjust prototype. * src/character.c (lisp_string_width): Call 'find_automatic_composition' with the value of BACKLIM equal to POS, to avoid costly and unnecessary search back in the string, since those previous characters were already checked for automatic compositions. (Bug#48734) (Bug#48839) diff --git a/src/character.c b/src/character.c index 70e68961a5..38a81d36b0 100644 --- a/src/character.c +++ b/src/character.c @@ -375,7 +375,8 @@ lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to, else if (auto_comp && f && FRAME_WINDOW_P (f) && multibyte - && find_automatic_composition (i, -1, &ignore, &end, &val, string) + && find_automatic_composition (i, -1, i, &ignore, + &end, &val, string) && end > i) { int j; diff --git a/src/composite.c b/src/composite.c index 17d5914e63..129e9d6bb2 100644 --- a/src/composite.c +++ b/src/composite.c @@ -1473,14 +1473,60 @@ struct position_record (POSITION).pos--; \ } while (0) -/* This is like find_composition, but find an automatic composition - instead. It is assured that POS is not within a static - composition. If found, set *GSTRING to the glyph-string - representing the composition, and return true. Otherwise, *GSTRING to - Qnil, and return false. */ +/* Similar to find_composition, but find an automatic composition instead. + + This function looks for automatic composition at or near position + POS of OBJECT (a buffer or a string). OBJECT defaults to the + current buffer. It must be assured that POS is not within a static + composition. Also, the current buffer must be displayed in some + window, otherwise the function will return FALSE. + + If LIMIT is negative, and there's no composition that includes POS + (i.e. starts at or before POS and ends at or after POS), return + FALSE. In this case, the function is allowed to look from POS as + far back as BACKLIM, and as far forward as POS+1 plus + MAX_AUTO_COMPOSITION_LOOKBACK, the maximum number of look-back for + automatic compositions (3) -- this is a limitation imposed by + composition rules in composition-function-table, which see. If + BACKLIM is negative, it stands for the beginning of OBJECT: BEGV + for a buffer or position zero for a string. + + If LIMIT is positive, search for a composition forward (LIMIT > + POS) or backward (LIMIT < POS). In this case, LIMIT bounds the + search for the first character of a composed sequence. + (LIMIT == POS is the same as LIMIT < 0.) If LIMIT > POS, the + function can find a composition that starts after POS. + + BACKLIM limits how far back is the function allowed to look in + OBJECT while trying to find a position where it is safe to start + searching forward for compositions. Such a safe place is generally + the position after a character that can never be composed. + + If BACKLIM is negative, that means the first character position of + OBJECT; this is useful when calling the function for the first time + for a given buffer or string, since it is possible that a + composition begins before POS. However, if POS is very far from + the beginning of OBJECT, a negative value of BACKLIM could make the + function slow. Also, in this case the function may return START + and END that do not include POS, something that is not necessarily + wanted, and needs to be explicitly checked by the caller. + + When calling the function in a loop for the same buffer/string, the + caller should generally set BACKLIM equal to POS, to avoid costly + repeated searches backward. This is because if the previous + positions were already checked for compositions, there should be no + reason to re-check them. + + If BACKLIM is positive, it must be less or equal to LIMIT. + + If an automatic composition satisfying the above conditions is + found, set *GSTRING to the Lispy glyph-string representing the + composition, set *START and *END to the start and end of the + composed sequence, and return TRUE. Otherwise, set *GSTRING to + nil, and return FALSE. */ bool -find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, +find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim, ptrdiff_t *start, ptrdiff_t *end, Lisp_Object *gstring, Lisp_Object string) { @@ -1502,13 +1548,13 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, cur.pos = pos; if (NILP (string)) { - head = BEGV, tail = ZV, stop = GPT; + head = backlim < 0 ? BEGV : backlim, tail = ZV, stop = GPT; cur.pos_byte = CHAR_TO_BYTE (cur.pos); cur.p = BYTE_POS_ADDR (cur.pos_byte); } else { - head = 0, tail = SCHARS (string), stop = -1; + head = backlim < 0 ? 0 : backlim, tail = SCHARS (string), stop = -1; cur.pos_byte = string_char_to_byte (string, cur.pos); cur.p = SDATA (string) + cur.pos_byte; } @@ -1516,6 +1562,9 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, /* Finding a composition covering the character after POS is the same as setting LIMIT to POS. */ limit = pos; + + eassert (backlim < 0 || backlim <= limit); + if (limit <= pos) fore_check_limit = min (tail, pos + 1 + MAX_AUTO_COMPOSITION_LOOKBACK); else @@ -1696,8 +1745,8 @@ composition_adjust_point (ptrdiff_t last_pt, ptrdiff_t new_pt) return new_pt; /* Next check the automatic composition. */ - if (! find_automatic_composition (new_pt, (ptrdiff_t) -1, &beg, &end, &val, - Qnil) + if (! find_automatic_composition (new_pt, (ptrdiff_t) -1, (ptrdiff_t) -1, + &beg, &end, &val, Qnil) || beg == new_pt) return new_pt; for (i = 0; i < LGSTRING_GLYPH_LEN (val); i++) @@ -1893,8 +1942,8 @@ See `find-composition' for more details. */) { if (!NILP (BVAR (current_buffer, enable_multibyte_characters)) && ! NILP (Vauto_composition_mode) - && find_automatic_composition (from, to, &start, &end, &gstring, - string)) + && find_automatic_composition (from, to, (ptrdiff_t) -1, + &start, &end, &gstring, string)) return list3 (make_fixnum (start), make_fixnum (end), gstring); return Qnil; } @@ -1902,7 +1951,8 @@ See `find-composition' for more details. */) { ptrdiff_t s, e; - if (find_automatic_composition (from, to, &s, &e, &gstring, string) + if (find_automatic_composition (from, to, (ptrdiff_t) -1, + &s, &e, &gstring, string) && (e <= fixed_pos ? e > end : s < start)) return list3 (make_fixnum (s), make_fixnum (e), gstring); } diff --git a/src/composite.h b/src/composite.h index 75e5f9b9ec..660b1fa1b9 100644 --- a/src/composite.h +++ b/src/composite.h @@ -320,9 +320,9 @@ extern bool composition_gstring_p (Lisp_Object); extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t, struct font_metrics *); -extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t *, - ptrdiff_t *, Lisp_Object *, - Lisp_Object); +extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t, + ptrdiff_t *, ptrdiff_t *, + Lisp_Object *, Lisp_Object); extern void composition_compute_stop_pos (struct composition_it *, ptrdiff_t, ptrdiff_t, ptrdiff_t,