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