10 import scala.util.parsing.combinator.RegexParsers |
10 import scala.util.parsing.combinator.RegexParsers |
11 |
11 |
12 |
12 |
13 private object Completion |
13 private object Completion |
14 { |
14 { |
15 /** String/CharSequence utilities */ |
|
16 |
|
17 def length_ord(s1: String, s2: String): Boolean = |
|
18 s1.length < s2.length || s1.length == s2.length && s1 <= s2 |
|
19 |
|
20 class Reverse(text: CharSequence, start: Int, end: Int) extends CharSequence |
|
21 { |
|
22 require(0 <= start && start <= end && end <= text.length) |
|
23 |
|
24 def this(text: CharSequence) = this(text, 0, text.length) |
|
25 |
|
26 def length: Int = end - start |
|
27 def charAt(i: Int): Char = text.charAt(end - i - 1) |
|
28 |
|
29 def subSequence(i: Int, j: Int): CharSequence = |
|
30 if (0 <= i && i <= j && j <= length) new Reverse(text, end - j, end - i) |
|
31 else throw new IndexOutOfBoundsException |
|
32 |
|
33 override def toString: String = |
|
34 { |
|
35 val buf = new StringBuilder(length) |
|
36 for (i <- 0 until length) |
|
37 buf.append(charAt(i)) |
|
38 buf.toString |
|
39 } |
|
40 } |
|
41 |
|
42 |
|
43 /** word completion **/ |
15 /** word completion **/ |
44 |
16 |
45 val word_regex = "[a-zA-Z0-9_']+".r |
17 val word_regex = "[a-zA-Z0-9_']+".r |
46 def is_word(s: CharSequence): Boolean = word_regex.pattern.matcher(s).matches |
18 def is_word(s: CharSequence): Boolean = word_regex.pattern.matcher(s).matches |
47 |
19 |
53 def rev_symb: Parser[String] = """[A-Za-z0-9_']{2,}<\\""".r |
25 def rev_symb: Parser[String] = """[A-Za-z0-9_']{2,}<\\""".r |
54 def word: Parser[String] = "[a-zA-Z0-9_']{3,}".r |
26 def word: Parser[String] = "[a-zA-Z0-9_']{3,}".r |
55 |
27 |
56 def read(in: CharSequence): Option[String] = |
28 def read(in: CharSequence): Option[String] = |
57 { |
29 { |
58 val rev_in = new Reverse(in) |
30 val rev_in = new Library.Reverse(in) |
59 parse((rev_symbol | rev_symb | word) ^^ (_.reverse), rev_in) match { |
31 parse((rev_symbol | rev_symb | word) ^^ (_.reverse), rev_in) match { |
60 case Success(result, _) => Some(result) |
32 case Success(result, _) => Some(result) |
61 case _ => None |
33 case _ => None |
62 } |
34 } |
63 } |
35 } |
111 |
83 |
112 /* complete */ |
84 /* complete */ |
113 |
85 |
114 def complete(line: CharSequence): Option[(String, List[String])] = |
86 def complete(line: CharSequence): Option[(String, List[String])] = |
115 { |
87 { |
116 abbrevs_lex.parse(abbrevs_lex.keyword, new Completion.Reverse(line)) match { |
88 abbrevs_lex.parse(abbrevs_lex.keyword, new Library.Reverse(line)) match { |
117 case abbrevs_lex.Success((rev_a, _), _) => |
89 case abbrevs_lex.Success(rev_a, _) => |
118 val (word, c) = abbrevs_map(rev_a) |
90 val (word, c) = abbrevs_map(rev_a) |
119 if (word == c) None |
91 if (word == c) None |
120 else Some(word, List(c)) |
92 else Some(word, List(c)) |
121 case _ => |
93 case _ => |
122 Completion.Parse.read(line) match { |
94 Completion.Parse.read(line) match { |
123 case Some(word) => |
95 case Some(word) => |
124 words_lex.completions(word).map(words_map(_)).filter(_ != word) match { |
96 words_lex.completions(word).map(words_map(_)).filter(_ != word) match { |
125 case Nil => None |
97 case Nil => None |
126 case cs => Some (word, cs.sort(Completion.length_ord _)) |
98 case cs => Some(word, cs.sort(_ < _)) |
127 } |
99 } |
128 case None => None |
100 case None => None |
129 } |
101 } |
130 } |
102 } |
131 } |
103 } |