Index of /tcl/ftparchive/sorted/databases/tkbind

      Name                   Last modified     Size  Description

[DIR] Parent Directory 29-Jan-99 12:24 - [   ] README 11-Oct-96 21:26 17k

tkBindExtended v1.0 beta1 - enhanced bindings for Tk4.0
Paul Raines <raines@slac.stanford.edu>

**** WARNING: this is still to be considered BETA software ****

INTRODUCTION:

  The included files contain replacement bindings for the text 
  and entry bindings of the standard library of the Tk4.0 
  distribution. It is a highly extended version of the original 
  which adds many new emacs-like bindings. These include 

	  - multi-level undo that handles tags (no embedded windows yet)
	  - argument keys
	  - "hard" auto-filling and paragraph filling with prefixes
	  - a mark ring
	  - multi-level kill buffer (Copy,Cut,Paste) which handles tags
	  - xterm-like mouse bindings
	  - incremental or dialog search ( optional package )
	  - rectangle editing ( optional package )
	  - support for emacs-like minibuffer for text widgets
	  
  The included entry.tcl file also has undo, argument keys, kill
  buffer, and xterm-like mouse bindings. Basically, it has all the
  same bindings as the text widget that don't affect multiple lines
  or tags.

  Run the included tkBindTest script with this README file as an
  argument to demo the new bindings. This script also gives one a good
  idea how to use the enhanced text bindings in ones own applications.

  See the included file emacs.list for complete status of the emacs
  bindings.  If one has tk_strictMotif set, they will have the
  following MAC-like bindings instead of those listed in emacs.list.

    Undo:		C-z
    Cut:		C-x
    Copy:		C-c
    Paste:		C-v
    Select All:   	C-/

  For emacs bindings, all the Meta bindings can also be accessed using
  the Escape key as a "state" key. Implementing a "state" keys was
  kind of tricky and I am sure not fully bug free so if you see any
  irregularities using them, please report them to me. The "state"
  keys are Escape, C-x, C-q, and to a certain extent the isearch C-s
  and C-r keys.

INSTALLATION:

  Just created a directory (possibly /usr/local/lib/tkbind) and copy
  all the files in the distribution there. That is it!

  To use these bindings on selected Tk programs, you should add the
  following lines at beginning of the Tk scripts. You must of course
  provide the proper path to the extended binding scripts.

	# if the enhanced bindxtnd.tcl is not the default, source it
	if {[info proc tkBindDefVar]==""} {
	  foreach key [bind Text] { bind Text $key {} }
	  foreach key [bind Entry] { bind Entry $key {} }
	  source /usr/local/lib/tkbind/bindxtnd.tcl
	  source /usr/local/lib/tkbind/text.tcl
	  source /usr/local/lib/tkbind/entry.tcl
	  # source additional packages here
	}

  If you choose to have these files actually replace the default Tk4.0
  library files, follow the preceding steps (sorry, no Makefile yet).
  At this point I do not suggest doing this as the software is still
  experimental and I feel that there are many ways Tk applications can
  create conflicts with these bindings (especially if they use the
  bindtags command).

  1) Make a backup of the tk.tcl, text.tcl and entry.tcl files in your
     TK_LIBRARY directory.

  2) Copy all *.tcl files from distribution to the TK_LIBRARY
     directory.

  3) Apply the following patch to the tk.tcl file there.

*** tk.tcl.orig  Sun Jul 16 17:37:18 1995
--- tk.tcl      Tue Sep 12 12:30:36 1995
***************
*** 78,83 ****
--- 78,84 ----
  # Read in files that define all of the class bindings.
  # ----------------------------------------------------------------------
  
+ source $tk_library/bindxtnd.tcl
  source $tk_library/button.tcl
  source $tk_library/entry.tcl
  source $tk_library/listbox.tcl

  4) You are done. Now test it out.


