#
# String completion for Text widgets
#

proc th_Text_completion_replace {w m new_string} {
  set new_index "$m linestart + [expr \
   [string length [$w get "$m linestart" insert]] \
    + [string length $new_string] \
    - [string length [$w get "$m linestart" "$m lineend"]]] c"
  $w delete "$m linestart" "$m lineend"
  $w insert $m $new_string
  $w mark set $m $new_index
  $w see $m
}

# Replaces current line with new_string. Undoable if undo is available.
proc th_Text_undoable_completion_replace {w new_string} {
  global auto_index
  if {([info procs th_Text_register_undoable_cmd] != "") || \
     ([lsearch [array names auto_index] th_Text_register_undoable_cmd] >= 0)} {
    set start [th_gensym]
    $w mark set $start "insert linestart"
    th_Text_register_undoable_cmd $w "th_Text_completion_replace $w $start \
	\{[$w get $start "$start lineend"]\}" "String Completion" $start
  }
  th_Text_completion_replace $w insert $new_string
}

# Does completion to the string in an entry binding.
# Beeps unless exact completion was made. Returns 0 if regular key should
# be inserted instead
proc th_Text_complete {w possibilities {function filter_completions}} {
  if {[$w compare insert == "insert linestart"]} {return 0}
  set new_string [th_Misc_complete [$w get "insert linestart" "insert lineend"] $possibilities $function]
  if {$new_string != ""} {th_Text_undoable_completion_replace $w $new_string}
  return 1
}

# Does completion to the substring in an entry binding before the insert cursor.
# Beeps unless completion was made and no message exists.
proc th_Text_complete_multiple {w {completion_list ""}} { 
  set prev_char [$w get insert-1c]
  if {([string first $prev_char " \n\t"] >= 0) ||
      [$w compare insert == 1.0]} {return 0}

  set head [$w get "insert linestart" insert]
  set tail [$w get insert "insert lineend"]
  set new_string [th_Misc_complete_multiple $head $completion_list]
  if {$new_string != ""} {
    th_Text_undoable_completion_replace $w "$new_string$tail"
  }
  return 1
}

# Shows list of completions, letting user pick one.
proc th_Text_completion_dialog {w} {
  global TH
  set view [string length [$w get "insert linestart" insert]]
  set new_string [th_Misc_completion_dialog $view]
 if {$new_string != ""} {
      th_Text_undoable_completion_replace $w "[$w get "insert linestart" "insert linestart +$TH(Completion,Index) c"]$new_string[$w get insert "insert lineend"]"}
}
