more text edit operations;
authorwenzelm
Wed, 06 Jan 2010 23:18:44 +0100
changeset 34286951aa92d06bb
parent 34285 218fa4267718
child 34287 16496e04ca46
more text edit operations;
src/Pure/Thy/text_edit.scala
     1.1 --- a/src/Pure/Thy/text_edit.scala	Wed Jan 06 23:18:12 2010 +0100
     1.2 +++ b/src/Pure/Thy/text_edit.scala	Wed Jan 06 23:18:44 2010 +0100
     1.3 @@ -11,33 +11,67 @@
     1.4  sealed abstract class Text_Edit
     1.5  {
     1.6    val start: Int
     1.7 +  def after(offset: Int): Int
     1.8    def before(offset: Int): Int
     1.9 -  def after(offset: Int): Int
    1.10 +  def edit(string: String, shift: Int): (Option[Text_Edit], String)
    1.11  }
    1.12  
    1.13  
    1.14  object Text_Edit
    1.15  {
    1.16 +  /* transform offsets */
    1.17 +
    1.18 +  private def after_insert(start: Int, text: String, offset: Int): Int =
    1.19 +    if (start <= offset) offset + text.length
    1.20 +    else offset
    1.21 +
    1.22 +  private def after_remove(start: Int, text: String, offset: Int): Int =
    1.23 +    if (start > offset) offset
    1.24 +    else (offset - text.length) max start
    1.25 +
    1.26 +
    1.27 +  /* edit strings */
    1.28 +
    1.29 +  private def insert(index: Int, text: String, string: String): String =
    1.30 +    string.substring(0, index) + text + string.substring(index)
    1.31 +
    1.32 +  private def remove(index: Int, count: Int, string: String): String =
    1.33 +    string.substring(0, index) + string.substring(index + count)
    1.34 +
    1.35 +
    1.36 +  /* explicit edits */
    1.37 +
    1.38    case class Insert(start: Int, text: String) extends Text_Edit
    1.39    {
    1.40 -    def before(offset: Int): Int =
    1.41 -      if (start > offset) offset
    1.42 -      else (offset - text.length) max start
    1.43 +    def after(offset: Int): Int = after_insert(start, text, offset)
    1.44 +    def before(offset: Int): Int = after_remove(start, text, offset)
    1.45  
    1.46 -    def after(offset: Int): Int =
    1.47 -      if (start <= offset) offset + text.length
    1.48 -      else offset
    1.49 +    def can_edit(string_length: Int, shift: Int): Boolean =
    1.50 +      shift <= start && start <= shift + string_length
    1.51 +
    1.52 +    def edit(string: String, shift: Int): (Option[Insert], String) =
    1.53 +      if (can_edit(string.length, shift)) (None, insert(start - shift, text, string))
    1.54 +      else (Some(this), string)
    1.55    }
    1.56  
    1.57    case class Remove(start: Int, text: String) extends Text_Edit
    1.58    {
    1.59 -    def before(offset: Int): Int =
    1.60 -      if (start <= offset) offset + text.length
    1.61 -      else offset
    1.62 +    def after(offset: Int): Int = after_remove(start, text, offset)
    1.63 +    def before(offset: Int): Int = after_insert(start, text, offset)
    1.64  
    1.65 -    def after(offset: Int): Int =
    1.66 -      if (start > offset) offset
    1.67 -      else (offset - text.length) max start
    1.68 +    def can_edit(string_length: Int, shift: Int): Boolean =
    1.69 +      shift <= start && start < shift + string_length
    1.70 +
    1.71 +    def edit(string: String, shift: Int): (Option[Remove], String) =
    1.72 +      if (can_edit(string.length, shift)) {
    1.73 +        val index = start - shift
    1.74 +        val count = text.length min (string.length - index)
    1.75 +        val rest =
    1.76 +          if (count == text.length) None
    1.77 +          else Some(Remove(start, text.substring(count)))
    1.78 +        (rest, remove(index, count, string))
    1.79 +      }
    1.80 +      else (Some(this), string)
    1.81    }
    1.82  }
    1.83