Index of /tcl/ftparchive/sorted/databases/tkbind
Name Last modified Size Description
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