# jedit_checkpoint.tcl - undo and redo support for jedit
#
######################################################################
# Copyright 1992-1995 by Jay Sekora.  This file may be freely        #
# distributed, modified or unmodified, for any purpose, provided     #
# that this copyright notice is retained verbatim in all copies and  #
# no attempt is made to obscure the authorship of this file.  If you #
# distribute any modified versions, I ask, but do not require, that  #
# you clearly mark any changes you make as such and that you provide #
# your users with instructions for getting the original sources.     #
######################################################################

j:ldb:set_defaults {
  {undo:not_on {You aren't saving any undo information.}}
  {undo:no_more_undo {No more undo information available.}}
  {undo:no_more_redo {No more redo information available.}}
}

######################################################################
# save current state in undo ring
#   { t args } lets it be used with j:tkb:mkmap
######################################################################

proc jedit:save_checkpoint { t args } {
  global CKPT_TEXT CKPT_ANNO JEDIT_PREFS UNDOPTR

  if $JEDIT_PREFS(undolevels) {
    set CKPT_TEXT($UNDOPTR) [$t get 1.0 end]
    set CKPT_ANNO($UNDOPTR) [j:tag:get_annotation $t]
    incr UNDOPTR
    set old [expr {$UNDOPTR - $JEDIT_PREFS(undolevels)}]
    catch {
      unset CKPT_TEXT($old)			;# forget a previous checkpoint
      unset CKPT_ANNO($old)
    }
  }
}


######################################################################
# save current state in undo ring
#   { t args } lets it be used with j:tkb:mkmap
#   unlike jedit:checkpoint, this complains if undo is not on.
######################################################################

j:command:register jedit:cmd:save_checkpoint {Checkpoint}
proc jedit:cmd:save_checkpoint { t args } {
  global JEDIT_PREFS

  if $JEDIT_PREFS(undolevels) {
    jedit:save_checkpoint $t
  } else {
    j:alert -text undo:not_on
  }
}

######################################################################
# jedit:cmd:undo - restore from saved state (moving backwards in undo ring)
#   { t args } lets it be used with j:tkb:mkmap
######################################################################

j:command:register jedit:cmd:undo {Undo}
proc jedit:cmd:undo { t args } {
  global CKPT_TEXT CKPT_ANNO JEDIT_PREFS UNDOPTR

  if $JEDIT_PREFS(undolevels) {
    set CKPT_TEXT($UNDOPTR) [$t get 1.0 end]
    set CKPT_ANNO($UNDOPTR) [j:tag:get_annotation $t]
    incr UNDOPTR -1
    if {![info exists CKPT_TEXT($UNDOPTR)]} {
      incr UNDOPTR
      j:alert -text undo:no_more_undo
    }
    $t delete 1.0 end
    $t insert end $CKPT_TEXT($UNDOPTR)
    j:tag:set_annotation $t $CKPT_ANNO($UNDOPTR)
    $t yview -pickplace insert
  } else {
    j:alert -text undo:not_on
  }
}

######################################################################
# restore from saved state (moving forwards in undo ring)
#   { t args } lets it be used with j:tkb:mkmap
######################################################################

j:command:register jedit:cmd:redo {Redo}
proc jedit:cmd:redo { t args } {
  global CKPT_TEXT CKPT_ANNO JEDIT_PREFS UNDOPTR

  if $JEDIT_PREFS(undolevels) {
    set CKPT_TEXT($UNDOPTR) [$t get 1.0 end]
    set CKPT_ANNO($UNDOPTR) [j:tag:get_annotation $t]
    incr UNDOPTR
    if {![info exists CKPT_TEXT($UNDOPTR)]} {
      incr UNDOPTR -1
      j:alert -text undo:no_more_redo
    }
    $t delete 1.0 end
    $t insert end $CKPT_TEXT($UNDOPTR)
    j:tag:set_annotation $t $CKPT_ANNO($UNDOPTR)
    $t yview -pickplace insert
  } else {
    j:alert -text undo:not_on
  }
}
