src/Pure/General/completion.scala
changeset 55992 1e7f04ba8196
parent 55986 61b0021ed674
child 55993 4c17e46c44c1
equal deleted inserted replaced
55991:3fa6e6c81788 55992:1e7f04ba8196
     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 }