[plt-scheme] Overriding the keymap in drscheme

From: Danny Yoo (dyoo at hkn.eecs.berkeley.edu)
Date: Tue Jul 25 14:26:38 EDT 2006

Hi everyone,

Guillaume and I are running into a problem in DivaScheme when installs its 
keymap. The thing is that I'm not just extending the existing keymap, but 
overriding it entirely.  It is important that no other keybindings be 
available when DivaScheme is on.

Here's a snippet of the text mixin:

   (define (diva-link:text-mixin super%)
     (class super%


       (define divascheme-keymap ...)

       (define (to-divascheme-mode)
         (preferences:set 'divascheme:on? #t)
         (send divascheme-keymap chain-to-keymap (get-keymap) false)
         (set-keymap divascheme-keymap))

       (define/public (to-normal-mode)
         (preferences:set 'divascheme:on? #f)
         (set-keymap (first (send divascheme-keymap get-chained-keymaps))))

       (let ([keymap (get-keymap)])
         (send keymap add-function "diva:to-divascheme-mode"
               (lambda (any event) (to-divascheme-mode)))
         (send keymap map-function "f4" "diva:to-divascheme-mode"))

       (when (preferences:get 'divascheme:on?)

The scenario is the following: if 'divascheme:on? is true, DrScheme 
installs the DivaScheme keymap midway through the initialization.  Tools 
that load after DivaScheme break in two ways:

    1.  Their keyboard bindings are active during the DivaScheme session 
because they chain their keymap to the DivaScheme keymap.

    2.  When we go back to normal mode, the set-keymap call restores a 
keymap that does not have the tools that loaded after DivaScheme.

The SET-KEYMAP in TO-NORMAL-MODE tries to alleviate problem #2 a bit.  If 
a tool loads after DrScheme and chains its keymap at the end of the list, 
the GET-CHAINED-KEYMAPS will recover it.  It's better than saving the 
original (partially initialized) keymap in a global variable, and 
restoring it in TO-NORMAL-MODE, but it's still not right.

We haven't been able to find API support to do this properly.  Is there a 
way to do this?

Posted on the users mailing list.