File: bindings.tcl

package info (click to toggle)
exmh 1%3A2.9.0-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 4,216 kB
  • sloc: tcl: 38,046; perl: 1,647; makefile: 130; sh: 101; exp: 75; csh: 9; sed: 2
file content (297 lines) | stat: -rw-r--r-- 9,772 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# bindings.tcl
#
# Keystroke bindings
#
# Copyright (c) 1993 Xerox Corporation.
# Use and copying of this software and preparation of derivative works based
# upon this software are permitted. Any distribution of this software or
# derivative works must comply with all applicable United States export
# control laws. This software is made available AS IS, and Xerox Corporation
# makes no warranty about the software, its performance or its conformity to
# any specification.

proc Bindings_Main { w } {
    # Keystroke bindings for operations on messages and folders
    # Assert $w == $exwin(mtext)
    global bindings
    catch {unset bindings}
    set bindings(dotfile) ~/.exmh/exmhbindings
    BindingsReadPref
    BindingsReset $w
}
proc BindingsReset { w } {
    global bindings mhProfile
    bindtags $w [list TSelect TScroll Command $w all]
    set w Command
    bind $w <Any-Key> {if {"%A" != "{}"} {Exmh_Status "bad key %A"} }
    Bind_Key $w <Control-Return> 	{Folder_Commit}
    Bind_Key $w <Key-A> {MimeSunAppSelection}
    Bind_Key $w <Key-i> {Inc}
    Bind_Key $w <Key-c> {Msg_Compose}
    Bind_Key $w <Key-C> {Msg_CompSel}
    Bind_Key $w <Key-d> {Msg_Remove}
    Bind_Key $w <Key-D> {Msg_RemoveNoshow}
    Bind_Key $w <Key-g> {URI_OpenSelection}
    Bind_Key $w <Key-z> {URI_ScanMsg {} $uri(scanLimit)}
    Bind_Key $w <Key-p> {Ftoc_Prev show}
    Bind_Key $w <Key-P> {Ftoc_Prev noshow}
    Bind_Key $w <minus> {Ftoc_PrevMarked}
    Bind_Key $w <Key-n> {Ftoc_Next show}
    Bind_Key $w <Key-N> {Ftoc_Next noshow}
    Bind_Key $w <Key-m> {Msg_Move}
    Bind_Key $w <Key-M> {Msg_MoveNoshow}
    Bind_Key $w <Key-r> {Msg_Reply -nocc to -nocc cc}
    Bind_Key $w <Key-R> {Msg_ReplyAll}
    Bind_Key $w <Key-f> {Msg_Forward}
    Bind_Key $w <Key-F> {Ftoc_NextFolder}
    Bind_Key $w <Key-s> {Msg_Show cur}
    Bind_Key $w <Key-u> {Ftoc_Unmark}
    Bind_Key $w <Key-U> "Msg_Show $mhProfile(unseen-sequence)"
    Bind_Key $w <asciicircum> {Msg_First}
    Bind_Key $w <dollar> {Msg_Last}
    Bind_Key $w <Control-s> {Find_It forw}
    Bind_Key $w <Control-r> {Find_It prev}
    Bind_Key $w <question> {Bind_Pref}
    Bind_Key $w <period> {Folder_AutoRefile}
    Bind_Key $w <Key-S> {Bogo_Filter spam}
    Bind_Key $w <Key-H> {Bogo_Filter ham}
    # Page message - the function keys are Sun4 keyboard specific
    Bind_Key $w <space>			{Msg_PageOrNext}
    Bind_Key $w {<BackSpace> <Prior> <F29>}	{Msg_PageUp}
    Bind_Key $w {<Up> <Key-k>}		{Msg_LineUp}
    Bind_Key $w {<Next> <F35>}		{Msg_PageDown}
    Bind_Key $w {<Down> <Key-j>}	{Msg_LineDown}
    Bind_Key $w {<Home> <Key-less>}	{Msg_Top}
    Bind_Key $w {<End> <Key-greater>}	{Msg_Bottom}
    # Page Ftoc
    Bind_Key $w {<Control-n> <Shift-Next>}  {Ftoc_PageDown}
    Bind_Key $w {<Control-p> <Shift-Prior>} {Ftoc_PageUp}
    #
    Bind_Key $w <Control-w>	{Msg_CopySelection}

    Select_Bindings $w	;# Keyboard selection of folders
    Addr_Bindings $w	;# Address book bindings.

    if {[info command User_Bindings] != ""} {
	User_Bindings $w
    }
    # This is a round about way to add in the user's custom bindings.
    # They'll be defined in the bindings array, but not have a default binding
    foreach item [array names bindings] {
	if [regexp ^key $item match] {
	    set cmd [lindex [split $item ,] 1]
            if {![info exist bindings(default,$cmd)] || $bindings(default,$cmd) == ""} {
                Bind_Key $w {} $cmd 
            }
	}
    }
}