CUSTOMIZATION:

  The standard text.tcl file is sourced before the individual user
  has any chance to  override the bindings made there. One
  problem I discovered is that many keyboards have only an Alt modifier
  key and no Meta modifier key. Rebinding all the <Meta-*> bindings to
  <Alt-*> bindings in ones ~/.wishrc file is a pain and not very
  efficient.  Therefore, I have allowed for the existance of a
  ~/.tkbindrc file in which one may put the line

  set tkBind(meta) Alt

  so that the <Alt-*> bindings are used in place of <Meta-*> bindings.
  One can also set any of the other non-widget specific tkBind()
  settings here. See the top of the text.tcl file for a list.
  It is important that you get the tkBind(modKeys) setting correct,
  so make sure you check its list against 'xmodmap -pm'. The default
  list is

  set tkBind(modKeys) [list Control_L Control_R Meta_R Meta_L Alt_R \
			   Alt_L Shift_L Shift_R Caps_Lock Multi_key \
			   Super_L Super_R]

  Note that the ~/.tkbindrc file is also the place to set the
  tk_strictMotif variable to your liking since text.tcl is sourced
  before any scripts. Read the top of the bindxtnd.tcl file for a
  complete table of tkBind() settings.

  Since the ~/.tkbindrc file is sourced before any of the default
  bindings are made, it cannot be used at the global level to override
  these bindings with your own. However, you can define procedures
  named tkTextInitHook and/or tkEntryInitHook which will be run (if it
  exists) after all the default bindings are made and standard
  procedures are created. These procedures takes no arguments. This
  hook is the ideal place to require any add-on packages such as
  isearch and to make your own bindings.

  Another hook, tkTextWidgetHook, will be run (if it exists) after the
  widget specific setup for a newly created text widget is done. It
  takes the text widget pathname as its sole argument. There is also
  a tkEntryWidgetHook hook.

  See the included example.tkbindrc file and also read the sections on
  MULTI-KEY BINDINGS and ARGUMENTS IN PERSONAL BINDINGS below.

ISEARCH PACKAGE:

  The included isearch package gives the standard emacs C-s and C-r
  isearch keys for the text widget. No regexp support at present. Also
  no search ring capability, but C-s, C-r, BackSpace, Delete, C-g,
  C-j, C-w, C-y, and C-q should work in isearch mode as
  expected. Unlike emacs isearch, unsuccessful additions to the search
  are not added to the search string anyway.

  To get the isearch package, place the line 'tkBindRequire isearch'
  in the tkTextInitHook procedure in your ~/.tkbindrc file. See
  CUSTOMIZATION above and the example.tkbindrc file.

DSEARCH PACKAGE:

  The included dsearch package gives binds the C-s and C-r keys to
  popup a dialog doing searchs. This has an additional advantage
  over isearch in that it can do replaces and handle regular expressions.

  To get the dsearch package, place the line 'tkBindRequire dsearch'
  in the tkTextInitHook procedure in your ~/.tkbindrc file. See
  CUSTOMIZATION above and the example.tkbindrc file.

PROMPT PACKAGE:

  The prompt package is designed mainly as a library of routines
  for other packages to use for prompting the user for information.
  Currently, only the rectangle package uses it. The application using
  tkBindEnhanced may also find it useful. It does define two bindings
  of its own. 
		C-x i	Insert file at current position
		M-x	Prompt for Tcl command to eval

  Normally, a transient dialog is popped up to request the information
  but if a MesgBuffer is present for the affected widget, then it will
  be used instead. See EMACS-LIKE MINIBUFFER below.

  NOTE: documentation on use of package for developers is coming soon.

RECTANGLE PACKAGE:

  The included rectangle package defines bindings for edit operations
  on rectangles of text. Use of these routines will have unpredictable
  results in non-fixed fonts are used. Correct processing of tabs is
  not yet implemented.
  
  The following bindings should work as in standard emacs
 
 	C-x r o		open-rectangle
 	C-x r y		yank-rectangle
 	C-x r d		delete-rectangle
 	C-x r k		kill-rectangle
 	C-x r c		clear-rectangle
 	C-x r t		string-rectangle (requires prompt package)
 
 	C-x r r		copy-rectangle
 
 		Not a copy to a register but just a copy to the
 		normal rectangle kill buffer. This may change once
 		a register package is written.


  To get the rectangle package, place the line 'tkBindRequire rectangle'
  in the tkTextInitHook procedure in your ~/.tkbindrc file. See
  CUSTOMIZATION above and the example.tkbindrc file.

