1 ! Copyright (C) 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs calendar colors colors.constants
4 documents documents.elements fry kernel words sets splitting math
5 math.vectors models.delay models.arrow combinators.short-circuit
6 parser present sequences tools.completion help.vocabs generic fonts
7 definitions.icons ui.images ui.commands ui.operations ui.gadgets
8 ui.gadgets.editors ui.gadgets.glass ui.gadgets.scrollers
9 ui.gadgets.tables ui.gadgets.tracks ui.gadgets.labeled ui.gadgets.theme
10 ui.gadgets.worlds ui.gadgets.wrappers ui.gestures ui.pens.solid
11 ui.tools.listener.history combinators vocabs ui.tools.listener.popups ;
12 IN: ui.tools.listener.completion
14 ! We don't directly depend on the listener tool but we use a few slots
18 : history-list ( interactor -- alist )
20 [ dup string>> H{ { CHAR: \n CHAR: \s } } substitute ] { } map>assoc
23 : history-completions ( short interactor -- seq )
24 history-list over empty? [ nip ] [ members completions ] if ;
26 TUPLE: word-completion manifest ;
27 C: <word-completion> word-completion
29 SINGLETONS: vocab-completion color-completion char-completion
30 path-completion history-completion ;
31 UNION: definition-completion word-completion vocab-completion ;
32 UNION: listener-completion definition-completion
33 color-completion char-completion path-completion history-completion ;
35 GENERIC: completion-quot ( interactor completion-mode -- quot )
37 : (completion-quot) ( interactor completion-mode quot -- quot' )
38 2nip '[ [ { } ] _ if-empty ] ; inline
40 M: word-completion completion-quot [ words-matching ] (completion-quot) ;
41 M: vocab-completion completion-quot [ vocabs-matching ] (completion-quot) ;
42 M: color-completion completion-quot [ colors-matching ] (completion-quot) ;
43 M: char-completion completion-quot [ chars-matching ] (completion-quot) ;
44 M: path-completion completion-quot [ paths-matching ] (completion-quot) ;
45 M: history-completion completion-quot drop '[ _ history-completions ] ;
47 GENERIC: completion-element ( completion-mode -- element )
49 M: object completion-element drop word-start-elt ;
50 M: history-completion completion-element drop one-line-elt ;
52 GENERIC: completion-banner ( completion-mode -- string )
54 M: word-completion completion-banner drop "Words" ;
55 M: vocab-completion completion-banner drop "Vocabularies" ;
56 M: color-completion completion-banner drop "Colors" ;
57 M: char-completion completion-banner drop "Unicode code point names" ;
58 M: path-completion completion-banner drop "Paths" ;
59 M: history-completion completion-banner drop "Input history" ;
61 ! Completion modes also implement the row renderer protocol
62 M: listener-completion row-columns drop present 1array ;
64 M: definition-completion prototype-row
65 drop \ + definition-icon <image-name> "" 2array ;
67 M: definition-completion row-columns
69 [ definition-icon <image-name> ]
73 M: word-completion row-color
74 [ vocabulary>> ] [ manifest>> ] bi* {
75 { [ dup not ] [ COLOR: black ] }
76 { [ 2dup search-vocab-names>> in? ] [ COLOR: black ] }
77 { [ over ".private" tail? ] [ COLOR: dark-red ] }
81 M: vocab-completion row-color
83 name>> ".private" tail? COLOR: dark-red COLOR: black ?
84 ] [ drop COLOR: dark-gray ] if ;
86 M: color-completion row-color
89 : up-to-caret ( caret document -- string )
90 [ { 0 0 } ] 2dip doc-range ;
92 : completion-mode ( interactor -- symbol )
93 [ manifest>> ] [ editor-caret ] [ model>> ] tri up-to-caret " \r\n" split
95 { [ dup complete-vocab? ] [ 2drop vocab-completion ] }
96 { [ dup complete-char? ] [ 2drop char-completion ] }
97 { [ dup complete-color? ] [ 2drop color-completion ] }
98 { [ dup complete-pathname? ] [ 2drop path-completion ] }
99 [ drop <word-completion> ]
102 TUPLE: completion-popup < track interactor table completion-mode ;
104 : find-completion-popup ( gadget -- popup )
105 [ completion-popup? ] find-parent ;
107 : <completion-model> ( editor element quot -- model )
108 [ <element-model> 1/3 seconds <delay> ] dip
109 '[ @ keys 1000 short head ] <arrow> ;
111 M: completion-popup focusable-child* table>> ;
113 : completion-loc/doc/elt ( popup -- loc doc elt )
114 [ interactor>> [ editor-caret ] [ model>> ] bi ]
115 [ completion-mode>> completion-element ]
118 GENERIC: completion-string ( object -- string )
120 M: object completion-string present ;
122 : method-completion-string ( word -- string )
123 "method-generic" word-prop present ;
125 M: method completion-string method-completion-string ;
127 GENERIC# accept-completion-hook 1 ( item popup -- )
129 : insert-completion ( item popup -- )
130 [ completion-string ] [ completion-loc/doc/elt ] bi* set-elt-string ;
132 : accept-completion ( item table -- )
133 find-completion-popup
134 [ insert-completion ]
135 [ accept-completion-hook ]
139 : <completion-table> ( interactor completion-mode -- table )
140 [ completion-element ] [ completion-quot ] [ nip ] 2tri
141 [ <completion-model> ] dip <table>
142 monospace-font >>font
143 t >>selection-required?
148 dup '[ _ accept-completion ] >>action ;
150 : <completion-scroller> ( completion-popup -- scroller )
151 table>> <scroller> COLOR: white <solid> >>interior ;
153 : <completion-popup> ( interactor completion-mode -- popup )
154 [ vertical completion-popup new-track ] 2dip
155 [ [ >>interactor ] [ >>completion-mode ] bi* ] [ <completion-table> >>table ] 2bi
156 dup [ <completion-scroller> ] [ completion-mode>> completion-banner ] bi
157 completion-color <framed-labeled> 1 track-add ;
160 { T{ key-down f f "TAB" } [ table>> row-action ] }
161 { T{ key-down f f " " } [ table>> row-action ] }
164 : show-completion-popup ( interactor mode -- )
165 [ completion-element ] [ <completion-popup> ] 2bi
166 show-listener-popup ;
168 : code-completion-popup ( interactor -- )
169 dup completion-mode show-completion-popup ;
171 : history-completion-popup ( interactor -- )
172 history-completion show-completion-popup ;
174 : recall-previous ( interactor -- )
175 history>> history-recall-previous ;
177 : recall-next ( interactor -- )
178 history>> history-recall-next ;
180 : completion-gesture ( gesture completion -- value/f operation/f )
182 [ [ nip ] [ gesture>operation ] 2bi ] [ drop f ] if ;
184 M: completion-popup handle-gesture ( gesture completion -- ? )
185 2dup completion-gesture dup [
186 [ nip hide-glass ] [ invoke-command ] 2bi* f
187 ] [ 2drop call-next-method ] if ;