proc Bindings_Search { entry } {
    # Bindings for the search entry widget
    Widget_BindEntryCmd $entry <Return> { Find_It }
    Widget_BindEntryCmd $entry <Control-r> { Find_It prev }
    Widget_BindEntryCmd $entry <Control-s> { Find_It forw }
}

proc UserCommitAction { } {
    global bind
    if [info exists bind(commitAction)] {
	if [eval $bind(commitAction)] {
	    unset bind(commitAction)
	}
    }
}
proc BindOrderReset {} {
    global bindings
    set bindings(order) {}
}
proc Bind_Key { w defaultSeq cmd } {
    global bindings
    if [info exists bindings(key,$cmd)] {
	# Preserve existing key specifications (from ~/.exmh/exmhbindings)
	set seqs $bindings(key,$cmd)
    } else {
	set seqs $defaultSeq
    }
    foreach seq $seqs {
	if [catch {
	    if {$seq == {}} {
		continue
	    }
	    bind $w $seq $cmd
	    # Double-bind Meta-key and Escape-key
	    if [regexp {<Meta-(.*)>} $seq match letter] {
		bind $w <Escape><$letter> $cmd
	    }
	    # Make leading keystroke harmless
	    if [regexp {(<.+>)<.+>} $seq match prefix] {
		bind $w $prefix { }
	    }
	    bind $w $seq $cmd
	} err] {
	    Exmh_Status "$cmd: $err"
	}
    }
    set bindings(key,$cmd) $seqs
    if {[string length $defaultSeq] != 0} {
	set bindings(default,$cmd) $defaultSeq
    } elseif {! [info exists bindings(default,$cmd)]} {
	set bindings(default,$cmd) {}
    }
Exmh_Debug Bind_Key $seqs $cmd default $bindings(default,$cmd)
}

