emacs-diffs
[Top][All Lists]
Advanced

[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)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]