commit e68912ea6be6338f3ca659cb01ec2bd616e8e660 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Fri Nov 15 01:28:33 2019 -0800 Port hexdigit init to non-GCC + pdumper The old code assumed that hexdigit initialization (needed by non-GCC) could be done in syms_of_character, but that is no longer true with pdumper. Instead, simplify hexdigit init so that it can be done statically on all C99 platforms. Problem discovered on Solaris 10 sparc + Oracle Solaris Studio 12.6. * src/character.c (hexdigit): Add 1 to every value; all uses changed. This simplifies the initialization so that it can be done statically on any C99 compiler. hexdigit is now always const. (syms_of_character): Omit no-longer-necessary initialization. * src/character.h (HEXDIGIT_CONST, HEXDIGIT_IS_CONST): Remove. All uses removed. diff --git a/src/character.c b/src/character.c index a80e6f8de0..708eb2f702 100644 --- a/src/character.c +++ b/src/character.c @@ -1082,26 +1082,21 @@ confusable_symbol_character_p (int ch) } } -signed char HEXDIGIT_CONST hexdigit[UCHAR_MAX + 1] = +/* hexdigit[C] is one greater than C's numeric value if C is a + hexadecimal digit, zero otherwise. */ +signed char const hexdigit[UCHAR_MAX + 1] = { -#if HEXDIGIT_IS_CONST - [0 ... UCHAR_MAX] = -1, -#endif - ['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4, - ['5'] = 5, ['6'] = 6, ['7'] = 7, ['8'] = 8, ['9'] = 9, - ['A'] = 10, ['B'] = 11, ['C'] = 12, ['D'] = 13, ['E'] = 14, ['F'] = 15, - ['a'] = 10, ['b'] = 11, ['c'] = 12, ['d'] = 13, ['e'] = 14, ['f'] = 15 + ['0'] = 1 + 0, ['1'] = 1 + 1, ['2'] = 1 + 2, ['3'] = 1 + 3, ['4'] = 1 + 4, + ['5'] = 1 + 5, ['6'] = 1 + 6, ['7'] = 1 + 7, ['8'] = 1 + 8, ['9'] = 1 + 9, + ['A'] = 1 + 10, ['B'] = 1 + 11, ['C'] = 1 + 12, + ['D'] = 1 + 13, ['E'] = 1 + 14, ['F'] = 1 + 15, + ['a'] = 1 + 10, ['b'] = 1 + 11, ['c'] = 1 + 12, + ['d'] = 1 + 13, ['e'] = 1 + 14, ['f'] = 1 + 15 }; void syms_of_character (void) { -#if !HEXDIGIT_IS_CONST - /* Set the non-hex digit values to -1. */ - for (int i = 0; i <= UCHAR_MAX; i++) - hexdigit[i] -= i != '0' && !hexdigit[i]; -#endif - DEFSYM (Qcharacterp, "characterp"); DEFSYM (Qauto_fill_chars, "auto-fill-chars"); diff --git a/src/character.h b/src/character.h index cc57a2a7d5..230fc6eab5 100644 --- a/src/character.h +++ b/src/character.h @@ -704,14 +704,7 @@ char_table_translate (Lisp_Object obj, int ch) return CHARACTERP (obj) ? XFIXNUM (obj) : ch; } -#if defined __GNUC__ && !defined __STRICT_ANSI__ -# define HEXDIGIT_CONST const -# define HEXDIGIT_IS_CONST true -#else -# define HEXDIGIT_CONST -# define HEXDIGIT_IS_CONST false -#endif -extern signed char HEXDIGIT_CONST hexdigit[]; +extern signed char const hexdigit[]; /* If C is a hexadecimal digit ('0'-'9', 'a'-'f', 'A'-'F'), return its value (0-15). Otherwise return -1. */ @@ -719,7 +712,7 @@ extern signed char HEXDIGIT_CONST hexdigit[]; INLINE int char_hexdigit (int c) { - return 0 <= c && c <= UCHAR_MAX ? hexdigit[c] : -1; + return 0 <= c && c <= UCHAR_MAX ? hexdigit[c] - 1 : -1; } INLINE_HEADER_END commit 0114bb964afd81b6a6dc8c742bceba61d0f2a7dc Author: Eli Zaretskii Date: Fri Nov 15 11:16:09 2019 +0200 Improve documentation of 'add-variable-watcher' * doc/lispref/variables.texi (Watching Variables): Clarify the documentation of 'add-variable-watcher' and fix markup. * src/data.c (Fadd_variable_watcher): Clarify the doc string. (Bug#38205) diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index f92540dbd3..f7fe738ac3 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -832,10 +832,10 @@ error is signaled. @cindex watchpoints for Lisp variables It is sometimes useful to take some action when a variable changes its -value. The watchpoint facility provides the means to do so. Some -possible uses for this feature include keeping display in sync with -variable settings, and invoking the debugger to track down unexpected -changes to variables (@pxref{Variable Debugging}). +value. The @dfn{variable watchpoint} facility provides the means to +do so. Some possible uses for this feature include keeping display in +sync with variable settings, and invoking the debugger to track down +unexpected changes to variables (@pxref{Variable Debugging}). The following functions may be used to manipulate and query the watch functions for a variable. @@ -845,15 +845,17 @@ This function arranges for @var{watch-function} to be called whenever @var{symbol} is modified. Modifications through aliases (@pxref{Variable Aliases}) will have the same effect. -@var{watch-function} will be called with 4 arguments: (@var{symbol} -@var{newval} @var{operation} @var{where}). - -@var{symbol} is the variable being changed. -@var{newval} is the value it will be changed to. -@var{operation} is a symbol representing the kind of change, one of: -`set', `let', `unlet', `makunbound', and `defvaralias'. -@var{where} is a buffer if the buffer-local value of the variable is -being changed, @code{nil} otherwise. +@var{watch-function} will be called, just before changing the value of +@var{symbol}, with 4 arguments: @var{symbol}, @var{newval}, +@var{operation}, and @var{where}. +@var{symbol} is the variable being changed. @var{newval} is the value +it will be changed to. (The old value is available to +@var{watch-function} as the value of @var{symbol}, since it was not +yet changed to @var{newval}.) @var{operation} is a symbol +representing the kind of change, one of: @code{set}, @code{let}, +@code{unlet}, @code{makunbound}, or @code{defvaralias}. @var{where} +is a buffer if the buffer-local value of the variable is being +changed, @code{nil} otherwise. @end defun @defun remove-variable-watch symbol watch-function diff --git a/src/data.c b/src/data.c index 9efcd72f93..26e8611304 100644 --- a/src/data.c +++ b/src/data.c @@ -1472,11 +1472,12 @@ harmonize_variable_watchers (Lisp_Object alias, Lisp_Object base_variable) DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher, 2, 2, 0, - doc: /* Cause WATCH-FUNCTION to be called when SYMBOL is set. + doc: /* Cause WATCH-FUNCTION to be called when SYMBOL is about to be set. It will be called with 4 arguments: (SYMBOL NEWVAL OPERATION WHERE). SYMBOL is the variable being changed. -NEWVAL is the value it will be changed to. +NEWVAL is the value it will be changed to. (The variable still has +the old value when WATCH-FUNCTION is called.) OPERATION is a symbol representing the kind of change, one of: `set', `let', `unlet', `makunbound', and `defvaralias'. WHERE is a buffer if the buffer-local value of the variable is being commit 3495cefcf67e508152097a53e6505f214e46fa9e Author: Lars Ingebrigtsen Date: Fri Nov 15 10:04:23 2019 +0100 Avoid using subr-x function * lisp/vc/vc-hg.el (vc-hg-retrieve-tag): Avoid using subr-x function (bug#38216). diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 48a7838684..6ecf9fb41d 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -578,7 +578,8 @@ Optional arg REVISION is a revision to annotate from." (defun vc-hg-retrieve-tag (dir name _update) "Retrieve the version tagged by NAME of all registered files at or below DIR." (let ((default-directory dir)) - (vc-hg-command nil 0 nil "update" (unless (string-empty-p name) name)) + (vc-hg-command nil 0 nil "update" (and (not (equal name "")) + name)) ;; TODO: update *vc-change-log* buffer so can see @ if --graph )) commit fb3dea96b7930a83bba156b5ad9f6fdca72fa7d8 Author: Martin Rudalics Date: Fri Nov 15 09:43:02 2019 +0100 In 'dframe-frame-mode' avoid 'switch-to-buffer' (Bug#37840) * lisp/dframe.el (dframe-frame-mode): Use 'set-window-buffer' instead of 'switch-to-buffer’ to avoid that 'switch-to-buffer-obey-display-actions' butts in (Bug#37840). diff --git a/lisp/dframe.el b/lisp/dframe.el index 91f89e1705..dc9b30add5 100644 --- a/lisp/dframe.el +++ b/lisp/dframe.el @@ -309,8 +309,10 @@ CREATE-HOOK is a hook to run after creating a frame." (make-frame-visible (symbol-value frame-var)) (select-frame (symbol-value frame-var)) (set-window-dedicated-p (selected-window) nil) - (if (not (eq (current-buffer) (symbol-value buffer-var))) - (switch-to-buffer (symbol-value buffer-var))) + (unless (eq (current-buffer) (symbol-value buffer-var)) + ;; To avoid that 'switch-to-buffer-obey-display-actions' + ;; butts in, use plain 'set-window-buffer' (Bug#37840). + (set-window-buffer nil (symbol-value buffer-var))) (set-window-dedicated-p (selected-window) t) (raise-frame (symbol-value frame-var)) ) @@ -346,7 +348,9 @@ CREATE-HOOK is a hook to run after creating a frame." ;; Put the buffer into the frame (save-excursion (select-frame (symbol-value frame-var)) - (switch-to-buffer (symbol-value buffer-var)) + ;; To avoid that 'switch-to-buffer-obey-display-actions' + ;; butts in, use plain 'set-window-buffer' (Bug#37840). + (set-window-buffer nil (symbol-value buffer-var)) (set-window-dedicated-p (selected-window) t)) ;; Run hooks (like reposition) (run-hooks create-hook) commit 3db1de04527acee3a5cdd563c848582e85e0f77e Author: Andrii Kolomoiets Date: Fri Nov 15 09:13:55 2019 +0100 lisp/vc/vc-hg.el: Don't pass empty string to hg update * lisp/vc/vc-hg.el (vc-hg-retrieve-tag): Don't pass empty name to `hg update` (bug#38216). diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 16e5dd6db0..48a7838684 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -578,7 +578,7 @@ Optional arg REVISION is a revision to annotate from." (defun vc-hg-retrieve-tag (dir name _update) "Retrieve the version tagged by NAME of all registered files at or below DIR." (let ((default-directory dir)) - (vc-hg-command nil 0 nil "update" name) + (vc-hg-command nil 0 nil "update" (unless (string-empty-p name) name)) ;; TODO: update *vc-change-log* buffer so can see @ if --graph )) commit 35ab18c03cf2ec5f7f1f8c511d656cd96f24d007 Author: Lele Gaifax Date: Fri Nov 15 09:10:24 2019 +0100 Fix minor formatting issue in isearch-forward documentation * lisp/isearch.el (isearch-forward): Doc string formatting fix (bug#38207). diff --git a/lisp/isearch.el b/lisp/isearch.el index a46f4fc3ee..4f3342782d 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -1049,8 +1049,8 @@ Type \\[isearch-occur] to run `occur' that shows\ the last search string. Type \\[isearch-highlight-regexp] to run `highlight-regexp'\ that highlights the last search string. -Type \\[isearch-highlight-lines-matching-regexp] to run - `highlight-lines-matching-regexp'\ that highlights lines +Type \\[isearch-highlight-lines-matching-regexp] to run\ + `highlight-lines-matching-regexp' that highlights lines matching the last search string. Type \\[isearch-describe-bindings] to display all Isearch key bindings. commit ecc21845eaac931dc12ac5057296fbf742336a02 Author: Lars Ingebrigtsen Date: Fri Nov 15 09:00:49 2019 +0100 Make edebug-remove-instrumentation remove macro instrumentation * lisp/emacs-lisp/edebug.el (edebug-remove-instrumentation): Macros can also have edebug instrumentation, so remove that as well (bug#38195). diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 6b55d7cff0..5d52704410 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -4580,8 +4580,9 @@ instrumentation for, defaulting to all functions." (let ((functions nil)) (mapatoms (lambda (symbol) - (when (and (functionp symbol) - (get symbol 'edebug)) + (when (and (get symbol 'edebug) + (or (functionp symbol) + (macrop symbol))) (let ((unwrapped (edebug-unwrap* (symbol-function symbol)))) (unless (equal unwrapped (symbol-function symbol)) (push symbol functions))))) commit 06ac04a8ec4fd5ff3f51a174192511a75d104822 Author: Robert Pluim Date: Fri Nov 15 08:56:08 2019 +0100 Update nnir-method-default-engines version tag * lisp/gnus/nnir.el (nnir-method-default-engines): Update version tag. diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el index b8a6639719..3b6b8255f7 100644 --- a/lisp/gnus/nnir.el +++ b/lisp/gnus/nnir.el @@ -580,7 +580,7 @@ Add an entry here when adding a new search engine.") (defcustom nnir-method-default-engines '((nnimap . imap)) "Alist of default search engines keyed by server method." - :version "24.1" + :version "27.1" :group 'nnir :type `(repeat (cons (choice (const nnimap) (const nntp) (const nnspool) (const nneething) (const nndir) (const nnmbox) commit 81d3f1b6b1a34e831aabc91b8c0208efdadf6ca8 Author: Eli Zaretskii Date: Fri Nov 15 09:54:43 2019 +0200 Fix a recent change in xdisp.c * src/xdisp.c (tty_handle_tab_bar_click): Revert the last change which made this work only in the HAVE_NTGUI build. This function is needed by any build which supports a mouse on TTY frames. diff --git a/src/xdisp.c b/src/xdisp.c index 320e0731de..8aefab964a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13437,8 +13437,6 @@ tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end) return Qnil; } -#if defined HAVE_NTGUI && !defined CYGWIN - /* Handle a mouse click at X/Y on the tab bar of TTY frame F. If the click was on the tab bar and was handled, populate the EVENT structure, store it in keyboard queue, and return true; otherwise @@ -13501,7 +13499,6 @@ tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, return true; } -#endif /* HAVE_NTGUI && !CYGWIN */ commit 8b848def9bc3c4ad786670d0447a6fb396f2ff30 Author: Paul Eggert Date: Thu Nov 14 18:51:17 2019 -0800 Handle weird cases like (ceil 0 0.0) * src/floatfns.c (double_integer_scale): Distinguish Inf from NaN. (rounding_driver): Handle (ceil 0 0.0) and (ceil 0 1.0e+INF). * test/src/floatfns-tests.el (special-round): Add tests for weird cases like this. Avoid crash with (floor 0 0.0) * src/floatfns.c (rounding_driver): Signal an arithmetic error if divisor is 0.0 or -0.0, instead of crashing. diff --git a/src/floatfns.c b/src/floatfns.c index a626845377..30526a1644 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -340,9 +340,8 @@ This is the same as the exponent of a float. */) representable as a double. Return DBL_MANT_DIG - DBL_MIN_EXP (the maximum possible valid - scale) if D is zero or tiny. Return a value greater than - DBL_MANT_DIG - DBL_MIN_EXP if there is conversion trouble; on all - current platforms this can happen only if D is infinite or a NaN. */ + scale) if D is zero or tiny. Return one greater than that if + D is infinite, and two greater than that if D is a NaN. */ int double_integer_scale (double d) @@ -351,11 +350,10 @@ double_integer_scale (double d) return (DBL_MIN_EXP - 1 <= exponent && exponent < INT_MAX ? DBL_MANT_DIG - 1 - exponent : (DBL_MANT_DIG - DBL_MIN_EXP - + (exponent == INT_MAX - || (exponent == FP_ILOGBNAN - && (FP_ILOGBNAN != FP_ILOGB0 || isnan (d))) - || (!IEEE_FLOATING_POINT && exponent == INT_MIN - && (FP_ILOGB0 != INT_MIN || d != 0))))); + + ((exponent == FP_ILOGBNAN + && (FP_ILOGBNAN != FP_ILOGB0 || isnan (d))) + ? 2 + : exponent == INT_MAX))); } /* Convert the Lisp number N to an integer and return a pointer to the @@ -404,6 +402,7 @@ rounding_driver (Lisp_Object n, Lisp_Object d, CHECK_NUMBER (d); + int dscale = 0; if (FIXNUMP (d)) { if (XFIXNUM (d) == 0) @@ -413,9 +412,21 @@ rounding_driver (Lisp_Object n, Lisp_Object d, if (FIXNUMP (n)) return make_int (fixnum_divide (XFIXNUM (n), XFIXNUM (d))); } + else if (FLOATP (d)) + { + if (XFLOAT_DATA (d) == 0) + xsignal0 (Qarith_error); + dscale = double_integer_scale (XFLOAT_DATA (d)); + } int nscale = FLOATP (n) ? double_integer_scale (XFLOAT_DATA (n)) : 0; - int dscale = FLOATP (d) ? double_integer_scale (XFLOAT_DATA (d)) : 0; + + /* If the numerator is finite and the denominator infinite, the + quotient is zero and there is no need to try the impossible task + of rescaling the denominator. */ + if (dscale == DBL_MANT_DIG - DBL_MIN_EXP + 1 && nscale < dscale) + return make_fixnum (0); + int_divide (mpz[0], *rescale_for_division (n, &mpz[0], nscale, dscale), *rescale_for_division (d, &mpz[1], dscale, nscale)); diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el index 7f1d4691bf..0eef3de75f 100644 --- a/test/src/floatfns-tests.el +++ b/test/src/floatfns-tests.el @@ -106,19 +106,17 @@ (zerop (% (round n d) 2))))))))))) (ert-deftest special-round () - (let ((ns '(-1e+INF 1e+INF -1 1 -1e+NaN 1e+NaN))) - (dolist (n ns) - (unless (<= (abs n) 1) - (should-error (ceiling n)) - (should-error (floor n)) - (should-error (round n)) - (should-error (truncate n))) - (dolist (d ns) - (unless (<= (abs (/ n d)) 1) - (should-error (ceiling n d)) - (should-error (floor n d)) - (should-error (round n d)) - (should-error (truncate n d))))))) + (dolist (f '(ceiling floor round truncate)) + (let ((ns '(-1e+INF 1e+INF -1 -0.0 0.0 0 1 -1e+NaN 1e+NaN))) + (dolist (n ns) + (if (not (<= (abs n) 1)) + (should-error (funcall f n)) + (should (= n (funcall f n))) + (dolist (d '(-1e+INF 1e+INF)) + (should (eq 0 (funcall f n d))))) + (dolist (d ns) + (when (or (zerop d) (= (abs n) 1e+INF) (not (= n n)) (not (= d d))) + (should-error (funcall f n d)))))))) (ert-deftest big-round () (should (= (floor 54043195528445955 3) commit 6ea1e35f6f8b89b979e660bf04bda1757c0cdff0 Author: Stefan Monnier Date: Thu Nov 14 18:55:18 2019 -0500 * lisp/cedet/semantic/db.el: Use lexical-binding Also prefer setf over oset. (semanticdb-abstract-table-list): Always define. (semanticdb--inhibit-make-directory): Fix name of declaration to match name of variable actually used. (semanticdb-with-match-any-mode): Use `declare`. Add Edebug spec. (semanticdb-project-roots): Remove redundant :group. diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el index 8847fcc755..3b33f096b4 100644 --- a/lisp/cedet/semantic/db.el +++ b/lisp/cedet/semantic/db.el @@ -1,4 +1,4 @@ -;;; semantic/db.el --- Semantic tag database manager +;;; semantic/db.el --- Semantic tag database manager -*- lexical-binding:t -*- ;; Copyright (C) 2000-2019 Free Software Foundation, Inc. @@ -115,11 +115,11 @@ This table is the root of tables, and contains the minimum needed for a new table not associated with a buffer." :abstract t) -(cl-defmethod semanticdb-in-buffer-p ((obj semanticdb-abstract-table)) +(cl-defmethod semanticdb-in-buffer-p ((_obj semanticdb-abstract-table)) "Return a nil, meaning abstract table OBJ is not in a buffer." nil) -(cl-defmethod semanticdb-get-buffer ((obj semanticdb-abstract-table)) +(cl-defmethod semanticdb-get-buffer ((_obj semanticdb-abstract-table)) "Return a buffer associated with OBJ. If the buffer is not in memory, load it with `find-file-noselect'." nil) @@ -136,23 +136,23 @@ This uses semanticdb to get a better file name." ((and (stringp buffer-or-string) (file-exists-p buffer-or-string)) (expand-file-name buffer-or-string)))) -(cl-defmethod semanticdb-full-filename ((obj semanticdb-abstract-table)) +(cl-defmethod semanticdb-full-filename ((_obj semanticdb-abstract-table)) "Fetch the full filename that OBJ refers to. Abstract tables do not have file names associated with them." nil) -(cl-defmethod semanticdb-dirty-p ((obj semanticdb-abstract-table)) +(cl-defmethod semanticdb-dirty-p ((_obj semanticdb-abstract-table)) "Return non-nil if OBJ is dirty." nil) -(cl-defmethod semanticdb-set-dirty ((obj semanticdb-abstract-table)) +(cl-defmethod semanticdb-set-dirty ((_obj semanticdb-abstract-table)) "Mark the abstract table OBJ dirty. Abstract tables can not be marked dirty, as there is nothing for them to synchronize against." ;; The abstract table can not be dirty. nil) -(cl-defmethod semanticdb-normalize-tags ((obj semanticdb-abstract-table) tags) +(cl-defmethod semanticdb-normalize-tags ((_obj semanticdb-abstract-table) tags) "For the table OBJ, convert a list of TAGS, into standardized form. The default is to return TAGS. Some databases may default to searching and providing simplified tags @@ -194,17 +194,18 @@ If one doesn't exist, create it." ;; Fill in the defaults :table obj )) - (oset obj index idx) + (setf (slot-value obj 'index) idx) idx))) -(cl-defmethod semanticdb-synchronize ((idx semanticdb-abstract-search-index) - new-tags) +(cl-defmethod semanticdb-synchronize ((_idx semanticdb-abstract-search-index) + _new-tags) "Synchronize the search index IDX with some NEW-TAGS." ;; The abstract class will do... NOTHING! ) -(cl-defmethod semanticdb-partial-synchronize ((idx semanticdb-abstract-search-index) - new-tags) +(cl-defmethod semanticdb-partial-synchronize + ((_idx semanticdb-abstract-search-index) + _new-tags) "Synchronize the search index IDX with some changed NEW-TAGS." ;; The abstract class will do... NOTHING! ) @@ -221,7 +222,8 @@ If one doesn't exist, create it." Examples include search results from external sources such as from Emacs's own symbol table, or from external libraries.") -(cl-defmethod semanticdb-refresh-table ((obj semanticdb-search-results-table) &optional force) +(cl-defmethod semanticdb-refresh-table ((_obj semanticdb-search-results-table) + &optional _force) "If the tag list associated with OBJ is loaded, refresh it. This will call `semantic-fetch-tags' if that file is in memory." nil) @@ -279,7 +281,7 @@ If the buffer is in memory, return that buffer." (let ((buff (oref obj buffer))) (if (buffer-live-p buff) buff - (oset obj buffer nil)))) + (setf (slot-value obj 'buffer) nil)))) (cl-defmethod semanticdb-get-buffer ((obj semanticdb-table)) "Return a buffer associated with OBJ. @@ -301,7 +303,7 @@ If OBJ's file is not loaded, read it in first." (cl-defmethod semanticdb-set-dirty ((obj semanticdb-table)) "Mark the abstract table OBJ dirty." - (oset obj dirty t) + (setf (slot-value obj 'dirty) t) ) (cl-defmethod semanticdb-debug-info ((obj semanticdb-table)) @@ -319,9 +321,8 @@ Adds the number of tags in this file to the object print name." ;;; DATABASE BASE CLASS ;; -(unless (fboundp 'semanticdb-abstract-table-list-p) - (cl-deftype semanticdb-abstract-table-list () - '(list-of semanticdb-abstract-table))) +(cl-deftype semanticdb-abstract-table-list () + '(list-of semanticdb-abstract-table)) (defclass semanticdb-project-database (eieio-instance-tracker) ((tracking-symbol :initform semanticdb-database-list) @@ -357,7 +358,7 @@ Note: This index will not be saved in a persistent file.") (expand-file-name (oref obj file) (oref (oref obj parent-db) reference-directory))) -(cl-defmethod semanticdb-full-filename ((obj semanticdb-project-database)) +(cl-defmethod semanticdb-full-filename ((_obj semanticdb-project-database)) "Fetch the full filename that OBJ refers to. Abstract tables do not have file names associated with them." nil) @@ -385,7 +386,7 @@ Adds the number of tables in this file to the object print name." (princ (eieio-object-name obj (semanticdb-debug-info obj)) stream)) -(cl-defmethod semanticdb-create-database ((dbc (subclass semanticdb-project-database)) directory) +(cl-defmethod semanticdb-create-database ((_dbc (subclass semanticdb-project-database)) directory) "Create a new semantic database of class DBC for DIRECTORY and return it. If a database for DIRECTORY has already been created, return it. If DIRECTORY doesn't exist, create a new one." @@ -396,12 +397,12 @@ If DIRECTORY doesn't exist, create a new one." :tables nil)) ;; Set this up here. We can't put it in the constructor because it ;; would be saved, and we want DB files to be portable. - (oset db reference-directory (file-truename directory))) + (setf (slot-value db 'reference-directory) (file-truename directory))) db)) (cl-defmethod semanticdb-flush-database-tables ((db semanticdb-project-database)) "Reset the tables in DB to be empty." - (oset db tables nil)) + (setf (slot-value db 'tables) nil)) (cl-defmethod semanticdb-create-table ((db semanticdb-project-database) file) "Create a new table in DB for FILE and return it. @@ -416,7 +417,7 @@ If the table for FILE does not exist, create one." (file-name-nondirectory file) :file (file-name-nondirectory file) )) - (oset newtab parent-db db) + (setf (slot-value newtab 'parent-db) db) (object-add-to-list db 'tables newtab t)) newtab)) @@ -495,14 +496,14 @@ other than :table." "Remove from TABLE the cache object CACHE." (object-remove-from-list table 'cache cache)) -(cl-defmethod semanticdb-synchronize ((cache semanticdb-abstract-cache) - new-tags) +(cl-defmethod semanticdb-synchronize ((_cache semanticdb-abstract-cache) + _new-tags) "Synchronize a CACHE with some NEW-TAGS." ;; The abstract class will do... NOTHING! ) -(cl-defmethod semanticdb-partial-synchronize ((cache semanticdb-abstract-cache) - new-tags) +(cl-defmethod semanticdb-partial-synchronize ((_cache semanticdb-abstract-cache) + _new-tags) "Synchronize a CACHE with some changed NEW-TAGS." ;; The abstract class will do... NOTHING! ) @@ -547,14 +548,14 @@ other than :table." (object-remove-from-list db 'cache cache)) -(cl-defmethod semanticdb-synchronize ((cache semanticdb-abstract-db-cache) - new-tags) +(cl-defmethod semanticdb-synchronize ((_cache semanticdb-abstract-db-cache) + _new-tags) "Synchronize a CACHE with some NEW-TAGS." ;; The abstract class will do... NOTHING! ) -(cl-defmethod semanticdb-partial-synchronize ((cache semanticdb-abstract-db-cache) - new-tags) +(cl-defmethod semanticdb-partial-synchronize ((_cache semanticdb-abstract-db-cache) + _new-tags) "Synchronize a CACHE with some changed NEW-TAGS." ;; The abstract class will do... NOTHING! ) @@ -622,17 +623,18 @@ The file associated with OBJ does not need to be in a buffer." (cl-defmethod semanticdb-synchronize ((table semanticdb-abstract-table) new-tags) "Synchronize the table TABLE with some NEW-TAGS." - (oset table tags new-tags) - (oset table pointmax (point-max)) + (setf (slot-value table 'tags) new-tags) + (setf (slot-value table 'pointmax) (point-max)) (let ((fattr (file-attributes (semanticdb-full-filename table)))) - (oset table fsize (file-attribute-size fattr)) - (oset table lastmodtime (file-attribute-modification-time fattr)) - ) + (setf (slot-value table 'fsize) (file-attribute-size fattr)) + (setf (slot-value table 'lastmodtime) + (file-attribute-modification-time fattr))) + ;; Assume it is now up to date. - (oset table unmatched-syntax semantic-unmatched-syntax-cache) + (setf (slot-value table 'unmatched-syntax) semantic-unmatched-syntax-cache) ;; The lexical table should be good too. (when (featurep 'semantic/lex-spp) - (oset table lexical-table (semantic-lex-spp-save-table))) + (setf (slot-value table 'lexical-table) (semantic-lex-spp-save-table))) ;; this implies dirtiness (semanticdb-set-dirty table) @@ -655,16 +657,16 @@ The file associated with OBJ does not need to be in a buffer." "Synchronize the table TABLE where some NEW-TAGS changed." ;; You might think we need to reset the tags, but since the partial ;; parser splices the lists, we don't need to do anything - ;;(oset table tags new-tags) + ;;(setf (slot-value table 'tags) new-tags) ;; We do need to mark ourselves dirty. (semanticdb-set-dirty table) ;; The lexical table may be modified. (when (featurep 'semantic/lex-spp) - (oset table lexical-table (semantic-lex-spp-save-table))) + (setf (slot-value table 'lexical-table) (semantic-lex-spp-save-table))) ;; Incremental parser doesn't monkey around with this. - (oset table unmatched-syntax semantic-unmatched-syntax-cache) + (setf (slot-value table 'unmatched-syntax) semantic-unmatched-syntax-cache) ;; Synchronize the index (when (slot-boundp table 'index) @@ -683,8 +685,8 @@ The file associated with OBJ does not need to be in a buffer." ;;; SAVE/LOAD ;; -(cl-defmethod semanticdb-save-db ((DB semanticdb-project-database) - &optional suppress-questions) +(cl-defmethod semanticdb-save-db ((_DB semanticdb-project-database) + &optional _suppress-questions) "Cause a database to save itself. The database base class does not save itself persistently. Subclasses could save themselves to a file, or to a database, or other @@ -702,7 +704,7 @@ form." ;; This prevents Semanticdb from querying multiple times if the users ;; answers "no" to creating the Semanticdb directory. -(defvar semanticdb--inhibit-create-file-directory) +(defvar semanticdb--inhibit-make-directory) (defun semanticdb-save-all-db () "Save all semantic tag databases." @@ -710,7 +712,7 @@ form." (unless noninteractive (message "Saving tag summaries...")) (let ((semanticdb--inhibit-make-directory noninteractive)) - (mapc 'semanticdb-save-db semanticdb-database-list)) + (mapc #'semanticdb-save-db semanticdb-database-list)) (unless noninteractive (message "Saving tag summaries...done"))) @@ -737,7 +739,7 @@ Project Management software (such as EDE and JDE) should add their own predicates with `add-hook' to this variable, and semanticdb will save tag caches in directories controlled by them.") -(cl-defmethod semanticdb-write-directory-p ((obj semanticdb-project-database)) +(cl-defmethod semanticdb-write-directory-p ((_obj semanticdb-project-database)) "Return non-nil if OBJ should be written to disk. Uses `semanticdb-persistent-path' to determine the return value." nil) @@ -764,9 +766,9 @@ Do not set the value of this variable permanently.") (defmacro semanticdb-with-match-any-mode (&rest body) "A Semanticdb search occurring withing BODY will search tags in all modes. This temporarily sets `semanticdb-match-any-mode' while executing BODY." + (declare (indent 0) (debug t)) `(let ((semanticdb-match-any-mode t)) ,@body)) -(put 'semanticdb-with-match-any-mode 'lisp-indent-function 0) (cl-defmethod semanticdb-equivalent-mode-for-search (table &optional buffer) "Return non-nil if TABLE's mode is equivalent to BUFFER. @@ -779,7 +781,7 @@ all files of any type." (semanticdb-equivalent-mode table buffer)) ) -(cl-defmethod semanticdb-equivalent-mode ((table semanticdb-abstract-table) &optional buffer) +(cl-defmethod semanticdb-equivalent-mode ((_table semanticdb-abstract-table) &optional _buffer) "Return non-nil if TABLE's mode is equivalent to BUFFER. Equivalent modes are specified by the `semantic-equivalent-major-modes' local variable." @@ -813,7 +815,6 @@ local variable." All subdirectories of a root project are considered a part of one project. Values in this string can be overridden by project management programs via the `semanticdb-project-root-functions' variable." - :group 'semanticdb :type '(repeat string)) (defvar semanticdb-project-root-functions nil commit c2cd8e6265b78a5f0be3335ea6d8868e80814db0 Author: Paul Eggert Date: Thu Nov 14 14:42:39 2019 -0800 Fix byte-counting error in ‘format’ Problem reported by Paul Pogonyshev (Bug#38191). * src/editfns.c (styled_format): When checking for adjacent %-sequences, use byte position rather than character position. * test/src/editfns-tests.el (format-properties): Test for fix. diff --git a/src/editfns.c b/src/editfns.c index 1b33f39711..8fc866d391 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3143,7 +3143,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) /* The start and end bytepos in the output string. */ ptrdiff_t start, end; - /* The start of the spec in the format string. */ + /* The start bytepos of the spec in the format string. */ ptrdiff_t fbeg; /* Whether the argument is a string with intervals. */ @@ -3954,7 +3954,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) { position++; if (fieldn < nspec - && position > info[fieldn].fbeg + && bytepos >= info[fieldn].fbeg && translated == info[fieldn].start) { translated += info[fieldn].end - info[fieldn].start; @@ -3976,7 +3976,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) { position++; if (fieldn < nspec - && position > info[fieldn].fbeg + && bytepos >= info[fieldn].fbeg && translated == info[fieldn].start) { translated += info[fieldn].end - info[fieldn].start; diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index a1060808f6..238fb409f0 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el @@ -90,6 +90,10 @@ (propertize "45" 'face 'italic))) #("012345 " 0 2 (face bold) 2 4 (face underline) 4 10 (face italic)))) + ;; Bug #38191 + (should (ert-equal-including-properties + (format (propertize "‘foo’ %s bar" 'face 'bold) "xxx") + #("‘foo’ xxx bar" 0 13 (face bold)))) ;; Bug #32404 (should (ert-equal-including-properties (format (concat (propertize "%s" 'face 'bold) commit 2241f7ca7adb8aa7d785174dec0280a07cd16479 Author: Paul Eggert Date: Thu Nov 14 14:00:07 2019 -0800 In Cairo builds, omit some unnecessary functions * src/font.c (fset_font_data, font_put_frame_data) (font_get_frame_data): * src/ftfont.c (ftfont_open, ftfont_close) (ftfont_encode_char, ftfont_glyph_metrics) (ftfont_text_extents, ftfont_driver): Define only if USE_CAIRO. * src/xdisp.c (tty_handle_tab_bar_click): Define only if HAVE_NTGUI && !CYGWIN. diff --git a/src/font.c b/src/font.c index 7c8e9e30c9..b987a453d6 100644 --- a/src/font.c +++ b/src/font.c @@ -3650,7 +3650,7 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers) return active_drivers; } -#if defined (HAVE_XFT) || defined (HAVE_FREETYPE) +#if (defined HAVE_XFT || defined HAVE_FREETYPE) && !defined USE_CAIRO static void fset_font_data (struct frame *f, Lisp_Object val) @@ -3683,7 +3683,7 @@ font_get_frame_data (struct frame *f, Lisp_Object driver) return NILP (val) ? NULL : xmint_pointer (XCDR (val)); } -#endif /* HAVE_XFT || HAVE_FREETYPE */ +#endif /* (HAVE_XFT || HAVE_FREETYPE) && !USE_CAIRO */ /* Sets attributes on a font. Any properties that appear in ALIST and BOOLEAN_PROPERTIES or NON_BOOLEAN_PROPERTIES are set on the font. diff --git a/src/ftfont.c b/src/ftfont.c index 77a4cf5de5..d649c991dd 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -1264,6 +1264,8 @@ ftfont_entity_pattern (Lisp_Object entity, int pixel_size) return pat; } +#ifndef USE_CAIRO + Lisp_Object ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { @@ -1459,6 +1461,8 @@ ftfont_close (struct font *font) FT_Done_Size (ftfont_info->ft_size); } +#endif /* !USE_CAIRO */ + int ftfont_has_char (Lisp_Object font, int c) { @@ -1489,6 +1493,8 @@ ftfont_has_char (Lisp_Object font, int c) } } +#ifndef USE_CAIRO + unsigned ftfont_encode_char (struct font *font, int c) { @@ -1560,6 +1566,8 @@ ftfont_text_extents (struct font *font, const unsigned int *code, metrics->width = width; } +#endif /* !USE_CAIRO */ + int ftfont_get_bitmap (struct font *font, unsigned int code, struct font_bitmap *bitmap, int bits_per_pixel) { @@ -3031,6 +3039,8 @@ ftfont_combining_capability (struct font *font) static void syms_of_ftfont_for_pdumper (void); +#ifndef USE_CAIRO + static struct font_driver const ftfont_driver = { /* We can't draw a text without device dependent functions. */ @@ -3059,6 +3069,8 @@ static struct font_driver const ftfont_driver = .combining_capability = ftfont_combining_capability, }; +#endif /* !USE_CAIRO */ + void syms_of_ftfont (void) { diff --git a/src/xdisp.c b/src/xdisp.c index 8aefab964a..320e0731de 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13437,6 +13437,8 @@ tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end) return Qnil; } +#if defined HAVE_NTGUI && !defined CYGWIN + /* Handle a mouse click at X/Y on the tab bar of TTY frame F. If the click was on the tab bar and was handled, populate the EVENT structure, store it in keyboard queue, and return true; otherwise @@ -13499,6 +13501,7 @@ tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, return true; } +#endif /* HAVE_NTGUI && !CYGWIN */ commit 6a2a371c288a13060c44fa1af3ab73db611705a4 Author: Dmitry Gutov Date: Thu Nov 14 23:41:07 2019 +0200 (repos-count-screen-lines): Narrow without changing point-min * lisp/reposition.el (repos-count-screen-lines): Narrow without changing point-min. It wasn't necessary for vertical-motion to work, and it had some adverse effects on how font-lock rules were applied (https://lists.gnu.org/archive/html/emacs-devel/2019-11/msg00522.html). This can also be an alternative fix for bug#38049. diff --git a/lisp/reposition.el b/lisp/reposition.el index 22f9986efb..111bc0841f 100644 --- a/lisp/reposition.el +++ b/lisp/reposition.el @@ -170,12 +170,13 @@ first comment line visible (if point is in a comment)." ;;; Auxiliary functions + ;; Return number of screen lines between START and END. (defun repos-count-screen-lines (start end) (save-excursion (save-restriction - (narrow-to-region start end) - (goto-char (point-min)) + (narrow-to-region (point-min) end) + (goto-char start) (vertical-motion (- (point-max) (point-min)))))) ;; Return number of screen lines between START and END; returns a negative commit c455e609bdf065c3177eec29234348809cdc372c Author: Alan Mackenzie Date: Thu Nov 14 19:51:01 2019 +0000 CC Mode: Fix two bugs in the "state cache". This (along with a suggestion to the OP to set open-paren-in-column-0-is-defun-start to nil) fixes bug #37910. It may also have fixed bug #5490 and bug #18072. * lisp/progmodes/cc-engine.el (c-state-cache-non-literal-place): Remove thi non-sensical function, replacing it with .... (c-state-cache-lower-good-pos): New function. (c-renarrow-state-cache, c-append-lower-brace-pair-to-state-cache) (c-remove-stale-state-cache, c-remove-stale-state-cache-backwards): Instead of altering the state-cache list structure with setcar and setcdr, use setq and consing. (c-parse-state-1): Call c-state-cache-lower-good-pos rather than c-state-cache-non-literal-place. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 15b23bb2e6..e2f822951c 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -3366,19 +3366,35 @@ comment at the start of cc-engine.el for more info." (or (car (c-state-literal-at pos)) pos)) -(defsubst c-state-cache-non-literal-place (pos state) - ;; Return a position outside of a string/comment/macro at or before POS. - ;; STATE is the parse-partial-sexp state at POS. - (let ((res (if (or (nth 3 state) ; in a string? - (and (nth 4 state) - (not (eq (nth 7 state) 'syntax-table)))) ; in a comment? - (nth 8 state) - pos))) +(defun c-state-cache-lower-good-pos (here pos state) + ;; Return a good pos (in the sense of `c-state-cache-good-pos') at the + ;; lowest[*] position between POS and HERE which is syntactically equivalent + ;; to HERE. This position may be HERE itself. POS is before HERE in the + ;; buffer. + ;; [*] We don't actually always determine this exact position, since this + ;; would require a disproportionate amount of work, given that this function + ;; deals only with a corner condition, and POS and HERE are typically on + ;; adjacent lines. We actually return either POS, when POS is a good + ;; position, HERE otherwise. Exceptionally, when POS is in a comment, but + ;; HERE not, we can return the position of the end of the comment. + (let (s) (save-excursion - (goto-char res) - (if (c-beginning-of-macro) - (point) - res)))) + (goto-char pos) + (when (nth 8 state) ; POS in a comment or string. Move out of it. + (setq s (parse-partial-sexp pos here nil nil state 'syntax-table)) + (when (< (point) here) + (setq pos (point) + state s))) + (if (eq (point) here) ; HERE is in the same literal as POS + pos + (setq s (parse-partial-sexp pos here (1+ (car state)) nil state nil)) + (cond + ((> (car s) (car state)) ; Moved into a paren between POS and HERE + here) + ((not (eq (nth 6 s) (car state))) ; Moved out of a paren between POS + ; and HERE + here) + (t pos)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Stuff to do with point-min, and coping with any literal there. @@ -3685,7 +3701,13 @@ comment at the start of cc-engine.el for more info." ; brace pair. (setq c-state-cache nil c-state-cache-good-pos c-state-min-scan-pos) - (setcdr ptr nil) + ;; Do not alter the original `c-state-cache' structure, since there + ;; may be a loop suspended which is looping through that structure. + ;; This may have been the cause of bug #37910. + (let ((cdr-ptr (cdr ptr))) + (setcdr ptr nil) + (setq c-state-cache (copy-sequence c-state-cache)) + (setcdr ptr cdr-ptr)) (setq c-state-cache-good-pos (1+ (c-state-cache-top-lparen)))) ))) @@ -3788,11 +3810,12 @@ comment at the start of cc-engine.el for more info." (setq new-cons (cons bra (1+ ce))) (cond ((consp (car c-state-cache)) - (setcar c-state-cache new-cons)) + (setq c-state-cache (cons new-cons (cdr c-state-cache)))) ((and (numberp (car c-state-cache)) ; probably never happens (< ce (car c-state-cache))) - (setcdr c-state-cache - (cons new-cons (cdr c-state-cache)))) + (setq c-state-cache + (cons (car c-state-cache) + (cons new-cons (cdr c-state-cache))))) (t (setq c-state-cache (cons new-cons c-state-cache))))) ;; We haven't found a brace pair. Record this in the cache. @@ -3993,7 +4016,7 @@ comment at the start of cc-engine.el for more info." (when (and c-state-cache (consp (car c-state-cache)) (> (cdar c-state-cache) upper-lim)) - (setcar c-state-cache (caar c-state-cache)) + (setq c-state-cache (cons (caar c-state-cache) (cdr c-state-cache))) (setq scan-back-pos (car c-state-cache) cons-separated t)) @@ -4130,7 +4153,7 @@ comment at the start of cc-engine.el for more info." ;; knowledge of what's inside these braces, we have no alternative but ;; to direct the caller to scan the buffer from the opening brace. (setq pos (caar c-state-cache)) - (setcar c-state-cache pos) + (setq c-state-cache (cons pos (cdr c-state-cache))) (list (1+ pos) pos t)) ; return value. We've just converted a brace pair ; entry into a { entry, so the caller needs to ; search for a brace pair before the {. @@ -4380,7 +4403,7 @@ comment at the start of cc-engine.el for more info." (setq c-state-cache-good-pos (if (and bopl-state (< good-pos (- here c-state-cache-too-far))) - (c-state-cache-non-literal-place here-bopl bopl-state) + (c-state-cache-lower-good-pos here here-bopl bopl-state) good-pos))) ((eq strategy 'backward) commit 30e944b66b24254e007381c80237e96c721a127c Author: Robert Pluim Date: Thu Nov 14 15:40:12 2019 +0100 Remove unneeded font_is_ignored prototype * src/gtkutil.h: Remove unneeded prototype for font_is_ignored, it's in font.h now. diff --git a/src/gtkutil.h b/src/gtkutil.h index a059f53219..5795eb7342 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -204,9 +204,5 @@ extern bool xg_ignore_gtk_scrollbar; extern bool xg_gtk_initialized; -#if GTK_CHECK_VERSION (3, 2, 0) -extern bool font_is_ignored (const char *, ptrdiff_t); -#endif - #endif /* USE_GTK */ #endif /* GTKUTIL_H */ commit 99550f20a0cf294e271a1132ff1e5e57554c74f2 Author: Robert Pluim Date: Thu Nov 14 13:18:58 2019 +0100 ; Add explanation for face-ignored-fonts defaults diff --git a/src/xfaces.c b/src/xfaces.c index d2dfbffe4e..7ca60c87b1 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6777,13 +6777,14 @@ other font of the appropriate family and registry is available. */); Each element is a regular expression that matches names of fonts to ignore. */); #ifdef HAVE_XFT - /* Bug#37786. */ + /* This font causes libXft crashes, so ignore it by default. Bug#37786. */ Vface_ignored_fonts = list1 (build_string ("Noto Color Emoji")); #else Vface_ignored_fonts = Qnil; #endif #ifdef HAVE_OTF_KANNADA_BUG - /* https://debbugs.gnu.org/30193 */ + /* This font causes libotf crashes, so ignore it when we know we're + using a vulnerable version. https://debbugs.gnu.org/30193 */ Vface_ignored_fonts = Fcons (build_string ("Noto Serif Kannada"), Vface_ignored_fonts); #endif commit 31be86c3478b1ca587357bf6b2c8be8c68d6f047 Merge: ab36b56e40 5803558cbf Author: Eli Zaretskii Date: Thu Nov 14 13:51:38 2019 +0200 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit ab36b56e40c6af3b3deb8ad768e410d4838615f9 Author: Eli Zaretskii Date: Thu Nov 14 13:50:45 2019 +0200 ; * src/font.h (font_is_ignored): Add prototype to avoid warnings. diff --git a/src/font.h b/src/font.h index 9d4b2d81c6..9ce46e8eab 100644 --- a/src/font.h +++ b/src/font.h @@ -836,6 +836,7 @@ extern Lisp_Object font_style_symbolic (Lisp_Object font, bool for_face); extern bool font_match_p (Lisp_Object spec, Lisp_Object font); +extern bool font_is_ignored (const char *name, ptrdiff_t namelen); extern Lisp_Object font_list_entities (struct frame *, Lisp_Object); extern Lisp_Object font_get_name (Lisp_Object font_object); commit 5803558cbf76ddae52d760b6329bbc1095524793 Merge: 75875cac21 77c3bc0297 Author: Phil Sainty Date: Fri Nov 15 00:43:46 2019 +1300 Merge branch 'scratch/so-long-updates' commit 77c3bc0297b41283da941f80a59c96fc8fc14936 Author: Phil Sainty Date: Sat Nov 9 19:52:06 2019 +1300 Make so-long disable flymake, flyspell, flycheck * so-long.el (so-long-minor-modes): Add flymake-mode, flyspell-mode, and flycheck-mode. diff --git a/lisp/so-long.el b/lisp/so-long.el index 2d551affa1..78fa32508a 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -731,6 +731,8 @@ was established." '(font-lock-mode ;; (Generally the most important). ;; Other standard minor modes: display-line-numbers-mode + flymake-mode + flyspell-mode goto-address-mode goto-address-prog-mode hi-lock-mode @@ -746,6 +748,7 @@ was established." diff-hl-flydiff-mode diff-hl-mode dtrt-indent-mode + flycheck-mode hl-sexp-mode idle-highlight-mode rainbow-delimiters-mode commit a94f961e625aa53deaf8605f892fd8993a4f0cb8 Author: Phil Sainty Date: Tue Oct 22 00:05:50 2019 +1300 Support loading so-long.el on top of an earlier version * so-long.el (so-long-version, so-long--latest-version): New variables. This enables users to safely load version 1.0 of so-long.el on top of an earlier version, as well as making provisions for doing likewise following any incompatible changes arising in future versions. diff --git a/lisp/so-long.el b/lisp/so-long.el index 982a699667..2d551affa1 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -411,6 +411,8 @@ (add-to-list 'customize-package-emacs-version-alist '(so-long ("1.0" . "27.1"))) +(defconst so-long--latest-version "1.0") + (declare-function longlines-mode "longlines") (defvar longlines-mode) @@ -1818,6 +1820,54 @@ If it appears in `%s', you should remove it." (cdr hookfunc))) (make-obsolete (car hookfunc) nil "so-long.el version 1.0"))) +;; Live upgrades, for when a newer version is loaded over an older one. +;; +;; If `so-long-version' was already bound then that tells us which version we +;; should upgrade from. If `so-long-version' is unbound then most likely there +;; was no older version loaded; however, prior to version 1.0 `so-long-version' +;; was not defined at all, and so we also need to detect that scenario, which +;; we can do by testing for the presence of a symbol which was removed in 1.0. +;; +;; The variable `so-long-mode-enabled' covers versions 0.5 - 0.7.6, which is +;; every pre-1.0 release using the name "so-long.el". +(defvar so-long-version (if (boundp 'so-long-mode-enabled) + "0.5" ;; >= 0.5 and < 1.0 + so-long--latest-version) + "The loaded version of so-long.el.") + +;; Version-specific updates. +(when (version< so-long-version so-long--latest-version) + ;; Perform each update in sequence, as necessary. + ;; Update to version 1.0 from earlier versions: + (when (version< so-long-version "1.0") + (remove-hook 'change-major-mode-hook 'so-long-change-major-mode) + (require 'advice) + (when (ad-find-advice 'hack-local-variables 'after 'so-long--file-local-mode) + (ad-remove-advice 'hack-local-variables 'after 'so-long--file-local-mode) + (ad-activate 'hack-local-variables)) + (when (ad-find-advice 'set-auto-mode 'around 'so-long--set-auto-mode) + (ad-remove-advice 'set-auto-mode 'around 'so-long--set-auto-mode) + (ad-activate 'set-auto-mode)) + (when (boundp 'so-long-mode-map) + (define-key so-long-mode-map [remap so-long-mode-revert] #'so-long-revert)) + (dolist (var '(so-long-mode--inhibited + so-long-original-mode)) + (makunbound var)) + (dolist (func '(so-long-change-major-mode + so-long-check-header-modes + so-long-line-detected-p)) + (fmakunbound func)) + (defvar so-long-mode-enabled) + (when so-long-mode-enabled + (unless global-so-long-mode + (global-so-long-mode 1))) + (makunbound 'so-long-mode-enabled)) + ;; Update to version 1.N: + ;; (when (version< so-long-version "1.N") ...) + ;; + ;; All updates completed. + (setq so-long-version so-long--latest-version)) + (provide 'so-long) commit b28f35ac65631243b8e29856a2d13e70d2567b53 Author: Phil Sainty Date: Tue Oct 22 00:01:59 2019 +1300 Backwards-compatibility function definitions for so-long.el * so-long.el (so-long-inhibit-whitespace-mode) (so-long-make-buffer-read-only, so-long-revert-buffer-read-only) (so-long-inhibit-global-hl-line-mode): Restore dummy definitions of now-obsolete hook functions used by earlier versions of so-long.el, to support users who have saved these symbols in their customized values for the hooks in question. diff --git a/lisp/so-long.el b/lisp/so-long.el index 5c9711b0bb..982a699667 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -1801,6 +1801,23 @@ or call the function `global-so-long-mode'.") (message "Error unloading so-long: %S %S" (car err) (cdr err)) t)))) +;; Backwards-compatibility definitions. +;; +;; The following obsolete functions may exist in the user's customized hook +;; values dating from versions < 1.0, so we need to ensure that such saved +;; values will not trigger errors. +(cl-flet ((ignore () nil)) + (dolist (hookfunc '((so-long-inhibit-whitespace-mode . so-long-hook) + (so-long-make-buffer-read-only . so-long-hook) + (so-long-revert-buffer-read-only . so-long-revert-hook) + (so-long-inhibit-global-hl-line-mode . so-long-mode-hook))) + (defalias (car hookfunc) #'ignore + (format "Obsolete function. It now does nothing. + +If it appears in `%s', you should remove it." + (cdr hookfunc))) + (make-obsolete (car hookfunc) nil "so-long.el version 1.0"))) + (provide 'so-long) commit bf29fc46c81114909bcfe9c4b60bd419651b49a7 Author: Phil Sainty Date: Tue Oct 22 00:00:16 2019 +1300 * lisp/so-long.el (so-long-unload-function): Improved feature unload diff --git a/lisp/so-long.el b/lisp/so-long.el index e76ab791fc..5c9711b0bb 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -1761,14 +1761,45 @@ or call the function `global-so-long-mode'.") (defun so-long-unload-function () "Handler for `unload-feature'." - (global-so-long-mode 0) - ;; Remove buffer-local `window-configuration-change-hook' values set by - ;; `so-long-deferred'. - (dolist (buf (buffer-list)) - (with-current-buffer buf - (remove-hook 'window-configuration-change-hook #'so-long :local))) - ;; Return nil. Refer to `unload-feature'. - nil) + (condition-case err + (progn + (global-so-long-mode 0) + ;; Process existing buffers. + (dolist (buf (buffer-list)) + (with-current-buffer buf + ;; Remove buffer-local `window-configuration-change-hook' values set + ;; by `so-long-deferred'. + (remove-hook 'window-configuration-change-hook #'so-long :local) + ;; Call `so-long-revert' in all buffers where so-long is active. + (when (bound-and-true-p so-long--active) + (so-long-revert)))) + ;; Un-define our buffer-local variables, as `unload-feature' will not do + ;; this automatically. We remove them from `unload-function-defs-list' + ;; as well, to prevent them being redefined. n.b.: `so-long--active' is + ;; tested (above) using `bound-and-true-p' because that is one of the + ;; variables which we unbind (below); and if something subsequent to + ;; this handler signals an error, the user may need to call this again. + (defvar unload-function-defs-list) + (dolist (var '(so-long--active + so-long--inhibited + so-long-detected-p + so-long-file-local-mode-function + so-long-function + so-long-minor-mode + so-long-mode-abbrev-table + so-long-mode-line-info + so-long-mode-syntax-table + so-long-original-values + so-long-revert-function)) + (makunbound var) + (setq unload-function-defs-list + (delq var unload-function-defs-list))) + ;; Return nil if unloading was successful. Refer to `unload-feature'. + nil) + ;; If any error occurred, return non-nil. + (error (progn + (message "Error unloading so-long: %S %S" (car err) (cdr err)) + t)))) (provide 'so-long) commit cb7b63d6e2da14eb92f8f535837fdae04c89dfb2 Author: Phil Sainty Date: Mon Oct 21 23:57:55 2019 +1300 ; * lisp/so-long.el (so-long-predicate): Custom type consistency This is for consistency with the other function options, which all used the 'radio' custom type. diff --git a/lisp/so-long.el b/lisp/so-long.el index f7dfc8a79c..e76ab791fc 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -545,8 +545,8 @@ The specified function will be called with no arguments. If it returns non-nil then `so-long' will be invoked. Defaults to `so-long-detected-long-line-p'." - :type '(choice (const so-long-detected-long-line-p) - (function :tag "Custom function")) + :type '(radio (const so-long-detected-long-line-p) + (function :tag "Custom function")) :package-version '(so-long . "1.0") :group 'so-long) commit e9dca2b5aa43116980321259682ad0c68fd0f937 Author: Phil Sainty Date: Mon Oct 21 23:52:29 2019 +1300 Defer triggering `so-long' until the buffer is displayed * lisp/so-long.el (so-long-invisible-buffer-function): New user option. (so-long--set-auto-mode): Use so-long-invisible-buffer-function. (so-long-deferred): New function/value for so-long-invisible-buffer-function. (so-long, so-long--disable): Support for so-long-deferred. * test/lisp/so-long-tests/autoload-longlines-mode-tests.el * test/lisp/so-long-tests/autoload-major-mode-tests.el * test/lisp/so-long-tests/autoload-minor-mode-tests.el * test/lisp/so-long-tests/so-long-tests.el: Support for so-long-deferred. Pre-existing tests have been updated to ensure the buffer is already displayed in cases where a call to `normal-mode' is the (potential) trigger for `so-long'. diff --git a/lisp/so-long.el b/lisp/so-long.el index 8d9b0dc062..f7dfc8a79c 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -162,6 +162,23 @@ ;; this option can also be configured to inhibit so-long entirely in this ;; scenario, or to not treat a file-local mode as a special case at all. +;; * Buffers which are not displayed in a window +;; --------------------------------------------- +;; When a file with long lines is visited and the buffer is not displayed right +;; away, it may be that it is not intended to be displayed at all, and that it +;; has instead been visited for behind-the-scenes processing by some library. +;; Invisible buffers are less likely to cause performance issues, and it also +;; might be surprising to the other library if such a buffer were manipulated by +;; `so-long' (which might in turn lead to confusing errors for the user); so in +;; these situations the `so-long-invisible-buffer-function' value is called +;; instead. By default this arranges for `so-long' to be invoked on the buffer +;; if and when it is displayed, but not otherwise. +;; +;; This 'deferred call' is actually the most common scenario -- even when a +;; visited file is displayed "right away", it is normal for the buffer to be +;; invisible when `global-so-long-mode' processes it, and the gap between +;; "arranging to call" and "calling" `so-long' is simply extremely brief. + ;; * Inhibiting and disabling minor modes ;; -------------------------------------- ;; Certain minor modes cause significant performance issues in the presence of @@ -345,6 +362,7 @@ ;; - New user option `so-long-variable-overrides'. ;; - New user option `so-long-skip-leading-comments'. ;; - New user option `so-long-file-local-mode-function'. +;; - New user option `so-long-invisible-buffer-function'. ;; - New user option `so-long-predicate'. ;; - New variable and function `so-long-function'. ;; - New variable and function `so-long-revert-function'. @@ -487,6 +505,37 @@ files would prevent Emacs from handling them correctly." :package-version '(so-long . "1.0") :group 'so-long) +(defcustom so-long-invisible-buffer-function #'so-long-deferred + "Function called in place of `so-long' when the buffer is not displayed. + +This affects the behaviour of `global-so-long-mode'. + +We treat invisible buffers differently from displayed buffers because, in +cases where a library is using a buffer for behind-the-scenes processing, +it might be surprising if that buffer were unexpectedly manipulated by +`so-long' (which might in turn lead to confusing errors for the user). +Invisible buffers are less likely to cause performance issues related to +long lines, so this differentiation is generally satisfactory. + +The default value `so-long-deferred' prevents `global-so-long-mode' from +triggering `so-long' for any given buffer until such time as the buffer is +displayed in a window. + +\(Note that buffers are normally invisible at this point -- when `find-file' +is used, the buffer is not displayed in a window until a short time after +`global-so-long-mode' has seen it.) + +The value nil or `so-long' means that `so-long' will be called directly; in +which case it may be problematic for `so-long-variable-overrides' to enable +`buffer-read-only', or for `so-long-action' to be set to `so-long-mode'. +This is because the buffer may not be intended to be displayed at all, and +the mentioned options might interfere with some intended processing." + :type '(radio (const so-long-deferred) + (const :tag "nil: Call so-long as normal" nil) + (function :tag "Custom function")) + :package-version '(so-long . "1.0") + :group 'so-long) + (defcustom so-long-predicate 'so-long-detected-long-line-p "Function, called after `set-auto-mode' to decide whether action is needed. @@ -1486,7 +1535,17 @@ major mode is a member (or derivative of a member) of `so-long-target-modes'. (or (eq so-long-target-modes t) (apply #'derived-mode-p so-long-target-modes)) (setq so-long-detected-p (funcall so-long-predicate)) - (so-long))) + ;; `so-long' should be called; but only if and when the buffer is + ;; displayed in a window. Long lines in invisible buffers are generally + ;; not problematic, whereas it might cause problems if an invisible + ;; buffer being used for behind-the-scenes processing is manipulated + ;; unexpectedly. The default `so-long-invisible-buffer-function' value + ;; is `so-long-deferred', which arranges to call `so-long' as soon as + ;; the buffer is displayed. + (if (or (get-buffer-window (current-buffer) t) + (not so-long-invisible-buffer-function)) + (so-long) + (funcall so-long-invisible-buffer-function)))) (defun so-long--hack-one-local-variable (orig-fun var val) ;; Advice, enabled with: @@ -1530,6 +1589,14 @@ These local variables will thus not vanish on setting a major mode." ;; VAR is not the 'mode' pseudo-variable. (funcall orig-fun var val))) +(defun so-long-deferred () + "Arrange to call `so-long' if the current buffer is displayed in a window." + ;; The first time that a window-configuration change results in the buffer + ;; being displayed in a window, `so-long' will be called (with the window + ;; selected and the buffer set as current). Because `so-long' removes this + ;; buffer-local hook value, it triggers once at most. + (add-hook 'window-configuration-change-hook #'so-long nil :local)) + ;;;###autoload (defun so-long (&optional action) "Invoke `so-long-action' and run `so-long-hook'. @@ -1547,6 +1614,8 @@ argument, select the action to use interactively." (completing-read "Action (none): " (mapcar #'car so-long-action-alist) nil :require-match))))) + ;; Ensure that `so-long-deferred' only triggers `so-long' once (at most). + (remove-hook 'window-configuration-change-hook #'so-long :local) (unless so-long--calling (let ((so-long--calling t)) (so-long--ensure-enabled) @@ -1693,6 +1762,12 @@ or call the function `global-so-long-mode'.") (defun so-long-unload-function () "Handler for `unload-feature'." (global-so-long-mode 0) + ;; Remove buffer-local `window-configuration-change-hook' values set by + ;; `so-long-deferred'. + (dolist (buf (buffer-list)) + (with-current-buffer buf + (remove-hook 'window-configuration-change-hook #'so-long :local))) + ;; Return nil. Refer to `unload-feature'. nil) diff --git a/test/lisp/so-long-tests/autoload-longlines-mode-tests.el b/test/lisp/so-long-tests/autoload-longlines-mode-tests.el index 5a57e049fb..c94aeaef24 100644 --- a/test/lisp/so-long-tests/autoload-longlines-mode-tests.el +++ b/test/lisp/so-long-tests/autoload-longlines-mode-tests.el @@ -40,6 +40,7 @@ (ert-deftest so-long-tests-autoload-longlines-mode () "File-local -*- so-long-action: longlines-mode; eval: (so-long) -*-" (with-temp-buffer + (display-buffer (current-buffer)) (so-long-tests-remember) (insert "-*- so-long-action: longlines-mode; eval: (so-long) -*-\n") (put 'so-long-action 'safe-local-variable #'symbolp) diff --git a/test/lisp/so-long-tests/autoload-major-mode-tests.el b/test/lisp/so-long-tests/autoload-major-mode-tests.el index d82cb59750..a8f6f9e7b3 100644 --- a/test/lisp/so-long-tests/autoload-major-mode-tests.el +++ b/test/lisp/so-long-tests/autoload-major-mode-tests.el @@ -38,6 +38,7 @@ (ert-deftest so-long-tests-autoload-major-mode () "File-local -*- so-long -*-" (with-temp-buffer + (display-buffer (current-buffer)) (so-long-tests-remember) (insert "-*- so-long -*-\n") (normal-mode) diff --git a/test/lisp/so-long-tests/autoload-minor-mode-tests.el b/test/lisp/so-long-tests/autoload-minor-mode-tests.el index 67f1903c09..600a35de0a 100644 --- a/test/lisp/so-long-tests/autoload-minor-mode-tests.el +++ b/test/lisp/so-long-tests/autoload-minor-mode-tests.el @@ -39,6 +39,7 @@ (ert-deftest so-long-tests-autoload-minor-mode () "File-local -*- so-long-action: so-long-minor-mode; eval: (so-long) -*-" (with-temp-buffer + (display-buffer (current-buffer)) (so-long-tests-remember) (insert "-*- so-long-action: so-long-minor-mode; eval: (so-long) -*-\n") (put 'so-long-action 'safe-local-variable #'symbolp) diff --git a/test/lisp/so-long-tests/so-long-tests.el b/test/lisp/so-long-tests/so-long-tests.el index b1e0cb90d0..99af5e91ba 100644 --- a/test/lisp/so-long-tests/so-long-tests.el +++ b/test/lisp/so-long-tests/so-long-tests.el @@ -29,13 +29,19 @@ ;; (We could consistently use the latter, but the mixture of approaches ;; means that we're testing more things.) -;; Running the tests with "make lisp/so-long-tests" is like: +;; Running manually: ;; -;; HOME=/nonexistent EMACSLOADPATH= LC_ALL=C \ -;; EMACS_TEST_DIRECTORY=/home/phil/emacs/trunk/repository/test \ +;; for test in lisp/so-long-tests/*-tests.el; do make ${test%.el}; done \ +;; 2>&1 | egrep -v '^(Loading|Source file|make|Changed to so-long-mode)' +;; +;; Which is equivalent to: +;; +;; for test in lisp/so-long-tests/*-tests.el; do \ +;; HOME=/nonexistent EMACSLOADPATH= LC_ALL=C EMACS_TEST_DIRECTORY=. \ ;; "../src/emacs" --no-init-file --no-site-file --no-site-lisp \ -;; -L ":." -l ert -l lisp/so-long-tests.el --batch --eval \ -;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))' +;; -L ":." -l ert -l "$test" --batch --eval \ +;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))'; \ +;; done 2>&1 | egrep -v '^(Loading|Source file|Changed to so-long-mode)' ;; ;; See also `ert-run-tests-batch-and-exit'. @@ -58,6 +64,7 @@ (ert-deftest so-long-tests-threshold-under () "Under line length threshold." (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (insert (make-string (1- so-long-threshold) ?x)) (normal-mode) @@ -66,6 +73,7 @@ (ert-deftest so-long-tests-threshold-at () "At line length threshold." (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (insert (make-string (1- so-long-threshold) ?x)) (normal-mode) @@ -74,6 +82,7 @@ (ert-deftest so-long-tests-threshold-over () "Over line length threshold." (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (normal-mode) (so-long-tests-remember) @@ -85,12 +94,14 @@ "Skip leading shebang, whitespace, and comments." ;; Long comment, no newline. (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (insert (make-string (1+ so-long-threshold) ?\;)) (normal-mode) (should (eq major-mode 'emacs-lisp-mode))) ;; Long comment, with newline. (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (insert (make-string (1+ so-long-threshold) ?\;)) (insert "\n") @@ -98,6 +109,7 @@ (should (eq major-mode 'emacs-lisp-mode))) ;; Long comment, with short text following. (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (insert (make-string (1+ so-long-threshold) ?\;)) (insert "\n") @@ -106,6 +118,7 @@ (should (eq major-mode 'emacs-lisp-mode))) ;; Long comment, with long text following. (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (insert (make-string (1+ so-long-threshold) ?\;)) (insert "\n") @@ -116,6 +129,7 @@ (ert-deftest so-long-tests-max-lines () "Give up after `so-long-max-lines'." (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") ;; Insert exactly `so-long-max-lines' non-comment lines, followed ;; by a long line. @@ -139,10 +153,91 @@ (normal-mode) (should (eq major-mode 'so-long-mode)))))) +(ert-deftest so-long-tests-invisible-buffer-function () + "Call `so-long-invisible-buffer-function' in invisible buffers." + ;; Visible buffer. + (with-temp-buffer + (display-buffer (current-buffer)) + (insert "#!emacs\n") + (normal-mode) + (so-long-tests-remember) + (insert (make-string (1+ so-long-threshold) ?x)) + (normal-mode) + (so-long-tests-assert-and-revert 'so-long-mode)) + ;; Invisible buffer. + (with-temp-buffer + (insert "#!emacs\n") + (normal-mode) + (so-long-tests-remember) + (insert (make-string (1+ so-long-threshold) ?x)) + (normal-mode) + (should (eq major-mode 'emacs-lisp-mode)) + (should (eq nil (get-buffer-window))) + ;; Displaying the buffer should invoke `so-long'. + (display-buffer (current-buffer)) + (should (window-live-p (get-buffer-window))) + (unless (version< emacs-version "27") + ;; From Emacs 27 the `display-buffer' call is insufficient. + ;; The various 'window change functions' are now invoked by the + ;; redisplay, and redisplay does nothing at all in batch mode, + ;; so we cannot test under this revised behaviour. Refer to: + ;; https://lists.gnu.org/archive/html/emacs-devel/2019-10/msg00971.html + ;; For interactive (non-batch) test runs, calling `redisplay' + ;; does do the trick; so do that first. + (redisplay) + (when noninteractive + ;; In batch mode we need to cheat, and just pretend that + ;; `redisplay' triggered `window-configuration-change-hook'. + ;; This means the test is not as useful, but it still covers + ;; part of the process, and so it's better than nothing. + ;; + ;; Also test `so-long--active', in case a future version of + ;; Emacs adds the framework necessary to make `redisplay' work + ;; in batch mode. + (unless (eq so-long--active t) + (run-window-configuration-change-hook)))) + (so-long-tests-assert-and-revert 'so-long-mode)) + ;; `so-long-invisible-buffer-function' is `nil'. + (with-temp-buffer + (insert "#!emacs\n") + (normal-mode) + (so-long-tests-remember) + (insert (make-string (1+ so-long-threshold) ?x)) + (let ((so-long-invisible-buffer-function nil)) + (normal-mode)) + (so-long-tests-assert-and-revert 'so-long-mode)) + ;; `so-long-invisible-buffer-function' is `so-long'. + (with-temp-buffer + (insert "#!emacs\n") + (normal-mode) + (so-long-tests-remember) + (insert (make-string (1+ so-long-threshold) ?x)) + (let ((so-long-invisible-buffer-function #'so-long)) + (normal-mode)) + (so-long-tests-assert-and-revert 'so-long-mode)) + ;; `so-long-invisible-buffer-function' is `ignore'. + (with-temp-buffer + (insert "#!emacs\n") + (normal-mode) + (so-long-tests-remember) + (insert (make-string (1+ so-long-threshold) ?x)) + (let ((so-long-invisible-buffer-function #'ignore)) + (normal-mode)) + (should (eq major-mode 'emacs-lisp-mode)) + (display-buffer (current-buffer)) + (unless (version< emacs-version "27") + ;; See the "Invisible buffer" case earlier in this function. + (redisplay) + (when noninteractive + (unless (eq so-long--active t) + (run-window-configuration-change-hook)))) + (should (eq major-mode 'emacs-lisp-mode)))) + (ert-deftest so-long-tests-actions () "Test each of the standard actions." (dolist (action (mapcar #'car so-long-action-alist)) (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (normal-mode) (so-long-tests-remember) @@ -210,6 +305,7 @@ "Targeted major modes." ;; Test the `so-long-target-modes' user option. (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") (insert (make-string (1+ so-long-threshold) ?x)) ;; Nil target modes. @@ -233,6 +329,7 @@ "Custom predicate function." ;; Test the `so-long-predicate' user option. (with-temp-buffer + (display-buffer (current-buffer)) (insert "#!emacs\n") ;; Always false. (let ((so-long-predicate #'ignore)) @@ -257,6 +354,7 @@ ;; valid for the file-locals to be on the second line after the shebang, ;; but with the *.el filename we no longer need the shebang. (with-temp-buffer + (display-buffer (current-buffer)) (setq buffer-file-name (expand-file-name "so-long-tests-data.el")) (insert ";; -*- so-long-action:so-long-minor-mode; -*-\n") (put 'so-long-action 'safe-local-variable #'symbolp) @@ -275,6 +373,7 @@ (normal-mode) (so-long-tests-remember)) (with-temp-buffer + (display-buffer (current-buffer)) (setq buffer-file-name (concat (make-temp-name "so-long-tests-") ".el")) (insert ";; -*- so-long-action:so-long-minor-mode; eval:(so-long) -*-\n") (put 'so-long-action 'safe-local-variable #'symbolp) @@ -314,6 +413,7 @@ ;; Downgrade the action from major mode to minor mode. (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade) (with-temp-buffer + (display-buffer (current-buffer)) (insert ,prop-line) (insert (make-string (1+ so-long-threshold) ?x)) (insert ,local-vars) @@ -322,6 +422,7 @@ ;; Do not treat the file-local mode specially. (setq-default so-long-file-local-mode-function nil) (with-temp-buffer + (display-buffer (current-buffer)) (insert ,prop-line) (insert (make-string (1+ so-long-threshold) ?x)) (insert ,local-vars) @@ -331,6 +432,7 @@ (setq-default so-long-file-local-mode-function #'so-long-tests-file-local-mode-function) (with-temp-buffer + (display-buffer (current-buffer)) (insert ,prop-line) (insert (make-string (1+ so-long-threshold) ?x)) (insert ,local-vars) @@ -371,6 +473,7 @@ ;; Do nothing at all when a file-local mode is used. (setq-default so-long-file-local-mode-function 'so-long-inhibit) (with-temp-buffer + (display-buffer (current-buffer)) ;; Remember the new-buffer state. The other cases will ;; validate the 'reverted' state against this. (so-long-tests-remember) @@ -382,6 +485,7 @@ ;; Downgrade from major mode to minor mode. (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade) (with-temp-buffer + (display-buffer (current-buffer)) (insert ,prop-line) (insert (make-string (1+ so-long-threshold) ?x)) (insert ,local-vars) @@ -390,6 +494,7 @@ ;; Do not treat the file-local mode specially. (setq-default so-long-file-local-mode-function nil) (with-temp-buffer + (display-buffer (current-buffer)) (insert ,prop-line) (insert (make-string (1+ so-long-threshold) ?x)) (insert ,local-vars) @@ -399,6 +504,7 @@ (setq-default so-long-file-local-mode-function #'so-long-tests-file-local-mode-function) (with-temp-buffer + (display-buffer (current-buffer)) (insert ,prop-line) (insert (make-string (1+ so-long-threshold) ?x)) (insert ,local-vars) commit 90290745d74b18f8a824ea90fe6c6bf5110d716d Author: Phil Sainty Date: Tue Oct 22 01:01:28 2019 +1300 ; Documentation and spelling * lisp/so-long.el: Documentation fixes. For the purposes of consistency, this reverts some of the changes made in commit 41ba8231ef072571e1a6feabc15d113e5cf57556, including one which had introduced inconsistent spelling. ispell configuration and LocalWords have been added such that `ispell-buffer' should find no misspellings for this library. * test/lisp/so-long-tests/spelling-tests.el (so-long-spelling): New test to check the spelling using `ispell-buffer'. diff --git a/lisp/so-long.el b/lisp/so-long.el index b5eb124215..8d9b0dc062 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -325,7 +325,7 @@ ;; * Caveats ;; --------- -;; The variables affecting the automated behavior of this library (such as +;; The variables affecting the automated behaviour of this library (such as ;; `so-long-action') can be used as file- or dir-local values in Emacs 26+, but ;; not in previous versions of Emacs. This is on account of improvements made ;; to `normal-mode' in 26.1, which altered the execution order with respect to @@ -413,7 +413,7 @@ Has no effect if `global-so-long-mode' is not enabled.") "Non-nil while `set-auto-mode' is executing.") (defvar so-long--hack-local-variables-no-mode nil ; internal use - "Non-nil to prevent `hack-local-variables' applying a 'mode' variable.") + "Non-nil to prevent `hack-local-variables' applying a `mode' variable.") (defvar-local so-long--inhibited nil ; internal use "When non-nil, prevents the `set-auto-mode' advice from calling `so-long'.") @@ -654,7 +654,7 @@ an example." ;; `provided-mode-derived-p' was added in 26.1 (unless (fboundp 'provided-mode-derived-p) (defun provided-mode-derived-p (mode &rest modes) - "Return non-nil if MODE is derived from one of MODES. + "Non-nil if MODE is derived from one of MODES. Uses the `derived-mode-parent' property of the symbol to trace backwards. If you just want to check `major-mode', use `derived-mode-p'." (while (and (not (memq mode modes)) @@ -707,7 +707,7 @@ was established." "List of buffer-local minor modes to explicitly disable. The ones which were originally enabled in the buffer are disabled by calling -them with the numeric argument 0. Unknown modes, and modes which were were not +them with the numeric argument 0. Unknown modes, and modes which were not enabled, are ignored. This happens after any globalized minor modes have acted, so that buffer-local @@ -742,8 +742,8 @@ If `so-long-revert' is subsequently invoked, then the variables are restored to their original states. The combination of `line-move-visual' (enabled) and `truncate-lines' (disabled) -is important for avoiding performance hits when moving vertically between -excessively long lines, as otherwise the full length of the line may need to be +is important for maximising responsiveness when moving vertically within an +extremely long line, as otherwise the full length of the line may need to be scanned to find the next position." :type '(alist :key-type (variable :tag "Variable") :value-type (sexp :tag "Value")) @@ -1174,11 +1174,11 @@ enabled, and `so-long-predicate' has detected that the file contains long lines. Many Emacs modes struggle with buffers which contain excessively long lines, and may consequently cause unacceptable performance issues. -This is commonly on account of \"minified\" code (i.e., code compacted -into the smallest file size possible, which often entails removing newlines -should they not be strictly necessary). These kinds of files are typically -not intended to be edited, so not providing the usual editing mode in these -cases will rarely be an issue. +This is commonly on account of \"minified\" code (i.e. code that has been +compacted into the smallest file size possible, which often entails removing +newlines should they not be strictly necessary). These kinds of files are +typically not intended to be edited, so not providing the usual editing mode +in these cases will rarely be an issue. This major mode disables any active minor modes listed in `so-long-minor-modes' for the current buffer, and buffer-local values are assigned to variables in @@ -1189,7 +1189,7 @@ values), despite potential performance issues, type \\[so-long-revert]. Use \\[so-long-commentary] for more information. -Use \\[so-long-customize] to configure the behavior." +Use \\[so-long-customize] to configure the behaviour." ;; Housekeeping. `so-long-mode' might be invoked directly rather than via ;; `so-long', so replicate the necessary behaviours. We could use this same ;; test in `so-long-after-change-major-mode' to run `so-long-hook', but that's @@ -1344,7 +1344,7 @@ This is the `so-long-revert-function' for `so-long-mode'." A buffer-local \"downgrade\" from `so-long-mode' to `so-long-minor-mode'. -When `so-long-function' is set to `so-long-mode', then we change it to to +When `so-long-function' is set to `so-long-mode', then we change it to `turn-on-so-long-minor-mode' instead -- retaining the file-local major mode, but still doing everything else that `so-long-mode' would have done. `so-long-revert-function' is likewise updated. @@ -1379,7 +1379,7 @@ and cannot be conveniently intercepted, so we are forced to replicate it here. This special-case code will ultimately be removed from Emacs, as it exists to deal with a deprecated feature; but until then we need to replicate it in order -to inhibit our own behavior in the presence of a header comment `mode' +to inhibit our own behaviour in the presence of a header comment `mode' declaration. If a file-local mode is detected in the header comment, then we call the @@ -1626,9 +1626,9 @@ Equivalent to calling (global-so-long-mode 0)" Many Emacs modes struggle with buffers which contain excessively long lines, and may consequently cause unacceptable performance issues. -This is commonly on account of \"minified\" code (i.e., code compacted into the -smallest file size possible, which often entails removing newlines should they -not be strictly necessary). +This is commonly on account of \"minified\" code (i.e. code that has been +compacted into the smallest file size possible, which often entails removing +newlines should they not be strictly necessary). When such files are detected by `so-long-predicate', we invoke the selected `so-long-action' to mitigate potential performance problems in the buffer. @@ -1695,14 +1695,34 @@ or call the function `global-so-long-mode'.") (global-so-long-mode 0) nil) + (provide 'so-long) ;; Local Variables: ;; emacs-lisp-docstring-fill-column: 80 ;; fill-column: 80 ;; indent-tabs-mode: nil +;; ispell-check-comments: exclusive +;; ispell-local-dictionary: "british" ;; End: +;; This library is extensively documented in British English, contrary to the +;; preference for American English in Emacs. I hope the benefits of the library +;; will outweigh any discontent you may experience regarding the spelling (or +;; that you find the spelling to be an agreeable bonus). Certain standard Emacs +;; terminology, and text quoted from elsewhere in Emacs, retains its original +;; spelling. The following LocalWords should result in no misspellings from +;; M-x ispell-buffer (using aspell). + +; LocalWords: LocalWords british ispell aspell hunspell emacs elisp el init dir +; LocalWords: customize customized customizing Customization globalized amongst +; LocalWords: initialized profiler boolean minified pre redisplay config keymap +; LocalWords: noerror selectable mapc sgml nxml hl flydiff defs arg Phil Sainty +; LocalWords: defadvice nadvice whitespace ie bos eos eobp origmode un Un cXXXr +; LocalWords: docstring auf wiedersehen longlines alist autoload Refactored Inc +; LocalWords: MERCHANTABILITY RET REGEXP VAR ELPA WS mitigations EmacsWiki eval +; LocalWords: setq rx filename filenames + ;; So long, farewell, auf wiedersehen, goodbye ;; You have to go, this code is minified ;; Goodbye! diff --git a/test/lisp/so-long-tests/spelling-tests.el b/test/lisp/so-long-tests/spelling-tests.el new file mode 100644 index 0000000000..d5bae1ef0c --- /dev/null +++ b/test/lisp/so-long-tests/spelling-tests.el @@ -0,0 +1,69 @@ +;;; spelling-tests.el --- Test suite for so-long.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2019 Free Software Foundation, Inc. + +;; Author: Phil Sainty +;; Keywords: convenience + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert) +(require 'ispell) +(require 'cl-lib) + +;; This test is tagged as :unstable on the basis that there may be +;; inconsistencies between spell-checking facilities on different +;; systems, which may cause the test to be unreliable in practice. +;; As such the Emacs test Makefile will skip it by default, but you +;; can run it manually with: +;; +;; make lisp/so-long-tests/spelling-tests SELECTOR=t + +;; Only define the test if spell-checking is possible. +(when (and ispell-program-name + (executable-find ispell-program-name) + (condition-case () + (progn (ispell-check-version) t) + (error nil)) + (member "british" (ispell-valid-dictionary-list))) + (ert-deftest so-long-spelling () + "Check the spelling in the source code." + :tags '(:unstable) ;; It works for me, but I'm not sure about others. + ;; There could be different "british" dictionaries yielding different + ;; results, for instance. + ;; + ;; The Emacs test Makefile's use of HOME=/nonexistent triggers an error + ;; when starting the inferior ispell process, so we set HOME to a valid + ;; (but empty) temporary directory for this test. + (let* ((tmpdir (make-temp-file "so-long." :dir ".ispell")) + (process-environment (cons (format "HOME=%s" tmpdir) + process-environment)) + (find-spelling-mistake + (unwind-protect + (cl-letf (((symbol-function 'ispell-command-loop) + (lambda (_miss _guess word _start _end) + (message "Unrecognised word: %s." word) + (throw 'mistake t)))) + (catch 'mistake + (find-library "so-long") + (ispell-buffer) + nil)) + (delete-directory tmpdir)))) + (should (not find-spelling-mistake))))) + +;;; spelling-tests.el ends here commit 75875cac2100544f7c1192fc37ea23fbe9db12d7 Author: Eli Zaretskii Date: Thu Nov 14 12:25:10 2019 +0200 Fix recent documentation changes * doc/lispref/minibuf.texi (Multiple Queries): Move the reference to 'read-char-from-minibuffer' from here... * doc/lispref/commands.texi (Reading One Event): ...to here. Fix the wording of the description of 'read-char-from-minibuffer'. diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 0db38b7176..0c848a8025 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2501,6 +2501,9 @@ and key sequences read from keyboard macros being executed. The lowest level functions for command input are @code{read-event}, @code{read-char}, and @code{read-char-exclusive}. +If you need a function to read a character using the minibuffer, use +@code{read-char-from-minibuffer} (@pxref{Multiple Queries}). + @defun read-event &optional prompt inherit-input-method seconds This function reads and returns the next event of command input, waiting if necessary until an event is available. diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index c87723df1f..4a218fe737 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -2253,16 +2253,12 @@ Here is an example of using this function: @end lisp @end defun -If you need a function to read a character like @code{read-char} or -@code{read-char-choice} (@pxref{Reading One Event}) but using the -minibuffer, use @code{read-char-from-minibuffer}. - @defun read-char-from-minibuffer prompt &optional chars history This function uses the minibuffer to read and return a single character. Optionally, it ignores any input that is not a member of @var{chars}, a list of accepted characters. The @var{history} -argument specifies the history list symbol to use; if is omitted or -@code{nil}, it doesn't use the history. +argument specifies the history list symbol to use; if it is omitted or +@code{nil}, this function doesn't use the history. @end defun @node Reading a Password commit ca44f33be2e2c91dad4037c730408b2b1d4529dd Author: Robert Pluim Date: Wed Nov 13 15:19:04 2019 +0100 Make GTK font chooser respect face-ignored-fonts * src/font.c (font_delete_unmatched): Move Vface_ignored_fonts matching to... (font_is_ignored): ..Here. New function. * src/gtkutil.c (xg_font_filter): New function, uses font_is_ignored to filter fonts. (xg_get_font): Set GTK font chooser filter to xg_font_filter. * src/gtkutil.h: Add prototype for font_is_ignored. diff --git a/src/font.c b/src/font.c index 8dfbfa0fac..7c8e9e30c9 100644 --- a/src/font.c +++ b/src/font.c @@ -2655,6 +2655,26 @@ font_clear_cache (struct frame *f, Lisp_Object cache, } +/* Check whether NAME should be ignored based on Vface_ignored_fonts. + This is reused by xg_font_filter to apply the same checks to the + GTK font chooser. */ + +bool +font_is_ignored (const char *name, ptrdiff_t namelen) +{ + Lisp_Object tail = Vface_ignored_fonts; + Lisp_Object regexp; + + FOR_EACH_TAIL_SAFE (tail) + { + regexp = XCAR (tail); + if (STRINGP (regexp) + && fast_c_string_match_ignore_case (regexp, name, + namelen) >= 0) + return true; + } + return false; +} static Lisp_Object scratch_font_spec, scratch_font_prefer; /* Check each font-entity in VEC, and return a list of font-entities @@ -2677,22 +2697,10 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) { char name[256]; ptrdiff_t namelen; - Lisp_Object tail, regexp; - namelen = font_unparse_xlfd (entity, 0, name, 256); if (namelen >= 0) - { - for (tail = Vface_ignored_fonts; CONSP (tail); tail = XCDR (tail)) - { - regexp = XCAR (tail); - if (STRINGP (regexp) - && fast_c_string_match_ignore_case (regexp, name, - namelen) >= 0) - break; - } - if (CONSP (tail)) - continue; - } + if (font_is_ignored (name, namelen)) + continue; } if (NILP (spec)) { diff --git a/src/gtkutil.c b/src/gtkutil.c index 16d765533a..c4d2ef9d80 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -2228,6 +2228,21 @@ xg_get_file_name (struct frame *f, static char *x_last_font_name; +#if GTK_CHECK_VERSION (3, 2, 0) +static gboolean +xg_font_filter (const PangoFontFamily *family, + const PangoFontFace *face, + gpointer data) +{ + const char *name = pango_font_family_get_name ((PangoFontFamily *)family); + ptrdiff_t namelen = strlen (name); + + if (font_is_ignored (name, namelen)) + return FALSE; + return TRUE; +} +#endif + /* Pop up a GTK font selector and return the name of the font the user selects, as a C string. The returned font name follows GTK's own format: @@ -2247,6 +2262,9 @@ xg_get_font (struct frame *f, const char *default_name) w = gtk_font_chooser_dialog_new ("Pick a font", GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); +#if GTK_CHECK_VERSION (3, 2, 0) + gtk_font_chooser_set_filter_func (GTK_FONT_CHOOSER (w), xg_font_filter, NULL, NULL); +#endif if (default_name) { /* Convert fontconfig names to Gtk names, i.e. remove - before diff --git a/src/gtkutil.h b/src/gtkutil.h index 229aa08f81..a059f53219 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -203,5 +203,10 @@ extern void xg_initialize (void); extern bool xg_ignore_gtk_scrollbar; extern bool xg_gtk_initialized; + +#if GTK_CHECK_VERSION (3, 2, 0) +extern bool font_is_ignored (const char *, ptrdiff_t); +#endif + #endif /* USE_GTK */ #endif /* GTKUTIL_H */