1 /* Title: Pure/General/completion.scala |
1 /* Title: Pure/General/completion.scala |
2 Author: Makarius |
2 Author: Makarius |
3 |
3 |
4 Semantic completion within the formal context (reported names). |
4 Semantic completion within the formal context (reported names). |
5 Syntactic completion of keywords and symbols, with abbreviations |
5 Syntactic completion of keywords and symbols, with abbreviations |
6 (based on language context). */ |
6 (based on language context). |
|
7 */ |
7 |
8 |
8 package isabelle |
9 package isabelle |
9 |
10 |
10 |
11 |
11 import scala.collection.immutable.SortedMap |
12 import scala.collection.immutable.SortedMap |
344 if (abbrevs_result.isDefined) None |
345 if (abbrevs_result.isDefined) None |
345 else { |
346 else { |
346 val end = |
347 val end = |
347 if (extend_word) Completion.Word_Parsers.extend_word(text, caret) |
348 if (extend_word) Completion.Word_Parsers.extend_word(text, caret) |
348 else caret |
349 else caret |
349 (Completion.Word_Parsers.read_symbol(text.subSequence(0, end)) match { |
350 val opt_word = |
350 case Some(symbol) => Some(symbol) |
351 Completion.Word_Parsers.read_symbol(text.subSequence(0, end)) match { |
351 case None => |
352 case Some(symbol) => Some(symbol) |
352 val word_context = |
353 case None => |
353 end < length && Completion.Word_Parsers.is_word_char(text.charAt(end)) |
354 val word_context = |
354 if (word_context) None |
355 end < length && Completion.Word_Parsers.is_word_char(text.charAt(end)) |
355 else Completion.Word_Parsers.read_word(explicit, text.subSequence(0, end)) |
356 if (word_context) None |
356 }) match { |
357 else Completion.Word_Parsers.read_word(explicit, text.subSequence(0, end)) |
357 case Some(word) => |
358 } |
|
359 opt_word.map(word => |
|
360 { |
358 val completions = |
361 val completions = |
359 for { |
362 for { |
360 s <- words_lex.completions(word) |
363 s <- words_lex.completions(word) |
361 if (if (is_keyword(s)) language_context.is_outer else language_context.symbols) |
364 if (if (is_keyword(s)) language_context.is_outer else language_context.symbols) |
362 r <- words_map.get_list(s) |
365 r <- words_map.get_list(s) |
363 } yield r |
366 } yield r |
364 if (completions.isEmpty) None |
367 (((word, completions), end)) |
365 else Some(((word, completions), end)) |
368 }) |
366 case None => None |
|
367 } |
|
368 } |
369 } |
369 |
370 |
370 (abbrevs_result orElse words_result) match { |
371 (abbrevs_result orElse words_result) match { |
371 case Some(((original, completions0), end)) => |
372 case Some(((original, completions0), end)) if !completions0.isEmpty => |
372 val completions1 = completions0.map(decode(_)) |
|
373 |
|
374 val range = Text.Range(- original.length, 0) + end + start |
373 val range = Text.Range(- original.length, 0) + end + start |
375 val immediate = |
374 val immediate = |
376 explicit || |
375 explicit || |
377 (!Completion.Word_Parsers.is_word(original) && |
376 (!Completion.Word_Parsers.is_word(original) && |
378 Character.codePointCount(original, 0, original.length) > 1) |
377 Character.codePointCount(original, 0, original.length) > 1) |
379 val unique = completions0.length == 1 |
378 val unique = completions0.length == 1 |
380 |
379 |
|
380 val completions1 = completions0.map(decode(_)) |
381 val items = |
381 val items = |
382 for { |
382 for { |
383 (name0, name1) <- completions0 zip completions1 |
383 (name0, name1) <- completions0 zip completions1 |
384 if name1 != original |
384 if name1 != original |
385 (s1, s2) = |
385 (s1, s2) = |
402 yield Completion.Item(range, original, name1, description, s1 + s2, move, immediate) |
402 yield Completion.Item(range, original, name1, description, s1 + s2, move, immediate) |
403 |
403 |
404 if (items.isEmpty) None |
404 if (items.isEmpty) None |
405 else Some(Completion.Result(range, original, unique, items.sorted(history.ordering))) |
405 else Some(Completion.Result(range, original, unique, items.sorted(history.ordering))) |
406 |
406 |
407 case None => None |
407 case _ => None |
408 } |
408 } |
409 } |
409 } |
410 } |
410 } |