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