Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!uxc!uxc.cso.uiuc.edu!m.cs.uiuc.edu!liberte From: liberte@m.cs.uiuc.edu Newsgroups: gnu.emacs Subject: Re: Minor modes Message-ID: <52400013@m.cs.uiuc.edu> Date: 8 Feb 89 17:51:00 GMT References: <35717@bbn.COM> Lines: 61 Nf-ID: #R:bbn.COM:35717:m.cs.uiuc.edu:52400013:000:2925 Nf-From: m.cs.uiuc.edu!liberte Feb 8 11:51:00 1989 I had posted a note about minor modes in bug-gnu-emacs. That note follows. Stallman's response was that minor modes for character insertion are an unsolved problem. (I wrote some change-hooks that are called before or after each change to a buffer. This solves most of the problems, but may introduce garbage collection problems that I have to look into.) The last solution below looks like it would be too slow. Dan LaLiberte uiucdcs!liberte liberte@cs.uiuc.edu liberte%a.cs.uiuc.edu@uiucvmd.bitnet ====================================== I've been revising the elisp manual section on minor modes, and I have come to the conclusion that there are no simple ways to implement (in Lisp) minor modes that affect character insertion commands. It does not work to substitute a lisp function for self-insert-command since that function is called directly, or simulated, in the command loop. It does not work to use substitute-key-definition to replace the self-insert-command with a differently named lisp function because another minor mode might wish to do the same, or the major mode might have already done that. A minor mode could replace bindings for a set of keys, but the major mode might be doing something completely different with them. Even if we could catch all self-inserts, we wouldnt catch insertions (or deletions for that matter) caused by other commands. The change-hooks are needed for that. But there is a general problem with minor modes implemented by changing the keymap. To reliably deactivate several such minor modes (so the keymaps are restored to the original), the user must deactivate them in the inverse order they were activated. Here is a bizarre scheme to handle this: every minor mode that needs to be automatically deactivated should wrap an unwind-protect around a catch around a recursive-edit. Then to deactivate a mode farther up the stack, a throw is done with the corresponding tag and any intermediate minor modes would be able to automatically deactivate themselves. An example of this kind of minor mode is Leif mode. Leif mode is a rather large minor mode that remembers the keymap it was started with and restores to that when deactivated. It is rather tricky to make Leif mode work with vip-mode too. Here is another scheme to avoid the above problems. Replace each key binding with a function that first calls your-minor-mode-hook, if it is non-nil, and then calls the original function, or whatever is appropriate. When a minor mode is deactivated, the hook is simply niled out so the function behaves as the original did. When reactivated, the minor mode should test whether the hook is already in place, by testing a global variable. This scheme would not work well with minor modes that replace keymaps (or entries) when deactivated because they would restore the keymap to use the original function rather than the hooked function. Any other ideas?