proc Bind_Pref {} {
    global bindings
    if [Exwin_Toplevel .bindpref "Key Commands Preferences" Pref] {
	Widget_Label .bindpref.but label {left fill} \
	    -text "Key command bindings"

	Widget_AddBut .bindpref.but save "Save" {BindingsPrefSave}
	Widget_AddBut .bindpref.but help "Help" {BindingsPrefHelp}
	set f2 [Widget_Frame .bindpref def Dialog {top fillx}]
	$f2 configure -bd 10

	Widget_Frame $f2 cmd Preference {top fillx}
	Widget_Label $f2.cmd label {left} -text Command -width 10 -anchor w
	Widget_Entry $f2.cmd entry {right expand fillx} -width 30

	Widget_Frame $f2 key Preference {top fillx}
	Widget_Label $f2.key label {left} -text Key -width 10 -anchor w
	Widget_Entry $f2.key entry {left expand fillx} -width 30
    
	set cmdEntry $f2.cmd.entry
	set keyEntry $f2.key.entry
	bind $cmdEntry <Tab> [list focus $keyEntry]
	bind $keyEntry <Return> [list BindingsDefine $cmdEntry $keyEntry]
	set doit [button $f2.key.doit -text Define \
	    -command [list BindingsDefine $cmdEntry $keyEntry]]
	pack $doit -side left

	set f [Widget_Frame .bindpref c ScrollCanvas]

	canvas $f.can -width 500 -height 300 \
	    -yscrollcommand [list $f.scroll set] \
	    -scrollregion "0 0 500 300"
	wm minsize .bindpref 300 200
	scrollbar $f.scroll -command [list $f.can yview] -orient vertical
	pack $f.scroll -side right -fill y
	pack $f.can -side left -fill both -expand true
	BindPrefDisplay .bindpref.c.can
    }
    focus .bindpref.def.cmd
}
proc BindingsPrefHelp {} {
    Help Bindings "Command Bindings Help"
}
proc BindPrefDisplay { canvas } {
    global bindings
    set width 0
    foreach item [array names bindings] {
	if [regexp ^key $item] {
	    set name [lindex [split $item ,] 1]
	    set w [string length $name]
	    if {$w > $width} { set width $w }
	    set map($name) $bindings($item)
	}
    }
    set size 0
    if {$width > 50} {
	set width 50
    }
    catch {destroy $canvas.f}
    frame $canvas.f
    $canvas create window 5 0 -anchor nw -window $canvas.f
    foreach name [lsort -command BindPrefSort [array names map]] {
	set keystroke $map($name)
	incr size
	BindingsPrefItem $canvas.f $width $name action$size $keystroke
	if {[string length $keystroke] == 0} {
	    pack forget $canvas.f.action$size
	}
    }
    set child [lindex [pack slaves $canvas.f] 0]
    Visibility_Wait $child
    $canvas config -scrollregion "0 0 [winfo width $canvas.f] [winfo height $canvas.f]"
}
proc BindPrefSort {s1 s2} {
    string compare [string tolower $s1] [string tolower $s2]
}
proc BindingsPrefItem { frame width cmd name keystroke } {
    global bindings
    Widget_Frame $frame $name Preference
    set label [string range $cmd 0 [expr $width-1]]
    Widget_Label $frame.$name label {left} -text $label -width $width -anchor w
    Widget_Entry $frame.$name entry {right expand fill} -width 30
    set bindings(entry,$cmd) $frame.$name.entry
    $frame.$name.entry insert 0 $keystroke
    Widget_BindEntryCmd $frame.$name.entry <Return> [list BindRebind $cmd]
}
proc BindingsPrefSave { } {
    global bindings
    # Save it
    set out [open $bindings(dotfile) w]
    foreach item [array names bindings] {
	if [regexp ^key $item match] {
	    set name [lindex [split $item ,] 1]
	    set entry $bindings(entry,$name)
	    set keystrokes [$entry get]
	    if {[catch {set bindings(default,$name)} default] == 0} {
		if {[string compare $default $keystrokes] == 0} {
		    # Don't save settings that are system defaults
		    # Because default for user-defined things is NULL, this
		    # also means you can delete user-defined bindings by
		    # clearing their binding string.
		    continue
		}
	    }
	    puts $out [list set bindings($match,$name) $keystrokes]
	}
    }
    close $out
    Exwin_Dismiss .bindpref
    # Apply it to current session
    global exwin
    BindingsReset $exwin(mtext)
}

proc BindingsReadPref {} {
    global bindings
    if [file exists $bindings(dotfile)] {
	if [catch {uplevel #0 source [glob $bindings(dotfile)]} msg] {
	    Exmh_Status "Error in $bindings(dotfile): $msg"
	    return
	} 
    }
}

proc BindingsDefine { cmdEntry keyEntry } {
    set cmd [$cmdEntry get]
    set key [$keyEntry get]
    Exmh_Status "Bind $key => $cmd"
    BindingsDefineInner $cmd $key
}
proc BindRebind { cmd } {
    global bindings
    set key [$bindings(entry,$cmd) get]
    Exmh_Status "Bind $key => $cmd"
    BindingsDefineInner $cmd $key
}
proc BindingsDefineInner { newcmd key } {
    global bindings exwin
    #
    # Make sure we get any unsaved changes to other entries
    #
    foreach item [array names bindings] {
	if {[string match entry,* $item]} {
	    set cmd [lindex [split $item ,] 1]
	    set seqs [$bindings(entry,$cmd) get]
	    set bindings(key,$cmd) $seqs
	}
    }
    # But override a change from the main entires
    set bindings(key,$newcmd) $key
    BindingsReset $exwin(mtext)	;# clear and reset everything
    BindPrefDisplay .bindpref.c.can
}