Keybinding 101 in DrScheme

Ever since I can remember during my days with DrScheme, it has always annoyed me that I couldn't comment out a block of code with an easy to use keyboard shortcut. The default short cut for the comment-out command is either `ESC;c:semicolon' or `m:c:semicolon'. Now see here we go, I have to immediately explain this little language for expressing keystrokes, or you won't get a thing out of what I'm trying to convey. The truth is that I only last week finally put all the pieces together to assign a set of easily accessible keys combinations to both the comment-out and the uncomment commands, which in scheme simply prepends a semicolon at the very first character of a line, and removes it respectively. These are great tools when you are hacking up a program and you run into a bug, but your not quite sure what section of code is responsible for the bug. You just comment out pieces of your source in a logical progression until you've isolated the little pest.

Let me say first how appreciative I am of the help I received on this topic, both from various posts on this topic at plt-scheme@list.cs.brown.edu, and specifically a grand gentlemen who is perpetually involved with helping people who submit posts or bug reports to PLT. His name is Robby Findler, and you'll never find a more helpful man to deal with on matters relating to PLT. And he is kind of heart, not known to me to punish you for posting a bug report that turns out to be your own typographical mistake. I can vouch for this personally. Actually, I could say the same things about nearly the entire PLT crew, but it was Robby who specifically helped me out with todays topic.

The first thing you should realize about assigning a new key binding to actuate a certain command is that there are several ways to go about it. But to make the task much simpler for typical kinds of keymapping, which is what the process is called in DrScheme, the PLT bunch have provided a way directly off the `Edit' menu, under the menu item `Keybindings' a sub-menu-item entitled `Add User-defined Keybindings...'. Sounds simple enough, and indeed a file open dialog box appears straight away ready to accept your User-defined Keybinding file. The catch is, it doesn't take you to a directory filled with example keybinding files that you could use as a template in making your own file. The truth is the description of the structure of this file is only been recently better documented in the manuals, and in my opinion, the documentation still leaves the uninitiated pretty much clueless on what sort of file they should be handing to DrScheme as a valid keybindings file. I intend to show you how that file should be written, and document where you can read more about the topic.

First off you'll want to read section 3.3.7 Defining Custom Shortcuts, in the PLT:DrScheme Programming Environment Manual. I've reproduce it here with permission, for your convenience, since it's such a short piece.

3.3.7 Defining Custom Shortcuts

The Add User-defined Keybindings... menu item in the Keybindings sub-menu of Edit selects a file containing Scheme definitions of keybindings. The file must contain a single module that uses a special keybindings language, (lib "keybinding-lang.ss" "framework"). For example, a file named mykeys.ss for keybindings might contain the following code:

(

module

mykeys

(

lib

"keybinding-lang.ss"

"framework"

)

...

)

The keybindings language includes all of MzScheme, (lib "mred.ss" "mred"), (lib "class.ss"), and one addition, a keybinding form:

(

keybinding

keybinding-string-expr keybinding-proc-expr

)

The keybinding-string-expr must produce a suitable first argument for map-function in keymap%, and the keybinding-proc-expr must produce a suitable second argument for add-function in keymap%.

Also the require statement

(

require

(

lib

"tool-lib.ss" "drscheme"

))

adds all of the names defined in the tools manual to your keybindings module, in order to help define drscheme-specific keybindings.

Putting it all together it means our keybinding file should come out looking something like this, for a single instance of key remapping:

(

module

mykeys

(

lib

"keybinding-lang.ss"

"framework"

)

(

require

(

lib

"tool-lib.ss" "drscheme"

))

(

keybinding

keybinding-string-expr keybinding-proc-expr

)

)

Now all we have to do is come up with two expressions, the keybinding-string-expr and the keybinding-proc-expr. They've even provided hot links to the functions whose arguments these two expression become to help us out. These hot links are live in this post as well, so feel free to check out the documentation available for both functions.

In the case of the first keybinding-string-expr the documentation has become quite thorough. It describes how you build the string that defines the keystroke sequence that you wish to use to activate your function. I'll review this with you in just a moment. In the case of the second keybinding-proc-expr it is not clear at all what you should be using for a valid function name, nor where one would find them. As it was explained to me by Robby Findler, the scope of the available functions includes simply everything PLT has to offer, including functions that can be found in PlaneT, and even my own libraries. That's good to know, but I remain fuzzy on the precise protocol for calling functions from different sources. What I intend to do in this post is make available to you a method of determining the vast majority of editor functions available in standard DrScheme. If you have a desire to make a hot key for your favorite PlaneT package function I would refer you to the good people on the PLT mailing list, who should be able to come up with an answer for a specific question on mapping a specific function.

Now to get back to how you go about defining the keystrokes for your new keybinding-string-expr. The first thing to know is the terminating character, of a possibly chorded key combination, can have more than one keybinding. The rules for precedence over which keybinding actually gets invoked are pretty simple, but very specific. Generally speaking, the more modifier keys used in a key combination, the higher its precedence. In the event that two key combinations enumerate the same number of modifiers, the string that prohibits the use of the most modifier keys while typing the other required keys in the sequence, has the higher precedence. I'll have more to say about this later when we get to some specific examples.

The actual string that makes up the keybinding-string-expr is formated as a semicolon delimited sequence of state strings. Each of these state strings indicates the presence of a either a modifier key being pressed or not pressed, or a the state of a mouse button, a double or triple click, function keys, numeric keypad keys or a regular character key. Certain characters are special. The colon indicates that the previous character in the string is to be interpreted as a modifier key. And the semicolon delimits sequences of states, such that you can represent first one key being pressed and then subsequently another key being pressed. Since they are special, and since states like the status of a mouse button do not have standard character representations, PLT has come up with a long list of special names that you can use to represent these states. For a complete list see the documentation for the map-function. I'll just give you enough to get you started. The colon key is represented as the string "colon" and the semicolon character is represented by the string "semicolon", not surprisingly. Another special character is tilde `~' key. When it is prefixed to a modifier key, it reverses the meaning, such that it only matches states in which the modifier key is not pressed. Since the modifier keys are so commonly used, I've reproduced their representative strings below for you convenience.

`` s: '' -- All platforms: Shift

'' -- All platforms: Shift `` c: '' -- All platforms: Control

'' -- All platforms: Control `` a: '' -- Mac OS X: Option

'' -- Mac OS X: Option `` m: '' -- Windows: Alt; X: Meta

'' -- Windows: Alt; X: Meta `` d: '' -- Mac OS X: Command

'' -- Mac OS X: Command `` ?: '' -- All platforms: allow match to character produced by opposite use of Shift and/or AltGr/Option, when available; see get-other-shift-key-code in key-event%

The modifier identifiers are:

