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 is_keyword(name: String): Boolean = keywords.isDefinedAt(name) |
268 private def is_keyword(name: String): Boolean = keywords.isDefinedAt(name) |
269 def is_keyword_template(name: String): Boolean = keywords.get(name) == Some(true) |
269 private def is_keyword_template(name: String): Boolean = keywords.get(name) == Some(true) |
270 |
270 |
271 def + (keyword: String, template: String): Completion = |
271 def + (keyword: String, template: String): Completion = |
272 new Completion( |
272 new Completion( |
273 keywords + (keyword -> (keyword != template)), |
273 keywords + (keyword -> (keyword != template)), |
274 words_lex + keyword, |
274 words_lex + keyword, |
278 |
278 |
279 def + (keyword: String): Completion = this + (keyword, keyword) |
279 def + (keyword: String): Completion = this + (keyword, keyword) |
280 |
280 |
281 |
281 |
282 /* symbols with abbreviations */ |
282 /* symbols with abbreviations */ |
|
283 |
|
284 private def is_symbol(name: String): Boolean = |
|
285 Symbol.names.isDefinedAt(name) |
283 |
286 |
284 private def add_symbols(): Completion = |
287 private def add_symbols(): Completion = |
285 { |
288 { |
286 val words = |
289 val words = |
287 (for ((x, _) <- Symbol.names.toList) yield (x, x)) ::: |
290 (for ((x, _) <- Symbol.names.toList) yield (x, x)) ::: |
367 } |
370 } |
368 |
371 |
369 (abbrevs_result orElse words_result) match { |
372 (abbrevs_result orElse words_result) match { |
370 case Some(((original, completions0), end)) => |
373 case Some(((original, completions0), end)) => |
371 val completions1 = completions0.map(decode(_)) |
374 val completions1 = completions0.map(decode(_)) |
372 if (completions1.exists(_ != original)) { |
375 |
373 val range = Text.Range(- original.length, 0) + end + start |
376 val range = Text.Range(- original.length, 0) + end + start |
374 val immediate = |
377 val immediate = |
375 explicit || |
378 explicit || |
376 (!Completion.Word_Parsers.is_word(original) && |
379 (!Completion.Word_Parsers.is_word(original) && |
377 Character.codePointCount(original, 0, original.length) > 1) |
380 Character.codePointCount(original, 0, original.length) > 1) |
378 val unique = completions0.length == 1 |
381 val unique = completions0.length == 1 |
379 val items = |
382 |
380 for { |
383 val items = |
381 (name0, name1) <- completions0 zip completions1 |
384 for { |
382 if name1 != original |
385 (name0, name1) <- completions0 zip completions1 |
383 (s1, s2) = |
386 if name1 != original |
384 space_explode(Completion.caret_indicator, name1) match { |
387 (s1, s2) = |
385 case List(s1, s2) => (s1, s2) |
388 space_explode(Completion.caret_indicator, name1) match { |
386 case _ => (name1, "") |
389 case List(s1, s2) => (s1, s2) |
387 } |
390 case _ => (name1, "") |
388 move = - s2.length |
391 } |
389 description = |
392 move = - s2.length |
390 if (Symbol.names.isDefinedAt(name0)) { |
393 description = |
391 if (name0 == name1) List(name0) |
394 if (is_symbol(name0)) { |
392 else List(name1, "(symbol " + quote(name0) + ")") |
395 if (name0 == name1) List(name0) |
393 } |
396 else List(name1, "(symbol " + quote(name0) + ")") |
394 else if (move != 0 || is_keyword_template(name0)) |
397 } |
395 List(name1, "(template)") |
398 else if (move != 0 || is_keyword_template(name0)) |
396 else if (is_keyword(name0)) |
399 List(name1, "(template)") |
397 List(name1, "(keyword)") |
400 else if (is_keyword(name0)) |
398 else List(name1) |
401 List(name1, "(keyword)") |
399 } |
402 else List(name1) |
400 yield Completion.Item(range, original, name1, description, s1 + s2, move, immediate) |
403 } |
401 Some(Completion.Result(range, original, unique, items.sorted(history.ordering))) |
404 yield Completion.Item(range, original, name1, description, s1 + s2, move, immediate) |
402 } |
405 |
403 else None |
406 if (items.isEmpty) None |
|
407 else Some(Completion.Result(range, original, unique, items.sorted(history.ordering))) |
|
408 |
404 case None => None |
409 case None => None |
405 } |
410 } |
406 } |
411 } |
407 } |
412 } |