]> git.ipfire.org Git - thirdparty/git.git/blame - gitk
autoconf: Add config.cache to .gitignore
[thirdparty/git.git] / gitk
CommitLineData
1db95b00
PM
1#!/bin/sh
2# Tcl ignores the next line -*- tcl -*- \
9e026d39 3exec wish "$0" -- "$@"
1db95b00 4
e1a7c81f 5# Copyright (C) 2005-2006 Paul Mackerras. All rights reserved.
1db95b00
PM
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
da7c24dd 19proc start_rev_list {view} {
d1e46756 20 global startmsecs nextupdate
9f1afe05 21 global commfd leftover tclencoding datemode
098dd8a3 22 global viewargs viewfiles commitidx
9ccbdfbf 23
9ccbdfbf 24 set startmsecs [clock clicks -milliseconds]
2ed49d54 25 set nextupdate [expr {$startmsecs + 100}]
da7c24dd 26 set commitidx($view) 0
098dd8a3 27 set args $viewargs($view)
da7c24dd
PM
28 if {$viewfiles($view) ne {}} {
29 set args [concat $args "--" $viewfiles($view)]
a8aaf19c 30 }
9f1afe05
PM
31 set order "--topo-order"
32 if {$datemode} {
33 set order "--date-order"
34 }
418c4c7b 35 if {[catch {
8974c6f9 36 set fd [open [concat | git rev-list --header $order \
da7c24dd 37 --parents --boundary --default HEAD $args] r]
418c4c7b 38 } err]} {
8974c6f9 39 puts stderr "Error executing git rev-list: $err"
1d10f36d
PM
40 exit 1
41 }
da7c24dd
PM
42 set commfd($view) $fd
43 set leftover($view) {}
44 fconfigure $fd -blocking 0 -translation lf
fd8ccbec 45 if {$tclencoding != {}} {
da7c24dd 46 fconfigure $fd -encoding $tclencoding
fd8ccbec 47 }
da7c24dd
PM
48 fileevent $fd readable [list getcommitlines $fd $view]
49 nowbusy $view
38ad0910
PM
50}
51
22626ef4 52proc stop_rev_list {} {
da7c24dd 53 global commfd curview
22626ef4 54
da7c24dd
PM
55 if {![info exists commfd($curview)]} return
56 set fd $commfd($curview)
22626ef4 57 catch {
da7c24dd 58 set pid [pid $fd]
22626ef4
PM
59 exec kill $pid
60 }
da7c24dd
PM
61 catch {close $fd}
62 unset commfd($curview)
22626ef4
PM
63}
64
a8aaf19c 65proc getcommits {} {
da7c24dd 66 global phase canv mainfont curview
38ad0910 67
38ad0910 68 set phase getcommits
da7c24dd
PM
69 initlayout
70 start_rev_list $curview
098dd8a3 71 show_status "Reading commits..."
1d10f36d
PM
72}
73
da7c24dd 74proc getcommitlines {fd view} {
8ed16484 75 global commitlisted nextupdate
da7c24dd 76 global leftover commfd
8ed16484 77 global displayorder commitidx commitrow commitdata
da7c24dd
PM
78 global parentlist childlist children curview hlview
79 global vparentlist vchildlist vdisporder vcmitlisted
9ccbdfbf 80
d1e46756 81 set stuff [read $fd 500000]
b490a991 82 if {$stuff == {}} {
da7c24dd 83 if {![eof $fd]} return
098dd8a3 84 global viewname
da7c24dd 85 unset commfd($view)
098dd8a3 86 notbusy $view
f0654861 87 # set it blocking so we wait for the process to terminate
da7c24dd 88 fconfigure $fd -blocking 1
098dd8a3
PM
89 if {[catch {close $fd} err]} {
90 set fv {}
91 if {$view != $curview} {
92 set fv " for the \"$viewname($view)\" view"
da7c24dd 93 }
098dd8a3
PM
94 if {[string range $err 0 4] == "usage"} {
95 set err "Gitk: error reading commits$fv:\
8974c6f9 96 bad arguments to git rev-list."
098dd8a3
PM
97 if {$viewname($view) eq "Command line"} {
98 append err \
8974c6f9 99 " (Note: arguments to gitk are passed to git rev-list\
098dd8a3
PM
100 to allow selection of commits to be displayed.)"
101 }
102 } else {
103 set err "Error reading commits$fv: $err"
104 }
105 error_popup $err
1d10f36d 106 }
098dd8a3
PM
107 if {$view == $curview} {
108 after idle finishcommits
9a40c50c 109 }
098dd8a3 110 return
9a40c50c 111 }
b490a991 112 set start 0
8f7d0cec 113 set gotsome 0
b490a991
PM
114 while 1 {
115 set i [string first "\0" $stuff $start]
116 if {$i < 0} {
da7c24dd 117 append leftover($view) [string range $stuff $start end]
9f1afe05 118 break
9ccbdfbf 119 }
b490a991 120 if {$start == 0} {
da7c24dd 121 set cmit $leftover($view)
8f7d0cec 122 append cmit [string range $stuff 0 [expr {$i - 1}]]
da7c24dd 123 set leftover($view) {}
8f7d0cec
PM
124 } else {
125 set cmit [string range $stuff $start [expr {$i - 1}]]
b490a991
PM
126 }
127 set start [expr {$i + 1}]
e5ea701b
PM
128 set j [string first "\n" $cmit]
129 set ok 0
16c1ff96 130 set listed 1
e5ea701b
PM
131 if {$j >= 0} {
132 set ids [string range $cmit 0 [expr {$j - 1}]]
16c1ff96
PM
133 if {[string range $ids 0 0] == "-"} {
134 set listed 0
135 set ids [string range $ids 1 end]
136 }
e5ea701b
PM
137 set ok 1
138 foreach id $ids {
8f7d0cec 139 if {[string length $id] != 40} {
e5ea701b
PM
140 set ok 0
141 break
142 }
143 }
144 }
145 if {!$ok} {
7e952e79
PM
146 set shortcmit $cmit
147 if {[string length $shortcmit] > 80} {
148 set shortcmit "[string range $shortcmit 0 80]..."
149 }
8974c6f9 150 error_popup "Can't parse git rev-list output: {$shortcmit}"
b490a991
PM
151 exit 1
152 }
e5ea701b 153 set id [lindex $ids 0]
16c1ff96
PM
154 if {$listed} {
155 set olds [lrange $ids 1 end]
50b44ece 156 set i 0
79b2c75e 157 foreach p $olds {
50b44ece 158 if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
da7c24dd 159 lappend children($view,$p) $id
50b44ece
PM
160 }
161 incr i
79b2c75e 162 }
16c1ff96
PM
163 } else {
164 set olds {}
165 }
da7c24dd
PM
166 if {![info exists children($view,$id)]} {
167 set children($view,$id) {}
79b2c75e 168 }
f7a3e8d2 169 set commitdata($id) [string range $cmit [expr {$j + 1}] end]
da7c24dd
PM
170 set commitrow($view,$id) $commitidx($view)
171 incr commitidx($view)
172 if {$view == $curview} {
173 lappend parentlist $olds
174 lappend childlist $children($view,$id)
175 lappend displayorder $id
176 lappend commitlisted $listed
177 } else {
178 lappend vparentlist($view) $olds
179 lappend vchildlist($view) $children($view,$id)
180 lappend vdisporder($view) $id
181 lappend vcmitlisted($view) $listed
182 }
8f7d0cec
PM
183 set gotsome 1
184 }
185 if {$gotsome} {
da7c24dd 186 if {$view == $curview} {
d1e46756 187 while {[layoutmore $nextupdate]} doupdate
da7c24dd 188 } elseif {[info exists hlview] && $view == $hlview} {
908c3585 189 vhighlightmore
da7c24dd 190 }
9f1afe05 191 }
9f1afe05 192 if {[clock clicks -milliseconds] >= $nextupdate} {
da7c24dd 193 doupdate
9ccbdfbf
PM
194 }
195}
196
da7c24dd 197proc doupdate {} {
d1e46756 198 global commfd nextupdate numcommits
9ccbdfbf 199
da7c24dd
PM
200 foreach v [array names commfd] {
201 fileevent $commfd($v) readable {}
b664550c 202 }
9ccbdfbf 203 update
b664550c 204 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
da7c24dd
PM
205 foreach v [array names commfd] {
206 set fd $commfd($v)
207 fileevent $fd readable [list getcommitlines $fd $v]
b664550c 208 }
1db95b00
PM
209}
210
211proc readcommit {id} {
8974c6f9 212 if {[catch {set contents [exec git cat-file commit $id]}]} return
8f7d0cec 213 parsecommit $id $contents 0
b490a991
PM
214}
215
50b44ece 216proc updatecommits {} {
098dd8a3 217 global viewdata curview phase displayorder
908c3585 218 global children commitrow selectedline thickerline
50b44ece 219
22626ef4
PM
220 if {$phase ne {}} {
221 stop_rev_list
222 set phase {}
fd8ccbec 223 }
d94f8cd6 224 set n $curview
da7c24dd
PM
225 foreach id $displayorder {
226 catch {unset children($n,$id)}
227 catch {unset commitrow($n,$id)}
228 }
d94f8cd6 229 set curview -1
908c3585
PM
230 catch {unset selectedline}
231 catch {unset thickerline}
d94f8cd6 232 catch {unset viewdata($n)}
2d71bccc 233 discardallcommits
fd8ccbec 234 readrefs
d94f8cd6 235 showview $n
fd8ccbec
PM
236}
237
8f7d0cec 238proc parsecommit {id contents listed} {
b5c2f306
SV
239 global commitinfo cdate
240
241 set inhdr 1
242 set comment {}
243 set headline {}
244 set auname {}
245 set audate {}
246 set comname {}
247 set comdate {}
232475d3
PM
248 set hdrend [string first "\n\n" $contents]
249 if {$hdrend < 0} {
250 # should never happen...
251 set hdrend [string length $contents]
252 }
253 set header [string range $contents 0 [expr {$hdrend - 1}]]
254 set comment [string range $contents [expr {$hdrend + 2}] end]
255 foreach line [split $header "\n"] {
256 set tag [lindex $line 0]
257 if {$tag == "author"} {
258 set audate [lindex $line end-1]
259 set auname [lrange $line 1 end-2]
260 } elseif {$tag == "committer"} {
261 set comdate [lindex $line end-1]
262 set comname [lrange $line 1 end-2]
1db95b00
PM
263 }
264 }
232475d3
PM
265 set headline {}
266 # take the first line of the comment as the headline
267 set i [string first "\n" $comment]
268 if {$i >= 0} {
269 set headline [string trim [string range $comment 0 $i]]
f6e2869f
PM
270 } else {
271 set headline $comment
232475d3
PM
272 }
273 if {!$listed} {
8974c6f9
TH
274 # git rev-list indents the comment by 4 spaces;
275 # if we got this via git cat-file, add the indentation
232475d3
PM
276 set newcomment {}
277 foreach line [split $comment "\n"] {
278 append newcomment " "
279 append newcomment $line
f6e2869f 280 append newcomment "\n"
232475d3
PM
281 }
282 set comment $newcomment
1db95b00
PM
283 }
284 if {$comdate != {}} {
cfb4563c 285 set cdate($id) $comdate
1db95b00 286 }
e5c2d856
PM
287 set commitinfo($id) [list $headline $auname $audate \
288 $comname $comdate $comment]
1db95b00
PM
289}
290
f7a3e8d2 291proc getcommit {id} {
79b2c75e 292 global commitdata commitinfo
8ed16484 293
f7a3e8d2
PM
294 if {[info exists commitdata($id)]} {
295 parsecommit $id $commitdata($id) 1
8ed16484
PM
296 } else {
297 readcommit $id
298 if {![info exists commitinfo($id)]} {
299 set commitinfo($id) {"No commit information available"}
8ed16484
PM
300 }
301 }
302 return 1
303}
304
887fe3c4 305proc readrefs {} {
106288cb 306 global tagids idtags headids idheads tagcontents
8a48571c 307 global otherrefids idotherrefs mainhead
106288cb 308
b5c2f306
SV
309 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
310 catch {unset $v}
311 }
ce088722 312 set refd [open [list | git ls-remote [gitdir]] r]
36a7cad6
JH
313 while {0 <= [set n [gets $refd line]]} {
314 if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
315 match id path]} {
316 continue
c2f6a022 317 }
a970fcf2
JW
318 if {[regexp {^remotes/.*/HEAD$} $path match]} {
319 continue
320 }
36a7cad6
JH
321 if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
322 set type others
323 set name $path
887fe3c4 324 }
a970fcf2
JW
325 if {[regexp {^remotes/} $path match]} {
326 set type heads
327 }
36a7cad6
JH
328 if {$type == "tags"} {
329 set tagids($name) $id
330 lappend idtags($id) $name
331 set obj {}
332 set type {}
333 set tag {}
334 catch {
8974c6f9 335 set commit [exec git rev-parse "$id^0"]
e1a7c81f 336 if {$commit != $id} {
36a7cad6
JH
337 set tagids($name) $commit
338 lappend idtags($commit) $name
339 }
340 }
341 catch {
e1a7c81f 342 set tagcontents($name) [exec git cat-file tag $id]
f1d83ba3 343 }
36a7cad6
JH
344 } elseif { $type == "heads" } {
345 set headids($name) $id
346 lappend idheads($id) $name
347 } else {
348 set otherrefids($name) $id
349 lappend idotherrefs($id) $name
f1d83ba3
PM
350 }
351 }
36a7cad6 352 close $refd
8a48571c
PM
353 set mainhead {}
354 catch {
355 set thehead [exec git symbolic-ref HEAD]
356 if {[string match "refs/heads/*" $thehead]} {
357 set mainhead [string range $thehead 11 end]
358 }
359 }
887fe3c4
PM
360}
361
e54be9e3 362proc show_error {w top msg} {
df3d83b1
PM
363 message $w.m -text $msg -justify center -aspect 400
364 pack $w.m -side top -fill x -padx 20 -pady 20
e54be9e3 365 button $w.ok -text OK -command "destroy $top"
df3d83b1 366 pack $w.ok -side bottom -fill x
e54be9e3
PM
367 bind $top <Visibility> "grab $top; focus $top"
368 bind $top <Key-Return> "destroy $top"
369 tkwait window $top
df3d83b1
PM
370}
371
098dd8a3
PM
372proc error_popup msg {
373 set w .error
374 toplevel $w
375 wm transient $w .
e54be9e3 376 show_error $w $w $msg
098dd8a3
PM
377}
378
10299152
PM
379proc confirm_popup msg {
380 global confirm_ok
381 set confirm_ok 0
382 set w .confirm
383 toplevel $w
384 wm transient $w .
385 message $w.m -text $msg -justify center -aspect 400
386 pack $w.m -side top -fill x -padx 20 -pady 20
387 button $w.ok -text OK -command "set confirm_ok 1; destroy $w"
388 pack $w.ok -side left -fill x
389 button $w.cancel -text Cancel -command "destroy $w"
390 pack $w.cancel -side right -fill x
391 bind $w <Visibility> "grab $w; focus $w"
392 tkwait window $w
393 return $confirm_ok
394}
395
d94f8cd6 396proc makewindow {} {
fdedbcfb
PM
397 global canv canv2 canv3 linespc charspc ctext cflist
398 global textfont mainfont uifont
b74fd579 399 global findtype findtypemenu findloc findstring fstring geometry
887fe3c4 400 global entries sha1entry sha1string sha1but
94a2eede 401 global maincursor textcursor curtextcursor
f1b86294 402 global rowctxmenu mergemax wrapcomment
60f7a7dc 403 global highlight_files gdttype
3ea06f9f 404 global searchstring sstring
f8a2c0d1 405 global bgcolor fgcolor bglist fglist diffcolors
10299152 406 global headctxmenu
9a40c50c
PM
407
408 menu .bar
409 .bar add cascade -label "File" -menu .bar.file
4840be66 410 .bar configure -font $uifont
9a40c50c 411 menu .bar.file
50b44ece 412 .bar.file add command -label "Update" -command updatecommits
f1d83ba3 413 .bar.file add command -label "Reread references" -command rereadrefs
1d10f36d 414 .bar.file add command -label "Quit" -command doquit
4840be66 415 .bar.file configure -font $uifont
712fcc08
PM
416 menu .bar.edit
417 .bar add cascade -label "Edit" -menu .bar.edit
418 .bar.edit add command -label "Preferences" -command doprefs
4840be66 419 .bar.edit configure -font $uifont
da7c24dd 420
fdedbcfb 421 menu .bar.view -font $uifont
50b44ece 422 .bar add cascade -label "View" -menu .bar.view
da7c24dd
PM
423 .bar.view add command -label "New view..." -command {newview 0}
424 .bar.view add command -label "Edit view..." -command editview \
425 -state disabled
50b44ece
PM
426 .bar.view add command -label "Delete view" -command delview -state disabled
427 .bar.view add separator
a90a6d24
PM
428 .bar.view add radiobutton -label "All files" -command {showview 0} \
429 -variable selectedview -value 0
da7c24dd 430
9a40c50c
PM
431 menu .bar.help
432 .bar add cascade -label "Help" -menu .bar.help
433 .bar.help add command -label "About gitk" -command about
4e95e1f7 434 .bar.help add command -label "Key bindings" -command keys
4840be66 435 .bar.help configure -font $uifont
9a40c50c
PM
436 . configure -menu .bar
437
0fba86b3 438 if {![info exists geometry(canv1)]} {
2ed49d54
JH
439 set geometry(canv1) [expr {45 * $charspc}]
440 set geometry(canv2) [expr {30 * $charspc}]
441 set geometry(canv3) [expr {15 * $charspc}]
442 set geometry(canvh) [expr {25 * $linespc + 4}]
0fba86b3
PM
443 set geometry(ctextw) 80
444 set geometry(ctexth) 30
445 set geometry(cflistw) 30
446 }
0327d27a 447 panedwindow .ctop -orient vertical
0fba86b3
PM
448 if {[info exists geometry(width)]} {
449 .ctop conf -width $geometry(width) -height $geometry(height)
17386066
PM
450 set texth [expr {$geometry(height) - $geometry(canvh) - 56}]
451 set geometry(ctexth) [expr {($texth - 8) /
452 [font metrics $textfont -linespace]}]
0fba86b3 453 }
98f350e5
PM
454 frame .ctop.top
455 frame .ctop.top.bar
908c3585
PM
456 frame .ctop.top.lbar
457 pack .ctop.top.lbar -side bottom -fill x
98f350e5
PM
458 pack .ctop.top.bar -side bottom -fill x
459 set cscroll .ctop.top.csb
460 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
461 pack $cscroll -side right -fill y
462 panedwindow .ctop.top.clist -orient horizontal -sashpad 0 -handlesize 4
463 pack .ctop.top.clist -side top -fill both -expand 1
464 .ctop add .ctop.top
465 set canv .ctop.top.clist.canv
0fba86b3 466 canvas $canv -height $geometry(canvh) -width $geometry(canv1) \
f8a2c0d1 467 -background $bgcolor -bd 0 \
9f1afe05 468 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
98f350e5
PM
469 .ctop.top.clist add $canv
470 set canv2 .ctop.top.clist.canv2
0fba86b3 471 canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \
f8a2c0d1 472 -background $bgcolor -bd 0 -yscrollincr $linespc
98f350e5
PM
473 .ctop.top.clist add $canv2
474 set canv3 .ctop.top.clist.canv3
0fba86b3 475 canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \
f8a2c0d1 476 -background $bgcolor -bd 0 -yscrollincr $linespc
98f350e5 477 .ctop.top.clist add $canv3
43bddeb4 478 bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}
f8a2c0d1 479 lappend bglist $canv $canv2 $canv3
98f350e5
PM
480
481 set sha1entry .ctop.top.bar.sha1
887fe3c4
PM
482 set entries $sha1entry
483 set sha1but .ctop.top.bar.sha1label
484 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
4840be66 485 -command gotocommit -width 8 -font $uifont
887fe3c4 486 $sha1but conf -disabledforeground [$sha1but cget -foreground]
98f350e5 487 pack .ctop.top.bar.sha1label -side left
887fe3c4
PM
488 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
489 trace add variable sha1string write sha1change
98f350e5 490 pack $sha1entry -side left -pady 2
d698206c
PM
491
492 image create bitmap bm-left -data {
493 #define left_width 16
494 #define left_height 16
495 static unsigned char left_bits[] = {
496 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
497 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
498 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
499 }
500 image create bitmap bm-right -data {
501 #define right_width 16
502 #define right_height 16
503 static unsigned char right_bits[] = {
504 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
505 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
506 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
507 }
508 button .ctop.top.bar.leftbut -image bm-left -command goback \
509 -state disabled -width 26
510 pack .ctop.top.bar.leftbut -side left -fill y
511 button .ctop.top.bar.rightbut -image bm-right -command goforw \
512 -state disabled -width 26
513 pack .ctop.top.bar.rightbut -side left -fill y
514
4840be66 515 button .ctop.top.bar.findbut -text "Find" -command dofind -font $uifont
98f350e5
PM
516 pack .ctop.top.bar.findbut -side left
517 set findstring {}
df3d83b1 518 set fstring .ctop.top.bar.findstring
887fe3c4 519 lappend entries $fstring
908c3585 520 entry $fstring -width 30 -font $textfont -textvariable findstring
60f7a7dc 521 trace add variable findstring write find_change
df3d83b1 522 pack $fstring -side left -expand 1 -fill x
98f350e5 523 set findtype Exact
b74fd579
PM
524 set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
525 findtype Exact IgnCase Regexp]
60f7a7dc 526 trace add variable findtype write find_change
4840be66
KP
527 .ctop.top.bar.findtype configure -font $uifont
528 .ctop.top.bar.findtype.menu configure -font $uifont
98f350e5
PM
529 set findloc "All fields"
530 tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \
60f7a7dc
PM
531 Comments Author Committer
532 trace add variable findloc write find_change
4840be66
KP
533 .ctop.top.bar.findloc configure -font $uifont
534 .ctop.top.bar.findloc.menu configure -font $uifont
98f350e5
PM
535 pack .ctop.top.bar.findloc -side right
536 pack .ctop.top.bar.findtype -side right
b5721c72 537
60f7a7dc 538 label .ctop.top.lbar.flabel -text "Highlight: Commits " \
908c3585
PM
539 -font $uifont
540 pack .ctop.top.lbar.flabel -side left -fill y
60f7a7dc
PM
541 set gdttype "touching paths:"
542 set gm [tk_optionMenu .ctop.top.lbar.gdttype gdttype "touching paths:" \
543 "adding/removing string:"]
544 trace add variable gdttype write hfiles_change
545 $gm conf -font $uifont
546 .ctop.top.lbar.gdttype conf -font $uifont
547 pack .ctop.top.lbar.gdttype -side left -fill y
908c3585
PM
548 entry .ctop.top.lbar.fent -width 25 -font $textfont \
549 -textvariable highlight_files
550 trace add variable highlight_files write hfiles_change
551 lappend entries .ctop.top.lbar.fent
552 pack .ctop.top.lbar.fent -side left -fill x -expand 1
553 label .ctop.top.lbar.vlabel -text " OR in view" -font $uifont
554 pack .ctop.top.lbar.vlabel -side left -fill y
555 global viewhlmenu selectedhlview
556 set viewhlmenu [tk_optionMenu .ctop.top.lbar.vhl selectedhlview None]
557 $viewhlmenu entryconf 0 -command delvhighlight
63b79191
PM
558 $viewhlmenu conf -font $uifont
559 .ctop.top.lbar.vhl conf -font $uifont
908c3585 560 pack .ctop.top.lbar.vhl -side left -fill y
164ff275
PM
561 label .ctop.top.lbar.rlabel -text " OR " -font $uifont
562 pack .ctop.top.lbar.rlabel -side left -fill y
563 global highlight_related
564 set m [tk_optionMenu .ctop.top.lbar.relm highlight_related None \
565 "Descendent" "Not descendent" "Ancestor" "Not ancestor"]
566 $m conf -font $uifont
567 .ctop.top.lbar.relm conf -font $uifont
568 trace add variable highlight_related write vrel_change
569 pack .ctop.top.lbar.relm -side left -fill y
908c3585 570
5ad588de
PM
571 panedwindow .ctop.cdet -orient horizontal
572 .ctop add .ctop.cdet
d2610d11 573 frame .ctop.cdet.left
3ea06f9f
PM
574 frame .ctop.cdet.left.bot
575 pack .ctop.cdet.left.bot -side bottom -fill x
576 button .ctop.cdet.left.bot.search -text "Search" -command dosearch \
577 -font $uifont
578 pack .ctop.cdet.left.bot.search -side left -padx 5
579 set sstring .ctop.cdet.left.bot.sstring
580 entry $sstring -width 20 -font $textfont -textvariable searchstring
581 lappend entries $sstring
582 trace add variable searchstring write incrsearch
583 pack $sstring -side left -expand 1 -fill x
d2610d11 584 set ctext .ctop.cdet.left.ctext
f8a2c0d1
PM
585 text $ctext -background $bgcolor -foreground $fgcolor \
586 -state disabled -font $textfont \
0fba86b3 587 -width $geometry(ctextw) -height $geometry(ctexth) \
3ea06f9f 588 -yscrollcommand scrolltext -wrap none
d2610d11
PM
589 scrollbar .ctop.cdet.left.sb -command "$ctext yview"
590 pack .ctop.cdet.left.sb -side right -fill y
591 pack $ctext -side left -fill both -expand 1
592 .ctop.cdet add .ctop.cdet.left
f8a2c0d1
PM
593 lappend bglist $ctext
594 lappend fglist $ctext
d2610d11 595
f1b86294 596 $ctext tag conf comment -wrap $wrapcomment
f0654861 597 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
f8a2c0d1
PM
598 $ctext tag conf hunksep -fore [lindex $diffcolors 2]
599 $ctext tag conf d0 -fore [lindex $diffcolors 0]
600 $ctext tag conf d1 -fore [lindex $diffcolors 1]
712fcc08
PM
601 $ctext tag conf m0 -fore red
602 $ctext tag conf m1 -fore blue
603 $ctext tag conf m2 -fore green
604 $ctext tag conf m3 -fore purple
605 $ctext tag conf m4 -fore brown
b77b0278
PM
606 $ctext tag conf m5 -fore "#009090"
607 $ctext tag conf m6 -fore magenta
608 $ctext tag conf m7 -fore "#808000"
609 $ctext tag conf m8 -fore "#009000"
610 $ctext tag conf m9 -fore "#ff0080"
611 $ctext tag conf m10 -fore cyan
612 $ctext tag conf m11 -fore "#b07070"
613 $ctext tag conf m12 -fore "#70b0f0"
614 $ctext tag conf m13 -fore "#70f0b0"
615 $ctext tag conf m14 -fore "#f0b070"
616 $ctext tag conf m15 -fore "#ff70b0"
712fcc08 617 $ctext tag conf mmax -fore darkgrey
b77b0278 618 set mergemax 16
712fcc08
PM
619 $ctext tag conf mresult -font [concat $textfont bold]
620 $ctext tag conf msep -font [concat $textfont bold]
621 $ctext tag conf found -back yellow
e5c2d856 622
d2610d11 623 frame .ctop.cdet.right
f8b28a40
PM
624 frame .ctop.cdet.right.mode
625 radiobutton .ctop.cdet.right.mode.patch -text "Patch" \
626 -command reselectline -variable cmitmode -value "patch"
627 radiobutton .ctop.cdet.right.mode.tree -text "Tree" \
628 -command reselectline -variable cmitmode -value "tree"
629 grid .ctop.cdet.right.mode.patch .ctop.cdet.right.mode.tree -sticky ew
630 pack .ctop.cdet.right.mode -side top -fill x
d2610d11 631 set cflist .ctop.cdet.right.cfiles
7fcceed7 632 set indent [font measure $mainfont "nn"]
f8a2c0d1
PM
633 text $cflist -width $geometry(cflistw) \
634 -background $bgcolor -foreground $fgcolor \
635 -font $mainfont \
7fcceed7
PM
636 -tabs [list $indent [expr {2 * $indent}]] \
637 -yscrollcommand ".ctop.cdet.right.sb set" \
638 -cursor [. cget -cursor] \
639 -spacing1 1 -spacing3 1
f8a2c0d1
PM
640 lappend bglist $cflist
641 lappend fglist $cflist
d2610d11
PM
642 scrollbar .ctop.cdet.right.sb -command "$cflist yview"
643 pack .ctop.cdet.right.sb -side right -fill y
644 pack $cflist -side left -fill both -expand 1
89b11d3b
PM
645 $cflist tag configure highlight \
646 -background [$cflist cget -selectbackground]
63b79191 647 $cflist tag configure bold -font [concat $mainfont bold]
d2610d11 648 .ctop.cdet add .ctop.cdet.right
0fba86b3 649 bind .ctop.cdet <Configure> {resizecdetpanes %W %w}
d2610d11 650
0327d27a 651 pack .ctop -side top -fill both -expand 1
1db95b00 652
c8dfbcf9
PM
653 bindall <1> {selcanvline %W %x %y}
654 #bindall <B1-Motion> {selcanvline %W %x %y}
cfb4563c
PM
655 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
656 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
be0cd098
PM
657 bindall <2> "canvscan mark %W %x %y"
658 bindall <B2-Motion> "canvscan dragto %W %x %y"
6e5f7203
RN
659 bindkey <Home> selfirstline
660 bindkey <End> sellastline
17386066
PM
661 bind . <Key-Up> "selnextline -1"
662 bind . <Key-Down> "selnextline 1"
4e7d6779
PM
663 bind . <Shift-Key-Up> "next_highlight -1"
664 bind . <Shift-Key-Down> "next_highlight 1"
6e5f7203
RN
665 bindkey <Key-Right> "goforw"
666 bindkey <Key-Left> "goback"
667 bind . <Key-Prior> "selnextpage -1"
668 bind . <Key-Next> "selnextpage 1"
669 bind . <Control-Home> "allcanvs yview moveto 0.0"
670 bind . <Control-End> "allcanvs yview moveto 1.0"
671 bind . <Control-Key-Up> "allcanvs yview scroll -1 units"
672 bind . <Control-Key-Down> "allcanvs yview scroll 1 units"
673 bind . <Control-Key-Prior> "allcanvs yview scroll -1 pages"
674 bind . <Control-Key-Next> "allcanvs yview scroll 1 pages"
cfb4563c
PM
675 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
676 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
677 bindkey <Key-space> "$ctext yview scroll 1 pages"
df3d83b1
PM
678 bindkey p "selnextline -1"
679 bindkey n "selnextline 1"
6e2dda35
RS
680 bindkey z "goback"
681 bindkey x "goforw"
682 bindkey i "selnextline -1"
683 bindkey k "selnextline 1"
684 bindkey j "goback"
685 bindkey l "goforw"
cfb4563c
PM
686 bindkey b "$ctext yview scroll -1 pages"
687 bindkey d "$ctext yview scroll 18 units"
688 bindkey u "$ctext yview scroll -18 units"
b74fd579
PM
689 bindkey / {findnext 1}
690 bindkey <Key-Return> {findnext 0}
df3d83b1 691 bindkey ? findprev
39ad8570 692 bindkey f nextfile
1d10f36d 693 bind . <Control-q> doquit
98f350e5 694 bind . <Control-f> dofind
b74fd579 695 bind . <Control-g> {findnext 0}
1902c270 696 bind . <Control-r> dosearchback
3ea06f9f 697 bind . <Control-s> dosearch
1d10f36d
PM
698 bind . <Control-equal> {incrfont 1}
699 bind . <Control-KP_Add> {incrfont 1}
700 bind . <Control-minus> {incrfont -1}
701 bind . <Control-KP_Subtract> {incrfont -1}
0fba86b3 702 bind . <Destroy> {savestuff %W}
df3d83b1 703 bind . <Button-1> "click %W"
17386066 704 bind $fstring <Key-Return> dofind
887fe3c4 705 bind $sha1entry <Key-Return> gotocommit
ee3dc72e 706 bind $sha1entry <<PasteSelection>> clearsha1
7fcceed7
PM
707 bind $cflist <1> {sel_flist %W %x %y; break}
708 bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
f8b28a40 709 bind $cflist <ButtonRelease-1> {treeclick %W %x %y}
ea13cba1
PM
710
711 set maincursor [. cget -cursor]
712 set textcursor [$ctext cget -cursor]
94a2eede 713 set curtextcursor $textcursor
84ba7345 714
c8dfbcf9
PM
715 set rowctxmenu .rowctxmenu
716 menu $rowctxmenu -tearoff 0
717 $rowctxmenu add command -label "Diff this -> selected" \
718 -command {diffvssel 0}
719 $rowctxmenu add command -label "Diff selected -> this" \
720 -command {diffvssel 1}
74daedb6 721 $rowctxmenu add command -label "Make patch" -command mkpatch
bdbfbe3d 722 $rowctxmenu add command -label "Create tag" -command mktag
4a2139f5 723 $rowctxmenu add command -label "Write commit to file" -command writecommit
d6ac1a86 724 $rowctxmenu add command -label "Create new branch" -command mkbranch
ca6d8f58
PM
725 $rowctxmenu add command -label "Cherry-pick this commit" \
726 -command cherrypick
10299152
PM
727
728 set headctxmenu .headctxmenu
729 menu $headctxmenu -tearoff 0
730 $headctxmenu add command -label "Check out this branch" \
731 -command cobranch
732 $headctxmenu add command -label "Remove this branch" \
733 -command rmbranch
df3d83b1
PM
734}
735
be0cd098
PM
736# mouse-2 makes all windows scan vertically, but only the one
737# the cursor is in scans horizontally
738proc canvscan {op w x y} {
739 global canv canv2 canv3
740 foreach c [list $canv $canv2 $canv3] {
741 if {$c == $w} {
742 $c scan $op $x $y
743 } else {
744 $c scan $op 0 $y
745 }
746 }
747}
748
9f1afe05
PM
749proc scrollcanv {cscroll f0 f1} {
750 $cscroll set $f0 $f1
751 drawfrac $f0 $f1
908c3585 752 flushhighlights
9f1afe05
PM
753}
754
df3d83b1
PM
755# when we make a key binding for the toplevel, make sure
756# it doesn't get triggered when that key is pressed in the
757# find string entry widget.
758proc bindkey {ev script} {
887fe3c4 759 global entries
df3d83b1
PM
760 bind . $ev $script
761 set escript [bind Entry $ev]
762 if {$escript == {}} {
763 set escript [bind Entry <Key>]
764 }
887fe3c4
PM
765 foreach e $entries {
766 bind $e $ev "$escript; break"
767 }
df3d83b1
PM
768}
769
770# set the focus back to the toplevel for any click outside
887fe3c4 771# the entry widgets
df3d83b1 772proc click {w} {
887fe3c4
PM
773 global entries
774 foreach e $entries {
775 if {$w == $e} return
df3d83b1 776 }
887fe3c4 777 focus .
0fba86b3
PM
778}
779
780proc savestuff {w} {
4840be66 781 global canv canv2 canv3 ctext cflist mainfont textfont uifont
712fcc08 782 global stuffsaved findmergefiles maxgraphpct
b8ab2e17 783 global maxwidth showneartags
098dd8a3 784 global viewname viewfiles viewargs viewperm nextviewnum
f1b86294 785 global cmitmode wrapcomment
f8a2c0d1 786 global colors bgcolor fgcolor diffcolors
4ef17537 787
0fba86b3 788 if {$stuffsaved} return
df3d83b1 789 if {![winfo viewable .]} return
0fba86b3
PM
790 catch {
791 set f [open "~/.gitk-new" w]
f0654861
PM
792 puts $f [list set mainfont $mainfont]
793 puts $f [list set textfont $textfont]
4840be66 794 puts $f [list set uifont $uifont]
f0654861 795 puts $f [list set findmergefiles $findmergefiles]
8d858d1a 796 puts $f [list set maxgraphpct $maxgraphpct]
04c13d38 797 puts $f [list set maxwidth $maxwidth]
f8b28a40 798 puts $f [list set cmitmode $cmitmode]
f1b86294 799 puts $f [list set wrapcomment $wrapcomment]
b8ab2e17 800 puts $f [list set showneartags $showneartags]
f8a2c0d1
PM
801 puts $f [list set bgcolor $bgcolor]
802 puts $f [list set fgcolor $fgcolor]
803 puts $f [list set colors $colors]
804 puts $f [list set diffcolors $diffcolors]
0fba86b3
PM
805 puts $f "set geometry(width) [winfo width .ctop]"
806 puts $f "set geometry(height) [winfo height .ctop]"
2ed49d54
JH
807 puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]"
808 puts $f "set geometry(canv2) [expr {[winfo width $canv2]-2}]"
809 puts $f "set geometry(canv3) [expr {[winfo width $canv3]-2}]"
810 puts $f "set geometry(canvh) [expr {[winfo height $canv]-2}]"
0fba86b3
PM
811 set wid [expr {([winfo width $ctext] - 8) \
812 / [font measure $textfont "0"]}]
0fba86b3 813 puts $f "set geometry(ctextw) $wid"
0fba86b3
PM
814 set wid [expr {([winfo width $cflist] - 11) \
815 / [font measure [$cflist cget -font] "0"]}]
816 puts $f "set geometry(cflistw) $wid"
a90a6d24
PM
817 puts -nonewline $f "set permviews {"
818 for {set v 0} {$v < $nextviewnum} {incr v} {
819 if {$viewperm($v)} {
098dd8a3 820 puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}"
a90a6d24
PM
821 }
822 }
823 puts $f "}"
0fba86b3
PM
824 close $f
825 file rename -force "~/.gitk-new" "~/.gitk"
826 }
827 set stuffsaved 1
1db95b00
PM
828}
829
43bddeb4
PM
830proc resizeclistpanes {win w} {
831 global oldwidth
418c4c7b 832 if {[info exists oldwidth($win)]} {
43bddeb4
PM
833 set s0 [$win sash coord 0]
834 set s1 [$win sash coord 1]
835 if {$w < 60} {
836 set sash0 [expr {int($w/2 - 2)}]
837 set sash1 [expr {int($w*5/6 - 2)}]
838 } else {
839 set factor [expr {1.0 * $w / $oldwidth($win)}]
840 set sash0 [expr {int($factor * [lindex $s0 0])}]
841 set sash1 [expr {int($factor * [lindex $s1 0])}]
842 if {$sash0 < 30} {
843 set sash0 30
844 }
845 if {$sash1 < $sash0 + 20} {
2ed49d54 846 set sash1 [expr {$sash0 + 20}]
43bddeb4
PM
847 }
848 if {$sash1 > $w - 10} {
2ed49d54 849 set sash1 [expr {$w - 10}]
43bddeb4 850 if {$sash0 > $sash1 - 20} {
2ed49d54 851 set sash0 [expr {$sash1 - 20}]
43bddeb4
PM
852 }
853 }
854 }
855 $win sash place 0 $sash0 [lindex $s0 1]
856 $win sash place 1 $sash1 [lindex $s1 1]
857 }
858 set oldwidth($win) $w
859}
860
861proc resizecdetpanes {win w} {
862 global oldwidth
418c4c7b 863 if {[info exists oldwidth($win)]} {
43bddeb4
PM
864 set s0 [$win sash coord 0]
865 if {$w < 60} {
866 set sash0 [expr {int($w*3/4 - 2)}]
867 } else {
868 set factor [expr {1.0 * $w / $oldwidth($win)}]
869 set sash0 [expr {int($factor * [lindex $s0 0])}]
870 if {$sash0 < 45} {
871 set sash0 45
872 }
873 if {$sash0 > $w - 15} {
2ed49d54 874 set sash0 [expr {$w - 15}]
43bddeb4
PM
875 }
876 }
877 $win sash place 0 $sash0 [lindex $s0 1]
878 }
879 set oldwidth($win) $w
880}
881
b5721c72
PM
882proc allcanvs args {
883 global canv canv2 canv3
884 eval $canv $args
885 eval $canv2 $args
886 eval $canv3 $args
887}
888
889proc bindall {event action} {
890 global canv canv2 canv3
891 bind $canv $event $action
892 bind $canv2 $event $action
893 bind $canv3 $event $action
894}
895
9a40c50c
PM
896proc about {} {
897 set w .about
898 if {[winfo exists $w]} {
899 raise $w
900 return
901 }
902 toplevel $w
903 wm title $w "About gitk"
904 message $w.m -text {
9f1afe05 905Gitk - a commit viewer for git
9a40c50c 906
9f1afe05 907