On this page:
3.3.1 Moving Around
3.3.2 Editing Operations
3.3.3 File Operations
3.3.4 Search
3.3.5 Evaluation
3.3.6 Interactions
3.3.7 La Te X and Te X inspired keybindings
3.3.8 Defining Custom Shortcuts
3.3.9 Sending Program Fragments to the REPL

3.3 Keyboard Shortcuts

Most key presses simply insert a character into the editor, such as a, 3, or (. Other keys and key combinations act as keyboard shortcuts that move the blinking caret, delete a line, copy the selection, etc. Keyboard shortcuts are usually trigger by key combinations using the Control, Meta, or Command key.

Many of the key-binding actions can also be performed with menu items.

C-‹key› means press the Control key, hold it down and then press ‹key› and then release them both. For example: C-e (Control-E) moves the blinking caret to the end of the current line.

M-‹key› is the same as C-‹key›, except with the Meta key. Depending on your keyboard, Meta may be called “Left,” “Right,” or have a diamond symbol, but it’s usually on the bottom row next to the space bar. M-‹key› can also be performed as a two-character sequence: first, strike and release the Escape key, then strike ‹key›. On Windows and Mac OS X, Meta is only available through the Escape key.

DEL is the Delete key.

SPACE is the Space bar.

On most keyboards, “<” and “>” are shifted characters. So, to get M->, you actually have to type Meta-Shift->. That is, press and hold down both the Meta and Shift keys, and then strike “>”.

On Windows, some of these keybindings are actually standard menu items. Those keybindings will behave according to the menus, unless the Enable keybindings in menus preference is unchecked.

If you are most familiar with Emacs-style key bindings (especially on windows or some linux installations where the control key is, by default, for the menu shortcuts), you should uncheck the Enable keybindings in menus preference. Many of the keybindings below are inspired by Emacs.

3.3.1 Moving Around
3.3.2 Editing Operations
3.3.3 File Operations
3.3.4 Search
3.3.5 Evaluation
3.3.6 Interactions

The interactions window has all of the same keyboard shortcuts as the definitions window plus a few more:

3.3.7 LaTeX and TeX inspired keybindings
3.3.8 Defining Custom Shortcuts

The Add User-defined Keybindings... menu item in the Keybindings sub-menu of Edit selects a file containing Racket definitions of keybindings. The file must contain a module that uses a special keybindings language, framework/keybinding-lang. To do so, begin your file with this line:

#lang s-exp framework/keybinding-lang

The framework/keybinding-lang languages provides all of the bindings from racket, racket/class, and drracket/tool-lib, except that it adjusts #%module-begin to introduce a keybinding form:

(keybinding string-expr proc-expr)

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

For example, this remaps the key combination “control-a” key to “!”.

#lang s-exp framework/keybinding-lang
(keybinding "c:a" (λ (editor evt) (send editor insert "!")))

Since the file contains plain Racket code, you can write keybindings files that use DrRacket’s Extension API. For example, the following file binds “control-t” and “control-=” to a execute the program and open a new tab respectively, as they were used before version 5.2.

#lang s-exp framework/keybinding-lang
 
(define modifiers
  (apply string-append
         (map (λ (p)
                (case p
                  [(ctl) "c:"] [(cmd) "d:"] [(alt meta) "m:"]
                  [(shift) "s:"] [(option) "a:"]))
              (get-default-shortcut-prefix))))
 
(define-syntax-rule (frame-key key command)
  (keybinding
   (string-append modifiers key)
   (λ (ed evt)
     (when (is-a? ed text:basic<%>)
       (define fr (send ed get-top-level-window))
 
       (when fr (send fr command))))))
 
(frame-key "t" execute-callback)
(frame-key "=" create-new-tab)

Another example, this file rebinds “control-w” to delete the word behind the insertion point, but it does it by setting a new key to be an existing keyboard shortcut. If you see a key in the Show Active Keybindings dialog (in the Keybindings submenu of the Edit menu), then you can use its name with the new keystroke you want, like this:

#lang s-exp framework/keybinding-lang
 
(define (rebind key command)
  (keybinding
   key
   (λ (ed evt)
     (send (send ed get-keymap) call-function command ed evt #t))))
 
(rebind "c:w" "backward-kill-word")

Note that DrRacket does not reload keybindings files automatically when you make changes, so you’ll need to restart DrRacket to see changes to the file.

3.3.9 Sending Program Fragments to the REPL

Users comfortable with Emacs and the conventional Lisp/Scheme-style of interaction with an “inferior process” commonly request keybindings in DrRacket that send program fragments to be evaluated at the prompt. This style of interaction is fraught with difficulty, especially for beginners, and so DrRacket, by default, does not support it. Instead, clicking DrRacket’s “Run” button starts with a clean slate and sends the entire contents of the definitions window, ensuring that the state in the REPL matches what you would expect by reading the source code of the program.

Based on years of experience with Emacs modes, some of the authors consider this mode of interaction also appropriate for experienced programmers. Indeed, they go through great effort to mimic this behavior in Emacs.

That said, some people may wish to use such incremental keystroke modes anyway. Therefore the remainder of this section illustrates how to add such an incremental mode for your personal use with an example keybindings file. Specifically, the file shows how to add the ability to send expressions piecemeal to the interactions window. It also demonstrates how to pull together a bunch of pieces of DrRacket’s implementation and its libraries to implement keystrokes.

#lang s-exp framework/keybinding-lang
 
(require drracket/tool-lib)
 
(keybinding "c:c;c:e" (lambda (ed evt) (send-toplevel-form ed #f)))
(keybinding "c:c;c:r" (lambda (ed evt) (send-selection ed #f)))
(keybinding "c:c;m:e" (lambda (ed evt) (send-toplevel-form ed #t)))
(keybinding "c:c;m:r" (lambda (ed evt) (send-selection ed #t)))
 
(define/contract (send-toplevel-form defs shift-focus?)
  (-> any/c boolean? any)
  (when (is-a? defs drracket:unit:definitions-text<%>)
    (when (= (send defs get-start-position)
             (send defs get-end-position))
      (let loop ([pos (send defs get-start-position)])
        (define next-up (send defs find-up-sexp pos)) 
        (cond
          [next-up (loop next-up)]
          [else
           (send-range-to-repl defs 
                               pos
                               (send defs get-forward-sexp pos)
                               shift-focus?)])))))
 
(define/contract (send-selection defs shift-focus?)
  (-> any/c boolean? any)
  (when (is-a? defs drracket:unit:definitions-text<%>)
    (send-range-to-repl defs
                        (send defs get-start-position) 
                        (send defs get-end-position) 
                        shift-focus?)))
 
(define/contract (send-range-to-repl defs start end shift-focus?)
  (-> (is-a?/c drracket:unit:definitions-text<%>)
      exact-positive-integer?
      exact-positive-integer?
      boolean?
      any)
  (unless (= start end)
    (define ints (send (send defs get-tab) get-ints))
    (define frame (send (send defs get-tab) get-frame))
    (send defs move/copy-to-edit 
          ints start end
          (send ints last-position)
          #:try-to-move? #f)
 
    (let loop ()
      (define last-pos (- (send ints last-position) 1))
      (when (last-pos . > . 0)
        (define last-char (send ints get-character last-pos))
        (when (char-whitespace? last-char)
          (send ints delete last-pos (+ last-pos 1))
          (loop))))
    (send ints insert
          "\n"
          (send ints last-position)
          (send ints last-position))
    
    (send frame ensure-rep-shown ints)
    (when shift-focus? (send (send ints get-canvas) focus))
    (send ints do-submission)))
 

Others may wish to use the above example to invent other keystrokes for making work in DrRacket convenient.