🌐 AI搜索 & 代理 主页
blob: 87e71629afd4b2eca8d1c768bea0a20815405b2b [file] [log] [blame]
Paul Mackerras1db95b02005-05-09 04:08:391#!/bin/sh
2# Tcl ignores the next line -*- tcl -*- \
Paul Mackerras9e026d32005-09-27 00:29:413exec wish "$0" -- "$@"
Paul Mackerras1db95b02005-05-09 04:08:394
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
Junio C Hamano73b6a6c2005-07-28 07:28:4410proc gitdir {} {
11 global env
12 if {[info exists env(GIT_DIR)]} {
13 return $env(GIT_DIR)
14 } else {
15 return ".git"
16 }
17}
18
Sven Verdoolaegeb5c2f302005-11-29 21:15:5119proc parse_args {rargs} {
20 global parsed_args
Paul Mackerras9ccbdfb2005-06-16 00:27:2321
Paul Mackerras418c4c72006-02-06 22:10:1822 if {[catch {
Paul Mackerrasb490a992005-06-22 00:25:3823 set parse_args [concat --default HEAD $rargs]
Paul Mackerras2efef4b2005-06-21 00:20:0424 set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
Paul Mackerras418c4c72006-02-06 22:10:1825 }]} {
Paul Mackerrasb490a992005-06-22 00:25:3826 # if git-rev-parse failed for some reason...
Paul Mackerras2efef4b2005-06-21 00:20:0427 if {$rargs == {}} {
28 set rargs HEAD
29 }
Paul Mackerrasb490a992005-06-22 00:25:3830 set parsed_args $rargs
Paul Mackerras2efef4b2005-06-21 00:20:0431 }
Sven Verdoolaegeb5c2f302005-11-29 21:15:5132 return $parsed_args
33}
34
Paul Mackerras38ad0912005-12-01 11:42:4635proc start_rev_list {rlargs} {
Sven Verdoolaegeb5c2f302005-11-29 21:15:5136 global startmsecs nextupdate ncmupdate
Paul Mackerras9f1afe02006-02-19 11:44:4737 global commfd leftover tclencoding datemode
Paul Mackerras38ad0912005-12-01 11:42:4638
39 set startmsecs [clock clicks -milliseconds]
40 set nextupdate [expr {$startmsecs + 100}]
41 set ncmupdate 1
Paul Mackerras8f7d0ce2006-02-28 11:10:1942 initlayout
Paul Mackerras9f1afe02006-02-19 11:44:4743 set order "--topo-order"
44 if {$datemode} {
45 set order "--date-order"
46 }
Paul Mackerras418c4c72006-02-06 22:10:1847 if {[catch {
Paul Mackerras9f1afe02006-02-19 11:44:4748 set commfd [open [concat | git-rev-list --header $order \
Paul Mackerras16c1ff92006-03-30 07:43:5149 --parents --boundary $rlargs] r]
Paul Mackerras418c4c72006-02-06 22:10:1850 } err]} {
Paul Mackerras38ad0912005-12-01 11:42:4651 puts stderr "Error executing git-rev-list: $err"
52 exit 1
53 }
54 set leftover {}
Paul Mackerrasfd8ccbe2005-12-07 12:28:2255 fconfigure $commfd -blocking 0 -translation lf
56 if {$tclencoding != {}} {
57 fconfigure $commfd -encoding $tclencoding
58 }
Paul Mackerras38ad0912005-12-01 11:42:4659 fileevent $commfd readable [list getcommitlines $commfd]
60 . config -cursor watch
61 settextcursor watch
62}
63
64proc getcommits {rargs} {
Paul Mackerrasaa81d972006-02-28 00:27:1265 global phase canv mainfont
Sven Verdoolaegeb5c2f302005-11-29 21:15:5166
Sven Verdoolaegeb5c2f302005-11-29 21:15:5167 set phase getcommits
Paul Mackerras38ad0912005-12-01 11:42:4668 start_rev_list [parse_args $rargs]
Paul Mackerras1d10f362005-05-15 12:55:4769 $canv delete all
70 $canv create text 3 3 -anchor nw -text "Reading commits..." \
71 -font $mainfont -tags textitems
Paul Mackerras1d10f362005-05-15 12:55:4772}
73
Paul Mackerrasb490a992005-06-22 00:25:3874proc getcommitlines {commfd} {
Paul Mackerras8ed16482006-03-02 11:56:4475 global commitlisted nextupdate
76 global leftover
77 global displayorder commitidx commitrow commitdata
Paul Mackerras79b2c752006-04-02 10:47:4078 global parentlist childlist children
Paul Mackerras9ccbdfb2005-06-16 00:27:2379
Paul Mackerrasb490a992005-06-22 00:25:3880 set stuff [read $commfd]
81 if {$stuff == {}} {
Paul Mackerras1d10f362005-05-15 12:55:4782 if {![eof $commfd]} return
Paul Mackerrasf0654862005-07-18 18:29:0383 # set it blocking so we wait for the process to terminate
Paul Mackerrasdf3d83b2005-05-17 23:23:0784 fconfigure $commfd -blocking 1
Paul Mackerras1d10f362005-05-15 12:55:4785 if {![catch {close $commfd} err]} {
Paul Mackerras9ccbdfb2005-06-16 00:27:2386 after idle finishcommits
Paul Mackerras1d10f362005-05-15 12:55:4787 return
88 }
Paul Mackerras9a40c502005-05-12 23:46:1689 if {[string range $err 0 4] == "usage"} {
Paul Mackerras9ccbdfb2005-06-16 00:27:2390 set err \
Jeff Hobbs2ed49d52005-11-23 01:39:5391 "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.)"
Paul Mackerras9a40c502005-05-12 23:46:1694 } else {
Paul Mackerrasdf3d83b2005-05-17 23:23:0795 set err "Error reading commits: $err"
Paul Mackerras9a40c502005-05-12 23:46:1696 }
Paul Mackerrasdf3d83b2005-05-17 23:23:0797 error_popup $err
Paul Mackerras1d10f362005-05-15 12:55:4798 exit 1
Paul Mackerras9a40c502005-05-12 23:46:1699 }
Paul Mackerrasb490a992005-06-22 00:25:38100 set start 0
Paul Mackerras8f7d0ce2006-02-28 11:10:19101 set gotsome 0
Paul Mackerrasb490a992005-06-22 00:25:38102 while 1 {
103 set i [string first "\0" $stuff $start]
104 if {$i < 0} {
Paul Mackerras7e952e72005-06-27 10:04:26105 append leftover [string range $stuff $start end]
Paul Mackerras9f1afe02006-02-19 11:44:47106 break
Paul Mackerras9ccbdfb2005-06-16 00:27:23107 }
Paul Mackerrasb490a992005-06-22 00:25:38108 if {$start == 0} {
Paul Mackerras8f7d0ce2006-02-28 11:10:19109 set cmit $leftover
110 append cmit [string range $stuff 0 [expr {$i - 1}]]
Paul Mackerras7e952e72005-06-27 10:04:26111 set leftover {}
Paul Mackerras8f7d0ce2006-02-28 11:10:19112 } else {
113 set cmit [string range $stuff $start [expr {$i - 1}]]
Paul Mackerrasb490a992005-06-22 00:25:38114 }
115 set start [expr {$i + 1}]
Paul Mackerrase5ea7012005-08-18 10:40:39116 set j [string first "\n" $cmit]
117 set ok 0
Paul Mackerras16c1ff92006-03-30 07:43:51118 set listed 1
Paul Mackerrase5ea7012005-08-18 10:40:39119 if {$j >= 0} {
120 set ids [string range $cmit 0 [expr {$j - 1}]]
Paul Mackerras16c1ff92006-03-30 07:43:51121 if {[string range $ids 0 0] == "-"} {
122 set listed 0
123 set ids [string range $ids 1 end]
124 }
Paul Mackerrase5ea7012005-08-18 10:40:39125 set ok 1
126 foreach id $ids {
Paul Mackerras8f7d0ce2006-02-28 11:10:19127 if {[string length $id] != 40} {
Paul Mackerrase5ea7012005-08-18 10:40:39128 set ok 0
129 break
130 }
131 }
132 }
133 if {!$ok} {
Paul Mackerras7e952e72005-06-27 10:04:26134 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}"
Paul Mackerrasb490a992005-06-22 00:25:38139 exit 1
140 }
Paul Mackerrase5ea7012005-08-18 10:40:39141 set id [lindex $ids 0]
Paul Mackerras16c1ff92006-03-30 07:43:51142 if {$listed} {
143 set olds [lrange $ids 1 end]
Paul Mackerras79b2c752006-04-02 10:47:40144 if {[llength $olds] > 1} {
145 set olds [lsort -unique $olds]
146 }
147 foreach p $olds {
148 lappend children($p) $id
149 }
Paul Mackerras16c1ff92006-03-30 07:43:51150 } else {
151 set olds {}
152 }
Paul Mackerras79b2c752006-04-02 10:47:40153 lappend parentlist $olds
154 if {[info exists children($id)]} {
155 lappend childlist $children($id)
156 } else {
157 lappend childlist {}
158 }
Paul Mackerrasf7a3e8d2006-03-17 23:04:48159 set commitdata($id) [string range $cmit [expr {$j + 1}] end]
Paul Mackerras8f7d0ce2006-02-28 11:10:19160 set commitrow($id) $commitidx
161 incr commitidx
162 lappend displayorder $id
Paul Mackerras79b2c752006-04-02 10:47:40163 lappend commitlisted $listed
Paul Mackerras8f7d0ce2006-02-28 11:10:19164 set gotsome 1
Paul Mackerras9f1afe02006-02-19 11:44:47165 }
Paul Mackerras8f7d0ce2006-02-28 11:10:19166 if {$gotsome} {
167 layoutmore
168 }
Paul Mackerras9f1afe02006-02-19 11:44:47169 if {[clock clicks -milliseconds] >= $nextupdate} {
170 doupdate 1
Paul Mackerras9ccbdfb2005-06-16 00:27:23171 }
Paul Mackerrascfb45632005-05-31 12:14:42172}
173
Paul Mackerrasb6645502005-08-10 23:56:23174proc doupdate {reading} {
175 global commfd nextupdate numcommits ncmupdate
Paul Mackerras9ccbdfb2005-06-16 00:27:23176
Paul Mackerrasb6645502005-08-10 23:56:23177 if {$reading} {
178 fileevent $commfd readable {}
179 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23180 update
Paul Mackerrasb6645502005-08-10 23:56:23181 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 }
Paul Mackerras1db95b02005-05-09 04:08:39192}
193
194proc readcommit {id} {
Paul Mackerras418c4c72006-02-06 22:10:18195 if {[catch {set contents [exec git-cat-file commit $id]}]} return
Paul Mackerras8f7d0ce2006-02-28 11:10:19196 parsecommit $id $contents 0
Paul Mackerrasb490a992005-06-22 00:25:38197}
198
Paul Mackerrasfd8ccbe2005-12-07 12:28:22199proc updatecommits {rargs} {
Paul Mackerrasaa81d972006-02-28 00:27:12200 stopfindproc
Paul Mackerras79b2c752006-04-02 10:47:40201 foreach v {colormap selectedline matchinglines treediffs
Paul Mackerras8f7d0ce2006-02-28 11:10:19202 mergefilelist currentid rowtextx commitrow
Paul Mackerrasaa81d972006-02-28 00:27:12203 rowidlist rowoffsets idrowranges idrangedrawn iddrawn
204 linesegends crossings cornercrossings} {
205 global $v
206 catch {unset $v}
Paul Mackerrasfd8ccbe2005-12-07 12:28:22207 }
Paul Mackerrasaa81d972006-02-28 00:27:12208 allcanvs delete all
Paul Mackerrasfd8ccbe2005-12-07 12:28:22209 readrefs
Paul Mackerrasaa81d972006-02-28 00:27:12210 getcommits $rargs
Paul Mackerrasfd8ccbe2005-12-07 12:28:22211}
212
Paul Mackerras8f7d0ce2006-02-28 11:10:19213proc parsecommit {id contents listed} {
Sven Verdoolaegeb5c2f302005-11-29 21:15:51214 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 {}
Paul Mackerras232475d2005-11-14 23:34:03223 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]
Paul Mackerras1db95b02005-05-09 04:08:39238 }
239 }
Paul Mackerras232475d2005-11-14 23:34:03240 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]]
Paul Mackerrasf6e28692005-11-20 12:08:22245 } else {
246 set headline $comment
Paul Mackerras232475d2005-11-14 23:34:03247 }
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
Paul Mackerrasf6e28692005-11-20 12:08:22255 append newcomment "\n"
Paul Mackerras232475d2005-11-14 23:34:03256 }
257 set comment $newcomment
Paul Mackerras1db95b02005-05-09 04:08:39258 }
259 if {$comdate != {}} {
Paul Mackerrascfb45632005-05-31 12:14:42260 set cdate($id) $comdate
Paul Mackerras1db95b02005-05-09 04:08:39261 }
Paul Mackerrase5c2d852005-05-11 23:44:54262 set commitinfo($id) [list $headline $auname $audate \
263 $comname $comdate $comment]
Paul Mackerras1db95b02005-05-09 04:08:39264}
265
Paul Mackerrasf7a3e8d2006-03-17 23:04:48266proc getcommit {id} {
Paul Mackerras79b2c752006-04-02 10:47:40267 global commitdata commitinfo
Paul Mackerras8ed16482006-03-02 11:56:44268
Paul Mackerrasf7a3e8d2006-03-17 23:04:48269 if {[info exists commitdata($id)]} {
270 parsecommit $id $commitdata($id) 1
Paul Mackerras8ed16482006-03-02 11:56:44271 } else {
272 readcommit $id
273 if {![info exists commitinfo($id)]} {
274 set commitinfo($id) {"No commit information available"}
Paul Mackerras8ed16482006-03-02 11:56:44275 }
276 }
277 return 1
278}
279
Paul Mackerras887fe3c2005-05-21 07:35:37280proc readrefs {} {
Paul Mackerras106288c2005-08-19 13:11:39281 global tagids idtags headids idheads tagcontents
Paul Mackerrasf1d83ba2005-08-19 12:14:28282 global otherrefids idotherrefs
283
Sven Verdoolaegeb5c2f302005-11-29 21:15:51284 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
285 catch {unset $v}
286 }
Mark Woodingce088722006-04-04 06:24:55287 set refd [open [list | git ls-remote [gitdir]] r]
Junio C Hamano36a7cad2005-11-19 07:54:17288 while {0 <= [set n [gets $refd line]]} {
289 if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
290 match id path]} {
291 continue
292 }
293 if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
294 set type others
295 set name $path
296 }
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"]
Paul Mackerrasf1d83ba2005-08-19 12:14:28312 }
Junio C Hamano36a7cad2005-11-19 07:54:17313 } 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
Paul Mackerrasf1d83ba2005-08-19 12:14:28319 }
320 }
Junio C Hamano36a7cad2005-11-19 07:54:17321 close $refd
Paul Mackerras887fe3c2005-05-21 07:35:37322}
323
Paul Mackerrasdf3d83b2005-05-17 23:23:07324proc 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"
Martin Mares9f841cf2006-03-02 12:15:05333 bind $w <Key-Return> "destroy $w"
Paul Mackerrasdf3d83b2005-05-17 23:23:07334 tkwait window $w
335}
336
Sven Verdoolaegeb5c2f302005-11-29 21:15:51337proc makewindow {rargs} {
Keith Packard4840be62006-04-04 07:19:45338 global canv canv2 canv3 linespc charspc ctext cflist textfont mainfont uifont
Paul Mackerrasb74fd572005-07-16 11:46:13339 global findtype findtypemenu findloc findstring fstring geometry
Paul Mackerras887fe3c2005-05-21 07:35:37340 global entries sha1entry sha1string sha1but
Paul Mackerras94a2eed2005-08-07 05:27:57341 global maincursor textcursor curtextcursor
Paul Mackerras712fcc02005-11-29 22:28:16342 global rowctxmenu mergemax
Paul Mackerras9a40c502005-05-12 23:46:16343
344 menu .bar
345 .bar add cascade -label "File" -menu .bar.file
Keith Packard4840be62006-04-04 07:19:45346 .bar configure -font $uifont
Paul Mackerras9a40c502005-05-12 23:46:16347 menu .bar.file
Sven Verdoolaegeb5c2f302005-11-29 21:15:51348 .bar.file add command -label "Update" -command [list updatecommits $rargs]
Paul Mackerrasf1d83ba2005-08-19 12:14:28349 .bar.file add command -label "Reread references" -command rereadrefs
Paul Mackerras1d10f362005-05-15 12:55:47350 .bar.file add command -label "Quit" -command doquit
Keith Packard4840be62006-04-04 07:19:45351 .bar.file configure -font $uifont
Paul Mackerras712fcc02005-11-29 22:28:16352 menu .bar.edit
353 .bar add cascade -label "Edit" -menu .bar.edit
354 .bar.edit add command -label "Preferences" -command doprefs
Keith Packard4840be62006-04-04 07:19:45355 .bar.edit configure -font $uifont
Paul Mackerras9a40c502005-05-12 23:46:16356 menu .bar.help
357 .bar add cascade -label "Help" -menu .bar.help
358 .bar.help add command -label "About gitk" -command about
Paul Mackerras4e95e1f2006-04-04 23:39:51359 .bar.help add command -label "Key bindings" -command keys
Keith Packard4840be62006-04-04 07:19:45360 .bar.help configure -font $uifont
Paul Mackerras9a40c502005-05-12 23:46:16361 . configure -menu .bar
362
Paul Mackerras0fba86b2005-05-16 23:54:58363 if {![info exists geometry(canv1)]} {
Jeff Hobbs2ed49d52005-11-23 01:39:53364 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}]
Paul Mackerras0fba86b2005-05-16 23:54:58368 set geometry(ctextw) 80
369 set geometry(ctexth) 30
370 set geometry(cflistw) 30
371 }
Paul Mackerras0327d272005-05-10 00:23:42372 panedwindow .ctop -orient vertical
Paul Mackerras0fba86b2005-05-16 23:54:58373 if {[info exists geometry(width)]} {
374 .ctop conf -width $geometry(width) -height $geometry(height)
Paul Mackerras17386062005-05-18 22:51:00375 set texth [expr {$geometry(height) - $geometry(canvh) - 56}]
376 set geometry(ctexth) [expr {($texth - 8) /
377 [font metrics $textfont -linespace]}]
Paul Mackerras0fba86b2005-05-16 23:54:58378 }
Paul Mackerras98f350e2005-05-15 05:56:51379 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
Paul Mackerras0fba86b2005-05-16 23:54:58389 canvas $canv -height $geometry(canvh) -width $geometry(canv1) \
Paul Mackerrasb5721c72005-05-10 12:08:22390 -bg white -bd 0 \
Paul Mackerras9f1afe02006-02-19 11:44:47391 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
Paul Mackerras98f350e2005-05-15 05:56:51392 .ctop.top.clist add $canv
393 set canv2 .ctop.top.clist.canv2
Paul Mackerras0fba86b2005-05-16 23:54:58394 canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \
Paul Mackerrasb5721c72005-05-10 12:08:22395 -bg white -bd 0 -yscrollincr $linespc
Paul Mackerras98f350e2005-05-15 05:56:51396 .ctop.top.clist add $canv2
397 set canv3 .ctop.top.clist.canv3
Paul Mackerras0fba86b2005-05-16 23:54:58398 canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \
Paul Mackerrasb5721c72005-05-10 12:08:22399 -bg white -bd 0 -yscrollincr $linespc
Paul Mackerras98f350e2005-05-15 05:56:51400 .ctop.top.clist add $canv3
Paul Mackerras43bddeb2005-05-15 23:19:18401 bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}
Paul Mackerras98f350e2005-05-15 05:56:51402
403 set sha1entry .ctop.top.bar.sha1
Paul Mackerras887fe3c2005-05-21 07:35:37404 set entries $sha1entry
405 set sha1but .ctop.top.bar.sha1label
406 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
Keith Packard4840be62006-04-04 07:19:45407 -command gotocommit -width 8 -font $uifont
Paul Mackerras887fe3c2005-05-21 07:35:37408 $sha1but conf -disabledforeground [$sha1but cget -foreground]
Paul Mackerras98f350e2005-05-15 05:56:51409 pack .ctop.top.bar.sha1label -side left
Paul Mackerras887fe3c2005-05-21 07:35:37410 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
411 trace add variable sha1string write sha1change
Paul Mackerras98f350e2005-05-15 05:56:51412 pack $sha1entry -side left -pady 2
Paul Mackerrasd6982062005-08-06 12:06:06413
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
Keith Packard4840be62006-04-04 07:19:45437 button .ctop.top.bar.findbut -text "Find" -command dofind -font $uifont
Paul Mackerras98f350e2005-05-15 05:56:51438 pack .ctop.top.bar.findbut -side left
439 set findstring {}
Paul Mackerrasdf3d83b2005-05-17 23:23:07440 set fstring .ctop.top.bar.findstring
Paul Mackerras887fe3c2005-05-21 07:35:37441 lappend entries $fstring
Keith Packard4840be62006-04-04 07:19:45442 entry $fstring -width 30 -font $textfont -textvariable findstring -font $textfont
Paul Mackerrasdf3d83b2005-05-17 23:23:07443 pack $fstring -side left -expand 1 -fill x
Paul Mackerras98f350e2005-05-15 05:56:51444 set findtype Exact
Paul Mackerrasb74fd572005-07-16 11:46:13445 set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
446 findtype Exact IgnCase Regexp]
Keith Packard4840be62006-04-04 07:19:45447 .ctop.top.bar.findtype configure -font $uifont
448 .ctop.top.bar.findtype.menu configure -font $uifont
Paul Mackerras98f350e2005-05-15 05:56:51449 set findloc "All fields"
450 tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \
Paul Mackerrasb74fd572005-07-16 11:46:13451 Comments Author Committer Files Pickaxe
Keith Packard4840be62006-04-04 07:19:45452 .ctop.top.bar.findloc configure -font $uifont
453 .ctop.top.bar.findloc.menu configure -font $uifont
454
Paul Mackerras98f350e2005-05-15 05:56:51455 pack .ctop.top.bar.findloc -side right
456 pack .ctop.top.bar.findtype -side right
Paul Mackerrasb74fd572005-07-16 11:46:13457 # for making sure type==Exact whenever loc==Pickaxe
458 trace add variable findloc write findlocchange
Paul Mackerrasb5721c72005-05-10 12:08:22459
Paul Mackerras5ad588d2005-05-10 01:02:55460 panedwindow .ctop.cdet -orient horizontal
461 .ctop add .ctop.cdet
Paul Mackerrasd2610d12005-05-11 00:45:38462 frame .ctop.cdet.left
463 set ctext .ctop.cdet.left.ctext
Paul Mackerras0fba86b2005-05-16 23:54:58464 text $ctext -bg white -state disabled -font $textfont \
465 -width $geometry(ctextw) -height $geometry(ctexth) \
Linus Torvaldsb1ba39e2005-08-09 03:04:20466 -yscrollcommand ".ctop.cdet.left.sb set" -wrap none
Paul Mackerrasd2610d12005-05-11 00:45:38467 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
Paul Mackerrasf0654862005-07-18 18:29:03472 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
Paul Mackerras712fcc02005-11-29 22:28:16473 $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
Paul Mackerrasb77b0272006-02-06 22:13:52481 $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"
Paul Mackerras712fcc02005-11-29 22:28:16492 $ctext tag conf mmax -fore darkgrey
Paul Mackerrasb77b0272006-02-06 22:13:52493 set mergemax 16
Paul Mackerras712fcc02005-11-29 22:28:16494 $ctext tag conf mresult -font [concat $textfont bold]
495 $ctext tag conf msep -font [concat $textfont bold]
496 $ctext tag conf found -back yellow
Paul Mackerrase5c2d852005-05-11 23:44:54497
Paul Mackerrasd2610d12005-05-11 00:45:38498 frame .ctop.cdet.right
499 set cflist .ctop.cdet.right.cfiles
Paul Mackerras17386062005-05-18 22:51:00500 listbox $cflist -bg white -selectmode extended -width $geometry(cflistw) \
Keith Packard4840be62006-04-04 07:19:45501 -yscrollcommand ".ctop.cdet.right.sb set" -font $mainfont
Paul Mackerrasd2610d12005-05-11 00:45:38502 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
Paul Mackerras0fba86b2005-05-16 23:54:58506 bind .ctop.cdet <Configure> {resizecdetpanes %W %w}
Paul Mackerrasd2610d12005-05-11 00:45:38507
Paul Mackerras0327d272005-05-10 00:23:42508 pack .ctop -side top -fill both -expand 1
Paul Mackerras1db95b02005-05-09 04:08:39509
Paul Mackerrasc8dfbcf2005-06-25 05:39:21510 bindall <1> {selcanvline %W %x %y}
511 #bindall <B1-Motion> {selcanvline %W %x %y}
Paul Mackerrascfb45632005-05-31 12:14:42512 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
513 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
Paul Mackerrasbe0cd092006-03-30 22:55:11514 bindall <2> "canvscan mark %W %x %y"
515 bindall <B2-Motion> "canvscan dragto %W %x %y"
Rutger Nijlunsing6e5f7202006-04-05 00:24:03516 bindkey <Home> selfirstline
517 bindkey <End> sellastline
Paul Mackerras17386062005-05-18 22:51:00518 bind . <Key-Up> "selnextline -1"
519 bind . <Key-Down> "selnextline 1"
Rutger Nijlunsing6e5f7202006-04-05 00:24:03520 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"
Paul Mackerrascfb45632005-05-31 12:14:42530 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"
Paul Mackerrasdf3d83b2005-05-17 23:23:07533 bindkey p "selnextline -1"
534 bindkey n "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 00:07:36535 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"
Paul Mackerrascfb45632005-05-31 12:14:42541 bindkey b "$ctext yview scroll -1 pages"
542 bindkey d "$ctext yview scroll 18 units"
543 bindkey u "$ctext yview scroll -18 units"
Paul Mackerrasb74fd572005-07-16 11:46:13544 bindkey / {findnext 1}
545 bindkey <Key-Return> {findnext 0}
Paul Mackerrasdf3d83b2005-05-17 23:23:07546 bindkey ? findprev
Paul Mackerras39ad8572005-05-19 12:35:53547 bindkey f nextfile
Paul Mackerras1d10f362005-05-15 12:55:47548 bind . <Control-q> doquit
Paul Mackerras98f350e2005-05-15 05:56:51549 bind . <Control-f> dofind
Paul Mackerrasb74fd572005-07-16 11:46:13550 bind . <Control-g> {findnext 0}
Paul Mackerras98f350e2005-05-15 05:56:51551 bind . <Control-r> findprev
Paul Mackerras1d10f362005-05-15 12:55:47552 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}
Paul Mackerrase5c2d852005-05-11 23:44:54556 bind $cflist <<ListboxSelect>> listboxsel
Paul Mackerras0fba86b2005-05-16 23:54:58557 bind . <Destroy> {savestuff %W}
Paul Mackerrasdf3d83b2005-05-17 23:23:07558 bind . <Button-1> "click %W"
Paul Mackerras17386062005-05-18 22:51:00559 bind $fstring <Key-Return> dofind
Paul Mackerras887fe3c2005-05-21 07:35:37560 bind $sha1entry <Key-Return> gotocommit
Paul Mackerrasee3dc722005-06-25 06:37:13561 bind $sha1entry <<PasteSelection>> clearsha1
Paul Mackerrasea13cba2005-06-16 10:54:04562
563 set maincursor [. cget -cursor]
564 set textcursor [$ctext cget -cursor]
Paul Mackerras94a2eed2005-08-07 05:27:57565 set curtextcursor $textcursor
Paul Mackerras84ba7342005-06-17 00:12:26566
Paul Mackerrasc8dfbcf2005-06-25 05:39:21567 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}
Paul Mackerras74daedb2005-06-27 09:27:32573 $rowctxmenu add command -label "Make patch" -command mkpatch
Paul Mackerrasbdbfbe32005-06-27 12:56:40574 $rowctxmenu add command -label "Create tag" -command mktag
Paul Mackerras4a2139f2005-06-28 23:47:48575 $rowctxmenu add command -label "Write commit to file" -command writecommit
Paul Mackerrasdf3d83b2005-05-17 23:23:07576}
577
Paul Mackerrasbe0cd092006-03-30 22:55:11578# 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
Paul Mackerras9f1afe02006-02-19 11:44:47591proc scrollcanv {cscroll f0 f1} {
592 $cscroll set $f0 $f1
593 drawfrac $f0 $f1
594}
595
Paul Mackerrasdf3d83b2005-05-17 23:23:07596# 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} {
Paul Mackerras887fe3c2005-05-21 07:35:37600 global entries
Paul Mackerrasdf3d83b2005-05-17 23:23:07601 bind . $ev $script
602 set escript [bind Entry $ev]
603 if {$escript == {}} {
604 set escript [bind Entry <Key>]
605 }
Paul Mackerras887fe3c2005-05-21 07:35:37606 foreach e $entries {
607 bind $e $ev "$escript; break"
608 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07609}
610
611# set the focus back to the toplevel for any click outside
Paul Mackerras887fe3c2005-05-21 07:35:37612# the entry widgets
Paul Mackerrasdf3d83b2005-05-17 23:23:07613proc click {w} {
Paul Mackerras887fe3c2005-05-21 07:35:37614 global entries
615 foreach e $entries {
616 if {$w == $e} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07617 }
Paul Mackerras887fe3c2005-05-21 07:35:37618 focus .
Paul Mackerras0fba86b2005-05-16 23:54:58619}
620
621proc savestuff {w} {
Keith Packard4840be62006-04-04 07:19:45622 global canv canv2 canv3 ctext cflist mainfont textfont uifont
Paul Mackerras712fcc02005-11-29 22:28:16623 global stuffsaved findmergefiles maxgraphpct
Paul Mackerras04c13d32005-08-19 00:22:24624 global maxwidth
Paul Mackerras4ef17532005-07-28 03:16:51625
Paul Mackerras0fba86b2005-05-16 23:54:58626 if {$stuffsaved} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07627 if {![winfo viewable .]} return
Paul Mackerras0fba86b2005-05-16 23:54:58628 catch {
629 set f [open "~/.gitk-new" w]
Paul Mackerrasf0654862005-07-18 18:29:03630 puts $f [list set mainfont $mainfont]
631 puts $f [list set textfont $textfont]
Keith Packard4840be62006-04-04 07:19:45632 puts $f [list set uifont $uifont]
Paul Mackerrasf0654862005-07-18 18:29:03633 puts $f [list set findmergefiles $findmergefiles]
Paul Mackerras8d858d12005-08-04 23:52:16634 puts $f [list set maxgraphpct $maxgraphpct]
Paul Mackerras04c13d32005-08-19 00:22:24635 puts $f [list set maxwidth $maxwidth]
Paul Mackerras0fba86b2005-05-16 23:54:58636 puts $f "set geometry(width) [winfo width .ctop]"
637 puts $f "set geometry(height) [winfo height .ctop]"
Jeff Hobbs2ed49d52005-11-23 01:39:53638 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}]"
Paul Mackerras0fba86b2005-05-16 23:54:58642 set wid [expr {([winfo width $ctext] - 8) \
643 / [font measure $textfont "0"]}]
Paul Mackerras0fba86b2005-05-16 23:54:58644 puts $f "set geometry(ctextw) $wid"
Paul Mackerras0fba86b2005-05-16 23:54:58645 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
Paul Mackerras1db95b02005-05-09 04:08:39652}
653
Paul Mackerras43bddeb2005-05-15 23:19:18654proc resizeclistpanes {win w} {
655 global oldwidth
Paul Mackerras418c4c72006-02-06 22:10:18656 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18657 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} {
Jeff Hobbs2ed49d52005-11-23 01:39:53670 set sash1 [expr {$sash0 + 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18671 }
672 if {$sash1 > $w - 10} {
Jeff Hobbs2ed49d52005-11-23 01:39:53673 set sash1 [expr {$w - 10}]
Paul Mackerras43bddeb2005-05-15 23:19:18674 if {$sash0 > $sash1 - 20} {
Jeff Hobbs2ed49d52005-11-23 01:39:53675 set sash0 [expr {$sash1 - 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18676 }
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
Paul Mackerras418c4c72006-02-06 22:10:18687 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18688 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} {
Jeff Hobbs2ed49d52005-11-23 01:39:53698 set sash0 [expr {$w - 15}]
Paul Mackerras43bddeb2005-05-15 23:19:18699 }
700 }
701 $win sash place 0 $sash0 [lindex $s0 1]
702 }
703 set oldwidth($win) $w
704}
705
Paul Mackerrasb5721c72005-05-10 12:08:22706proc 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
Paul Mackerras9a40c502005-05-12 23:46:16720proc 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 {
Paul Mackerras9f1afe02006-02-19 11:44:47729Gitk - a commit viewer for git
Paul Mackerras9a40c502005-05-12 23:46:16730
Paul Mackerras9f1afe02006-02-19 11:44:47731Copyright © 2005-2006 Paul Mackerras
Paul Mackerras9a40c502005-05-12 23:46:16732
Paul Mackerrasc8dfbcf2005-06-25 05:39:21733Use and redistribute under the terms of the GNU General Public License} \
Paul Mackerras9a40c502005-05-12 23:46:16734 -justify center -aspect 400
735 pack $w.m -side top -fill x -padx 20 -pady 20
736 button $w.ok -text Close -command "destroy $w"
737 pack $w.ok -side bottom
738}
739
Paul Mackerras4e95e1f2006-04-04 23:39:51740proc keys {} {
741 set w .keys
742 if {[winfo exists $w]} {
743 raise $w
744 return
745 }
746 toplevel $w
747 wm title $w "Gitk key bindings"
748 message $w.m -text {
749Gitk key bindings:
750
751<Ctrl-Q> Quit
Rutger Nijlunsing6e5f7202006-04-05 00:24:03752<Home> Move to first commit
753<End> Move to last commit
Paul Mackerras4e95e1f2006-04-04 23:39:51754<Up>, p, i Move up one commit
755<Down>, n, k Move down one commit
756<Left>, z, j Go back in history list
757<Right>, x, l Go forward in history list
Rutger Nijlunsing6e5f7202006-04-05 00:24:03758<PageUp> Move up one page in commit list
759<PageDown> Move down one page in commit list
760<Ctrl-Home> Scroll to top of commit list
761<Ctrl-End> Scroll to bottom of commit list
762<Ctrl-Up> Scroll commit list up one line
763<Ctrl-Down> Scroll commit list down one line
764<Ctrl-PageUp> Scroll commit list up one page
765<Ctrl-PageDown> Scroll commit list down one page
Paul Mackerras4e95e1f2006-04-04 23:39:51766<Delete>, b Scroll diff view up one page
767<Backspace> Scroll diff view up one page
768<Space> Scroll diff view down one page
769u Scroll diff view up 18 lines
770d Scroll diff view down 18 lines
771<Ctrl-F> Find
772<Ctrl-G> Move to next find hit
773<Ctrl-R> Move to previous find hit
774<Return> Move to next find hit
775/ Move to next find hit, or redo find
776? Move to previous find hit
777f Scroll diff view to next file
778<Ctrl-KP+> Increase font size
779<Ctrl-plus> Increase font size
780<Ctrl-KP-> Decrease font size
781<Ctrl-minus> Decrease font size
782} \
783 -justify left -bg white -border 2 -relief sunken
784 pack $w.m -side top -fill both
785 button $w.ok -text Close -command "destroy $w"
786 pack $w.ok -side bottom
787}
788
Paul Mackerras9f1afe02006-02-19 11:44:47789proc shortids {ids} {
790 set res {}
791 foreach id $ids {
792 if {[llength $id] > 1} {
793 lappend res [shortids $id]
794 } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
795 lappend res [string range $id 0 7]
796 } else {
797 lappend res $id
798 }
799 }
800 return $res
801}
802
803proc incrange {l x o} {
804 set n [llength $l]
805 while {$x < $n} {
806 set e [lindex $l $x]
807 if {$e ne {}} {
808 lset l $x [expr {$e + $o}]
809 }
810 incr x
811 }
812 return $l
813}
814
815proc ntimes {n o} {
816 set ret {}
817 for {} {$n > 0} {incr n -1} {
818 lappend ret $o
819 }
820 return $ret
821}
822
823proc usedinrange {id l1 l2} {
824 global children commitrow
825
826 if {[info exists commitrow($id)]} {
827 set r $commitrow($id)
828 if {$l1 <= $r && $r <= $l2} {
829 return [expr {$r - $l1 + 1}]
830 }
831 }
832 foreach c $children($id) {
833 if {[info exists commitrow($c)]} {
834 set r $commitrow($c)
835 if {$l1 <= $r && $r <= $l2} {
836 return [expr {$r - $l1 + 1}]
837 }
838 }
839 }
840 return 0
841}
842
843proc sanity {row {full 0}} {
844 global rowidlist rowoffsets
845
846 set col -1
Paul Mackerras8f7d0ce2006-02-28 11:10:19847 set ids [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 11:44:47848 foreach id $ids {
849 incr col
850 if {$id eq {}} continue
851 if {$col < [llength $ids] - 1 &&
852 [lsearch -exact -start [expr {$col+1}] $ids $id] >= 0} {
Paul Mackerras8f7d0ce2006-02-28 11:10:19853 puts "oops: [shortids $id] repeated in row $row col $col: {[shortids [lindex $rowidlist $row]]}"
Paul Mackerras9f1afe02006-02-19 11:44:47854 }
Paul Mackerras8f7d0ce2006-02-28 11:10:19855 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 11:44:47856 set y $row
857 set x $col
858 while {$o ne {}} {
859 incr y -1
860 incr x $o
Paul Mackerras8f7d0ce2006-02-28 11:10:19861 if {[lindex $rowidlist $y $x] != $id} {
Paul Mackerras9f1afe02006-02-19 11:44:47862 puts "oops: rowoffsets wrong at row [expr {$y+1}] col [expr {$x-$o}]"
863 puts " id=[shortids $id] check started at row $row"
864 for {set i $row} {$i >= $y} {incr i -1} {
Paul Mackerras8f7d0ce2006-02-28 11:10:19865 puts " row $i ids={[shortids [lindex $rowidlist $i]]} offs={[lindex $rowoffsets $i]}"
Paul Mackerras9f1afe02006-02-19 11:44:47866 }
867 break
868 }
869 if {!$full} break
Paul Mackerras8f7d0ce2006-02-28 11:10:19870 set o [lindex $rowoffsets $y $x]
Paul Mackerras9f1afe02006-02-19 11:44:47871 }
872 }
873}
874
875proc makeuparrow {oid x y z} {
876 global rowidlist rowoffsets uparrowlen idrowranges
877
878 for {set i 1} {$i < $uparrowlen && $y > 1} {incr i} {
879 incr y -1
880 incr x $z
Paul Mackerras8f7d0ce2006-02-28 11:10:19881 set off0 [lindex $rowoffsets $y]
Paul Mackerras9f1afe02006-02-19 11:44:47882 for {set x0 $x} {1} {incr x0} {
883 if {$x0 >= [llength $off0]} {
Paul Mackerras8f7d0ce2006-02-28 11:10:19884 set x0 [llength [lindex $rowoffsets [expr {$y-1}]]]
Paul Mackerras9f1afe02006-02-19 11:44:47885 break
886 }
887 set z [lindex $off0 $x0]
888 if {$z ne {}} {
889 incr x0 $z
890 break
891 }
892 }
893 set z [expr {$x0 - $x}]
Paul Mackerras8f7d0ce2006-02-28 11:10:19894 lset rowidlist $y [linsert [lindex $rowidlist $y] $x $oid]
895 lset rowoffsets $y [linsert [lindex $rowoffsets $y] $x $z]
Paul Mackerras9f1afe02006-02-19 11:44:47896 }
Paul Mackerras8f7d0ce2006-02-28 11:10:19897 set tmp [lreplace [lindex $rowoffsets $y] $x $x {}]
898 lset rowoffsets $y [incrange $tmp [expr {$x+1}] -1]
Paul Mackerras9f1afe02006-02-19 11:44:47899 lappend idrowranges($oid) $y
900}
901
902proc initlayout {} {
Paul Mackerras79b2c752006-04-02 10:47:40903 global rowidlist rowoffsets displayorder commitlisted
Paul Mackerras9f1afe02006-02-19 11:44:47904 global rowlaidout rowoptim
905 global idinlist rowchk
Paul Mackerrasbe0cd092006-03-30 22:55:11906 global commitidx numcommits canvxmax canv
Paul Mackerras8f7d0ce2006-02-28 11:10:19907 global nextcolor
Paul Mackerras79b2c752006-04-02 10:47:40908 global parentlist childlist children
Paul Mackerras9f1afe02006-02-19 11:44:47909
Paul Mackerras8f7d0ce2006-02-28 11:10:19910 set commitidx 0
911 set numcommits 0
912 set displayorder {}
Paul Mackerras79b2c752006-04-02 10:47:40913 set commitlisted {}
914 set parentlist {}
915 set childlist {}
916 catch {unset children}
Paul Mackerras8f7d0ce2006-02-28 11:10:19917 set nextcolor 0
918 set rowidlist {{}}
919 set rowoffsets {{}}
Paul Mackerras9f1afe02006-02-19 11:44:47920 catch {unset idinlist}
921 catch {unset rowchk}
922 set rowlaidout 0
923 set rowoptim 0
Paul Mackerrasbe0cd092006-03-30 22:55:11924 set canvxmax [$canv cget -width]
925}
926
927proc setcanvscroll {} {
928 global canv canv2 canv3 numcommits linespc canvxmax canvy0
929
930 set ymax [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]
931 $canv conf -scrollregion [list 0 0 $canvxmax $ymax]
932 $canv2 conf -scrollregion [list 0 0 0 $ymax]
933 $canv3 conf -scrollregion [list 0 0 0 $ymax]
Paul Mackerras9f1afe02006-02-19 11:44:47934}
935
936proc visiblerows {} {
937 global canv numcommits linespc
938
939 set ymax [lindex [$canv cget -scrollregion] 3]
940 if {$ymax eq {} || $ymax == 0} return
941 set f [$canv yview]
942 set y0 [expr {int([lindex $f 0] * $ymax)}]
943 set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
944 if {$r0 < 0} {
945 set r0 0
946 }
947 set y1 [expr {int([lindex $f 1] * $ymax)}]
948 set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
949 if {$r1 >= $numcommits} {
950 set r1 [expr {$numcommits - 1}]
951 }
952 return [list $r0 $r1]
953}
954
955proc layoutmore {} {
956 global rowlaidout rowoptim commitidx numcommits optim_delay
957 global uparrowlen
958
959 set row $rowlaidout
960 set rowlaidout [layoutrows $row $commitidx 0]
961 set orow [expr {$rowlaidout - $uparrowlen - 1}]
962 if {$orow > $rowoptim} {
963 checkcrossings $rowoptim $orow
964 optimize_rows $rowoptim 0 $orow
965 set rowoptim $orow
966 }
967 set canshow [expr {$rowoptim - $optim_delay}]
968 if {$canshow > $numcommits} {
969 showstuff $canshow
970 }
971}
972
973proc showstuff {canshow} {
974 global numcommits
Paul Mackerras9f1afe02006-02-19 11:44:47975 global linesegends idrowranges idrangedrawn
976
Paul Mackerras8f7d0ce2006-02-28 11:10:19977 if {$numcommits == 0} {
978 global phase
979 set phase "incrdraw"
980 allcanvs delete all
981 }
Paul Mackerras9f1afe02006-02-19 11:44:47982 set row $numcommits
983 set numcommits $canshow
Paul Mackerrasbe0cd092006-03-30 22:55:11984 setcanvscroll
Paul Mackerras9f1afe02006-02-19 11:44:47985 set rows [visiblerows]
986 set r0 [lindex $rows 0]
987 set r1 [lindex $rows 1]
988 for {set r $row} {$r < $canshow} {incr r} {
989 if {[info exists linesegends($r)]} {
990 foreach id $linesegends($r) {
991 set i -1
992 foreach {s e} $idrowranges($id) {
993 incr i
994 if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
995 && ![info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 12:00:44996 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 11:44:47997 set idrangedrawn($id,$i) 1
998 }
999 }
1000 }
1001 }
1002 }
1003 if {$canshow > $r1} {
1004 set canshow $r1
1005 }
1006 while {$row < $canshow} {
1007 drawcmitrow $row
1008 incr row
1009 }
1010}
1011
1012proc layoutrows {row endrow last} {
1013 global rowidlist rowoffsets displayorder
1014 global uparrowlen downarrowlen maxwidth mingaplen
Paul Mackerras79b2c752006-04-02 10:47:401015 global childlist parentlist
Paul Mackerras9f1afe02006-02-19 11:44:471016 global idrowranges linesegends
1017 global commitidx
1018 global idinlist rowchk
1019
Paul Mackerras8f7d0ce2006-02-28 11:10:191020 set idlist [lindex $rowidlist $row]
1021 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 11:44:471022 while {$row < $endrow} {
1023 set id [lindex $displayorder $row]
1024 set oldolds {}
1025 set newolds {}
Paul Mackerras79b2c752006-04-02 10:47:401026 foreach p [lindex $parentlist $row] {
Paul Mackerras9f1afe02006-02-19 11:44:471027 if {![info exists idinlist($p)]} {
1028 lappend newolds $p
1029 } elseif {!$idinlist($p)} {
1030 lappend oldolds $p
1031 }
1032 }
1033 set nev [expr {[llength $idlist] + [llength $newolds]
1034 + [llength $oldolds] - $maxwidth + 1}]
1035 if {$nev > 0} {
1036 if {!$last && $row + $uparrowlen + $mingaplen >= $commitidx} break
1037 for {set x [llength $idlist]} {[incr x -1] >= 0} {} {
1038 set i [lindex $idlist $x]
1039 if {![info exists rowchk($i)] || $row >= $rowchk($i)} {
1040 set r [usedinrange $i [expr {$row - $downarrowlen}] \
1041 [expr {$row + $uparrowlen + $mingaplen}]]
1042 if {$r == 0} {
1043 set idlist [lreplace $idlist $x $x]
1044 set offs [lreplace $offs $x $x]
1045 set offs [incrange $offs $x 1]
1046 set idinlist($i) 0
Paul Mackerrasd8d2df02006-03-18 09:42:461047 set rm1 [expr {$row - 1}]
1048 lappend linesegends($rm1) $i
1049 lappend idrowranges($i) $rm1
Paul Mackerras9f1afe02006-02-19 11:44:471050 if {[incr nev -1] <= 0} break
1051 continue
1052 }
1053 set rowchk($id) [expr {$row + $r}]
1054 }
1055 }
Paul Mackerras8f7d0ce2006-02-28 11:10:191056 lset rowidlist $row $idlist
1057 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 11:44:471058 }
1059 set col [lsearch -exact $idlist $id]
1060 if {$col < 0} {
1061 set col [llength $idlist]
1062 lappend idlist $id
Paul Mackerras8f7d0ce2006-02-28 11:10:191063 lset rowidlist $row $idlist
Paul Mackerras9f1afe02006-02-19 11:44:471064 set z {}
Paul Mackerras79b2c752006-04-02 10:47:401065 if {[lindex $childlist $row] ne {}} {
Paul Mackerras8f7d0ce2006-02-28 11:10:191066 set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}]
Paul Mackerras9f1afe02006-02-19 11:44:471067 unset idinlist($id)
1068 }
1069 lappend offs $z
Paul Mackerras8f7d0ce2006-02-28 11:10:191070 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 11:44:471071 if {$z ne {}} {
1072 makeuparrow $id $col $row $z
1073 }
1074 } else {
1075 unset idinlist($id)
1076 }
1077 if {[info exists idrowranges($id)]} {
Paul Mackerras9f1afe02006-02-19 11:44:471078 lappend idrowranges($id) $row
1079 }
1080 incr row
1081 set offs [ntimes [llength $idlist] 0]
1082 set l [llength $newolds]
1083 set idlist [eval lreplace \$idlist $col $col $newolds]
1084 set o 0
1085 if {$l != 1} {
1086 set offs [lrange $offs 0 [expr {$col - 1}]]
1087 foreach x $newolds {
1088 lappend offs {}
1089 incr o -1
1090 }
1091 incr o
1092 set tmp [expr {[llength $idlist] - [llength $offs]}]
1093 if {$tmp > 0} {
1094 set offs [concat $offs [ntimes $tmp $o]]
1095 }
1096 } else {
1097 lset offs $col {}
1098 }
1099 foreach i $newolds {
1100 set idinlist($i) 1
1101 set idrowranges($i) $row
1102 }
1103 incr col $l
1104 foreach oid $oldolds {
1105 set idinlist($oid) 1
1106 set idlist [linsert $idlist $col $oid]
1107 set offs [linsert $offs $col $o]
1108 makeuparrow $oid $col $row $o
1109 incr col
1110 }
Paul Mackerras8f7d0ce2006-02-28 11:10:191111 lappend rowidlist $idlist
1112 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 11:44:471113 }
1114 return $row
1115}
1116
1117proc addextraid {id row} {
Paul Mackerras79b2c752006-04-02 10:47:401118 global displayorder commitrow commitinfo
Paul Mackerrase7da3472006-04-17 00:27:591119 global commitidx commitlisted
Paul Mackerras79b2c752006-04-02 10:47:401120 global parentlist childlist children
Paul Mackerras9f1afe02006-02-19 11:44:471121
1122 incr commitidx
1123 lappend displayorder $id
Paul Mackerrase7da3472006-04-17 00:27:591124 lappend commitlisted 0
Paul Mackerras79b2c752006-04-02 10:47:401125 lappend parentlist {}
Paul Mackerras9f1afe02006-02-19 11:44:471126 set commitrow($id) $row
Paul Mackerras9f1afe02006-02-19 11:44:471127 readcommit $id
1128 if {![info exists commitinfo($id)]} {
1129 set commitinfo($id) {"No commit information available"}
Paul Mackerras79b2c752006-04-02 10:47:401130 }
1131 if {[info exists children($id)]} {
1132 lappend childlist $children($id)
1133 } else {
1134 lappend childlist {}
Paul Mackerras9f1afe02006-02-19 11:44:471135 }
1136}
1137
1138proc layouttail {} {
1139 global rowidlist rowoffsets idinlist commitidx
Paul Mackerrasd8d2df02006-03-18 09:42:461140 global idrowranges
Paul Mackerras9f1afe02006-02-19 11:44:471141
1142 set row $commitidx
Paul Mackerras8f7d0ce2006-02-28 11:10:191143 set idlist [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 11:44:471144 while {$idlist ne {}} {
1145 set col [expr {[llength $idlist] - 1}]
1146 set id [lindex $idlist $col]
1147 addextraid $id $row
1148 unset idinlist($id)
Paul Mackerras9f1afe02006-02-19 11:44:471149 lappend idrowranges($id) $row
1150 incr row
1151 set offs [ntimes $col 0]
1152 set idlist [lreplace $idlist $col $col]
Paul Mackerras8f7d0ce2006-02-28 11:10:191153 lappend rowidlist $idlist
1154 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 11:44:471155 }
1156
1157 foreach id [array names idinlist] {
1158 addextraid $id $row
Paul Mackerras8f7d0ce2006-02-28 11:10:191159 lset rowidlist $row [list $id]
1160 lset rowoffsets $row 0
Paul Mackerras9f1afe02006-02-19 11:44:471161 makeuparrow $id 0 $row 0
Paul Mackerras9f1afe02006-02-19 11:44:471162 lappend idrowranges($id) $row
1163 incr row
Paul Mackerras8f7d0ce2006-02-28 11:10:191164 lappend rowidlist {}
1165 lappend rowoffsets {}
Paul Mackerras9f1afe02006-02-19 11:44:471166 }
1167}
1168
1169proc insert_pad {row col npad} {
1170 global rowidlist rowoffsets
1171
1172 set pad [ntimes $npad {}]
Paul Mackerras8f7d0ce2006-02-28 11:10:191173 lset rowidlist $row [eval linsert [list [lindex $rowidlist $row]] $col $pad]
1174 set tmp [eval linsert [list [lindex $rowoffsets $row]] $col $pad]
1175 lset rowoffsets $row [incrange $tmp [expr {$col + $npad}] [expr {-$npad}]]
Paul Mackerras9f1afe02006-02-19 11:44:471176}
1177
1178proc optimize_rows {row col endrow} {
Paul Mackerrasd8d2df02006-03-18 09:42:461179 global rowidlist rowoffsets idrowranges linesegends displayorder
Paul Mackerras9f1afe02006-02-19 11:44:471180
1181 for {} {$row < $endrow} {incr row} {
Paul Mackerras8f7d0ce2006-02-28 11:10:191182 set idlist [lindex $rowidlist $row]
1183 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 11:44:471184 set haspad 0
1185 for {} {$col < [llength $offs]} {incr col} {
1186 if {[lindex $idlist $col] eq {}} {
1187 set haspad 1
1188 continue
1189 }
1190 set z [lindex $offs $col]
1191 if {$z eq {}} continue
1192 set isarrow 0
1193 set x0 [expr {$col + $z}]
1194 set y0 [expr {$row - 1}]
Paul Mackerras8f7d0ce2006-02-28 11:10:191195 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 11:44:471196 if {$z0 eq {}} {
1197 set id [lindex $idlist $col]
1198 if {[info exists idrowranges($id)] &&
1199 $y0 > [lindex $idrowranges($id) 0]} {
1200 set isarrow 1
1201 }
1202 }
1203 if {$z < -1 || ($z < 0 && $isarrow)} {
1204 set npad [expr {-1 - $z + $isarrow}]
1205 set offs [incrange $offs $col $npad]
1206 insert_pad $y0 $x0 $npad
1207 if {$y0 > 0} {
1208 optimize_rows $y0 $x0 $row
1209 }
1210 set z [lindex $offs $col]
1211 set x0 [expr {$col + $z}]
Paul Mackerras8f7d0ce2006-02-28 11:10:191212 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 11:44:471213 } elseif {$z > 1 || ($z > 0 && $isarrow)} {
1214 set npad [expr {$z - 1 + $isarrow}]
1215 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 11:10:191216 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 11:44:471217 set x1 -1
1218 foreach z $offs2 {
1219 incr x1
1220 if {$z eq {} || $x1 + $z < $col} continue
1221 if {$x1 + $z > $col} {
1222 incr npad
1223 }
Paul Mackerras8f7d0ce2006-02-28 11:10:191224 lset rowoffsets $y1 [incrange $offs2 $x1 $npad]
Paul Mackerras9f1afe02006-02-19 11:44:471225 break
1226 }
1227 set pad [ntimes $npad {}]
1228 set idlist [eval linsert \$idlist $col $pad]
1229 set tmp [eval linsert \$offs $col $pad]
1230 incr col $npad
1231 set offs [incrange $tmp $col [expr {-$npad}]]
1232 set z [lindex $offs $col]
1233 set haspad 1
1234 }
Paul Mackerraseb447a12006-03-18 12:11:371235 if {$z0 eq {} && !$isarrow} {
1236 # this line links to its first child on row $row-2
1237 set rm2 [expr {$row - 2}]
1238 set id [lindex $displayorder $rm2]
1239 set xc [lsearch -exact [lindex $rowidlist $rm2] $id]
1240 if {$xc >= 0} {
1241 set z0 [expr {$xc - $x0}]
1242 }
1243 }
Paul Mackerras9f1afe02006-02-19 11:44:471244 if {$z0 ne {} && $z < 0 && $z0 > 0} {
1245 insert_pad $y0 $x0 1
1246 set offs [incrange $offs $col 1]
1247 optimize_rows $y0 [expr {$x0 + 1}] $row
1248 }
1249 }
1250 if {!$haspad} {
Paul Mackerraseb447a12006-03-18 12:11:371251 set o {}
Paul Mackerras9f1afe02006-02-19 11:44:471252 for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
1253 set o [lindex $offs $col]
Paul Mackerraseb447a12006-03-18 12:11:371254 if {$o eq {}} {
1255 # check if this is the link to the first child
1256 set id [lindex $idlist $col]
1257 if {[info exists idrowranges($id)] &&
1258 $row == [lindex $idrowranges($id) 0]} {
1259 # it is, work out offset to child
1260 set y0 [expr {$row - 1}]
1261 set id [lindex $displayorder $y0]
1262 set x0 [lsearch -exact [lindex $rowidlist $y0] $id]
1263 if {$x0 >= 0} {
1264 set o [expr {$x0 - $col}]
1265 }
1266 }
1267 }
Paul Mackerras9f1afe02006-02-19 11:44:471268 if {$o eq {} || $o <= 0} break
1269 }
Paul Mackerraseb447a12006-03-18 12:11:371270 if {$o ne {} && [incr col] < [llength $idlist]} {
Paul Mackerras9f1afe02006-02-19 11:44:471271 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 11:10:191272 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 11:44:471273 set x1 -1
1274 foreach z $offs2 {
1275 incr x1
1276 if {$z eq {} || $x1 + $z < $col} continue
Paul Mackerras8f7d0ce2006-02-28 11:10:191277 lset rowoffsets $y1 [incrange $offs2 $x1 1]
Paul Mackerras9f1afe02006-02-19 11:44:471278 break
1279 }
1280 set idlist [linsert $idlist $col {}]
1281 set tmp [linsert $offs $col {}]
1282 incr col
1283 set offs [incrange $tmp $col -1]
1284 }
1285 }
Paul Mackerras8f7d0ce2006-02-28 11:10:191286 lset rowidlist $row $idlist
1287 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 11:44:471288 set col 0
1289 }
1290}
1291
1292proc xc {row col} {
1293 global canvx0 linespc
1294 return [expr {$canvx0 + $col * $linespc}]
1295}
1296
1297proc yc {row} {
1298 global canvy0 linespc
1299 return [expr {$canvy0 + $row * $linespc}]
1300}
1301
Paul Mackerrasc934a8a2006-03-02 12:00:441302proc linewidth {id} {
1303 global thickerline lthickness
1304
1305 set wid $lthickness
1306 if {[info exists thickerline] && $id eq $thickerline} {
1307 set wid [expr {2 * $lthickness}]
1308 }
1309 return $wid
1310}
1311
1312proc drawlineseg {id i} {
Paul Mackerras9f1afe02006-02-19 11:44:471313 global rowoffsets rowidlist idrowranges
Paul Mackerraseb447a12006-03-18 12:11:371314 global displayorder
Paul Mackerras879e8b12006-03-30 23:45:141315 global canv colormap linespc
Paul Mackerras9f1afe02006-02-19 11:44:471316
1317 set startrow [lindex $idrowranges($id) [expr {2 * $i}]]
1318 set row [lindex $idrowranges($id) [expr {2 * $i + 1}]]
1319 if {$startrow == $row} return
1320 assigncolor $id
1321 set coords {}
Paul Mackerras8f7d0ce2006-02-28 11:10:191322 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 11:44:471323 if {$col < 0} {
1324 puts "oops: drawline: id $id not on row $row"
1325 return
1326 }
1327 set lasto {}
1328 set ns 0
1329 while {1} {
Paul Mackerras8f7d0ce2006-02-28 11:10:191330 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 11:44:471331 if {$o eq {}} break
1332 if {$o ne $lasto} {
1333 # changing direction
1334 set x [xc $row $col]
1335 set y [yc $row]
1336 lappend coords $x $y
1337 set lasto $o
1338 }
1339 incr col $o
1340 incr row -1
1341 }
Paul Mackerras9f1afe02006-02-19 11:44:471342 set x [xc $row $col]
1343 set y [yc $row]
1344 lappend coords $x $y
Paul Mackerraseb447a12006-03-18 12:11:371345 if {$i == 0} {
1346 # draw the link to the first child as part of this line
1347 incr row -1
1348 set child [lindex $displayorder $row]
1349 set ccol [lsearch -exact [lindex $rowidlist $row] $child]
1350 if {$ccol >= 0} {
1351 set x [xc $row $ccol]
1352 set y [yc $row]
1353 if {$ccol < $col - 1} {
Paul Mackerras7a1d9d12006-03-21 23:21:451354 lappend coords [xc $row [expr {$col - 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 12:11:371355 } elseif {$ccol > $col + 1} {
Paul Mackerras7a1d9d12006-03-21 23:21:451356 lappend coords [xc $row [expr {$col + 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 12:11:371357 }
1358 lappend coords $x $y
1359 }
1360 }
1361 if {[llength $coords] < 4} return
1362 set last [expr {[llength $idrowranges($id)] / 2 - 1}]
Paul Mackerras879e8b12006-03-30 23:45:141363 if {$i < $last} {
1364 # This line has an arrow at the lower end: check if the arrow is
1365 # on a diagonal segment, and if so, work around the Tk 8.4
1366 # refusal to draw arrows on diagonal lines.
1367 set x0 [lindex $coords 0]
1368 set x1 [lindex $coords 2]
1369 if {$x0 != $x1} {
1370 set y0 [lindex $coords 1]
1371 set y1 [lindex $coords 3]
1372 if {$y0 - $y1 <= 2 * $linespc && $x1 == [lindex $coords 4]} {
1373 # we have a nearby vertical segment, just trim off the diag bit
1374 set coords [lrange $coords 2 end]
1375 } else {
1376 set slope [expr {($x0 - $x1) / ($y0 - $y1)}]
1377 set xi [expr {$x0 - $slope * $linespc / 2}]
1378 set yi [expr {$y0 - $linespc / 2}]
1379 set coords [lreplace $coords 0 1 $xi $y0 $xi $yi]
1380 }
1381 }
1382 }
Paul Mackerraseb447a12006-03-18 12:11:371383 set arrow [expr {2 * ($i > 0) + ($i < $last)}]
1384 set arrow [lindex {none first last both} $arrow]
Paul Mackerrasc934a8a2006-03-02 12:00:441385 set t [$canv create line $coords -width [linewidth $id] \
Paul Mackerras9f1afe02006-02-19 11:44:471386 -fill $colormap($id) -tags lines.$id -arrow $arrow]
1387 $canv lower $t
1388 bindline $t $id
1389}
1390
Paul Mackerrasc934a8a2006-03-02 12:00:441391proc drawparentlinks {id row col olds} {
Paul Mackerraseb447a12006-03-18 12:11:371392 global rowidlist canv colormap idrowranges
Paul Mackerras9f1afe02006-02-19 11:44:471393
1394 set row2 [expr {$row + 1}]
1395 set x [xc $row $col]
1396 set y [yc $row]
1397 set y2 [yc $row2]
Paul Mackerras8f7d0ce2006-02-28 11:10:191398 set ids [lindex $rowidlist $row2]
Paul Mackerras9f1afe02006-02-19 11:44:471399 # rmx = right-most X coord used
1400 set rmx 0
Paul Mackerras9f1afe02006-02-19 11:44:471401 foreach p $olds {
Paul Mackerrasf3408442006-03-30 22:54:241402 set i [lsearch -exact $ids $p]
1403 if {$i < 0} {
1404 puts "oops, parent $p of $id not in list"
1405 continue
1406 }
1407 set x2 [xc $row2 $i]
1408 if {$x2 > $rmx} {
1409 set rmx $x2
1410 }
Paul Mackerraseb447a12006-03-18 12:11:371411 if {[info exists idrowranges($p)] &&
1412 $row2 == [lindex $idrowranges($p) 0] &&
1413 $row2 < [lindex $idrowranges($p) 1]} {
1414 # drawlineseg will do this one for us
1415 continue
1416 }
Paul Mackerras9f1afe02006-02-19 11:44:471417 assigncolor $p
1418 # should handle duplicated parents here...
1419 set coords [list $x $y]
1420 if {$i < $col - 1} {
1421 lappend coords [xc $row [expr {$i + 1}]] $y
1422 } elseif {$i > $col + 1} {
1423 lappend coords [xc $row [expr {$i - 1}]] $y
1424 }
Paul Mackerras9f1afe02006-02-19 11:44:471425 lappend coords $x2 $y2
Paul Mackerrasc934a8a2006-03-02 12:00:441426 set t [$canv create line $coords -width [linewidth $p] \
Paul Mackerras9f1afe02006-02-19 11:44:471427 -fill $colormap($p) -tags lines.$p]
1428 $canv lower $t
1429 bindline $t $p
1430 }
1431 return $rmx
1432}
1433
Paul Mackerrasc934a8a2006-03-02 12:00:441434proc drawlines {id} {
Paul Mackerras9f1afe02006-02-19 11:44:471435 global colormap canv
1436 global idrowranges idrangedrawn
Paul Mackerras79b2c752006-04-02 10:47:401437 global childlist iddrawn commitrow rowidlist
Paul Mackerras9f1afe02006-02-19 11:44:471438
1439 $canv delete lines.$id
Paul Mackerras9f1afe02006-02-19 11:44:471440 set nr [expr {[llength $idrowranges($id)] / 2}]
1441 for {set i 0} {$i < $nr} {incr i} {
1442 if {[info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 12:00:441443 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 11:44:471444 }
1445 }
Paul Mackerras79b2c752006-04-02 10:47:401446 foreach child [lindex $childlist $commitrow($id)] {
1447 if {[info exists iddrawn($child)]} {
1448 set row $commitrow($child)
1449 set col [lsearch -exact [lindex $rowidlist $row] $child]
1450 if {$col >= 0} {
1451 drawparentlinks $child $row $col [list $id]
Paul Mackerras9f1afe02006-02-19 11:44:471452 }
1453 }
1454 }
1455}
1456
1457proc drawcmittext {id row col rmx} {
1458 global linespc canv canv2 canv3 canvy0
1459 global commitlisted commitinfo rowidlist
1460 global rowtextx idpos idtags idheads idotherrefs
1461 global linehtag linentag linedtag
Paul Mackerrasbe0cd092006-03-30 22:55:111462 global mainfont namefont canvxmax
Paul Mackerras9f1afe02006-02-19 11:44:471463
Paul Mackerras79b2c752006-04-02 10:47:401464 set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}]
Paul Mackerras9f1afe02006-02-19 11:44:471465 set x [xc $row $col]
1466 set y [yc $row]
1467 set orad [expr {$linespc / 3}]
1468 set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
1469 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
1470 -fill $ofill -outline black -width 1]
1471 $canv raise $t
1472 $canv bind $t <1> {selcanvline {} %x %y}
Paul Mackerras8f7d0ce2006-02-28 11:10:191473 set xt [xc $row [llength [lindex $rowidlist $row]]]
Paul Mackerras9f1afe02006-02-19 11:44:471474 if {$xt < $rmx} {
1475 set xt $rmx
1476 }
1477 set rowtextx($row) $xt
1478 set idpos($id) [list $x $xt $y]
1479 if {[info exists idtags($id)] || [info exists idheads($id)]
1480 || [info exists idotherrefs($id)]} {
1481 set xt [drawtags $id $x $xt $y]
1482 }
1483 set headline [lindex $commitinfo($id) 0]
1484 set name [lindex $commitinfo($id) 1]
1485 set date [lindex $commitinfo($id) 2]
1486 set date [formatdate $date]
1487 set linehtag($row) [$canv create text $xt $y -anchor w \
1488 -text $headline -font $mainfont ]
1489 $canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
1490 set linentag($row) [$canv2 create text 3 $y -anchor w \
1491 -text $name -font $namefont]
1492 set linedtag($row) [$canv3 create text 3 $y -anchor w \
1493 -text $date -font $mainfont]
Paul Mackerrasbe0cd092006-03-30 22:55:111494 set xr [expr {$xt + [font measure $mainfont $headline]}]
1495 if {$xr > $canvxmax} {
1496 set canvxmax $xr
1497 setcanvscroll
1498 }
Paul Mackerras9f1afe02006-02-19 11:44:471499}
1500
1501proc drawcmitrow {row} {
Paul Mackerras8f7d0ce2006-02-28 11:10:191502 global displayorder rowidlist
Paul Mackerras9f1afe02006-02-19 11:44:471503 global idrowranges idrangedrawn iddrawn
Paul Mackerrase7da3472006-04-17 00:27:591504 global commitinfo parentlist numcommits
Paul Mackerras9f1afe02006-02-19 11:44:471505
Paul Mackerras8f7d0ce2006-02-28 11:10:191506 if {$row >= $numcommits} return
1507 foreach id [lindex $rowidlist $row] {
Paul Mackerras9f1afe02006-02-19 11:44:471508 if {![info exists idrowranges($id)]} continue
1509 set i -1
1510 foreach {s e} $idrowranges($id) {
1511 incr i
1512 if {$row < $s} continue
1513 if {$e eq {}} break
1514 if {$row <= $e} {
1515 if {$e < $numcommits && ![info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 12:00:441516 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 11:44:471517 set idrangedrawn($id,$i) 1
1518 }
1519 break
1520 }
1521 }
1522 }
1523
1524 set id [lindex $displayorder $row]
1525 if {[info exists iddrawn($id)]} return
Paul Mackerras8f7d0ce2006-02-28 11:10:191526 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 11:44:471527 if {$col < 0} {
1528 puts "oops, row $row id $id not in list"
1529 return
1530 }
1531 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-17 23:04:481532 getcommit $id
Paul Mackerras9f1afe02006-02-19 11:44:471533 }
1534 assigncolor $id
Paul Mackerras79b2c752006-04-02 10:47:401535 set olds [lindex $parentlist $row]
1536 if {$olds ne {}} {
1537 set rmx [drawparentlinks $id $row $col $olds]
Paul Mackerras9f1afe02006-02-19 11:44:471538 } else {
1539 set rmx 0
1540 }
1541 drawcmittext $id $row $col $rmx
1542 set iddrawn($id) 1
1543}
1544
1545proc drawfrac {f0 f1} {
1546 global numcommits canv
1547 global linespc
1548
1549 set ymax [lindex [$canv cget -scrollregion] 3]
1550 if {$ymax eq {} || $ymax == 0} return
1551 set y0 [expr {int($f0 * $ymax)}]
1552 set row [expr {int(($y0 - 3) / $linespc) - 1}]
1553 if {$row < 0} {
1554 set row 0
1555 }
1556 set y1 [expr {int($f1 * $ymax)}]
1557 set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
1558 if {$endrow >= $numcommits} {
1559 set endrow [expr {$numcommits - 1}]
1560 }
1561 for {} {$row <= $endrow} {incr row} {
1562 drawcmitrow $row
1563 }
1564}
1565
1566proc drawvisible {} {
1567 global canv
1568 eval drawfrac [$canv yview]
1569}
1570
1571proc clear_display {} {
1572 global iddrawn idrangedrawn
1573
1574 allcanvs delete all
1575 catch {unset iddrawn}
1576 catch {unset idrangedrawn}
1577}
1578
Paul Mackerrase5c2d852005-05-11 23:44:541579proc assigncolor {id} {
Paul Mackerrasaa81d972006-02-28 00:27:121580 global colormap colors nextcolor
Paul Mackerras79b2c752006-04-02 10:47:401581 global commitrow parentlist children childlist
Paul Mackerras6c20ff32005-06-22 09:53:321582 global cornercrossings crossings
1583
Paul Mackerras418c4c72006-02-06 22:10:181584 if {[info exists colormap($id)]} return
Paul Mackerrase5c2d852005-05-11 23:44:541585 set ncolors [llength $colors]
Paul Mackerras79b2c752006-04-02 10:47:401586 if {[info exists commitrow($id)]} {
1587 set kids [lindex $childlist $commitrow($id)]
1588 } elseif {[info exists children($id)]} {
1589 set kids $children($id)
1590 } else {
1591 set kids {}
1592 }
1593 if {[llength $kids] == 1} {
1594 set child [lindex $kids 0]
Paul Mackerras9ccbdfb2005-06-16 00:27:231595 if {[info exists colormap($child)]
Paul Mackerras79b2c752006-04-02 10:47:401596 && [llength [lindex $parentlist $commitrow($child)]] == 1} {
Paul Mackerras9ccbdfb2005-06-16 00:27:231597 set colormap($id) $colormap($child)
1598 return
Paul Mackerrase5c2d852005-05-11 23:44:541599 }
Paul Mackerras9ccbdfb2005-06-16 00:27:231600 }
1601 set badcolors {}
Paul Mackerras6c20ff32005-06-22 09:53:321602 if {[info exists cornercrossings($id)]} {
1603 foreach x $cornercrossings($id) {
1604 if {[info exists colormap($x)]
1605 && [lsearch -exact $badcolors $colormap($x)] < 0} {
1606 lappend badcolors $colormap($x)
1607 }
Paul Mackerrase5c2d852005-05-11 23:44:541608 }
Paul Mackerras6c20ff32005-06-22 09:53:321609 if {[llength $badcolors] >= $ncolors} {
1610 set badcolors {}
1611 }
1612 }
1613 set origbad $badcolors
1614 if {[llength $badcolors] < $ncolors - 1} {
1615 if {[info exists crossings($id)]} {
1616 foreach x $crossings($id) {
1617 if {[info exists colormap($x)]
1618 && [lsearch -exact $badcolors $colormap($x)] < 0} {
1619 lappend badcolors $colormap($x)
1620 }
1621 }
1622 if {[llength $badcolors] >= $ncolors} {
1623 set badcolors $origbad
1624 }
1625 }
1626 set origbad $badcolors
1627 }
1628 if {[llength $badcolors] < $ncolors - 1} {
Paul Mackerras79b2c752006-04-02 10:47:401629 foreach child $kids {
Paul Mackerras6c20ff32005-06-22 09:53:321630 if {[info exists colormap($child)]
1631 && [lsearch -exact $badcolors $colormap($child)] < 0} {
1632 lappend badcolors $colormap($child)
1633 }
Paul Mackerras79b2c752006-04-02 10:47:401634 foreach p [lindex $parentlist $commitrow($child)] {
1635 if {[info exists colormap($p)]
1636 && [lsearch -exact $badcolors $colormap($p)] < 0} {
1637 lappend badcolors $colormap($p)
Paul Mackerrase5c2d852005-05-11 23:44:541638 }
1639 }
1640 }
Paul Mackerras6c20ff32005-06-22 09:53:321641 if {[llength $badcolors] >= $ncolors} {
1642 set badcolors $origbad
1643 }
Paul Mackerras9ccbdfb2005-06-16 00:27:231644 }
1645 for {set i 0} {$i <= $ncolors} {incr i} {
1646 set c [lindex $colors $nextcolor]
1647 if {[incr nextcolor] >= $ncolors} {
1648 set nextcolor 0
Paul Mackerrase5c2d852005-05-11 23:44:541649 }
Paul Mackerras9ccbdfb2005-06-16 00:27:231650 if {[lsearch -exact $badcolors $c]} break
1651 }
1652 set colormap($id) $c
1653}
1654
Paul Mackerrasa823a912005-06-21 00:01:381655proc bindline {t id} {
1656 global canv
1657
Paul Mackerrasa823a912005-06-21 00:01:381658 $canv bind $t <Enter> "lineenter %x %y $id"
1659 $canv bind $t <Motion> "linemotion %x %y $id"
1660 $canv bind $t <Leave> "lineleave $id"
Paul Mackerrasfa4da7b2005-08-07 23:47:221661 $canv bind $t <Button-1> "lineclick %x %y $id 1"
Paul Mackerrasa823a912005-06-21 00:01:381662}
1663
Paul Mackerrasbdbfbe32005-06-27 12:56:401664proc drawtags {id x xt y1} {
Paul Mackerrasf1d83ba2005-08-19 12:14:281665 global idtags idheads idotherrefs
Paul Mackerrasbdbfbe32005-06-27 12:56:401666 global linespc lthickness
Paul Mackerras9f1afe02006-02-19 11:44:471667 global canv mainfont commitrow rowtextx
Paul Mackerrasbdbfbe32005-06-27 12:56:401668
1669 set marks {}
1670 set ntags 0
Paul Mackerrasf1d83ba2005-08-19 12:14:281671 set nheads 0
Paul Mackerrasbdbfbe32005-06-27 12:56:401672 if {[info exists idtags($id)]} {
1673 set marks $idtags($id)
1674 set ntags [llength $marks]
1675 }
1676 if {[info exists idheads($id)]} {
1677 set marks [concat $marks $idheads($id)]
Paul Mackerrasf1d83ba2005-08-19 12:14:281678 set nheads [llength $idheads($id)]
1679 }
1680 if {[info exists idotherrefs($id)]} {
1681 set marks [concat $marks $idotherrefs($id)]
Paul Mackerrasbdbfbe32005-06-27 12:56:401682 }
1683 if {$marks eq {}} {
1684 return $xt
1685 }
1686
1687 set delta [expr {int(0.5 * ($linespc - $lthickness))}]
Jeff Hobbs2ed49d52005-11-23 01:39:531688 set yt [expr {$y1 - 0.5 * $linespc}]
1689 set yb [expr {$yt + $linespc - 1}]
Paul Mackerrasbdbfbe32005-06-27 12:56:401690 set xvals {}
1691 set wvals {}
1692 foreach tag $marks {
1693 set wid [font measure $mainfont $tag]
1694 lappend xvals $xt
1695 lappend wvals $wid
1696 set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
1697 }
1698 set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
1699 -width $lthickness -fill black -tags tag.$id]
1700 $canv lower $t
1701 foreach tag $marks x $xvals wid $wvals {
Jeff Hobbs2ed49d52005-11-23 01:39:531702 set xl [expr {$x + $delta}]
1703 set xr [expr {$x + $delta + $wid + $lthickness}]
Paul Mackerrasbdbfbe32005-06-27 12:56:401704 if {[incr ntags -1] >= 0} {
1705 # draw a tag
Jeff Hobbs2ed49d52005-11-23 01:39:531706 set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
1707 $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
Paul Mackerras106288c2005-08-19 13:11:391708 -width 1 -outline black -fill yellow -tags tag.$id]
1709 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras9f1afe02006-02-19 11:44:471710 set rowtextx($commitrow($id)) [expr {$xr + $linespc}]
Paul Mackerrasbdbfbe32005-06-27 12:56:401711 } else {
Paul Mackerrasf1d83ba2005-08-19 12:14:281712 # draw a head or other ref
1713 if {[incr nheads -1] >= 0} {
1714 set col green
1715 } else {
1716 set col "#ddddff"
1717 }
Jeff Hobbs2ed49d52005-11-23 01:39:531718 set xl [expr {$xl - $delta/2}]
Paul Mackerrasbdbfbe32005-06-27 12:56:401719 $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
Paul Mackerrasf1d83ba2005-08-19 12:14:281720 -width 1 -outline black -fill $col -tags tag.$id
Paul Mackerrasbdbfbe32005-06-27 12:56:401721 }
Paul Mackerras106288c2005-08-19 13:11:391722 set t [$canv create text $xl $y1 -anchor w -text $tag \
1723 -font $mainfont -tags tag.$id]
1724 if {$ntags >= 0} {
1725 $canv bind $t <1> [list showtag $tag 1]
1726 }
Paul Mackerrasbdbfbe32005-06-27 12:56:401727 }
1728 return $xt
1729}
1730
Paul Mackerras9f1afe02006-02-19 11:44:471731proc checkcrossings {row endrow} {
Paul Mackerras79b2c752006-04-02 10:47:401732 global displayorder parentlist rowidlist
Paul Mackerras9f1afe02006-02-19 11:44:471733
1734 for {} {$row < $endrow} {incr row} {
1735 set id [lindex $displayorder $row]
Paul Mackerras8f7d0ce2006-02-28 11:10:191736 set i [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 11:44:471737 if {$i < 0} continue
Paul Mackerras8f7d0ce2006-02-28 11:10:191738 set idlist [lindex $rowidlist [expr {$row+1}]]
Paul Mackerras79b2c752006-04-02 10:47:401739 foreach p [lindex $parentlist $row] {
Paul Mackerras9f1afe02006-02-19 11:44:471740 set j [lsearch -exact $idlist $p]
1741 if {$j > 0} {
1742 if {$j < $i - 1} {
1743 notecrossings $row $p $j $i [expr {$j+1}]
1744 } elseif {$j > $i + 1} {
1745 notecrossings $row $p $i $j [expr {$j-1}]
1746 }
1747 }
1748 }
1749 }
1750}
1751
1752proc notecrossings {row id lo hi corner} {
1753 global rowidlist crossings cornercrossings
Paul Mackerras6c20ff32005-06-22 09:53:321754
1755 for {set i $lo} {[incr i] < $hi} {} {
Paul Mackerras8f7d0ce2006-02-28 11:10:191756 set p [lindex [lindex $rowidlist $row] $i]
Paul Mackerras6c20ff32005-06-22 09:53:321757 if {$p == {}} continue
1758 if {$i == $corner} {
1759 if {![info exists cornercrossings($id)]
1760 || [lsearch -exact $cornercrossings($id) $p] < 0} {
1761 lappend cornercrossings($id) $p
1762 }
1763 if {![info exists cornercrossings($p)]
1764 || [lsearch -exact $cornercrossings($p) $id] < 0} {
1765 lappend cornercrossings($p) $id
1766 }
1767 } else {
1768 if {![info exists crossings($id)]
1769 || [lsearch -exact $crossings($id) $p] < 0} {
1770 lappend crossings($id) $p
1771 }
1772 if {![info exists crossings($p)]
1773 || [lsearch -exact $crossings($p) $id] < 0} {
1774 lappend crossings($p) $id
1775 }
1776 }
1777 }
1778}
1779
Paul Mackerras8d858d12005-08-04 23:52:161780proc xcoord {i level ln} {
1781 global canvx0 xspc1 xspc2
Paul Mackerras9ccbdfb2005-06-16 00:27:231782
Paul Mackerras8d858d12005-08-04 23:52:161783 set x [expr {$canvx0 + $i * $xspc1($ln)}]
1784 if {$i > 0 && $i == $level} {
1785 set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
1786 } elseif {$i > $level} {
1787 set x [expr {$x + $xspc2 - $xspc1($ln)}]
1788 }
1789 return $x
1790}
1791
Paul Mackerras9ccbdfb2005-06-16 00:27:231792proc finishcommits {} {
Paul Mackerras8ed16482006-03-02 11:56:441793 global commitidx phase
Paul Mackerras8a0a74a2005-06-27 03:38:291794 global canv mainfont ctext maincursor textcursor
Paul Mackerrasf4171a12006-03-18 05:02:511795 global findinprogress
Paul Mackerras9ccbdfb2005-06-16 00:27:231796
Paul Mackerras8ed16482006-03-02 11:56:441797 if {$commitidx > 0} {
Sven Verdoolaegeb5c2f302005-11-29 21:15:511798 drawrest
Sven Verdoolaegeb5c2f302005-11-29 21:15:511799 } else {
Paul Mackerras9ccbdfb2005-06-16 00:27:231800 $canv delete all
1801 $canv create text 3 3 -anchor nw -text "No commits selected" \
1802 -font $mainfont -tags textitems
Paul Mackerras9ccbdfb2005-06-16 00:27:231803 }
Paul Mackerrasf4171a12006-03-18 05:02:511804 if {![info exists findinprogress]} {
1805 . config -cursor $maincursor
1806 settextcursor $textcursor
1807 }
Paul Mackerras8ed16482006-03-02 11:56:441808 set phase {}
Paul Mackerras94a2eed2005-08-07 05:27:571809}
1810
1811# Don't change the text pane cursor if it is currently the hand cursor,
1812# showing that we are over a sha1 ID link.
1813proc settextcursor {c} {
1814 global ctext curtextcursor
1815
1816 if {[$ctext cget -cursor] == $curtextcursor} {
1817 $ctext config -cursor $c
1818 }
1819 set curtextcursor $c
Paul Mackerras9ccbdfb2005-06-16 00:27:231820}
1821
Paul Mackerrasf6075eb2005-08-17 23:30:101822proc drawrest {} {
Paul Mackerras9f1afe02006-02-19 11:44:471823 global numcommits
1824 global startmsecs
1825 global canvy0 numcommits linespc
1826 global rowlaidout commitidx
Paul Mackerras9ccbdfb2005-06-16 00:27:231827
Paul Mackerras9f1afe02006-02-19 11:44:471828 set row $rowlaidout
1829 layoutrows $rowlaidout $commitidx 1
1830 layouttail
1831 optimize_rows $row 0 $commitidx
1832 showstuff $commitidx
Paul Mackerras4dd5d0d2005-12-05 22:46:231833
Jeff Hobbs2ed49d52005-11-23 01:39:531834 set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
Paul Mackerras4e95e1f2006-04-04 23:39:511835 #puts "overall $drawmsecs ms for $numcommits commits"
Paul Mackerras1db95b02005-05-09 04:08:391836}
1837
Paul Mackerrasdf3d83b2005-05-17 23:23:071838proc findmatches {f} {
1839 global findtype foundstring foundstrlen
1840 if {$findtype == "Regexp"} {
1841 set matches [regexp -indices -all -inline $foundstring $f]
1842 } else {
1843 if {$findtype == "IgnCase"} {
1844 set str [string tolower $f]
1845 } else {
1846 set str $f
1847 }
1848 set matches {}
1849 set i 0
1850 while {[set j [string first $foundstring $str $i]] >= 0} {
Jeff Hobbs2ed49d52005-11-23 01:39:531851 lappend matches [list $j [expr {$j+$foundstrlen-1}]]
1852 set i [expr {$j + $foundstrlen}]
Paul Mackerrasdf3d83b2005-05-17 23:23:071853 }
1854 }
1855 return $matches
1856}
1857
Paul Mackerras98f350e2005-05-15 05:56:511858proc dofind {} {
1859 global findtype findloc findstring markedmatches commitinfo
Paul Mackerras8f7d0ce2006-02-28 11:10:191860 global numcommits displayorder linehtag linentag linedtag
Paul Mackerras98f350e2005-05-15 05:56:511861 global mainfont namefont canv canv2 canv3 selectedline
Paul Mackerras8ed16482006-03-02 11:56:441862 global matchinglines foundstring foundstrlen matchstring
1863 global commitdata
Paul Mackerrasb74fd572005-07-16 11:46:131864
1865 stopfindproc
Paul Mackerras98f350e2005-05-15 05:56:511866 unmarkmatches
Paul Mackerrasdf3d83b2005-05-17 23:23:071867 focus .
Paul Mackerras98f350e2005-05-15 05:56:511868 set matchinglines {}
Paul Mackerrasb74fd572005-07-16 11:46:131869 if {$findloc == "Pickaxe"} {
1870 findpatches
1871 return
1872 }
Paul Mackerras98f350e2005-05-15 05:56:511873 if {$findtype == "IgnCase"} {
Paul Mackerrasdf3d83b2005-05-17 23:23:071874 set foundstring [string tolower $findstring]
Paul Mackerras98f350e2005-05-15 05:56:511875 } else {
Paul Mackerrasdf3d83b2005-05-17 23:23:071876 set foundstring $findstring
Paul Mackerras98f350e2005-05-15 05:56:511877 }
Paul Mackerrasdf3d83b2005-05-17 23:23:071878 set foundstrlen [string length $findstring]
1879 if {$foundstrlen == 0} return
Paul Mackerras8ed16482006-03-02 11:56:441880 regsub -all {[*?\[\\]} $foundstring {\\&} matchstring
1881 set matchstring "*$matchstring*"
Paul Mackerrasb74fd572005-07-16 11:46:131882 if {$findloc == "Files"} {
1883 findfiles
1884 return
1885 }
Paul Mackerras98f350e2005-05-15 05:56:511886 if {![info exists selectedline]} {
1887 set oldsel -1
1888 } else {
1889 set oldsel $selectedline
1890 }
1891 set didsel 0
Paul Mackerrasb74fd572005-07-16 11:46:131892 set fldtypes {Headline Author Date Committer CDate Comment}
Paul Mackerras8ed16482006-03-02 11:56:441893 set l -1
Paul Mackerrasf7a3e8d2006-03-17 23:04:481894 foreach id $displayorder {
1895 set d $commitdata($id)
Paul Mackerras8ed16482006-03-02 11:56:441896 incr l
1897 if {$findtype == "Regexp"} {
1898 set doesmatch [regexp $foundstring $d]
1899 } elseif {$findtype == "IgnCase"} {
1900 set doesmatch [string match -nocase $matchstring $d]
1901 } else {
1902 set doesmatch [string match $matchstring $d]
1903 }
1904 if {!$doesmatch} continue
Paul Mackerras8ed16482006-03-02 11:56:441905 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-17 23:04:481906 getcommit $id
Paul Mackerras8ed16482006-03-02 11:56:441907 }
Paul Mackerras98f350e2005-05-15 05:56:511908 set info $commitinfo($id)
1909 set doesmatch 0
1910 foreach f $info ty $fldtypes {
1911 if {$findloc != "All fields" && $findloc != $ty} {
1912 continue
1913 }
Paul Mackerrasdf3d83b2005-05-17 23:23:071914 set matches [findmatches $f]
Paul Mackerras98f350e2005-05-15 05:56:511915 if {$matches == {}} continue
1916 set doesmatch 1
1917 if {$ty == "Headline"} {
Paul Mackerras9f1afe02006-02-19 11:44:471918 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:511919 markmatches $canv $l $f $linehtag($l) $matches $mainfont
1920 } elseif {$ty == "Author"} {
Paul Mackerras9f1afe02006-02-19 11:44:471921 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:511922 markmatches $canv2 $l $f $linentag($l) $matches $namefont
1923 } elseif {$ty == "Date"} {
Paul Mackerras9f1afe02006-02-19 11:44:471924 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:511925 markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
1926 }
1927 }
1928 if {$doesmatch} {
1929 lappend matchinglines $l
1930 if {!$didsel && $l > $oldsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:071931 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:511932 set didsel 1
1933 }
1934 }
1935 }
1936 if {$matchinglines == {}} {
1937 bell
1938 } elseif {!$didsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:071939 findselectline [lindex $matchinglines 0]
1940 }
1941}
1942
1943proc findselectline {l} {
1944 global findloc commentend ctext
Paul Mackerrasd6982062005-08-06 12:06:061945 selectline $l 1
Paul Mackerrasdf3d83b2005-05-17 23:23:071946 if {$findloc == "All fields" || $findloc == "Comments"} {
1947 # highlight the matches in the comments
1948 set f [$ctext get 1.0 $commentend]
1949 set matches [findmatches $f]
1950 foreach match $matches {
1951 set start [lindex $match 0]
Jeff Hobbs2ed49d52005-11-23 01:39:531952 set end [expr {[lindex $match 1] + 1}]
Paul Mackerrasdf3d83b2005-05-17 23:23:071953 $ctext tag add found "1.0 + $start c" "1.0 + $end c"
1954 }
Paul Mackerras98f350e2005-05-15 05:56:511955 }
1956}
1957
Paul Mackerrasb74fd572005-07-16 11:46:131958proc findnext {restart} {
Paul Mackerras98f350e2005-05-15 05:56:511959 global matchinglines selectedline
1960 if {![info exists matchinglines]} {
Paul Mackerrasb74fd572005-07-16 11:46:131961 if {$restart} {
1962 dofind
1963 }
Paul Mackerras98f350e2005-05-15 05:56:511964 return
1965 }
1966 if {![info exists selectedline]} return
1967 foreach l $matchinglines {
1968 if {$l > $selectedline} {
Paul Mackerrasdf3d83b2005-05-17 23:23:071969 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:511970 return
1971 }
1972 }
1973 bell
1974}
1975
1976proc findprev {} {
1977 global matchinglines selectedline
1978 if {![info exists matchinglines]} {
1979 dofind
1980 return
1981 }
1982 if {![info exists selectedline]} return
1983 set prev {}
1984 foreach l $matchinglines {
1985 if {$l >= $selectedline} break
1986 set prev $l
1987 }
1988 if {$prev != {}} {
Paul Mackerrasdf3d83b2005-05-17 23:23:071989 findselectline $prev
Paul Mackerras98f350e2005-05-15 05:56:511990 } else {
1991 bell
1992 }
1993}
1994
Paul Mackerrasb74fd572005-07-16 11:46:131995proc findlocchange {name ix op} {
1996 global findloc findtype findtypemenu
1997 if {$findloc == "Pickaxe"} {
1998 set findtype Exact
1999 set state disabled
2000 } else {
2001 set state normal
2002 }
2003 $findtypemenu entryconf 1 -state $state
2004 $findtypemenu entryconf 2 -state $state
2005}
2006
2007proc stopfindproc {{done 0}} {
2008 global findprocpid findprocfile findids
2009 global ctext findoldcursor phase maincursor textcursor
2010 global findinprogress
2011
2012 catch {unset findids}
2013 if {[info exists findprocpid]} {
2014 if {!$done} {
2015 catch {exec kill $findprocpid}
2016 }
2017 catch {close $findprocfile}
2018 unset findprocpid
2019 }
2020 if {[info exists findinprogress]} {
2021 unset findinprogress
2022 if {$phase != "incrdraw"} {
2023 . config -cursor $maincursor
Paul Mackerras94a2eed2005-08-07 05:27:572024 settextcursor $textcursor
Paul Mackerrasb74fd572005-07-16 11:46:132025 }
2026 }
2027}
2028
2029proc findpatches {} {
2030 global findstring selectedline numcommits
2031 global findprocpid findprocfile
Paul Mackerras8f7d0ce2006-02-28 11:10:192032 global finddidsel ctext displayorder findinprogress
Paul Mackerras14c9dbd2005-07-17 01:53:552033 global findinsertpos
Paul Mackerrasb74fd572005-07-16 11:46:132034
2035 if {$numcommits == 0} return
2036
2037 # make a list of all the ids to search, starting at the one
2038 # after the selected line (if any)
2039 if {[info exists selectedline]} {
2040 set l $selectedline
2041 } else {
2042 set l -1
2043 }
2044 set inputids {}
2045 for {set i 0} {$i < $numcommits} {incr i} {
2046 if {[incr l] >= $numcommits} {
2047 set l 0
2048 }
Paul Mackerras8f7d0ce2006-02-28 11:10:192049 append inputids [lindex $displayorder $l] "\n"
Paul Mackerrasb74fd572005-07-16 11:46:132050 }
2051
2052 if {[catch {
2053 set f [open [list | git-diff-tree --stdin -s -r -S$findstring \
2054 << $inputids] r]
2055 } err]} {
2056 error_popup "Error starting search process: $err"
2057 return
2058 }
2059
Paul Mackerras14c9dbd2005-07-17 01:53:552060 set findinsertpos end
Paul Mackerrasb74fd572005-07-16 11:46:132061 set findprocfile $f
2062 set findprocpid [pid $f]
2063 fconfigure $f -blocking 0
2064 fileevent $f readable readfindproc
2065 set finddidsel 0
2066 . config -cursor watch
Paul Mackerras94a2eed2005-08-07 05:27:572067 settextcursor watch
Paul Mackerrasb74fd572005-07-16 11:46:132068 set findinprogress 1
2069}
2070
2071proc readfindproc {} {
2072 global findprocfile finddidsel
Paul Mackerras9f1afe02006-02-19 11:44:472073 global commitrow matchinglines findinsertpos
Paul Mackerrasb74fd572005-07-16 11:46:132074
2075 set n [gets $findprocfile line]
2076 if {$n < 0} {
2077 if {[eof $findprocfile]} {
2078 stopfindproc 1
2079 if {!$finddidsel} {
2080 bell
2081 }
2082 }
2083 return
2084 }
2085 if {![regexp {^[0-9a-f]{40}} $line id]} {
2086 error_popup "Can't parse git-diff-tree output: $line"
2087 stopfindproc
2088 return
2089 }
Paul Mackerras9f1afe02006-02-19 11:44:472090 if {![info exists commitrow($id)]} {
Paul Mackerrasb74fd572005-07-16 11:46:132091 puts stderr "spurious id: $id"
2092 return
2093 }
Paul Mackerras9f1afe02006-02-19 11:44:472094 set l $commitrow($id)
Paul Mackerras14c9dbd2005-07-17 01:53:552095 insertmatch $l $id
2096}
2097
2098proc insertmatch {l id} {
2099 global matchinglines findinsertpos finddidsel
2100
2101 if {$findinsertpos == "end"} {
2102 if {$matchinglines != {} && $l < [lindex $matchinglines 0]} {
2103 set matchinglines [linsert $matchinglines 0 $l]
2104 set findinsertpos 1
2105 } else {
2106 lappend matchinglines $l
2107 }
2108 } else {
2109 set matchinglines [linsert $matchinglines $findinsertpos $l]
2110 incr findinsertpos
2111 }
2112 markheadline $l $id
Paul Mackerrasb74fd572005-07-16 11:46:132113 if {!$finddidsel} {
2114 findselectline $l
2115 set finddidsel 1
2116 }
2117}
2118
2119proc findfiles {} {
Paul Mackerras8f7d0ce2006-02-28 11:10:192120 global selectedline numcommits displayorder ctext
Paul Mackerras79b2c752006-04-02 10:47:402121 global ffileline finddidsel parentlist
Paul Mackerras14c9dbd2005-07-17 01:53:552122 global findinprogress findstartline findinsertpos
Paul Mackerras69d47bd2006-02-09 23:29:262123 global treediffs fdiffid fdiffsneeded fdiffpos
Paul Mackerras14c9dbd2005-07-17 01:53:552124 global findmergefiles
Paul Mackerrasb74fd572005-07-16 11:46:132125
2126 if {$numcommits == 0} return
2127
2128 if {[info exists selectedline]} {
2129 set l [expr {$selectedline + 1}]
2130 } else {
2131 set l 0
2132 }
2133 set ffileline $l
Paul Mackerrasb74fd572005-07-16 11:46:132134 set findstartline $l
Paul Mackerras14c9dbd2005-07-17 01:53:552135 set diffsneeded {}
2136 set fdiffsneeded {}
2137 while 1 {
Paul Mackerras8f7d0ce2006-02-28 11:10:192138 set id [lindex $displayorder $l]
Paul Mackerras79b2c752006-04-02 10:47:402139 if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} {
Paul Mackerras69d47bd2006-02-09 23:29:262140 if {![info exists treediffs($id)]} {
2141 append diffsneeded "$id\n"
2142 lappend fdiffsneeded $id
Paul Mackerras14c9dbd2005-07-17 01:53:552143 }
2144 }
2145 if {[incr l] >= $numcommits} {
2146 set l 0
2147 }
2148 if {$l == $findstartline} break
2149 }
2150
2151 # start off a git-diff-tree process if needed
2152 if {$diffsneeded ne {}} {
2153 if {[catch {
2154 set df [open [list | git-diff-tree -r --stdin << $diffsneeded] r]
2155 } err ]} {
2156 error_popup "Error starting search process: $err"
2157 return
2158 }
Paul Mackerras69d47bd2006-02-09 23:29:262159 catch {unset fdiffid}
Paul Mackerras14c9dbd2005-07-17 01:53:552160 set fdiffpos 0
2161 fconfigure $df -blocking 0
2162 fileevent $df readable [list readfilediffs $df]
2163 }
2164
2165 set finddidsel 0
2166 set findinsertpos end
Paul Mackerras8f7d0ce2006-02-28 11:10:192167 set id [lindex $displayorder $l]
Paul Mackerrasb74fd572005-07-16 11:46:132168 . config -cursor watch
Paul Mackerras94a2eed2005-08-07 05:27:572169 settextcursor watch
Paul Mackerrasb74fd572005-07-16 11:46:132170 set findinprogress 1
Paul Mackerras79b2c752006-04-02 10:47:402171 findcont
Paul Mackerras14c9dbd2005-07-17 01:53:552172 update
2173}
2174
2175proc readfilediffs {df} {
Paul Mackerras69d47bd2006-02-09 23:29:262176 global findid fdiffid fdiffs
Paul Mackerras14c9dbd2005-07-17 01:53:552177
2178 set n [gets $df line]
2179 if {$n < 0} {
2180 if {[eof $df]} {
2181 donefilediff
2182 if {[catch {close $df} err]} {
2183 stopfindproc
2184 bell
2185 error_popup "Error in git-diff-tree: $err"
Paul Mackerras69d47bd2006-02-09 23:29:262186 } elseif {[info exists findid]} {
2187 set id $findid
Paul Mackerras14c9dbd2005-07-17 01:53:552188 stopfindproc
2189 bell
Paul Mackerras69d47bd2006-02-09 23:29:262190 error_popup "Couldn't find diffs for $id"
Paul Mackerras14c9dbd2005-07-17 01:53:552191 }
2192 }
2193 return
2194 }
Paul Mackerras69d47bd2006-02-09 23:29:262195 if {[regexp {^([0-9a-f]{40})$} $line match id]} {
Paul Mackerras14c9dbd2005-07-17 01:53:552196 # start of a new string of diffs
2197 donefilediff
Paul Mackerras69d47bd2006-02-09 23:29:262198 set fdiffid $id
Paul Mackerras14c9dbd2005-07-17 01:53:552199 set fdiffs {}
2200 } elseif {[string match ":*" $line]} {
2201 lappend fdiffs [lindex $line 5]
2202 }
2203}
2204
2205proc donefilediff {} {
Paul Mackerras69d47bd2006-02-09 23:29:262206 global fdiffid fdiffs treediffs findid
Paul Mackerras14c9dbd2005-07-17 01:53:552207 global fdiffsneeded fdiffpos
2208
Paul Mackerras69d47bd2006-02-09 23:29:262209 if {[info exists fdiffid]} {
2210 while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffid
Paul Mackerras14c9dbd2005-07-17 01:53:552211 && $fdiffpos < [llength $fdiffsneeded]} {
2212 # git-diff-tree doesn't output anything for a commit
2213 # which doesn't change anything
Paul Mackerras69d47bd2006-02-09 23:29:262214 set nullid [lindex $fdiffsneeded $fdiffpos]
2215 set treediffs($nullid) {}
2216 if {[info exists findid] && $nullid eq $findid} {
2217 unset findid
Paul Mackerras79b2c752006-04-02 10:47:402218 findcont
Paul Mackerras14c9dbd2005-07-17 01:53:552219 }
2220 incr fdiffpos
2221 }
2222 incr fdiffpos
2223
Paul Mackerras69d47bd2006-02-09 23:29:262224 if {![info exists treediffs($fdiffid)]} {
2225 set treediffs($fdiffid) $fdiffs
Paul Mackerras14c9dbd2005-07-17 01:53:552226 }
Paul Mackerras69d47bd2006-02-09 23:29:262227 if {[info exists findid] && $fdiffid eq $findid} {
2228 unset findid
Paul Mackerras79b2c752006-04-02 10:47:402229 findcont
Paul Mackerras14c9dbd2005-07-17 01:53:552230 }
2231 }
Paul Mackerrasb74fd572005-07-16 11:46:132232}
2233
Pavel Roskin37543542006-04-05 23:02:502234proc findcont {} {
Paul Mackerras79b2c752006-04-02 10:47:402235 global findid treediffs parentlist
Paul Mackerrasb74fd572005-07-16 11:46:132236 global ffileline findstartline finddidsel
Paul Mackerras8f7d0ce2006-02-28 11:10:192237 global displayorder numcommits matchinglines findinprogress
Paul Mackerrasb74fd572005-07-16 11:46:132238 global findmergefiles
2239
Paul Mackerrasb74fd572005-07-16 11:46:132240 set l $ffileline
Paul Mackerras79b2c752006-04-02 10:47:402241 while {1} {
2242 set id [lindex $displayorder $l]
2243 if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} {
Paul Mackerras69d47bd2006-02-09 23:29:262244 if {![info exists treediffs($id)]} {
2245 set findid $id
Paul Mackerrasb74fd572005-07-16 11:46:132246 set ffileline $l
Paul Mackerrasb74fd572005-07-16 11:46:132247 return
2248 }
2249 set doesmatch 0
Paul Mackerras69d47bd2006-02-09 23:29:262250 foreach f $treediffs($id) {
Paul Mackerrasb74fd572005-07-16 11:46:132251 set x [findmatches $f]
2252 if {$x != {}} {
2253 set doesmatch 1
2254 break
2255 }
2256 }
2257 if {$doesmatch} {
Paul Mackerras14c9dbd2005-07-17 01:53:552258 insertmatch $l $id
Paul Mackerrasb74fd572005-07-16 11:46:132259 }
Paul Mackerrasb74fd572005-07-16 11:46:132260 }
Paul Mackerras69d47bd2006-02-09 23:29:262261 if {[incr l] >= $numcommits} {
2262 set l 0
Paul Mackerrasb74fd572005-07-16 11:46:132263 }
Paul Mackerras69d47bd2006-02-09 23:29:262264 if {$l == $findstartline} break
Paul Mackerrasb74fd572005-07-16 11:46:132265 }
2266 stopfindproc
2267 if {!$finddidsel} {
2268 bell
2269 }
2270}
2271
2272# mark a commit as matching by putting a yellow background
2273# behind the headline
2274proc markheadline {l id} {
Paul Mackerras8ed16482006-03-02 11:56:442275 global canv mainfont linehtag
Paul Mackerrasb74fd572005-07-16 11:46:132276
Paul Mackerras9f1afe02006-02-19 11:44:472277 drawcmitrow $l
Paul Mackerrasb74fd572005-07-16 11:46:132278 set bbox [$canv bbox $linehtag($l)]
2279 set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
2280 $canv lower $t
2281}
2282
2283# mark the bits of a headline, author or date that match a find string
Paul Mackerras98f350e2005-05-15 05:56:512284proc markmatches {canv l str tag matches font} {
2285 set bbox [$canv bbox $tag]
2286 set x0 [lindex $bbox 0]
2287 set y0 [lindex $bbox 1]
2288 set y1 [lindex $bbox 3]
2289 foreach match $matches {
2290 set start [lindex $match 0]
2291 set end [lindex $match 1]
2292 if {$start > $end} continue
Jeff Hobbs2ed49d52005-11-23 01:39:532293 set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
2294 set xlen [font measure $font [string range $str 0 [expr {$end}]]]
2295 set t [$canv create rect [expr {$x0+$xoff}] $y0 \
2296 [expr {$x0+$xlen+2}] $y1 \
Paul Mackerras98f350e2005-05-15 05:56:512297 -outline {} -tags matches -fill yellow]
2298 $canv lower $t
2299 }
2300}
2301
2302proc unmarkmatches {} {
Paul Mackerrasb74fd572005-07-16 11:46:132303 global matchinglines findids
Paul Mackerras98f350e2005-05-15 05:56:512304 allcanvs delete matches
2305 catch {unset matchinglines}
Paul Mackerrasb74fd572005-07-16 11:46:132306 catch {unset findids}
Paul Mackerras98f350e2005-05-15 05:56:512307}
2308
Paul Mackerrasc8dfbcf2005-06-25 05:39:212309proc selcanvline {w x y} {
Paul Mackerrasfa4da7b2005-08-07 23:47:222310 global canv canvy0 ctext linespc
Paul Mackerras9f1afe02006-02-19 11:44:472311 global rowtextx
Paul Mackerras1db95b02005-05-09 04:08:392312 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerrascfb45632005-05-31 12:14:422313 if {$ymax == {}} return
Paul Mackerras1db95b02005-05-09 04:08:392314 set yfrac [lindex [$canv yview] 0]
2315 set y [expr {$y + $yfrac * $ymax}]
2316 set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
2317 if {$l < 0} {
2318 set l 0
2319 }
Paul Mackerrasc8dfbcf2005-06-25 05:39:212320 if {$w eq $canv} {
2321 if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return
2322 }
Paul Mackerras98f350e2005-05-15 05:56:512323 unmarkmatches
Paul Mackerrasd6982062005-08-06 12:06:062324 selectline $l 1
Paul Mackerras5ad588d2005-05-10 01:02:552325}
2326
Linus Torvaldsb1ba39e2005-08-09 03:04:202327proc commit_descriptor {p} {
2328 global commitinfo
2329 set l "..."
2330 if {[info exists commitinfo($p)]} {
2331 set l [lindex $commitinfo($p) 0]
2332 }
2333 return "$p ($l)"
2334}
2335
Paul Mackerras106288c2005-08-19 13:11:392336# append some text to the ctext widget, and make any SHA1 ID
2337# that we know about be a clickable link.
2338proc appendwithlinks {text} {
Paul Mackerras9f1afe02006-02-19 11:44:472339 global ctext commitrow linknum
Paul Mackerras106288c2005-08-19 13:11:392340
2341 set start [$ctext index "end - 1c"]
2342 $ctext insert end $text
2343 $ctext insert end "\n"
2344 set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
2345 foreach l $links {
2346 set s [lindex $l 0]
2347 set e [lindex $l 1]
2348 set linkid [string range $text $s $e]
Paul Mackerras9f1afe02006-02-19 11:44:472349 if {![info exists commitrow($linkid)]} continue
Paul Mackerras106288c2005-08-19 13:11:392350 incr e
2351 $ctext tag add link "$start + $s c" "$start + $e c"
2352 $ctext tag add link$linknum "$start + $s c" "$start + $e c"
Paul Mackerras9f1afe02006-02-19 11:44:472353 $ctext tag bind link$linknum <1> [list selectline $commitrow($linkid) 1]
Paul Mackerras106288c2005-08-19 13:11:392354 incr linknum
2355 }
2356 $ctext tag conf link -foreground blue -underline 1
2357 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
2358 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
2359}
2360
Rutger Nijlunsing6e5f7202006-04-05 00:24:032361proc viewnextline {dir} {
2362 global canv linespc
2363
2364 $canv delete hover
2365 set ymax [lindex [$canv cget -scrollregion] 3]
2366 set wnow [$canv yview]
2367 set wtop [expr {[lindex $wnow 0] * $ymax}]
2368 set newtop [expr {$wtop + $dir * $linespc}]
2369 if {$newtop < 0} {
2370 set newtop 0
2371 } elseif {$newtop > $ymax} {
2372 set newtop $ymax
2373 }
2374 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
2375}
2376
Paul Mackerrasd6982062005-08-06 12:06:062377proc selectline {l isnew} {
Paul Mackerrasd2610d12005-05-11 00:45:382378 global canv canv2 canv3 ctext commitinfo selectedline
Paul Mackerras8f7d0ce2006-02-28 11:10:192379 global displayorder linehtag linentag linedtag
Paul Mackerras79b2c752006-04-02 10:47:402380 global canvy0 linespc parentlist childlist
Paul Mackerras14c9dbd2005-07-17 01:53:552381 global cflist currentid sha1entry
Paul Mackerras9f1afe02006-02-19 11:44:472382 global commentend idtags linknum
Paul Mackerras8f7d0ce2006-02-28 11:10:192383 global mergemax numcommits
Paul Mackerrasd6982062005-08-06 12:06:062384
Paul Mackerras84ba7342005-06-17 00:12:262385 $canv delete hover
Paul Mackerras9843c302005-08-30 00:57:112386 normalline
Paul Mackerras8f7d0ce2006-02-28 11:10:192387 if {$l < 0 || $l >= $numcommits} return
Paul Mackerras5ad588d2005-05-10 01:02:552388 set y [expr {$canvy0 + $l * $linespc}]
Paul Mackerras17386062005-05-18 22:51:002389 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras58422152005-05-19 10:56:422390 set ytop [expr {$y - $linespc - 1}]
2391 set ybot [expr {$y + $linespc + 1}]
Paul Mackerras5ad588d2005-05-10 01:02:552392 set wnow [$canv yview]
Jeff Hobbs2ed49d52005-11-23 01:39:532393 set wtop [expr {[lindex $wnow 0] * $ymax}]
2394 set wbot [expr {[lindex $wnow 1] * $ymax}]
Paul Mackerras58422152005-05-19 10:56:422395 set wh [expr {$wbot - $wtop}]
2396 set newtop $wtop
Paul Mackerras17386062005-05-18 22:51:002397 if {$ytop < $wtop} {
Paul Mackerras58422152005-05-19 10:56:422398 if {$ybot < $wtop} {
2399 set newtop [expr {$y - $wh / 2.0}]
2400 } else {
2401 set newtop $ytop
2402 if {$newtop > $wtop - $linespc} {
2403 set newtop [expr {$wtop - $linespc}]
2404 }
Paul Mackerras17386062005-05-18 22:51:002405 }
Paul Mackerras58422152005-05-19 10:56:422406 } elseif {$ybot > $wbot} {
2407 if {$ytop > $wbot} {
2408 set newtop [expr {$y - $wh / 2.0}]
2409 } else {
2410 set newtop [expr {$ybot - $wh}]
2411 if {$newtop < $wtop + $linespc} {
2412 set newtop [expr {$wtop + $linespc}]
2413 }
Paul Mackerras17386062005-05-18 22:51:002414 }
Paul Mackerras58422152005-05-19 10:56:422415 }
2416 if {$newtop != $wtop} {
2417 if {$newtop < 0} {
2418 set newtop 0
2419 }
Jeff Hobbs2ed49d52005-11-23 01:39:532420 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
Paul Mackerras9f1afe02006-02-19 11:44:472421 drawvisible
Paul Mackerras5ad588d2005-05-10 01:02:552422 }
Paul Mackerrasd6982062005-08-06 12:06:062423
Paul Mackerras9f1afe02006-02-19 11:44:472424 if {![info exists linehtag($l)]} return
2425 $canv delete secsel
2426 set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
2427 -tags secsel -fill [$canv cget -selectbackground]]
2428 $canv lower $t
2429 $canv2 delete secsel
2430 set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
2431 -tags secsel -fill [$canv2 cget -selectbackground]]
2432 $canv2 lower $t
2433 $canv3 delete secsel
2434 set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
2435 -tags secsel -fill [$canv3 cget -selectbackground]]
2436 $canv3 lower $t
2437
Paul Mackerrasfa4da7b2005-08-07 23:47:222438 if {$isnew} {
2439 addtohistory [list selectline $l 0]
Paul Mackerrasd6982062005-08-06 12:06:062440 }
2441
Paul Mackerras5ad588d2005-05-10 01:02:552442 set selectedline $l
2443
Paul Mackerras8f7d0ce2006-02-28 11:10:192444 set id [lindex $displayorder $l]
Paul Mackerras887fe3c2005-05-21 07:35:372445 set currentid $id
Paul Mackerras98f350e2005-05-15 05:56:512446 $sha1entry delete 0 end
2447 $sha1entry insert 0 $id
2448 $sha1entry selection from 0
2449 $sha1entry selection to end
Paul Mackerras98f350e2005-05-15 05:56:512450
Paul Mackerras5ad588d2005-05-10 01:02:552451 $ctext conf -state normal
Paul Mackerras1db95b02005-05-09 04:08:392452 $ctext delete 0.0 end
Paul Mackerras106288c2005-08-19 13:11:392453 set linknum 0
Paul Mackerrasc8dfbcf2005-06-25 05:39:212454 $ctext mark set fmark.0 0.0
2455 $ctext mark gravity fmark.0 left
Paul Mackerras1db95b02005-05-09 04:08:392456 set info $commitinfo($id)
Paul Mackerras232475d2005-11-14 23:34:032457 set date [formatdate [lindex $info 2]]
2458 $ctext insert end "Author: [lindex $info 1] $date\n"
2459 set date [formatdate [lindex $info 4]]
2460 $ctext insert end "Committer: [lindex $info 3] $date\n"
Paul Mackerras887fe3c2005-05-21 07:35:372461 if {[info exists idtags($id)]} {
2462 $ctext insert end "Tags:"
2463 foreach tag $idtags($id) {
2464 $ctext insert end " $tag"
2465 }
2466 $ctext insert end "\n"
2467 }
Linus Torvalds8b192802005-08-07 20:58:562468
Linus Torvalds8b192802005-08-07 20:58:562469 set comment {}
Paul Mackerras79b2c752006-04-02 10:47:402470 set olds [lindex $parentlist $l]
2471 if {[llength $olds] > 1} {
Paul Mackerrasb77b0272006-02-06 22:13:522472 set np 0
Paul Mackerras79b2c752006-04-02 10:47:402473 foreach p $olds {
Paul Mackerrasb77b0272006-02-06 22:13:522474 if {$np >= $mergemax} {
2475 set tag mmax
2476 } else {
2477 set tag m$np
2478 }
2479 $ctext insert end "Parent: " $tag
2480 appendwithlinks [commit_descriptor $p]
2481 incr np
2482 }
2483 } else {
Paul Mackerras79b2c752006-04-02 10:47:402484 foreach p $olds {
2485 append comment "Parent: [commit_descriptor $p]\n"
Linus Torvalds8b192802005-08-07 20:58:562486 }
Linus Torvaldsb1ba39e2005-08-09 03:04:202487 }
Paul Mackerrasb77b0272006-02-06 22:13:522488
Paul Mackerras79b2c752006-04-02 10:47:402489 foreach c [lindex $childlist $l] {
2490 append comment "Child: [commit_descriptor $c]\n"
Linus Torvalds8b192802005-08-07 20:58:562491 }
2492 append comment "\n"
2493 append comment [lindex $info 5]
Paul Mackerrasd6982062005-08-06 12:06:062494
2495 # make anything that looks like a SHA1 ID be a clickable link
Paul Mackerras106288c2005-08-19 13:11:392496 appendwithlinks $comment
Paul Mackerrasd6982062005-08-06 12:06:062497
Paul Mackerrase5c2d852005-05-11 23:44:542498 $ctext tag delete Comments
Paul Mackerrasdf3d83b2005-05-17 23:23:072499 $ctext tag remove found 1.0 end
Paul Mackerras5ad588d2005-05-10 01:02:552500 $ctext conf -state disabled
Paul Mackerrasdf3d83b2005-05-17 23:23:072501 set commentend [$ctext index "end - 1c"]
Paul Mackerras5ad588d2005-05-10 01:02:552502
2503 $cflist delete 0 end
Paul Mackerrasc8dfbcf2005-06-25 05:39:212504 $cflist insert end "Comments"
Paul Mackerras79b2c752006-04-02 10:47:402505 if {[llength $olds] <= 1} {
Paul Mackerrasd3272442005-11-28 09:41:562506 startdiff $id
Paul Mackerras7b5ff7e2006-03-30 09:50:402507 } else {
Paul Mackerras79b2c752006-04-02 10:47:402508 mergediff $id $l
Paul Mackerrasc8dfbcf2005-06-25 05:39:212509 }
2510}
2511
Rutger Nijlunsing6e5f7202006-04-05 00:24:032512proc selfirstline {} {
2513 unmarkmatches
2514 selectline 0 1
2515}
2516
2517proc sellastline {} {
2518 global numcommits
2519 unmarkmatches
2520 set l [expr {$numcommits - 1}]
2521 selectline $l 1
2522}
2523
Paul Mackerrase5c2d852005-05-11 23:44:542524proc selnextline {dir} {
2525 global selectedline
2526 if {![info exists selectedline]} return
Jeff Hobbs2ed49d52005-11-23 01:39:532527 set l [expr {$selectedline + $dir}]
Paul Mackerras98f350e2005-05-15 05:56:512528 unmarkmatches
Paul Mackerrasd6982062005-08-06 12:06:062529 selectline $l 1
2530}
2531
Rutger Nijlunsing6e5f7202006-04-05 00:24:032532proc selnextpage {dir} {
2533 global canv linespc selectedline numcommits
2534
2535 set lpp [expr {([winfo height $canv] - 2) / $linespc}]
2536 if {$lpp < 1} {
2537 set lpp 1
2538 }
2539 allcanvs yview scroll [expr {$dir * $lpp}] units
2540 if {![info exists selectedline]} return
2541 set l [expr {$selectedline + $dir * $lpp}]
2542 if {$l < 0} {
2543 set l 0
2544 } elseif {$l >= $numcommits} {
2545 set l [expr $numcommits - 1]
2546 }
2547 unmarkmatches
2548 selectline $l 1
2549}
2550
Paul Mackerrasfa4da7b2005-08-07 23:47:222551proc unselectline {} {
2552 global selectedline
2553
2554 catch {unset selectedline}
2555 allcanvs delete secsel
2556}
2557
2558proc addtohistory {cmd} {
2559 global history historyindex
2560
2561 if {$historyindex > 0
2562 && [lindex $history [expr {$historyindex - 1}]] == $cmd} {
2563 return
2564 }
2565
2566 if {$historyindex < [llength $history]} {
2567 set history [lreplace $history $historyindex end $cmd]
2568 } else {
2569 lappend history $cmd
2570 }
2571 incr historyindex
2572 if {$historyindex > 1} {
2573 .ctop.top.bar.leftbut conf -state normal
2574 } else {
2575 .ctop.top.bar.leftbut conf -state disabled
2576 }
2577 .ctop.top.bar.rightbut conf -state disabled
2578}
2579
Paul Mackerrasd6982062005-08-06 12:06:062580proc goback {} {
2581 global history historyindex
2582
2583 if {$historyindex > 1} {
2584 incr historyindex -1
Paul Mackerrasfa4da7b2005-08-07 23:47:222585 set cmd [lindex $history [expr {$historyindex - 1}]]
2586 eval $cmd
Paul Mackerrasd6982062005-08-06 12:06:062587 .ctop.top.bar.rightbut conf -state normal
2588 }
2589 if {$historyindex <= 1} {
2590 .ctop.top.bar.leftbut conf -state disabled
2591 }
2592}
2593
2594proc goforw {} {
2595 global history historyindex
2596
2597 if {$historyindex < [llength $history]} {
Paul Mackerrasfa4da7b2005-08-07 23:47:222598 set cmd [lindex $history $historyindex]
Paul Mackerrasd6982062005-08-06 12:06:062599 incr historyindex
Paul Mackerrasfa4da7b2005-08-07 23:47:222600 eval $cmd
Paul Mackerrasd6982062005-08-06 12:06:062601 .ctop.top.bar.leftbut conf -state normal
2602 }
2603 if {$historyindex >= [llength $history]} {
2604 .ctop.top.bar.rightbut conf -state disabled
2605 }
Paul Mackerras5ad588d2005-05-10 01:02:552606}
2607
Paul Mackerras79b2c752006-04-02 10:47:402608proc mergediff {id l} {
2609 global diffmergeid diffopts mdifffd
Paul Mackerras7a1d9d12006-03-21 23:21:452610 global difffilestart diffids
Paul Mackerras79b2c752006-04-02 10:47:402611 global parentlist
Paul Mackerrase2ed4322005-07-17 07:39:442612
Paul Mackerras3c461ff2005-07-20 13:13:462613 set diffmergeid $id
Paul Mackerras7a1d9d12006-03-21 23:21:452614 set diffids $id
Paul Mackerrasb77b0272006-02-06 22:13:522615 catch {unset difffilestart}
2616 # this doesn't seem to actually affect anything...
Paul Mackerras9d2a52e2005-07-28 03:15:472617 set env(GIT_DIFF_OPTS) $diffopts
Paul Mackerrasb77b0272006-02-06 22:13:522618 set cmd [concat | git-diff-tree --no-commit-id --cc $id]
2619 if {[catch {set mdf [open $cmd r]} err]} {
2620 error_popup "Error getting merge diffs: $err"
2621 return
Paul Mackerras9d2a52e2005-07-28 03:15:472622 }
Paul Mackerrasb77b0272006-02-06 22:13:522623 fconfigure $mdf -blocking 0
2624 set mdifffd($id) $mdf
Paul Mackerras79b2c752006-04-02 10:47:402625 set np [llength [lindex $parentlist $l]]
2626 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasb77b0272006-02-06 22:13:522627 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerras9d2a52e2005-07-28 03:15:472628}
2629
Paul Mackerras79b2c752006-04-02 10:47:402630proc getmergediffline {mdf id np} {
2631 global diffmergeid ctext cflist nextupdate mergemax
Paul Mackerras7a1d9d12006-03-21 23:21:452632 global difffilestart mdifffd
Paul Mackerras9d2a52e2005-07-28 03:15:472633
Paul Mackerrasb77b0272006-02-06 22:13:522634 set n [gets $mdf line]
Paul Mackerras9d2a52e2005-07-28 03:15:472635 if {$n < 0} {
Paul Mackerrasb77b0272006-02-06 22:13:522636 if {[eof $mdf]} {
2637 close $mdf
Paul Mackerras9d2a52e2005-07-28 03:15:472638 }
2639 return
2640 }
Paul Mackerras7a1d9d12006-03-21 23:21:452641 if {![info exists diffmergeid] || $id != $diffmergeid
2642 || $mdf != $mdifffd($id)} {
Paul Mackerrasb77b0272006-02-06 22:13:522643 return
Paul Mackerras9d2a52e2005-07-28 03:15:472644 }
Paul Mackerras9d2a52e2005-07-28 03:15:472645 $ctext conf -state normal
Paul Mackerrasb77b0272006-02-06 22:13:522646 if {[regexp {^diff --cc (.*)} $line match fname]} {
2647 # start of a new file
Paul Mackerras9d2a52e2005-07-28 03:15:472648 $ctext insert end "\n"
2649 set here [$ctext index "end - 1c"]
Paul Mackerrasb77b0272006-02-06 22:13:522650 set i [$cflist index end]
2651 $ctext mark set fmark.$i $here
2652 $ctext mark gravity fmark.$i left
2653 set difffilestart([expr {$i-1}]) $here
2654 $cflist insert end $fname
2655 set l [expr {(78 - [string length $fname]) / 2}]
Paul Mackerras9d2a52e2005-07-28 03:15:472656 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerrasb77b0272006-02-06 22:13:522657 $ctext insert end "$pad $fname $pad\n" filesep
2658 } elseif {[regexp {^@@} $line]} {
2659 $ctext insert end "$line\n" hunksep
2660 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
2661 # do nothing
2662 } else {
2663 # parse the prefix - one ' ', '-' or '+' for each parent
Paul Mackerrasb77b0272006-02-06 22:13:522664 set spaces {}
2665 set minuses {}
2666 set pluses {}
2667 set isbad 0
2668 for {set j 0} {$j < $np} {incr j} {
2669 set c [string range $line $j $j]
2670 if {$c == " "} {
2671 lappend spaces $j
2672 } elseif {$c == "-"} {
2673 lappend minuses $j
2674 } elseif {$c == "+"} {
2675 lappend pluses $j
Paul Mackerras9d2a52e2005-07-28 03:15:472676 } else {
Paul Mackerrasb77b0272006-02-06 22:13:522677 set isbad 1
2678 break
Paul Mackerras9d2a52e2005-07-28 03:15:472679 }
2680 }
Paul Mackerrasb77b0272006-02-06 22:13:522681 set tags {}
2682 set num {}
2683 if {!$isbad && $minuses ne {} && $pluses eq {}} {
2684 # line doesn't appear in result, parents in $minuses have the line
2685 set num [lindex $minuses 0]
2686 } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
2687 # line appears in result, parents in $pluses don't have the line
2688 lappend tags mresult
2689 set num [lindex $spaces 0]
Paul Mackerras9d2a52e2005-07-28 03:15:472690 }
Paul Mackerrasb77b0272006-02-06 22:13:522691 if {$num ne {}} {
2692 if {$num >= $mergemax} {
2693 set num "max"
Paul Mackerras9d2a52e2005-07-28 03:15:472694 }
Paul Mackerrasb77b0272006-02-06 22:13:522695 lappend tags m$num
Paul Mackerras9d2a52e2005-07-28 03:15:472696 }
Paul Mackerrasb77b0272006-02-06 22:13:522697 $ctext insert end "$line\n" $tags
Paul Mackerras9d2a52e2005-07-28 03:15:472698 }
2699 $ctext conf -state disabled
Paul Mackerrasb77b0272006-02-06 22:13:522700 if {[clock clicks -milliseconds] >= $nextupdate} {
2701 incr nextupdate 100
2702 fileevent $mdf readable {}
2703 update
Paul Mackerrasc5a4c4d2006-04-06 00:20:032704 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasc8a4acb2005-07-29 14:23:032705 }
Paul Mackerrasc8a4acb2005-07-29 14:23:032706}
2707
Paul Mackerras3c461ff2005-07-20 13:13:462708proc startdiff {ids} {
2709 global treediffs diffids treepending diffmergeid
2710
2711 set diffids $ids
2712 catch {unset diffmergeid}
2713 if {![info exists treediffs($ids)]} {
2714 if {![info exists treepending]} {
2715 gettreediffs $ids
2716 }
2717 } else {
2718 addtocflist $ids
2719 }
2720}
2721
2722proc addtocflist {ids} {
2723 global treediffs cflist
Paul Mackerrasc8dfbcf2005-06-25 05:39:212724 foreach f $treediffs($ids) {
Paul Mackerrasd2610d12005-05-11 00:45:382725 $cflist insert end $f
2726 }
Paul Mackerrasc8dfbcf2005-06-25 05:39:212727 getblobdiffs $ids
Paul Mackerrasd2610d12005-05-11 00:45:382728}
2729
Paul Mackerrasc8dfbcf2005-06-25 05:39:212730proc gettreediffs {ids} {
Paul Mackerras79b2c752006-04-02 10:47:402731 global treediff treepending
Paul Mackerrasc8dfbcf2005-06-25 05:39:212732 set treepending $ids
Paul Mackerras3c461ff2005-07-20 13:13:462733 set treediff {}
Paul Mackerras418c4c72006-02-06 22:10:182734 if {[catch \
2735 {set gdtf [open [concat | git-diff-tree --no-commit-id -r $ids] r]} \
2736 ]} return
Paul Mackerrasd2610d12005-05-11 00:45:382737 fconfigure $gdtf -blocking 0
Paul Mackerras3c461ff2005-07-20 13:13:462738 fileevent $gdtf readable [list gettreediffline $gdtf $ids]
Paul Mackerrasd2610d12005-05-11 00:45:382739}
2740
Paul Mackerrasc8dfbcf2005-06-25 05:39:212741proc gettreediffline {gdtf ids} {
Paul Mackerras3c461ff2005-07-20 13:13:462742 global treediff treediffs treepending diffids diffmergeid
2743
Paul Mackerrasd2610d12005-05-11 00:45:382744 set n [gets $gdtf line]
2745 if {$n < 0} {
2746 if {![eof $gdtf]} return
2747 close $gdtf
Paul Mackerras3c461ff2005-07-20 13:13:462748 set treediffs($ids) $treediff
Paul Mackerrasd2610d12005-05-11 00:45:382749 unset treepending
Paul Mackerras3c461ff2005-07-20 13:13:462750 if {$ids != $diffids} {
Paul Mackerras7a1d9d12006-03-21 23:21:452751 if {![info exists diffmergeid]} {
2752 gettreediffs $diffids
Paul Mackerrasb74fd572005-07-16 11:46:132753 }
Paul Mackerras7a1d9d12006-03-21 23:21:452754 } else {
2755 addtocflist $ids
Paul Mackerrasb74fd572005-07-16 11:46:132756 }
Paul Mackerrasd2610d12005-05-11 00:45:382757 return
2758 }
Paul Mackerrasd4e95cb2005-06-01 00:02:132759 set file [lindex $line 5]
Paul Mackerras3c461ff2005-07-20 13:13:462760 lappend treediff $file
Paul Mackerrasd2610d12005-05-11 00:45:382761}
2762
Paul Mackerrasc8dfbcf2005-06-25 05:39:212763proc getblobdiffs {ids} {
Paul Mackerras3c461ff2005-07-20 13:13:462764 global diffopts blobdifffd diffids env curdifftag curtagstart
Paul Mackerras7eab2932005-07-20 16:25:542765 global difffilestart nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 05:39:212766
Paul Mackerrase5c2d852005-05-11 23:44:542767 set env(GIT_DIFF_OPTS) $diffopts
Paul Mackerrasd3272442005-11-28 09:41:562768 set cmd [concat | git-diff-tree --no-commit-id -r -p -C $ids]
Paul Mackerras3c461ff2005-07-20 13:13:462769 if {[catch {set bdf [open $cmd r]} err]} {
Paul Mackerrase5c2d852005-05-11 23:44:542770 puts "error getting diffs: $err"
2771 return
2772 }
Paul Mackerras4f2c2642005-07-17 15:11:442773 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:542774 fconfigure $bdf -blocking 0
Paul Mackerrasc8dfbcf2005-06-25 05:39:212775 set blobdifffd($ids) $bdf
Paul Mackerras3c461ff2005-07-20 13:13:462776 set curdifftag Comments
2777 set curtagstart 0.0
Paul Mackerras3c461ff2005-07-20 13:13:462778 catch {unset difffilestart}
2779 fileevent $bdf readable [list getblobdiffline $bdf $diffids]
Paul Mackerrasc8dfbcf2005-06-25 05:39:212780 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerrase5c2d852005-05-11 23:44:542781}
2782
Paul Mackerrasc8dfbcf2005-06-25 05:39:212783proc getblobdiffline {bdf ids} {
Paul Mackerras4f2c2642005-07-17 15:11:442784 global diffids blobdifffd ctext curdifftag curtagstart
Paul Mackerras7eab2932005-07-20 16:25:542785 global diffnexthead diffnextnote difffilestart
2786 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 05:39:212787
Paul Mackerrase5c2d852005-05-11 23:44:542788 set n [gets $bdf line]
2789 if {$n < 0} {
2790 if {[eof $bdf]} {
2791 close $bdf
Paul Mackerrase2ed4322005-07-17 07:39:442792 if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:542793 $ctext tag add $curdifftag $curtagstart end
2794 }
2795 }
2796 return
2797 }
Paul Mackerrase2ed4322005-07-17 07:39:442798 if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:542799 return
2800 }
2801 $ctext conf -state normal
Paul Mackerras7eab2932005-07-20 16:25:542802 if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} {
Paul Mackerrase5c2d852005-05-11 23:44:542803 # start of a new file
2804 $ctext insert end "\n"
2805 $ctext tag add $curdifftag $curtagstart end
2806 set curtagstart [$ctext index "end - 1c"]
Paul Mackerras7eab2932005-07-20 16:25:542807 set header $newname
Paul Mackerrasc8dfbcf2005-06-25 05:39:212808 set here [$ctext index "end - 1c"]
Paul Mackerras7eab2932005-07-20 16:25:542809 set i [lsearch -exact $treediffs($diffids) $fname]
2810 if {$i >= 0} {
2811 set difffilestart($i) $here
2812 incr i
2813 $ctext mark set fmark.$i $here
2814 $ctext mark gravity fmark.$i left
2815 }
2816 if {$newname != $fname} {
2817 set i [lsearch -exact $treediffs($diffids) $newname]
2818 if {$i >= 0} {
2819 set difffilestart($i) $here
2820 incr i
2821 $ctext mark set fmark.$i $here
2822 $ctext mark gravity fmark.$i left
2823 }
2824 }
Paul Mackerrase5c2d852005-05-11 23:44:542825 set curdifftag "f:$fname"
2826 $ctext tag delete $curdifftag
Paul Mackerras58422152005-05-19 10:56:422827 set l [expr {(78 - [string length $header]) / 2}]
Paul Mackerrase5c2d852005-05-11 23:44:542828 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerras58422152005-05-19 10:56:422829 $ctext insert end "$pad $header $pad\n" filesep
Paul Mackerras4f2c2642005-07-17 15:11:442830 set diffinhdr 1
Paul Mackerrasb06bc2a2006-03-07 22:15:322831 } elseif {$diffinhdr && [string compare -length 3 $line "---"] == 0} {
2832 # do nothing
2833 } elseif {$diffinhdr && [string compare -length 3 $line "+++"] == 0} {
Paul Mackerras4f2c2642005-07-17 15:11:442834 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:542835 } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
2836 $line match f1l f1c f2l f2c rest]} {
Paul Mackerras712fcc02005-11-29 22:28:162837 $ctext insert end "$line\n" hunksep
Paul Mackerras4f2c2642005-07-17 15:11:442838 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:542839 } else {
2840 set x [string range $line 0 0]
2841 if {$x == "-" || $x == "+"} {
2842 set tag [expr {$x == "+"}]
Paul Mackerrase5c2d852005-05-11 23:44:542843 $ctext insert end "$line\n" d$tag
2844 } elseif {$x == " "} {
Paul Mackerrase5c2d852005-05-11 23:44:542845 $ctext insert end "$line\n"
Paul Mackerras4f2c2642005-07-17 15:11:442846 } elseif {$diffinhdr || $x == "\\"} {
Paul Mackerras58422152005-05-19 10:56:422847 # e.g. "\ No newline at end of file"
2848 $ctext insert end "$line\n" filesep
Paul Mackerrase5c2d852005-05-11 23:44:542849 } else {
2850 # Something else we don't recognize
2851 if {$curdifftag != "Comments"} {
2852 $ctext insert end "\n"
2853 $ctext tag add $curdifftag $curtagstart end
2854 set curtagstart [$ctext index "end - 1c"]
2855 set curdifftag Comments
2856 }
2857 $ctext insert end "$line\n" filesep
2858 }
2859 }
2860 $ctext conf -state disabled
Paul Mackerrasc8dfbcf2005-06-25 05:39:212861 if {[clock clicks -milliseconds] >= $nextupdate} {
2862 incr nextupdate 100
2863 fileevent $bdf readable {}
2864 update
2865 fileevent $bdf readable "getblobdiffline $bdf {$ids}"
2866 }
Paul Mackerrase5c2d852005-05-11 23:44:542867}
2868
Paul Mackerras39ad8572005-05-19 12:35:532869proc nextfile {} {
2870 global difffilestart ctext
2871 set here [$ctext index @0,0]
2872 for {set i 0} {[info exists difffilestart($i)]} {incr i} {
2873 if {[$ctext compare $difffilestart($i) > $here]} {
Paul Mackerras7eab2932005-07-20 16:25:542874 if {![info exists pos]
2875 || [$ctext compare $difffilestart($i) < $pos]} {
2876 set pos $difffilestart($i)
2877 }
Paul Mackerras39ad8572005-05-19 12:35:532878 }
2879 }
Paul Mackerras7eab2932005-07-20 16:25:542880 if {[info exists pos]} {
2881 $ctext yview $pos
2882 }
Paul Mackerras39ad8572005-05-19 12:35:532883}
2884
Paul Mackerrase5c2d852005-05-11 23:44:542885proc listboxsel {} {
Paul Mackerras7eab2932005-07-20 16:25:542886 global ctext cflist currentid
Paul Mackerras9a40c502005-05-12 23:46:162887 if {![info exists currentid]} return
Paul Mackerrasc8dfbcf2005-06-25 05:39:212888 set sel [lsort [$cflist curselection]]
2889 if {$sel eq {}} return
2890 set first [lindex $sel 0]
2891 catch {$ctext yview fmark.$first}
Paul Mackerras1db95b02005-05-09 04:08:392892}
2893
Paul Mackerras1d10f362005-05-15 12:55:472894proc setcoords {} {
2895 global linespc charspc canvx0 canvy0 mainfont
Paul Mackerrasf6075eb2005-08-17 23:30:102896 global xspc1 xspc2 lthickness
Paul Mackerras8d858d12005-08-04 23:52:162897
Paul Mackerras1d10f362005-05-15 12:55:472898 set linespc [font metrics $mainfont -linespace]
2899 set charspc [font measure $mainfont "m"]
Paul Mackerras9f1afe02006-02-19 11:44:472900 set canvy0 [expr {int(3 + 0.5 * $linespc)}]
2901 set canvx0 [expr {int(3 + 0.5 * $linespc)}]
Paul Mackerrasf6075eb2005-08-17 23:30:102902 set lthickness [expr {int($linespc / 9) + 1}]
Paul Mackerras8d858d12005-08-04 23:52:162903 set xspc1(0) $linespc
2904 set xspc2 $linespc
Paul Mackerras9a40c502005-05-12 23:46:162905}
Paul Mackerras1db95b02005-05-09 04:08:392906
Paul Mackerras1d10f362005-05-15 12:55:472907proc redisplay {} {
Paul Mackerrasbe0cd092006-03-30 22:55:112908 global canv
Paul Mackerras9f1afe02006-02-19 11:44:472909 global selectedline
2910
2911 set ymax [lindex [$canv cget -scrollregion] 3]
2912 if {$ymax eq {} || $ymax == 0} return
2913 set span [$canv yview]
2914 clear_display
Paul Mackerrasbe0cd092006-03-30 22:55:112915 setcanvscroll
Paul Mackerras9f1afe02006-02-19 11:44:472916 allcanvs yview moveto [lindex $span 0]
2917 drawvisible
2918 if {[info exists selectedline]} {
2919 selectline $selectedline 0
Paul Mackerras1db95b02005-05-09 04:08:392920 }
2921}
Paul Mackerras1d10f362005-05-15 12:55:472922
2923proc incrfont {inc} {
Paul Mackerrasfa4da7b2005-08-07 23:47:222924 global mainfont namefont textfont ctext canv phase
Paul Mackerrascfb45632005-05-31 12:14:422925 global stopped entries
Paul Mackerras1d10f362005-05-15 12:55:472926 unmarkmatches
2927 set mainfont [lreplace $mainfont 1 1 [expr {[lindex $mainfont 1] + $inc}]]
2928 set namefont [lreplace $namefont 1 1 [expr {[lindex $namefont 1] + $inc}]]
2929 set textfont [lreplace $textfont 1 1 [expr {[lindex $textfont 1] + $inc}]]
2930 setcoords
2931 $ctext conf -font $textfont
2932 $ctext tag conf filesep -font [concat $textfont bold]
Paul Mackerras887fe3c2005-05-21 07:35:372933 foreach e $entries {
2934 $e conf -font $mainfont
2935 }
Paul Mackerras1d10f362005-05-15 12:55:472936 if {$phase == "getcommits"} {
2937 $canv itemconf textitems -font $mainfont
2938 }
2939 redisplay
Paul Mackerras1db95b02005-05-09 04:08:392940}
Paul Mackerras1d10f362005-05-15 12:55:472941
Paul Mackerrasee3dc722005-06-25 06:37:132942proc clearsha1 {} {
2943 global sha1entry sha1string
2944 if {[string length $sha1string] == 40} {
2945 $sha1entry delete 0 end
2946 }
2947}
2948
Paul Mackerras887fe3c2005-05-21 07:35:372949proc sha1change {n1 n2 op} {
2950 global sha1string currentid sha1but
2951 if {$sha1string == {}
2952 || ([info exists currentid] && $sha1string == $currentid)} {
2953 set state disabled
2954 } else {
2955 set state normal
2956 }
2957 if {[$sha1but cget -state] == $state} return
2958 if {$state == "normal"} {
2959 $sha1but conf -state normal -relief raised -text "Goto: "
2960 } else {
2961 $sha1but conf -state disabled -relief flat -text "SHA1 ID: "
2962 }
2963}
2964
2965proc gotocommit {} {
Stephen Rothwelle1007122006-03-30 05:13:122966 global sha1string currentid commitrow tagids headids
Paul Mackerras8f7d0ce2006-02-28 11:10:192967 global displayorder numcommits
Paul Mackerrasf3b8b3c2005-07-18 16:16:352968
Paul Mackerras887fe3c2005-05-21 07:35:372969 if {$sha1string == {}
2970 || ([info exists currentid] && $sha1string == $currentid)} return
2971 if {[info exists tagids($sha1string)]} {
2972 set id $tagids($sha1string)
Stephen Rothwelle1007122006-03-30 05:13:122973 } elseif {[info exists headids($sha1string)]} {
2974 set id $headids($sha1string)
Paul Mackerras887fe3c2005-05-21 07:35:372975 } else {
2976 set id [string tolower $sha1string]
Paul Mackerrasf3b8b3c2005-07-18 16:16:352977 if {[regexp {^[0-9a-f]{4,39}$} $id]} {
2978 set matches {}
Paul Mackerras8ed16482006-03-02 11:56:442979 foreach i $displayorder {
2980 if {[string match $id* $i]} {
2981 lappend matches $i
Paul Mackerrasf3b8b3c2005-07-18 16:16:352982 }
2983 }
2984 if {$matches ne {}} {
2985 if {[llength $matches] > 1} {
2986 error_popup "Short SHA1 id $id is ambiguous"
2987 return
2988 }
2989 set id [lindex $matches 0]
2990 }
2991 }
Paul Mackerras887fe3c2005-05-21 07:35:372992 }
Paul Mackerras9f1afe02006-02-19 11:44:472993 if {[info exists commitrow($id)]} {
2994 selectline $commitrow($id) 1
Paul Mackerras887fe3c2005-05-21 07:35:372995 return
2996 }
Paul Mackerrasf3b8b3c2005-07-18 16:16:352997 if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
Paul Mackerras887fe3c2005-05-21 07:35:372998 set type "SHA1 id"
2999 } else {
Stephen Rothwelle1007122006-03-30 05:13:123000 set type "Tag/Head"
Paul Mackerras887fe3c2005-05-21 07:35:373001 }
3002 error_popup "$type $sha1string is not known"
3003}
3004
Paul Mackerras84ba7342005-06-17 00:12:263005proc lineenter {x y id} {
3006 global hoverx hovery hoverid hovertimer
3007 global commitinfo canv
3008
Paul Mackerras8ed16482006-03-02 11:56:443009 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerras84ba7342005-06-17 00:12:263010 set hoverx $x
3011 set hovery $y
3012 set hoverid $id
3013 if {[info exists hovertimer]} {
3014 after cancel $hovertimer
3015 }
3016 set hovertimer [after 500 linehover]
3017 $canv delete hover
3018}
3019
3020proc linemotion {x y id} {
3021 global hoverx hovery hoverid hovertimer
3022
3023 if {[info exists hoverid] && $id == $hoverid} {
3024 set hoverx $x
3025 set hovery $y
3026 if {[info exists hovertimer]} {
3027 after cancel $hovertimer
3028 }
3029 set hovertimer [after 500 linehover]
3030 }
3031}
3032
3033proc lineleave {id} {
3034 global hoverid hovertimer canv
3035
3036 if {[info exists hoverid] && $id == $hoverid} {
3037 $canv delete hover
3038 if {[info exists hovertimer]} {
3039 after cancel $hovertimer
3040 unset hovertimer
3041 }
3042 unset hoverid
3043 }
3044}
3045
3046proc linehover {} {
3047 global hoverx hovery hoverid hovertimer
3048 global canv linespc lthickness
3049 global commitinfo mainfont
3050
3051 set text [lindex $commitinfo($hoverid) 0]
3052 set ymax [lindex [$canv cget -scrollregion] 3]
3053 if {$ymax == {}} return
3054 set yfrac [lindex [$canv yview] 0]
3055 set x [expr {$hoverx + 2 * $linespc}]
3056 set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
3057 set x0 [expr {$x - 2 * $lthickness}]
3058 set y0 [expr {$y - 2 * $lthickness}]
3059 set x1 [expr {$x + [font measure $mainfont $text] + 2 * $lthickness}]
3060 set y1 [expr {$y + $linespc + 2 * $lthickness}]
3061 set t [$canv create rectangle $x0 $y0 $x1 $y1 \
3062 -fill \#ffff80 -outline black -width 1 -tags hover]
3063 $canv raise $t
Frank Sorensone2464832005-10-30 09:06:463064 set t [$canv create text $x $y -anchor nw -text $text -tags hover -font $mainfont]
Paul Mackerras84ba7342005-06-17 00:12:263065 $canv raise $t
3066}
3067
Paul Mackerras9843c302005-08-30 00:57:113068proc clickisonarrow {id y} {
Paul Mackerrasf6342482006-02-27 23:02:033069 global lthickness idrowranges
Paul Mackerras9843c302005-08-30 00:57:113070
3071 set thresh [expr {2 * $lthickness + 6}]
Paul Mackerrasf6342482006-02-27 23:02:033072 set n [expr {[llength $idrowranges($id)] - 1}]
3073 for {set i 1} {$i < $n} {incr i} {
3074 set row [lindex $idrowranges($id) $i]
3075 if {abs([yc $row] - $y) < $thresh} {
3076 return $i
Paul Mackerras9843c302005-08-30 00:57:113077 }
3078 }
3079 return {}
3080}
3081
Paul Mackerrasf6342482006-02-27 23:02:033082proc arrowjump {id n y} {
3083 global idrowranges canv
Paul Mackerras9843c302005-08-30 00:57:113084
Paul Mackerrasf6342482006-02-27 23:02:033085 # 1 <-> 2, 3 <-> 4, etc...
3086 set n [expr {(($n - 1) ^ 1) + 1}]
3087 set row [lindex $idrowranges($id) $n]
3088 set yt [yc $row]
Paul Mackerras9843c302005-08-30 00:57:113089 set ymax [lindex [$canv cget -scrollregion] 3]
3090 if {$ymax eq {} || $ymax <= 0} return
3091 set view [$canv yview]
3092 set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
3093 set yfrac [expr {$yt / $ymax - $yspan / 2}]
3094 if {$yfrac < 0} {
3095 set yfrac 0
3096 }
Paul Mackerrasf6342482006-02-27 23:02:033097 allcanvs yview moveto $yfrac
Paul Mackerras9843c302005-08-30 00:57:113098}
3099
Paul Mackerrasfa4da7b2005-08-07 23:47:223100proc lineclick {x y id isnew} {
Paul Mackerras79b2c752006-04-02 10:47:403101 global ctext commitinfo childlist commitrow cflist canv thickerline
Paul Mackerrasc8dfbcf2005-06-25 05:39:213102
Paul Mackerras8ed16482006-03-02 11:56:443103 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerrasc8dfbcf2005-06-25 05:39:213104 unmarkmatches
Paul Mackerrasfa4da7b2005-08-07 23:47:223105 unselectline
Paul Mackerras9843c302005-08-30 00:57:113106 normalline
Paul Mackerrasc8dfbcf2005-06-25 05:39:213107 $canv delete hover
Paul Mackerras9843c302005-08-30 00:57:113108 # draw this line thicker than normal
Paul Mackerras9843c302005-08-30 00:57:113109 set thickerline $id
Paul Mackerrasc934a8a2006-03-02 12:00:443110 drawlines $id
Paul Mackerras9843c302005-08-30 00:57:113111 if {$isnew} {
3112 set ymax [lindex [$canv cget -scrollregion] 3]
3113 if {$ymax eq {}} return
3114 set yfrac [lindex [$canv yview] 0]
3115 set y [expr {$y + $yfrac * $ymax}]
3116 }
3117 set dirn [clickisonarrow $id $y]
3118 if {$dirn ne {}} {
3119 arrowjump $id $dirn $y
3120 return
3121 }
3122
3123 if {$isnew} {
3124 addtohistory [list lineclick $x $y $id 0]
3125 }
Paul Mackerrasc8dfbcf2005-06-25 05:39:213126 # fill the details pane with info about this line
3127 $ctext conf -state normal
3128 $ctext delete 0.0 end
Paul Mackerrasfa4da7b2005-08-07 23:47:223129 $ctext tag conf link -foreground blue -underline 1
3130 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
3131 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
3132 $ctext insert end "Parent:\t"
3133 $ctext insert end $id [list link link0]
3134 $ctext tag bind link0 <1> [list selbyid $id]
Paul Mackerrasc8dfbcf2005-06-25 05:39:213135 set info $commitinfo($id)
Paul Mackerrasfa4da7b2005-08-07 23:47:223136 $ctext insert end "\n\t[lindex $info 0]\n"
Paul Mackerrasc8dfbcf2005-06-25 05:39:213137 $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
Paul Mackerras232475d2005-11-14 23:34:033138 set date [formatdate [lindex $info 2]]
3139 $ctext insert end "\tDate:\t$date\n"
Paul Mackerras79b2c752006-04-02 10:47:403140 set kids [lindex $childlist $commitrow($id)]
3141 if {$kids ne {}} {
Paul Mackerrasc8dfbcf2005-06-25 05:39:213142 $ctext insert end "\nChildren:"
Paul Mackerrasfa4da7b2005-08-07 23:47:223143 set i 0
Paul Mackerras79b2c752006-04-02 10:47:403144 foreach child $kids {
Paul Mackerrasfa4da7b2005-08-07 23:47:223145 incr i
Paul Mackerras8ed16482006-03-02 11:56:443146 if {![info exists commitinfo($child)] && ![getcommit $child]} continue
Paul Mackerrasc8dfbcf2005-06-25 05:39:213147 set info $commitinfo($child)
Paul Mackerrasfa4da7b2005-08-07 23:47:223148 $ctext insert end "\n\t"
3149 $ctext insert end $child [list link link$i]
3150 $ctext tag bind link$i <1> [list selbyid $child]
3151 $ctext insert end "\n\t[lindex $info 0]"
3152 $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
Paul Mackerras232475d2005-11-14 23:34:033153 set date [formatdate [lindex $info 2]]
3154 $ctext insert end "\n\tDate:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 05:39:213155 }
3156 }
3157 $ctext conf -state disabled
3158
3159 $cflist delete 0 end
3160}
3161
Paul Mackerras9843c302005-08-30 00:57:113162proc normalline {} {
3163 global thickerline
3164 if {[info exists thickerline]} {
Paul Mackerrasc934a8a2006-03-02 12:00:443165 set id $thickerline
Paul Mackerras9843c302005-08-30 00:57:113166 unset thickerline
Paul Mackerrasc934a8a2006-03-02 12:00:443167 drawlines $id
Paul Mackerras9843c302005-08-30 00:57:113168 }
3169}
3170
Paul Mackerrasc8dfbcf2005-06-25 05:39:213171proc selbyid {id} {
Paul Mackerras9f1afe02006-02-19 11:44:473172 global commitrow
3173 if {[info exists commitrow($id)]} {
3174 selectline $commitrow($id) 1
Paul Mackerrasc8dfbcf2005-06-25 05:39:213175 }
3176}
3177
3178proc mstime {} {
3179 global startmstime
3180 if {![info exists startmstime]} {
3181 set startmstime [clock clicks -milliseconds]
3182 }
3183 return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
3184}
3185
3186proc rowmenu {x y id} {
Paul Mackerras9f1afe02006-02-19 11:44:473187 global rowctxmenu commitrow selectedline rowmenuid
Paul Mackerrasc8dfbcf2005-06-25 05:39:213188
Paul Mackerras9f1afe02006-02-19 11:44:473189 if {![info exists selectedline] || $commitrow($id) eq $selectedline} {
Paul Mackerrasc8dfbcf2005-06-25 05:39:213190 set state disabled
3191 } else {
3192 set state normal
3193 }
3194 $rowctxmenu entryconfigure 0 -state $state
3195 $rowctxmenu entryconfigure 1 -state $state
Paul Mackerras74daedb2005-06-27 09:27:323196 $rowctxmenu entryconfigure 2 -state $state
Paul Mackerrasc8dfbcf2005-06-25 05:39:213197 set rowmenuid $id
3198 tk_popup $rowctxmenu $x $y
3199}
3200
3201proc diffvssel {dirn} {
Paul Mackerras8f7d0ce2006-02-28 11:10:193202 global rowmenuid selectedline displayorder
Paul Mackerrasc8dfbcf2005-06-25 05:39:213203
3204 if {![info exists selectedline]} return
3205 if {$dirn} {
Paul Mackerras8f7d0ce2006-02-28 11:10:193206 set oldid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 05:39:213207 set newid $rowmenuid
3208 } else {
3209 set oldid $rowmenuid
Paul Mackerras8f7d0ce2006-02-28 11:10:193210 set newid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 05:39:213211 }
Paul Mackerrasfa4da7b2005-08-07 23:47:223212 addtohistory [list doseldiff $oldid $newid]
3213 doseldiff $oldid $newid
3214}
3215
3216proc doseldiff {oldid newid} {
3217 global ctext cflist
3218 global commitinfo
3219
Paul Mackerrasc8dfbcf2005-06-25 05:39:213220 $ctext conf -state normal
3221 $ctext delete 0.0 end
3222 $ctext mark set fmark.0 0.0
3223 $ctext mark gravity fmark.0 left
3224 $cflist delete 0 end
3225 $cflist insert end "Top"
Paul Mackerrasfa4da7b2005-08-07 23:47:223226 $ctext insert end "From "
3227 $ctext tag conf link -foreground blue -underline 1
3228 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
3229 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
3230 $ctext tag bind link0 <1> [list selbyid $oldid]
3231 $ctext insert end $oldid [list link link0]
3232 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 05:39:213233 $ctext insert end [lindex $commitinfo($oldid) 0]
Paul Mackerrasfa4da7b2005-08-07 23:47:223234 $ctext insert end "\n\nTo "
3235 $ctext tag bind link1 <1> [list selbyid $newid]
3236 $ctext insert end $newid [list link link1]
3237 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 05:39:213238 $ctext insert end [lindex $commitinfo($newid) 0]
3239 $ctext insert end "\n"
3240 $ctext conf -state disabled
3241 $ctext tag delete Comments
3242 $ctext tag remove found 1.0 end
Paul Mackerrasd3272442005-11-28 09:41:563243 startdiff [list $oldid $newid]
Paul Mackerrasc8dfbcf2005-06-25 05:39:213244}
3245
Paul Mackerras74daedb2005-06-27 09:27:323246proc mkpatch {} {
3247 global rowmenuid currentid commitinfo patchtop patchnum
3248
3249 if {![info exists currentid]} return
3250 set oldid $currentid
3251 set oldhead [lindex $commitinfo($oldid) 0]
3252 set newid $rowmenuid
3253 set newhead [lindex $commitinfo($newid) 0]
3254 set top .patch
3255 set patchtop $top
3256 catch {destroy $top}
3257 toplevel $top
3258 label $top.title -text "Generate patch"
Paul Mackerras4a2139f2005-06-28 23:47:483259 grid $top.title - -pady 10
Paul Mackerras74daedb2005-06-27 09:27:323260 label $top.from -text "From:"
Paul Mackerras4a2139f2005-06-28 23:47:483261 entry $top.fromsha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:323262 $top.fromsha1 insert 0 $oldid
3263 $top.fromsha1 conf -state readonly
3264 grid $top.from $top.fromsha1 -sticky w
Paul Mackerras4a2139f2005-06-28 23:47:483265 entry $top.fromhead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:323266 $top.fromhead insert 0 $oldhead
3267 $top.fromhead conf -state readonly
3268 grid x $top.fromhead -sticky w
3269 label $top.to -text "To:"
Paul Mackerras4a2139f2005-06-28 23:47:483270 entry $top.tosha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:323271 $top.tosha1 insert 0 $newid
3272 $top.tosha1 conf -state readonly
3273 grid $top.to $top.tosha1 -sticky w
Paul Mackerras4a2139f2005-06-28 23:47:483274 entry $top.tohead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:323275 $top.tohead insert 0 $newhead
3276 $top.tohead conf -state readonly
3277 grid x $top.tohead -sticky w
3278 button $top.rev -text "Reverse" -command mkpatchrev -padx 5
3279 grid $top.rev x -pady 10
3280 label $top.flab -text "Output file:"
3281 entry $top.fname -width 60
3282 $top.fname insert 0 [file normalize "patch$patchnum.patch"]
3283 incr patchnum
Paul Mackerrasbdbfbe32005-06-27 12:56:403284 grid $top.flab $top.fname -sticky w
Paul Mackerras74daedb2005-06-27 09:27:323285 frame $top.buts
3286 button $top.buts.gen -text "Generate" -command mkpatchgo
3287 button $top.buts.can -text "Cancel" -command mkpatchcan
3288 grid $top.buts.gen $top.buts.can
3289 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3290 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3291 grid $top.buts - -pady 10 -sticky ew
Paul Mackerrasbdbfbe32005-06-27 12:56:403292 focus $top.fname
Paul Mackerras74daedb2005-06-27 09:27:323293}
3294
3295proc mkpatchrev {} {
3296 global patchtop
3297
3298 set oldid [$patchtop.fromsha1 get]
3299 set oldhead [$patchtop.fromhead get]
3300 set newid [$patchtop.tosha1 get]
3301 set newhead [$patchtop.tohead get]
3302 foreach e [list fromsha1 fromhead tosha1 tohead] \
3303 v [list $newid $newhead $oldid $oldhead] {
3304 $patchtop.$e conf -state normal
3305 $patchtop.$e delete 0 end
3306 $patchtop.$e insert 0 $v
3307 $patchtop.$e conf -state readonly
3308 }
3309}
3310
3311proc mkpatchgo {} {
3312 global patchtop
3313
3314 set oldid [$patchtop.fromsha1 get]
3315 set newid [$patchtop.tosha1 get]
3316 set fname [$patchtop.fname get]
3317 if {[catch {exec git-diff-tree -p $oldid $newid >$fname &} err]} {
3318 error_popup "Error creating patch: $err"
3319 }
3320 catch {destroy $patchtop}
3321 unset patchtop
3322}
3323
3324proc mkpatchcan {} {
3325 global patchtop
3326
3327 catch {destroy $patchtop}
3328 unset patchtop
3329}
3330
Paul Mackerrasbdbfbe32005-06-27 12:56:403331proc mktag {} {
3332 global rowmenuid mktagtop commitinfo
3333
3334 set top .maketag
3335 set mktagtop $top
3336 catch {destroy $top}
3337 toplevel $top
3338 label $top.title -text "Create tag"
Paul Mackerras4a2139f2005-06-28 23:47:483339 grid $top.title - -pady 10
Paul Mackerrasbdbfbe32005-06-27 12:56:403340 label $top.id -text "ID:"
Paul Mackerras4a2139f2005-06-28 23:47:483341 entry $top.sha1 -width 40 -relief flat
Paul Mackerrasbdbfbe32005-06-27 12:56:403342 $top.sha1 insert 0 $rowmenuid
3343 $top.sha1 conf -state readonly
3344 grid $top.id $top.sha1 -sticky w
Paul Mackerras4a2139f2005-06-28 23:47:483345 entry $top.head -width 60 -relief flat
Paul Mackerrasbdbfbe32005-06-27 12:56:403346 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
3347 $top.head conf -state readonly
3348 grid x $top.head -sticky w
3349 label $top.tlab -text "Tag name:"
Paul Mackerras4a2139f2005-06-28 23:47:483350 entry $top.tag -width 60
Paul Mackerrasbdbfbe32005-06-27 12:56:403351 grid $top.tlab $top.tag -sticky w
3352 frame $top.buts
3353 button $top.buts.gen -text "Create" -command mktaggo
3354 button $top.buts.can -text "Cancel" -command mktagcan
3355 grid $top.buts.gen $top.buts.can
3356 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3357 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3358 grid $top.buts - -pady 10 -sticky ew
3359 focus $top.tag
3360}
3361
3362proc domktag {} {
3363 global mktagtop env tagids idtags
Paul Mackerrasbdbfbe32005-06-27 12:56:403364
3365 set id [$mktagtop.sha1 get]
3366 set tag [$mktagtop.tag get]
3367 if {$tag == {}} {
3368 error_popup "No tag name specified"
3369 return
3370 }
3371 if {[info exists tagids($tag)]} {
3372 error_popup "Tag \"$tag\" already exists"
3373 return
3374 }
3375 if {[catch {
Junio C Hamano73b6a6c2005-07-28 07:28:443376 set dir [gitdir]
Paul Mackerrasbdbfbe32005-06-27 12:56:403377 set fname [file join $dir "refs/tags" $tag]
3378 set f [open $fname w]
3379 puts $f $id
3380 close $f
3381 } err]} {
3382 error_popup "Error creating tag: $err"
3383 return
3384 }
3385
3386 set tagids($tag) $id
3387 lappend idtags($id) $tag
Paul Mackerrasf1d83ba2005-08-19 12:14:283388 redrawtags $id
3389}
3390
3391proc redrawtags {id} {
Paul Mackerras9f1afe02006-02-19 11:44:473392 global canv linehtag commitrow idpos selectedline
Paul Mackerrasf1d83ba2005-08-19 12:14:283393
Paul Mackerras9f1afe02006-02-19 11:44:473394 if {![info exists commitrow($id)]} return
3395 drawcmitrow $commitrow($id)
Paul Mackerrasbdbfbe32005-06-27 12:56:403396 $canv delete tag.$id
3397 set xt [eval drawtags $id $idpos($id)]
Paul Mackerras9f1afe02006-02-19 11:44:473398 $canv coords $linehtag($commitrow($id)) $xt [lindex $idpos($id) 2]
3399 if {[info exists selectedline] && $selectedline == $commitrow($id)} {
Paul Mackerrasd6982062005-08-06 12:06:063400 selectline $selectedline 0
Paul Mackerrasbdbfbe32005-06-27 12:56:403401 }
3402}
3403
3404proc mktagcan {} {
3405 global mktagtop
3406
3407 catch {destroy $mktagtop}
3408 unset mktagtop
3409}
3410
3411proc mktaggo {} {
3412 domktag
3413 mktagcan
3414}
3415
Paul Mackerras4a2139f2005-06-28 23:47:483416proc writecommit {} {
3417 global rowmenuid wrcomtop commitinfo wrcomcmd
3418
3419 set top .writecommit
3420 set wrcomtop $top
3421 catch {destroy $top}
3422 toplevel $top
3423 label $top.title -text "Write commit to file"
3424 grid $top.title - -pady 10
3425 label $top.id -text "ID:"
3426 entry $top.sha1 -width 40 -relief flat
3427 $top.sha1 insert 0 $rowmenuid
3428 $top.sha1 conf -state readonly
3429 grid $top.id $top.sha1 -sticky w
3430 entry $top.head -width 60 -relief flat
3431 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
3432 $top.head conf -state readonly
3433 grid x $top.head -sticky w
3434 label $top.clab -text "Command:"
3435 entry $top.cmd -width 60 -textvariable wrcomcmd
3436 grid $top.clab $top.cmd -sticky w -pady 10
3437 label $top.flab -text "Output file:"
3438 entry $top.fname -width 60
3439 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
3440 grid $top.flab $top.fname -sticky w
3441 frame $top.buts
3442 button $top.buts.gen -text "Write" -command wrcomgo
3443 button $top.buts.can -text "Cancel" -command wrcomcan
3444 grid $top.buts.gen $top.buts.can
3445 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3446 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3447 grid $top.buts - -pady 10 -sticky ew
3448 focus $top.fname
3449}
3450
3451proc wrcomgo {} {
3452 global wrcomtop
3453
3454 set id [$wrcomtop.sha1 get]
3455 set cmd "echo $id | [$wrcomtop.cmd get]"
3456 set fname [$wrcomtop.fname get]
3457 if {[catch {exec sh -c $cmd >$fname &} err]} {
3458 error_popup "Error writing commit: $err"
3459 }
3460 catch {destroy $wrcomtop}
3461 unset wrcomtop
3462}
3463
3464proc wrcomcan {} {
3465 global wrcomtop
3466
3467 catch {destroy $wrcomtop}
3468 unset wrcomtop
3469}
3470
Paul Mackerrasf1d83ba2005-08-19 12:14:283471proc listrefs {id} {
3472 global idtags idheads idotherrefs
3473
3474 set x {}
3475 if {[info exists idtags($id)]} {
3476 set x $idtags($id)
3477 }
3478 set y {}
3479 if {[info exists idheads($id)]} {
3480 set y $idheads($id)
3481 }
3482 set z {}
3483 if {[info exists idotherrefs($id)]} {
3484 set z $idotherrefs($id)
3485 }
3486 return [list $x $y $z]
3487}
3488
3489proc rereadrefs {} {
3490 global idtags idheads idotherrefs
Paul Mackerrasf1d83ba2005-08-19 12:14:283491
3492 set refids [concat [array names idtags] \
3493 [array names idheads] [array names idotherrefs]]
3494 foreach id $refids {
3495 if {![info exists ref($id)]} {
3496 set ref($id) [listrefs $id]
3497 }
3498 }
Paul Mackerrasf1d83ba2005-08-19 12:14:283499 readrefs
3500 set refids [lsort -unique [concat $refids [array names idtags] \
3501 [array names idheads] [array names idotherrefs]]]
3502 foreach id $refids {
3503 set v [listrefs $id]
3504 if {![info exists ref($id)] || $ref($id) != $v} {
3505 redrawtags $id
3506 }
3507 }
3508}
3509
Paul Mackerras106288c2005-08-19 13:11:393510proc showtag {tag isnew} {
3511 global ctext cflist tagcontents tagids linknum
3512
3513 if {$isnew} {
3514 addtohistory [list showtag $tag 0]
3515 }
3516 $ctext conf -state normal
3517 $ctext delete 0.0 end
3518 set linknum 0
3519 if {[info exists tagcontents($tag)]} {
3520 set text $tagcontents($tag)
3521 } else {
3522 set text "Tag: $tag\nId: $tagids($tag)"
3523 }
3524 appendwithlinks $text
3525 $ctext conf -state disabled
3526 $cflist delete 0 end
3527}
3528
Paul Mackerras1d10f362005-05-15 12:55:473529proc doquit {} {
3530 global stopped
3531 set stopped 100
3532 destroy .
3533}
3534
Paul Mackerras712fcc02005-11-29 22:28:163535proc doprefs {} {
3536 global maxwidth maxgraphpct diffopts findmergefiles
3537 global oldprefs prefstop
Paul Mackerras232475d2005-11-14 23:34:033538
Paul Mackerras712fcc02005-11-29 22:28:163539 set top .gitkprefs
3540 set prefstop $top
3541 if {[winfo exists $top]} {
3542 raise $top
3543 return
Paul Mackerras757f17b2005-11-20 22:56:073544 }
Paul Mackerras712fcc02005-11-29 22:28:163545 foreach v {maxwidth maxgraphpct diffopts findmergefiles} {
3546 set oldprefs($v) [set $v]
Paul Mackerras232475d2005-11-14 23:34:033547 }
Paul Mackerras712fcc02005-11-29 22:28:163548 toplevel $top
3549 wm title $top "Gitk preferences"
3550 label $top.ldisp -text "Commit list display options"
3551 grid $top.ldisp - -sticky w -pady 10
3552 label $top.spacer -text " "
3553 label $top.maxwidthl -text "Maximum graph width (lines)" \
3554 -font optionfont
3555 spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
3556 grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
3557 label $top.maxpctl -text "Maximum graph width (% of pane)" \
3558 -font optionfont
3559 spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
3560 grid x $top.maxpctl $top.maxpct -sticky w
3561 checkbutton $top.findm -variable findmergefiles
3562 label $top.findml -text "Include merges for \"Find\" in \"Files\"" \
3563 -font optionfont
3564 grid $top.findm $top.findml - -sticky w
3565 label $top.ddisp -text "Diff display options"
3566 grid $top.ddisp - -sticky w -pady 10
3567 label $top.diffoptl -text "Options for diff program" \
3568 -font optionfont
3569 entry $top.diffopt -width 20 -textvariable diffopts
3570 grid x $top.diffoptl $top.diffopt -sticky w
3571 frame $top.buts
3572 button $top.buts.ok -text "OK" -command prefsok
3573 button $top.buts.can -text "Cancel" -command prefscan
3574 grid $top.buts.ok $top.buts.can
3575 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3576 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3577 grid $top.buts - - -pady 10 -sticky ew
3578}
3579
3580proc prefscan {} {
3581 global maxwidth maxgraphpct diffopts findmergefiles
3582 global oldprefs prefstop
3583
3584 foreach v {maxwidth maxgraphpct diffopts findmergefiles} {
3585 set $v $oldprefs($v)
3586 }
3587 catch {destroy $prefstop}
3588 unset prefstop
3589}
3590
3591proc prefsok {} {
3592 global maxwidth maxgraphpct
3593 global oldprefs prefstop
3594
3595 catch {destroy $prefstop}
3596 unset prefstop
3597 if {$maxwidth != $oldprefs(maxwidth)
3598 || $maxgraphpct != $oldprefs(maxgraphpct)} {
3599 redisplay
3600 }
3601}
3602
3603proc formatdate {d} {
3604 return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
Paul Mackerras232475d2005-11-14 23:34:033605}
3606
Paul Mackerrasfd8ccbe2005-12-07 12:28:223607# This list of encoding names and aliases is distilled from
3608# http://www.iana.org/assignments/character-sets.
3609# Not all of them are supported by Tcl.
3610set encoding_aliases {
3611 { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
3612 ISO646-US US-ASCII us IBM367 cp367 csASCII }
3613 { ISO-10646-UTF-1 csISO10646UTF1 }
3614 { ISO_646.basic:1983 ref csISO646basic1983 }
3615 { INVARIANT csINVARIANT }
3616 { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
3617 { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
3618 { NATS-SEFI iso-ir-8-1 csNATSSEFI }
3619 { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
3620 { NATS-DANO iso-ir-9-1 csNATSDANO }
3621 { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
3622 { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
3623 { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
3624 { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
3625 { ISO-2022-KR csISO2022KR }
3626 { EUC-KR csEUCKR }
3627 { ISO-2022-JP csISO2022JP }
3628 { ISO-2022-JP-2 csISO2022JP2 }
3629 { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
3630 csISO13JISC6220jp }
3631 { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
3632 { IT iso-ir-15 ISO646-IT csISO15Italian }
3633 { PT iso-ir-16 ISO646-PT csISO16Portuguese }
3634 { ES iso-ir-17 ISO646-ES csISO17Spanish }
3635 { greek7-old iso-ir-18 csISO18Greek7Old }
3636 { latin-greek iso-ir-19 csISO19LatinGreek }
3637 { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
3638 { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
3639 { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
3640 { ISO_5427 iso-ir-37 csISO5427Cyrillic }
3641 { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
3642 { BS_viewdata iso-ir-47 csISO47BSViewdata }
3643 { INIS iso-ir-49 csISO49INIS }
3644 { INIS-8 iso-ir-50 csISO50INIS8 }
3645 { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
3646 { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
3647 { ISO_5428:1980 iso-ir-55 csISO5428Greek }
3648 { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
3649 { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
3650 { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
3651 csISO60Norwegian1 }
3652 { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
3653 { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
3654 { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
3655 { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
3656 { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
3657 { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
3658 { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
3659 { greek7 iso-ir-88 csISO88Greek7 }
3660 { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
3661 { iso-ir-90 csISO90 }
3662 { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
3663 { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
3664 csISO92JISC62991984b }
3665 { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
3666 { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
3667 { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
3668 csISO95JIS62291984handadd }
3669 { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
3670 { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
3671 { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
3672 { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
3673 CP819 csISOLatin1 }
3674 { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
3675 { T.61-7bit iso-ir-102 csISO102T617bit }
3676 { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
3677 { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
3678 { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
3679 { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
3680 { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
3681 { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
3682 { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
3683 { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
3684 arabic csISOLatinArabic }
3685 { ISO_8859-6-E csISO88596E ISO-8859-6-E }
3686 { ISO_8859-6-I csISO88596I ISO-8859-6-I }
3687 { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
3688 greek greek8 csISOLatinGreek }
3689 { T.101-G2 iso-ir-128 csISO128T101G2 }
3690 { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
3691 csISOLatinHebrew }
3692 { ISO_8859-8-E csISO88598E ISO-8859-8-E }
3693 { ISO_8859-8-I csISO88598I ISO-8859-8-I }
3694 { CSN_369103 iso-ir-139 csISO139CSN369103 }
3695 { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
3696 { ISO_6937-2-add iso-ir-142 csISOTextComm }
3697 { IEC_P27-1 iso-ir-143 csISO143IECP271 }
3698 { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
3699 csISOLatinCyrillic }
3700 { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
3701 { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
3702 { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
3703 { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
3704 { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
3705 { ISO_6937-2-25 iso-ir-152 csISO6937Add }
3706 { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
3707 { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
3708 { ISO_10367-box iso-ir-155 csISO10367Box }
3709 { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
3710 { latin-lap lap iso-ir-158 csISO158Lap }
3711 { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
3712 { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
3713 { us-dk csUSDK }
3714 { dk-us csDKUS }
3715 { JIS_X0201 X0201 csHalfWidthKatakana }
3716 { KSC5636 ISO646-KR csKSC5636 }
3717 { ISO-10646-UCS-2 csUnicode }
3718 { ISO-10646-UCS-4 csUCS4 }
3719 { DEC-MCS dec csDECMCS }
3720 { hp-roman8 roman8 r8 csHPRoman8 }
3721 { macintosh mac csMacintosh }
3722 { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
3723 csIBM037 }
3724 { IBM038 EBCDIC-INT cp038 csIBM038 }
3725 { IBM273 CP273 csIBM273 }
3726 { IBM274 EBCDIC-BE CP274 csIBM274 }
3727 { IBM275 EBCDIC-BR cp275 csIBM275 }
3728 { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
3729 { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
3730 { IBM280 CP280 ebcdic-cp-it csIBM280 }
3731 { IBM281 EBCDIC-JP-E cp281 csIBM281 }
3732 { IBM284 CP284 ebcdic-cp-es csIBM284 }
3733 { IBM285 CP285 ebcdic-cp-gb csIBM285 }
3734 { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
3735 { IBM297 cp297 ebcdic-cp-fr csIBM297 }
3736 { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
3737 { IBM423 cp423 ebcdic-cp-gr csIBM423 }
3738 { IBM424 cp424 ebcdic-cp-he csIBM424 }
3739 { IBM437 cp437 437 csPC8CodePage437 }
3740 { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
3741 { IBM775 cp775 csPC775Baltic }
3742 { IBM850 cp850 850 csPC850Multilingual }
3743 { IBM851 cp851 851 csIBM851 }
3744 { IBM852 cp852 852 csPCp852 }
3745 { IBM855 cp855 855 csIBM855 }
3746 { IBM857 cp857 857 csIBM857 }
3747 { IBM860 cp860 860 csIBM860 }
3748 { IBM861 cp861 861 cp-is csIBM861 }
3749 { IBM862 cp862 862 csPC862LatinHebrew }
3750 { IBM863 cp863 863 csIBM863 }
3751 { IBM864 cp864 csIBM864 }
3752 { IBM865 cp865 865 csIBM865 }
3753 { IBM866 cp866 866 csIBM866 }
3754 { IBM868 CP868 cp-ar csIBM868 }
3755 { IBM869 cp869 869 cp-gr csIBM869 }
3756 { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
3757 { IBM871 CP871 ebcdic-cp-is csIBM871 }
3758 { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
3759 { IBM891 cp891 csIBM891 }
3760 { IBM903 cp903 csIBM903 }
3761 { IBM904 cp904 904 csIBBM904 }
3762 { IBM905 CP905 ebcdic-cp-tr csIBM905 }
3763 { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
3764 { IBM1026 CP1026 csIBM1026 }
3765 { EBCDIC-AT-DE csIBMEBCDICATDE }
3766 { EBCDIC-AT-DE-A csEBCDICATDEA }
3767 { EBCDIC-CA-FR csEBCDICCAFR }
3768 { EBCDIC-DK-NO csEBCDICDKNO }
3769 { EBCDIC-DK-NO-A csEBCDICDKNOA }
3770 { EBCDIC-FI-SE csEBCDICFISE }
3771 { EBCDIC-FI-SE-A csEBCDICFISEA }
3772 { EBCDIC-FR csEBCDICFR }
3773 { EBCDIC-IT csEBCDICIT }
3774 { EBCDIC-PT csEBCDICPT }
3775 { EBCDIC-ES csEBCDICES }
3776 { EBCDIC-ES-A csEBCDICESA }
3777 { EBCDIC-ES-S csEBCDICESS }
3778 { EBCDIC-UK csEBCDICUK }
3779 { EBCDIC-US csEBCDICUS }
3780 { UNKNOWN-8BIT csUnknown8BiT }
3781 { MNEMONIC csMnemonic }
3782 { MNEM csMnem }
3783 { VISCII csVISCII }
3784 { VIQR csVIQR }
3785 { KOI8-R csKOI8R }
3786 { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
3787 { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
3788 { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
3789 { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
3790 { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
3791 { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
3792 { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
3793 { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
3794 { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
3795 { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
3796 { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
3797 { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
3798 { IBM1047 IBM-1047 }
3799 { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
3800 { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
3801 { UNICODE-1-1 csUnicode11 }
3802 { CESU-8 csCESU-8 }
3803 { BOCU-1 csBOCU-1 }
3804 { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
3805 { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
3806 l8 }
3807 { ISO-8859-15 ISO_8859-15 Latin-9 }
3808 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
3809 { GBK CP936 MS936 windows-936 }
3810 { JIS_Encoding csJISEncoding }
3811 { Shift_JIS MS_Kanji csShiftJIS }
3812 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
3813 EUC-JP }
3814 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
3815 { ISO-10646-UCS-Basic csUnicodeASCII }
3816 { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
3817 { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
3818 { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
3819 { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
3820 { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
3821 { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
3822 { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
3823 { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
3824 { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
3825 { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
3826 { Adobe-Standard-Encoding csAdobeStandardEncoding }
3827 { Ventura-US csVenturaUS }
3828 { Ventura-International csVenturaInternational }
3829 { PC8-Danish-Norwegian csPC8DanishNorwegian }
3830 { PC8-Turkish csPC8Turkish }
3831 { IBM-Symbols csIBMSymbols }
3832 { IBM-Thai csIBMThai }
3833 { HP-Legal csHPLegal }
3834 { HP-Pi-font csHPPiFont }
3835 { HP-Math8 csHPMath8 }
3836 { Adobe-Symbol-Encoding csHPPSMath }
3837 { HP-DeskTop csHPDesktop }
3838 { Ventura-Math csVenturaMath }
3839 { Microsoft-Publishing csMicrosoftPublishing }
3840 { Windows-31J csWindows31J }
3841 { GB2312 csGB2312 }
3842 { Big5 csBig5 }
3843}
3844
3845proc tcl_encoding {enc} {
3846 global encoding_aliases
3847 set names [encoding names]
3848 set lcnames [string tolower $names]
3849 set enc [string tolower $enc]
3850 set i [lsearch -exact $lcnames $enc]
3851 if {$i < 0} {
3852 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
3853 if {[regsub {^iso[-_]} $enc iso encx]} {
3854 set i [lsearch -exact $lcnames $encx]
3855 }
3856 }
3857 if {$i < 0} {
3858 foreach l $encoding_aliases {
3859 set ll [string tolower $l]
3860 if {[lsearch -exact $ll $enc] < 0} continue
3861 # look through the aliases for one that tcl knows about
3862 foreach e $ll {
3863 set i [lsearch -exact $lcnames $e]
3864 if {$i < 0} {
3865 if {[regsub {^iso[-_]} $e iso ex]} {
3866 set i [lsearch -exact $lcnames $ex]
3867 }
3868 }
3869 if {$i >= 0} break
3870 }
3871 break
3872 }
3873 }
3874 if {$i >= 0} {
3875 return [lindex $names $i]
3876 }
3877 return {}
3878}
3879
Paul Mackerras1d10f362005-05-15 12:55:473880# defaults...
3881set datemode 0
Paul Mackerras1d10f362005-05-15 12:55:473882set diffopts "-U 5 -p"
Paul Mackerras4a2139f2005-06-28 23:47:483883set wrcomcmd "git-diff-tree --stdin -p --pretty"
Junio C Hamano671bc152005-11-28 00:12:513884
Paul Mackerrasfd8ccbe2005-12-07 12:28:223885set gitencoding {}
Junio C Hamano671bc152005-11-28 00:12:513886catch {
3887 set gitencoding [exec git-repo-config --get i18n.commitencoding]
3888}
3889if {$gitencoding == ""} {
Paul Mackerrasfd8ccbe2005-12-07 12:28:223890 set gitencoding "utf-8"
3891}
3892set tclencoding [tcl_encoding $gitencoding]
3893if {$tclencoding == {}} {
3894 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
Junio C Hamano671bc152005-11-28 00:12:513895}
Paul Mackerras1d10f362005-05-15 12:55:473896
3897set mainfont {Helvetica 9}
Paul Mackerras1d10f362005-05-15 12:55:473898set textfont {Courier 9}
Keith Packard4840be62006-04-04 07:19:453899set uifont {Helvetica 9 bold}
Paul Mackerrasb74fd572005-07-16 11:46:133900set findmergefiles 0
Paul Mackerras8d858d12005-08-04 23:52:163901set maxgraphpct 50
Paul Mackerrasf6075eb2005-08-17 23:30:103902set maxwidth 16
Paul Mackerras232475d2005-11-14 23:34:033903set revlistorder 0
Paul Mackerras757f17b2005-11-20 22:56:073904set fastdate 0
Paul Mackerras9f1afe02006-02-19 11:44:473905set uparrowlen 7
3906set downarrowlen 7
3907set mingaplen 30
Paul Mackerras1d10f362005-05-15 12:55:473908
3909set colors {green red blue magenta darkgrey brown orange}
Paul Mackerras1d10f362005-05-15 12:55:473910
3911catch {source ~/.gitk}
3912
Paul Mackerras17386062005-05-18 22:51:003913set namefont $mainfont
Paul Mackerras712fcc02005-11-29 22:28:163914
3915font create optionfont -family sans-serif -size -12
Paul Mackerras17386062005-05-18 22:51:003916
Paul Mackerras1d10f362005-05-15 12:55:473917set revtreeargs {}
3918foreach arg $argv {
3919 switch -regexp -- $arg {
3920 "^$" { }
Paul Mackerras1d10f362005-05-15 12:55:473921 "^-d" { set datemode 1 }
Paul Mackerras1d10f362005-05-15 12:55:473922 default {
3923 lappend revtreeargs $arg
3924 }
3925 }
3926}
3927
Paul Mackerrasaa81d972006-02-28 00:27:123928# check that we can find a .git directory somewhere...
3929set gitdir [gitdir]
3930if {![file isdirectory $gitdir]} {
3931 error_popup "Cannot find the git directory \"$gitdir\"."
3932 exit 1
3933}
3934
Paul Mackerrasd6982062005-08-06 12:06:063935set history {}
3936set historyindex 0
3937
Paul Mackerras9f1afe02006-02-19 11:44:473938set optim_delay 16
3939
Paul Mackerras1d10f362005-05-15 12:55:473940set stopped 0
Paul Mackerras0fba86b2005-05-16 23:54:583941set stuffsaved 0
Paul Mackerras74daedb2005-06-27 09:27:323942set patchnum 0
Paul Mackerras1d10f362005-05-15 12:55:473943setcoords
Sven Verdoolaegeb5c2f302005-11-29 21:15:513944makewindow $revtreeargs
Paul Mackerras887fe3c2005-05-21 07:35:373945readrefs
Paul Mackerras1d10f362005-05-15 12:55:473946getcommits $revtreeargs