src/Pure/Thy/completion.scala
changeset 34141 297b2149077d
parent 34135 63dd95e3b393
child 35004 b89a31957950
equal deleted inserted replaced
34140:31be1235d0fb 34141:297b2149077d
    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   }