@@ -17,30 +17,20 @@ use syntect::highlighting::{Theme, ThemeSet};
1717use syntect:: parsing:: { SyntaxDefinition , SyntaxSet , SyntaxSetBuilder } ;
1818use syntect:: util:: LinesWithEndings ;
1919
20- static SQL_SYNTAX : & str = include_str ! ( "../../tools/sublime/SpaceTimeDbSQL.sublime-syntax" ) ;
21- static SYNTAX_NAME : & str = "SQL (SpaceTimeDb)" ;
22-
23- static AUTO_COMPLETE : & str = "\
24- true
25- false
26- select
27- from
28- insert
29- into
30- values
31- update,
32- delete,
33- create,
34- where
35- join
36- sort by
37- .exit
38- .clear
39- " ;
20+ const SQL_SYNTAX : & str = include_str ! ( "../../tools/sublime/SpaceTimeDbSQL.sublime-syntax" ) ;
21+ const SYNTAX_NAME : & str = "SQL (SpaceTimeDb)" ;
22+
23+ const AUTO_COMPLETE : & [ & str ] = & [
24+ "true" , "false" , "select" , "from" , "insert" , "into" , "values" , "update," , "delete," , "create," , "where" , "join" ,
25+ "sort by" , ".exit" , ".clear" ,
26+ ] ;
4027
4128pub async fn exec ( con : Connection ) -> Result < ( ) , anyhow:: Error > {
4229 let database = con. database . clone ( ) ;
43- let mut rl = Editor :: < ReplHelper , DefaultHistory > :: new ( ) . unwrap ( ) ;
30+ let rl_config = rustyline:: Config :: builder ( )
31+ . completion_type ( rustyline:: config:: CompletionType :: List )
32+ . build ( ) ;
33+ let mut rl = Editor :: < ReplHelper , DefaultHistory > :: with_config ( rl_config) ?;
4434 let history = home_dir ( ) . unwrap_or_else ( temp_dir) . join ( ".stdb.history.txt" ) ;
4535 if rl. load_history ( & history) . is_err ( ) {
4636 eprintln ! ( "No previous history." ) ;
@@ -121,33 +111,22 @@ impl ReplHelper {
121111impl Helper for ReplHelper { }
122112
123113impl Completer for ReplHelper {
124- type Candidate = String ;
114+ type Candidate = & ' static str ;
125115
126116 fn complete (
127117 & self ,
128118 line : & str ,
129119 pos : usize ,
130120 _: & rustyline:: Context < ' _ > ,
131121 ) -> rustyline:: Result < ( usize , Vec < Self :: Candidate > ) > {
132- let mut name = String :: new ( ) ;
133- let mut name_pos = pos;
134- while let Some ( char) = line
135- . chars ( )
136- . nth ( name_pos. wrapping_sub ( 1 ) )
137- . filter ( |c| c. is_ascii_alphanumeric ( ) || [ '_' , '.' ] . contains ( c) )
138- {
139- name. push ( char) ;
140- name_pos -= 1 ;
141- }
142- if name. is_empty ( ) {
143- return Ok ( ( 0 , vec ! [ ] ) ) ;
144- }
145- name = name. chars ( ) . rev ( ) . collect ( ) ;
122+ let ( name_pos, name) = rustyline:: completion:: extract_word ( line, pos, None , |c| {
123+ !( c. is_ascii_alphanumeric ( ) || matches ! ( c, '_' | '.' ) )
124+ } ) ;
146125
147- let mut completions: Vec < _ > = AUTO_COMPLETE . split ( '\n' ) . map ( str:: to_string) . collect ( ) ;
148- completions = completions
126+ let completions: Vec < _ > = AUTO_COMPLETE
149127 . iter ( )
150- . filter_map ( |it| it. starts_with ( & name) . then ( || it. clone ( ) ) )
128+ . copied ( )
129+ . filter ( |completion| completion. starts_with ( name) )
151130 . collect ( ) ;
152131
153132 Ok ( ( name_pos, completions) )
@@ -161,19 +140,11 @@ impl Hinter for ReplHelper {
161140 if line. len ( ) > pos {
162141 return None ;
163142 }
164- if let Ok ( ( mut completion_pos, completions) ) = self . complete ( line, pos, ctx) {
165- if completions. is_empty ( ) {
166- return None ;
167- }
168- let mut hint = completions[ 0 ] . clone ( ) ;
169- while completion_pos < pos {
170- if hint. is_empty ( ) {
171- return None ;
172- }
173- hint. remove ( 0 ) ;
174- completion_pos += 1 ;
143+ if let Ok ( ( completion_pos, completions) ) = self . complete ( line, pos, ctx) {
144+ match & completions[ ..] {
145+ [ completion] => Some ( completion[ pos - completion_pos..] . to_owned ( ) ) ,
146+ _ => None ,
175147 }
176- Some ( hint)
177148 } else {
178149 None
179150 }
0 commit comments