]> git.ipfire.org Git - thirdparty/git.git/blame - gitk
Use symbolic name SHORT_NAME_AMBIGUOUS as error return value
[thirdparty/git.git] / gitk
CommitLineData
1db95b00
PM
1#!/bin/sh
2# Tcl ignores the next line -*- tcl -*- \
9e026d39 3exec wish "$0" -- "$@"
1db95b00
PM
4
5# Copyright (C) 2005 Paul Mackerras. All rights reserved.
6# This program is free software; it may be used, copied, modified
7# and distributed under the terms of the GNU General Public Licence,
8# either version 2, or (at your option) any later version.
9
73b6a6cb
JH
10proc gitdir {} {
11 global env
12 if {[info exists env(GIT_DIR)]} {
13 return $env(GIT_DIR)
14 } else {
15 return ".git"
16 }
17}
18
b5c2f306
SV
19proc parse_args {rargs} {
20 global parsed_args
21
22 if [catch {
23 set parse_args [concat --default HEAD $rargs]
24 set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
25 }] {
26 # if git-rev-parse failed for some reason...
27 if {$rargs == {}} {
28 set rargs HEAD
29 }
30 set parsed_args $rargs
31 }
32 return $parsed_args
33}
34
38ad0910 35proc start_rev_list {rlargs} {
466e4fdd 36 global startmsecs nextupdate ncmupdate
fd8ccbec 37 global commfd leftover tclencoding
9ccbdfbf 38
9ccbdfbf 39 set startmsecs [clock clicks -milliseconds]
2ed49d54 40 set nextupdate [expr {$startmsecs + 100}]
b664550c 41 set ncmupdate 1
2efef4b9 42 if [catch {
38ad0910
PM
43 set commfd [open [concat | git-rev-list --header --topo-order \
44 --parents $rlargs] r]
2efef4b9 45 } err] {
cfb4563c 46 puts stderr "Error executing git-rev-list: $err"
1d10f36d
PM
47 exit 1
48 }
b490a991 49 set leftover {}
fd8ccbec
PM
50 fconfigure $commfd -blocking 0 -translation lf
51 if {$tclencoding != {}} {
52 fconfigure $commfd -encoding $tclencoding
53 }
466e4fdd 54 fileevent $commfd readable [list getcommitlines $commfd]
38ad0910
PM
55 . config -cursor watch
56 settextcursor watch
57}
58
59proc getcommits {rargs} {
60 global oldcommits commits phase canv mainfont env
61
62 # check that we can find a .git directory somewhere...
63 set gitdir [gitdir]
64 if {![file isdirectory $gitdir]} {
65 error_popup "Cannot find the git directory \"$gitdir\"."
66 exit 1
67 }
68 set oldcommits {}
69 set commits {}
70 set phase getcommits
71 start_rev_list [parse_args $rargs]
1d10f36d
PM
72 $canv delete all
73 $canv create text 3 3 -anchor nw -text "Reading commits..." \
74 -font $mainfont -tags textitems
75}
76
b490a991 77proc getcommitlines {commfd} {
b5c2f306 78 global oldcommits commits parents cdate children nchildren
232475d3 79 global commitlisted phase nextupdate
b490a991 80 global stopped redisplaying leftover
b5c2f306 81 global canv
9ccbdfbf 82
b490a991
PM
83 set stuff [read $commfd]
84 if {$stuff == {}} {
1d10f36d 85 if {![eof $commfd]} return
f0654861 86 # set it blocking so we wait for the process to terminate
df3d83b1 87 fconfigure $commfd -blocking 1
1d10f36d 88 if {![catch {close $commfd} err]} {
9ccbdfbf 89 after idle finishcommits
1d10f36d
PM
90 return
91 }
9a40c50c 92 if {[string range $err 0 4] == "usage"} {
9ccbdfbf 93 set err \
2ed49d54
JH
94 "Gitk: error reading commits: bad arguments to git-rev-list.\
95 (Note: arguments to gitk are passed to git-rev-list\
96 to allow selection of commits to be displayed.)"
9a40c50c 97 } else {
df3d83b1 98 set err "Error reading commits: $err"
9a40c50c 99 }
df3d83b1 100 error_popup $err
1d10f36d 101 exit 1
9a40c50c 102 }
b490a991
PM
103 set start 0
104 while 1 {
105 set i [string first "\0" $stuff $start]
106 if {$i < 0} {
7e952e79 107 append leftover [string range $stuff $start end]
b490a991 108 return
9ccbdfbf 109 }
b490a991
PM
110 set cmit [string range $stuff $start [expr {$i - 1}]]
111 if {$start == 0} {
112 set cmit "$leftover$cmit"
7e952e79 113 set leftover {}
b490a991
PM
114 }
115 set start [expr {$i + 1}]
e5ea701b
PM
116 set j [string first "\n" $cmit]
117 set ok 0
118 if {$j >= 0} {
119 set ids [string range $cmit 0 [expr {$j - 1}]]
120 set ok 1
121 foreach id $ids {
122 if {![regexp {^[0-9a-f]{40}$} $id]} {
123 set ok 0
124 break
125 }
126 }
127 }
128 if {!$ok} {
7e952e79
PM
129 set shortcmit $cmit
130 if {[string length $shortcmit] > 80} {
131 set shortcmit "[string range $shortcmit 0 80]..."
132 }
133 error_popup "Can't parse git-rev-list output: {$shortcmit}"
b490a991
PM
134 exit 1
135 }
e5ea701b
PM
136 set id [lindex $ids 0]
137 set olds [lrange $ids 1 end]
138 set cmit [string range $cmit [expr {$j + 1}] end]
b490a991
PM
139 lappend commits $id
140 set commitlisted($id) 1
e5ea701b 141 parsecommit $id $cmit 1 [lrange $ids 1 end]
b5c2f306 142 drawcommit $id 1
b664550c
PM
143 if {[clock clicks -milliseconds] >= $nextupdate} {
144 doupdate 1
b490a991
PM
145 }
146 while {$redisplaying} {
147 set redisplaying 0
148 if {$stopped == 1} {
149 set stopped 0
150 set phase "getcommits"
151 foreach id $commits {
b5c2f306 152 drawcommit $id 1
b490a991 153 if {$stopped} break
b664550c
PM
154 if {[clock clicks -milliseconds] >= $nextupdate} {
155 doupdate 1
b490a991 156 }
9ccbdfbf
PM
157 }
158 }
159 }
160 }
161}
162
b664550c
PM
163proc doupdate {reading} {
164 global commfd nextupdate numcommits ncmupdate
9ccbdfbf 165
b664550c
PM
166 if {$reading} {
167 fileevent $commfd readable {}
168 }
9ccbdfbf 169 update
b664550c
PM
170 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
171 if {$numcommits < 100} {
172 set ncmupdate [expr {$numcommits + 1}]
173 } elseif {$numcommits < 10000} {
174 set ncmupdate [expr {$numcommits + 10}]
175 } else {
176 set ncmupdate [expr {$numcommits + 100}]
177 }
178 if {$reading} {
179 fileevent $commfd readable [list getcommitlines $commfd]
180 }
1db95b00
PM
181}
182
183proc readcommit {id} {
b490a991 184 if [catch {set contents [exec git-cat-file commit $id]}] return
e5ea701b 185 parsecommit $id $contents 0 {}
b490a991
PM
186}
187
fd8ccbec
PM
188proc updatecommits {rargs} {
189 global commitlisted commfd phase
190 global startmsecs nextupdate ncmupdate
191 global idtags idheads idotherrefs
192 global leftover
193 global parsed_args
194 global canv mainfont
195 global oldcommits commits
196 global parents nchildren children ncleft
197
198 set old_args $parsed_args
199 parse_args $rargs
200
201 if {$phase == "getcommits" || $phase == "incrdraw"} {
202 # havent read all the old commits, just start again from scratch
203 stopfindproc
204 set oldcommits {}
205 set commits {}
206 foreach v {children nchildren parents commitlisted commitinfo
207 selectedline matchinglines treediffs
208 mergefilelist currentid rowtextx} {
209 global $v
210 catch {unset $v}
211 }
212 readrefs
213 if {$phase == "incrdraw"} {
214 allcanvs delete all
215 $canv create text 3 3 -anchor nw -text "Reading commits..." \
216 -font $mainfont -tags textitems
217 set phase getcommits
218 }
219 start_rev_list $parsed_args
220 return
221 }
222
223 foreach id $old_args {
224 if {![regexp {^[0-9a-f]{40}$} $id]} continue
225 if {[info exists oldref($id)]} continue
226 set oldref($id) $id
227 lappend ignoreold "^$id"
228 }
229 foreach id $parsed_args {
230 if {![regexp {^[0-9a-f]{40}$} $id]} continue
231 if {[info exists ref($id)]} continue
232 set ref($id) $id
233 lappend ignorenew "^$id"
234 }
235
236 foreach a $old_args {
237 if {![info exists ref($a)]} {
238 lappend ignorenew $a
239 }
240 }
241
242 set phase updatecommits
243 set oldcommits $commits
244 set commits {}
245 set removed_commits [split [eval exec git-rev-list $ignorenew] "\n" ]
246 if {[llength $removed_commits] > 0} {
247 allcanvs delete all
248 foreach c $removed_commits {
249 set i [lsearch -exact $oldcommits $c]
250 if {$i >= 0} {
251 set oldcommits [lreplace $oldcommits $i $i]
252 unset commitlisted($c)
253 foreach p $parents($c) {
254 if {[info exists nchildren($p)]} {
255 set j [lsearch -exact $children($p) $c]
256 if {$j >= 0} {
257 set children($p) [lreplace $children($p) $j $j]
258 incr nchildren($p) -1
259 }
260 }
261 }
262 }
263 }
264 set phase removecommits
265 }
266
267 set args {}
268 foreach a $parsed_args {
269 if {![info exists oldref($a)]} {
270 lappend args $a
271 }
272 }
273
274 readrefs
275 start_rev_list [concat $ignoreold $args]
276}
277
b5c2f306
SV
278proc updatechildren {id olds} {
279 global children nchildren parents nparents ncleft
9ccbdfbf 280
cfb4563c
PM
281 if {![info exists nchildren($id)]} {
282 set children($id) {}
283 set nchildren($id) 0
9ccbdfbf 284 set ncleft($id) 0
cfb4563c 285 }
e5ea701b
PM
286 set parents($id) $olds
287 set nparents($id) [llength $olds]
288 foreach p $olds {
289 if {![info exists nchildren($p)]} {
290 set children($p) [list $id]
291 set nchildren($p) 1
292 set ncleft($p) 1
293 } elseif {[lsearch -exact $children($p) $id] < 0} {
294 lappend children($p) $id
295 incr nchildren($p)
296 incr ncleft($p)
244edd12
PM
297 }
298 }
b5c2f306
SV
299}
300
301proc parsecommit {id contents listed olds} {
302 global commitinfo cdate
303
304 set inhdr 1
305 set comment {}
306 set headline {}
307 set auname {}
308 set audate {}
309 set comname {}
310 set comdate {}
311 updatechildren $id $olds
232475d3
PM
312 set hdrend [string first "\n\n" $contents]
313 if {$hdrend < 0} {
314 # should never happen...
315 set hdrend [string length $contents]
316 }
317 set header [string range $contents 0 [expr {$hdrend - 1}]]
318 set comment [string range $contents [expr {$hdrend + 2}] end]
319 foreach line [split $header "\n"] {
320 set tag [lindex $line 0]
321 if {$tag == "author"} {
322 set audate [lindex $line end-1]
323 set auname [lrange $line 1 end-2]
324 } elseif {$tag == "committer"} {
325 set comdate [lindex $line end-1]
326 set comname [lrange $line 1 end-2]
1db95b00
PM
327 }
328 }
232475d3
PM
329 set headline {}
330 # take the first line of the comment as the headline
331 set i [string first "\n" $comment]
332 if {$i >= 0} {
333 set headline [string trim [string range $comment 0 $i]]
f6e2869f
PM
334 } else {
335 set headline $comment
232475d3
PM
336 }
337 if {!$listed} {
338 # git-rev-list indents the comment by 4 spaces;
339 # if we got this via git-cat-file, add the indentation
340 set newcomment {}
341 foreach line [split $comment "\n"] {
342 append newcomment " "
343 append newcomment $line
f6e2869f 344 append newcomment "\n"
232475d3
PM
345 }
346 set comment $newcomment
1db95b00
PM
347 }
348 if {$comdate != {}} {
cfb4563c 349 set cdate($id) $comdate
1db95b00 350 }
e5c2d856
PM
351 set commitinfo($id) [list $headline $auname $audate \
352 $comname $comdate $comment]
1db95b00
PM
353}
354
887fe3c4 355proc readrefs {} {
106288cb 356 global tagids idtags headids idheads tagcontents
36a7cad6 357 global otherrefids idotherrefs
106288cb 358
b5c2f306
SV
359 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
360 catch {unset $v}
361 }
36a7cad6
JH
362 set refd [open [list | git-ls-remote [gitdir]] r]
363 while {0 <= [set n [gets $refd line]]} {
364 if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
365 match id path]} {
366 continue
c2f6a022 367 }
36a7cad6
JH
368 if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
369 set type others
370 set name $path
887fe3c4 371 }
36a7cad6
JH
372 if {$type == "tags"} {
373 set tagids($name) $id
374 lappend idtags($id) $name
375 set obj {}
376 set type {}
377 set tag {}
378 catch {
379 set commit [exec git-rev-parse "$id^0"]
380 if {"$commit" != "$id"} {
381 set tagids($name) $commit
382 lappend idtags($commit) $name
383 }
384 }
385 catch {
386 set tagcontents($name) [exec git-cat-file tag "$id"]
f1d83ba3 387 }
36a7cad6
JH
388 } elseif { $type == "heads" } {
389 set headids($name) $id
390 lappend idheads($id) $name
391 } else {
392 set otherrefids($name) $id
393 lappend idotherrefs($id) $name
f1d83ba3
PM
394 }
395 }
36a7cad6 396 close $refd
887fe3c4
PM
397}
398
df3d83b1
PM
399proc error_popup msg {
400 set w .error
401 toplevel $w
402 wm transient $w .
403 message $w.m -text $msg -justify center -aspect 400
404 pack $w.m -side top -fill x -padx 20 -pady 20
405 button $w.ok -text OK -command "destroy $w"
406 pack $w.ok -side bottom -fill x
407 bind $w <Visibility> "grab $w; focus $w"
408 tkwait window $w
409}
410
b5c2f306 411proc makewindow {rargs} {
e5c2d856 412 global canv canv2 canv3 linespc charspc ctext cflist textfont
b74fd579 413 global findtype findtypemenu findloc findstring fstring geometry
887fe3c4 414 global entries sha1entry sha1string sha1but
94a2eede 415 global maincursor textcursor curtextcursor
712fcc08 416 global rowctxmenu mergemax
9a40c50c
PM
417
418 menu .bar
419 .bar add cascade -label "File" -menu .bar.file
420 menu .bar.file
b5c2f306 421 .bar.file add command -label "Update" -command [list updatecommits $rargs]
f1d83ba3 422 .bar.file add command -label "Reread references" -command rereadrefs
1d10f36d 423 .bar.file add command -label "Quit" -command doquit
712fcc08
PM
424 menu .bar.edit
425 .bar add cascade -label "Edit" -menu .bar.edit
426 .bar.edit add command -label "Preferences" -command doprefs
9a40c50c
PM
427 menu .bar.help
428 .bar add cascade -label "Help" -menu .bar.help
429 .bar.help add command -label "About gitk" -command about
430 . configure -menu .bar
431
0fba86b3 432 if {![info exists geometry(canv1)]} {
2ed49d54
JH
433 set geometry(canv1) [expr {45 * $charspc}]
434 set geometry(canv2) [expr {30 * $charspc}]
435 set geometry(canv3) [expr {15 * $charspc}]
436 set geometry(canvh) [expr {25 * $linespc + 4}]
0fba86b3
PM
437 set geometry(ctextw) 80
438 set geometry(ctexth) 30
439 set geometry(cflistw) 30
440 }
0327d27a 441 panedwindow .ctop -orient vertical
0fba86b3
PM
442 if {[info exists geometry(width)]} {
443 .ctop conf -width $geometry(width) -height $geometry(height)
17386066
PM
444 set texth [expr {$geometry(height) - $geometry(canvh) - 56}]
445 set geometry(ctexth) [expr {($texth - 8) /
446 [font metrics $textfont -linespace]}]
0fba86b3 447 }
98f350e5
PM
448 frame .ctop.top
449 frame .ctop.top.bar
450 pack .ctop.top.bar -side bottom -fill x
451 set cscroll .ctop.top.csb
452 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
453 pack $cscroll -side right -fill y
454 panedwindow .ctop.top.clist -orient horizontal -sashpad 0 -handlesize 4
455 pack .ctop.top.clist -side top -fill both -expand 1
456 .ctop add .ctop.top
457 set canv .ctop.top.clist.canv
0fba86b3 458 canvas $canv -height $geometry(canvh) -width $geometry(canv1) \
b5721c72
PM
459 -bg white -bd 0 \
460 -yscrollincr $linespc -yscrollcommand "$cscroll set"
98f350e5
PM
461 .ctop.top.clist add $canv
462 set canv2 .ctop.top.clist.canv2
0fba86b3 463 canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \
b5721c72 464 -bg white -bd 0 -yscrollincr $linespc
98f350e5
PM
465 .ctop.top.clist add $canv2
466 set canv3 .ctop.top.clist.canv3
0fba86b3 467 canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \
b5721c72 468 -bg white -bd 0 -yscrollincr $linespc
98f350e5 469 .ctop.top.clist add $canv3
43bddeb4 470 bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}
98f350e5
PM
471
472 set sha1entry .ctop.top.bar.sha1
887fe3c4
PM
473 set entries $sha1entry
474 set sha1but .ctop.top.bar.sha1label
475 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
476 -command gotocommit -width 8
477 $sha1but conf -disabledforeground [$sha1but cget -foreground]
98f350e5 478 pack .ctop.top.bar.sha1label -side left
887fe3c4
PM
479 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
480 trace add variable sha1string write sha1change
98f350e5 481 pack $sha1entry -side left -pady 2
d698206c
PM
482
483 image create bitmap bm-left -data {
484 #define left_width 16
485 #define left_height 16
486 static unsigned char left_bits[] = {
487 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
488 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
489 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
490 }
491 image create bitmap bm-right -data {
492 #define right_width 16
493 #define right_height 16
494 static unsigned char right_bits[] = {
495 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
496 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
497 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
498 }
499 button .ctop.top.bar.leftbut -image bm-left -command goback \
500 -state disabled -width 26
501 pack .ctop.top.bar.leftbut -side left -fill y
502 button .ctop.top.bar.rightbut -image bm-right -command goforw \
503 -state disabled -width 26
504 pack .ctop.top.bar.rightbut -side left -fill y
505
98f350e5
PM
506 button .ctop.top.bar.findbut -text "Find" -command dofind
507 pack .ctop.top.bar.findbut -side left
508 set findstring {}
df3d83b1 509 set fstring .ctop.top.bar.findstring
887fe3c4 510 lappend entries $fstring
df3d83b1 511 entry $fstring -width 30 -font $textfont -textvariable findstring
df3d83b1 512 pack $fstring -side left -expand 1 -fill x
98f350e5 513 set findtype Exact
b74fd579
PM
514 set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
515 findtype Exact IgnCase Regexp]
98f350e5
PM
516 set findloc "All fields"
517 tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \
b74fd579 518 Comments Author Committer Files Pickaxe
98f350e5
PM
519 pack .ctop.top.bar.findloc -side right
520 pack .ctop.top.bar.findtype -side right
b74fd579
PM
521 # for making sure type==Exact whenever loc==Pickaxe
522 trace add variable findloc write findlocchange
b5721c72 523
5ad588de
PM
524 panedwindow .ctop.cdet -orient horizontal
525 .ctop add .ctop.cdet
d2610d11
PM
526 frame .ctop.cdet.left
527 set ctext .ctop.cdet.left.ctext
0fba86b3
PM
528 text $ctext -bg white -state disabled -font $textfont \
529 -width $geometry(ctextw) -height $geometry(ctexth) \
b1ba39e7 530 -yscrollcommand ".ctop.cdet.left.sb set" -wrap none
d2610d11
PM
531 scrollbar .ctop.cdet.left.sb -command "$ctext yview"
532 pack .ctop.cdet.left.sb -side right -fill y
533 pack $ctext -side left -fill both -expand 1
534 .ctop.cdet add .ctop.cdet.left
535
f0654861 536 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
712fcc08
PM
537 $ctext tag conf hunksep -fore blue
538 $ctext tag conf d0 -fore red
539 $ctext tag conf d1 -fore "#00a000"
540 $ctext tag conf m0 -fore red
541 $ctext tag conf m1 -fore blue
542 $ctext tag conf m2 -fore green
543 $ctext tag conf m3 -fore purple
544 $ctext tag conf m4 -fore brown
545 $ctext tag conf mmax -fore darkgrey
546 set mergemax 5
547 $ctext tag conf mresult -font [concat $textfont bold]
548 $ctext tag conf msep -font [concat $textfont bold]
549 $ctext tag conf found -back yellow
e5c2d856 550
d2610d11
PM
551 frame .ctop.cdet.right
552 set cflist .ctop.cdet.right.cfiles
17386066 553 listbox $cflist -bg white -selectmode extended -width $geometry(cflistw) \
d2610d11
PM
554 -yscrollcommand ".ctop.cdet.right.sb set"
555 scrollbar .ctop.cdet.right.sb -command "$cflist yview"
556 pack .ctop.cdet.right.sb -side right -fill y
557 pack $cflist -side left -fill both -expand 1
558 .ctop.cdet add .ctop.cdet.right
0fba86b3 559 bind .ctop.cdet <Configure> {resizecdetpanes %W %w}
d2610d11 560
0327d27a 561 pack .ctop -side top -fill both -expand 1
1db95b00 562
c8dfbcf9
PM
563 bindall <1> {selcanvline %W %x %y}
564 #bindall <B1-Motion> {selcanvline %W %x %y}
cfb4563c
PM
565 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
566 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
b5721c72
PM
567 bindall <2> "allcanvs scan mark 0 %y"
568 bindall <B2-Motion> "allcanvs scan dragto 0 %y"
17386066
PM
569 bind . <Key-Up> "selnextline -1"
570 bind . <Key-Down> "selnextline 1"
6e2dda35
RS
571 bind . <Key-Right> "goforw"
572 bind . <Key-Left> "goback"
cfb4563c
PM
573 bind . <Key-Prior> "allcanvs yview scroll -1 pages"
574 bind . <Key-Next> "allcanvs yview scroll 1 pages"
575 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
576 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
577 bindkey <Key-space> "$ctext yview scroll 1 pages"
df3d83b1
PM
578 bindkey p "selnextline -1"
579 bindkey n "selnextline 1"
6e2dda35
RS
580 bindkey z "goback"
581 bindkey x "goforw"
582 bindkey i "selnextline -1"
583 bindkey k "selnextline 1"
584 bindkey j "goback"
585 bindkey l "goforw"
cfb4563c
PM
586 bindkey b "$ctext yview scroll -1 pages"
587 bindkey d "$ctext yview scroll 18 units"
588 bindkey u "$ctext yview scroll -18 units"
b74fd579
PM
589 bindkey / {findnext 1}
590 bindkey <Key-Return> {findnext 0}
df3d83b1 591 bindkey ? findprev
39ad8570 592 bindkey f nextfile
1d10f36d 593 bind . <Control-q> doquit
98f350e5 594 bind . <Control-f> dofind
b74fd579 595 bind . <Control-g> {findnext 0}
98f350e5 596 bind . <Control-r> findprev
1d10f36d
PM
597 bind . <Control-equal> {incrfont 1}
598 bind . <Control-KP_Add> {incrfont 1}
599 bind . <Control-minus> {incrfont -1}
600 bind . <Control-KP_Subtract> {incrfont -1}
e5c2d856 601 bind $cflist <<ListboxSelect>> listboxsel
0fba86b3 602 bind . <Destroy> {savestuff %W}
df3d83b1 603 bind . <Button-1> "click %W"
17386066 604 bind $fstring <Key-Return> dofind
887fe3c4 605 bind $sha1entry <Key-Return> gotocommit
ee3dc72e 606 bind $sha1entry <<PasteSelection>> clearsha1
ea13cba1
PM
607
608 set maincursor [. cget -cursor]
609 set textcursor [$ctext cget -cursor]
94a2eede 610 set curtextcursor $textcursor
84ba7345 611
c8dfbcf9
PM
612 set rowctxmenu .rowctxmenu
613 menu $rowctxmenu -tearoff 0
614 $rowctxmenu add command -label "Diff this -> selected" \
615 -command {diffvssel 0}
616 $rowctxmenu add command -label "Diff selected -> this" \
617 -command {diffvssel 1}
74daedb6 618 $rowctxmenu add command -label "Make patch" -command mkpatch
bdbfbe3d 619 $rowctxmenu add command -label "Create tag" -command mktag
4a2139f5 620 $rowctxmenu add command -label "Write commit to file" -command writecommit
df3d83b1
PM
621}
622
623# when we make a key binding for the toplevel, make sure
624# it doesn't get triggered when that key is pressed in the
625# find string entry widget.
626proc bindkey {ev script} {
887fe3c4 627 global entries
df3d83b1
PM
628 bind . $ev $script
629 set escript [bind Entry $ev]
630 if {$escript == {}} {
631 set escript [bind Entry <Key>]
632 }
887fe3c4
PM
633 foreach e $entries {
634 bind $e $ev "$escript; break"
635 }
df3d83b1
PM
636}
637
638# set the focus back to the toplevel for any click outside
887fe3c4 639# the entry widgets
df3d83b1 640proc click {w} {
887fe3c4
PM
641 global entries
642 foreach e $entries {
643 if {$w == $e} return
df3d83b1 644 }
887fe3c4 645 focus .
0fba86b3
PM
646}
647
648proc savestuff {w} {
649 global canv canv2 canv3 ctext cflist mainfont textfont
712fcc08 650 global stuffsaved findmergefiles maxgraphpct
04c13d38 651 global maxwidth
4ef17537 652
0fba86b3 653 if {$stuffsaved} return
df3d83b1 654 if {![winfo viewable .]} return
0fba86b3
PM
655 catch {
656 set f [open "~/.gitk-new" w]
f0654861
PM
657 puts $f [list set mainfont $mainfont]
658 puts $f [list set textfont $textfont]
659 puts $f [list set findmergefiles $findmergefiles]
8d858d1a 660 puts $f [list set maxgraphpct $maxgraphpct]
04c13d38 661 puts $f [list set maxwidth $maxwidth]
0fba86b3
PM
662 puts $f "set geometry(width) [winfo width .ctop]"
663 puts $f "set geometry(height) [winfo height .ctop]"
2ed49d54
JH
664 puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]"
665 puts $f "set geometry(canv2) [expr {[winfo width $canv2]-2}]"
666 puts $f "set geometry(canv3) [expr {[winfo width $canv3]-2}]"
667 puts $f "set geometry(canvh) [expr {[winfo height $canv]-2}]"
0fba86b3
PM
668 set wid [expr {([winfo width $ctext] - 8) \
669 / [font measure $textfont "0"]}]
0fba86b3 670 puts $f "set geometry(ctextw) $wid"
0fba86b3
PM
671 set wid [expr {([winfo width $cflist] - 11) \
672 / [font measure [$cflist cget -font] "0"]}]
673 puts $f "set geometry(cflistw) $wid"
674 close $f
675 file rename -force "~/.gitk-new" "~/.gitk"
676 }
677 set stuffsaved 1
1db95b00
PM
678}
679
43bddeb4
PM
680proc resizeclistpanes {win w} {
681 global oldwidth
682 if [info exists oldwidth($win)] {
683 set s0 [$win sash coord 0]
684 set s1 [$win sash coord 1]
685 if {$w < 60} {
686 set sash0 [expr {int($w/2 - 2)}]
687 set sash1 [expr {int($w*5/6 - 2)}]
688 } else {
689 set factor [expr {1.0 * $w / $oldwidth($win)}]
690 set sash0 [expr {int($factor * [lindex $s0 0])}]
691 set sash1 [expr {int($factor * [lindex $s1 0])}]
692 if {$sash0 < 30} {
693 set sash0 30
694 }
695 if {$sash1 < $sash0 + 20} {
2ed49d54 696 set sash1 [expr {$sash0 + 20}]
43bddeb4
PM
697 }
698 if {$sash1 > $w - 10} {
2ed49d54 699 set sash1 [expr {$w - 10}]
43bddeb4 700 if {$sash0 > $sash1 - 20} {
2ed49d54 701 set sash0 [expr {$sash1 - 20}]
43bddeb4
PM
702 }
703 }
704 }
705 $win sash place 0 $sash0 [lindex $s0 1]
706 $win sash place 1 $sash1 [lindex $s1 1]
707 }
708 set oldwidth($win) $w
709}
710
711proc resizecdetpanes {win w} {
712 global oldwidth
713 if [info exists oldwidth($win)] {
714 set s0 [$win sash coord 0]
715 if {$w < 60} {
716 set sash0 [expr {int($w*3/4 - 2)}]
717 } else {
718 set factor [expr {1.0 * $w / $oldwidth($win)}]
719 set sash0 [expr {int($factor * [lindex $s0 0])}]
720 if {$sash0 < 45} {
721 set sash0 45
722 }
723 if {$sash0 > $w - 15} {
2ed49d54 724 set sash0 [expr {$w - 15}]
43bddeb4
PM
725 }
726 }
727 $win sash place 0 $sash0 [lindex $s0 1]
728 }
729 set oldwidth($win) $w
730}
731
b5721c72
PM
732proc allcanvs args {
733 global canv canv2 canv3
734 eval $canv $args
735 eval $canv2 $args
736 eval $canv3 $args
737}
738
739proc bindall {event action} {
740 global canv canv2 canv3
741 bind $canv $event $action
742 bind $canv2 $event $action
743 bind $canv3 $event $action
744}
745
9a40c50c
PM
746proc about {} {
747 set w .about
748 if {[winfo exists $w]} {
749 raise $w
750 return
751 }
752 toplevel $w
753 wm title $w "About gitk"
754 message $w.m -text {
c8dfbcf9 755Gitk version 1.2
9a40c50c
PM
756
757