src/Pure/Isar/completion.scala
author wenzelm
Fri, 30 Aug 2013 23:38:18 +0200
changeset 53337 b3817a0e3211
parent 53325 ffabc0083786
child 55492 28d4db6c6e79
permissions -rw-r--r--
sort items according to persistent history of frequency of use;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
53279
763d35697338 clarified module location;
wenzelm
parents: 53275
diff changeset
     1
/*  Title:      Pure/Isar/completion.scala
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
     3
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
     4
Completion of symbols and keywords.
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
     5
*/
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
     6
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
     7
package isabelle
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
     8
53337
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
     9
import scala.collection.immutable.SortedMap
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
    10
import scala.util.parsing.combinator.RegexParsers
53337
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    11
import scala.math.Ordering
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
    12
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
    13
46624
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
    14
object Completion
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
    15
{
53325
ffabc0083786 more explicit indication of unique result (see also 45be26b98ca6, 3d654643cf56);
wenzelm
parents: 53324
diff changeset
    16
  /* result */
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
    17
53296
65c60c782da5 less aggressive immediate completion, based on input and text;
wenzelm
parents: 53295
diff changeset
    18
  sealed case class Item(
65c60c782da5 less aggressive immediate completion, based on input and text;
wenzelm
parents: 53295
diff changeset
    19
    original: String,
65c60c782da5 less aggressive immediate completion, based on input and text;
wenzelm
parents: 53295
diff changeset
    20
    replacement: String,
65c60c782da5 less aggressive immediate completion, based on input and text;
wenzelm
parents: 53295
diff changeset
    21
    description: String,
65c60c782da5 less aggressive immediate completion, based on input and text;
wenzelm
parents: 53295
diff changeset
    22
    immediate: Boolean)
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
    23
  { override def toString: String = description }
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
    24
53325
ffabc0083786 more explicit indication of unique result (see also 45be26b98ca6, 3d654643cf56);
wenzelm
parents: 53324
diff changeset
    25
  sealed case class Result(original: String, unique: Boolean, items: List[Item])
ffabc0083786 more explicit indication of unique result (see also 45be26b98ca6, 3d654643cf56);
wenzelm
parents: 53324
diff changeset
    26
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
    27
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
    28
  /* init */
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
    29
46625
wenzelm
parents: 46624
diff changeset
    30
  val empty: Completion = new Completion()
46624
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
    31
  def init(): Completion = empty.add_symbols()
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
    32
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
    33
53337
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    34
  /** persistent history **/
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    35
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    36
  private val COMPLETION_HISTORY = Path.explode("$ISABELLE_HOME_USER/etc/completion_history")
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    37
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    38
  object History
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    39
  {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    40
    val empty: History = new History()
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    41
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    42
    def load(): History =
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    43
    {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    44
      def ignore_error(msg: String): Unit =
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    45
        java.lang.System.err.println("### Ignoring bad content of file " + COMPLETION_HISTORY +
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    46
          (if (msg == "") "" else "\n" + msg))
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    47
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    48
      val content =
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    49
        if (COMPLETION_HISTORY.is_file) {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    50
          try {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    51
            import XML.Decode._
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    52
            list(pair(Symbol.decode_string, int))(
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    53
              YXML.parse_body(File.read(COMPLETION_HISTORY)))
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    54
          }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    55
          catch {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    56
            case ERROR(msg) => ignore_error(msg); Nil
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    57
            case _: XML.Error => ignore_error(""); Nil
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    58
          }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    59
        }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    60
        else Nil
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    61
      (empty /: content)(_ + _)
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    62
    }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    63
  }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    64
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    65
  final class History private(rep: SortedMap[String, Int] = SortedMap.empty)
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    66
  {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    67
    override def toString: String = rep.mkString("Completion.History(", ",", ")")
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    68
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    69
    def frequency(name: String): Int = rep.getOrElse(name, 0)
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    70
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    71
    def + (entry: (String, Int)): History =
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    72
    {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    73
      val (name, freq) = entry
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    74
      new History(rep + (name -> (frequency(name) + freq)))
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    75
    }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    76
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    77
    def ordering: Ordering[Item] =
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    78
      new Ordering[Item] {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    79
        def compare(item1: Item, item2: Item): Int =
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    80
        {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    81
          frequency(item1.replacement) compare frequency(item2.replacement) match {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    82
            case 0 => item1.replacement compare item2.replacement
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    83
            case ord => - ord
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    84
          }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    85
        }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    86
      }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    87
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    88
    def save()
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    89
    {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    90
      Isabelle_System.mkdirs(COMPLETION_HISTORY.dir)
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    91
      File.write_backup(COMPLETION_HISTORY,
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    92
        {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    93
          import XML.Encode._
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    94
          YXML.string_of_body(list(pair(Symbol.encode_string, int))(rep.toList))
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    95
        })
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    96
    }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    97
  }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    98
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
    99
  class History_Variable
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   100
  {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   101
    private var history = History.empty
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   102
    def value: History = synchronized { history }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   103
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   104
    def load()
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   105
    {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   106
      val h = History.load()
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   107
      synchronized { history = h }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   108
    }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   109
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   110
    def update(item: Item, freq: Int = 1): Unit = synchronized {
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   111
      history = history + (item.replacement -> freq)
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   112
    }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   113
  }
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   114
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   115
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   116
  /** word completion **/
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   117
46624
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   118
  private val word_regex = "[a-zA-Z0-9_']+".r
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   119
  private def is_word(s: CharSequence): Boolean = word_regex.pattern.matcher(s).matches
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   120
46624
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   121
  private object Parse extends RegexParsers
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   122
  {
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   123
    override val whiteSpace = "".r
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   124
43462
7f65a68f8b26 completion for control symbols;
wenzelm
parents: 40533
diff changeset
   125
    def reverse_symbol: Parser[String] = """>[A-Za-z0-9_']+\^?<\\""".r
7f65a68f8b26 completion for control symbols;
wenzelm
parents: 40533
diff changeset
   126
    def reverse_symb: Parser[String] = """[A-Za-z0-9_']{2,}\^?<\\""".r
53251
7facc08da806 complete symbols only in backslash forms -- less intrusive editing, greater chance of finding escape sequence in text;
wenzelm
parents: 46712
diff changeset
   127
    def escape: Parser[String] = """[a-zA-Z0-9_']+\\""".r
53322
a4cd032172e0 allow short words for explicit completion;
wenzelm
parents: 53318
diff changeset
   128
    def word: Parser[String] = word_regex
a4cd032172e0 allow short words for explicit completion;
wenzelm
parents: 53318
diff changeset
   129
    def word3: Parser[String] = """[a-zA-Z0-9_']{3,}""".r
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   130
53322
a4cd032172e0 allow short words for explicit completion;
wenzelm
parents: 53318
diff changeset
   131
    def read(explicit: Boolean, in: CharSequence): Option[String] =
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   132
    {
53322
a4cd032172e0 allow short words for explicit completion;
wenzelm
parents: 53318
diff changeset
   133
      val parse_word = if (explicit) word else word3
37072
9105c8237c7a renamed "rev" to "reverse" following usual Scala conventions;
wenzelm
parents: 36012
diff changeset
   134
      val reverse_in = new Library.Reverse(in)
53322
a4cd032172e0 allow short words for explicit completion;
wenzelm
parents: 53318
diff changeset
   135
      parse((reverse_symbol | reverse_symb | escape | parse_word) ^^ (_.reverse), reverse_in) match {
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   136
        case Success(result, _) => Some(result)
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   137
        case _ => None
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   138
      }
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   139
    }
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   140
  }
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   141
}
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   142
46712
8650d9a95736 prefer final ADTs -- prevent ooddities;
wenzelm
parents: 46625
diff changeset
   143
