[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] scratch/so-long 9a209c6 1/2: fixup! Add so-long library
From: |
Phil |
Subject: |
[Emacs-diffs] scratch/so-long 9a209c6 1/2: fixup! Add so-long library |
Date: |
Thu, 27 Jun 2019 08:18:46 -0400 (EDT) |
branch: scratch/so-long
commit 9a209c6b7cd344bce38e609925b08eb34cd892cd
Author: Phil Sainty <address@hidden>
Commit: Phil Sainty <address@hidden>
fixup! Add so-long library
* Compatibility fixes for Emacs 24 and 25.
* Eliminate special-case when calling `so-long-file-local-mode-function'.
---
lisp/so-long.el | 65 ++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 46 insertions(+), 19 deletions(-)
diff --git a/lisp/so-long.el b/lisp/so-long.el
index 51fff68..1a6104d 100644
--- a/lisp/so-long.el
+++ b/lisp/so-long.el
@@ -388,6 +388,8 @@
;;; Code:
+(require 'cl-lib)
+
(add-to-list 'customize-package-emacs-version-alist
'(so-long ("1.0" . "27.1")))
@@ -410,6 +412,9 @@ Has no effect if `global-so-long-mode' is not enabled.")
(defvar so-long--set-auto-mode nil ; internal use
"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.")
+
(defvar-local so-long--inhibited nil ; internal use
"When non-nil, prevents the `set-auto-mode' advice from calling `so-long'.")
(put 'so-long--inhibited 'permanent-local t)
@@ -636,9 +641,9 @@ If nil, then do not treat files with file-local modes any
differently to other
files.
Note that this function is called if a file-local mode is set even if `so-long'
-will not be called. The exception to this is when the file-local mode is
-`so-long-mode', in which case `so-long-file-local-mode-function' is ignored,
-as the required action is unambiguous."
+will not be called, and also if the file-local mode is `so-long-mode'. Custom
+functions may need to test for these cases -- see `so-long-mode-downgrade' for
+an example."
:type '(radio (const so-long-mode-downgrade)
(const so-long-inhibit)
(const :tag "nil: Use so-long-function as normal" nil)
@@ -665,11 +670,11 @@ was established."
;; Handle the special case whereby the file-local mode was `so-long-mode'.
;; In this instance we set `so-long--inhibited', because the file-local mode
;; is already going to do everything that is wanted.
- (if (provided-mode-derived-p mode 'so-long-mode)
- (setq so-long--inhibited t)
- ;; Call `so-long-file-local-mode-function'.
- (when so-long-file-local-mode-function
- (funcall so-long-file-local-mode-function mode))))
+ (when (provided-mode-derived-p mode 'so-long-mode)
+ (setq so-long--inhibited t))
+ ;; Call `so-long-file-local-mode-function'.
+ (when so-long-file-local-mode-function
+ (funcall so-long-file-local-mode-function mode)))
(defcustom so-long-minor-modes
;; In sorted groups.
@@ -1305,9 +1310,15 @@ This is the `so-long-revert-function' for
`so-long-mode'."
(error "Original mode unknown."))
(funcall so-long-original-mode)
;; Emacs 26+ has already called `hack-local-variables' (during
- ;; `run-mode-hooks'), but for older versions we need to call it here.
+ ;; `run-mode-hooks'; provided there was a `buffer-file-name'), but for
older
+ ;; versions we need to call it here. In Emacs 26+ the revised
'HANDLE-MODE'
+ ;; argument is set to `no-mode' (being the non-nil-and-non-t behaviour),
+ ;; which we mimic here by binding `so-long--hack-local-variables-no-mode',
+ ;; in order to prevent a local 'mode' variable from clobbering the major
+ ;; mode we have just called.
(when (< emacs-major-version 26)
- (hack-local-variables))
+ (let ((so-long--hack-local-variables-no-mode t))
+ (hack-local-variables)))
;; Restore minor modes.
(so-long-restore-minor-modes)
;; Restore overridden variables.
@@ -1318,7 +1329,7 @@ This is the `so-long-revert-function' for `so-long-mode'."
(unless (derived-mode-p 'so-long-mode)
(setq so-long-mode-line-info (so-long-mode-line-info)))))
-(defun so-long-mode-downgrade (&optional _mode)
+(defun so-long-mode-downgrade (&optional mode)
"The default value for `so-long-file-local-mode-function'.
A buffer-local 'downgrade' from `so-long-mode' to `so-long-minor-mode'.
@@ -1329,12 +1340,18 @@ mode, but still doing everything else that
`so-long-mode' would have done.
`so-long-revert-function' is likewise updated.
If `so-long-function' has any value other than `so-long-mode', we do nothing,
-as if `so-long-file-local-mode-function' was nil."
- (when (and (symbolp (so-long-function))
- (provided-mode-derived-p (so-long-function) 'so-long-mode))
- ;; Downgrade from `so-long-mode' to the `so-long-minor-mode' behaviour.
- (setq so-long-function 'turn-on-so-long-minor-mode
- so-long-revert-function 'turn-off-so-long-minor-mode)))
+as if `so-long-file-local-mode-function' was nil.
+
+We also do nothing if MODE (the file-local mode) has the value `so-long-mode',
+because we do not want to downgrade the major mode in that scenario."
+ ;; Do nothing if the file-local mode was `so-long-mode'.
+ (unless (provided-mode-derived-p mode 'so-long-mode)
+ ;; Act only if `so-long-mode' would be enabled by the current action.
+ (when (and (symbolp (so-long-function))
+ (provided-mode-derived-p (so-long-function) 'so-long-mode))
+ ;; Downgrade from `so-long-mode' to the `so-long-minor-mode' behaviour.
+ (setq so-long-function 'turn-on-so-long-minor-mode
+ so-long-revert-function 'turn-off-so-long-minor-mode))))
(defun so-long-inhibit (&optional _mode)
"Prevent so-long from having any effect at all.
@@ -1477,6 +1494,10 @@ by testing the value against `major-mode'; but as we may
have changed the
major mode to `so-long-mode' by this point, that protection is insufficient
and so we need to perform our own test.
+We likewise need to support an equivalent of the `no-mode' behaviour in 26.1+
+to ensure that `so-long-mode-revert' will not restore a file-local mode again
+after it has already reverted to the original mode.
+
The changes to `normal-mode' in Emacs 26.1 modified the execution order, and
makes this advice unnecessary. The relevant NEWS entry is:
@@ -1487,8 +1508,14 @@ These local variables will thus not vanish on setting a
major mode."
;; Adapted directly from `hack-one-local-variable'
(let ((mode (intern (concat (downcase (symbol-name val))
"-mode"))))
- (unless (eq (indirect-function mode)
- (indirect-function (so-long-original 'major-mode)))
+ (unless (or so-long--hack-local-variables-no-mode
+ (let ((origmode (so-long-original 'major-mode)))
+ ;; We bind origmode because (indirect-function nil) is an
+ ;; error in Emacs versions < 25.1, and so we need to test
+ ;; it first.
+ (and origmode
+ (eq (indirect-function mode)
+ (indirect-function origmode)))))
(funcall orig-fun var val)))
;; VAR is not the 'mode' pseudo-variable.
(funcall orig-fun var val)))