1 ! Copyright (C) 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays definitions gadgets gadgets-panes
5 generic hashtables help io kernel namespaces prettyprint styles
6 threads sequences vectors definitions parser words strings
7 math listener models errors ;
11 continuation quot busy?
14 C: interactor ( output -- gadget )
15 [ set-interactor-output ] keep
16 <editor> over set-gadget-delegate
17 V{ } clone over set-interactor-history
18 dup dup set-control-self ;
21 f over set-interactor-busy? delegate graft* ;
23 : write-input ( string input -- )
24 <input> presented associate
25 [ H{ { font-style bold } } format ] with-nesting ;
27 : interactor-input. ( string interactor -- )
29 dup string? [ dup write-input terpri ] [ short. ] if
32 : add-interactor-history ( str interactor -- )
33 over empty? [ 2drop ] [ interactor-history push-new ] if ;
35 : interactor-continue ( obj interactor -- )
36 t over set-interactor-busy?
37 interactor-continuation schedule-thread-with ;
39 : interactor-finish ( obj interactor -- )
40 [ editor-string ] keep
41 [ interactor-input. ] 2keep
42 [ add-interactor-history ] keep
43 dup control-model clear-doc
46 : interactor-eval ( interactor -- )
48 [ editor-string ] keep dup interactor-quot call
51 : interactor-eof ( interactor -- )
52 f swap interactor-continuation schedule-thread-with ;
54 : interactor-commit ( interactor -- )
55 dup interactor-busy? [ drop ] [ interactor-eval ] if ;
57 : interactor-yield ( interactor quot -- )
58 over set-interactor-quot
59 f over set-interactor-busy?
60 [ swap set-interactor-continuation stop ] callcc1 nip ;
62 M: interactor stream-readln
67 : interactor-call ( quot interactor -- )
68 2dup interactor-input. interactor-continue ;
70 M: interactor stream-read
72 [ 2drop "" ] [ >r stream-readln r> head ] if ;
74 : save-in/use ( interactor -- )
75 use get over set-interactor-use
76 in get over set-interactor-in
77 error-hook get swap set-interactor-error-hook ;
79 : restore-in/use ( interactor -- )
80 dup interactor-use use set
81 dup interactor-in in set
82 interactor-error-hook error-hook set ;
84 : go-to-error ( interactor error -- )
85 dup parse-error-line 1- swap parse-error-col 2array
86 over editor-caret set-model mark>caret ;
88 : handle-parse-error ( interactor error -- )
89 dup parse-error? [ 2dup go-to-error delegate ] when
90 swap interactor-error-hook call ;
92 : try-parse ( str interactor -- quot/error/f )
97 1array \ parse with-datastack dup length 1 =
98 [ first ] [ drop f ] if
105 : handle-interactive ( str/f interactor -- )
107 { [ dup quotation? ] [ swap interactor-finish ] }
108 { [ dup not ] [ drop "\n" swap user-input ] }
109 { [ t ] [ handle-parse-error ] }
112 M: interactor parse-interactive
114 [ [ handle-interactive ] interactor-yield ] keep
117 interactor "interactor" {
118 { "Evaluate" T{ key-down f f "RETURN" } [ interactor-commit ] }
119 { "Clear input" T{ key-down f { C+ } "k" } [ control-model clear-doc ] }