From b1a360be9d5c0bbb8fd7390b8c43e3c54136fda3 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 22 Sep 2011 10:47:08 -0500 Subject: [PATCH] Add the following keybindings in a (hopefully) transparent REPL-friendly way: esc;c:x send-toplevel-form-to-repl m:c:x send-toplevel-form-to-repl c:c;c:e send-toplevel-form-to-repl c:c;c:r send-selection-to-repl c:c;m:e send-toplevel-form-to-repl-and-go c:c;m:r send-selection-to-repl-and-go c:c;c:z move-to-interactions Took the inspiration for the list from the keybindings available in Scheme mode in Emacs. Closes PR 12211 (and probably others) --- collects/drracket/private/rep.rkt | 24 ++++++++-- collects/drracket/private/unit.rkt | 48 +++++++++++++++++-- .../scribblings/drracket/keybindings.scrbl | 22 +++++++-- 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/collects/drracket/private/rep.rkt b/collects/drracket/private/rep.rkt index 8283951268..718056a6c5 100644 --- a/collects/drracket/private/rep.rkt +++ b/collects/drracket/private/rep.rkt @@ -247,7 +247,8 @@ TODO [name (and l (send l get-language-name))]) (drracket:help-desk:help-desk str (and ctxt (list ctxt name))))))))) - (add-drs-function "execute" (λ (frame) (send frame execute-callback))) + (add-drs-function "execute" (λ (frame) (send frame execute-callback))) ;; keep this in case people use it in their keymaps + (add-drs-function "run" (λ (frame) (send frame execute-callback))) (add-drs-function "next-tab" (λ (frame) (send frame next-tab))) (add-drs-function "prev-tab" (λ (frame) (send frame prev-tab))) (add-drs-function "collapse" (λ (frame) (send frame collapse))) @@ -256,7 +257,13 @@ TODO (add-drs-function "jump-to-previous-error-loc" (λ (frame) (send frame jump-to-previous-error-loc))) (add-drs-function "jump-to-next-error-loc" - (λ (frame) (send frame jump-to-next-error-loc)))) + (λ (frame) (send frame jump-to-next-error-loc))) + + (add-drs-function "send-toplevel-form-to-repl" (λ (frame) (send frame send-toplevel-form-to-repl #f))) + (add-drs-function "send-selection-to-repl" (λ (frame) (send frame send-selection-to-repl #f))) + (add-drs-function "send-toplevel-form-to-repl-and-go" (λ (frame) (send frame send-toplevel-form-to-repl #t))) + (add-drs-function "send-selection-to-repl-and-go" (λ (frame) (send frame send-selection-to-repl #t))) + (add-drs-function "move-to-interactions" (λ (frame) (send frame move-to-interactions)))) (send drs-bindings-keymap map-function "m:p" "jump-to-previous-error-loc") (send drs-bindings-keymap map-function "m:n" "jump-to-next-error-loc") @@ -264,7 +271,7 @@ TODO (send drs-bindings-keymap map-function "esc;n" "jump-to-next-error-loc") (send drs-bindings-keymap map-function "c:x;`" "jump-to-next-error-loc") - (send drs-bindings-keymap map-function "f5" "execute") + (send drs-bindings-keymap map-function "f5" "run") (send drs-bindings-keymap map-function "f1" "search-help-desk") (send drs-bindings-keymap map-function "c:tab" "next-tab") (send drs-bindings-keymap map-function "c:s:tab" "prev-tab") @@ -274,6 +281,15 @@ TODO (send drs-bindings-keymap map-function "c:x;0" "collapse") (send drs-bindings-keymap map-function "c:x;2" "split") + (send drs-bindings-keymap map-function "esc;c:x" "send-toplevel-form-to-repl") + (send drs-bindings-keymap map-function "m:c:x" "send-toplevel-form-to-repl") + (send drs-bindings-keymap map-function "c:c;c:e" "send-toplevel-form-to-repl") + (send drs-bindings-keymap map-function "c:c;c:r" "send-selection-to-repl") + (send drs-bindings-keymap map-function "c:c;m:e" "send-toplevel-form-to-repl-and-go") + (send drs-bindings-keymap map-function "c:c;m:r" "send-selection-to-repl-and-go") + + (send drs-bindings-keymap map-function "c:c;c:z" "move-to-interactions") + (for ([i (in-range 1 10)]) (send drs-bindings-keymap map-function (format "a:~a" i) @@ -1144,7 +1160,7 @@ TODO (define/private shutdown-user-custodian ; =Kernel=, =Handler= ; Use this procedure to shutdown when in the middle of other cleanup - ; operations, such as when the user clicks "Execute". + ; operations, such as when the user clicks "Run". ; Don't use it to kill a thread where other, external cleanup ; actions must occur (e.g., the exit handler for the user's ; thread). In that case, shut down user-custodian directly. diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index bffebbbaa3..3199fe300f 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -4012,6 +4012,49 @@ module browser threading seems wrong. (define ed (srcloc-source srcloc)) (send ed set-position (- (srcloc-position srcloc) 1)) (send ed set-caret-owner #f 'global)) + + + (define/public (send-toplevel-form-to-repl shift-focus?) + (define defs (get-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 pos + (send defs get-forward-sexp pos) + shift-focus?)])))) + (define/public (send-selection-to-repl shift-focus?) + (define defs (get-definitions-text)) + (send-range-to-repl (send defs get-start-position) (send defs get-end-position) shift-focus?)) + (define/public (move-to-interactions) + (ensure-rep-shown (get-interactions-text)) + (send (get-interactions-canvas) focus)) + + (define/private (send-range-to-repl start end shift-focus?) + (unless (= start end) + (define defs (get-definitions-text)) + (define ints (get-interactions-text)) + (send defs move/copy-to-edit ints start end (send ints last-position) #:try-to-move? #f) + + + ;; clear out the whitespace after the copied down thing + (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)))) + + ;; insert a newline + (send ints insert "\n" (send ints last-position) (send ints last-position)) + + (ensure-rep-shown ints) + (when shift-focus? (send (get-interactions-canvas) focus)) + (send ints do-submission))) ; @@ -4131,9 +4174,8 @@ module browser threading seems wrong. interactions-canvases null)) - (public get-definitions-canvas get-interactions-canvas) - [define get-definitions-canvas (λ () definitions-canvas)] - [define get-interactions-canvas (λ () interactions-canvas)] + (define/public (get-definitions-canvas) definitions-canvas) + (define/public (get-interactions-canvas) interactions-canvas) (set! save-button (new switchable-button% diff --git a/collects/scribblings/drracket/keybindings.scrbl b/collects/scribblings/drracket/keybindings.scrbl index 29e0c2b8da..86f4918fa4 100644 --- a/collects/scribblings/drracket/keybindings.scrbl +++ b/collects/scribblings/drracket/keybindings.scrbl @@ -51,10 +51,11 @@ items. Those keybindings will behave according to the menus, unless the @onscreen{Enable keybindings in menus} preference is unchecked. @index['("Emacs keybindings")]{If} you are most familiar with -Emacs-style key bindings, you should uncheck the @onscreen{Enable +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 @onscreen{Enable keybindings in menus} preference. Many of the keybindings below are -inspired by Emacs.} - +inspired by Emacs. @section{Moving Around} @@ -89,6 +90,7 @@ inspired by Emacs.} @keybinding["M-C-down"]{move down into an embedded editor} @keybinding["A-C-down"]{move down into an embedded editor} +@keybinding["C-C C-Z"]{move the cursor to the interactions window} @keybinding["C-F6"]{move the cursor from the definitions window to the interactions window (or the search window, if it is open).} ] @@ -150,10 +152,22 @@ window to the interactions window (or the search window, if it is open).} @keybinding["C-r"]{search for string backward} ] -@section{Miscellaneous} +@section{Evaluation} @itemize[ @keybinding["F5"]{Run} +@keybinding["M-C-x"]{Copy the top-level form surrounding the insertion point to the interactions window + and submit it for evaluation} +@keybinding["C-c C-e"]{Copy the top-level form surrounding the insertion point to the interactions window + and submit it for evaluation} +@keybinding["C-c M-e"]{Copy the top-level form surrounding the insertion point to the interactions window, + submit it for evaluation, and move the focus to the interations window} +@keybinding["C-c C-r"]{Copy the selection to the interactions window + and submit it for evaluation} +@keybinding["C-c C-r"]{Copy the selection to the interactions window + and submit it for evaluation} +@keybinding["C-c M-r"]{Copy the selection to the interactions window, + submit it for evaluation, and move the focus to the interactions window} ]