By the way, that last modifier matching string "?:", produces two other precedence classes of state strings, both of which rank below everything else. The higher of the two precedence classes takes effect when you simply use the "?:" match sequence on either the Shift or the AltGr(Windows)/Option(Mac) keys, and the lowest takes effect when you use it on both. But remember, you'll likely be trying to achieve the highest precedence you can so that you'll be certain to override any other keybinding that may be in effect for your chosen hot key, so it's not likely that you'll be worrying about these types of match sequences very often.

I think about now is a good time to review some examples taken shamelessly from the manual.

Examples:

"space" -- matches whenever the space bar is pressed, regardless of the state of modifiers keys.

-- matches whenever the space bar is pressed, regardless of the state of modifiers keys. "~c:space" -- matches whenever the space bar is pressed and the Control key is not pressed.

-- matches whenever the space bar is pressed and the Control key is not pressed. "a" -- matches whenever ``a'' is typed, regardless of the state of modifiers keys (other than Shift).

-- matches whenever ``a'' is typed, regardless of the state of modifiers keys (other than Shift). ":a" -- matches only when ``a'' is typed with no modifier keys pressed.

-- matches only when ``a'' is typed with no modifier keys pressed. "~c:a" -- matches whenever ``a'' is typed and neither the Shift key nor the Control key is pressed.

-- matches whenever ``a'' is typed and neither the Shift key nor the Control key is pressed. ":esc;:c:c" -- matches an Escape key press (no modifiers) followed by a Control-C press (no modifiers other than Control).

-- matches an Escape key press (no modifiers) followed by a Control-C press (no modifiers other than Control). "?:d:+" -- matches when Command is pressed with the key that produces ``+'', even if producing ``+'' normally requires pressing Shift.

There are two examples here that I think are worthy of mention beyond what is explained in the manual. The first is the ":a" sequence. You'll notice it has a leading colon, but no preceding character for the colon to interpret as a modifier key. This has a very desirable effect, in that is it matches only if no modifier keys are pressed. You'll remember that the precedence goes up with the number of modifiers that cannot be pressed for a state string to match, all else being equal. Well this is the best way to insure that your hot key to whatever key you've chosen; lets make it a bit more realistic and map it to a function key like this ":f11", will have the highest precedence possible for an un-chorded press of F11. The state string ":f11" matches only if no modifier keys are pressed and the f11 function key is pressed by itself, and since it is preceded by a colon, it trumps any other keybinding to f11 without a modifier key, except for any other keybindings that are identical, in which case, unfortunately, the winner is selected arbitrarily. The other example worthy of further mention is the ":esc;:c:c" sequence. Note it to starts off with a colon as well, so the Esc key must be pressed by itself. Then there is that semicolon. This translates to, and now you release the previous state string, and press the sequence corresponding to the following state string. In this case the following sequence again starts off with a colon (you can tell somebody was after the highest possible precedence they could get), so the following `c:' represents the control key, which must be typed in the absence of any other modifiers due to the previous colon. Finally, we get to the actual character key, which is the letter `c'. To match this sequence you have to type the Esc key by itself, release it, and then type control-c, with no other modifier keys pressed. Not the most convenient shortcut, but it shows off the versatility of what you can do with the proper encoding.

I encourage you to read the entire section on the map-function. It is very well written, and it supplies you with the names for any possible key and/or mouse combination you could possibly want. With all that we've learned now, you can finally decode those annoying hot keys for commenting out code that I was complaining about at the outset of this post. They are `ESC;c:semicolon' and `m:c:semicolon' respectively. Well that first one sure looks familiar. It requires that you press the Esc key, with any set of modifiers you'd like to throw in, then release the Esc key, and finally press control-semicolon. Not what I'd call exactly convenient. Then it gets worse with the next sequence. At the time I first started using DrScheme I didn't own a *nix box, or a Mac. And the first of the two required modifier keys in this sequence is the meta key, which has no equivalent on an XP box. So even had I wanted to learn these unwieldy chorded keystrokes, I wasn't going to be able to use that hot key sequence at all. I know now that I could have used the Alt key for the meta key, but at the time I was clueless. Now I own a Mac Pro and DrScheme gives you the option of using your option key as the meta key. However, the option key is my gateway into quick access to a variety of special characters, that I would other wise have to pull up the special-character tool to insert into a document. No, what I wanted was a very quick key combination, so that I'd actually get some use out of these shortcuts.

The official document within the Help Desk where you can find the default global keybindings for an editor is keymap:setup-global in frameworks functions. However, this doesn't nearly cover all the keybindings you'll see when you look at your Active Keybindings. To get the entire list, minus the menu shortcuts, you have to employ the use of several functions, each of which adds its own particular set of bindings to the keymap. As far as I know, this information is not provided in any one location within a particular manual. So, here you get the product of my research into reconstructing the better part of the Active Keybindings in a default DrScheme system.