UNDO:    *** NOT ON BY DEFAULT ***

  The default maximum number of levels is 50. It doesn't yet handle
  embedded windows. The undo ring also does not cycle. One must use the
  wrapper procedures tkTextDelete, tkTextInsert, tkTextReplace, and
  tkTextReTag in order to key the undo tracking in sync. Using the normal
  'text insert', 'text tag add', 'test tag remove' and 'text delete'
  commands will invalidate undo tracking. (NOTE: I will document these
  procedures soon.)

  For the above reasons, the undo feature is not on by default.  One
  can make a call to the tkTextUndoSetup procedure to turn it on for a
  specific widget. When a large change is made to a text widget (such
  as an editor app deleting the whole buffer and replacing it with the
  contents of a new file) it will be more efficient to use the normal
  text commands and make a call to the tkTextUndoSetup procedure again
  to reinitialize undo tracking for the widget.

  One can make undo on by default for all text widgets by setting 
  the tkBind(bindUndo) settings to 1 in the ~/.tkbindrc file. This 
  isn't recommended unless you have modified all your Tk apps to
  follow the rules above.

  The tag information stored is only the tag's name. If the tag's 
  configuration is changed, a later undo reinstating text with that
  tag will have the new characteristics. One might consider this a
  feature :)

  If multiple delete/insert/tag operations are to be considered
  one operation from an undo perspective, the developer should use
  tkTextUndoBeginGroup and tkTextUndoEndGroup procedures. Each
  operation still counts individually toward the maxUndo limit.

  NOTE: some of the tkText* procedures have a side-effect of moving
  the insert cursor. I might be convinced of changing this if it
  proves a problem to users.

  All the above (except tag stuff) applies to the Entry widget also,
  with the appropriate change of name for the procedures.

EMACS-LIKE MINIBUFFER:

  The text.tcl, entry.tcl and compliant packages write information
  to the global variable tkBind(%W,mesg) where %W is the text or entry
  widget. It would be most advantagous for developers to use the
  -textvariable option of a entry, message or label widget packed below the
  text widget to act as a message area for the tkText procedures. 

  The name of this variable can be changed for each widget using the
  tkTextSetMesgVar procedure. This can allow several widgets to use
  the global variable for messages. For example, 
	pack [label .l -textvariable bindmesg -anchor w \
	    -wraplength 0 -height 1] -side bottom -fill x 
	tkBindSetMesgVar .t bindmesg
	tkBindSetMesgVar .e bindmesg

  However, to get the best emacs compliance, a fully functioning
  minibuffer-like widget packaged underneath the text widget is
  desired.  This is possible with the tkBindCreateMesgBuffer procedure
  which operates like a widget creation command. For example

  pack [tkBindCreateMesgBuffer .m -foreground blue] -side bottom -fill x 

  The possible widget options are the same as those for the label
  widget which deal with color, font, cursor or border. Use of any
  other option might break it. One created, text and entry widgets can
  be connected to it with the tkBindAttachMesgBuffer command. Example.

      # set up entry and text to use label for message echo
      tkBindAttachMesgBuffer .t .m
      tkBindAttachMesgBuffer .e .m

  If one of these MesgBuffers is attached to a widget, the prompt
  package will use it instead of popping up separate window.

MULTI-KEY BINDINGS:

  Doing multi-key bindings in tk4.0 by using the bind command with
  sequences such as <Control-x><Control-s> has proven to have many
  problems. I have decided that they are evil and should be avoided
  at all costs. Instead, I use a bindtags method of achieving the
  same effect. Here is how it works. Say you want <Control-c> to
  be a state key like in emacs. Then do

  bind Text <Control-c> {
    tkBindSetStateKey %W TextCC C-c
  }

  The 2nd argument to tkBindSetStateKey is a bindtag that will be
  used for <Control-c><?> bindings as you will see below. The last
  argument is a "message" that will be put in the tkBind(%W,mesg)
  variable when the key is pressed as a prompt for a second key.

  Then to bind any key to the Control-c map, one simply uses a
  call to the bind command like

  bind TextCC <Control-c> {
    sendmessage %W
    set tkBind(%W,arg) {}
    set tkText(%W,prevCmd) SendMessage
  }

  The last two lines in the binding are recommended to be consistent
  with the emacs-style API. To report unbound key sequences it is also
  suggested that one make the following bindings for the above
  example.

  bind TextCC <KeyPress> {
    if {[lsearch $tkBind(modKeys) %K] > -1} break
    set $tkBind(%W,mesgvar) "C-c [tkBindGetMod %s]%K not bound."
    eval $tkBind(bell)
  }
  bind TextCC <ButtonPress> {
    set $tkBind(%W,mesgvar) "C-c [tkBindGetMod %s]mouse-%b not bound."
    eval $tkBind(bell)
  }

  Stacked multi-key bindings are possible as in the following.

  bind TextCX <KeyPress-r> { 
    tkBindSetStateKey %W TextCXR {C-x r}
  }
  bind TextCXR <KeyPress-k> { tkBindRectangleKill %W }
  bind TextCXR <KeyPress-y> { tkBindRectangleYank %W }

