commit 7a9fb5d55c9bf612a38348d59e769ee915175e28 (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Tue Apr 14 02:33:52 2020 +0300 Fix hi-lock test and add new test for unhighlight (bug#40337) * lisp/hi-lock.el (hi-lock-unface-buffer): Use hi-lock--hashcons only on strings, not lists. * test/lisp/hi-lock-tests.el (hi-lock-bug26666): Revert previous change, use "a" instead of "b". (hi-lock-unhighlight): New test. diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el index 1d8dc0624b..bf79e48f85 100644 --- a/lisp/hi-lock.el +++ b/lisp/hi-lock.el @@ -681,8 +681,8 @@ then remove all hi-lock highlighting." (delq keyword hi-lock-interactive-patterns)) (remove-overlays nil nil 'hi-lock-overlay-regexp - (hi-lock--hashcons (or (car (rassq keyword hi-lock-interactive-lighters)) - (car keyword)))) + (or (car (rassq keyword hi-lock-interactive-lighters)) + (hi-lock--hashcons (car keyword)))) (setq hi-lock-interactive-lighters (rassq-delete-all keyword hi-lock-interactive-lighters)) (font-lock-flush)))) diff --git a/test/lisp/hi-lock-tests.el b/test/lisp/hi-lock-tests.el index 252caaa265..59f3e73b17 100644 --- a/test/lisp/hi-lock-tests.el +++ b/test/lisp/hi-lock-tests.el @@ -33,9 +33,7 @@ (car defaults)))) (dotimes (_ 2) (let ((face (hi-lock-read-face-name))) - ;; This test should use regexp "b" different from "a" - ;; used in another test because hi-lock--hashcons is global. - (hi-lock-set-pattern "b" face)))) + (hi-lock-set-pattern "a" face)))) (should (equal hi-lock--unused-faces (cdr faces)))))) (ert-deftest hi-lock-test-set-pattern () @@ -148,5 +146,63 @@ (call-interactively 'unhighlight-regexp)) (should (null (get-text-property 1 'face)))))) +(ert-deftest hi-lock-unhighlight () + "Test for unhighlighting and `hi-lock--regexps-at-point'." + (let ((hi-lock-auto-select-face t)) + (with-temp-buffer + (insert "aAbB\n") + + (cl-letf (((symbol-function 'completing-read) + (lambda (_prompt _coll _x _y _z _hist defaults) + (car defaults)))) + + (highlight-regexp "a") + (highlight-regexp "b") + (should (= (length (overlays-in (point-min) (point-max))) 4)) + ;; `hi-lock--regexps-at-point' should take regexp "a" at point 1, + ;; not the last regexp "b" + (goto-char 1) + (call-interactively 'unhighlight-regexp) + (should (= (length (overlays-in 1 3)) 0)) + (should (= (length (overlays-in 3 5)) 2)) + ;; Next call should unhighlight remaining regepxs + (call-interactively 'unhighlight-regexp) + (should (= (length (overlays-in 3 5)) 0)) + + ;; Test unhighlight all + (highlight-regexp "a") + (highlight-regexp "b") + (should (= (length (overlays-in (point-min) (point-max))) 4)) + (unhighlight-regexp t) + (should (= (length (overlays-in (point-min) (point-max))) 0)) + + (emacs-lisp-mode) + (setq font-lock-mode t) + + (highlight-regexp "a") + (highlight-regexp "b") + (font-lock-ensure) + (should (memq 'hi-yellow (get-text-property 1 'face))) + (should (memq 'hi-yellow (get-text-property 3 'face))) + ;; `hi-lock--regexps-at-point' should take regexp "a" at point 1, + ;; not the last regexp "b" + (goto-char 1) + (let ((font-lock-fontified t)) (call-interactively 'unhighlight-regexp)) + (should (null (get-text-property 1 'face))) + (should (memq 'hi-yellow (get-text-property 3 'face))) + ;; Next call should unhighlight remaining regepxs + (let ((font-lock-fontified t)) (call-interactively 'unhighlight-regexp)) + (should (null (get-text-property 3 'face))) + + ;; Test unhighlight all + (highlight-regexp "a") + (highlight-regexp "b") + (font-lock-ensure) + (should (memq 'hi-yellow (get-text-property 1 'face))) + (should (memq 'hi-yellow (get-text-property 3 'face))) + (let ((font-lock-fontified t)) (unhighlight-regexp t)) + (should (null (get-text-property 1 'face))) + (should (null (get-text-property 3 'face))))))) + (provide 'hi-lock-tests) ;;; hi-lock-tests.el ends here commit 086faceb1c395d24487c20bcb32ca710291bee41 Author: Juri Linkov Date: Tue Apr 14 02:24:51 2020 +0300 * lisp/vc/vc.el (vc-deduce-fileset): Improve docstring (bug#34949). diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index d4323d59eb..c640ba0420 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1012,23 +1012,33 @@ Within directories, only files already under version control are noticed." allow-unregistered state-model-only-files) "Deduce a set of files and a backend to which to apply an operation. -Return (BACKEND FILESET FILESET-ONLY-FILES STATE CHECKOUT-MODEL). +Return a list of the form: -NOT-STATE-CHANGING if non-nil, means that the operation -requesting the fileset doesn't intend to change VC state, -such as printing the log or showing the diff. + (BACKEND FILESET FILESET-ONLY-FILES STATE CHECKOUT-MODEL) -If we're in VC-dir mode, FILESET is the list of marked files, -or the directory if no files are marked. -Otherwise, if in a buffer visiting a version-controlled file, -FILESET is a single-file fileset containing that file. +where the last 3 members are optional, and must be present only if +STATE-MODEL-ONLY-FILES is non-nil. + +NOT-STATE-CHANGING, if non-nil, means that the operation +requesting the fileset doesn't intend to change the VC state, +such as when printing the log or showing the diffs. + +If the current buffer is in `vc-dir' or Dired mode, FILESET is the +list of marked files, or the current directory if no files are +marked. +Otherwise, if the current buffer is visiting a version-controlled +file, FILESET is a single-file list containing that file's name. Otherwise, if ALLOW-UNREGISTERED is non-nil and the visited file -is unregistered, FILESET is a single-file fileset containing it. +is unregistered, FILESET is a single-file list containing the +name of the visited file. Otherwise, throw an error. -STATE-MODEL-ONLY-FILES if non-nil, means that the caller needs -the FILESET-ONLY-FILES STATE and MODEL info. Otherwise, that -part may be skipped. +STATE-MODEL-ONLY-FILES, if non-nil, means that the caller needs +the FILESET-ONLY-FILES, STATE, and CHECKOUT-MODEL info, where +FILESET-ONLY-FILES means only files in similar VC states, +possible values of STATE are explained in `vc-state', and MODEL in +`vc-checkout-model'. Otherwise, these 3 members may be omitted from +the returned list. BEWARE: this function may change the current buffer." (let (backend) commit cdbb37f628aad1455af349d703c5838827bea8b3 Merge: 584ff8c2dc f84aed5fd2 Author: Glenn Morris Date: Mon Apr 13 09:02:29 2020 -0700 Merge from origin/emacs-27 f84aed5fd2 (origin/emacs-27) Clarify documentation on inhibit-modific... commit 584ff8c2dcfb330a0580ff280dd4554e556a2846 Merge: 0a4b992c42 81d07da788 Author: Glenn Morris Date: Mon Apr 13 09:02:29 2020 -0700 ; Merge from origin/emacs-27 The following commit was skipped: 81d07da788 gnus-shorten-url: Improve and avoid args-out-of-range error commit 0a4b992c422d98fbb351d3b03265eb1029012c1d Merge: d0b9cf876f 1dfc497fac Author: Glenn Morris Date: Mon Apr 13 09:02:29 2020 -0700 Merge from origin/emacs-27 1dfc497fac Minor wording change in Introduction to Programming in Ema... ff09b4eeac Fix 'flymake-show-diagnostics-buffer' when line numbers ar... 63e8d0ea87 Fix last changes describing mail commands 01212a762f Do setup Flymake in file-less Elisp buffers 36873ef2b2 Fix error message for ‘cl-struct-unknown-slot’ (bug#39995) 3f9310b0fe Fix and improve documentation of mail-related features 1482a75efa Fix build failure with Fx_gtk_debug cf57663f2a Mention jit-lock deferred as an alternative to fast-but-im... # Conflicts: # etc/NEWS commit d0b9cf876fa62e3584a062e123a87e28278782cf Author: Glenn Morris Date: Mon Apr 13 09:01:45 2020 -0700 * doc/lispref/processes.texi (Network): Fix xref usage. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 735e9fd7db..c6e735a9b1 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -2466,7 +2466,7 @@ If non-@code{nil}, try to make an asynchronous connection. @item :coding @var{coding} Use this to set the coding systems used by the network process, in preference to binding @code{coding-system-for-read} or -@code{coding-system-for-write}. @xref{Network Processes} for +@code{coding-system-for-write}. @xref{Network Processes}, for details. @item :type @var{type} commit 3b4def8e60b82c11d7296aa78be5b49a20d846f5 Author: Glenn Morris Date: Mon Apr 13 08:59:05 2020 -0700 * doc/emacs/msdos.texi (Windows Keyboard): Fix xref. diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi index 30dbaa3abd..48492ab2f2 100644 --- a/doc/emacs/msdos.texi +++ b/doc/emacs/msdos.texi @@ -721,7 +721,7 @@ applications to communicate with the Input Method Editor (@acronym{IME}), the native Windows input method service. Emacs uses the @acronym{IME} when available to allow users to input East Asian non-@acronym{ASCII} characters, similarly to Emacs's built-in input -methods (@pxref{Input methods}). However, in some situations the +methods (@pxref{Input Methods}). However, in some situations the @acronym{IME} can get in the way if it interprets simple @acronym{ASCII} keys you input as part of a key sequence that designates a non-@acronym{ASCII} character. The @acronym{IME} can be commit 9c6392c35891a869a08c25d4195c395fd49af82a Author: Albert Date: Mon Apr 13 22:52:30 2020 +0800 Fix previous change in w32fns.c * src/w32fns.c (w32_msg_pump): Simplify by not calling ImmGetOpenStatus. (Fw32_get_ime_open_status): Fix a typo. diff --git a/src/w32fns.c b/src/w32fns.c index dddf3dc571..4f7cbed249 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -3459,10 +3459,7 @@ w32_msg_pump (deferred_msg * msg_buf) if (!context) break; - BOOL new_status = (msg.wParam != 0); - BOOL ime_status = get_ime_open_status_fn (context); - if (new_status != ime_status) - set_ime_open_status_fn (context, new_status); + set_ime_open_status_fn (context, msg.wParam != 0); release_ime_context_fn (focus_window, context); break; } @@ -10261,7 +10258,7 @@ This function returns non-nil if the IME is active, otherwise nil. */) { HWND current_window = FRAME_W32_WINDOW (sf); HIMC context = get_ime_context_fn (current_window); - if (!context) + if (context) { BOOL retval = get_ime_open_status_fn (context); release_ime_context_fn (current_window, context); commit fc336a46553919206d9ac621d1ea5e9740477e18 Author: Eli Zaretskii Date: Mon Apr 13 16:33:57 2020 +0300 Document the new 'w32-get/set-ime-open-status' functions * doc/emacs/msdos.texi (Windows Keyboard): Document 'w32-set-ime-open-status'. * etc/NEWS: Announce the new IME-related functions. diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi index 3275fded56..30dbaa3abd 100644 --- a/doc/emacs/msdos.texi +++ b/doc/emacs/msdos.texi @@ -712,6 +712,21 @@ is @code{t}, which means these keys produce @code{AltGr}; setting it to @code{nil} causes @key{AltGr} or the equivalent key combination to be interpreted as the combination of @key{Ctrl} and @key{Meta} modifiers. + +@cindex IME, MS-Windows +@findex w32-set-ime-open-status + Some versions of MS-Windows, typically East Asian localized Windows, +enable the Input Method Manager (@acronym{IMM}) that allows +applications to communicate with the Input Method Editor +(@acronym{IME}), the native Windows input method service. Emacs uses +the @acronym{IME} when available to allow users to input East Asian +non-@acronym{ASCII} characters, similarly to Emacs's built-in input +methods (@pxref{Input methods}). However, in some situations the +@acronym{IME} can get in the way if it interprets simple +@acronym{ASCII} keys you input as part of a key sequence that +designates a non-@acronym{ASCII} character. The @acronym{IME} can be +temporarily turned off and then on again by using the +@code{w32-set-ime-open-status} function. @end ifnottex @node Windows Mouse diff --git a/etc/NEWS b/etc/NEWS index 9f3e5b650b..46f59ab869 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -379,6 +379,13 @@ coding-system-for-{read,write} or call 'set-process-coding-system'. 'module-file-suffix' now has the value ".dylib" on macOS, but the ".so" suffix is supported as well. ++++ +** On MS-Windows, Emacs can now toggle the IME. +A new function 'w32-set-ime-open-status' can now be used to disable +and enable the MS-Windows native Input Method Editor (IME) at run +time. A companion function 'w32-get-ime-open-status' returns the +current IME activation status. + ---------------------------------------------------------------------- This file is part of GNU Emacs. commit 61da72dc2df46603a25b0cde2aea82f8f2e7faf8 Author: Eli Zaretskii Date: Mon Apr 13 16:20:14 2020 +0300 ; Fix last change. diff --git a/src/w32fns.c b/src/w32fns.c index 2d1a92be09..dddf3dc571 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -3459,8 +3459,10 @@ w32_msg_pump (deferred_msg * msg_buf) if (!context) break; - BOOL wParam = (BOOL) msg.wParam; - set_ime_open_status_fn (context, wParam); + BOOL new_status = (msg.wParam != 0); + BOOL ime_status = get_ime_open_status_fn (context); + if (new_status != ime_status) + set_ime_open_status_fn (context, new_status); release_ime_context_fn (focus_window, context); break; } commit c6ecdab0ee5b633e184502e5440e3b893cb6a797 Author: Albert Date: Mon Apr 13 18:02:17 2020 +0800 Support toggling native Input Methods on MS-Windows * src/w32term.h (WM_EMACS_IME_STATUS): New message code. * src/w32fns.c (ImmGetOpenStatus_Proc, ImmSetOpenStatus_Proc): New typedefs. (w32_msg_pump): Handle the WM_EMACS_IME_STATUS message. (Fw32_get_ime_open_status, Fw32_set_ime_open_status): New functions (syms_of_w32fns): Defsubr them. (globals_of_w32fns): Load ImmGetOpenStatus and ImmSetOpenStatus from IMM2.DLL. diff --git a/src/w32fns.c b/src/w32fns.c index 8d714f0b8d..2d1a92be09 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -166,6 +166,10 @@ typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window); typedef BOOL (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context); typedef BOOL (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, IN COMPOSITIONFORM *form); +/* For toggling IME status. */ +typedef BOOL (WINAPI * ImmGetOpenStatus_Proc) (IN HIMC); +typedef BOOL (WINAPI * ImmSetOpenStatus_Proc) (IN HIMC, IN BOOL); + typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); typedef BOOL (WINAPI * GetMonitorInfo_Proc) (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); @@ -185,6 +189,8 @@ typedef HRESULT (WINAPI *SetThreadDescription_Proc) TrackMouseEvent_Proc track_mouse_event_fn = NULL; ImmGetCompositionString_Proc get_composition_string_fn = NULL; ImmGetContext_Proc get_ime_context_fn = NULL; +ImmGetOpenStatus_Proc get_ime_open_status_fn = NULL; +ImmSetOpenStatus_Proc set_ime_open_status_fn = NULL; ImmReleaseContext_Proc release_ime_context_fn = NULL; ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; MonitorFromPoint_Proc monitor_from_point_fn = NULL; @@ -3305,6 +3311,7 @@ w32_name_of_message (UINT msg) M (WM_EMACS_SETCURSOR), M (WM_EMACS_SHOWCURSOR), M (WM_EMACS_PAINT), + M (WM_EMACS_IME_STATUS), M (WM_CHAR), #undef M { 0, 0 } @@ -3442,6 +3449,22 @@ w32_msg_pump (deferred_msg * msg_buf) emacs_abort (); } break; + case WM_EMACS_IME_STATUS: + { + focus_window = GetFocus (); + if (!set_ime_open_status_fn || !focus_window) + break; + + HIMC context = get_ime_context_fn (focus_window); + if (!context) + break; + + BOOL wParam = (BOOL) msg.wParam; + set_ime_open_status_fn (context, wParam); + release_ime_context_fn (focus_window, context); + break; + } + #ifdef MSG_DEBUG /* Broadcast messages make it here, so you need to be looking for something in particular for this to be useful. */ @@ -10218,6 +10241,51 @@ DEFUN ("w32-notification-close", #endif /* WINDOWSNT && !HAVE_DBUS */ +DEFUN ("w32-get-ime-open-status", + Fw32_get_ime_open_status, Sw32_get_ime_open_status, + 0, 0, 0, + doc: /* Return non-nil if IME is active, otherwise return nil. + +IME, the MS-Windows Input Method Editor, can be active or inactive. +This function returns non-nil if the IME is active, otherwise nil. */) + (void) +{ + struct frame *sf = + FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame)) + ? XFRAME (selected_frame) + : NULL; + + if (sf) + { + HWND current_window = FRAME_W32_WINDOW (sf); + HIMC context = get_ime_context_fn (current_window); + if (!context) + { + BOOL retval = get_ime_open_status_fn (context); + release_ime_context_fn (current_window, context); + + return retval ? Qt : Qnil; + } + } + + return Qnil; +} + +DEFUN ("w32-set-ime-open-status", + Fw32_set_ime_open_status, Sw32_set_ime_open_status, + 1, 1, 0, + doc: /* Open or close the IME according to STATUS. + +This function activates the IME, the MS-Windows Input Method Editor, +if STATUS is non-nil, otherwise it deactivates the IME. */) + (Lisp_Object status) +{ + unsigned ime_status = NILP (status) ? 0 : 1; + + PostThreadMessage (dwWindowsThreadId, WM_EMACS_IME_STATUS, ime_status, 0); + return Qnil; +} + #ifdef WINDOWSNT /*********************************************************************** @@ -10744,6 +10812,8 @@ tip frame. */); defsubr (&Sw32_notification_notify); defsubr (&Sw32_notification_close); #endif + defsubr (&Sw32_get_ime_open_status); + defsubr (&Sw32_set_ime_open_status); #ifdef WINDOWSNT defsubr (&Sw32_read_registry); @@ -11032,6 +11102,11 @@ globals_of_w32fns (void) get_proc_addr (imm32_lib, "ImmReleaseContext"); set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc) get_proc_addr (imm32_lib, "ImmSetCompositionWindow"); + + get_ime_open_status_fn = (ImmGetOpenStatus_Proc) + get_proc_addr (imm32_lib, "ImmGetOpenStatus"); + set_ime_open_status_fn = (ImmSetOpenStatus_Proc) + get_proc_addr (imm32_lib, "ImmSetOpenStatus"); } HMODULE hm_kernel32 = GetModuleHandle ("kernel32.dll"); diff --git a/src/w32term.h b/src/w32term.h index f8a8a727e8..4e9234f239 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -670,7 +670,8 @@ do { \ #define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 23) #define WM_EMACS_INPUT_READY (WM_EMACS_START + 24) #define WM_EMACS_FILENOTIFY (WM_EMACS_START + 25) -#define WM_EMACS_END (WM_EMACS_START + 26) +#define WM_EMACS_IME_STATUS (WM_EMACS_START + 26) +#define WM_EMACS_END (WM_EMACS_START + 27) #define WND_FONTWIDTH_INDEX (0) #define WND_LINEHEIGHT_INDEX (4) commit f84aed5fd233d59196d942acfb67bb4051c69cf1 Author: Štěpán Němec Date: Tue Mar 31 05:38:50 2020 +0200 Clarify documentation on inhibit-modification-hooks intended usage Cf. bug#40332 and the discussion at https://lists.gnu.org/archive/html/emacs-devel/2020-03/msg00921.html * doc/lispref/text.texi (Change Hooks): * src/insdel.c (syms_of_insdel): Clarify the intended usage of 'inhibit-modification-hooks'. diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index f027cdf8ed..ffdf952b08 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -5776,4 +5776,11 @@ code that is itself run from a modification hook, then rebind locally may cause recursive calls to the modification hooks, so be sure to prepare for that (for example, by binding some variable which tells your hook to do nothing). + +We recommend that you only bind this variable for modifications that +do not result in lasting changes to buffer text contents (for example +face changes or temporary modifications). If you need to delay change +hooks during a series of changes (typically for performance reasons), +use @code{combine-change-calls} or @code{combine-after-change-calls} +instead. @end defvar diff --git a/src/insdel.c b/src/insdel.c index 21acf0e61d..dfa1cc311c 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -2397,7 +2397,13 @@ This affects `before-change-functions' and `after-change-functions', as well as hooks attached to text properties and overlays. Setting this variable non-nil also inhibits file locks and checks whether files are locked by another Emacs session, as well as -handling of the active region per `select-active-regions'. */); +handling of the active region per `select-active-regions'. + +To delay change hooks during a series of changes, use +`combine-change-calls' or `combine-after-change-calls' instead of +binding this variable. + +See also the info node `(elisp) Change Hooks'. */); inhibit_modification_hooks = 0; DEFSYM (Qinhibit_modification_hooks, "inhibit-modification-hooks"); commit 188bd80a903d34ef6a85b09e99890433e7adceb7 Author: Štěpán Němec Date: Sat Mar 7 18:26:44 2020 +0100 gnus-shorten-url: Improve and avoid args-out-of-range error 'gnus-shorten-url' (used by 'gnus-summary-browse-url') ignored fragment identifiers and didn't check substring bounds, in some cases leading to runtime errors, e.g.: (gnus-shorten-url "https://some.url.with/path/and#also_a_long_target" 40) ;; => Lisp error: (args-out-of-range "/path/and" -18 nil) This commit makes it account for #fragments and fixes faulty string computation, reusing existing helper function. (bug#39980) * lisp/vc/ediff-init.el (ediff-truncate-string-left): Rename to 'string-truncate-left' and move... * lisp/emacs-lisp/subr-x.el (string-truncate-left): ...here. All callers changed. * lisp/gnus/gnus-sum.el (gnus-shorten-url): Fix args-out-of-range error, don't drop #fragments, use 'string-truncate-left'. diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 044c9aada0..9f96ac50d1 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -236,6 +236,15 @@ REGEXP defaults to \"[ \\t\\n\\r]+\"." TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"." (string-trim-left (string-trim-right string trim-right) trim-left)) +;;;###autoload +(defun string-truncate-left (string length) + "Truncate STRING to LENGTH, replacing initial surplus with \"...\"." + (let ((strlen (length string))) + (if (<= strlen length) + string + (setq length (max 0 (- length 3))) + (concat "..." (substring string (max 0 (- strlen 1 length))))))) + (defsubst string-blank-p (string) "Check whether STRING is either empty or only whitespace. The following characters count as whitespace here: space, tab, newline and diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index a47e657623..6f367692dd 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -9494,15 +9494,15 @@ The 1st element is the button named by `gnus-collect-urls-primary-text'." (delete-dups urls))) (defun gnus-shorten-url (url max) - "Return an excerpt from URL." + "Return an excerpt from URL not exceeding MAX characters." (if (<= (length url) max) url - (let ((parsed (url-generic-parse-url url))) - (concat (url-host parsed) - "..." - (substring (url-filename parsed) - (- (length (url-filename parsed)) - (max (- max (length (url-host parsed))) 0))))))) + (let* ((parsed (url-generic-parse-url url)) + (host (url-host parsed)) + (rest (concat (url-filename parsed) + (when-let ((target (url-target parsed))) + (concat "#" target))))) + (concat host (string-truncate-left rest (- max (length host))))))) (defun gnus-summary-browse-url (&optional external) "Scan the current article body for links, and offer to browse them. diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el index e59d4b57b5..da6509b7cb 100644 --- a/lisp/vc/ediff-init.el +++ b/lisp/vc/ediff-init.el @@ -1510,16 +1510,6 @@ This default should work without changes." (setq dir (substring dir 0 pos))) (ediff-abbreviate-file-name (file-name-directory dir)))) -(defun ediff-truncate-string-left (str newlen) - ;; leave space for ... on the left - (let ((len (length str)) - substr) - (if (<= len newlen) - str - (setq newlen (max 0 (- newlen 3))) - (setq substr (substring str (max 0 (- len 1 newlen)))) - (concat "..." substr)))) - (defsubst ediff-nonempty-string-p (string) (and (stringp string) (not (string= string "")))) diff --git a/lisp/vc/ediff-mult.el b/lisp/vc/ediff-mult.el index fee87e8352..2b1b07927f 100644 --- a/lisp/vc/ediff-mult.el +++ b/lisp/vc/ediff-mult.el @@ -113,7 +113,6 @@ (require 'ediff-wind) (require 'ediff-util) - ;; meta-buffer (ediff-defvar-local ediff-meta-buffer nil "") (ediff-defvar-local ediff-parent-meta-buffer nil "") @@ -1172,7 +1171,7 @@ behavior." ;; abbreviate the file name, if file exists (if (and (not (stringp fname)) (< file-size -1)) "-------" ; file doesn't exist - (ediff-truncate-string-left + (string-truncate-left (ediff-abbreviate-file-name fname) max-filename-width))))))) @@ -1266,7 +1265,7 @@ Useful commands: (if (= (mod membership-code ediff-membership-code1) 0) ; dir1 (let ((beg (point))) (insert (format "%-27s" - (ediff-truncate-string-left + (string-truncate-left (ediff-abbreviate-file-name (if (file-directory-p (concat dir1 file)) (file-name-as-directory file) @@ -1281,7 +1280,7 @@ Useful commands: (if (= (mod membership-code ediff-membership-code2) 0) ; dir2 (let ((beg (point))) (insert (format "%-26s" - (ediff-truncate-string-left + (string-truncate-left (ediff-abbreviate-file-name (if (file-directory-p (concat dir2 file)) (file-name-as-directory file) @@ -1295,7 +1294,7 @@ Useful commands: (if (= (mod membership-code ediff-membership-code3) 0) ; dir3 (let ((beg (point))) (insert (format " %-25s" - (ediff-truncate-string-left + (string-truncate-left (ediff-abbreviate-file-name (if (file-directory-p (concat dir3 file)) (file-name-as-directory file) commit 81d07da788e7caea266f4a520cd9922c990d04e9 Author: Štěpán Němec Date: Sun Apr 12 19:57:59 2020 +0200 gnus-shorten-url: Improve and avoid args-out-of-range error 'gnus-shorten-url' (used by 'gnus-summary-browse-url') ignored fragment identifiers and didn't check substring bounds, in some cases leading to runtime errors, e.g.: (gnus-shorten-url "https://some.url.with/path/and#also_a_long_target" 40) ;; => Lisp error: (args-out-of-range "/path/and" -18 nil) This commit makes it account for #fragments and fixes faulty string computation. (bug#39980) Do not merge to master, where the helper is put to subr-x.el. * lisp/gnus/gnus-sum.el (gnus--string-truncate-left): New helper function (copied from 'ediff-truncate-string-left'). (gnus-shorten-url): Use it and don't drop #fragments. diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index a40e563e75..9b11d5878d 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -9493,16 +9493,26 @@ The 1st element is the button named by `gnus-collect-urls-primary-text'." (push primary urls)) (delete-dups urls))) +;; cf. `ediff-truncate-string-left', to become `string-truncate-left' +;; in Emacs 28 +(defun gnus--string-truncate-left (string length) + "Truncate STRING to LENGTH, replacing initial surplus with \"...\"." + (let ((strlen (length string))) + (if (<= strlen length) + string + (setq length (max 0 (- length 3))) + (concat "..." (substring string (max 0 (- strlen 1 length))))))) + (defun gnus-shorten-url (url max) - "Return an excerpt from URL." + "Return an excerpt from URL not exceeding MAX characters." (if (<= (length url) max) url - (let ((parsed (url-generic-parse-url url))) - (concat (url-host parsed) - "..." - (substring (url-filename parsed) - (- (length (url-filename parsed)) - (max (- max (length (url-host parsed))) 0))))))) + (let* ((parsed (url-generic-parse-url url)) + (host (url-host parsed)) + (rest (concat (url-filename parsed) + (when-let ((target (url-target parsed))) + (concat "#" target))))) + (concat host (gnus--string-truncate-left rest (- max (length host))))))) (defun gnus-summary-browse-url (&optional external) "Scan the current article body for links, and offer to browse them. commit c395ebaf2142b4a142262353f730fb7b1fcea710 Author: Eli Zaretskii Date: Mon Apr 13 12:25:37 2020 +0300 Fix last change * lisp/mail/rmail.el (rmail-simplified-subject): A prefix can have up to 4 characters, not 3. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 6c9847304f..40d34702e4 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -3408,7 +3408,7 @@ whitespace, replacing whitespace runs with a single space and removing prefixes such as Re:, Fwd: and so on and mailing list tags such as [tag]." (let ((subject (or (rmail-get-header "Subject" msgnum) "")) - (regexp "\\`[ \t\n]*\\(\\(\\w\\{1,3\\}[::]\\|\\[[^]]+]\\)[ \t\n]+\\)*")) + (regexp "\\`[ \t\n]*\\(\\(\\w\\{1,4\\}[::]\\|\\[[^]]+]\\)[ \t\n]+\\)*")) (setq subject (rfc2047-decode-string subject)) (setq subject (replace-regexp-in-string regexp "" subject)) (replace-regexp-in-string "[ \t\n]+" " " subject))) commit 1dfc497fac22c199a944ef64233266bd6cd2fee6 Author: Eli Zaretskii Date: Mon Apr 13 11:53:47 2020 +0300 Minor wording change in Introduction to Programming in Emacs Lisp * doc/lispintro/emacs-lisp-intro.texi (Prevent confusion): Mention that dynamic scoping is only the default in Emacs Lisp, not the only scoping rule. (Bug#40594) diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 9e23f055f5..bd688070a3 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -3667,7 +3667,8 @@ automatically undone when the @code{let} is finished. The setting only affects expressions that are inside the bounds of the @code{let} expression. In computer science jargon, we would say the binding of a symbol is visible only in functions called in the @code{let} form; -in Emacs Lisp, scoping is dynamic, not lexical. +in Emacs Lisp, the default scoping is dynamic, not lexical. (The +non-default lexical binding is not discussed in this manual.) @code{let} can create more than one variable at once. Also, @code{let} gives each variable it creates an initial value, either a commit 49f2811f7827142fd5dcd6c4a53fd7c0c700054f Author: Eli Zaretskii Date: Mon Apr 13 11:43:39 2020 +0300 Improve support of "Re:" in Rmail * lisp/mail/rmail.el (rmail-simplified-subject) (rmail-reply-regexp): Recognize U+FF1A FULLWIDTH COLON as a colon after "Re:"-type prefixes. (rmail-re-abbrevs): New defcustom with localized abbreviations of "Re:". (rmail-reply-regexp): Use 'rmail-re-abbrevs'. Recognize U+FF1A in addition to the ASCII colon. * etc/NEWS: Call out the new defcustom 'rmail-re-abbrevs'. diff --git a/etc/NEWS b/etc/NEWS index 7a7f11f507..9f3e5b650b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -275,6 +275,13 @@ The new default value is 2000000 (2 megabytes). *** New customizable option 'texinfo-texi2dvi-options'. This is used when invoking 'texi2dvi' from 'texinfo-tex-buffer'. +** Rmail + +--- +*** New customizable option 'rmail-re-abbrevs'. +Its default value matches localized abbreviations of the "reply" +prefix on the Subject line in various languages. + * New Modes and Packages in Emacs 28.1 diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index d79cea987e..6c9847304f 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -578,11 +578,21 @@ Examples: (defvar rmail-reply-prefix "Re: " "String to prepend to Subject line when replying to a message.") +;; Note: this is matched with case-fold-search bound to t. +(defcustom rmail-re-abbrevs + "\\(RE\\|رد\\|回复\\|回覆\\|SV\\|Antw\\|VS\\|REF\\|AW\\|ΑΠ\\|ΣΧΕΤ\\|השב\\|Vá\\|R\\|RIF\\|BLS\\|RES\\|Odp\\|YNT\\|ATB\\)" + "Regexp with localized 'Re:' abbreviations in various languages." + :version "28.1" + :type 'regexp) + ;; Some mailers use "Re(2):" or "Re^2:" or "Re: Re:" or "Re[2]:". ;; This pattern should catch all the common variants. ;; rms: I deleted the change to delete tags in square brackets ;; because they mess up RT tags. -(defvar rmail-reply-regexp "\\`\\(Re\\(([0-9]+)\\|\\[[0-9]+\\]\\|\\^[0-9]+\\)?: *\\)*" +(defvar rmail-reply-regexp + (concat "\\`\\(" + rmail-re-abbrevs + "\\(([0-9]+)\\|\\[[0-9]+\\]\\|\\^[0-9]+\\)?[::] *\\)*") "Regexp to delete from Subject line before inserting `rmail-reply-prefix'.") (defcustom rmail-display-summary nil @@ -3398,7 +3408,7 @@ whitespace, replacing whitespace runs with a single space and removing prefixes such as Re:, Fwd: and so on and mailing list tags such as [tag]." (let ((subject (or (rmail-get-header "Subject" msgnum) "")) - (regexp "\\`[ \t\n]*\\(\\(\\w\\{1,3\\}:\\|\\[[^]]+]\\)[ \t\n]+\\)*")) + (regexp "\\`[ \t\n]*\\(\\(\\w\\{1,3\\}[::]\\|\\[[^]]+]\\)[ \t\n]+\\)*")) (setq subject (rfc2047-decode-string subject)) (setq subject (replace-regexp-in-string regexp "" subject)) (replace-regexp-in-string "[ \t\n]+" " " subject))) commit ff09b4eeac7703ed60acc8c8635a5baf7a6fda34 Author: Eli Zaretskii Date: Mon Apr 13 08:00:14 2020 +0300 Fix 'flymake-show-diagnostics-buffer' when line numbers are displayed * lisp/progmodes/flymake.el (flymake--diagnostics-buffer-entries): Do nothing if 'flymake--diagnostics-buffer-source' is not a buffer. (Bug#40529) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 25a2152f00..7fca9dac1a 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -1321,35 +1321,42 @@ POS can be a buffer position or a button" (flymake-show-diagnostic (if (button-type pos) (button-start pos) pos)))) (defun flymake--diagnostics-buffer-entries () - (with-current-buffer flymake--diagnostics-buffer-source - (cl-loop for diag in - (cl-sort (flymake-diagnostics) #'< :key #'flymake-diagnostic-beg) - for (line . col) = - (save-excursion - (goto-char (flymake--diag-beg diag)) - (cons (line-number-at-pos) - (- (point) - (line-beginning-position)))) - for type = (flymake--diag-type diag) - collect - (list (list :diagnostic diag - :line line - :severity (flymake--lookup-type-property - type - 'severity (warning-numeric-level :error))) - `[,(format "%s" line) - ,(format "%s" col) - ,(propertize (format "%s" - (flymake--lookup-type-property - type 'flymake-type-name type)) - 'face (flymake--lookup-type-property - type 'mode-line-face 'flymake-error)) - (,(format "%s" (flymake--diag-text diag)) - mouse-face highlight - help-echo "mouse-2: visit this diagnostic" - face nil - action flymake-goto-diagnostic - mouse-action flymake-goto-diagnostic)])))) + ;; Do nothing if 'flymake--diagnostics-buffer-source' has not yet + ;; been set to a valid buffer. This could happen when this function + ;; is called too early. For example 'global-display-line-numbers-mode' + ;; calls us from its mode hook, when the diagnostic buffer has just + ;; been created by 'flymake-show-diagnostics-buffer', but is not yet + ;; set up properly. + (when (bufferp flymake--diagnostics-buffer-source) + (with-current-buffer flymake--diagnostics-buffer-source + (cl-loop for diag in + (cl-sort (flymake-diagnostics) #'< :key #'flymake-diagnostic-beg) + for (line . col) = + (save-excursion + (goto-char (flymake--diag-beg diag)) + (cons (line-number-at-pos) + (- (point) + (line-beginning-position)))) + for type = (flymake--diag-type diag) + collect + (list (list :diagnostic diag + :line line + :severity (flymake--lookup-type-property + type + 'severity (warning-numeric-level :error))) + `[,(format "%s" line) + ,(format "%s" col) + ,(propertize (format "%s" + (flymake--lookup-type-property + type 'flymake-type-name type)) + 'face (flymake--lookup-type-property + type 'mode-line-face 'flymake-error)) + (,(format "%s" (flymake--diag-text diag)) + mouse-face highlight + help-echo "mouse-2: visit this diagnostic" + face nil + action flymake-goto-diagnostic + mouse-action flymake-goto-diagnostic)]))))) (define-derived-mode flymake-diagnostics-buffer-mode tabulated-list-mode "Flymake diagnostics" commit 63e8d0ea877117394f76b5213eecf0441b88c7e6 Author: Eli Zaretskii Date: Sun Apr 12 21:47:52 2020 +0300 Fix last changes describing mail commands * doc/emacs/sending.texi (Sending Mail): Fix the description of the behavior of 'C-x m' without prefix argument. (Bug#40561) diff --git a/doc/emacs/sending.texi b/doc/emacs/sending.texi index a2895493c1..e3f9fbec07 100644 --- a/doc/emacs/sending.texi +++ b/doc/emacs/sending.texi @@ -32,14 +32,14 @@ In the mail buffer, send the message and bury the buffer The mail buffer is an ordinary Emacs buffer, so you can switch to other buffers while composing the mail. If you want to send another -mail before sending the current one, type @kbd{C-x m} again, and Emacs -will switch back to the last mail buffer and ask if you want to erase -the message in that buffer; answer yes to discard the unsent message -and start composing a new one. If you know that you'd like to -continue composing an unsent message, invoke this command with a -prefix argument, @w{@kbd{C-u C-x m}}, and Emacs will switch to the -last mail buffer and let you pick up editing the message where you -left off. +message before finishing the current one, type @kbd{C-x m} again to +open a new mail buffer whose name has a different numeric suffix +(@pxref{Misc Buffer}). (This only works if you use the default +Message mode to compose email; see @ref{Mail Commands}.) If you know +that you'd like to continue composing the unsent message you were +editing, invoke this command with a prefix argument, @w{@kbd{C-u C-x +m}}, and Emacs will switch to the last mail buffer you used and let +you pick up editing the message where you left off. @kindex C-x 4 m @findex compose-mail-other-window commit 01212a762f2977e1f95036ee37ff3e68a28f467b Author: João Távora Date: Sun Apr 12 15:17:15 2020 +0100 Do setup Flymake in file-less Elisp buffers Fixes: bug#40573 * lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Change condition for setting flymake-diagnostic-functions. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 2617a6e4cc..f39ecf9b7b 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -264,9 +264,9 @@ Blank lines separate paragraphs. Semicolons start comments. (unless (let* ((bfname (buffer-file-name)) (fname (and (stringp bfname) (file-name-nondirectory bfname)))) - (or (not (stringp fname)) - (string-match "\\`\\.#" fname) - (string-equal dir-locals-file fname))) + (and (stringp fname) + (or (string-match "\\`\\.#" fname) + (string-equal dir-locals-file fname)))) (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t) (add-hook 'flymake-diagnostic-functions #'elisp-flymake-byte-compile nil t))) commit 36873ef2b268d8d8be1ed8b517c90be2c1dcdc8b Author: Philipp Stephani Date: Sun Apr 12 15:11:22 2020 +0200 Fix error message for ‘cl-struct-unknown-slot’ (bug#39995) * lisp/emacs-lisp/cl-macs.el (cl-struct-unknown-slot): Remove spurious format specifiers. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index c4f69120ff..9edd85e36b 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3110,7 +3110,7 @@ slots skipped by :initial-offset may appear in the list." descs))) (nreverse descs))) -(define-error 'cl-struct-unknown-slot "struct %S has no slot %S") +(define-error 'cl-struct-unknown-slot "struct has no slot") (defun cl-struct-slot-offset (struct-type slot-name) "Return the offset of slot SLOT-NAME in STRUCT-TYPE. commit 3f9310b0fecbd842244798fb9a62d56b2151c534 Author: Eli Zaretskii Date: Sun Apr 12 11:31:29 2020 +0300 Fix and improve documentation of mail-related features * lisp/simple.el (compose-mail): Clarify the effect of the CONTINUE argument. * lisp/mail/sendmail.el (mail-from-style): Update the RFC value in the obsolescence warning text. * doc/emacs/sending.texi (Sending Mail): Fix the description of the behavior of 'C-x m' wrt prefix argument. (Mail Headers): Remove the description of 'mail-from-style'. * etc/NEWS: Mention that 'mail-from-style' is obsolete. (Bug#40561) diff --git a/doc/emacs/sending.texi b/doc/emacs/sending.texi index 190549a194..a2895493c1 100644 --- a/doc/emacs/sending.texi +++ b/doc/emacs/sending.texi @@ -32,12 +32,13 @@ In the mail buffer, send the message and bury the buffer The mail buffer is an ordinary Emacs buffer, so you can switch to other buffers while composing the mail. If you want to send another -mail before finishing the current one, type @kbd{C-x m} again to open -a new mail buffer whose name has a different numeric suffix -(@pxref{Misc Buffer}). If you invoke the command with a prefix -argument, @w{@kbd{C-u C-x m}}, Emacs switches back to the last mail -buffer, and asks if you want to erase the message in that buffer; if -you answer no, this lets you pick up editing the message where you +mail before sending the current one, type @kbd{C-x m} again, and Emacs +will switch back to the last mail buffer and ask if you want to erase +the message in that buffer; answer yes to discard the unsent message +and start composing a new one. If you know that you'd like to +continue composing an unsent message, invoke this command with a +prefix argument, @w{@kbd{C-u C-x m}}, and Emacs will switch to the +last mail buffer and let you pick up editing the message where you left off. @kindex C-x 4 m @@ -122,26 +123,6 @@ environment variables (@pxref{General Variables}). If this information is unavailable or wrong, you should customize the variables yourself (@pxref{Easy Customization}). -@vindex mail-from-style - The value of the variable @code{mail-from-style} specifies how to -format the contents of the @samp{From} field: - -@table @asis -@item @code{nil} -Use just the address, as in @samp{king@@grassland.com}. -@item @code{parens} -Use both address and full name, as in:@* -@samp{king@@grassland.com (Elvis Parsley)}. -@item @code{angles} -Use both address and full name, as in:@* -@samp{Elvis Parsley }. -@item any other value -Use @code{angles} normally. But if the address must be quoted to -remain syntactically valid under the @code{angles} format but not -under the @code{parens} format, use @code{parens} instead. This is -the default. -@end table - Apart from @samp{From}, here is a table of commonly-used fields: @table @samp diff --git a/etc/NEWS b/etc/NEWS index 44a92ecbdd..f4edfaf9be 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2239,6 +2239,10 @@ The option is useful for two reasons when verifying the signature: 2.2.17 to fully benefit from this feature. See gpg(1) man page for "--auto-key-retrieve". ++++ +*** The 'mail-from-style' variable is now obsolete. +According to RFC 5322, only the 'angles' value is valid. + --- ** EasyPG diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index 14adb5a195..65d598c3ba 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el @@ -73,7 +73,7 @@ Otherwise, most addresses look like `angles', but they look like :version "27.1") (make-obsolete-variable 'mail-from-style - "only the `angles' value is valid according to RFC2822." "27.1" 'set) + "only the `angles' value is valid according to RFC5322." "27.1" 'set) ;;;###autoload (defcustom mail-specify-envelope-from nil diff --git a/lisp/simple.el b/lisp/simple.el index cb04c98222..da9e04d16a 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -8020,8 +8020,12 @@ OTHER-HEADERS is an alist specifying additional header fields. Elements look like (HEADER . VALUE) where both HEADER and VALUE are strings. -CONTINUE, if non-nil, says to continue editing a message already -being composed. Interactively, CONTINUE is the prefix argument. +By default, if an unsent message is already being composed, this +command will ask whether to erase the unsent message, and will not +start a new message if the user doesn't allow erasing. However, if +CONTINUE is non-nil, it means to continue editing a message already +being composed without asking. Interactively, CONTINUE is the prefix +argument. SWITCH-FUNCTION, if non-nil, is a function to use to switch to and display the buffer used for mail composition. commit 1482a75efa7e198b38bd6871c1b35eedc2c94fca Author: Martin Rudalics Date: Sun Apr 12 10:00:28 2020 +0200 Fix build failure with Fx_gtk_debug * src/xfns.c (Fx_gtk_debug, Sx_gtk_debug): Define only for GTK versions >= 3.14.0 so gtk_window_set_interactive_debugging is defined. Reported by Andreas Schwab . diff --git a/src/xfns.c b/src/xfns.c index 0fc553012b..a5431aa890 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -7755,6 +7755,7 @@ Note: Text drawn with the `x' font backend is shown with hollow boxes. */) #ifdef USE_GTK #ifdef HAVE_GTK3 +#if GTK_CHECK_VERSION (3, 14, 0) DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 0, doc: /* Toggle interactive GTK debugging. */) (Lisp_Object enable) @@ -7767,6 +7768,7 @@ DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 0, return NILP (enable) ? Qnil : Qt; } +#endif /* GTK_CHECK_VERSION (3, 14, 0) */ #endif /* HAVE_GTK3 */ #endif /* USE_GTK */ @@ -8154,7 +8156,9 @@ eliminated in future versions of Emacs. */); #endif #ifdef USE_GTK #ifdef HAVE_GTK3 +#if GTK_CHECK_VERSION (3, 14, 0) defsubr (&Sx_gtk_debug); #endif #endif +#endif } commit cf57663f2ab80814d17eee0f21b498262f933d89 Author: Alan Mackenzie Date: Sat Apr 11 21:04:50 2020 +0000 Mention jit-lock deferred as an alternative to fast-but-imprecise-scrolling * doc/emacs/display.texi (Scrolling): Add a paragraph on using jit-lock deferred fontification as a way of obviating Emacs hanging after auto-repeated scrolling. diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 8444aef3bd..4273357995 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -141,6 +141,15 @@ default face. This can cause Emacs to scroll to somewhat wrong buffer positions when the faces in use are not all the same size, even with single (i.e., without auto-repeat) scrolling operations. +@vindex jit-lock-defer-time +As an alternative to setting @code{fast-but-imprecise-scrolling} you +might prefer to enable jit-lock deferred fontification (@pxref{Font +Lock}). To do this, customize @code{jit-lock-defer-time} to a small +positive number such as 0.25, or even 0.1 if you type quickly. This +gives you less jerky scrolling when you hold down @kbd{C-v}, but the +window contents after any action which scrolls into a fresh portion of +the buffer will be momentarily unfontified. + @vindex scroll-up @vindex scroll-down @findex scroll-up-line