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