3 # This file defines the default bindings for text widgets and provides
4 # procedures that help in implementing the bindings.
6 # Copyright (c) 1992-1994 The Regents of the University of California.
7 # Copyright (c) 1994-1995 Sun Microsystems, Inc.
9 # See the file "license.terms" for information on usage and redistribution
10 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 #-------------------------------------------------------------------------
14 # The code below creates the default class bindings for texts.
15 #-------------------------------------------------------------------------
18 ckTextSetCursor %W [%W index {insert - 1c}]
21 ckTextSetCursor %W [%W index {insert + 1c}]
24 ckTextSetCursor %W [ckTextUpDownLine %W -1]
27 ckTextSetCursor %W [ckTextUpDownLine %W 1]
30 ckTextSetCursor %W [ckTextScrollPages %W -1]
33 ckTextSetCursor %W [ckTextScrollPages %W 1]
36 ckTextSetCursor %W {insert linestart}
39 ckTextSetCursor %W {insert lineend}
49 bind Text <Linefeed> {
53 if {[%W tag nextrange sel 1.0 end] != ""} {
54 %W delete sel.first sel.last
60 bind Text <ASCIIDelete> {
61 if {[%W tag nextrange sel 1.0 end] != ""} {
62 %W delete sel.first sel.last
68 bind Text <BackSpace> {
69 if {[%W tag nextrange sel 1.0 end] != ""} {
70 %W delete sel.first sel.last
71 } elseif [%W compare insert != 1.0] {
76 bind Text <KeyPress> {
79 bind Text <Button-1> {
81 ckTextSetCursor %W @%x,%y
86 # Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
87 # Otherwise, if a widget binding for one of these is defined, the
88 # <KeyPress> class binding will also fire and insert the character,
89 # which is wrong. Ditto for <Escape>.
91 bind Text <Control> {# nothing}
93 bind Text <Control-x> {focus [ck_focusNext %W]}
95 bind Text <Control-a> {
96 ckTextSetCursor %W {insert linestart}
98 bind Text <Control-b> {
99 ckTextSetCursor %W insert-1c
101 bind Text <Control-d> {
104 bind Text <Control-e> {
105 ckTextSetCursor %W {insert lineend}
107 bind Text <Control-f> {
108 ckTextSetCursor %W insert+1c
110 bind Text <Control-k> {
111 if [%W compare insert == {insert lineend}] {
114 %W delete insert {insert lineend}
117 bind Text <Control-n> {
118 ckTextSetCursor %W [ckTextUpDownLine %W 1]
120 bind Text <Control-o> {
122 %W mark set insert insert-1c
124 bind Text <Control-p> {
125 ckTextSetCursor %W [ckTextUpDownLine %W -1]
127 bind Text <Control-v> {
128 ckTextScrollPages %W 1
130 bind Text <Control-h> {
131 if [%W compare insert != 1.0] {
136 bind Text <FocusIn> {%W see insert}
138 set ckPriv(prevPos) {}
141 # Move the insertion cursor to a given position in a text. Also
142 # clears the selection, if there is one in the text, and makes sure
143 # that the insertion cursor is visible. Also, don't let the insertion
144 # cursor appear on the dummy last line of the text.
147 # w - The text window.
148 # pos - The desired new position for the cursor in the window.
150 proc ckTextSetCursor {w pos} {
153 if [$w compare $pos == end] {
154 set pos {end - 1 chars}
156 $w mark set insert $pos
157 $w tag remove sel 1.0 end
162 # Insert a string into a text at the point of the insertion cursor.
163 # If there is a selection in the text, and it covers the point of the
164 # insertion cursor, then delete the selection before inserting.
167 # w - The text window in which to insert the string
168 # s - The string to insert (usually just a single character)
170 proc ckTextInsert {w s} {
171 if {([string length $s] == 0) || ([$w cget -state] == "disabled")} {
175 if {[$w compare sel.first <= insert]
176 && [$w compare sel.last >= insert]} {
177 $w delete sel.first sel.last
184 # ckTextUpDownLine --
185 # Returns the index of the character one line above or below the
186 # insertion cursor. There are two tricky things here. First,
187 # we want to maintain the original column across repeated operations,
188 # even though some lines that will get passed through don't have
189 # enough characters to cover the original column. Second, don't
190 # try to scroll past the beginning or end of the text.
193 # w - The text window in which the cursor is to move.
194 # n - The number of lines to move: -1 for up one line,
195 # +1 for down one line.
197 proc ckTextUpDownLine {w n} {
200 set i [$w index insert]
201 scan $i "%d.%d" line char
202 if {[string compare $ckPriv(prevPos) $i] != 0} {
203 set ckPriv(char) $char
205 set new [$w index [expr $line + $n].$ckPriv(char)]
206 if {[$w compare $new == end] || [$w compare $new == "insert linestart"]} {
209 set ckPriv(prevPos) $new
213 # ckTextScrollPages --
214 # This is a utility procedure used in bindings for moving up and down
215 # pages and possibly extending the selection along the way. It scrolls
216 # the view in the widget by the number of pages, and it returns the
217 # index of the character that is at the same position in the new view
218 # as the insertion cursor used to be in the old view.
221 # w - The text window in which the cursor is to move.
222 # count - Number of pages forward to scroll; may be negative
223 # to scroll backwards.
225 proc ckTextScrollPages {w count} {
226 set bbox [$w bbox insert]
227 $w yview scroll $count pages
229 return [$w index @[expr [winfo height $w]/2],0]
231 return [$w index @[lindex $bbox 0],[lindex $bbox 1]]