[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 31be86c 2/2: Merge branch 'master' of git.savannah.gnu.org:/srv/g
From: |
Eli Zaretskii |
Subject: |
master 31be86c 2/2: Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs |
Date: |
Thu, 14 Nov 2019 06:52:00 -0500 (EST) |
branch: master
commit 31be86c3478b1ca587357bf6b2c8be8c68d6f047
Merge: ab36b56 5803558
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>
Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
---
lisp/so-long.el | 240 +++++++++++++++++++--
.../so-long-tests/autoload-longlines-mode-tests.el | 1 +
.../so-long-tests/autoload-major-mode-tests.el | 1 +
.../so-long-tests/autoload-minor-mode-tests.el | 1 +
test/lisp/so-long-tests/so-long-tests.el | 116 +++++++++-
test/lisp/so-long-tests/spelling-tests.el | 69 ++++++
6 files changed, 401 insertions(+), 27 deletions(-)
diff --git a/lisp/so-long.el b/lisp/so-long.el
index b5eb124..78fa325 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
@@ -325,7 +342,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
@@ -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'.
@@ -393,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)
@@ -413,7 +433,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'.")
@@ -487,6 +507,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.
@@ -496,8 +547,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)
@@ -654,7 +705,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))
@@ -680,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
@@ -695,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
@@ -707,7 +761,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 +796,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 +1228,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 +1243,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 +1398,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 +1433,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
@@ -1486,7 +1540,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 +1594,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 +1619,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)
@@ -1626,9 +1700,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.
@@ -1692,17 +1766,139 @@ or call the function `global-so-long-mode'.")
(defun so-long-unload-function ()
"Handler for `unload-feature'."
- (global-so-long-mode 0)
- 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))))
+
+;; 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")))
+
+;; 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)
;; 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/autoload-longlines-mode-tests.el
b/test/lisp/so-long-tests/autoload-longlines-mode-tests.el
index 5a57e04..c94aeae 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 d82cb59..a8f6f9e 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 67f1903..600a35d 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 b1e0cb9..99af5e9 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)
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 0000000..d5bae1e
--- /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 <address@hidden>
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; 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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 31be86c 2/2: Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs,
Eli Zaretskii <=