10. Minor Modes
Like Emacs, StumpWM has the concept of minor modes. These are defined by
the macro DEFINE-MINOR-MODE
. Defining a minor mode creates a
class and a set of methods specializing upon it. Minor modes are scoped
to a window, head, group, or screen, or they may be unscoped. In
addition to this minor modes may be local or global. When a minor mode
is global all new instances of the scope object will be created with the
minor mode already active in them. Minor modes define their own top
level and root level keymaps, as well as hooks that are run upon
enabling or disabling the minor mode, and a lighter to display in the
mode line.
Minor modes are mixins that get added to the appropriate scope object
when enabled. As such minor modes allow the augmenting, modifying, and
overriding of default StumpWM behavior by defining methods for the
generic functions of the scope object. For example, a minor mode may be
scoped to a window and define a method for the generic function
UPDATE-DECORATION
to change how window decoration is handled for
the windows it is enabled in.
- Macro: define-minor-mode mode superclasses slots &rest options
Define a minor mode as a class to be instantiated when the minor mode is
activated. Minor modes are dynamically mixed in to and out of the appropriate
object when they are enabled or disabled.
If SUPERCLASSES is not provided a default superclass of MINOR-MODE will be
provided. OPTIONS may include all normal options when defining a class,
with the addition of the following options:
-
(:SCOPE SCOPE-DESIGNATOR)
The :SCOPE option determines what object(s) the minor mode can be mixed in
with. New scopes can be defined with the macro DEFINE-MINOR-MODE-SCOPE.
-
(:GLOBAL (OR T NIL))
When true the :GLOBAL option changes the way enable methods are defined to track
the minor mode and autoenable it in all existing scope objects, as well as
autoenabled when new scope objects are instantiated. If the :SCOPE option is
:UNSCOPED then this option does not need to be provided.
-
(:TOP-MAP spec)
The minor modes top map is created based upon the provided spec, which must be a
list of cons cells whose car is a key sequence and whose cdr is a binding. For
example: (list (cons "C-m x" "echo"))
. This would bind the key
sequence C-m x to the echo command. A reference to this keymap is stored
as a slot in the minor mode object and can be accessed via the reader
MODE-KEYMAP
where MODE
is the minor mode name.
-
(:ROOT-MAP spec)
The minor modes root map is created based upon the provided spec. The spec is as
described in the :TOP-MAP option.
-
(:EXPOSE-KEYMAPS (OR T NIL))
This value is used at macroexpansion time to determine whether or not to
generate keymap variables or store the keymap within the object. When T the
variables *MODE-TOP-MAP* and *MODE-ROOT-MAP* will be generated.
-
(:REBIND (MEMBER :TOP-MAP :ROOT-MAP :ALL-MAPS))
This option controls rebinding of the top and root maps. When it is :TOP-MAP the
top map is rebound, when it is :ROOT-MAP the root map is rebound, and when it is
:ALL-MAPS both the top and root map are rebound. Any rebound map will be rebound
to the provided keymap specification. This only has an effect if the minor mode
has previously been defined.
-
(:LIGHTER T)
The :LIGHTER option will be used to generate a function returning a string to
display in the mode line. When :LIGHTER is NULL a string is generated based upon
the mode name. When it is a string that string is used as is. Otherwise :LIGHTER
will assumed to be funcallable and used as is. When it is a symbol or a list
that doesn’t begin with LAMBDA or FUNCTION a warning is issued that
DEFINE-MINOR-MODE is assuming it is funcallable. When assumed to be funcallable,
it is called with the mode object as its only argument.
-
(:LIGHTER-MAKE-CLICKABLE (OR T NIL))
When :LIGHTER-MAKE-CLICKABLE is T then the :LIGHTER is wrapped in a call to
FORMAT-WITH-ON-CLICK-ID, called with the id :ML-ON-CLICK-MINOR-MODE and the mode
as a quoted symbol.
-
(:LIGHTER-ON-CLICK FUNCTION)
When :LIGHTER-ON-CLICK is provided it must be a function of arity one, which
will be called whenever the minor modes lighter is clicked, with the button code
of the click as its only argument. If this is provided then
:LIGHTER-MAKE-CLICKABLE is implied to be T.
-
(:INTERACTIVE (OR SYMBOL T NIL))
The :INTERACTIVE option determines whether a command to toggle the minor mode on
and off is generated. If it is T then a command with the same name as the minor
mode is generated. If it is a symbol then that symbol will be used when defining
the command.
-
(:ENABLE-WHEN (MODE OBJECT) &BODY BODY)
When provided, the :ENABLE-WHEN option generates a method for the enable-when
generic function. MODE is bound to the mode symbol, and OBJECT is bound to the
scope object. If this is not provided, a method is generated which returns T for
the minor mode and its scope. If it is provided and is nil, then no method is
generated and a method for ENABLE-WHEN which dispatches upon the mode as a
symbol and the scope type for the minor mode must be manually defined.
-
(:MAKE-HOOKS (OR T NIL))
When :MAKE-HOOKS is T a set of hook variables are generated. These variables are
fourfold: *MODE-HOOK* is run after explicitly enabling the minor
mode. *MODE-ENABLE-HOOK* is run when the minor mode is
autoenabled. *MODE-DISABLE-HOOK* is run when the minor mode is
autodisabled. Finally *MODE-DESTROY-HOOK* is run when the minor mode is
explicitly disabled.
-
(:DEFINE-COMMAND-DEFINER (OR T NIL))
When :DEFINE-COMMAND-DEFINER is T a macro is defined for defining commands that
are active only when the minor mode is active. Commands defined with this macro
have the special variable *MINOR-MODE* bound to the minor mode object in their
body. The generated macro is called DEFINE-MODE-COMMAND. This option defaults to
T.
-
(:MIX-BEFORE &REST RULES)
The :MIX-BEFORE option defines rules on the order this class should be mixed in
relative to other minor modes. This allows the implementer of a minor mode to
make the mixing process aware of dependencies that dont otherwise make sense as
a class hierarchy; If minor modes FOO and BAR both define around methods for the
same method, but FOO’s method must be called first, FOO can add a rule stating
that it must come before BAR in the mixin list. RULES must be a set of conses
which have the form (SYMBOL-DESIGNATOR . PACKAGE-DESIGNATOR). SYMBOL-DESIGNATOR
must be a valid argument to #’STRING, and PACKAGE-DESIGNATOR must be a valid
argument to #’FIND-PACKAGE. Together these shall form a single symbol which
should be the class name of the minor mode being referred to by the rule.
-
(:MIX-AFTER &REST RULES)
The :MIX-AFTER option is similar to the :MIX-BEFORE option, except it specifies
classes that this minor mode should occur after in the mixin list.
Example:
(define-minor-mode evil-mode () ()
(:scope :unscoped)
(:top-map '(("j" . "move-focus down")
("k" . "move-focus up")
("h" . "move-focus left")
("l" . "move-focus right")
("x" . *exchange-window-map*)
("C-m b" . "evil-echo")))
(:lighter "EVIL")
(:lighter-make-clickable nil))
(define-evil-mode-command evil-echo () ()
(run-commands "echo"))
This document was generated on January 28, 2024 using texi2html 1.82.