( let ([ keymap ( new keymap:aug-keymap% )] [ drscheme:keymap ( drscheme:rep:get-drs-bindings-keymap )]) ( scheme:setup-keymap keymap ) ( keymap:setup-global keymap ) ( keymap:setup-search keymap ) ( keymap:setup-file keymap ) ( keymap:set-chained-keymaps keymap ( list drscheme:keymap )) ( let* ([ table ( send keymap get-map-function-table )] [ bindings ( hash-table-map table list )] [ sym-first-list ( sort bindings ( lambda ( x y ) ( string<=? ( cadr x ) ( cadr y ))))])

There are in fact commands available for all the menu functions, but to get the correct function name to call to actuate them takes some direct help from someone in the PLT group to help you, or a lot of searching through source code. As far as I know, there is no place in the manuals that gives any more information than what I've provided you. And as you can see, it's scattered about in different function calls that simply take a lot of time to research. Now many of these functions are displayed in the Active Keybindings dialog box, however, there is no way to copy them off the dialog box, so that you can make your own list and design a strategy for your custom keymapping. Hopefully, the tables below will fill this gap, and you'll be able to get to the majority of the generic editor functions provided by a basic DrScheme editor frame in Scheme mode. One very hospitable thing the PLT crew have done with the global keybindings is make it quite simple for you to override them. If you go down the list, there is only one state string that begins with a colon, and that is for the mouse-popup-menu, bound to ":rightbuttonseq". That means, if you would rather use a keybinding for something else, or swap a couple around, you can easily do this by simply placing a colon at the beginning of your own custom keybinding, which will automatically give it higher precedence, as we discussed above.

Keymap - Welcome to DrScheme, version 369.100-svn5may2007 [3m].

"\u001f" undo back-to-prev-embedded

-editor "m:c:left" ")" balance-parens back-to-prev-embedded

-editor "ESC;c:left" ":rightbuttonseq" mouse-popup-menu back-to-prev-embedded

-editor "a:c:left" "ESC;"" insert-""-pair backward-character "c:b" "ESC;(" insert-()-pair backward-character "left" "ESC;0" command-repeat-0 backward-kill-word "m:del" "ESC;1" command-repeat-1 backward-kill-word "ESC;del" "ESC;2" command-repeat-2 backward-select "s:c:b" "ESC;3" command-repeat-3 backward-select "s:left" "ESC;4" command-repeat-4 backward-select

-word "m:s:b" "ESC;5" command-repeat-5 backward-select

-word "ESC;s:b" "ESC;6" command-repeat-6 backward-select

-word "a:s:left" "ESC;7" command-repeat-7 backward-select

-word "c:s:left" "ESC;8" command-repeat-8 backward-sexp "ESC;left" "ESC;9" command-repeat-9 backward-sexp "m:c:b" "ESC;<" beginning-of-file backward-sexp "ESC;c:b" "ESC;>" end-of-file backward-word "m:b" "ESC;[" insert-[]-pair backward-word "ESC;b" "ESC;a:return" do-return backward-word "a:left" "ESC;b" backward-word backward-word "c:left" "ESC;c" capitalize-word balance-parens ")" "ESC;c:=" uncomment balance-parens "]" "ESC;c:a:return" do-return balance-parens "}" "ESC;c:b" backward-sexp beginning-of-file "m:<" "ESC;c:down" down-into-embedded

-editor beginning-of-file "ESC;<" "ESC;c:f" forward-sexp beginning-of-file "d:up" "ESC;c:g" ring-bell beginning-of-file "c:home" "ESC;c:k" remove-sexp beginning-of-line "c:a" "ESC;c:left" back-to-prev-embedded

-editor beginning-of-line "d:left" "ESC;c:p" flash-backward-sexp beginning-of-line "m:left" "ESC;c:return" do-return beginning-of-line "home" "ESC;c:right" forward-to-next

-embedded-editor capitalize-word "m:c" "ESC;c:s:a:return" do-return capitalize-word "ESC;c" "ESC;c:semicolon" comment-out center-view-on-line "c:l" "ESC;c:space" select-forward-sexp check syntax "c:c;c:c" "ESC;c:t" transpose-sexp check syntax "f6" "ESC;c:u" up-sexp collapse-newline "c:x;c:o" "ESC;c:up" up-out-of-embedded

-editor collapse-space "m:space" "ESC;d" kill-word collapse-space "ESC;space" "ESC;del" backward-kill-word command-repeat-0 "c:u" "ESC;down" down-sexp command-repeat-0 "m:0" "ESC;f" forward-word command-repeat-0 "ESC;0" "ESC;g" goto-line command-repeat-1 "m:1" "ESC;l" downcase-word command-repeat-1 "ESC;1" "ESC;left" backward-sexp command-repeat-2 "m:2" "ESC;o" toggle-overwrite command-repeat-2 "ESC;2" "ESC;p" goto-position command-repeat-3 "m:3" "ESC;return" do-return command-repeat-3 "ESC;3" "ESC;right" forward-sexp command-repeat-4 "m:4" "ESC;s:a:return" do-return command-repeat-4 "ESC;4" "ESC;s:b" backward-select

-word command-repeat-5 "m:5" "ESC;s:c:b" select-backward

-sexp command-repeat-5 "ESC;5" "ESC;s:c:down" select-down-sexp command-repeat-6 "m:6" "ESC;s:c:f" select-forward-sexp command-repeat-6 "ESC;6" "ESC;s:c:n" flash-forward-sexp command-repeat-7 "m:7" "ESC;s:c:return" do-return command-repeat-7 "ESC;7" "ESC;s:c:u" select-up-sexp command-repeat-8 "m:8" "ESC;s:down" select-down-sexp command-repeat-8 "ESC;8" "ESC;s:f" forward-select-word command-repeat-9 "m:9" "ESC;s:l" insert-lambda-template command-repeat-9 "ESC;9" "ESC;s:left" select-backward

-sexp comment-out "m:c:semicolon" "ESC;s:return" do-return comment-out "ESC;c:semicolon" "ESC;s:right" select-forward-sexp copy-clipboard "m:w" "ESC;s:up" select-up-sexp copy-clipboard "ESC;w" "ESC;s:v" select-page-up copy-clipboard "a:c" "ESC;space" collapse-space copy-clipboard "d:c" "ESC;t" transpose-words copy-clipboard "c:insert" "ESC;u" upcase-word cut-clipboard "c:w" "ESC;up" up-sexp cut-clipboard "a:x" "ESC;v" previous-page cut-clipboard "d:x" "ESC;w" copy-clipboard cut-clipboard "s:delete" "ESC;y" paste-next delete-key "del" "ESC;{" insert-{}-pair delete-next-character "c:d" "ESC;|" insert-||-pair delete-previous

-character "c:h" "TAB" tabify-at-caret delete-to-end-of

-line "c:k" "[" rewrite-square-paren do-return "s:return" "]" balance-parens do-return "s:c:return" "a:c" copy-clipboard do-return "a:return" "a:c:down" down-into-embedded

-editor do-return "s:a:return" "a:c:left" back-to-prev-embedded

-editor do-return "c:a:return" "a:c:right" forward-to-next

-embedded-editor do-return "c:s:a:return" "a:c:up" up-out-of-embedded

-editor do-return "c:return" "a:down" next-page do-return "d:return" "a:left" backward-word do-return "m:return" "a:return" do-return do-return "ESC;return" "a:right" forward-word do-return "m:s:return" "a:s:down" select-page-down do-return "ESC;s:return" "a:s:left" backward-select

-word do-return "m:s:c:return" "a:s:right" forward-select-word do-return "ESC;s:c:return" "a:s:up" select-up-sexp do-return "m:a:return" "a:up" previous-page do-return "ESC;a:return" "a:v" paste-clipboard do-return "m:s:a:return" "a:x" cut-clipboard do-return "ESC;s:a:return" "a:z" undo do-return "m:c:a:return" "c:)" non-clever-close

-round-paren do-return "ESC;c:a:return" "c:+" redo do-return "m:c:s:a:return" "c:/" undo do-return "ESC;c:s:a:return" "c:[" non-clever-open

-square-bracket do-return "m:c:return" "c:]" non-clever-close

-square-bracket do-return "ESC;c:return" "c:_" undo do-return "return" "c:a" beginning-of-line down-into-embedded

-editor "m:c:down" "c:a:return" do-return down-into-embedded

-editor "ESC;c:down" "c:b" backward-character down-into-embedded

-editor "a:c:down" "c:c;c:b" remove-parens-forward down-sexp "m:down" "c:c;c:c" check syntax down-sexp "ESC;down" "c:c;c:g" ring-bell downcase-word "m:l" "c:c;c:l" introduce-let-ans downcase-word "ESC;l" "c:c;c:o" move-sexp-out end-of-file "m:>" "c:c;c:r" make-read-only end-of-file "ESC;>" "c:d" delete-next-character end-of-file "d:down" "c:down" next-page end-of-file "c:end" "c:e" end-of-line end-of-line "c:e" "c:end" end-of-file end-of-line "d:right" "c:f" forward-character end-of-line "m:right" "c:f6" toggle-focus-between

-definitions-and

-interactions end-of-line "end" "c:g" hide-search execute "f5" "c:h" delete-previous

-character find-string-again "d:g" "c:home" beginning-of-file flash-backward-sexp "m:c:p" "c:i" toggle-search-focus flash-backward-sexp "ESC;c:p" "c:insert" copy-clipboard flash-forward-sexp "m:s:c:n" "c:k" delete-to-end-of

-line flash-forward-sexp "ESC;s:c:n" "c:l" center-view-on-line forward-character "c:f" "c:left" backward-word forward-character "right" "c:n" next-line forward-select "s:c:f" "c:o" open-line forward-select "s:right" "c:p" previous-line forward-select-word "m:s:f" "c:pagedown" next-tab forward-select-word "ESC;s:f" "c:pageup" prev-tab forward-select-word "a:s:right" "c:r" move-to-search-or

-reverse-search forward-select-word "c:s:right" "c:return" do-return forward-sexp "ESC;right" "c:right" forward-word forward-sexp "m:c:f" "c:s" move-to-search-or

-search forward-sexp "ESC;c:f" "c:s:a:return" do-return forward-to-next

-embedded-editor "m:c:right" "c:s:left" backward-select

-word forward-to-next

-embedded-editor "ESC;c:right" "c:s:right" forward-select-word forward-to-next

-embedded-editor "a:c:right" "c:s:tab" prev-tab forward-word "m:f" "c:space" toggle-anchor forward-word "ESC;f" "c:t" transpose-chars forward-word "a:right" "c:tab" next-tab forward-word "c:right" "c:u" command-repeat-0 goto-line "m:g" "c:up" previous-page goto-line "ESC;g" "c:v" next-page goto-position "m:p" "c:w" cut-clipboard goto-position "ESC;p" "c:x;(" keyboard-macro-start

-record hide-search "c:g" "c:x;)" keyboard-macro-end

-record insert-""-pair "m:"" "c:x;b" jump to binding occurrence insert-""-pair "ESC;"" "c:x;c:f" load-file insert-()-pair "m:(" "c:x;c:g" ring-bell insert-()-pair "ESC;(" "c:x;c:o" collapse-newline insert-[]-pair "m:[" "c:x;c:s" save-file insert-[]-pair "ESC;[" "c:x;c:w" save-file-as insert-lambda-template "m:s:l" "c:x;d" jump to definition (in other file) insert-lambda-template "ESC;s:l" "c:x;e" keyboard-macro-run

-saved insert-{}-pair "m:{" "c:x;n" jump to next bound occurrence insert-{}-pair "ESC;{" "c:x;o" toggle-focus-between

-definitions-and

-interactions insert-||-pair "m:|" "c:x;u" undo insert-||-pair "ESC;|" "c:y" paste-clipboard introduce-let-ans "c:c;c:l" "c:}" non-clever-close

-curley-bracket jump to binding occurrence "c:x;b" "d:c" copy-clipboard jump to definition (in other file) "c:x;d" "d:down" end-of-file jump to next bound occurrence "c:x;n" "d:g" find-string-again keyboard-macro-end

-record "c:x;)" "d:left" beginning-of-line keyboard-macro-run

-saved "c:x;e" "d:return" do-return keyboard-macro-start

-record "c:x;(" "d:right" end-of-line kill-word "m:d" "d:s" save-file kill-word "ESC;d" "d:s:left" prev-tab load-file "c:x;c:f" "d:s:right" next-tab make-read-only "c:c;c:r" "d:up" beginning-of-file mouse-popup-menu ":rightbuttonseq" "d:v" paste-clipboard move-sexp-out "c:c;c:o" "d:x" cut-clipboard move-to-search-or

-reverse-search "c:r" "d:z" undo move-to-search-or

-search "c:s" "del" delete-key next-line "c:n" "down" next-line next-line "down" "end" end-of-line next-page "c:v" "f1" search-help-desk next-page "a:down" "f5" execute next-page "pagedown" "f6" check syntax next-page "c:down" "home" beginning-of-line next-tab "c:tab" "insert" toggle-overwrite next-tab "d:s:right" "left" backward-character next-tab "c:pagedown" "leftbuttondouble" select-click-word non-clever-close

-curley-bracket "c:}" "leftbuttontriple" select-click-line non-clever-close

-round-paren "c:)" "m:"" insert-""-pair non-clever-close

-square-bracket "c:]" "m:(" insert-()-pair non-clever-open

-square-bracket "c:[" "m:0" command-repeat-0 open-line "c:o" "m:1" command-repeat-1 paste-click-region "middlebutton" "m:2" command-repeat-2 paste-clipboard "c:y" "m:3" command-repeat-3 paste-clipboard "a:v" "m:4" command-repeat-4 paste-clipboard "d:v" "m:5" command-repeat-5 paste-clipboard "s:insert" "m:6" command-repeat-6 paste-next "m:y" "m:7" command-repeat-7 paste-next "ESC;y" "m:8" command-repeat-8 prev-tab "c:s:tab" "m:9" command-repeat-9 prev-tab "d:s:left" "m:<" beginning-of-file prev-tab "c:pageup" "m:>" end-of-file previous-line "c:p" "m:[" insert-[]-pair previous-line "up" "m:a:return" do-return previous-page "m:v" "m:b" backward-word previous-page "ESC;v" "m:c" capitalize-word previous-page "a:up" "m:c:=" uncomment previous-page "pageup" "m:c:a:return" do-return previous-page "c:up" "m:c:b" backward-sexp redo "c:+" "m:c:down" down-into-embedded

-editor remove-parens-forward "c:c;c:b" "m:c:f" forward-sexp remove-sexp "m:c:k" "m:c:g" ring-bell remove-sexp "ESC;c:k" "m:c:k" remove-sexp rewrite-square-paren "[" "m:c:left" back-to-prev-embedded

-editor ring-bell "m:c:g" "m:c:p" flash-backward-sexp ring-bell "ESC;c:g" "m:c:return" do-return ring-bell "c:x;c:g" "m:c:right" forward-to-next

-embedded-editor ring-bell "c:c;c:g" "m:c:s:a:return" do-return save-file "c:x;c:s" "m:c:semicolon" comment-out save-file "d:s" "m:c:space" select-forward-sexp save-file-as "c:x;c:w" "m:c:t" transpose-sexp search-help-desk "f1" "m:c:u" up-sexp select-backward

-sexp "m:s:c:b" "m:c:up" up-out-of-embedded

-editor select-backward

-sexp "ESC;s:left" "m:d" kill-word select-backward

-sexp "ESC;s:c:b" "m:del" backward-kill-word select-click-line "leftbuttontriple" "m:down" down-sexp select-click-word "leftbuttondouble" "m:f" forward-word select-down "s:c:n" "m:g" goto-line select-down "s:down" "m:l" downcase-word select-down-sexp "m:s:down" "m:left" beginning-of-line select-down-sexp "ESC;s:down" "m:o" toggle-overwrite select-down-sexp "m:s:c:down" "m:p" goto-position select-down-sexp "ESC;s:c:down" "m:return" do-return select-forward-sexp "ESC;s:right" "m:right" end-of-line select-forward-sexp "m:s:c:f" "m:s:a:return" do-return select-forward-sexp "ESC;s:c:f" "m:s:b" backward-select

-word select-forward-sexp "m:c:space" "m:s:c:b" select-backward

-sexp select-forward-sexp "ESC;c:space" "m:s:c:down" select-down-sexp select-page-down "s:c:v" "m:s:c:f" select-forward-sexp select-page-down "a:s:down" "m:s:c:n" flash-forward-sexp select-page-down "s:pagedown" "m:s:c:return" do-return select-page-down "s:c:down" "m:s:c:u" select-up-sexp select-page-up "m:s:v" "m:s:down" select-down-sexp select-page-up "ESC;s:v" "m:s:f" forward-select-word select-page-up "s:a:up" "m:s:l" insert-lambda-template select-page-up "s:pageup" "m:s:left" select-to-beginning

-of-line select-page-up "s:c:up" "m:s:return" do-return select-to-beginning

-of-file "s:c:home" "m:s:right" select-to-end-of

-line select-to-beginning

-of-file "s:d:up" "m:s:up" select-up-sexp select-to-beginning

-of-line "m:s:left" "m:s:v" select-page-up select-to-beginning

-of-line "s:home" "m:space" collapse-space select-to-beginning

-of-line "s:c:a" "m:t" transpose-words select-to-end-of

-file "s:c:end" "m:u" upcase-word select-to-end-of

-file "s:d:down" "m:up" up-sexp select-to-end-of

-line "m:s:right" "m:v" previous-page select-to-end-of

-line "s:end" "m:w" copy-clipboard select-to-end-of

-line "s:c:e" "m:y" paste-next select-up "s:c:p" "m:{" insert-{}-pair select-up "s:up" "m:|" insert-||-pair select-up-sexp "m:s:up" "middlebutton" paste-click-region select-up-sexp "ESC;s:up" "pagedown" next-page select-up-sexp "a:s:up" "pageup" previous-page select-up-sexp "m:s:c:u" "return" do-return select-up-sexp "ESC;s:c:u" "right" forward-character tabify-at-caret "TAB" "s:a:return" do-return toggle-anchor "c:space" "s:a:up" select-page-up toggle-focus-between

-definitions-and

-interactions "c:x;o" "s:c:a" select-to-beginning

-of-line toggle-focus-between

-definitions-and

-interactions "c:f6" "s:c:b" backward-select toggle-overwrite "m:o" "s:c:down" select-page-down toggle-overwrite "ESC;o" "s:c:e" select-to-end-of

-line toggle-overwrite "insert" "s:c:end" select-to-end-of

-file toggle-search-focus "c:i" "s:c:f" forward-select transpose-chars "c:t" "s:c:home" select-to-beginning

-of-file transpose-sexp "m:c:t" "s:c:n" select-down transpose-sexp "ESC;c:t" "s:c:p" select-up transpose-words "m:t" "s:c:return" do-return transpose-words "ESC;t" "s:c:up" select-page-up uncomment "m:c:=" "s:c:v" select-page-down uncomment "ESC;c:=" "s:d:down" select-to-end-of

-file undo "c:_" "s:d:up" select-to-beginning

-of-file undo "c:/" "s:delete" cut-clipboard undo "\u001f" "s:down" select-down undo "a:z" "s:end" select-to-end-of

-line undo "d:z" "s:home" select-to-beginning

-of-line undo "c:x;u" "s:insert" paste-clipboard up-out-of-embedded

-editor "m:c:up" "s:left" backward-select up-out-of-embedded

-editor "ESC;c:up" "s:pagedown" select-page-down up-out-of-embedded

-editor "a:c:up" "s:pageup" select-page-up up-sexp "m:up" "s:return" do-return up-sexp "ESC;up" "s:right" forward-select up-sexp "m:c:u" "s:up" select-up up-sexp "ESC;c:u" "up" previous-line upcase-word "m:u" "}" balance-parens upcase-word "ESC;u"

The following tables are meant to help you in making decisions about what shortcuts you might want to create. I've arranged them first by platform specificity and followed up with tables of easy sequences to type and then the akward sequences, either because they take your hand off the home row, or they involve more than one modifier key and finally those that involve a sequence of keystrokes. You'll find that some sequences will inevitably be in more than one table, as they qualify under several catagories. If your like me you'll find it ineresting what choices were made to accomadate such a diverse audience as are the consumers of PLT software.

Unicode Character - Control - Unit Separator:

its control effect is to make following text underlined.

"\u001f" undo

Platform Neutrual Keyboard Commands:

avaialable on all platforms.

"ESC;c:=" uncomment "ESC;c:b" backward-sexp "ESC;c:down" down-into-embedded-editor "ESC;c:f" forward-sexp "ESC;c:g" ring-bell "ESC;c:k" remove-sexp "ESC;c:left" back-to-prev-embedded-editor "ESC;c:p" flash-backward-sexp "ESC;c:return" do-return "ESC;c:right" forward-to-next-embedded-editor "ESC;c:semicolon" comment-out "ESC;c:space" select-forward-sexp "ESC;c:t" transpose-sexp "ESC;c:u" up-sexp "ESC;c:up" up-out-of-embedded-editor "c:)" non-clever-close-round-paren "c:+" redo "c:/" undo "c:[" non-clever-open-square-bracket "c:]" non-clever-close-square-bracket "c:_" undo "c:a" beginning-of-line "c:b" backward-character "c:d" delete-next-character "c:down" next-page "c:e" end-of-line "c:end" end-of-file "c:f" forward-character "c:f6" toggle-focus-between-definitions-and-interactions "c:g" hide-search "c:h" delete-previous-character "c:home" beginning-of-file "c:i" toggle-search-focus "c:insert" copy-clipboard "c:k" delete-to-end-of-line "c:l" center-view-on-line "c:left" backward-word "c:n" next-line "c:o" open-line "c:p" previous-line "c:pagedown" next-tab "c:pageup" prev-tab "c:r" move-to-search-or-reverse-search "c:return" do-return "c:right" forward-word "c:s" move-to-search-or-search "c:space" toggle-anchor "c:t" transpose-chars "c:tab" next-tab "c:u" command-repeat-0 "c:up" previous-page "c:v" next-page "c:w" cut-clipboard "c:x;(" keyboard-macro-start-record "c:x;)" keyboard-macro-end-record "c:x;b" jump to binding occurrence "c:x;d" jump to definition (in other file) "c:x;e" keyboard-macro-run-saved "c:x;n" jump to next bound occurrence "c:x;o" toggle-focus-between-definitions-and-interactions "c:x;u" undo "c:y" paste-clipboard "c:}" non-clever-close-curley-bracket

Platform Neutral Mouse Shortcuts

available on any platform with a mouse, but note `paste-click-region' requires a three-button mouse.

":rightbuttonseq" mouse-popup-menu "leftbuttondouble" select-click-word "leftbuttontriple" select-click-line "middlebutton" paste-click-region

Mac Specific Shortcuts:

using the `option' key modifier -

from my experience on a Mac Pro running OS X Server v10.4.9, thankfully the a:c, a:v, a:x and a:z shortcuts aren't active, and the option key's function to provide an extended character set to your keyboard takes precedence. It is interesting to note the sequences involving both the meta and option key; as far as I know these are impossible combinations on any keyboard of which I'm familiar. Also, there seems to be an effort to capture all possible bindings of the return key, perhaps to prevent anyone from binding any modifier enhanced sequence to the return key.

"ESC;a:return" do-return "ESC;c:a:return" do-return "ESC;c:s:a:return" do-return "ESC;s:a:return" do-return "a:c" copy-clipboard "a:c:down" down-into-embedded-editor "a:c:left" back-to-prev-embedded-editor "a:c:right" forward-to-next-embedded-editor "a:c:up" up-out-of-embedded-editor "a:down" next-page "a:left" backward-word "a:return" do-return "a:right" forward-word "a:s:down" select-page-down "a:s:left" backward-select-word "a:s:right" forward-select-word "a:s:up" select-up-sexp "a:up" previous-page "a:v" paste-clipboard "a:x" cut-clipboard "a:z" undo "c:a:return" do-return "c:s:a:return" do-return "m:a:return" do-return "m:c:a:return" do-return "m:c:s:a:return" do-return "m:s:a:return" do-return "s:a:return" do-return "s:a:up" select-page-up

Mac Specific Shortcuts:

using the `command' modifier

"d:c" copy-clipboard "d:down" end-of-file "d:g" find-string-again "d:left" beginning-of-line "d:return" do-return "d:right" end-of-line "d:s" save-file "d:s:left" prev-tab "d:s:right" next-tab "d:up" beginning-of-file "d:v" paste-clipboard "d:x" cut-clipboard "d:z" undo "s:d:down" select-to-end-of-file "s:d:up" select-to-beginning-of-file

*nix and Windows Specific Shortcuts:

using the `meta' key modifier on *nix or `Alt' key modifier on Windows -

also available on OS X by giving up the function of your option key.

"m:"" insert-""-pair "m:(" insert-()-pair "m:0" command-repeat-0 "m:1" command-repeat-1 "m:2" command-repeat-2 "m:3" command-repeat-3 "m:4" command-repeat-4 "m:5" command-repeat-5 "m:6" command-repeat-6 "m:7" command-repeat-7 "m:8" command-repeat-8 "m:9" command-repeat-9 "m:<" beginning-of-file "m:>" end-of-file "m:[" insert-[]-pair "m:a:return" do-return "m:b" backward-word "m:c" capitalize-word "m:c:=" uncomment "m:c:a:return" do-return "m:c:b" backward-sexp "m:c:down" down-into-embedded-editor "m:c:f" forward-sexp "m:c:g" ring-bell "m:c:k" remove-sexp "m:c:left" back-to-prev-embedded-editor "m:c:p" flash-backward-sexp "m:c:return" do-return "m:c:right" forward-to-next-embedded-editor "m:c:s:a:return" do-return "m:c:semicolon" comment-out "m:c:space" select-forward-sexp "m:c:t" transpose-sexp "m:c:u" up-sexp "m:c:up" up-out-of-embedded-editor "m:d" kill-word "m:del" backward-kill-word "m:down" down-sexp "m:f" forward-word "m:g" goto-line "m:l" downcase-word "m:left" beginning-of-line "m:o" toggle-overwrite "m:p" goto-position "m:return" do-return "m:right" end-of-line "m:s:a:return" do-return "m:s:b" backward-select-word "m:s:c:b" select-backward-sexp "m:s:c:down" select-down-sexp "m:s:c:f" select-forward-sexp "m:s:c:n" flash-forward-sexp "m:s:c:return" do-return "m:s:c:u" select-up-sexp "m:s:down" select-down-sexp "m:s:f" forward-select-word "m:s:l" insert-lambda-template "m:s:left" select-to-beginning-of-line "m:s:return" do-return "m:s:right" select-to-end-of-line "m:s:up" select-up-sexp "m:s:v" select-page-up "m:space" collapse-space "m:t" transpose-words "m:u" upcase-word "m:up" up-sexp "m:v" previous-page "m:w" copy-clipboard "m:y" paste-next "m:{" insert-{}-pair "m:|" insert-||-pair

Easy to Type Shortcuts

")" balance-parens "TAB" tabify-at-caret "[" rewrite-square-paren "]" balance-parens "a:c" copy-clipboard "a:v" paste-clipboard "a:x" cut-clipboard "a:z" undo "c:)" non-clever-close-round-paren "c:+" redo "c:/" undo "c:[" non-clever-open-square-bracket "c:]" non-clever-close-square-bracket "c:_" undo "c:a" beginning-of-line "c:b" backward-character "c:d" delete-next-character "c:e" end-of-line "c:f" forward-character "c:f6" toggle-focus-between-definitions-and-interactions "c:g" hide-search "c:h" delete-previous-character "c:i" toggle-search-focus "c:k" delete-to-end-of-line "c:l" center-view-on-line "c:n" next-line "c:o" open-line "c:p" previous-line "c:r" move-to-search-or-reverse-search "c:return" do-return "c:s" move-to-search-or-search "c:space" toggle-anchor "c:t" transpose-chars "c:tab" next-tab "c:u" command-repeat-0 "c:v" next-page "c:w" cut-clipboard "c:y" paste-clipboard "d:c" copy-clipboard "d:g" find-string-again "d:return" do-return "d:s" save-file "d:v" paste-clipboard "d:x" cut-clipboard "d:z" undo "f1" search-help-desk "f5" execute "f6" check syntax "m:"" insert-""-pair "m:(" insert-()-pair "m:0" command-repeat-0 "m:1" command-repeat-1 "m:2" command-repeat-2 "m:3" command-repeat-3 "m:4" command-repeat-4 "m:5" command-repeat-5 "m:6" command-repeat-6 "m:7" command-repeat-7 "m:8" command-repeat-8 "m:9" command-repeat-9 "m:<" beginning-of-file "m:>" end-of-file "m:[" insert-[]-pair "m:b" backward-word "m:c" capitalize-word "m:d" kill-word "m:f" forward-word "m:g" goto-line "m:l" downcase-word "m:o" toggle-overwrite "m:p" goto-position "m:space" collapse-space "m:t" transpose-words "m:u" upcase-word "m:v" previous-page "m:w" copy-clipboard "m:y" paste-next "m:{" insert-{}-pair "m:|" insert-||-pair "return" do-return "}" balance-parens

Shortcuts That Take a Hand Off Home Row

":rightbuttonseq" mouse-popup-menu "ESC;c:down" down-into-embedded-editor "ESC;c:left" back-to-prev-embedded-editor "ESC;c:right" forward-to-next-embedded-editor "ESC;c:up" up-out-of-embedded-editor "ESC;del" backward-kill-word "ESC;down" down-sexp "ESC;left" backward-sexp "ESC;right" forward-sexp "ESC;s:c:down" select-down-sexp "ESC;s:down" select-down-sexp "ESC;s:left" select-backward-sexp "ESC;s:right" select-forward-sexp "ESC;s:up" select-up-sexp "ESC;up" up-sexp "a:c:down" down-into-embedded-editor "a:c:left" back-to-prev-embedded-editor "a:c:right" forward-to-next-embedded-editor "a:c:up" up-out-of-embedded-editor "a:down" next-page "a:left" backward-word "a:right" forward-word "a:s:down" select-page-down "a:s:left" backward-select-word "a:s:right" forward-select-word "a:s:up" select-up-sexp "a:up" previous-page "c:down" next-page "c:end" end-of-file "c:home" beginning-of-file "c:insert" copy-clipboard "c:left" backward-word "c:pagedown" next-tab "c:pageup" prev-tab "c:right" forward-word "c:s:left" backward-select-word "c:s:right" forward-select-word "c:up" previous-page "d:down" end-of-file "d:left" beginning-of-line "d:right" end-of-line "d:s:left" prev-tab "d:s:right" next-tab "d:up" beginning-of-file "del" delete-key "down" next-line "end" end-of-line "home" beginning-of-line "insert" toggle-overwrite "left" backward-character "leftbuttondouble" select-click-word "leftbuttontriple" select-click-line "m:c:down" down-into-embedded-editor "m:c:left" back-to-prev-embedded-editor "m:c:right" forward-to-next-embedded-editor "m:c:up" up-out-of-embedded-editor "m:del" backward-kill-word "m:down" down-sexp "m:left" beginning-of-line "m:right" end-of-line "m:s:c:down" select-down-sexp "m:s:down" select-down-sexp "m:s:left" select-to-beginning-of-line "m:s:right" select-to-end-of-line "m:s:up" select-up-sexp "m:up" up-sexp "middlebutton" paste-click-region "pagedown" next-page "pageup" previous-page "right" forward-character "s:a:up" select-page-up "s:c:down" select-page-down "s:c:end" select-to-end-of-file "s:c:home" select-to-beginning-of-file "s:c:up" select-page-up "s:d:down" select-to-end-of-file "s:d:up" select-to-beginning-of-file "s:delete" cut-clipboard "s:down" select-down "s:end" select-to-end-of-line "s:home" select-to-beginning-of-line "s:insert" paste-clipboard "s:left" backward-select "s:pagedown" select-page-down "s:pageup" select-page-up "s:right" forward-select "s:up" select-up "up" previous-line

Single Chorded Shortcuts With More Than One Modifier

"a:c:down" down-into-embedded-editor "a:c:left" back-to-prev-embedded-editor "a:c:right" forward-to-next-embedded-editor "a:c:up" up-out-of-embedded-editor "a:s:down" select-page-down "a:s:left" backward-select-word "a:s:right" forward-select-word "a:s:up" select-up-sexp "c:a:return" do-return "c:s:a:return" do-return "c:s:left" backward-select-word "c:s:right" forward-select-word "c:s:tab" prev-tab "d:s:left" prev-tab "d:s:right" next-tab "m:a:return" do-return "m:c:=" uncomment "m:c:a:return" do-return "m:c:b" backward-sexp "m:c:down" down-into-embedded-editor "m:c:f" forward-sexp "m:c:g" ring-bell "m:c:k" remove-sexp "m:c:left" back-to-prev-embedded-editor "m:c:p" flash-backward-sexp "m:c:return" do-return "m:c:right" forward-to-next-embedded-editor "m:c:s:a:return" do-return "m:c:semicolon" comment-out "m:c:space" select-forward-sexp "m:c:t" transpose-sexp "m:c:u" up-sexp "m:c:up" up-out-of-embedded-editor "m:s:a:return" do-return "m:s:b" backward-select-word "m:s:c:b" select-backward-sexp "m:s:c:down" select-down-sexp "m:s:c:f" select-forward-sexp "m:s:c:n" flash-forward-sexp "m:s:c:return" do-return "m:s:c:u" select-up-sexp "m:s:down" select-down-sexp "m:s:f" forward-select-word "m:s:l" insert-lambda-template "m:s:left" select-to-beginning-of-line "m:s:return" do-return "m:s:right" select-to-end-of-line "m:s:up" select-up-sexp "m:s:v" select-page-up "s:a:return" do-return "s:a:up" select-page-up "s:c:a" select-to-beginning-of-line "s:c:b" backward-select "s:c:down" select-page-down "s:c:e" select-to-end-of-line "s:c:end" select-to-end-of-file "s:c:f" forward-select "s:c:home" select-to-beginning-of-file "s:c:n" select-down "s:c:p" select-up "s:c:return" do-return "s:c:up" select-page-up "s:c:v" select-page-down "s:d:down" select-to-end-of-file "s:d:up" select-to-beginning-of-file

Shortcuts That Require a Sequence of Keys

"ESC;"" insert-""-pair "ESC;(" insert-()-pair "ESC;0" command-repeat-0 "ESC;1" command-repeat-1 "ESC;2" command-repeat-2 "ESC;3" command-repeat-3 "ESC;4" command-repeat-4 "ESC;5" command-repeat-5 "ESC;6" command-repeat-6 "ESC;7" command-repeat-7 "ESC;8" command-repeat-8 "ESC;9" command-repeat-9 "ESC;<" beginning-of-file "ESC;>" end-of-file "ESC;[" insert-[]-pair "ESC;a:return" do-return "ESC;b" backward-word "ESC;c" capitalize-word "ESC;c:=" uncomment "ESC;c:a:return" do-return "ESC;c:b" backward-sexp "ESC;c:down" down-into-embedded-editor "ESC;c:f" forward-sexp "ESC;c:g" ring-bell "ESC;c:k" remove-sexp "ESC;c:left" back-to-prev-embedded-editor "ESC;c:p" flash-backward-sexp "ESC;c:return" do-return "ESC;c:right" forward-to-next-embedded-editor "ESC;c:s:a:return" do-return "ESC;c:semicolon" comment-out "ESC;c:space" select-forward-sexp "ESC;c:t" transpose-sexp "ESC;c:u" up-sexp "ESC;c:up" up-out-of-embedded-editor "ESC;d" kill-word "ESC;del" backward-kill-word "ESC;down" down-sexp "ESC;f" forward-word "ESC;g" goto-line "ESC;l" downcase-word "ESC;left" backward-sexp "ESC;o" toggle-overwrite "ESC;p" goto-position "ESC;return" do-return "ESC;right" forward-sexp "ESC;s:a:return" do-return "ESC;s:b" backward-select-word "ESC;s:c:b" select-backward-sexp "ESC;s:c:down" select-down-sexp "ESC;s:c:f" select-forward-sexp "ESC;s:c:n" flash-forward-sexp "ESC;s:c:return" do-return "ESC;s:c:u" select-up-sexp "ESC;s:down" select-down-sexp "ESC;s:f" forward-select-word "ESC;s:l" insert-lambda-template "ESC;s:left" select-backward-sexp "ESC;s:return" do-return "ESC;s:right" select-forward-sexp "ESC;s:up" select-up-sexp "ESC;s:v" select-page-up "ESC;space" collapse-space "ESC;t" transpose-words "ESC;u" upcase-word "ESC;up" up-sexp "ESC;v" previous-page "ESC;w" copy-clipboard "ESC;y" paste-next "ESC;{" insert-{}-pair "ESC;|" insert-||-pair "c:c;c:b" remove-parens-forward "c:c;c:c" check syntax "c:c;c:g" ring-bell "c:c;c:l" introduce-let-ans "c:c;c:o" move-sexp-out "c:c;c:r" make-read-only "c:x;(" keyboard-macro-start-record "c:x;)" keyboard-macro-end-record "c:x;b" jump to binding occurrence "c:x;c:f" load-file "c:x;c:g" ring-bell "c:x;c:o" collapse-newline "c:x;c:s" save-file "c:x;c:w" save-file-as "c:x;d" jump to definition (in other file) "c:x;e" keyboard-macro-run-saved "c:x;n" jump to next bound occurrence "c:x;o" toggle-focus-between-definitions-and-interactions "c:x;u" undo

You should be aware that these tables were built from the output as produced on a Mac Pro; it is entirely possible that they would give somewhat different output depending on the platform you have DrScheme installed on. Use these tables as a guide, and when you want to make a binding change, double check your own Active Keybinding dialog to make certain that the keys your are binding to are either free or the ones you had decided to override. Finally, the Active Keybinding dialog will show many bindings to menu shortcuts, but the name that is used to describe it is clearly not a valid Scheme identifier, rather it is a description of the menu item's function. If you really want to bind to one of these functions, you'll need the assistance of someone from the PLT team. I had hoped to be able to programatically provide a list of these functions for you, but the code that manipulates these bindings is inside a private function within the code that defines one of the frameworks most basic interface, and there was no clear way for me to access it without hacking into DrScheme.

Now to wrap it all up, I've put an abridged version of my own keybinding module below. However, the two different forms in which you will likely be calling your target functions. The first form is when you simply write your own lambda function of two arguments, an editor<%> object and an event<%> object. You'll likely have little use for the event<%> object, as you know what triggered the call to your function, however, if you had need of the exact time that the event had taken place, you can query the event to get that information. The editor<%> object, on the other hand, is your only link to DrScheme. You can call any public method on the editor you so desire. I've given some simple examples of inserting a string-snip<%> object. But, truely, your imagination is the only limit on what you can do with your custom keybinding and a live editor at your command.

The second form is the method you need to use to execute any of the named functions from the editor's keymap. You send the editor's keymap the call-function method with the name of the function as a string argument. These are the functions listed in the tables. I encourage you to read the documentation regarding the editor<%> class. You're bound to come up with some inovative ways of doing things you never dreamed of before.

As always, it's been a pleasure bringing you this article. I hope you have learned something new. Either way, please leave a comment about your impression of the topic, how it was covered, how it could be improved or anything else you have on your mind.

( module schemekeys-keymap ( lib "keybinding-lang.ss" "framework" ) ( require ( lib "tool-lib.ss" "drscheme" )) ( define ( sendsnip e s ) ( let ([ snip ( make-object string-snip% s )]) ( send snip set-flags '( hard-newline )) ( send e insert snip ( string-length s ) 0 ))) ( keybinding ":d:semicolon" ( lambda ( editor event ) ( preferences:show-dialog ))) ( keybinding ":c:1" ( lambda ( editor event ) ( sendsnip editor "(module <name> \"../schemekeys/schemekeys.ss\"" ))) ( keybinding ":c:5" ( lambda ( editor event ) ( sendsnip editor "(fold (λ (x rest) (if (<pred>? x) (cons x rest) rest)) () <list>)" ))) ( keybinding ":f2" ( lambda ( editor event ) ( send ( send editor get-keymap ) call-function "toggle-focus-between-definitions-and-interactions" editor event #t ))) ( keybinding ":c:8" ( lambda ( editor event ) ( send ( send editor get-keymap ) call-function "keyboard-macro-start-record" editor event #t ))) ( keybinding ":c:9" ( lambda ( editor event ) ( send ( send editor get-keymap ) call-function "keyboard-macro-end-record" editor event #t ))) ( keybinding ":c:0" ( lambda ( editor event ) ( send ( send editor get-keymap ) call-function "keyboard-macro-run-saved" editor event #t ))) ( keybinding ":d:]" ( lambda ( editor event ) ( send ( send editor get-keymap ) call-function "comment-out" editor event #t ))) ( keybinding ":d:[" ( lambda ( editor event ) ( send ( send editor get-keymap ) call-function "uncomment" editor event #t )))

Enjoy!



--kyle