# jbindentry.tcl - support for Entry bindings
#
######################################################################
# Copyright 1992-1999 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:eb:init - initialise info for bindings
######################################################################

proc j:eb:init { {e Entry} } {
  global J_PREFS env
  if {! [info exists J_PREFS(typeover)]} {set J_PREFS(typeover) 1}
  switch -exact $J_PREFS(bindings) {
    basic {
      j:eb:basic_init $e
    }
    emacs {
      j:eb:emacs_init $e
    }
    edt {
      j:eb:edt_init $e
    }
    vi {
      j:eb:vi_init $e
    }
  }

  # read in user's supplementary entry bindings
  j:source_config entrybindings.tcl
}

######################################################################
# j:eb:no_op - do nothing
######################################################################

proc j:eb:no_op { args } {
  return 0
}

######################################################################
# j:eb:beep W - beep
######################################################################

proc j:eb:beep { W args } {
  ::aq::beep $W
  return 0
}

######################################################################
# j:eb:clear_selection W - clear the selection in widget W
######################################################################

proc j:eb:clear_selection { W args } {
  $W select clear
}

######################################################################
# j:eb:select_all W - select all text in widget W
######################################################################

proc j:eb:select_all { W args } {
  $W select from 0
  $W select to end
}

######################################################################
# j:eb:is_bol W - return true if insert is at beginning of line
#   from Achim Bonet <ach@.....>
######################################################################

proc j:eb:is_bol { W } {
  return [expr {!([$W index insert])}]
}

######################################################################
# j:eb:is_eol W - return true if insert is at end of line
#   from Achim Bonet <ach@.....>
######################################################################

proc j:eb:is_eol { W } {
  return [expr {!([$W index end]-[$W index insert])}]
}

######################################################################
###  GENERAL ENTRY ROUTINE (can be used as key or mouse binding)
######################################################################

# j:eb:paste_selection W - insert the X selection in an entry
proc j:eb:paste_selection { W args } {
  $W insert insert [string trim [::aq::selection_if_any] "\n\r"]
  j:entry_see_insert $W
}

######################################################################
######################################################################
### ROUTINES TO SET UP ENTRY BINDINGS

# j:eb:key_bind W args - set up bindings to process keys
proc j:eb:key_bind { W args } {
  # restore mouse pointer on motion:
  bind $W <Any-Motion> {::aq::show_pointer %W}
  
  # get rid of some of the default Tk bindings:
  
  foreach binding {
    <Enter> <FocusIn>
  } {
    bind $W $binding {}
  }
  #
  # note that <Tab> is NOT rebound!
  # 
  foreach binding {
    <Left>
    <Right>
    <Shift-Left>
    <Shift-Right>
    <Home>
    <Shift-Home>
    <End>
    <Shift-End>
    <Delete>
    <BackSpace>
    <Select>
    <Shift-Select>
    <Escape>
    <Return>
    <Insert>
    <Any-Key> <Shift-Key>
  } {
    bind $W $binding {
      ::aq::hide_pointer %W
      j:ekb:process_key %W "" %K %A
      break
    }
  }
  foreach binding {
    <Control-Left>
    <Control-Right>
    <Shift-Control-Left>
    <Shift-Control-Right>
    <Control-space>
    <Control-Shift-space>
    <Control-slash>
    <Control-backslash>
    <Control-a>
    <Control-b>
    <Control-d>
    <Control-e>
    <Control-f>
    <Control-h>
    <Control-k>
    <Control-t>
    <Control-v>
    <Control-w>
    <Control-y>
    <Control-Key> <Control-Shift-Key>
  } {
    bind $W $binding {
      ::aq::hide_pointer %W
      j:ekb:process_key %W Control %K %A
      break
    }
  }
  foreach binding {
    <Meta-b>
    <Meta-d>
    <Meta-f>
    <Meta-w>
    <Alt-w>
    <Meta-y>
    <Alt-y>
    <Meta-BackSpace>
    <Alt-KeyPress> <Meta-KeyPress>
    <Meta-Shift-KeyPress> <Alt-Shift-KeyPress>
  } {
    bind $W $binding { }
  }
  
  # and create null bindings for modifiers, so they don't trigger commands:
  foreach binding {
    <Shift_L> <Shift_R> <Control_L> <Control_R> <Caps_Lock>
    <Shift_Lock> <Meta_L> <Meta_R> <Alt_L> <Alt_R>
  } {
    bind $W $binding { }
  }
  
  # Compose (Multi_key) key support:
  bind $W <Multi_key>		{ }
  bind $W <Multi_key><Any-Key>	{j:ec:start_sequence %W %K %A}
  bind $W <Multi_key><Any-Key><Any-Key> \
  				{j:ec:finish_sequence %W %K %A}
  bind $W <Multi_key><Any-KeyRelease><Any-Key> \
    				{j:ec:start_sequence %W %K %A}
  bind $W <Multi_key><Any-Key><Any-Key> \
  				{j:ec:finish_sequence %W %K %A}
  bind $W <Multi_key><Any-Key><Any-KeyRelease><Any-Key> \
  				{j:ec:finish_sequence %W %K %A}
  bind $W <Multi_key><Any-KeyRelease><Any-Key><Any-KeyRelease><Any-Key> \
  				{j:ec:finish_sequence %W %K %A}
}
