diff options
author | Phil Sainty <psainty@orcon.net.nz> | 2021-01-17 01:25:13 +1300 |
---|---|---|
committer | Phil Sainty <psainty@orcon.net.nz> | 2021-03-21 16:23:12 +1300 |
commit | 31843e5eaadb3aee3ee3cb2a13838973dd185203 (patch) | |
tree | ef7c95570dd7149934b5c246fcbf83ef7df06e6a | |
parent | 6edeae3b4b7dd5105c9cf0dc0560d4c2c96a85bd (diff) | |
download | emacs-31843e5eaadb3aee3ee3cb2a13838973dd185203.tar.gz |
WIP: Use `buffer-line-statistics'
-rw-r--r-- | etc/NEWS | 10 | ||||
-rw-r--r-- | lisp/so-long.el | 59 |
2 files changed, 53 insertions, 16 deletions
@@ -2235,9 +2235,17 @@ defines an additional key to exit mode like 'isearch-exit' ('RET'). ** So Long --- +*** New 'so-long-predicate' function 'so-long-statistics-excessive-p' +efficiently detects the presence of a long line anywhere in the buffer +using 'buffer-line-statistics' (see above). This is now the default +predicate (replacing 'so-long-detected-long-line-p'). + +--- *** 'so-long-threshold' and 'so-long-max-lines' have been raised to 10000 characters and 500 lines respectively, to reduce the likelihood -of false-positives when 'global-so-long-mode' is enabled. +of false-positives when 'global-so-long-mode' is enabled. The latter +value is now only used by the old predicate, as the new predicate +knows the longest line in the entire buffer. --- *** 'so-long-target-modes' now includes 'fundamental-mode' by default, diff --git a/lisp/so-long.el b/lisp/so-long.el index 79d0d347f80..833c4b45295 100644 --- a/lisp/so-long.el +++ b/lisp/so-long.el @@ -128,9 +128,9 @@ ;; Use M-x customize-group RET so-long RET ;; (or M-x so-long-customize RET) ;; -;; The user options `so-long-target-modes', `so-long-threshold', and -;; `so-long-max-lines' determine whether action will be taken automatically when -;; visiting a file, and `so-long-action' determines what will be done. +;; The user options `so-long-target-modes' and `so-long-threshold' determine +;; whether action will be taken automatically when visiting a file, and +;; `so-long-action' determines what will be done. ;; * Actions and menus ;; ------------------- @@ -306,8 +306,9 @@ ;; the criteria for calling `so-long' in any given mode (plus its derivatives) ;; by setting buffer-local values for the variables in question. This includes ;; `so-long-predicate' itself, as well as any variables used by the predicate -;; when determining the result. By default this means `so-long-max-lines', -;; `so-long-skip-leading-comments', and `so-long-threshold'. E.g.: +;; when determining the result. By default this means `so-long-threshold' and +;; possibly also `so-long-max-lines' and `so-long-skip-leading-comments' (these +;; latter two are not used by default starting from Emacs 28.1). E.g.: ;; ;; (add-hook 'js-mode-hook 'my-js-mode-hook) ;; @@ -409,7 +410,9 @@ ;; * Change Log: ;; -;; 1.1 - Increase `so-long-threshold' from 250 to 10,000. +;; 1.1 - Utilise `buffer-line-statistics' in Emacs 28+, with the new +;; `so-long-predicate' function `so-long-statistics-excessive-p'. +;; - Increase `so-long-threshold' from 250 to 10,000. ;; - Increase `so-long-max-lines' from 5 to 500. ;; - Include `fundamental-mode' in `so-long-target-modes'. ;; - New user option `so-long-mode-preserved-minor-modes'. @@ -472,8 +475,10 @@ (defconst so-long--latest-version "1.1") +(declare-function buffer-line-statistics "fns.c" t t) ;; Emacs 28+ (declare-function longlines-mode "longlines") (defvar longlines-mode) + (defvar so-long-enabled nil ;; This was initially a renaming of the old `so-long-mode-enabled' and ;; documented as "Set to nil to prevent `so-long' from being triggered @@ -516,7 +521,8 @@ (defcustom so-long-threshold 10000 "Maximum line length permitted before invoking `so-long-function'. -See `so-long-detected-long-line-p' for details." +This is the only variable used to determine the presence of long lines if +the `so-long-predicate' function is `so-long-statistics-excessive-p'." :type 'integer :package-version '(so-long . "1.1")) @@ -591,7 +597,9 @@ the mentioned options might interfere with some intended processing." (function :tag "Custom function")) :package-version '(so-long . "1.0")) -(defcustom so-long-predicate 'so-long-detected-long-line-p +(defcustom so-long-predicate (if (fboundp 'buffer-line-statistics) + 'so-long-statistics-excessive-p + 'so-long-detected-long-line-p) "Function, called after `set-auto-mode' to decide whether action is needed. Only called if the major mode is a member of `so-long-target-modes'. @@ -599,10 +607,12 @@ Only called if the major mode is a member of `so-long-target-modes'. 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 '(radio (const so-long-detected-long-line-p) +Defaults to `so-long-statistics-excessive-p' starting from Emacs 28, or +`so-long-detected-long-line-p' in earlier versions." + :type '(radio (const so-long-statistics-excessive-p) + (const so-long-detected-long-line-p) (function :tag "Custom function")) - :package-version '(so-long . "1.0")) + :package-version '(so-long . "1.1")) ;; Silence byte-compiler warning. `so-long-action-alist' is defined below ;; as a user option; but the definition sequence required for its setter @@ -1149,12 +1159,23 @@ serves the same purpose.") ;; We change automatically to faster code ;; And then I won't feel so mad +(defun so-long-statistics-excessive-p () + "Non-nil if the buffer contains a line longer than `so-long-threshold' bytes. + +This uses `buffer-line-statistics' (available from Emacs 28.1) to establish the +longest line in the buffer (counted in bytes rather than characters). + +This is the default value of `so-long-predicate' in Emacs versions >= 28.1. +\(In earlier versions `so-long-detected-long-line-p' is used by default.)" + (> (cadr (buffer-line-statistics)) + so-long-threshold)) + (defun so-long-detected-long-line-p () "Determine whether the current buffer contains long lines. Following any initial comments and blank lines, the next N lines of the buffer -will be tested for excessive length (where \"excessive\" means above -`so-long-threshold', and N is `so-long-max-lines'). +will be tested for excessive length (where \"excessive\" means greater than +`so-long-threshold' characters, and N is `so-long-max-lines'). Returns non-nil if any such excessive-length line is detected. @@ -1162,7 +1183,9 @@ If `so-long-skip-leading-comments' is nil then the N lines will be counted starting from the first line of the buffer. In this instance you will likely want to increase `so-long-max-lines' to allow for possible comments. -This is the default value of `so-long-predicate'." +This is the default `so-long-predicate' function in Emacs versions < 28.1. +\(Starting from 28.1, the default and recommended predicate function is +`so-long-statistics-excessive-p', which is faster and sees the entire buffer.)" (let ((count 0) start) (save-excursion (goto-char (point-min)) @@ -2000,7 +2023,13 @@ If it appears in `%s', you should remove it." (makunbound 'so-long-mode-enabled)) ;; Update to version 1.1 from earlier versions: (when (version< so-long-version "1.1") - (add-to-list 'so-long-target-modes 'fundamental-mode)) + (add-to-list 'so-long-target-modes 'fundamental-mode) + (let ((saved (eval (car (get 'so-long-predicate 'saved-value)))) + (standard (eval (car (get 'so-long-predicate 'standard-value))))) + (when (and (eq standard 'so-long-statistics-excessive-p) + (or (not saved) + (eq saved 'so-long-detected-long-line-p))) + (setq so-long-predicate standard)))) ;; Update to version 1.N: ;; (when (version< so-long-version "1.N") ...) ;; |