1 ! Copyright (C) 2005, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs colors.constants combinators
4 combinators.short-circuit fry io.directories io.files
5 io.files.info io.pathnames kernel locals make math math.order
6 sequences sequences.private sorting splitting typed
7 unicode.categories unicode.data vectors vocabs vocabs.hierarchy
14 : smart-index-from ( obj i seq -- n/f )
15 rot [ ch>lower ] [ ch>upper ] bi
16 '[ dup _ eq? [ drop t ] [ _ eq? ] if ] find-from drop ;
18 :: (fuzzy) ( accum i full ch -- accum i ? )
19 ch i full smart-index-from [
21 [ accum swap 1 + t ] bi
28 : fuzzy ( full short -- indices )
29 dup [ length <vector> 0 ] curry 2dip
30 [ (fuzzy) ] with all? 2drop ;
34 : (runs) ( runs n seq -- runs n )
38 [ drop ] [ nip V{ } clone pick push ] if
45 : runs ( seq -- newseq )
46 [ V{ } clone 1vector ] dip [ first ] keep (runs) drop ;
50 : score-1 ( i full -- n )
52 { [ over zero? ] [ 2drop 10 ] }
53 { [ 2dup length 1 - number= ] [ 2drop 4 ] }
54 { [ 2dup [ 1 - ] dip nth-unsafe Letter? not ] [ 2drop 10 ] }
55 { [ 2dup [ 1 + ] dip nth-unsafe Letter? not ] [ 2drop 4 ] }
61 : score ( full fuzzy -- n )
63 [ [ length ] bi@ - 15 swap [-] 3 /f ] 2keep
65 [ 0 [ pick score-1 max ] reduce nip ] keep
72 : rank-completions ( results -- newresults )
74 [ 0 [ first max ] reduce 3 /f ] keep
75 [ first-unsafe < ] with filter
78 : complete ( full short -- score )
79 [ dupd fuzzy score ] 2keep
81 dupd fuzzy score max ;
83 : completion ( short candidate -- result )
84 [ second swap complete ] keep 2array ; inline
86 : completion, ( short candidate -- )
87 completion dup first-unsafe 0 > [ , ] [ drop ] if ;
89 : completions ( short candidates -- seq )
91 [ [ completion, ] with each ] { } make
95 : name-completions ( str seq -- seq' )
96 [ dup name>> ] { } map>assoc completions ;
98 : words-matching ( str -- seq )
99 all-words name-completions ;
101 : vocabs-matching ( str -- seq )
102 all-disk-vocabs-recursive filter-vocabs name-completions ;
104 : chars-matching ( str -- seq )
105 name-map keys dup zip completions ;
107 : colors-matching ( str -- seq )
108 named-colors dup zip completions ;
110 : strings-matching ( str seq -- seq' )
111 dup zip completions keys ;
115 : directory-paths ( directory -- alist )
118 [ dup _ prepend-path ]
119 [ file-info directory? [ path-separator append ] when ]
122 ] with-directory-files ;
126 : paths-matching ( str -- seq )
127 dup last-path-separator [ 1 + cut ] [ drop "" ] if swap
128 dup { [ exists? ] [ file-info directory? ] } 1&&
129 [ directory-paths completions ] [ 2drop { } ] if ;
133 : (complete-single-vocab?) ( str -- ? )
134 { "IN:" "USE:" "UNUSE:" "QUALIFIED:" "QUALIFIED-WITH:" }
137 : complete-single-vocab? ( tokens -- ? )
139 harvest ?last (complete-single-vocab?)
141 harvest dup length 1 >
142 [ 2 tail* ?first (complete-single-vocab?) ] [ drop f ] if
145 : chop-; ( seq -- seq' )
146 { ";" } split1-last [ ] [ ] ?if ;
148 : complete-vocab-list? ( tokens -- ? )
149 chop-; 1 short head* "USING:" swap member? ;
153 : complete-vocab? ( tokens -- ? )
154 { [ complete-single-vocab? ] [ complete-vocab-list? ] } 1|| ;
158 : complete-token? ( tokens token -- ? )
160 [ harvest ?last ] [ = ] bi*
162 swap harvest dup length 1 >
163 [ 2 tail* ?first = ] [ 2drop f ] if
168 : complete-char? ( tokens -- ? ) "CHAR:" complete-token? ;
170 : complete-color? ( tokens -- ? ) "COLOR:" complete-token? ;
172 : complete-pathname? ( tokens -- ? ) "P\"" complete-token? ;