final class Completion private(
46625
wenzelm
parents: 46624
diff changeset
   144
  words_lex: Scan.Lexicon = Scan.Lexicon.empty,
53318
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   145
  words_map: Multi_Map[String, String] = Multi_Map.empty,
46625
wenzelm
parents: 46624
diff changeset
   146
  abbrevs_lex: Scan.Lexicon = Scan.Lexicon.empty,
53318
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   147
  abbrevs_map: Multi_Map[String, (String, String)] = Multi_Map.empty)
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   148
{
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   149
  /* adding stuff */
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   150
40533
e38e80686ce5 somewhat adhoc replacement for 'thus' and 'hence';
wenzelm
parents: 37072
diff changeset
   151
  def + (keyword: String, replace: String): Completion =
46624
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   152
    new Completion(
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   153
      words_lex + keyword,
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   154
      words_map + (keyword -> replace),
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   155
      abbrevs_lex,
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   156
      abbrevs_map)
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   157
40533
e38e80686ce5 somewhat adhoc replacement for 'thus' and 'hence';
wenzelm
parents: 37072
diff changeset
   158
  def + (keyword: String): Completion = this + (keyword, keyword)
e38e80686ce5 somewhat adhoc replacement for 'thus' and 'hence';
wenzelm
parents: 37072
diff changeset
   159
46624
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   160
  private def add_symbols(): Completion =
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   161
  {
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   162
    val words =
43695
5130dfe1b7be simplified Symbol based on lazy Symbol.Interpretation -- reduced odd "functorial style";
wenzelm
parents: 43462
diff changeset
   163
      (for ((x, _) <- Symbol.names) yield (x, x)).toList :::
53251
7facc08da806 complete symbols only in backslash forms -- less intrusive editing, greater chance of finding escape sequence in text;
wenzelm
parents: 46712
diff changeset
   164
      (for ((x, y) <- Symbol.names) yield ("\\" + y, x)).toList :::
53316
c3e549e0d3c7 allow multiple symbol properties, notably groups and abbrevs;
wenzelm
parents: 53313
diff changeset
   165
      (for ((x, y) <- Symbol.abbrevs.iterator if Completion.is_word(y)) yield (y, x)).toList
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   166
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   167
    val abbrs =
53316
c3e549e0d3c7 allow multiple symbol properties, notably groups and abbrevs;
wenzelm
parents: 53313
diff changeset
   168
      (for ((x, y) <- Symbol.abbrevs.iterator if !Completion.is_word(y))
31765
a5fdf7a76f9d tuned input: require longer symbol prefix;
wenzelm
parents: 31763
diff changeset
   169
        yield (y.reverse.toString, (y, x))).toList
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   170
46624
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   171
    new Completion(
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   172
      words_lex ++ words.map(_._1),
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   173
      words_map ++ words,
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   174
      abbrevs_lex ++ abbrs.map(_._1),
dc4c72092088 streamlined abstract datatype;
wenzelm
parents: 45900
diff changeset
   175
      abbrevs_map ++ abbrs)
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   176
  }
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   177
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   178
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   179
  /* complete */
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   180
53337
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   181
  def complete(
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   182
    history: Completion.History,
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   183
    decode: Boolean,
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   184
    explicit: Boolean,
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   185
    line: CharSequence): Option[Completion.Result] =
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   186
  {
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   187
    val raw_result =
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   188
      abbrevs_lex.parse(abbrevs_lex.keyword, new Library.Reverse(line)) match {
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   189
        case abbrevs_lex.Success(reverse_a, _) =>
53318
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   190
          val abbrevs = abbrevs_map.get_list(reverse_a)
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   191
          abbrevs match {
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   192
            case Nil => None
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   193
            case (a, _) :: _ => Some((a, abbrevs.map(_._2)))
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   194
          }
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   195
        case _ =>
53322
a4cd032172e0 allow short words for explicit completion;
wenzelm
parents: 53318
diff changeset
   196
          Completion.Parse.read(explicit, line) match {
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   197
            case Some(word) =>
53318
ec4511548304 allow multiple entries;
wenzelm
parents: 53316
diff changeset
   198
              words_lex.completions(word).map(words_map.get_list(_)).flatten match {
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   199
                case Nil => None
53337
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   200
                case cs => Some(word, cs)
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   201
              }
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   202
            case None => None
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   203
          }
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   204
      }
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   205
    raw_result match {
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   206
      case Some((word, cs)) =>
53337
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   207
        val ds =
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   208
          (if (decode) cs.map(Symbol.decode(_)) else cs).filter(_ != word)
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   209
        if (ds.isEmpty) None
53296
65c60c782da5 less aggressive immediate completion, based on input and text;
wenzelm
parents: 53295
diff changeset
   210
        else {
53313
2e745fc40416 less surprising immediate completion;
wenzelm
parents: 53296
diff changeset
   211
          val immediate =
2e745fc40416 less surprising immediate completion;
wenzelm
parents: 53296
diff changeset
   212
            !Completion.is_word(word) &&
2e745fc40416 less surprising immediate completion;
wenzelm
parents: 53296
diff changeset
   213
            Character.codePointCount(word, 0, word.length) > 1
53325
ffabc0083786 more explicit indication of unique result (see also 45be26b98ca6, 3d654643cf56);
wenzelm
parents: 53324
diff changeset
   214
          val items = ds.map(s => Completion.Item(word, s, s, explicit || immediate))
53337
b3817a0e3211 sort items according to persistent history of frequency of use;
wenzelm
parents: 53325
diff changeset
   215
          Some(Completion.Result(word, cs.length == 1, items.sorted(history.ordering)))
53296
65c60c782da5 less aggressive immediate completion, based on input and text;
wenzelm
parents: 53295
diff changeset
   216
        }
53275
b34aac6511ab tuned signature;
wenzelm
parents: 53251
diff changeset
   217
      case None => None
31765
a5fdf7a76f9d tuned input: require longer symbol prefix;
wenzelm
parents: 31763
diff changeset
   218
    }
31763
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   219
  }
c2c2d380729d Completion of symbols and keywords.
wenzelm
parents:
diff changeset
   220
}