1 ! Copyright (C) 2005, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: inspector ui.tools.interactor ui.tools.inspector
4 ui.tools.workspace help.markup io io.styles
5 kernel models namespaces parser quotations sequences ui.commands
6 ui.gadgets ui.gadgets.editors ui.gadgets.labelled
7 ui.gadgets.panes ui.gadgets.buttons ui.gadgets.scrollers
8 ui.gadgets.tracks ui.gestures ui.operations vocabs words
9 prettyprint listener debugger threads boxes concurrency.flags
10 math arrays generic accessors combinators ;
13 TUPLE: listener-gadget input output stack ;
15 : listener-output, ( -- )
16 <scrolling-pane> g-> set-listener-gadget-output
17 <scroller> "Output" <labelled-gadget> 1 track, ;
19 : listener-streams ( listener -- input output )
20 [ input>> ] [ output>> <pane-stream> ] bi ;
22 : <listener-input> ( listener -- gadget )
23 output>> <pane-stream> <interactor> ;
25 : listener-input, ( -- )
26 g <listener-input> g-> set-listener-gadget-input
27 <limited-scroller> { 0 100 } >>dim
28 "Input" <labelled-gadget> f track, ;
31 "If this is your first time with Factor, please read the " print
32 "cookbook" ($link) "." print nl ;
34 M: listener-gadget focusable-child*
37 M: listener-gadget call-tool* ( input listener -- )
38 >r string>> r> input>> set-editor-string ;
40 M: listener-gadget tool-scroller
41 output>> find-scroller ;
43 : wait-for-listener ( listener -- )
44 #! Wait for the listener to start.
45 input>> flag>> wait-for-flag ;
47 : workspace-busy? ( workspace -- ? )
48 listener>> input>> interactor-busy? ;
50 : listener-input ( string -- )
51 get-workspace listener>> input>> set-editor-string ;
53 : (call-listener) ( quot listener -- )
54 input>> interactor-call ;
56 : call-listener ( quot -- )
57 [ workspace-busy? not ] get-workspace* listener>>
58 [ dup wait-for-listener (call-listener) ] 2curry
59 "Listener call" spawn drop ;
61 M: listener-command invoke-command ( target command -- )
62 command-quot call-listener ;
64 M: listener-operation invoke-command ( target command -- )
65 [ operation-hook call ] keep operation-quot call-listener ;
67 : eval-listener ( string -- )
69 listener>> input>> [ set-editor-string ] keep
72 : listener-run-files ( seq -- )
76 [ [ run-file ] each ] curry call-listener
79 : com-end ( listener -- )
80 input>> interactor-eof ;
82 : clear-output ( listener -- )
85 \ clear-output H{ { +listener+ t } } define-command
87 : clear-stack ( listener -- )
88 [ clear ] swap (call-listener) ;
90 GENERIC: word-completion-string ( word -- string )
92 M: word word-completion-string
95 M: method-body word-completion-string
96 "method-generic" word-prop word-completion-string ;
98 USE: generic.standard.engines.tuple
100 M: engine-word word-completion-string
101 "engine-generic" word-prop word-completion-string ;
103 : use-if-necessary ( word seq -- )
104 >r word-vocabulary vocab-words r>
106 { [ dup not ] [ 2drop ] }
107 { [ 2dup memq? ] [ 2drop ] }
111 : insert-word ( word -- )
112 get-workspace workspace-listener input>>
113 [ >r word-completion-string r> user-input ]
114 [ interactor-use use-if-necessary ]
117 : quot-action ( interactor -- lines )
119 dup "\n" join pick add-interactor-history
122 TUPLE: stack-display ;
124 : <stack-display> ( -- gadget )
126 g workspace-listener swap [
127 dup <toolbar> f track,
128 stack>> [ [ stack. ] curry try ]
129 t "Data stack" <labelled-pane> 1 track,
130 ] { 0 1 } build-track ;
132 M: stack-display tool-scroller
133 find-workspace workspace-listener tool-scroller ;
135 : ui-listener-hook ( listener -- )
136 >r datastack r> listener-gadget-stack set-model ;
138 : ui-error-hook ( error listener -- )
139 find-workspace debugger-popup ;
141 : ui-inspector-hook ( obj listener -- )
142 find-workspace inspector-gadget
143 swap show-tool inspect-object ;
145 : listener-thread ( listener -- )
146 dup listener-streams [
147 [ [ ui-listener-hook ] curry listener-hook set ]
148 [ [ ui-error-hook ] curry error-hook set ]
149 [ [ ui-inspector-hook ] curry inspector-hook set ] tri
154 : start-listener-thread ( listener -- )
156 [ input>> register-self ] [ listener-thread ] bi
157 ] curry "Listener" spawn drop ;
159 : restart-listener ( listener -- )
160 #! Returns when listener is ready to receive input.
164 [ start-listener-thread ]
165 [ wait-for-listener ]
168 : init-listener ( listener -- )
169 f <model> swap set-listener-gadget-stack ;
171 : <listener-gadget> ( -- gadget )
172 listener-gadget new dup init-listener
173 [ listener-output, listener-input, ] { 0 1 } build-track ;
175 : listener-help "ui-listener" help-window ;
177 \ listener-help H{ { +nullary+ t } } define-command
179 listener-gadget "toolbar" f {
180 { f restart-listener }
181 { T{ key-down f f "CLEAR" } clear-output }
182 { T{ key-down f { C+ } "CLEAR" } clear-stack }
183 { T{ key-down f { C+ } "d" } com-end }
184 { T{ key-down f f "F1" } listener-help }
187 M: listener-gadget handle-gesture* ( gadget gesture delegate -- ? )
188 3dup drop swap find-workspace workspace-page handle-gesture
189 [ default-gesture-handler ] [ 3drop f ] if ;
191 M: listener-gadget graft*
192 [ delegate graft* ] [ restart-listener ] bi ;
194 M: listener-gadget ungraft*
195 [ com-end ] [ delegate ungraft* ] bi ;