[plt-scheme] keybinding and menus

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Tue Dec 1 11:16:21 EST 2009

On Wed, Nov 25, 2009 at 9:39 AM, Laurent <laurent.orseau at gmail.com> wrote:
> Hi all,
> DrScheme is a wonderful editor and the possibility to remap keys is great...
> when you can make it work.
> I'm struggling with my "mykeys.ss" and the net and the help desk could not
> help me much.
> There is of course the useful:
> http://schemekeys.blogspot.com/2007/05/keybinding-101-in-drscheme.html
> but it says nothing about the hereby problems.
> I did not find anything about keybindings on planet (is there?).
> First, in order to rebind some keys defined for menus, the option
> "keybindings in menus" in menu preferences/editing/general must be disabled
> (for me, and it seems that this behavior is different for other people (?)).
> My quick guess is that the menus keybindings are defined after "mykeys.ss"
> file is loaded, which is not what I want.
> This forces me to redefine some of the bindings of the menus by hand...

I've fixed drscheme so that user-defined keybindings override the menu
keys (in SVN).

> Thus, Second: How do I rebind a key to open a new tab?
> Let's define (this is a untested simplification of my file):
>> (define (keymap-fun fun-name)
>>     (lambda (editor event)
>>       (send (send editor get-keymap) call-function
>>             fun-name
>>             editor event #t)))
> Then:
>> (keybinding "c:n" (keymap-fun "New Tab"))
> does not work (it does nothing, no error, not even printing "n").
> "New tab", "Nouvel onglet", "Nouvel Onglet" (my DrScheme is in french, so I
> don't know which is the good one) did not work either.
> Where can I find information about this? (because there are other menu items
> that I want to rebind)

The names of the menus are different from the names in the keymap.
Generally speaking, the names in the "show active keybindings" menu
are either in lowercase with hyphens, meaning tha they are callable
like the above, or they are in mixed case with spaces, meaning they
are menu names and are not callable like that.

You can get a hold of the frame, tho, and call a method on it for this
particular menu item:

#lang s-exp framework/keybinding-lang

(define (get-frame obj)
    [(is-a? obj editor<%>)
     (send (send obj get-canvas) get-top-level-window)]
     (send obj get-top-level-window)]))

(keybinding "c:n" (λ (obj evt) (send (get-frame obj) open-in-new-tab #f)))

> Third:
> I tried some experiments and there are some strange behaviors:
>> (for-each (lambda (key-str) (keybinding (first key-str) (keymap-fun
>> (second key-str))))
>>   '(
>>      ["c:semicolon" "comment-out"] ; works
>>      ["c:s:semicolon" "uncomment"] ; does not work (on french layout, "."
>> is ";" shifted)
>>      ["c:s:." "uncomment"] ; does not work (also c:s:period does not
>> exist)
>>      ["c:." "uncomment"] ; does not work
>>      ["c:s:q" "uncomment"] ; does not work, prints "Q"
>>      ["c:q" "uncomment"] ; works
>>      ["c:s:W" "uncomment"] ; does not work, prints "W"
>>      ["c:W" "uncomment"] ; works, like c:w
>>      ["c:m:r" "uncomment"] ; does not work, does nothing
>>      ["m:s:r" "uncomment"] ; works
>>      ["m:semicolon" "uncomment"] ; works
>>      ["m:s:semicolon" "uncomment"] ; does not work, prints "."
>>  ))
> I would especially like the "c:s:semicolon" to work...

I think you might just need the ?: prefix to make things work (see the
docs for map-function for more on that). This is a messy area that
needs to be cleaned up at some point, but one of the above should be
made to work. I don't have a windows machine (or a french keyboard!)
to try these things out so I'm kind of stuck on this one.

> Also, reloading DrScheme for each test takes some time... isn't there a
> faster way to test keybindings?

In the general case, no. Your keybindings can (and from what I can
tell, people's often do) rely on all kinds of parts of drscheme's
implementation. And if that's not loaded it can't run.

You can, however, develop the implementation of your keybindings in a
separate file and then just require that file into your keybindings
file. For example, if your keybinding only depends on the core gui
library, you can use this to help you build it:

#lang scheme/gui

(define (my-keybinding)
  (send t insert "hello!"))

(define f (new frame% [label ""] [width 200] [height 200]))
(define t (new text%))
(define ec (new editor-canvas% [parent f] [editor t]))
(define b (new button%
               [label "test keybinding"]
               [parent f]
               [callback (λ x (my-keybinding))]))
(send ec focus)
(send f show #t)

> Thanks for reading this and helping me if possible.

On Mon, Nov 30, 2009 at 2:08 AM, Laurent <laurent.orseau at gmail.com> wrote:
> Does anyone has some thoughts about these issues? Or did I completely
> misunderstood how keybinding works?

Sorry for the delay in replying.


Posted on the users mailing list.