ARGUMENTS IN PERSONAL BINDINGS:

  One can use the argument mechanism in personal bindings using the
  tkBindDefArg procedure. Simply make a call like 

  set n [tkBindDefArg $w $n]

  in your binding to get the argument. The $w is the affected widget
  and the input $n may be either a decimal number, "+" or "-". If it
  is a decimal number, that number is returned. If it is "+", the
  current user argument is returned. If it is "-", the negative of the
  current user argument is returned. If there is no current user
  argument, then it defaults to 1. This can be changed with an
  optional third argument to tkBindDefArg. Possibilities are summarized
  as follows:
                                             RETURNS
         Call               current arg is X          no current arg
   -------------------      ----------------          --------------
   tkBindDefArg $w +               X                        1
   tkBindDefArg $w -              -X                       -1
   tkBindDefArg $w 2               2                        2
   tkBindDefArg $w + 3             X                        3
   tkBindDefArg $w - 3            -X                       -3
   tkBindDefArg $w 2 3             2                        2

  One should really make a call to tkBindDefArg even if no argument
  is going to be used in order to clear the current argument. One 
  can also set the tkBind(%N,arg) to empty explicitly 

OTHER NOTES:

  1) PARAGRAPH FILLING

  Attempts to be intelligent and handle prefixes like # or >>. This
  is probably pretty fragile so please test it for me.

  2) KILL RING

  Default maximum of 20 kills. It doesn't yet handle embedded windows.

  3) XTERM-LIKE MOUSE BINDINGS

  Any selection made with the mouse will go into Tk's private clipboard
  as well as the X server's PRIMARY selection. When mouse button 2 is 
  pressed to do a paste, it will first look for a PRIMARY selection and
  if it doesn't find one, it will use the Tk clipboard.  You should find
  this behavior similar to the way xterm works.

  One difference from xterms is the behavior of button 3. Instead of
  extending the current selection (shift-B1 can be used for this purpose)
  it can be used to make a selection with out moving the insert cursor.
  This is convenient for copying text elsewhere in the windo to the 
  current insertion point with a B3-drag then B2-click operation.

TODO:

  * Handle embedded windows for text widgets
  * More extensive set of Mac-like bindings and may other
    bindings styles
  * A package for query-replace bindings
  * A package for register handling
  * Better docs for users and developers
  * A package for shell operations on buffers

COPYRIGHT:
     Copyright 1995 by Paul Raines (raines@slac.stanford.edu)

     Permission to use, copy, modify, and distribute this software and
     its documentation for any purpose and without fee is hereby
     granted, provided that the above copyright notice appear in all
     copies.  The University of Pennsylvania, Stanford University, and
     Stanford Linear Accelerator Center makes no representations
     about the suitability of this software for any purpose.  It is
     provided "as is" without express or implied warranty.

     Parts of this packages are also covered by the following as noted:

     Copyright 1992-1994 by Jay Sekora.  All rights reserved, except 
     that this file may be freely redistributed in whole or in part 
     for non-profit, noncommercial use.

     Copyright (c) 1992-1994 The Regents of the University of California.
     Copyright (c) 1994-1995 Sun Microsystems, Inc.
     See the file "license.terms" for information on usage and redistribution
     of this file, and for a DISCLAIMER OF ALL WARRANTIES.

DISCLAIMER:
     UNDER NO CIRCUMSTANCES WILL THE AUTHOR OF THIS SOFTWARE OR THE
     UNIVERSITY OF PENNSYLVANIA, STANFORD UNIVERSITY, THE STANFORD
     LINEAR ACCELERATOR CENTER, OR THE DEPARTEMENT OF ENERGY BE HELD
     RESPONSIBLE FOR ANY DIRECT OR INCIDENTAL DAMAGE ARISING FROM THE
     USE OF THIS SOFTWARE AND ITS DOCUMENTATION. THE SOFTWARE HEREIN IS
     PROVIDED "AS IS" WITH NO IMPLIED OBLIGATION TO PROVIDE SUPPORT,
     UPDATES, OR MODIFICATIONS.

 Please mail any suggestions, bugs, whines to raines@slac.stanford.edu