|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 41124 (0xa0a4) Types: TextFile Names: »modes.texinfo«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦c06c473ab⟧ »./UNRELEASED/lispref.tar.Z« └─⟦1b57a2ffe⟧ └─⟦this⟧ »modes.texinfo«
@setfilename ../info/modes @node Major and Minor Modes, Documentation, Keymaps, Top @chapter Major and Minor Modes @cindex library files A @dfn{mode} is a set of definitions which customize Emacs for editing text of a particular sort. There are two varieties of modes: the major modes, which are used for specialized editing tasks; and minor modes, which provide features that several different major modes may use. This chapter covers major and minor modes, the @code{mode-line-format}, and hooks. Other related topics such as keymaps and syntax tables are covered in separate chapters. (@xref{Keymaps}, and @pxref{Syntax Tables}.) @menu * Major Modes:: * Minor Modes:: * Mode Line Format:: * Hooks:: @end menu @node Major Modes, Minor Modes, Major and Minor Modes, Major and Minor Modes @section Major Modes @cindex major modes The major modes are mutually exclusive; each buffer has only one major mode at a time. The least specialized major mode is called @dfn{Fundamental mode}. This mode has no mode-specific definitions or variable settings, so each Emacs command behaves in its default manner, and each option is in its default state. In contrast, Lisp Interaction mode provides special key bindings for @key{LFD} (@code{eval-print-last-sexp}), @key{TAB} (@code{lisp-indent-line}), and other keys. When you need to write large quantities of code to help you perform a specialized editing task, you are likely to want to create a new major mode. By writing a new major mode, rather than adding to an existing mode, you avoid having the one mode do double duty, and you thereby avoid making the code, and its use, confusing. Also, in practice, writing a major mode is often simple (this is a sharp contrast to writing a minor mode, which is often complicated). For example, Rmail Edit mode, which is in @file{emacs/lisp/rmailedit.el}, is a major mode that is very similar to Text mode except that it provides three additional commands. The additions to Rmail Edit mode are so small that you might not think to use a major mode for such a job; instead, you might think to use a recursive edit. But recursive edits don't change any commands, and so are not useful. In a few circumstances, a recursive edit might be an alternative to temporarily changing a buffer to a different mode; but recursive edits are confusing to the user and should only be used when there is no alternative, as in the Emacs debugger. For mail editing, a major mode is better. The standard GNU Emacs @file{lisp} library contains the code for several major modes, including @file{text-mode.el}, @file{texinfo.el}, @file{lisp-mode.el}, @file{c-mode.el}, and @file{rmail.el}. You can look at these libraries to see how modes are written. Text mode is perhaps the simplest major mode, besides Fundamental mode. Rmail mode is a rather complicated, full-featured mode. @menu * Major Mode Conventions:: Coding conventions for keymaps, etc. * Major Mode Examples:: Text mode and Lisp modes. * Setting the Major Mode:: Selecting the right mode for a buffer. * Mode Help:: Finding out how to use a mode. * Major Line Information:: What is on the mode line. @end menu @node Major Mode Conventions, Major Mode Examples, Major Modes, Major Modes @comment node-name, next, previous, up @subsection Major Mode Conventions The code for existing major modes follows various coding conventions, including conventions for local keymap and syntax table initialization, global names, and hooks. When you create a new major mode, please keep these conventions in mind. @itemize @bullet @item An apparently trivial, yet important convention is that a user should be able to initialize a new major mode with a command that has a @samp{-mode} suffix to its name. You may also create other ways to enter the mode, but you should have one function that can be called to initialize the keymap, syntax table, and local variables in an existing buffer without changing the buffer's text. In addition, the documentation string for this function is what @code{describe-mode} should use. @item This major mode function should include documentation that is displayed by typing @kbd{C-h m} (@code{describe-mode}). The documentation string may include the special documentation substrings, @samp{\[@var{command}]}, @samp{\@{@var{keymap}@}}, and @samp{\<@var{keymap}>}, that permit you to change the values of keymaps without having to update the documentation string. When the @code{describe-mode} function sees these special documentation substrings, Emacs reads their current values. (@xref{Documentation Strings}.) @item The major mode function should set the variable @code{major-mode} to the major mode function symbol. This is how @code{describe-mode} discovers which documentation to print. @item The major mode function should set the variable @code{mode-name} to the ``pretty'' name of the mode, as a string. This appears in the mode line. @item @cindex functions in modes Since all global names are in the same name space, you should take care to prefix the names of all global variables, constants, and functions with the major mode name (or with an abbreviation of it if the name is long). @c !!! at some point this should be put in a new chapter about how to @c write clear, maintainable Lisp code. @item @cindex keymaps in modes Each major mode typically has its own keymap, which is used as the local keymap in all buffers in that mode. The major mode function should just call @code{use-local-map} with the keymap variable. @xref{Global and Local Keymaps}, for more information. This keymap should be kept in a global variable named @code{@var{modename}-mode-map}. This variable is usually set up when the library that defines the mode is loaded. Use @code{defvar} to set the variable, so that it is not reinitialized if it already has a value. Such reinitialization could discard customizations made by the user. @item @cindex syntax tables in modes It is good practice to use both a syntax table variable and an abbrev table variable. The reasons for this are the same as for using a keymap variable. You can use the tables of a related mode, if they serve without change. @item @cindex buffer-local variables in modes To give variables a buffer-local binding, you should use @code{make-local-variable} in the major mode function rather than @code{make-variable-buffer-local}. The @code{make-local-variable} function makes a variable local to just the current buffer; while the @code{make-variable-buffer-local} function makes a variable local to @emph{every} buffer, even ones that are created later. Use of @code{make-local-variable} has fewer unexpected consequences. (@xref{Buffer Local Variables}.) @item If hooks are appropriate for the mode, the major mode function should run the hooks after completing all other initialization so the user may further customize any of the settings. @item If this mode is appropriate only for text specially made by Emacs, then the major mode command symbol should have a property named @code{mode-class} with value @code{special}, put on as follows: @cindex @code{mode-class} property @cindex @code{special} @example (put funny-mode 'mode-class 'special) @end example @noindent This tells Emacs that new buffers created while a buffer in Funny mode is current should not inherit Funny mode. Modes such as Dired, Rmail, and Buffer List use this feature. @item @cindex mode loading The top level forms in the mode library should be written in such a manner that they may be evaluated more than once without adverse consequences. Even if you never load your library more than once, someone else will. @item @pindex @samp{.emacs} customization In the documentation, you should provide an example @code{autoload} form and an example @code{auto-mode-alist} addition that users can include in their @file{.emacs} files. @end itemize @node Major Mode Examples, Setting the Major Mode, Major Mode Conventions, Major Modes @comment node-name, next, previous, up @subsection Major Mode Examples Text mode is perhaps the simplest mode besides Fundamental mode. Here are excepts from @file{text-mode.el} that illustrate many of the conventions listed above: @example ;; @r{Create mode-specific tables.} (defvar text-mode-syntax-table nil "Syntax table used while in text mode.") (if text-mode-syntax-table () ; @r{Do not change the table if it is already set.} (setq text-mode-syntax-table (make-syntax-table)) (set-syntax-table text-mode-syntax-table) (modify-syntax-entry ?\" ". " text-mode-syntax-table) (modify-syntax-entry ?\\ ". " text-mode-syntax-table) (modify-syntax-entry ?' "w " text-mode-syntax-table)) (defvar text-mode-abbrev-table nil "Abbrev table used while in text mode.") (define-abbrev-table 'text-mode-abbrev-table ()) (defvar text-mode-map nil "") ; @r{Create a mode-specific keymap.} (if text-mode-map () ; @r{Do not change the keymap if it is already set.} (setq text-mode-map (make-sparse-keymap)) (define-key text-mode-map "\t" 'tab-to-tab-stop) (define-key text-mode-map "\es" 'center-line) (define-key text-mode-map "\eS" 'center-paragraph)) @end example Here is the complete major mode function definition for Text mode: @example (defun text-mode () "Major mode for editing text intended for humans to read. Special commands: \\@{text-mode-map@} Turning on text-mode calls the value of the variable text-mode-hook, if that value is non-nil." (interactive) (kill-all-local-variables) (use-local-map text-mode-map) ; @r{This provides the local keymap.} (setq mode-name "Text") ; @r{This name goes into the mode line.} (setq major-mode 'text-mode) ; @r{This is how @code{describe-mode}} ; @r{finds out what to describe.} (setq local-abbrev-table text-mode-abbrev-table) (set-syntax-table text-mode-syntax-table) (run-hooks 'text-mode-hook)) ; @r{Finally, this permits the user to} ; @r{customize the mode with a hook.} @end example @pindex lisp-mode.el Each of the three Lisp modes (Lisp mode, Emacs Lisp mode, and Lisp Interaction mode) have more features than Text mode and the code is correspondingly more complicated. Here are excerpts from @file{lisp-mode.el} that illustrate how these modes are written. @example @cindex syntax table example ;; @r{Create mode-specific table variables.} (defvar lisp-mode-syntax-table nil "") (defvar emacs-lisp-mode-syntax-table nil "") (defvar lisp-mode-abbrev-table nil "") (if (not emacs-lisp-mode-syntax-table) ; @r{Do not change the table} ; @r{if it is already set.} (let ((i 0)) (setq emacs-lisp-mode-syntax-table (make-syntax-table)) ;; @r{Set syntax of chars up to 0 to class of chars that are} ;; @r{part of symbol names but not words.} ;; @r{(The number 0 is @code{48} in the @sc{ascii} character set.)} (while (< i ?0) (modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table) (setq i (1+ i))) @dots{} ;; @r{Set the syntax for other characters.} (modify-syntax-entry ? " " emacs-lisp-mode-syntax-table) (modify-syntax-entry ?\t " " emacs-lisp-mode-syntax-table) @dots{} (modify-syntax-entry ?\( "() " emacs-lisp-mode-syntax-table) (modify-syntax-entry ?\) ")( " emacs-lisp-mode-syntax-table) @dots{} )) ;; @r{Create an abbrev table for lisp-mode.} (define-abbrev-table 'lisp-mode-abbrev-table ()) @end example Much code is shared among the three Lisp modes; the code is all in one library. Here is one function that sets various variables. This function is called by each of the major Lisp mode functions. @example (defun lisp-mode-variables (lisp-syntax) ;; @r{The @code{lisp-syntax} argument is @code{nil} in Emacs Lisp mode,} ;; @r{and @code{t} in the other two Lisp modes.} (cond (lisp-syntax (if (not lisp-mode-syntax-table) ;; @r{The Emacs Lisp mode syntax table always exists, but} ;; @r{the Lisp Mode syntax table is created the first time a} ;; @r{mode that needs it is called. This is to save space.} (progn (setq lisp-mode-syntax-table (copy-syntax-table emacs-lisp-mode-syntax-table)) ;; @r{Change some entries for Lisp mode.} (modify-syntax-entry ?\| "\" " lisp-mode-syntax-table) (modify-syntax-entry ?\[ "_ " lisp-mode-syntax-table) (modify-syntax-entry ?\] "_ " lisp-mode-syntax-table))) (set-syntax-table lisp-mode-syntax-table))) (setq local-abbrev-table lisp-mode-abbrev-table) @dots{} @dots{} @end example Functions such as @code{forward-word} use the value of the @code{paragraph-start} variable. Since Lisp code is different from ordinary text, the @code{paragraph-start} variable needs to be set specially to handle Lisp. Also, comments are indented in a special fashion in Lisp and the Lisp modes need their own mode-specific @code{comment-indent-hook}. The code to set these variables is the rest of @code{lisp-mode-variables}. @example (make-local-variable 'paragraph-start) (setq paragraph-start (concat "^$\\|" page-delimiter)) @dots{} (make-local-variable 'comment-indent-hook) (setq comment-indent-hook 'lisp-comment-indent)) @end example Each of the different Lisp modes has a slightly different keymap. For example, Lisp mode binds @kbd{C-c C-l} to @code{run-lisp}, but the other Lisp modes do not. However, all Lisp modes have some commands in common. The following function adds these common commands to a given keymap. @example (defun lisp-mode-commands (map) (define-key map "\e\C-q" 'indent-sexp) (define-key map "\177" 'backward-delete-char-untabify) (define-key map "\t" 'lisp-indent-line)) @end example Here is an example of using @code{lisp-mode-commands} to initialize a keymap, as part of the code for Emacs Lisp mode. First, @code{defvar} is used to create a mode-specific keymap variable if one does not exist. Then an @code{if} expression tests whether the @code{emacs-lisp-mode-map} variable has a value. If the variable does have a value, the expression does not change it. This protects the else part of the @code{if} expression against duplicate evaluation; and it lets the user customize the keymap if he or she so wishes. But if the @code{emacs-lisp-mode-map} variable lacks a value, the expression creates a sparse keymap and defines some keys. @example (defvar emacs-lisp-mode-map () "") (if emacs-lisp-mode-map () (setq emacs-lisp-mode-map (make-sparse-keymap)) (define-key emacs-lisp-mode-map "\e\C-x" 'eval-defun) (lisp-mode-commands emacs-lisp-mode-map)) @end example Finally, here is the complete major mode function definition for Emacs Lisp mode. @example (defun emacs-lisp-mode () "Major mode for editing Lisp code to run in Emacs. Commands: Delete converts tabs to spaces as it moves back. Blank lines separate paragraphs. Semicolons start comments. \\@{emacs-lisp-mode-map@} Entry to this mode calls the value of emacs-lisp-mode-hook if that value is non-nil." (interactive) (kill-all-local-variables) (use-local-map emacs-lisp-mode-map) ; @r{This provides the local keymap.} (set-syntax-table emacs-lisp-mode-syntax-table) (setq major-mode 'emacs-lisp-mode) ; @r{This is how @code{describe-mode}} ; @r{finds out what to describe.} (setq mode-name "Emacs-Lisp") ; @r{This goes into the mode line.} (lisp-mode-variables nil) ; @r{This define various variables.} (run-hooks 'emacs-lisp-mode-hook)) ; @r{This permits the user to use a} ; @r{hook to customize the mode.} @end example @node Setting the Major Mode, Mode Help, Major Mode Examples, Major Modes @subsection Setting the Major Mode Based on information in the file name or in the file itself, Emacs automatically selects a major mode for a buffer. @deffn Command fundamental-mode Fundamental mode is a major mode that not specialized for anything in particular. Other major modes are defined by comparison with this one. The @code{fundamental-mode} function does @emph{not} run any hooks, so it is not readily customizable. @end deffn @defun set-auto-mode @cindex visited file mode This function selects the major mode that is appropriate for the current buffer. It may base its decision on the value of the @samp{-*-} line, on the visited file name (using @code{auto-mode-alist}), or on the value of a local variable. @xref{Choosing Modes, , How Major Modes are Chosen, emacs, The GNU Emacs Manual}). However, this function does not look for the @samp{mode:} local variable near the end of a file. The @code{hack-local-variables} function does that. @end defun @deffn Command normal-mode &optional find-file This function automatically chooses the major mode for the current buffer. The mode is determined by first calling @code{set-auto-mode}. After calling the major mode function selected by @code{set-auto-mode}, the @code{normal-mode} function then runs @code{hack-local-variables} to parse, and bind or evaluate as appropriate, any local variables. If the @var{find-file} argument to @code{normal-mode} is non-@code{nil}, Emacs assumes that the @code{find-file} function is calling @code{normal-mode}. In this case, if @code{inhibit-local-variables} is non-@code{nil}, Emacs requires confirmation before processing a local variables list. If you run @code{normal-mode} yourself, the argument @code{find-file} is @code{nil}, so confirmation is never requested. @cindex file mode specification error @code{normal-mode} uses @code{condition-case} around the call to the major mode function, so errors are caught and reported as a @samp{File mode specification error}, followed by the original error message. @end deffn @defopt default-major-mode This variable holds the default major mode for new buffers. The standard value is @code{fundamental-mode}. If the value of @code{default-major-mode} is @code{nil}, Emacs uses the (previously) current buffer's major mode for major mode of a new buffer. @end defopt @defvar auto-mode-alist This variable contains an association list of filename patterns (regular expressions) and corresponding major mode functions. Usually, the filename patterns are suffixes, such as @samp{.el} and @samp{.c}, but this need not be the case. Each element of the alist looks like @code{(@var{regexp} .@: @var{mode-function})}. For example, @example ("^/tmp/fol/" . text-mode) ("\\.texinfo$" . texinfo-mode) ("\\.el$" . emacs-lisp-mode) ("\\.c$" . c-mode) ("\\.h$" . c-mode) @end example When you visit a file whose @emph{full} path name matches @var{regexp}, Emacs calls @var{mode-function}. This feature is used to cause Emacs to select the major mode appropriate to the file. Here is an example of how to prepend several pattern pairs to an existing @code{auto-mode-alist}. (You might use this sort of expression in your @file{.emacs} file to customize your @code{auto-mode-alist}.) @example (setq auto-mode-alist (append '(("/\\.[^/]*$" . fundamental-mode) ; @r{Filename starts with a dot.} ("[^\\./]*$" . fundamental-mode) ; @r{Filename has no dot.} ("\\.C$" . c++-mode)) auto-mode-alist)) @end example @end defvar @defun hack-local-variables &optional force This function parses, and binds or evaluates as appropriate, any local variables for the current buffer. If non-@code{nil}, the optional argument @var{force} overides the effect of a non-@code{nil} value for @code{inhibit-local-variables}. @xref{File variables, , Local Variables in Files, emacs, The GNU Emacs Manual}, for the syntax of the @code{hack-local-variables} section of a file. @end defun @defopt inhibit-local-variables When this variable is non-@code{nil}, Emacs will query the user before obeying a file's local-variables list. Emacs checks this variable when the local-variables list is scanned automatically after you find a file. However, if you yourself call @code{normal-mode}, there is no query, regardless of the value of this variable. @end defopt @defvar initial-major-mode @cindex *scratch* The value of this variable determines the major mode of the initial @samp{*scratch*} buffer. The value of the variable is a symbol, the name of the mode. The default value is @code{lisp-interaction-mode}. @end defvar @node Mode Help, Major Line Information, Setting the Major Mode, Major Modes @comment node-name, next, previous, up @subsection Getting Help about a Major Mode @cindex mode help @cindex help for major mode @cindex documentation for major mode The @code{describe-mode} function is used to provide information about major modes. It is normally called with @kbd{C-h m}. The @code{describe-mode} function uses the value of @code{major-mode}, which is why every major mode function needs to set the @code{major-mode} variable. @deffn Command describe-mode This function displays the documentation of current major mode. The @code{describe-mode} function calls the @code{documentation} function using the value of @code{major-mode} as an argument. Thus, it displays the documentation string of the major mode function. (@xref{Documentation Strings}.) @end deffn @defvar major-mode This variable holds the symbol for the current buffer's major mode. This symbol should be the name of the function which is called to initialize the mode. The @code{describe-mode} function uses the documentation string of this symbol as the documentation of the major mode. @end defvar @node Major Line Information, , Mode Help, Major Modes @subsection Information from the Mode Line The normal mode line contains a considerable amount of information: whether the buffer is modified, its name, the names of the major and minor modes, and the percentage of the buffer scrolled off the top. @defvar mode-line-modified This variable holds the mode-line control for displaying whether the current buffer is modified. The default value @code{mode-line-modified} is @code{("--%1*%1*-")}. This means that the mode line displays @samp{--**-} if the buffer is modified, @samp{-----} if the buffer is not modified, and @samp{--%%-} if the buffer is read only. Changing this variable does not force an update of the mode line. @end defvar @defvar mode-line-buffer-identification This variable identifies the buffer being displayed. Its default value is @samp{Emacs: %17b}, which means that it also causes the mode line to display @samp{Emacs}. You may want to change this, when you write modes that do not behave like a `normal' Emacs. @end defvar @defvar mode-name This buffer-local variable holds the ``pretty'' name of the current buffer's major mode. This string is displayed in the mode line of the buffer, if @code{mode-line-format} includes @code{mode-name}. This is why every major mode function needs to set the @code{mode-name} variable. @end defvar @defvar global-mode-string This variable holds a string that is displayed in the mode line if the variable is included in @code{mode-line-format} (the default) or if a @samp{%M} specification is included. Currently, only @code{display-time} modifies @code{global-mode-string}. @end defvar There are several other mode-line related variables in addition to those listed here. These other variables are @code{mode-line-process}, @code{mode-line-inverse-video}, and @code{minor-mode-alist}. For @code{mode-line-process}, @pxref{Process Information}; for @code{mode-line-inverse-video}, @pxref{Screen Attributes}; and for @code{minor-mode-alist}, @pxref{Minor Modes}. @node Minor Modes, Mode Line Format, Major Modes, Major and Minor Modes @section Minor Modes A @dfn{minor mode} provides features that users may enable or disable independently of the choice of major mode. Minor modes can be enabled individually or in combination. A minor mode is not merely a modification of single major mode. For example, you may use @code{auto-fill-mode} and @code{auto-justify-mode} in any major mode that permits text insertion. Minor modes would be better named `Generally available, optional feature modes' except that such a name is unwieldy. A minor mode is often much more difficult to implement than a major mode. There are several reasons for this. One is that you should be able to deactivate a minor mode and restore the environment of the major mode to the state it was in before the minor mode was activated. Often, in implementing a minor mode, the biggest problem is finding a way to insert the necessary hook into the running system. For example, some minor modes, such as Auto Fill mode, change how text is inserted into a buffer. Without @code{auto-fill-hook}, Auto Fill mode would be implemented only at great pain and great cost in editing efficiency. @menu * Minor Mode Conventions:: Tips for writing a minor mode. * Minor Mode Status:: Emacs tries to select the right mode. * Minor Mode Difficulties:: It is hard to write a minor mode. @end menu @node Minor Mode Conventions, Minor Mode Status, Minor Modes, Minor Modes @comment node-name, next, previous, up @subsection Conventions for Writing Minor Modes @cindex minor mode conventions @cindex conventions for writing minor mode There are conventions for writing minor modes just as there are for major modes. Several of the major mode conventions apply to minor modes as well: those regarding the name of the mode initialization function, the names of global symbols, and the use of keymaps and other tables. In addition, there are several conventions that are specific to minor modes. @itemize @bullet @item A minor mode initialization function should toggle the mode on and off with each call, or turn the mode on if given a positive integer. @item The minor mode function should set a variable with the same name as the minor mode to a non-@code{nil} value. This variable is used in conjunction with the @code{minor-mode-alist} to display the minor mode name in the mode line. @item A two element list needs to be constructed, the first element of which is the minor mode variable and the second element of which is a short string name for the minor mode. This two list must be added to the @code{minor-mode-alist}. (@xref{Minor Mode Status}.) @item If the minor mode adds new keybindings to the local keymap, you should be able to restore the keymap to its original value when you deactivate the minor mode. @end itemize @node Minor Mode Status, Minor Mode Difficulties, Minor Mode Conventions, Minor Modes @comment node-name, next, previous, up @subsection Minor Mode Status Display Since minor modes can be enabled independently, it is nice to see which ones are enabled in each buffer. @defvar minor-mode-alist This variable holds an association list the elements of which specify how Emacs should indicate in the mode line that a minor mode is active. The usual procedure is to print a short name for the mode when it is active. Each element of the @code{minor-mode-alist} looks consists of the two element list: @example (@var{minor-mode-variable} @var{mode-line-string}) @end example @var{mode-line-string} is included in the mode line when the value of @var{minor-mode-variable} is non-@code{nil} and not otherwise. Conventionally, the @var{minor-mode-variable} for a specific mode is set to a non-@code{nil} value when that minor mode is activated. The default value of @code{minor-mode-alist} looks like this: @example minor-mode-alist @result{} ((abbrev-mode " Abbrev") (overwrite-mode " Ovwrt") (auto-fill-hook " Fill") (defining-kbd-macro " Def")) @end example @noindent (Note that in version 19, @code{auto-fill-hook} has been renamed @code{auto-fill-function}. Also, note the space at the beginning of each @var{mode-line-string}.) @code{minor-mode-alist} should not be made buffer-local. The variables in the alist should be buffer-local if the minor mdoe is enableable separately in each buffer. Here is an example of a safe way to augment the alist when you load a package or activate a minor mode; it avoids adding the element more than once. @example (or (assq 'leif-mode minor-mode-alist) (setq minor-mode-alist (cons '(leif-mode " Leif") minor-mode-alist))) @end example @end defvar @node Minor Mode Difficulties, , Minor Mode Status, Minor Modes @comment node-name, next, previous, up @subsection Difficulties Writing a Minor Mode @cindex @code{self-insert-command}, and minor modes It is very difficult to write a minor mode that responds to arbitrary self-insert characters. The principal problem is that @code{self-insert-command}, the primitive to insert the last key typed, is a primitive function written in C. It does not call any hooks, except in special cases. Unfortunately, you cannot simply substitute your own definition of @code{self-insert-command} for the existing one, as you can with most functions. This is a consequence of the way Emacs's command loop works: in the command loop, Emacs checks whether a key is bound to @code{self-insert-command} and, if it is, Emacs calls the primitive @code{self-insert-command} function directly. Emacs does not check to see whether you have written another version of the function to substitute for it. This is done for speed. (Indeed, in general, if you substitute a Lisp function for a primitive, the C code within Emacs will continue to call the original primitive, but Lisp code will call your substitute Lisp function.) Instead of attempting to replace the function definition for @code{self-insert-command}, you could rebind all keys that call @code{self-insert-command} using @code{substitute-key-definition}. This solution works fine if you are using only one minor mode. But if you are using several minor modes at the same time, and you want to deactivate them, you must deactivate them in the reverse order that they were activated to ensure that keymaps are properly restored. @node Mode Line Format, Hooks, Minor Modes, Major and Minor Modes @section Mode Line Format @cindex mode line format The @code{mode-line-format} is a buffer-local variable that holds a template used to display the mode line of the current buffer. All windows for the same buffer use the same @code{mode-line-format} and the mode lines will appear the same (except, possibly, for the percentage of the file scrolled off the top). The mode-line contains information about the buffer such as its name, associated file, depth of recursive editing, and, of course, the major and minor modes of the buffer. The mode line of a window is normally updated whenever a different buffer is shown in the window, or when the buffer's modified-status changes from @code{nil} to @code{t} or vice-versa. If you modify any of the variables referenced by @code{mode-line-format}, you may want to force an update of the mode line so as to display the new information. You can do this with the following expression: @findex buffer-modified-p @r{example} @example (set-buffer-modified-p (buffer-modified-p)) @end example The mode line display the values of variables such as @code{mode-name} and @code{minor-mode-alist}. Because of this, very few modes will need to alter @code{mode-line-format} or @code{default-mode-line-format}. For most tasks, it is sufficient to alter the variables referenced by @code{mode-line-format}. If you are writing a new mode and you must modify the mode line, it is good practice to use a value that is similar to the default since users will expect information to be displayed in familiar places. You should document what significant information might be displayed in the mode line by your mode. Any replacement for @code{mode-line-format} should use all the same variables that are used by the default value, rather than duplicating their contents or displaying the information in another fashion. This permits customizations made by the user, by libraries (such as @code{display-time}) or by major modes via changes to those variables remain effective. @cindex Shell mode @code{mode-line-format} Here is an example of a @code{mode-line-format} that might be useful for @code{shell-mode} since it contains the hostname and default directory. @example (setq mode-line-format (list "" 'mode-line-modified "%b--" (getenv "HOST") ":" 'default-directory " " 'global-mode-string " %[(" 'mode-name 'minor-mode-alist "%n" 'mode-line-process ")%]----" '(-3 . "%p") "-%-")) @end example @defvar mode-line-format The value of @code{mode-line-format} may be a list, cons cell, symbol, or string. If the value is a list, its elements may be a list, cons cell, symbol, or string. @table @code @item (@var{string} @var{rest}) @r{or} (@var{rest} @var{rest}) When the value of @code{mode-line-format} is a list whose first element is a string or list, each element is processed recursively and the results are concatenated. This is the most common form. @item (@var{symbol}) When the value of @code{mode-line-format} is a symbol, the value of @var{symbol} is used in place of @var{symbol} unless @var{symbol} is @code{t}, @code{nil}, or void, in which case @var{symbol} is ignored. The exception is that if the value of @var{symbol} is a string, it is processed verbatim in that the @dfn{%-constructs} described below are not recognized. @item (@var{symbol} @var{rest}) When the value of @code{mode-line-format} is a list whose first element is @var{symbol}, the symbol's value is found, and if that value is non-@code{nil}, the second element of the list is processed recursively. But if the value of @var{symbol} is @code{nil}, the third element of the list (if there is one) is processed recursively. This construct is, therefore, a conditional. @item (@var{width} @var{rest)} When the value of @code{mode-line-format} is a list whose first element is an integer, the remainder of the list is processed on its own and space filled (if positive) or truncated (if negative) on the right to the width specified by @var{width}. For example, the usual way to show what percent of a buffer is above the top of the window is to use a list that looks like this: @code{(-3 . "%p")}. @cindex percent symbol in mode-line @item @var{string} When the value of @code{mode-line-format} is a string, the string is displayed verbatim in the mode line except for @dfn{@code{%}-constructs}. Decimal digits after the @code{%} specify the field width for space filling on the right (i.e., the data is left justified). @end table @end defvar @menu * %-constructs:: Putting information into a mode line. @end menu @node %-constructs, , Mode Line Format, Mode Line Format @comment node-name, next, previous, up @subsection @code{%}-constructs in the Mode Line The following table lists the recognized @code{%}-constructs and what they mean. @table @code @item %b prints the buffer name; uses the @code{buffer-name} function. @item %f prints the visited file name; uses the @code{buffer-file-name} function. @item %* prints @samp{*} if the buffer is modified (see @code{buffer-modified-p}); @* prints @samp{-} if the buffer is not modified; @* prints @samp{%} if the buffer is read only (see @code{buffer-read-only}). @item %s prints the process status (see @code{process-status}). @item %p prints the percent of the buffer above the top of window, or Top, Bottom or All. @item %n prints @samp{Narrow} when a narrowing restriction is in effect (see @code{narrow-to-region}). @item %[ print one @samp{[} for each recursive editing level. @samp{%]} is similar. @item %% prints @samp{%} @item %- prints dashes that fill the remainder of line, ignoring the remainder of the template. @end table The following two @code{%}-constructs are still supported but are obsolete since use of the @code{mode-name} and @code{global-mode-string} variables will produce the same results. @table @code @item %m the value of @code{mode-name}. @item %M the value of @code{global-mode-string}. Currently, only @code{display-time} modifies @code{global-mode-string}. @end table @defvar default-mode-line-format This variable holds the default @code{mode-line-format} for buffers that do not override it. This is the same as @code{(default-value 'mode-line-format)}. The default value of @code{default-mode-line-format} is: @example (list "" 'mode-line-modified 'mode-line-buffer-identification " " 'global-mode-string " %[(" 'mode-name 'minor-mode-alist "%n" 'mode-line-process ")%]----" '(-3 . "%p") "-%-")) @end example @end defvar @node Hooks, , Mode Line Format, Major and Minor Modes @section Hooks A @dfn{hook} is a variable whose value is a @dfn{hook function} or a list of hook functions. These functions are called by parts of Emacs on well-defined occasions. Hooks are used for customization. The functions referenced by a hook may be changed by the user or by other functions. Most modes run hooks as the last step in the modes' initialization. This makes its easy for a user to customize the behavior of a mode. But hooks may also be used in other contexts. For example, the functions named by @code{find-file-not-found-hooks} are called whenever a file is not found by @code{find-file}. @xref{Standard Hooks}, for a list of hooks. Typically, the hooks for a mode are run after the mode has completed all its other initialization. You may, for example, use a hook to change the initial values of buffer-local variables. For example, you can put the following expression in your @file{.emacs} file if you want to turn on Auto Fill mode in Lisp Interaction mode: @example (setq lisp-interaction-mode-hook 'turn-on-auto-fill) @end example The following example shows how to use a hook to customize the way Emacs formats C code. (People often have strong personal preferences for one format compared to another.) Here the hook function is an anonymous @code{lambda} expression. @cindex lambda in hooks @example (setq c-mode-hook (function (lambda () (setq c-indent-level 4 c-argdecl-indent 0 c-label-offset -4 c-continued-statement-indent 0 c-brace-offset 0 comment-column 40 )))) (setq c++-mode-hook c-mode-hook) @end example Finally, here is an example of how to use the Text mode hook to provide a customized mode line for buffers in Text mode. This hook displays the directory in addition to the standard components of the mode line. (If you have very long path names or display the time and load, you may run out of space on the mode line.) @example (setq text-mode-hook (function (lambda () (setq mode-line-format (list "" 'mode-line-modified "Emacs: %14b" " " 'default-directory " " 'global-mode-string "%[(" 'mode-name 'minor-mode-alist "%n" 'mode-line-process ") %]---" '(-3 . "%p") "-%-"))))) @end example At the apprpriate time, Emacs uses the @code{run-hooks} function to run the hooks you have specified. Most major modes have lines in their functions defintions that look like these, from Text mode, C mode and Mail mode respectively. Note that Mail mode runs two hooks in succession. @example (run-hooks 'text-mode-hook) (run-hooks 'c-mode-hook) (run-hooks 'text-mode-hook 'mail-mode-hook) @end example @defun run-hooks &rest hookvar This function takes one or more hook names as arguments and runs each one in turn. Each @var{hookvar} argument should be a symbol which is a hook variable. These arguments are processed in the order specified. If a hook variable has a non-@code{nil} value, that value may be a function or a list of functions. If the value is a function (either a lambda expression or a symbol with a function definition), it is called. If it is a list, the elements are called, in order. The hook functions are all called with no arguments. @example (run-hooks 'emacs-lisp-mode-hook) @end example Major mode functions may use this function to call any hooks defined by the user. @end defun