From 760910f4917ad8ff5e1cd1bf0bfec443b02f0e44 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 14 Feb 2021 12:37:44 +0100 Subject: Add a new buffer-local variable `minor-modes' * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Keep `minor-modes' updated. * src/buffer.c (bset_minor_modes, Fmake_indirect_buffer) (reset_buffer, init_buffer_once): Initialise `minor-modes'. (syms_of_buffer): Add `minor-modes' as a new permanently-local variable. * src/buffer.h (struct buffer): Add minor_modes_. --- lisp/emacs-lisp/easy-mmode.el | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lisp/emacs-lisp/easy-mmode.el') diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 2916ae4adea..bfffbe4bf20 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -317,6 +317,10 @@ or call the function `%s'.")))) nil) (t t))) + ;; Keep `minor-modes' up to date. + (setq minor-modes (delq ',modefun minor-modes)) + (when ,getter + (push ',modefun minor-modes)) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) -- cgit v1.2.3 From 40f7804ecb299a7f7c3accd19d27e2898d3b8374 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 14 Feb 2021 14:06:16 +0100 Subject: Allow define-minor-mode to take an :interactive keyword * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Allow specifying the :interactive state and the modes. --- etc/NEWS | 8 +++++++- lisp/emacs-lisp/easy-mmode.el | 22 +++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'lisp/emacs-lisp/easy-mmode.el') diff --git a/etc/NEWS b/etc/NEWS index 9c3396d33af..22c320bfa31 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2294,7 +2294,13 @@ This permanently buffer-local variable holds a list of currently enabled minor modes in the current buffer (as a list of symbols). +++ -** 'defined-derived-mode' now takes an :interactive argument. +** 'define-minor-mode' now takes an :interactive argument. +This can be used for specifying which modes this minor mode is meant +for, or to make the new minor mode non-interactive. The default value +is t. + ++++ +** 'define-derived-mode' now takes an :interactive argument. This can be used to control whether the defined mode is a command or not, and is useful when defining commands that aren't meant to be used by users directly. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index bfffbe4bf20..08ac8186949 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -172,6 +172,10 @@ BODY contains code to execute each time the mode is enabled or disabled. :lighter SPEC Same as the LIGHTER argument. :keymap MAP Same as the KEYMAP argument. :require SYM Same as in `defcustom'. +:interactive VAL Whether this mode should be a command or not. The default + is to make it one; use nil to avoid that. If VAL is a list, + it's interpreted as a list of major modes this minor mode + is useful in. :variable PLACE The location to use instead of the variable MODE to store the state of the mode. This can be simply a different named variable, or a generalized variable. @@ -226,6 +230,7 @@ For example, you could write (hook (intern (concat mode-name "-hook"))) (hook-on (intern (concat mode-name "-on-hook"))) (hook-off (intern (concat mode-name "-off-hook"))) + (interactive t) keyw keymap-sym tmp) ;; Check keys. @@ -245,6 +250,7 @@ For example, you could write (:type (setq type (list :type (pop body)))) (:require (setq require (pop body))) (:keymap (setq keymap (pop body))) + (:interactive (setq interactive (pop body))) (:variable (setq variable (pop body)) (if (not (and (setq tmp (cdr-safe variable)) (or (symbolp tmp) @@ -303,11 +309,17 @@ or call the function `%s'.")))) ;; The actual function. (defun ,modefun (&optional arg ,@extra-args) ,(easy-mmode--mode-docstring doc pretty-name keymap-sym) - ;; Use `toggle' rather than (if ,mode 0 1) so that using - ;; repeat-command still does the toggling correctly. - (interactive (list (if current-prefix-arg - (prefix-numeric-value current-prefix-arg) - 'toggle))) + ,(when interactive + ;; Use `toggle' rather than (if ,mode 0 1) so that using + ;; repeat-command still does the toggling correctly. + (if (consp interactive) + `(command ,interactive + (list (if current-prefix-arg + (prefix-numeric-value current-prefix-arg) + 'toggle))) + '(interactive (list (if current-prefix-arg + (prefix-numeric-value current-prefix-arg) + 'toggle))))) (let ((,last-message (current-message))) (,@setter (cond ((eq arg 'toggle) -- cgit v1.2.3 From 07e6b29b12c961808fcf4d8f804946056118efc5 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 14 Feb 2021 14:12:08 +0100 Subject: Fix previous define-minor-mode change * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Fix interactive extension in previous change. --- lisp/emacs-lisp/easy-mmode.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lisp/emacs-lisp/easy-mmode.el') diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 08ac8186949..01fb58e863a 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -313,10 +313,11 @@ or call the function `%s'.")))) ;; Use `toggle' rather than (if ,mode 0 1) so that using ;; repeat-command still does the toggling correctly. (if (consp interactive) - `(command ,interactive - (list (if current-prefix-arg - (prefix-numeric-value current-prefix-arg) - 'toggle))) + `(interactive + ,interactive + (list (if current-prefix-arg + (prefix-numeric-value current-prefix-arg) + 'toggle))) '(interactive (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) 'toggle))))) -- cgit v1.2.3 From 869cdcf4e7a787534d275ca6fc0a792ab642c764 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 14 Feb 2021 14:13:38 +0100 Subject: Really fix the syntax problem in define-minor-mode * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Fix interactive extension in previous change. --- lisp/emacs-lisp/easy-mmode.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lisp/emacs-lisp/easy-mmode.el') diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 01fb58e863a..7e5e2a9b8a9 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -314,10 +314,10 @@ or call the function `%s'.")))) ;; repeat-command still does the toggling correctly. (if (consp interactive) `(interactive - ,interactive (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) - 'toggle))) + 'toggle)) + ,@interactive) '(interactive (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) 'toggle))))) -- cgit v1.2.3 From 2f00a3435a05bbcedbf8851baeefd33463bc525b Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sun, 14 Feb 2021 16:51:14 +0100 Subject: Don't update `minor-modes' in global modes * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): There's no point in setting the buffer-local `minor-modes' in global modes. --- lisp/emacs-lisp/easy-mmode.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lisp/emacs-lisp/easy-mmode.el') diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 7e5e2a9b8a9..5ba0d2187f2 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -330,10 +330,11 @@ or call the function `%s'.")))) nil) (t t))) - ;; Keep `minor-modes' up to date. - (setq minor-modes (delq ',modefun minor-modes)) - (when ,getter - (push ',modefun minor-modes)) + (unless ,globalp + ;; Keep `minor-modes' up to date. + (setq minor-modes (delq ',modefun minor-modes)) + (when ,getter + (push ',modefun minor-modes))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) -- cgit v1.2.3 From 0bd846c17474b161b11fbe21545609cd545b1798 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 15 Feb 2021 12:44:57 +0100 Subject: Rename minor-modes to local-minor-modes * doc/lispref/modes.texi (Minor Modes): Update documentation. * lisp/simple.el (completion-with-modes-p): Change usage. * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Change usage. * src/buffer.c: Rename from minor_modes to local_minor_modes throughout. (syms_of_buffer): Rename minor-modes to local-minor-modes. * src/buffer.h (struct buffer): Rename minor_modes_. * src/pdumper.c (dump_buffer): Update hash and usage. --- doc/lispref/modes.texi | 2 +- etc/NEWS | 2 +- lisp/emacs-lisp/easy-mmode.el | 6 +++--- lisp/simple.el | 7 ++++--- src/buffer.c | 13 +++++++------ src/buffer.h | 2 +- src/pdumper.c | 4 ++-- 7 files changed, 19 insertions(+), 17 deletions(-) (limited to 'lisp/emacs-lisp/easy-mmode.el') diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index b06cb585069..192ffb6a0a9 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1461,7 +1461,7 @@ used only with Diff mode. other minor modes in effect. It should be possible to activate and deactivate minor modes in any order. -@defvar minor-modes +@defvar local-minor-modes This buffer-local variable lists the currently enabled minor modes in the current buffer, and is a list of symbols. @end defvar diff --git a/etc/NEWS b/etc/NEWS index 1adfb8c5bb1..eeaed3b5cfa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2295,7 +2295,7 @@ minor mode activated. Note that using this form will create byte code that is not compatible with byte code in previous Emacs versions. +++ -** New buffer-local variable 'minor-modes'. +** New buffer-local variable 'local-minor-modes'. This permanently buffer-local variable holds a list of currently enabled minor modes in the current buffer (as a list of symbols). diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 5ba0d2187f2..c48ec505ce0 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -331,10 +331,10 @@ or call the function `%s'.")))) (t t))) (unless ,globalp - ;; Keep `minor-modes' up to date. - (setq minor-modes (delq ',modefun minor-modes)) + ;; Keep `local-minor-modes' up to date. + (setq local-minor-modes (delq ',modefun local-minor-modes)) (when ,getter - (push ',modefun minor-modes))) + (push ',modefun local-minor-modes))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) diff --git a/lisp/simple.el b/lisp/simple.el index 8d27cf8d625..cb7496d37c5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1984,13 +1984,14 @@ BUFFER, or any of the active minor modes in BUFFER." (if (null (cdr modes)) (or (provided-mode-derived-p (buffer-local-value 'major-mode buffer) (car modes)) - (memq (car modes) (buffer-local-value 'minor-modes buffer))) + (memq (car modes) + (buffer-local-value 'local-minor-modes buffer))) ;; Uncommon case: Multiple modes. (apply #'provided-mode-derived-p (buffer-local-value 'major-mode buffer) modes) (seq-intersection modes - (buffer-local-value 'minor-modes buffer) + (buffer-local-value 'local-minor-modes buffer) #'eq))))) (defun completion-with-modes-p (modes buffer) @@ -2002,7 +2003,7 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER." modes) ;; It's a minor mode. (seq-intersection modes - (buffer-local-value 'minor-modes buffer) + (buffer-local-value 'local-minor-modes buffer) #'eq))) (defun completion-button-p (category buffer) diff --git a/src/buffer.c b/src/buffer.c index 487599dbbed..5bd9b37702f 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -292,9 +292,9 @@ bset_major_mode (struct buffer *b, Lisp_Object val) b->major_mode_ = val; } static void -bset_minor_modes (struct buffer *b, Lisp_Object val) +bset_local_minor_modes (struct buffer *b, Lisp_Object val) { - b->minor_modes_ = val; + b->local_minor_modes_ = val; } static void bset_mark (struct buffer *b, Lisp_Object val) @@ -898,7 +898,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) bset_file_truename (b, Qnil); bset_display_count (b, make_fixnum (0)); bset_backed_up (b, Qnil); - bset_minor_modes (b, Qnil); + bset_local_minor_modes (b, Qnil); bset_auto_save_file_name (b, Qnil); set_buffer_internal_1 (b); Fset (intern ("buffer-save-without-query"), Qnil); @@ -973,7 +973,7 @@ reset_buffer (register struct buffer *b) b->clip_changed = 0; b->prevent_redisplay_optimizations_p = 1; bset_backed_up (b, Qnil); - bset_minor_modes (b, Qnil); + bset_local_minor_modes (b, Qnil); BUF_AUTOSAVE_MODIFF (b) = 0; b->auto_save_failure_time = 0; bset_auto_save_file_name (b, Qnil); @@ -5158,7 +5158,7 @@ init_buffer_once (void) bset_auto_save_file_name (&buffer_local_flags, make_fixnum (-1)); bset_read_only (&buffer_local_flags, make_fixnum (-1)); bset_major_mode (&buffer_local_flags, make_fixnum (-1)); - bset_minor_modes (&buffer_local_flags, make_fixnum (-1)); + bset_local_minor_modes (&buffer_local_flags, make_fixnum (-1)); bset_mode_name (&buffer_local_flags, make_fixnum (-1)); bset_undo_list (&buffer_local_flags, make_fixnum (-1)); bset_mark_active (&buffer_local_flags, make_fixnum (-1)); @@ -5625,7 +5625,8 @@ The default value (normally `fundamental-mode') affects new buffers. A value of nil means to use the current buffer's major mode, provided it is not marked as "special". */); - DEFVAR_PER_BUFFER ("minor-modes", &BVAR (current_buffer, minor_modes), + DEFVAR_PER_BUFFER ("local-minor-modes", + &BVAR (current_buffer, local_minor_modes), Qnil, doc: /* Minor modes currently active in the current buffer. This is a list of symbols, or nil if there are no minor modes active. */); diff --git a/src/buffer.h b/src/buffer.h index 0668d16608b..24e9c3fcbc8 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -339,7 +339,7 @@ struct buffer Lisp_Object major_mode_; /* Symbol listing all currently enabled minor modes. */ - Lisp_Object minor_modes_; + Lisp_Object local_minor_modes_; /* Pretty name of major mode (e.g., "Lisp"). */ Lisp_Object mode_name_; diff --git a/src/pdumper.c b/src/pdumper.c index b68f992c33a..337742fda4a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2692,7 +2692,7 @@ dump_hash_table (struct dump_context *ctx, static dump_off dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) { -#if CHECK_STRUCTS && !defined HASH_buffer_732A01EB61 +#if CHECK_STRUCTS && !defined HASH_buffer_F8FE65D42F # error "buffer changed. See CHECK_STRUCTS comment in config.h." #endif struct buffer munged_buffer = *in_buffer; @@ -2703,7 +2703,7 @@ dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer) buffer->window_count = 0; else eassert (buffer->window_count == -1); - buffer->minor_modes_ = Qnil; + buffer->local_minor_modes_ = Qnil; buffer->last_selected_window_ = Qnil; buffer->display_count_ = make_fixnum (0); buffer->clip_changed = 0; -- cgit v1.2.3 From b535c8ba8735409b43ec9b1ce99a966cfa1383b1 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 15 Feb 2021 13:08:15 +0100 Subject: Add a new variable `global-minor-modes' * doc/lispref/modes.texi (Minor Modes): Document it. * lisp/simple.el (global-minor-modes): New variable. (completion-in-mode-p): Use it. (completion-with-modes-p): Use it. * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Support it. --- doc/lispref/modes.texi | 5 +++++ etc/NEWS | 8 +++++++- lisp/emacs-lisp/easy-mmode.el | 13 ++++++++----- lisp/simple.el | 13 ++++++++++--- 4 files changed, 30 insertions(+), 9 deletions(-) (limited to 'lisp/emacs-lisp/easy-mmode.el') diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 192ffb6a0a9..e1299b52d41 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1466,6 +1466,11 @@ This buffer-local variable lists the currently enabled minor modes in the current buffer, and is a list of symbols. @end defvar +@defvar global-minor-modes +This variable lists the currently enabled global minor modes, and is a +list of symbols. +@end defvar + @defvar minor-mode-list The value of this variable is a list of all minor mode commands. @end defvar diff --git a/etc/NEWS b/etc/NEWS index eeaed3b5cfa..7f32f7bf6a9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2297,7 +2297,13 @@ that is not compatible with byte code in previous Emacs versions. +++ ** New buffer-local variable 'local-minor-modes'. This permanently buffer-local variable holds a list of currently -enabled minor modes in the current buffer (as a list of symbols). +enabled non-global minor modes in the current buffer (as a list of +symbols). + ++++ +** New variable 'global-minor-modes'. +This variable holds a list of currently enabled global minor modes (as +a list of symbols). +++ ** 'define-minor-mode' now takes an :interactive argument. diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index c48ec505ce0..4a9e58083b0 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -330,11 +330,14 @@ or call the function `%s'.")))) nil) (t t))) - (unless ,globalp - ;; Keep `local-minor-modes' up to date. - (setq local-minor-modes (delq ',modefun local-minor-modes)) - (when ,getter - (push ',modefun local-minor-modes))) + ;; Keep minor modes list up to date. + ,@(if globalp + `((setq global-minor-modes (delq ',modefun global-minor-modes)) + (when ,getter + (push ',modefun global-minor-modes))) + `((setq local-minor-modes (delq ',modefun local-minor-modes)) + (when ,getter + (push ',modefun local-minor-modes)))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) diff --git a/lisp/simple.el b/lisp/simple.el index cb7496d37c5..aafbb3e1f88 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -138,6 +138,10 @@ messages are highlighted; this helps to see what messages were visited." nil "Overlay highlighting the current error message in the `next-error' buffer.") +(defvar global-minor-modes nil + "A list of the currently enabled global minor modes. +This is a list of symbols.") + (defcustom next-error-hook nil "List of hook functions run by `next-error' after visiting source file." :type 'hook @@ -1985,14 +1989,16 @@ BUFFER, or any of the active minor modes in BUFFER." (or (provided-mode-derived-p (buffer-local-value 'major-mode buffer) (car modes)) (memq (car modes) - (buffer-local-value 'local-minor-modes buffer))) + (buffer-local-value 'local-minor-modes buffer)) + (memq (car modes) global-minor-modes)) ;; Uncommon case: Multiple modes. (apply #'provided-mode-derived-p (buffer-local-value 'major-mode buffer) modes) (seq-intersection modes (buffer-local-value 'local-minor-modes buffer) - #'eq))))) + #'eq) + (seq-intersection modes global-minor-modes #'eq))))) (defun completion-with-modes-p (modes buffer) "Say whether MODES are in action in BUFFER. @@ -2004,7 +2010,8 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER." ;; It's a minor mode. (seq-intersection modes (buffer-local-value 'local-minor-modes buffer) - #'eq))) + #'eq) + (seq-intersection modes global-minor-modes #'eq))) (defun completion-button-p (category buffer) "Return non-nil if there's a button of CATEGORY at point in BUFFER." -- cgit v1.2.3