src/Pure/Thy/text_edit.scala
author wenzelm
Wed, 06 Jan 2010 23:18:44 +0100
changeset 34286 951aa92d06bb
parent 34276 12436485c244
child 34302 9bb71dfe7314
permissions -rw-r--r--
more text edit operations;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Thy/text_edit.scala
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     2
    Author:     Fabian Immler, TU Munich
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     3
    Author:     Makarius
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     4
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     5
Basic edits on plain text.
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     6
*/
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     7
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     8
package isabelle
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
     9
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    10
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    11
sealed abstract class Text_Edit
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    12
{
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    13
  val start: Int
34286
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    14
  def after(offset: Int): Int
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    15
  def before(offset: Int): Int
34286
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    16
  def edit(string: String, shift: Int): (Option[Text_Edit], String)
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    17
}
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    18
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    19
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    20
object Text_Edit
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    21
{
34286
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    22
  /* transform offsets */
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    23
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    24
  private def after_insert(start: Int, text: String, offset: Int): Int =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    25
    if (start <= offset) offset + text.length
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    26
    else offset
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    27
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    28
  private def after_remove(start: Int, text: String, offset: Int): Int =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    29
    if (start > offset) offset
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    30
    else (offset - text.length) max start
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    31
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    32
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    33
  /* edit strings */
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    34
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    35
  private def insert(index: Int, text: String, string: String): String =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    36
    string.substring(0, index) + text + string.substring(index)
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    37
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    38
  private def remove(index: Int, count: Int, string: String): String =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    39
    string.substring(0, index) + string.substring(index + count)
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    40
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    41
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    42
  /* explicit edits */
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    43
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    44
  case class Insert(start: Int, text: String) extends Text_Edit
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    45
  {
34286
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    46
    def after(offset: Int): Int = after_insert(start, text, offset)
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    47
    def before(offset: Int): Int = after_remove(start, text, offset)
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    48
34286
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    49
    def can_edit(string_length: Int, shift: Int): Boolean =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    50
      shift <= start && start <= shift + string_length
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    51
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    52
    def edit(string: String, shift: Int): (Option[Insert], String) =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    53
      if (can_edit(string.length, shift)) (None, insert(start - shift, text, string))
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    54
      else (Some(this), string)
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    55
  }
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    56
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    57
  case class Remove(start: Int, text: String) extends Text_Edit
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    58
  {
34286
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    59
    def after(offset: Int): Int = after_remove(start, text, offset)
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    60
    def before(offset: Int): Int = after_insert(start, text, offset)
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    61
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    62
    def can_edit(string_length: Int, shift: Int): Boolean =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    63
      shift <= start && start < shift + string_length
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    64
34286
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    65
    def edit(string: String, shift: Int): (Option[Remove], String) =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    66
      if (can_edit(string.length, shift)) {
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    67
        val index = start - shift
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    68
        val count = text.length min (string.length - index)
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    69
        val rest =
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    70
          if (count == text.length) None
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    71
          else Some(Remove(start, text.substring(count)))
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    72
        (rest, remove(index, count, string))
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    73
      }
951aa92d06bb more text edit operations;
wenzelm
parents: 34276
diff changeset
    74
      else (Some(this), string)
34276
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    75
  }
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    76
}
12436485c244 Basic edits on plain text.
wenzelm
parents:
diff changeset
    77