# jedit_typing.tcl - special typing procedures for jedit, a tk-based editor
#
######################################################################
# 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.     #
######################################################################

# TO DO
#   abbrev fixes:
#     maybe some heuristics for things like plurals
#     maybe a syntax for suffixes (e.g., commit;t -> commitment)
#   problem with filename getting set when you cancel Save 
#     for the first time on a new unnamed file
#   gesture commands
#   autobreaking space a problem if you use two spaces betw sentences
#   word-end punctuation (and heuristics) sd be mode-specific
#
#   PROBLEM WITH CHANGING BINDINGS ON THE FLY!               (urgent)
######################################################################

######################################################################
# jedit:self_insert_punct - specialised version of j:tkb:self_insert
#   THERE SHOULD BE A GENERALISED MECHANISM FOR THIS!
######################################################################

proc jedit:self_insert_punct { W K A } {
  global j_teb

  if {"$A" != ""} {
    jedit:save_checkpoint $W
    jedit:sabbrev_hook $W
    j:tkb:repeatable {
      j:text:insert $W $A
    } $W
  }
}

######################################################################
# jedit:tabkey - do whatever tab does (abbrev, indent, whatever)
######################################################################

proc jedit:tabkey { t args } {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  if {[info procs mode:$mode:pre_tabkey_hook] != {}} {
    mode:$mode:pre_tabkey_hook $t
  }
  #
  if {[info procs mode:$mode:tabkey] != {}} {
    mode:$mode:tabkey $t
  } else {
    if $JEDIT_MODEPREFS($mode,dabbrev) {
      jedit:cmd:dabbrev $t
    } else {
      j:tkb:self_insert $t Tab "\t"
    }
  }
  #
  if {[info procs mode:$mode:post_tabkey_hook] != {}} {
    mode:$mode:post_tabkey_hook $t
  }
}

######################################################################
# jedit:spacebar - do whatever space does (abbrev, line breaking, whatever)
######################################################################

proc jedit:spacebar { t args } {
  set mode [jedit:get_mode $t]
  
  if {[info procs mode:$mode:pre_spacebar_hook] != {}} {
    mode:$mode:pre_spacebar_hook $t
  }
  #
  if {[info procs mode:$mode:spacebar] != {}} {
    mode:$mode:spacebar $t
  } else {
    jedit:sabbrev_hook $t
    j:tkb:self_insert $t space " "
    jedit:autobreak_hook $t
  }
  #
  if {[info procs mode:$mode:post_spacebar_hook] != {}} {
    mode:$mode:post_spacebar_hook $t
  }
}

######################################################################
# jedit:sabbrev_hook t - jedit:cmd:sabbrev if it's on
######################################################################

proc jedit:sabbrev_hook { t } {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  if $JEDIT_MODEPREFS($mode,sabbrev) {
    jedit:cmd:sabbrev $t
  }
}

######################################################################
# jedit:dabbrev_hook t - jedit:cmd:dabbrev if it's on
######################################################################
# (not used by plain mode - Tab does dabbrev *INSTEAD OF* inserting
#   tab, not *before* inserting tab)

proc jedit:dabbrev_hook { t } {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]

  if $JEDIT_MODEPREFS($mode,dabbrev) {
    jedit:cmd:dabbrev $t
  }
}

######################################################################
# jedit:autobreak_hook - insert a cr if line is long enough
######################################################################

proc jedit:autobreak_hook { t } {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  if $JEDIT_MODEPREFS($mode,autobreak) {
    set length [string length [$t get {insert linestart} insert]]
    if {$length > ($JEDIT_MODEPREFS($mode,textwidth) - 15)} {
      jedit:returnkey $t
    }
  }
}

######################################################################
# jedit:returnkey - do whatever return does (indentation, etc.)
######################################################################

proc jedit:returnkey { t args } {
  set mode [jedit:get_mode $t]
  
  jedit:save_checkpoint $t
  
  if {[info procs mode:$mode:pre_returnkey_hook] != {}} {
    mode:$mode:pre_returnkey_hook $t
  }
  #
  if {[info procs mode:$mode:returnkey] != {}} {
    mode:$mode:returnkey $t
  } else {
    jedit:sabbrev_hook $t
    j:tkb:self_insert $t Return "\n"
    jedit:autoindent $t
  }
  #
  if {[info procs mode:$mode:post_returnkey_hook] != {}} {
    mode:$mode:post_returnkey_hook $t
  }
}

######################################################################
# jedit:autoindent - insert same indentation as previous line
######################################################################

proc jedit:autoindent { t } {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  if $JEDIT_MODEPREFS($mode,autoindent) {
    if {[info procs mode:$mode:autoindent] != {}} {
      mode:$mode:autoindent $t
    } else {
      set prevline [$t get {insert -1lines linestart} {insert -1lines lineend}]
      if [regexp "^\[ \t\]\[ \t\]*" $prevline indentation] {
        j:text:insert $t $indentation
      }
    }
  }
}
