255 private val default_abbrs = |
255 private val default_abbrs = |
256 Map("@{" -> "@{\007}", "`" -> "\\<open>\007\\<close>") |
256 Map("@{" -> "@{\007}", "`" -> "\\<open>\007\\<close>") |
257 } |
257 } |
258 |
258 |
259 final class Completion private( |
259 final class Completion private( |
260 keywords: Set[String] = Set.empty, |
260 keywords: Map[String, Boolean] = Map.empty, |
261 words_lex: Scan.Lexicon = Scan.Lexicon.empty, |
261 words_lex: Scan.Lexicon = Scan.Lexicon.empty, |
262 words_map: Multi_Map[String, String] = Multi_Map.empty, |
262 words_map: Multi_Map[String, String] = Multi_Map.empty, |
263 abbrevs_lex: Scan.Lexicon = Scan.Lexicon.empty, |
263 abbrevs_lex: Scan.Lexicon = Scan.Lexicon.empty, |
264 abbrevs_map: Multi_Map[String, (String, String)] = Multi_Map.empty) |
264 abbrevs_map: Multi_Map[String, (String, String)] = Multi_Map.empty) |
265 { |
265 { |
266 /* keywords */ |
266 /* keywords */ |
267 |
267 |
268 def + (keyword: String, replace: String): Completion = |
268 def is_keyword(name: String): Boolean = keywords.isDefinedAt(name) |
|
269 def is_keyword_template(name: String): Boolean = keywords.get(name) == Some(true) |
|
270 |
|
271 def + (keyword: String, template: String): Completion = |
269 new Completion( |
272 new Completion( |
270 keywords + keyword, |
273 keywords + (keyword -> (keyword != template)), |
271 words_lex + keyword, |
274 words_lex + keyword, |
272 words_map + (keyword -> replace), |
275 words_map + (keyword -> template), |
273 abbrevs_lex, |
276 abbrevs_lex, |
274 abbrevs_map) |
277 abbrevs_map) |
275 |
278 |
276 def + (keyword: String): Completion = this + (keyword, keyword) |
279 def + (keyword: String): Completion = this + (keyword, keyword) |
277 |
280 |
352 }) match { |
355 }) match { |
353 case Some(word) => |
356 case Some(word) => |
354 val completions = |
357 val completions = |
355 for { |
358 for { |
356 s <- words_lex.completions(word) |
359 s <- words_lex.completions(word) |
357 if (if (keywords(s)) language_context.is_outer else language_context.symbols) |
360 if (if (is_keyword(s)) language_context.is_outer else language_context.symbols) |
358 r <- words_map.get_list(s) |
361 r <- words_map.get_list(s) |
359 } yield r |
362 } yield r |
360 if (completions.isEmpty) None |
363 if (completions.isEmpty) None |
361 else Some(((word, completions), end)) |
364 else Some(((word, completions), end)) |
362 case None => None |
365 case None => None |
382 case List(s1, s2) => (s1, s2) |
385 case List(s1, s2) => (s1, s2) |
383 case _ => (name1, "") |
386 case _ => (name1, "") |
384 } |
387 } |
385 move = - s2.length |
388 move = - s2.length |
386 description = |
389 description = |
387 if (move != 0) List(name1, "(template)") |
390 if (Symbol.names.isDefinedAt(name0)) { |
388 else if (words_result.isDefined && keywords(name0)) List(name1, "(keyword)") |
391 if (name0 == name1) List(name0) |
389 else if (Symbol.names.isDefinedAt(name0) && name0 != name1) |
392 else List(name1, "(symbol " + quote(name0) + ")") |
390 List(name1, "(symbol " + quote(name0) + ")") |
393 } |
|
394 else if (move != 0 || is_keyword_template(name0)) |
|
395 List(name1, "(template)") |
|
396 else if (is_keyword(name0)) |
|
397 List(name1, "(keyword)") |
391 else List(name1) |
398 else List(name1) |
392 } |
399 } |
393 yield Completion.Item(range, original, name1, description, s1 + s2, move, immediate) |
400 yield Completion.Item(range, original, name1, description, s1 + s2, move, immediate) |
394 Some(Completion.Result(range, original, unique, items.sorted(history.ordering))) |
401 Some(Completion.Result(range, original, unique, items.sorted(history.ordering))) |
395 } |
402 } |