wenzelm@31775: /* Title: Pure/Thy/completion.scala wenzelm@31775: Author: Makarius wenzelm@31775: wenzelm@31775: Completion of symbols and keywords. wenzelm@31775: */ wenzelm@31775: wenzelm@31775: package isabelle wenzelm@31775: wenzelm@31775: import scala.util.matching.Regex wenzelm@31775: import scala.util.parsing.combinator.RegexParsers wenzelm@31775: wenzelm@31775: wenzelm@31775: private object Completion wenzelm@31775: { wenzelm@31775: /** word completion **/ wenzelm@31775: wenzelm@31775: val word_regex = "[a-zA-Z0-9_']+".r wenzelm@31775: def is_word(s: CharSequence): Boolean = word_regex.pattern.matcher(s).matches wenzelm@31775: wenzelm@31775: object Parse extends RegexParsers wenzelm@31775: { wenzelm@31775: override val whiteSpace = "".r wenzelm@31775: wenzelm@44337: def reverse_symbol: Parser[String] = """>[A-Za-z0-9_']+\^?<\\""".r wenzelm@44337: def reverse_symb: Parser[String] = """[A-Za-z0-9_']{2,}\^?<\\""".r wenzelm@40779: def word: Parser[String] = "[a-zA-Z0-9_']{2,}".r wenzelm@31775: wenzelm@31775: def read(in: CharSequence): Option[String] = wenzelm@31775: { wenzelm@37112: val reverse_in = new Library.Reverse(in) wenzelm@37112: parse((reverse_symbol | reverse_symb | word) ^^ (_.reverse), reverse_in) match { wenzelm@31775: case Success(result, _) => Some(result) wenzelm@31775: case _ => None wenzelm@31775: } wenzelm@31775: } wenzelm@31775: } wenzelm@31775: } wenzelm@31775: wenzelm@31775: class Completion wenzelm@31775: { wenzelm@31775: /* representation */ wenzelm@31775: wenzelm@31780: protected val words_lex = Scan.Lexicon() wenzelm@31780: protected val words_map = Map[String, String]() wenzelm@31775: wenzelm@31780: protected val abbrevs_lex = Scan.Lexicon() wenzelm@31780: protected val abbrevs_map = Map[String, (String, String)]() wenzelm@31775: wenzelm@31775: wenzelm@31775: /* adding stuff */ wenzelm@31775: wenzelm@40779: def + (keyword: String, replace: String): Completion = wenzelm@31775: { wenzelm@31775: val old = this wenzelm@31775: new Completion { wenzelm@31775: override val words_lex = old.words_lex + keyword wenzelm@40779: override val words_map = old.words_map + (keyword -> replace) wenzelm@31775: override val abbrevs_lex = old.abbrevs_lex wenzelm@31775: override val abbrevs_map = old.abbrevs_map wenzelm@31775: } wenzelm@31775: } wenzelm@31775: wenzelm@40779: def + (keyword: String): Completion = this + (keyword, keyword) wenzelm@40779: wenzelm@44569: def add_symbols: Completion = wenzelm@31775: { wenzelm@31775: val words = wenzelm@44569: (for ((x, _) <- Symbol.names) yield (x, x)).toList ::: wenzelm@44569: (for ((x, y) <- Symbol.names) yield (y, x)).toList ::: wenzelm@44569: (for ((x, y) <- Symbol.abbrevs if Completion.is_word(y)) yield (y, x)).toList wenzelm@31775: wenzelm@31775: val abbrs = wenzelm@44569: (for ((x, y) <- Symbol.abbrevs if !Completion.is_word(y)) wenzelm@31777: yield (y.reverse.toString, (y, x))).toList wenzelm@31775: wenzelm@31775: val old = this wenzelm@31775: new Completion { wenzelm@31775: override val words_lex = old.words_lex ++ words.map(_._1) wenzelm@31777: override val words_map = old.words_map ++ words wenzelm@31775: override val abbrevs_lex = old.abbrevs_lex ++ abbrs.map(_._1) wenzelm@31775: override val abbrevs_map = old.abbrevs_map ++ abbrs wenzelm@31775: } wenzelm@31775: } wenzelm@31775: wenzelm@31775: wenzelm@31775: /* complete */ wenzelm@31775: wenzelm@31777: def complete(line: CharSequence): Option[(String, List[String])] = wenzelm@31775: { wenzelm@34150: abbrevs_lex.parse(abbrevs_lex.keyword, new Library.Reverse(line)) match { wenzelm@37112: case abbrevs_lex.Success(reverse_a, _) => wenzelm@37112: val (word, c) = abbrevs_map(reverse_a) wenzelm@35004: Some(word, List(c)) wenzelm@31777: case _ => wenzelm@31777: Completion.Parse.read(line) match { wenzelm@31777: case Some(word) => wenzelm@35004: words_lex.completions(word).map(words_map(_)) match { wenzelm@31777: case Nil => None wenzelm@36036: case cs => Some(word, cs.sortWith(_ < _)) wenzelm@31777: } wenzelm@31777: case None => None wenzelm@31777: } wenzelm@31777: } wenzelm@31775: } wenzelm@31775: }