diff --git a/drracket-test/tests/drracket/private/drracket-test-util.rkt b/drracket-test/tests/drracket/private/drracket-test-util.rkt index 507729b50..e4821533d 100644 --- a/drracket-test/tests/drracket/private/drracket-test-util.rkt +++ b/drracket-test/tests/drracket/private/drracket-test-util.rkt @@ -11,9 +11,8 @@ "gui.rkt" "no-fw-test-util.rkt") - (provide/contract - [use-get/put-dialog (-> (-> any) path? void?)] - [set-module-language! (->* () (boolean?) void?)]) + (provide (contract-out [use-get/put-dialog (-> (-> any) path? void?)] + [set-module-language! (->* () (boolean?) void?)])) (provide queue-callback/res fire-up-drracket-and-run-tests @@ -60,25 +59,25 @@ ;; filename is a string naming a file that should be typed into the dialog (define (use-get/put-dialog open-dialog filename) (not-on-eventspace-handler-thread 'use-get/put-dialog) - (let ([drs (wait-for-drracket-frame)]) - (with-handlers ([(lambda (x) #t) - (lambda (x) - (fw:preferences:set 'framework:file-dialogs 'std) - (raise x))]) - (fw:preferences:set 'framework:file-dialogs 'common) - (open-dialog) - (let ([dlg (wait-for-new-frame drs)]) - (send (find-labelled-window "Filename:" #f (fw:test:get-active-top-level-window)) focus) - (fw:test:keystroke #\a (list (case (system-type) - [(windows) 'control] - [(macosx macos) 'meta] - [(unix) 'control] - [else (error 'use-get/put-dialog "unknown platform: ~s\n" - (system-type))]))) - (for-each fw:test:keystroke (string->list (path->string filename))) - (fw:test:button-push "OK") - (wait-for-new-frame dlg)) - (fw:preferences:set 'framework:file-dialogs 'std)))) + (define drs (wait-for-drracket-frame)) + (with-handlers ([(lambda (x) #t) (lambda (x) + (fw:preferences:set 'framework:file-dialogs 'std) + (raise x))]) + (fw:preferences:set 'framework:file-dialogs 'common) + (open-dialog) + (let ([dlg (wait-for-new-frame drs)]) + (send (find-labelled-window "Filename:" #f (fw:test:get-active-top-level-window)) focus) + (fw:test:keystroke + #\a + (list (case (system-type) + [(windows) 'control] + [(macosx macos) 'meta] + [(unix) 'control] + [else (error 'use-get/put-dialog "unknown platform: ~s\n" (system-type))]))) + (for-each fw:test:keystroke (string->list (path->string filename))) + (fw:test:button-push "OK") + (wait-for-new-frame dlg)) + (fw:preferences:set 'framework:file-dialogs 'std))) (define (test-util-error fmt . args) (raise (make-exn (apply fmt args) (current-continuation-marks)))) @@ -90,10 +89,7 @@ (define (wait-for-drracket-frame [print-message? #f]) (define (wait-for-drracket-frame-pred) (define active (fw:test:get-active-top-level-window)) - (if (and active - (drracket-frame? active)) - active - #f)) + (and (and active (drracket-frame? active)) active)) (define drr-fr (or (wait-for-drracket-frame-pred) (begin @@ -116,10 +112,7 @@ (for/or ([eventspace (in-list extra-eventspaces)]) (parameterize ([current-eventspace eventspace]) (fw:test:get-active-top-level-window))))) - (if (and active - (not (eq? active old-frame))) - active - #f)) + (and (and active (not (eq? active old-frame))) active)) (define lab (send old-frame get-label)) (define fr (poll-until (procedure-rename wait-for-new-frame-pred @@ -167,34 +160,29 @@ (poll-until wait-for-computation-to-finish 60) (sync (system-idle-evt))) - (define do-execute - (case-lambda - [(frame) - (do-execute frame #t)] - [(frame wait-for-finish?) - (not-on-eventspace-handler-thread 'do-execute) - (queue-callback/res (λ () (verify-drracket-frame-frontmost 'do-execute frame))) - (let ([button (queue-callback/res (λ () (send frame get-execute-button)))]) - (fw:test:run-one (lambda () (send button command))) - (when wait-for-finish? - (wait-for-computation frame)))])) + (define (do-execute frame [wait-for-finish? #t]) + (not-on-eventspace-handler-thread 'do-execute) + (queue-callback/res (λ () (verify-drracket-frame-frontmost 'do-execute frame))) + (let ([button (queue-callback/res (λ () (send frame get-execute-button)))]) + (fw:test:run-one (lambda () (send button command))) + (when wait-for-finish? + (wait-for-computation frame)))) (define (verify-drracket-frame-frontmost function-name frame) (on-eventspace-handler-thread 'verify-drracket-frame-frontmost) - (let ([tl (fw:test:get-active-top-level-window)]) - (unless (and (eq? frame tl) - (drracket-frame? tl)) - (error function-name "drracket frame not frontmost: ~e (found ~e)" frame tl)))) + (define tl (fw:test:get-active-top-level-window)) + (unless (and (eq? frame tl) (drracket-frame? tl)) + (error function-name "drracket frame not frontmost: ~e (found ~e)" frame tl))) (define (clear-definitions frame) (queue-callback/res (λ () (verify-drracket-frame-frontmost 'clear-definitions frame))) (fw:test:new-window (queue-callback/res (λ () (send frame get-definitions-canvas)))) (let ([window (queue-callback/res (λ () (send frame get-edit-target-window)))]) - (let-values ([(cw ch) (queue-callback/res (λ () (send window get-client-size)))] - [(w h) (queue-callback/res (λ () (send window get-size)))]) - (fw:test:mouse-click 'left - (inexact->exact (floor (+ cw (/ (- w cw) 2)))) - (inexact->exact (floor (+ ch (/ (- h ch) 2))))))) + (define-values (cw ch) (queue-callback/res (λ () (send window get-client-size)))) + (define-values (w h) (queue-callback/res (λ () (send window get-size)))) + (fw:test:mouse-click 'left + (inexact->exact (floor (+ cw (/ (- w cw) 2)))) + (inexact->exact (floor (+ ch (/ (- h ch) 2)))))) (fw:test:menu-select "Edit" "Select All") (fw:test:menu-select "Edit" (if (eq? (system-type) 'macos) "Clear" @@ -217,64 +205,58 @@ (not-on-eventspace-handler-thread 'put-in-frame) (unless (and (object? frame) (is-a? frame top-level-window<%>)) (error who "expected a frame or a dialog as the first argument, got ~e" frame)) - (let ([str (if (string? str/sexp) - str/sexp - (let ([port (open-output-string)]) - (parameterize ([current-output-port port]) - (write str/sexp port)) - (get-output-string port)))]) - (queue-callback/res (λ () (verify-drracket-frame-frontmost who frame))) - (let ([canvas (queue-callback/res (λ () (get-canvas frame)))]) - (fw:test:new-window canvas) - (let ([editor (queue-callback/res (λ () (send canvas get-editor)))]) - (cond - [just-insert? - (let ([s (make-semaphore 0)]) - (queue-callback - (λ () - (send editor set-caret-owner #f) - (send editor insert str) - (semaphore-post s))) - (unless (sync/timeout 3 s) - (error who "callback didn't run for 3 seconds; trying to insert ~s" str/sexp)))] - [else - (queue-callback/res (λ () (send editor set-caret-owner #f))) - (type-string str)]))))) + (define str + (if (string? str/sexp) + str/sexp + (let ([port (open-output-string)]) + (parameterize ([current-output-port port]) + (write str/sexp port)) + (get-output-string port)))) + (queue-callback/res (λ () (verify-drracket-frame-frontmost who frame))) + (define canvas (queue-callback/res (λ () (get-canvas frame)))) + (fw:test:new-window canvas) + (define editor (queue-callback/res (λ () (send canvas get-editor)))) + (cond + [just-insert? + (let ([s (make-semaphore 0)]) + (queue-callback (λ () + (send editor set-caret-owner #f) + (send editor insert str) + (semaphore-post s))) + (unless (sync/timeout 3 s) + (error who "callback didn't run for 3 seconds; trying to insert ~s" str/sexp)))] + [else + (queue-callback/res (λ () (send editor set-caret-owner #f))) + (type-string str)])) (define (alt-return-in-interactions frame) (not-on-eventspace-handler-thread 'alt-return-in-interactions) (queue-callback/res (λ () (verify-drracket-frame-frontmost 'alt-return-in-interactions frame))) - (let ([canvas (send frame get-interactions-canvas)]) - (fw:test:new-window canvas) - (let ([editor (send canvas get-editor)]) - (send editor set-caret-owner #f) - (fw:test:keystroke #\return '(alt))))) + (define canvas (send frame get-interactions-canvas)) + (fw:test:new-window canvas) + (define editor (send canvas get-editor)) + (send editor set-caret-owner #f) + (fw:test:keystroke #\return '(alt))) ;; type-string : string -> void ;; to call test:keystroke repeatedly with the characters (define (type-string str) (not-on-eventspace-handler-thread 'type-string) - (let ([len (string-length str)]) - (let loop ([i 0]) - (unless (>= i len) - (let ([c (string-ref str i)]) - (fw:test:keystroke - (if (char=? c #\newline) - #\return - c))) - (loop (+ i 1)))))) - - (define wait - (case-lambda - [(test desc-string) (wait test desc-string 5)] - [(test desc-string time) - (let ([int 1/2]) - (let loop ([sofar 0]) - (cond - [(> sofar time) (error 'wait desc-string)] - [(test) (void)] - [else (sleep int) - (loop (+ sofar int))])))])) + (define len (string-length str)) + (let loop ([i 0]) + (unless (>= i len) + (let ([c (string-ref str i)]) (fw:test:keystroke (if (char=? c #\newline) #\return c))) + (loop (+ i 1))))) + + (define (wait test desc-string [time 5]) + (let ([int 1/2]) + (let loop ([sofar 0]) + (cond + [(> sofar time) (error 'wait desc-string)] + [(test) (void)] + [else + (sleep int) + (loop (+ sofar int))])))) (define (wait-pending) (wait (lambda () (= 0 (fw:test:number-pending-actions))) @@ -310,9 +292,9 @@ (define (get-text-pos text) (on-eventspace-handler-thread 'get-text-pos) - (let* ([last-pos (send text last-position)] - [last-line (send text position-line last-pos)]) - (send text line-start-position last-line))) + (define last-pos (send text last-position)) + (define last-line (send text position-line last-pos)) + (send text line-start-position last-line)) ; poll for enabled button @@ -338,146 +320,139 @@ ;; set-language-level! : (cons (union regexp string) (listof (union regexp string))) boolean -> void ;; set language level in the frontmost DrRacket frame (resets settings to defaults) ;; If `close-dialog?' it #t, - (define set-language-level! - (lambda (in-language-spec [close-dialog? #t]) - (unless (and (pair? in-language-spec) - (list? in-language-spec) - (andmap (lambda (x) (or string? regexp?)) in-language-spec)) - (error 'set-language-level! - "expected a non-empty list of regexps and strings for language, got: ~e" - in-language-spec)) - (not-on-eventspace-handler-thread 'set-language-level!) - (let ([drs-frame (fw:test:get-active-top-level-window)]) - (fw:test:menu-select "Language" "Choose Language…") - (define language-dialog (wait-for-new-frame drs-frame)) - (fw:test:set-radio-box-item! #rx"Other Languages") - (define language-choices (find-labelled-windows #f hierarchical-list% - (fw:test:get-active-top-level-window))) - (define (click-on-snip snip) - (define-values (x y) - (queue-callback/res - (λ () - (define b1 (box 0)) - (define b2 (box 0)) - (define editor (send (send snip get-admin) get-editor)) - (define between-threshold (send editor get-between-threshold)) - (send editor get-snip-location snip b1 b2) - (define-values (gx gy) (send editor editor-location-to-dc-location - (unbox b1) - (unbox b2))) - (define x (inexact->exact (floor (+ gx between-threshold 1)))) - (define y (inexact->exact (floor (+ gy between-threshold 1)))) - (values x y)))) - (fw:test:mouse-click 'left x y)) - - (define found-language? #f) - - (for ([language-choice (in-list language-choices)]) - (queue-callback/res (λ () (send language-choice focus))) - (let loop ([list-item language-choice] - [language-spec in-language-spec]) - (let* ([name (car language-spec)] - [which - (queue-callback/res - (λ () - (filter (lambda (child) - (let* ([text (send (send child get-editor) get-text)] - [matches - (or (and (regexp? name) - (regexp-match name text)) - (and (string? name) - (string=? name text)))]) - (and matches - child))) - (send list-item get-items))))]) - (unless (null? which) - (unless (= 1 (length which)) - (error 'set-language-level! "couldn't find language: ~e, double match ~e" - in-language-spec name)) - (let ([next-item (car which)]) - (cond - [(null? (cdr language-spec)) - (when (is-a? next-item hierarchical-list-compound-item<%>) - (error 'set-language-level! - "expected no more languages after ~e, but still are, input ~e" - name in-language-spec)) - (set! found-language? #t) - (click-on-snip (send next-item get-clickable-snip))] - [else - (unless (is-a? next-item hierarchical-list-compound-item<%>) - (error 'set-language-level! - "expected more languages after ~e, but got to end, input ~e" - name in-language-spec)) - (unless (queue-callback/res (λ () (send next-item is-open?))) - (click-on-snip (send next-item get-arrow-snip))) - (loop next-item (cdr language-spec))])))))) - - (unless found-language? - (error 'set-language-level! "couldn't find language: ~e" in-language-spec)) - - (with-handlers ([exn:fail? (lambda (x) (void))]) - (fw:test:button-push "Show Details")) - - (fw:test:button-push "Revert to Language Defaults") - - (when close-dialog? - (fw:test:button-push "OK") - (let ([new-frame (wait-for-new-frame language-dialog)]) - (unless (eq? new-frame drs-frame) - (error 'set-language-level! - "didn't get drracket frame back, got: ~s (drs-frame ~s)\n" - new-frame - drs-frame))))))) + (define (set-language-level! in-language-spec [close-dialog? #t]) + (unless (and (pair? in-language-spec) + (list? in-language-spec) + (andmap (lambda (x) (or string? regexp?)) in-language-spec)) + (error 'set-language-level! + "expected a non-empty list of regexps and strings for language, got: ~e" + in-language-spec)) + (not-on-eventspace-handler-thread 'set-language-level!) + (let ([drs-frame (fw:test:get-active-top-level-window)]) + (fw:test:menu-select "Language" "Choose Language…") + (define language-dialog (wait-for-new-frame drs-frame)) + (fw:test:set-radio-box-item! #rx"Other Languages") + (define language-choices + (find-labelled-windows #f hierarchical-list% (fw:test:get-active-top-level-window))) + (define (click-on-snip snip) + (define-values (x y) + (queue-callback/res (λ () + (define b1 (box 0)) + (define b2 (box 0)) + (define editor (send (send snip get-admin) get-editor)) + (define between-threshold (send editor get-between-threshold)) + (send editor get-snip-location snip b1 b2) + (define-values (gx gy) + (send editor editor-location-to-dc-location (unbox b1) (unbox b2))) + (define x (inexact->exact (floor (+ gx between-threshold 1)))) + (define y (inexact->exact (floor (+ gy between-threshold 1)))) + (values x y)))) + (fw:test:mouse-click 'left x y)) + + (define found-language? #f) + + (for ([language-choice (in-list language-choices)]) + (queue-callback/res (λ () (send language-choice focus))) + (let loop ([list-item language-choice] + [language-spec in-language-spec]) + (let* ([name (car language-spec)] + [which (queue-callback/res + (λ () + (filter (lambda (child) + (let* ([text (send (send child get-editor) get-text)] + [matches (or (and (regexp? name) (regexp-match name text)) + (and (string? name) (string=? name text)))]) + (and matches child))) + (send list-item get-items))))]) + (unless (null? which) + (unless (= 1 (length which)) + (error 'set-language-level! + "couldn't find language: ~e, double match ~e" + in-language-spec + name)) + (let ([next-item (car which)]) + (cond + [(null? (cdr language-spec)) + (when (is-a? next-item hierarchical-list-compound-item<%>) + (error 'set-language-level! + "expected no more languages after ~e, but still are, input ~e" + name + in-language-spec)) + (set! found-language? #t) + (click-on-snip (send next-item get-clickable-snip))] + [else + (unless (is-a? next-item hierarchical-list-compound-item<%>) + (error 'set-language-level! + "expected more languages after ~e, but got to end, input ~e" + name + in-language-spec)) + (unless (queue-callback/res (λ () (send next-item is-open?))) + (click-on-snip (send next-item get-arrow-snip))) + (loop next-item (cdr language-spec))])))))) + + (unless found-language? + (error 'set-language-level! "couldn't find language: ~e" in-language-spec)) + + (with-handlers ([exn:fail? (lambda (x) (void))]) + (fw:test:button-push "Show Details")) + + (fw:test:button-push "Revert to Language Defaults") + + (when close-dialog? + (fw:test:button-push "OK") + (let ([new-frame (wait-for-new-frame language-dialog)]) + (unless (eq? new-frame drs-frame) + (error 'set-language-level! + "didn't get drracket frame back, got: ~s (drs-frame ~s)\n" + new-frame + drs-frame)))))) (define (set-module-language! [close-dialog? #t]) (not-on-eventspace-handler-thread 'set-module-language!) - (let ([drs-frame (fw:test:get-active-top-level-window)]) - (fw:test:menu-select "Language" "Choose Language…") - (let* ([language-dialog (wait-for-new-frame drs-frame)]) - (fw:test:set-radio-box-item! #rx"The Racket Language") - - (with-handlers ([exn:fail? (lambda (x) (void))]) - (fw:test:button-push "Show Details")) - - (fw:test:button-push "Revert to Language Defaults") - - (when close-dialog? - (fw:test:button-push "OK") - (let ([new-frame (wait-for-new-frame language-dialog)]) - (unless (eq? new-frame drs-frame) - (error 'set-module-language! - "didn't get drracket frame back, got: ~s (drs-frame ~s)\n" - new-frame - drs-frame))))))) - - (provide/contract [check-language-level ((or/c string? regexp?) . -> . void?)]) + (define drs-frame (fw:test:get-active-top-level-window)) + (fw:test:menu-select "Language" "Choose Language…") + (define language-dialog (wait-for-new-frame drs-frame)) + (fw:test:set-radio-box-item! #rx"The Racket Language") + + (with-handlers ([exn:fail? (lambda (x) (void))]) + (fw:test:button-push "Show Details")) + + (fw:test:button-push "Revert to Language Defaults") + + (when close-dialog? + (fw:test:button-push "OK") + (let ([new-frame (wait-for-new-frame language-dialog)]) + (unless (eq? new-frame drs-frame) + (error 'set-module-language! + "didn't get drracket frame back, got: ~s (drs-frame ~s)\n" + new-frame + drs-frame))))) + + (provide (contract-out [check-language-level ((or/c string? regexp?) . -> . void?)])) ;; checks that the language in the drracket window is set to the given one. ;; clears the definitions, clicks execute and checks the interactions window. (define (check-language-level lang-spec) (not-on-eventspace-handler-thread 'check-language-level!) - (let* ([drs-frame (wait-for-drracket-frame)] - [interactions (send drs-frame get-interactions-text)] - [definitions-canvas (send drs-frame get-definitions-canvas)]) - (fw:test:new-window definitions-canvas) - (fw:test:menu-select "Edit" "Select All") - (fw:test:menu-select "Edit" "Delete") - (do-execute drs-frame) - (let ([lang-line (queue-callback/res - (λ () - (send interactions get-text - (send interactions line-start-position 1) - (send interactions line-end-position 1))))]) - (unless (regexp-match lang-spec lang-line) - (error 'check-language-level "expected ~s to match ~s" - lang-line lang-spec))))) + (define drs-frame (wait-for-drracket-frame)) + (define interactions (send drs-frame get-interactions-text)) + (define definitions-canvas (send drs-frame get-definitions-canvas)) + (fw:test:new-window definitions-canvas) + (fw:test:menu-select "Edit" "Select All") + (fw:test:menu-select "Edit" "Delete") + (do-execute drs-frame) + (define lang-line + (queue-callback/res (λ () + (send interactions get-text + (send interactions line-start-position 1) + (send interactions line-end-position 1))))) + (unless (regexp-match lang-spec lang-line) + (error 'check-language-level "expected ~s to match ~s" lang-line lang-spec))) (define (repl-in-edit-sequence?) (not-on-eventspace-handler-thread 'repl-in-edit-sequence?) - (let ([drr (wait-for-drracket-frame)]) - (queue-callback/res - (λ () - (send (send drr get-interactions-text) refresh-delayed?))))) + (define drr (wait-for-drracket-frame)) + (queue-callback/res (λ () (send (send drr get-interactions-text) refresh-delayed?)))) ;; has-error? : frame -> (union #f string) ;; returns the text of an error in the interactions window of the frame or #f if there is none. @@ -487,40 +462,41 @@ (run-one/sync (lambda () (verify-drracket-frame-frontmost 'had-error? frame) - (let* ([interactions-text (send frame get-interactions-text)] - [last-para (send interactions-text last-paragraph)]) - (unless (>= last-para 2) - (error 'has-error? "expected at least 2 paragraphs in interactions window, found ~a" - (+ last-para 1))) - (let ([start (send interactions-text paragraph-start-position 2)] - [end (send interactions-text paragraph-end-position - (- (send interactions-text last-paragraph) 1))]) - (send interactions-text split-snip start) - (send interactions-text split-snip end) - (let loop ([pos start]) - (cond - [(<= end pos) #f] - [else - (let ([snip (send interactions-text find-snip pos 'after-or-none)]) - (cond - [(not snip) #f] - [else - (let ([color (send (send snip get-style) get-foreground)]) - (if (and (= 255 (send color red)) - (= 0 (send color blue) (send color green))) - - ;; return the text of the entire line containing the red text - (let ([para (send interactions-text position-paragraph pos)]) - (unless (exact-nonnegative-integer? para) - (error 'has-error? - "got back a bad result from position-paragraph: ~s ~s\n" - para - (list pos (send interactions-text last-position)))) - (send interactions-text get-text - (send interactions-text paragraph-start-position para) - (send interactions-text paragraph-end-position para))) - - (loop (+ pos (send snip get-count)))))]))]))))))) + (define interactions-text (send frame get-interactions-text)) + (define last-para (send interactions-text last-paragraph)) + (unless (>= last-para 2) + (error 'has-error? + "expected at least 2 paragraphs in interactions window, found ~a" + (+ last-para 1))) + (define start (send interactions-text paragraph-start-position 2)) + (define end + (send interactions-text paragraph-end-position + (- (send interactions-text last-paragraph) 1))) + (send interactions-text split-snip start) + (send interactions-text split-snip end) + (let loop ([pos start]) + (cond + [(<= end pos) #f] + [else + (let ([snip (send interactions-text find-snip pos 'after-or-none)]) + (cond + [(not snip) #f] + [else + (let ([color (send (send snip get-style) get-foreground)]) + (if (and (= 255 (send color red)) (= 0 (send color blue) (send color green))) + + ;; return the text of the entire line containing the red text + (let ([para (send interactions-text position-paragraph pos)]) + (unless (exact-nonnegative-integer? para) + (error 'has-error? + "got back a bad result from position-paragraph: ~s ~s\n" + para + (list pos (send interactions-text last-position)))) + (send interactions-text get-text + (send interactions-text paragraph-start-position para) + (send interactions-text paragraph-end-position para))) + + (loop (+ pos (send snip get-count)))))]))]))))) (define fetch-output (case-lambda @@ -531,17 +507,18 @@ (lambda () (verify-drracket-frame-frontmost 'fetch-output frame) (define-values (start end) - (if (and _start _end) - (values _start _end) - (let* ([interactions-text (send frame get-interactions-text)] - [last-para (send interactions-text last-paragraph)]) - (unless (>= last-para 2) - (error 'fetch-output - "expected at least 2 paragraphs in interactions window, found ~a" - (+ last-para 1))) - (values (send interactions-text paragraph-start-position 2) - (send interactions-text paragraph-end-position - (- (send interactions-text last-paragraph) 1)))))) + (cond + [(and _start _end) (values _start _end)] + [else + (define interactions-text (send frame get-interactions-text)) + (define last-para (send interactions-text last-paragraph)) + (unless (>= last-para 2) + (error 'fetch-output + "expected at least 2 paragraphs in interactions window, found ~a" + (+ last-para 1))) + (values (send interactions-text paragraph-start-position 2) + (send interactions-text paragraph-end-position + (- (send interactions-text last-paragraph) 1)))])) (define (fetch-text-content text start end) (send text split-snip start) @@ -616,9 +593,9 @@ (call-with-values f (lambda x (set! anss x)))) (semaphore-post s))) (semaphore-wait s) - (if raised-exn? - (raise exn) - (apply values anss)))) + (when raised-exn? + (raise exn)) + (apply values anss))) ;; this is assumed to not open an windows or anything like that ;; but just to print and return.