aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sainty2019-11-15 00:43:46 +1300
committerPhil Sainty2019-11-15 00:43:46 +1300
commit5803558cbf76ddae52d760b6329bbc1095524793 (patch)
tree7e30b4c3bc03264a16362b2a185269a1cc7b999c
parent75875cac2100544f7c1192fc37ea23fbe9db12d7 (diff)
parent77c3bc0297b41283da941f80a59c96fc8fc14936 (diff)
downloademacs-5803558cbf76ddae52d760b6329bbc1095524793.tar.gz
emacs-5803558cbf76ddae52d760b6329bbc1095524793.zip
Merge branch 'scratch/so-long-updates'
-rw-r--r--lisp/so-long.el240
-rw-r--r--test/lisp/so-long-tests/autoload-longlines-mode-tests.el1
-rw-r--r--test/lisp/so-long-tests/autoload-major-mode-tests.el1
-rw-r--r--test/lisp/so-long-tests/autoload-minor-mode-tests.el1
-rw-r--r--test/lisp/so-long-tests/so-long-tests.el116
-rw-r--r--test/lisp/so-long-tests/spelling-tests.el69
6 files changed, 401 insertions, 27 deletions
diff --git a/lisp/so-long.el b/lisp/so-long.el
index b5eb1242156..78fa32508ae 100644
--- a/lisp/so-long.el
+++ b/lisp/so-long.el
@@ -162,6 +162,23 @@
162;; this option can also be configured to inhibit so-long entirely in this 162;; this option can also be configured to inhibit so-long entirely in this
163;; scenario, or to not treat a file-local mode as a special case at all. 163;; scenario, or to not treat a file-local mode as a special case at all.
164 164
165;; * Buffers which are not displayed in a window
166;; ---------------------------------------------
167;; When a file with long lines is visited and the buffer is not displayed right
168;; away, it may be that it is not intended to be displayed at all, and that it
169;; has instead been visited for behind-the-scenes processing by some library.
170;; Invisible buffers are less likely to cause performance issues, and it also
171;; might be surprising to the other library if such a buffer were manipulated by
172;; `so-long' (which might in turn lead to confusing errors for the user); so in
173;; these situations the `so-long-invisible-buffer-function' value is called
174;; instead. By default this arranges for `so-long' to be invoked on the buffer
175;; if and when it is displayed, but not otherwise.
176;;
177;; This 'deferred call' is actually the most common scenario -- even when a
178;; visited file is displayed "right away", it is normal for the buffer to be
179;; invisible when `global-so-long-mode' processes it, and the gap between
180;; "arranging to call" and "calling" `so-long' is simply extremely brief.
181
165;; * Inhibiting and disabling minor modes 182;; * Inhibiting and disabling minor modes
166;; -------------------------------------- 183;; --------------------------------------
167;; Certain minor modes cause significant performance issues in the presence of 184;; Certain minor modes cause significant performance issues in the presence of
@@ -325,7 +342,7 @@
325 342
326;; * Caveats 343;; * Caveats
327;; --------- 344;; ---------
328;; The variables affecting the automated behavior of this library (such as 345;; The variables affecting the automated behaviour of this library (such as
329;; `so-long-action') can be used as file- or dir-local values in Emacs 26+, but 346;; `so-long-action') can be used as file- or dir-local values in Emacs 26+, but
330;; not in previous versions of Emacs. This is on account of improvements made 347;; not in previous versions of Emacs. This is on account of improvements made
331;; to `normal-mode' in 26.1, which altered the execution order with respect to 348;; to `normal-mode' in 26.1, which altered the execution order with respect to
@@ -345,6 +362,7 @@
345;; - New user option `so-long-variable-overrides'. 362;; - New user option `so-long-variable-overrides'.
346;; - New user option `so-long-skip-leading-comments'. 363;; - New user option `so-long-skip-leading-comments'.
347;; - New user option `so-long-file-local-mode-function'. 364;; - New user option `so-long-file-local-mode-function'.
365;; - New user option `so-long-invisible-buffer-function'.
348;; - New user option `so-long-predicate'. 366;; - New user option `so-long-predicate'.
349;; - New variable and function `so-long-function'. 367;; - New variable and function `so-long-function'.
350;; - New variable and function `so-long-revert-function'. 368;; - New variable and function `so-long-revert-function'.
@@ -393,6 +411,8 @@
393(add-to-list 'customize-package-emacs-version-alist 411(add-to-list 'customize-package-emacs-version-alist
394 '(so-long ("1.0" . "27.1"))) 412 '(so-long ("1.0" . "27.1")))
395 413
414(defconst so-long--latest-version "1.0")
415
396(declare-function longlines-mode "longlines") 416(declare-function longlines-mode "longlines")
397(defvar longlines-mode) 417(defvar longlines-mode)
398 418
@@ -413,7 +433,7 @@ Has no effect if `global-so-long-mode' is not enabled.")
413 "Non-nil while `set-auto-mode' is executing.") 433 "Non-nil while `set-auto-mode' is executing.")
414 434
415(defvar so-long--hack-local-variables-no-mode nil ; internal use 435(defvar so-long--hack-local-variables-no-mode nil ; internal use
416 "Non-nil to prevent `hack-local-variables' applying a 'mode' variable.") 436 "Non-nil to prevent `hack-local-variables' applying a `mode' variable.")
417 437
418(defvar-local so-long--inhibited nil ; internal use 438(defvar-local so-long--inhibited nil ; internal use
419 "When non-nil, prevents the `set-auto-mode' advice from calling `so-long'.") 439 "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."
487 :package-version '(so-long . "1.0") 507 :package-version '(so-long . "1.0")
488 :group 'so-long) 508 :group 'so-long)
489 509
510(defcustom so-long-invisible-buffer-function #'so-long-deferred
511 "Function called in place of `so-long' when the buffer is not displayed.
512
513This affects the behaviour of `global-so-long-mode'.
514
515We treat invisible buffers differently from displayed buffers because, in
516cases where a library is using a buffer for behind-the-scenes processing,
517it might be surprising if that buffer were unexpectedly manipulated by
518`so-long' (which might in turn lead to confusing errors for the user).
519Invisible buffers are less likely to cause performance issues related to
520long lines, so this differentiation is generally satisfactory.
521
522The default value `so-long-deferred' prevents `global-so-long-mode' from
523triggering `so-long' for any given buffer until such time as the buffer is
524displayed in a window.
525
526\(Note that buffers are normally invisible at this point -- when `find-file'
527is used, the buffer is not displayed in a window until a short time after
528`global-so-long-mode' has seen it.)
529
530The value nil or `so-long' means that `so-long' will be called directly; in
531which case it may be problematic for `so-long-variable-overrides' to enable
532`buffer-read-only', or for `so-long-action' to be set to `so-long-mode'.
533This is because the buffer may not be intended to be displayed at all, and
534the mentioned options might interfere with some intended processing."
535 :type '(radio (const so-long-deferred)
536 (const :tag "nil: Call so-long as normal" nil)
537 (function :tag "Custom function"))
538 :package-version '(so-long . "1.0")
539 :group 'so-long)
540
490(defcustom so-long-predicate 'so-long-detected-long-line-p 541(defcustom so-long-predicate 'so-long-detected-long-line-p
491 "Function, called after `set-auto-mode' to decide whether action is needed. 542 "Function, called after `set-auto-mode' to decide whether action is needed.
492 543
@@ -496,8 +547,8 @@ The specified function will be called with no arguments. If it returns non-nil
496then `so-long' will be invoked. 547then `so-long' will be invoked.
497 548
498Defaults to `so-long-detected-long-line-p'." 549Defaults to `so-long-detected-long-line-p'."
499 :type '(choice (const so-long-detected-long-line-p) 550 :type '(radio (const so-long-detected-long-line-p)
500 (function :tag "Custom function")) 551 (function :tag "Custom function"))
501 :package-version '(so-long . "1.0") 552 :package-version '(so-long . "1.0")
502 :group 'so-long) 553 :group 'so-long)
503 554
@@ -654,7 +705,7 @@ an example."
654;; `provided-mode-derived-p' was added in 26.1 705;; `provided-mode-derived-p' was added in 26.1
655(unless (fboundp 'provided-mode-derived-p) 706(unless (fboundp 'provided-mode-derived-p)
656 (defun provided-mode-derived-p (mode &rest modes) 707 (defun provided-mode-derived-p (mode &rest modes)
657 "Return non-nil if MODE is derived from one of MODES. 708 "Non-nil if MODE is derived from one of MODES.
658Uses the `derived-mode-parent' property of the symbol to trace backwards. 709Uses the `derived-mode-parent' property of the symbol to trace backwards.
659If you just want to check `major-mode', use `derived-mode-p'." 710If you just want to check `major-mode', use `derived-mode-p'."
660 (while (and (not (memq mode modes)) 711 (while (and (not (memq mode modes))
@@ -680,6 +731,8 @@ was established."
680 '(font-lock-mode ;; (Generally the most important). 731 '(font-lock-mode ;; (Generally the most important).
681 ;; Other standard minor modes: 732 ;; Other standard minor modes:
682 display-line-numbers-mode 733 display-line-numbers-mode
734 flymake-mode
735 flyspell-mode
683 goto-address-mode 736 goto-address-mode
684 goto-address-prog-mode 737 goto-address-prog-mode
685 hi-lock-mode 738 hi-lock-mode
@@ -695,6 +748,7 @@ was established."
695 diff-hl-flydiff-mode 748 diff-hl-flydiff-mode
696 diff-hl-mode 749 diff-hl-mode
697 dtrt-indent-mode 750 dtrt-indent-mode
751 flycheck-mode
698 hl-sexp-mode 752 hl-sexp-mode
699 idle-highlight-mode 753 idle-highlight-mode
700 rainbow-delimiters-mode 754 rainbow-delimiters-mode
@@ -707,7 +761,7 @@ was established."
707 "List of buffer-local minor modes to explicitly disable. 761 "List of buffer-local minor modes to explicitly disable.
708 762
709The ones which were originally enabled in the buffer are disabled by calling 763The ones which were originally enabled in the buffer are disabled by calling
710them with the numeric argument 0. Unknown modes, and modes which were were not 764them with the numeric argument 0. Unknown modes, and modes which were not
711enabled, are ignored. 765enabled, are ignored.
712 766
713This happens after any globalized minor modes have acted, so that buffer-local 767This 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
742to their original states. 796to their original states.
743 797
744The combination of `line-move-visual' (enabled) and `truncate-lines' (disabled) 798The combination of `line-move-visual' (enabled) and `truncate-lines' (disabled)
745is important for avoiding performance hits when moving vertically between 799is important for maximising responsiveness when moving vertically within an
746excessively long lines, as otherwise the full length of the line may need to be 800extremely long line, as otherwise the full length of the line may need to be
747scanned to find the next position." 801scanned to find the next position."
748 :type '(alist :key-type (variable :tag "Variable") 802 :type '(alist :key-type (variable :tag "Variable")
749 :value-type (sexp :tag "Value")) 803 :value-type (sexp :tag "Value"))
@@ -1174,11 +1228,11 @@ enabled, and `so-long-predicate' has detected that the file contains long lines.
1174Many Emacs modes struggle with buffers which contain excessively long lines, 1228Many Emacs modes struggle with buffers which contain excessively long lines,
1175and may consequently cause unacceptable performance issues. 1229and may consequently cause unacceptable performance issues.
1176 1230
1177This is commonly on account of \"minified\" code (i.e., code compacted 1231This is commonly on account of \"minified\" code (i.e. code that has been
1178into the smallest file size possible, which often entails removing newlines 1232compacted into the smallest file size possible, which often entails removing
1179should they not be strictly necessary). These kinds of files are typically 1233newlines should they not be strictly necessary). These kinds of files are
1180not intended to be edited, so not providing the usual editing mode in these 1234typically not intended to be edited, so not providing the usual editing mode
1181cases will rarely be an issue. 1235in these cases will rarely be an issue.
1182 1236
1183This major mode disables any active minor modes listed in `so-long-minor-modes' 1237This major mode disables any active minor modes listed in `so-long-minor-modes'
1184for the current buffer, and buffer-local values are assigned to variables in 1238for 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].
1189 1243
1190Use \\[so-long-commentary] for more information. 1244Use \\[so-long-commentary] for more information.
1191 1245
1192Use \\[so-long-customize] to configure the behavior." 1246Use \\[so-long-customize] to configure the behaviour."
1193 ;; Housekeeping. `so-long-mode' might be invoked directly rather than via 1247 ;; Housekeeping. `so-long-mode' might be invoked directly rather than via
1194 ;; `so-long', so replicate the necessary behaviours. We could use this same 1248 ;; `so-long', so replicate the necessary behaviours. We could use this same
1195 ;; test in `so-long-after-change-major-mode' to run `so-long-hook', but that's 1249 ;; 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'."
1344 1398
1345A buffer-local \"downgrade\" from `so-long-mode' to `so-long-minor-mode'. 1399A buffer-local \"downgrade\" from `so-long-mode' to `so-long-minor-mode'.
1346 1400
1347When `so-long-function' is set to `so-long-mode', then we change it to to 1401When `so-long-function' is set to `so-long-mode', then we change it to
1348`turn-on-so-long-minor-mode' instead -- retaining the file-local major 1402`turn-on-so-long-minor-mode' instead -- retaining the file-local major
1349mode, but still doing everything else that `so-long-mode' would have done. 1403mode, but still doing everything else that `so-long-mode' would have done.
1350`so-long-revert-function' is likewise updated. 1404`so-long-revert-function' is likewise updated.
@@ -1379,7 +1433,7 @@ and cannot be conveniently intercepted, so we are forced to replicate it here.
1379 1433
1380This special-case code will ultimately be removed from Emacs, as it exists to 1434This special-case code will ultimately be removed from Emacs, as it exists to
1381deal with a deprecated feature; but until then we need to replicate it in order 1435deal with a deprecated feature; but until then we need to replicate it in order
1382to inhibit our own behavior in the presence of a header comment `mode' 1436to inhibit our own behaviour in the presence of a header comment `mode'
1383declaration. 1437declaration.
1384 1438
1385If a file-local mode is detected in the header comment, then we call the 1439If 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'.
1486 (or (eq so-long-target-modes t) 1540 (or (eq so-long-target-modes t)
1487 (apply #'derived-mode-p so-long-target-modes)) 1541 (apply #'derived-mode-p so-long-target-modes))
1488 (setq so-long-detected-p (funcall so-long-predicate)) 1542 (setq so-long-detected-p (funcall so-long-predicate))
1489 (so-long))) 1543 ;; `so-long' should be called; but only if and when the buffer is
1544 ;; displayed in a window. Long lines in invisible buffers are generally
1545 ;; not problematic, whereas it might cause problems if an invisible
1546 ;; buffer being used for behind-the-scenes processing is manipulated
1547 ;; unexpectedly. The default `so-long-invisible-buffer-function' value
1548 ;; is `so-long-deferred', which arranges to call `so-long' as soon as
1549 ;; the buffer is displayed.
1550 (if (or (get-buffer-window (current-buffer) t)
1551 (not so-long-invisible-buffer-function))
1552 (so-long)
1553 (funcall so-long-invisible-buffer-function))))
1490 1554
1491(defun so-long--hack-one-local-variable (orig-fun var val) 1555(defun so-long--hack-one-local-variable (orig-fun var val)
1492 ;; Advice, enabled with: 1556 ;; Advice, enabled with:
@@ -1530,6 +1594,14 @@ These local variables will thus not vanish on setting a major mode."
1530 ;; VAR is not the 'mode' pseudo-variable. 1594 ;; VAR is not the 'mode' pseudo-variable.
1531 (funcall orig-fun var val))) 1595 (funcall orig-fun var val)))
1532 1596
1597(defun so-long-deferred ()
1598 "Arrange to call `so-long' if the current buffer is displayed in a window."
1599 ;; The first time that a window-configuration change results in the buffer
1600 ;; being displayed in a window, `so-long' will be called (with the window
1601 ;; selected and the buffer set as current). Because `so-long' removes this
1602 ;; buffer-local hook value, it triggers once at most.
1603 (add-hook 'window-configuration-change-hook #'so-long nil :local))
1604
1533;;;###autoload 1605;;;###autoload
1534(defun so-long (&optional action) 1606(defun so-long (&optional action)
1535 "Invoke `so-long-action' and run `so-long-hook'. 1607 "Invoke `so-long-action' and run `so-long-hook'.
@@ -1547,6 +1619,8 @@ argument, select the action to use interactively."
1547 (completing-read "Action (none): " 1619 (completing-read "Action (none): "
1548 (mapcar #'car so-long-action-alist) 1620 (mapcar #'car so-long-action-alist)
1549 nil :require-match))))) 1621 nil :require-match)))))
1622 ;; Ensure that `so-long-deferred' only triggers `so-long' once (at most).
1623 (remove-hook 'window-configuration-change-hook #'so-long :local)
1550 (unless so-long--calling 1624 (unless so-long--calling
1551 (let ((so-long--calling t)) 1625 (let ((so-long--calling t))
1552 (so-long--ensure-enabled) 1626 (so-long--ensure-enabled)
@@ -1626,9 +1700,9 @@ Equivalent to calling (global-so-long-mode 0)"
1626Many Emacs modes struggle with buffers which contain excessively long lines, 1700Many Emacs modes struggle with buffers which contain excessively long lines,
1627and may consequently cause unacceptable performance issues. 1701and may consequently cause unacceptable performance issues.
1628 1702
1629This is commonly on account of \"minified\" code (i.e., code compacted into the 1703This is commonly on account of \"minified\" code (i.e. code that has been
1630smallest file size possible, which often entails removing newlines should they 1704compacted into the smallest file size possible, which often entails removing
1631not be strictly necessary). 1705newlines should they not be strictly necessary).
1632 1706
1633When such files are detected by `so-long-predicate', we invoke the selected 1707When such files are detected by `so-long-predicate', we invoke the selected
1634`so-long-action' to mitigate potential performance problems in the buffer. 1708`so-long-action' to mitigate potential performance problems in the buffer.
@@ -1692,17 +1766,139 @@ or call the function `global-so-long-mode'.")
1692 1766
1693(defun so-long-unload-function () 1767(defun so-long-unload-function ()
1694 "Handler for `unload-feature'." 1768 "Handler for `unload-feature'."
1695 (global-so-long-mode 0) 1769 (condition-case err
1696 nil) 1770 (progn
1771 (global-so-long-mode 0)
1772 ;; Process existing buffers.
1773 (dolist (buf (buffer-list))
1774 (with-current-buffer buf
1775 ;; Remove buffer-local `window-configuration-change-hook' values set
1776 ;; by `so-long-deferred'.
1777 (remove-hook 'window-configuration-change-hook #'so-long :local)
1778 ;; Call `so-long-revert' in all buffers where so-long is active.
1779 (when (bound-and-true-p so-long--active)
1780 (so-long-revert))))
1781 ;; Un-define our buffer-local variables, as `unload-feature' will not do
1782 ;; this automatically. We remove them from `unload-function-defs-list'
1783 ;; as well, to prevent them being redefined. n.b.: `so-long--active' is
1784 ;; tested (above) using `bound-and-true-p' because that is one of the
1785 ;; variables which we unbind (below); and if something subsequent to
1786 ;; this handler signals an error, the user may need to call this again.
1787 (defvar unload-function-defs-list)
1788 (dolist (var '(so-long--active
1789 so-long--inhibited
1790 so-long-detected-p
1791 so-long-file-local-mode-function
1792 so-long-function
1793 so-long-minor-mode
1794 so-long-mode-abbrev-table
1795 so-long-mode-line-info
1796 so-long-mode-syntax-table
1797 so-long-original-values
1798 so-long-revert-function))
1799 (makunbound var)
1800 (setq unload-function-defs-list
1801 (delq var unload-function-defs-list)))
1802 ;; Return nil if unloading was successful. Refer to `unload-feature'.
1803 nil)
1804 ;; If any error occurred, return non-nil.
1805 (error (progn
1806 (message "Error unloading so-long: %S %S" (car err) (cdr err))
1807 t))))
1808
1809;; Backwards-compatibility definitions.
1810;;
1811;; The following obsolete functions may exist in the user's customized hook
1812;; values dating from versions < 1.0, so we need to ensure that such saved
1813;; values will not trigger errors.
1814(cl-flet ((ignore () nil))
1815 (dolist (hookfunc '((so-long-inhibit-whitespace-mode . so-long-hook)
1816 (so-long-make-buffer-read-only . so-long-hook)
1817 (so-long-revert-buffer-read-only . so-long-revert-hook)
1818 (so-long-inhibit-global-hl-line-mode . so-long-mode-hook)))
1819 (defalias (car hookfunc) #'ignore
1820 (format "Obsolete function. It now does nothing.
1821
1822If it appears in `%s', you should remove it."
1823 (cdr hookfunc)))
1824 (make-obsolete (car hookfunc) nil "so-long.el version 1.0")))
1825
1826;; Live upgrades, for when a newer version is loaded over an older one.
1827;;
1828;; If `so-long-version' was already bound then that tells us which version we
1829;; should upgrade from. If `so-long-version' is unbound then most likely there
1830;; was no older version loaded; however, prior to version 1.0 `so-long-version'
1831;; was not defined at all, and so we also need to detect that scenario, which
1832;; we can do by testing for the presence of a symbol which was removed in 1.0.
1833;;
1834;; The variable `so-long-mode-enabled' covers versions 0.5 - 0.7.6, which is
1835;; every pre-1.0 release using the name "so-long.el".
1836(defvar so-long-version (if (boundp 'so-long-mode-enabled)
1837 "0.5" ;; >= 0.5 and < 1.0
1838 so-long--latest-version)
1839 "The loaded version of so-long.el.")
1840
1841;; Version-specific updates.
1842(when (version< so-long-version so-long--latest-version)
1843 ;; Perform each update in sequence, as necessary.
1844 ;; Update to version 1.0 from earlier versions:
1845 (when (version< so-long-version "1.0")
1846 (remove-hook 'change-major-mode-hook 'so-long-change-major-mode)
1847 (require 'advice)
1848 (when (ad-find-advice 'hack-local-variables 'after 'so-long--file-local-mode)
1849 (ad-remove-advice 'hack-local-variables 'after 'so-long--file-local-mode)
1850 (ad-activate 'hack-local-variables))
1851 (when (ad-find-advice 'set-auto-mode 'around 'so-long--set-auto-mode)
1852 (ad-remove-advice 'set-auto-mode 'around 'so-long--set-auto-mode)
1853 (ad-activate 'set-auto-mode))
1854 (when (boundp 'so-long-mode-map)
1855 (define-key so-long-mode-map [remap so-long-mode-revert] #'so-long-revert))
1856 (dolist (var '(so-long-mode--inhibited
1857 so-long-original-mode))
1858 (makunbound var))
1859 (dolist (func '(so-long-change-major-mode
1860 so-long-check-header-modes
1861 so-long-line-detected-p))
1862 (fmakunbound func))
1863 (defvar so-long-mode-enabled)
1864 (when so-long-mode-enabled
1865 (unless global-so-long-mode
1866 (global-so-long-mode 1)))
1867 (makunbound 'so-long-mode-enabled))
1868 ;; Update to version 1.N:
1869 ;; (when (version< so-long-version "1.N") ...)
1870 ;;
1871 ;; All updates completed.
1872 (setq so-long-version so-long--latest-version))
1697 1873
1874
1698(provide 'so-long) 1875(provide 'so-long)
1699 1876
1700;; Local Variables: 1877;; Local Variables:
1701;; emacs-lisp-docstring-fill-column: 80 1878;; emacs-lisp-docstring-fill-column: 80
1702;; fill-column: 80 1879;; fill-column: 80
1703;; indent-tabs-mode: nil 1880;; indent-tabs-mode: nil
1881;; ispell-check-comments: exclusive
1882;; ispell-local-dictionary: "british"
1704;; End: 1883;; End:
1705 1884
1885;; This library is extensively documented in British English, contrary to the
1886;; preference for American English in Emacs. I hope the benefits of the library
1887;; will outweigh any discontent you may experience regarding the spelling (or
1888;; that you find the spelling to be an agreeable bonus). Certain standard Emacs
1889;; terminology, and text quoted from elsewhere in Emacs, retains its original
1890;; spelling. The following LocalWords should result in no misspellings from
1891;; M-x ispell-buffer (using aspell).
1892
1893; LocalWords: LocalWords british ispell aspell hunspell emacs elisp el init dir
1894; LocalWords: customize customized customizing Customization globalized amongst
1895; LocalWords: initialized profiler boolean minified pre redisplay config keymap
1896; LocalWords: noerror selectable mapc sgml nxml hl flydiff defs arg Phil Sainty
1897; LocalWords: defadvice nadvice whitespace ie bos eos eobp origmode un Un cXXXr
1898; LocalWords: docstring auf wiedersehen longlines alist autoload Refactored Inc
1899; LocalWords: MERCHANTABILITY RET REGEXP VAR ELPA WS mitigations EmacsWiki eval
1900; LocalWords: setq rx filename filenames
1901
1706;; So long, farewell, auf wiedersehen, goodbye 1902;; So long, farewell, auf wiedersehen, goodbye
1707;; You have to go, this code is minified 1903;; You have to go, this code is minified
1708;; Goodbye! 1904;; 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 5a57e049fb5..c94aeaef24b 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 @@
40(ert-deftest so-long-tests-autoload-longlines-mode () 40(ert-deftest so-long-tests-autoload-longlines-mode ()
41 "File-local -*- so-long-action: longlines-mode; eval: (so-long) -*-" 41 "File-local -*- so-long-action: longlines-mode; eval: (so-long) -*-"
42 (with-temp-buffer 42 (with-temp-buffer
43 (display-buffer (current-buffer))
43 (so-long-tests-remember) 44 (so-long-tests-remember)
44 (insert "-*- so-long-action: longlines-mode; eval: (so-long) -*-\n") 45 (insert "-*- so-long-action: longlines-mode; eval: (so-long) -*-\n")
45 (put 'so-long-action 'safe-local-variable #'symbolp) 46 (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 d82cb59750c..a8f6f9e7b32 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 @@
38(ert-deftest so-long-tests-autoload-major-mode () 38(ert-deftest so-long-tests-autoload-major-mode ()
39 "File-local -*- so-long -*-" 39 "File-local -*- so-long -*-"
40 (with-temp-buffer 40 (with-temp-buffer
41 (display-buffer (current-buffer))
41 (so-long-tests-remember) 42 (so-long-tests-remember)
42 (insert "-*- so-long -*-\n") 43 (insert "-*- so-long -*-\n")
43 (normal-mode) 44 (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 67f1903c09c..600a35de0a9 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 @@
39(ert-deftest so-long-tests-autoload-minor-mode () 39(ert-deftest so-long-tests-autoload-minor-mode ()
40 "File-local -*- so-long-action: so-long-minor-mode; eval: (so-long) -*-" 40 "File-local -*- so-long-action: so-long-minor-mode; eval: (so-long) -*-"
41 (with-temp-buffer 41 (with-temp-buffer
42 (display-buffer (current-buffer))
42 (so-long-tests-remember) 43 (so-long-tests-remember)
43 (insert "-*- so-long-action: so-long-minor-mode; eval: (so-long) -*-\n") 44 (insert "-*- so-long-action: so-long-minor-mode; eval: (so-long) -*-\n")
44 (put 'so-long-action 'safe-local-variable #'symbolp) 45 (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 b1e0cb90d00..99af5e91ba0 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 @@
29;; (We could consistently use the latter, but the mixture of approaches 29;; (We could consistently use the latter, but the mixture of approaches
30;; means that we're testing more things.) 30;; means that we're testing more things.)
31 31
32;; Running the tests with "make lisp/so-long-tests" is like: 32;; Running manually:
33;; 33;;
34;; HOME=/nonexistent EMACSLOADPATH= LC_ALL=C \ 34;; for test in lisp/so-long-tests/*-tests.el; do make ${test%.el}; done \
35;; EMACS_TEST_DIRECTORY=/home/phil/emacs/trunk/repository/test \ 35;; 2>&1 | egrep -v '^(Loading|Source file|make|Changed to so-long-mode)'
36;;
37;; Which is equivalent to:
38;;
39;; for test in lisp/so-long-tests/*-tests.el; do \
40;; HOME=/nonexistent EMACSLOADPATH= LC_ALL=C EMACS_TEST_DIRECTORY=. \
36;; "../src/emacs" --no-init-file --no-site-file --no-site-lisp \ 41;; "../src/emacs" --no-init-file --no-site-file --no-site-lisp \
37;; -L ":." -l ert -l lisp/so-long-tests.el --batch --eval \ 42;; -L ":." -l ert -l "$test" --batch --eval \
38;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))' 43;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))'; \
44;; done 2>&1 | egrep -v '^(Loading|Source file|Changed to so-long-mode)'
39;; 45;;
40;; See also `ert-run-tests-batch-and-exit'. 46;; See also `ert-run-tests-batch-and-exit'.
41 47
@@ -58,6 +64,7 @@
58(ert-deftest so-long-tests-threshold-under () 64(ert-deftest so-long-tests-threshold-under ()
59 "Under line length threshold." 65 "Under line length threshold."
60 (with-temp-buffer 66 (with-temp-buffer
67 (display-buffer (current-buffer))
61 (insert "#!emacs\n") 68 (insert "#!emacs\n")
62 (insert (make-string (1- so-long-threshold) ?x)) 69 (insert (make-string (1- so-long-threshold) ?x))
63 (normal-mode) 70 (normal-mode)
@@ -66,6 +73,7 @@
66(ert-deftest so-long-tests-threshold-at () 73(ert-deftest so-long-tests-threshold-at ()
67 "At line length threshold." 74 "At line length threshold."
68 (with-temp-buffer 75 (with-temp-buffer
76 (display-buffer (current-buffer))
69 (insert "#!emacs\n") 77 (insert "#!emacs\n")
70 (insert (make-string (1- so-long-threshold) ?x)) 78 (insert (make-string (1- so-long-threshold) ?x))
71 (normal-mode) 79 (normal-mode)
@@ -74,6 +82,7 @@
74(ert-deftest so-long-tests-threshold-over () 82(ert-deftest so-long-tests-threshold-over ()
75 "Over line length threshold." 83 "Over line length threshold."
76 (with-temp-buffer 84 (with-temp-buffer
85 (display-buffer (current-buffer))
77 (insert "#!emacs\n") 86 (insert "#!emacs\n")
78 (normal-mode) 87 (normal-mode)
79 (so-long-tests-remember) 88 (so-long-tests-remember)
@@ -85,12 +94,14 @@
85 "Skip leading shebang, whitespace, and comments." 94 "Skip leading shebang, whitespace, and comments."
86 ;; Long comment, no newline. 95 ;; Long comment, no newline.
87 (with-temp-buffer 96 (with-temp-buffer
97 (display-buffer (current-buffer))
88 (insert "#!emacs\n") 98 (insert "#!emacs\n")
89 (insert (make-string (1+ so-long-threshold) ?\;)) 99 (insert (make-string (1+ so-long-threshold) ?\;))
90 (normal-mode) 100 (normal-mode)
91 (should (eq major-mode 'emacs-lisp-mode))) 101 (should (eq major-mode 'emacs-lisp-mode)))
92 ;; Long comment, with newline. 102 ;; Long comment, with newline.
93 (with-temp-buffer 103 (with-temp-buffer
104 (display-buffer (current-buffer))
94 (insert "#!emacs\n") 105 (insert "#!emacs\n")
95 (insert (make-string (1+ so-long-threshold) ?\;)) 106 (insert (make-string (1+ so-long-threshold) ?\;))
96 (insert "\n") 107 (insert "\n")
@@ -98,6 +109,7 @@
98 (should (eq major-mode 'emacs-lisp-mode))) 109 (should (eq major-mode 'emacs-lisp-mode)))
99 ;; Long comment, with short text following. 110 ;; Long comment, with short text following.
100 (with-temp-buffer 111 (with-temp-buffer
112 (display-buffer (current-buffer))
101 (insert "#!emacs\n") 113 (insert "#!emacs\n")
102 (insert (make-string (1+ so-long-threshold) ?\;)) 114 (insert (make-string (1+ so-long-threshold) ?\;))
103 (insert "\n") 115 (insert "\n")
@@ -106,6 +118,7 @@
106 (should (eq major-mode 'emacs-lisp-mode))) 118 (should (eq major-mode 'emacs-lisp-mode)))
107 ;; Long comment, with long text following. 119 ;; Long comment, with long text following.
108 (with-temp-buffer 120 (with-temp-buffer
121 (display-buffer (current-buffer))
109 (insert "#!emacs\n") 122 (insert "#!emacs\n")
110 (insert (make-string (1+ so-long-threshold) ?\;)) 123 (insert (make-string (1+ so-long-threshold) ?\;))
111 (insert "\n") 124 (insert "\n")
@@ -116,6 +129,7 @@
116(ert-deftest so-long-tests-max-lines () 129(ert-deftest so-long-tests-max-lines ()
117 "Give up after `so-long-max-lines'." 130 "Give up after `so-long-max-lines'."
118 (with-temp-buffer 131 (with-temp-buffer
132 (display-buffer (current-buffer))
119 (insert "#!emacs\n") 133 (insert "#!emacs\n")
120 ;; Insert exactly `so-long-max-lines' non-comment lines, followed 134 ;; Insert exactly `so-long-max-lines' non-comment lines, followed
121 ;; by a long line. 135 ;; by a long line.
@@ -139,10 +153,91 @@
139 (normal-mode) 153 (normal-mode)
140 (should (eq major-mode 'so-long-mode)))))) 154 (should (eq major-mode 'so-long-mode))))))
141 155
156(ert-deftest so-long-tests-invisible-buffer-function ()
157 "Call `so-long-invisible-buffer-function' in invisible buffers."
158 ;; Visible buffer.
159 (with-temp-buffer
160 (display-buffer (current-buffer))
161 (insert "#!emacs\n")
162 (normal-mode)
163 (so-long-tests-remember)
164 (insert (make-string (1+ so-long-threshold) ?x))
165 (normal-mode)
166 (so-long-tests-assert-and-revert 'so-long-mode))
167 ;; Invisible buffer.
168 (with-temp-buffer
169 (insert "#!emacs\n")
170 (normal-mode)
171 (so-long-tests-remember)
172 (insert (make-string (1+ so-long-threshold) ?x))
173 (normal-mode)
174 (should (eq major-mode 'emacs-lisp-mode))
175 (should (eq nil (get-buffer-window)))
176 ;; Displaying the buffer should invoke `so-long'.
177 (display-buffer (current-buffer))
178 (should (window-live-p (get-buffer-window)))
179 (unless (version< emacs-version "27")
180 ;; From Emacs 27 the `display-buffer' call is insufficient.
181 ;; The various 'window change functions' are now invoked by the
182 ;; redisplay, and redisplay does nothing at all in batch mode,
183 ;; so we cannot test under this revised behaviour. Refer to:
184 ;; https://lists.gnu.org/archive/html/emacs-devel/2019-10/msg00971.html
185 ;; For interactive (non-batch) test runs, calling `redisplay'
186 ;; does do the trick; so do that first.
187 (redisplay)
188 (when noninteractive
189 ;; In batch mode we need to cheat, and just pretend that
190 ;; `redisplay' triggered `window-configuration-change-hook'.
191 ;; This means the test is not as useful, but it still covers
192 ;; part of the process, and so it's better than nothing.
193 ;;
194 ;; Also test `so-long--active', in case a future version of
195 ;; Emacs adds the framework necessary to make `redisplay' work
196 ;; in batch mode.
197 (unless (eq so-long--active t)
198 (run-window-configuration-change-hook))))
199 (so-long-tests-assert-and-revert 'so-long-mode))
200 ;; `so-long-invisible-buffer-function' is `nil'.
201 (with-temp-buffer
202 (insert "#!emacs\n")
203 (normal-mode)
204 (so-long-tests-remember)
205 (insert (make-string (1+ so-long-threshold) ?x))
206 (let ((so-long-invisible-buffer-function nil))
207 (normal-mode))
208 (so-long-tests-assert-and-revert 'so-long-mode))
209 ;; `so-long-invisible-buffer-function' is `so-long'.
210 (with-temp-buffer
211 (insert "#!emacs\n")
212 (normal-mode)
213 (so-long-tests-remember)
214 (insert (make-string (1+ so-long-threshold) ?x))
215 (let ((so-long-invisible-buffer-function #'so-long))
216 (normal-mode))
217 (so-long-tests-assert-and-revert 'so-long-mode))
218 ;; `so-long-invisible-buffer-function' is `ignore'.
219 (with-temp-buffer
220 (insert "#!emacs\n")
221 (normal-mode)
222 (so-long-tests-remember)
223 (insert (make-string (1+ so-long-threshold) ?x))
224 (let ((so-long-invisible-buffer-function #'ignore))
225 (normal-mode))
226 (should (eq major-mode 'emacs-lisp-mode))
227 (display-buffer (current-buffer))
228 (unless (version< emacs-version "27")
229 ;; See the "Invisible buffer" case earlier in this function.
230 (redisplay)
231 (when noninteractive
232 (unless (eq so-long--active t)
233 (run-window-configuration-change-hook))))
234 (should (eq major-mode 'emacs-lisp-mode))))
235
142(ert-deftest so-long-tests-actions () 236(ert-deftest so-long-tests-actions ()
143 "Test each of the standard actions." 237 "Test each of the standard actions."
144 (dolist (action (mapcar #'car so-long-action-alist)) 238 (dolist (action (mapcar #'car so-long-action-alist))
145 (with-temp-buffer 239 (with-temp-buffer
240 (display-buffer (current-buffer))
146 (insert "#!emacs\n") 241 (insert "#!emacs\n")
147 (normal-mode) 242 (normal-mode)
148 (so-long-tests-remember) 243 (so-long-tests-remember)
@@ -210,6 +305,7 @@
210 "Targeted major modes." 305 "Targeted major modes."
211 ;; Test the `so-long-target-modes' user option. 306 ;; Test the `so-long-target-modes' user option.
212 (with-temp-buffer 307 (with-temp-buffer
308 (display-buffer (current-buffer))
213 (insert "#!emacs\n") 309 (insert "#!emacs\n")
214 (insert (make-string (1+ so-long-threshold) ?x)) 310 (insert (make-string (1+ so-long-threshold) ?x))
215 ;; Nil target modes. 311 ;; Nil target modes.
@@ -233,6 +329,7 @@
233 "Custom predicate function." 329 "Custom predicate function."
234 ;; Test the `so-long-predicate' user option. 330 ;; Test the `so-long-predicate' user option.
235 (with-temp-buffer 331 (with-temp-buffer
332 (display-buffer (current-buffer))
236 (insert "#!emacs\n") 333 (insert "#!emacs\n")
237 ;; Always false. 334 ;; Always false.
238 (let ((so-long-predicate #'ignore)) 335 (let ((so-long-predicate #'ignore))
@@ -257,6 +354,7 @@
257 ;; valid for the file-locals to be on the second line after the shebang, 354 ;; valid for the file-locals to be on the second line after the shebang,
258 ;; but with the *.el filename we no longer need the shebang. 355 ;; but with the *.el filename we no longer need the shebang.
259 (with-temp-buffer 356 (with-temp-buffer
357 (display-buffer (current-buffer))
260 (setq buffer-file-name (expand-file-name "so-long-tests-data.el")) 358 (setq buffer-file-name (expand-file-name "so-long-tests-data.el"))
261 (insert ";; -*- so-long-action:so-long-minor-mode; -*-\n") 359 (insert ";; -*- so-long-action:so-long-minor-mode; -*-\n")
262 (put 'so-long-action 'safe-local-variable #'symbolp) 360 (put 'so-long-action 'safe-local-variable #'symbolp)
@@ -275,6 +373,7 @@
275 (normal-mode) 373 (normal-mode)
276 (so-long-tests-remember)) 374 (so-long-tests-remember))
277 (with-temp-buffer 375 (with-temp-buffer
376 (display-buffer (current-buffer))
278 (setq buffer-file-name (concat (make-temp-name "so-long-tests-") ".el")) 377 (setq buffer-file-name (concat (make-temp-name "so-long-tests-") ".el"))
279 (insert ";; -*- so-long-action:so-long-minor-mode; eval:(so-long) -*-\n") 378 (insert ";; -*- so-long-action:so-long-minor-mode; eval:(so-long) -*-\n")
280 (put 'so-long-action 'safe-local-variable #'symbolp) 379 (put 'so-long-action 'safe-local-variable #'symbolp)
@@ -314,6 +413,7 @@
314 ;; Downgrade the action from major mode to minor mode. 413 ;; Downgrade the action from major mode to minor mode.
315 (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade) 414 (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade)
316 (with-temp-buffer 415 (with-temp-buffer
416 (display-buffer (current-buffer))
317 (insert ,prop-line) 417 (insert ,prop-line)
318 (insert (make-string (1+ so-long-threshold) ?x)) 418 (insert (make-string (1+ so-long-threshold) ?x))
319 (insert ,local-vars) 419 (insert ,local-vars)
@@ -322,6 +422,7 @@
322 ;; Do not treat the file-local mode specially. 422 ;; Do not treat the file-local mode specially.
323 (setq-default so-long-file-local-mode-function nil) 423 (setq-default so-long-file-local-mode-function nil)
324 (with-temp-buffer 424 (with-temp-buffer
425 (display-buffer (current-buffer))
325 (insert ,prop-line) 426 (insert ,prop-line)
326 (insert (make-string (1+ so-long-threshold) ?x)) 427 (insert (make-string (1+ so-long-threshold) ?x))
327 (insert ,local-vars) 428 (insert ,local-vars)
@@ -331,6 +432,7 @@
331 (setq-default so-long-file-local-mode-function 432 (setq-default so-long-file-local-mode-function
332 #'so-long-tests-file-local-mode-function) 433 #'so-long-tests-file-local-mode-function)
333 (with-temp-buffer 434 (with-temp-buffer
435 (display-buffer (current-buffer))
334 (insert ,prop-line) 436 (insert ,prop-line)
335 (insert (make-string (1+ so-long-threshold) ?x)) 437 (insert (make-string (1+ so-long-threshold) ?x))
336 (insert ,local-vars) 438 (insert ,local-vars)
@@ -371,6 +473,7 @@
371 ;; Do nothing at all when a file-local mode is used. 473 ;; Do nothing at all when a file-local mode is used.
372 (setq-default so-long-file-local-mode-function 'so-long-inhibit) 474 (setq-default so-long-file-local-mode-function 'so-long-inhibit)
373 (with-temp-buffer 475 (with-temp-buffer
476 (display-buffer (current-buffer))
374 ;; Remember the new-buffer state. The other cases will 477 ;; Remember the new-buffer state. The other cases will
375 ;; validate the 'reverted' state against this. 478 ;; validate the 'reverted' state against this.
376 (so-long-tests-remember) 479 (so-long-tests-remember)
@@ -382,6 +485,7 @@
382 ;; Downgrade from major mode to minor mode. 485 ;; Downgrade from major mode to minor mode.
383 (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade) 486 (setq-default so-long-file-local-mode-function 'so-long-mode-downgrade)
384 (with-temp-buffer 487 (with-temp-buffer
488 (display-buffer (current-buffer))
385 (insert ,prop-line) 489 (insert ,prop-line)
386 (insert (make-string (1+ so-long-threshold) ?x)) 490 (insert (make-string (1+ so-long-threshold) ?x))
387 (insert ,local-vars) 491 (insert ,local-vars)
@@ -390,6 +494,7 @@
390 ;; Do not treat the file-local mode specially. 494 ;; Do not treat the file-local mode specially.
391 (setq-default so-long-file-local-mode-function nil) 495 (setq-default so-long-file-local-mode-function nil)
392 (with-temp-buffer 496 (with-temp-buffer
497 (display-buffer (current-buffer))
393 (insert ,prop-line) 498 (insert ,prop-line)
394 (insert (make-string (1+ so-long-threshold) ?x)) 499 (insert (make-string (1+ so-long-threshold) ?x))
395 (insert ,local-vars) 500 (insert ,local-vars)
@@ -399,6 +504,7 @@
399 (setq-default so-long-file-local-mode-function 504 (setq-default so-long-file-local-mode-function
400 #'so-long-tests-file-local-mode-function) 505 #'so-long-tests-file-local-mode-function)
401 (with-temp-buffer 506 (with-temp-buffer
507 (display-buffer (current-buffer))
402 (insert ,prop-line) 508 (insert ,prop-line)
403 (insert (make-string (1+ so-long-threshold) ?x)) 509 (insert (make-string (1+ so-long-threshold) ?x))
404 (insert ,local-vars) 510 (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 00000000000..d5bae1ef0ce
--- /dev/null
+++ b/test/lisp/so-long-tests/spelling-tests.el
@@ -0,0 +1,69 @@
1;;; spelling-tests.el --- Test suite for so-long.el -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2019 Free Software Foundation, Inc.
4
5;; Author: Phil Sainty <psainty@orcon.net.nz>
6;; Keywords: convenience
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
22
23;;; Code:
24
25(require 'ert)
26(require 'ispell)
27(require 'cl-lib)
28
29;; This test is tagged as :unstable on the basis that there may be
30;; inconsistencies between spell-checking facilities on different
31;; systems, which may cause the test to be unreliable in practice.
32;; As such the Emacs test Makefile will skip it by default, but you
33;; can run it manually with:
34;;
35;; make lisp/so-long-tests/spelling-tests SELECTOR=t
36
37;; Only define the test if spell-checking is possible.
38(when (and ispell-program-name
39 (executable-find ispell-program-name)
40 (condition-case ()
41 (progn (ispell-check-version) t)
42 (error nil))
43 (member "british" (ispell-valid-dictionary-list)))
44 (ert-deftest so-long-spelling ()
45 "Check the spelling in the source code."
46 :tags '(:unstable) ;; It works for me, but I'm not sure about others.
47 ;; There could be different "british" dictionaries yielding different
48 ;; results, for instance.
49 ;;
50 ;; The Emacs test Makefile's use of HOME=/nonexistent triggers an error
51 ;; when starting the inferior ispell process, so we set HOME to a valid
52 ;; (but empty) temporary directory for this test.
53 (let* ((tmpdir (make-temp-file "so-long." :dir ".ispell"))
54 (process-environment (cons (format "HOME=%s" tmpdir)
55 process-environment))
56 (find-spelling-mistake
57 (unwind-protect
58 (cl-letf (((symbol-function 'ispell-command-loop)
59 (lambda (_miss _guess word _start _end)
60 (message "Unrecognised word: %s." word)
61 (throw 'mistake t))))
62 (catch 'mistake
63 (find-library "so-long")
64 (ispell-buffer)
65 nil))
66 (delete-directory tmpdir))))
67 (should (not find-spelling-mistake)))))
68
69;;; spelling-tests.el ends here