#lang racket/gui (require framework rackunit "private/util.rkt") (check-equal? (let ([k (make-object keymap:aug-keymap%)]) (send k add-function "abc" void) (send k map-function "c:k" "abc") (hash-map (send k get-map-function-table) list)) '((c:k "abc"))) (check-equal? (let ([k (make-object keymap:aug-keymap%)] [ht (make-hasheq)]) (send k add-function "abc" void) (send k map-function "c:k" "abc") (hash-set! ht 'c:k "def") (hash-map (send k get-map-function-table/ht ht) list)) '((c:k "def"))) (check-equal? (let ([k (make-object keymap:aug-keymap%)] [k1 (make-object keymap:aug-keymap%)] [k2 (make-object keymap:aug-keymap%)]) (send k1 add-function "abc-k1" void) (send k1 map-function "c:k" "abc-k1") (send k2 add-function "abc-k2" void) (send k2 map-function "c:k" "abc-k2") (send k chain-to-keymap k1 #t) (send k chain-to-keymap k2 #t) (hash-map (send k get-map-function-table) list)) '((c:k "abc-k2"))) (check-equal? (let ([k (make-object keymap:aug-keymap%)] [k1 (make-object keymap:aug-keymap%)]) (send k1 add-function "abc-k1" void) (send k1 map-function "c:k" "abc-k1") (send k add-function "abc-k" void) (send k map-function "c:k" "abc-k") (send k chain-to-keymap k1 #t) (hash-map (send k get-map-function-table) list)) '((c:k "abc-k"))) (check-equal? (let ([k (make-object keymap:aug-keymap%)] [k1 (make-object keymap:aug-keymap%)]) (send k1 add-function "abc-k1" void) (send k1 map-function "esc;p" "abc-k1") (send k add-function "abc-k2" void) (send k map-function "ESC;p" "abc-k2") (send k chain-to-keymap k1 #t) (hash-map (send k get-map-function-table) list)) '((|esc;p| "abc-k2"))) (check-equal? (let ([k (make-object keymap:aug-keymap%)]) (send k add-function "shift-em" void) (send k add-function "shift-ah" void) (send k map-function "s:m" "shift-em") (send k map-function "s:a" "shift-ah") (sort (hash-map (send k get-map-function-table) list) string [] (make-key-spec/allplatforms (build-buff-spec "(a)" 0 0) (build-buff-spec "[a]" 0 0) (list '((#\c control) (#\[ control)))) ; [] -> () (make-key-spec/allplatforms (build-buff-spec "[a]" 0 0) (build-buff-spec "(a)" 0 0) (list '((#\c control) (#\[ control)))) ; enclosed sexps (make-key-spec/allplatforms (build-buff-spec "[a (def )b]" 0 0) (build-buff-spec "(a (def )b)" 0 0) (list '((#\c control) (#\[ control)))) ; extra preceding whitespace (make-key-spec/allplatforms (build-buff-spec " \n [a (def )b]" 0 0) (build-buff-spec " \n (a (def )b)" 0 0) (list '((#\c control) (#\[ control)))) ; cursor not at beginning of buffer (make-key-spec/allplatforms (build-buff-spec " \n [a (def )b]" 1 1) (build-buff-spec " \n (a (def )b)" 1 1) (list '((#\c control) (#\[ control)))) ; intervening non-paren sexp (make-key-spec/allplatforms (build-buff-spec " \nf [a (def )b]" 1 1) (build-buff-spec " \nf [a (def )b]" 1 1) (list '((#\c control) (#\[ control)))) ;; at end of buffer (hence sexp-forward returns #f): (make-key-spec/allplatforms (build-buff-spec "[a]" 3 3) (build-buff-spec "[a]" 3 3) (list '((#\c control) (#\[ control)))) (make-key-spec/allplatforms (build-buff-spec "a" 0 0 #:overwrite? #t) (build-buff-spec "b" 1 1) (list '((#\b)))) (make-key-spec/allplatforms (build-buff-spec "a" 0 0 #:overwrite? #t) (build-buff-spec "|" 1 1) (list '((#\|)))) (make-key-spec/allplatforms (build-buff-spec "a" 0 0 #:overwrite? #t) (build-buff-spec "(" 1 1) (list '((#\()))) (make-key-spec/allplatforms (build-buff-spec "a" 0 0 #:overwrite? #t) (build-buff-spec ")" 1 1) (list '((#\))))) ;; needs to be in auto-adjut open paren mode (make-key-spec/allplatforms (build-buff-spec "a" 0 0 #:overwrite? #t) (build-buff-spec "(" 1 1) (list '((#\[)))) (ascii-art-box-spec "+" "═") (ascii-art-box-spec "x" "x") (ascii-art-box-spec "+-+" "═══") (ascii-art-box-spec "+\n|\n+\n" "║\n║\n║\n") (ascii-art-box-spec (string-append "+-+\n" "| |\n" "+-+\n") (string-append "╔═╗\n" "║ ║\n" "╚═╝\n")) (ascii-art-box-spec (string-append "+---+\n" "| - |\n" "|+ ||\n" "+---+\n") (string-append "╔═══╗\n" "║ - ║\n" "║+ |║\n" "╚═══╝\n")) (ascii-art-box-spec (string-append "+-+-+\n" "| | |\n" "+-+-+\n" "| | |\n" "+-+-+\n") (string-append "╔═╦═╗\n" "║ ║ ║\n" "╠═╬═╣\n" "║ ║ ║\n" "╚═╩═╝\n")))) (define automatic-scheme-specs (list (make-key-spec/allplatforms (build-buff-spec "" 0 0) (build-buff-spec "()" 1 1) '(((#\()))) (make-key-spec/allplatforms (build-buff-spec "" 0 0) (build-buff-spec "[]" 1 1) '(((#\[)))) (make-key-spec/allplatforms (build-buff-spec "" 0 0) (build-buff-spec "{}" 1 1) '(((#\{)))) (make-key-spec/allplatforms (build-buff-spec "" 0 0) (build-buff-spec "\"\"" 1 1) '(((#\")))) (make-key-spec/allplatforms (build-buff-spec "" 0 0) (build-buff-spec "||" 1 1) '(((#\|)))))) (define (queue-callback/wait t) (define c (make-channel)) (queue-callback (λ () (channel-put c (t)))) (channel-get c)) (define (test-specs frame-name frame-class specs) (define f #f) (queue-callback/wait (λ () (set! f (make-object frame-class frame-name)) (send f show #t))) (for ([key-spec (in-list specs)] [i (in-naturals)]) (define key-sequences ((case (system-type) [(macos macosx) key-spec-macos] [(unix) key-spec-unix] [(windows) key-spec-windows]) key-spec)) (define before (key-spec-before key-spec)) (define after (key-spec-after key-spec)) (for ([key-sequence (in-list key-sequences)]) (define text-expect (buff-spec-string after)) (define start-expect (buff-spec-start after)) (define end-expect (buff-spec-end after)) (queue-callback (λ () (define frame (test:get-active-top-level-window)) (define text (send frame get-editor)) (send text set-overwrite-mode (buff-spec-overwrite? before)) (send text erase) (send text insert (buff-spec-string before)) (send text set-position (buff-spec-start before) (buff-spec-end before)))) (for ([key (in-list key-sequence)]) (test:keystroke (car key) (cdr key))) (check-equal? (queue-callback/wait (λ () (define frame (test:get-active-top-level-window)) (define text (send frame get-editor)) (vector (send text get-text) (send text get-start-position) (send text get-end-position)))) (vector text-expect start-expect end-expect) (~s (list frame-name key-sequence i))))) (queue-callback/wait (λ () (send f close)))) (with-private-prefs (parameterize ([test:use-focus-table #t]) ;; needs to be inside the test:use-focus-table setting (parameterize ([current-eventspace (make-eventspace)]) (define dummy #f) (queue-callback (λ () (set! dummy (make-object frame:basic% "dummy to trick frame group")) (send dummy show #t))) (preferences:set 'framework:fixup-open-parens #t) (preferences:set 'framework:automatic-parens #f) (test-specs "global keybindings test" frame:text% global-specs) (test-specs "racket mode keybindings test" (class frame:editor% (define/override (get-editor%) racket:text%) (super-new)) scheme-specs) (preferences:set 'framework:automatic-parens #t) (preferences:set 'framework:fixup-open-parens #f) (test-specs "racket mode automatic-parens on keybindings test" (class frame:editor% (define/override (get-editor%) racket:text%) (super-new)) automatic-scheme-specs) (queue-callback (λ () (send dummy show #f))))))