🌐 AI搜索 & 代理 主页
blob: 4604c831fe0c5ac9b855cdef6f71888e99dd9462 [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
Paul Mackerrasee66e082008-05-09 00:14:075# Copyright © 2005-2008 Paul Mackerras. All rights reserved.
Paul Mackerras1db95b02005-05-09 04:08:396# 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 {
Peter Baumann5024baa2007-01-09 14:30:1915 return [exec git rev-parse --git-dir]
Junio C Hamano73b6a6c2005-07-28 07:28:4416 }
17}
18
Paul Mackerras7eb3cb92007-06-17 04:45:0019# A simple scheduler for compute-intensive stuff.
20# The aim is to make sure that event handlers for GUI actions can
21# run at least every 50-100 ms. Unfortunately fileevent handlers are
22# run before X event handlers, so reading from a fast source can
23# make the GUI completely unresponsive.
24proc run args {
Alexander Gavrilovdf75e862008-08-09 10:41:5025 global isonrunq runq currunq
Paul Mackerras7eb3cb92007-06-17 04:45:0026
27 set script $args
28 if {[info exists isonrunq($script)]} return
Alexander Gavrilovdf75e862008-08-09 10:41:5029 if {$runq eq {} && ![info exists currunq]} {
Paul Mackerras7eb3cb92007-06-17 04:45:0030 after idle dorunq
31 }
32 lappend runq [list {} $script]
33 set isonrunq($script) 1
34}
35
36proc filerun {fd script} {
37 fileevent $fd readable [list filereadable $fd $script]
38}
39
40proc filereadable {fd script} {
Alexander Gavrilovdf75e862008-08-09 10:41:5041 global runq currunq
Paul Mackerras7eb3cb92007-06-17 04:45:0042
43 fileevent $fd readable {}
Alexander Gavrilovdf75e862008-08-09 10:41:5044 if {$runq eq {} && ![info exists currunq]} {
Paul Mackerras7eb3cb92007-06-17 04:45:0045 after idle dorunq
46 }
47 lappend runq [list $fd $script]
48}
49
Paul Mackerras7fcc92b2007-12-02 23:33:0150proc nukefile {fd} {
51 global runq
52
53 for {set i 0} {$i < [llength $runq]} {} {
54 if {[lindex $runq $i 0] eq $fd} {
55 set runq [lreplace $runq $i $i]
56 } else {
57 incr i
58 }
59 }
60}
61
Paul Mackerras7eb3cb92007-06-17 04:45:0062proc dorunq {} {
Alexander Gavrilovdf75e862008-08-09 10:41:5063 global isonrunq runq currunq
Paul Mackerras7eb3cb92007-06-17 04:45:0064
65 set tstart [clock clicks -milliseconds]
66 set t0 $tstart
Paul Mackerras7fcc92b2007-12-02 23:33:0167 while {[llength $runq] > 0} {
Paul Mackerras7eb3cb92007-06-17 04:45:0068 set fd [lindex $runq 0 0]
69 set script [lindex $runq 0 1]
Alexander Gavrilovdf75e862008-08-09 10:41:5070 set currunq [lindex $runq 0]
71 set runq [lrange $runq 1 end]
Paul Mackerras7eb3cb92007-06-17 04:45:0072 set repeat [eval $script]
Alexander Gavrilovdf75e862008-08-09 10:41:5073 unset currunq
Paul Mackerras7eb3cb92007-06-17 04:45:0074 set t1 [clock clicks -milliseconds]
75 set t [expr {$t1 - $t0}]
Paul Mackerras7eb3cb92007-06-17 04:45:0076 if {$repeat ne {} && $repeat} {
77 if {$fd eq {} || $repeat == 2} {
78 # script returns 1 if it wants to be readded
79 # file readers return 2 if they could do more straight away
80 lappend runq [list $fd $script]
81 } else {
82 fileevent $fd readable [list filereadable $fd $script]
83 }
84 } elseif {$fd eq {}} {
85 unset isonrunq($script)
86 }
87 set t0 $t1
88 if {$t1 - $tstart >= 80} break
89 }
90 if {$runq ne {}} {
91 after idle dorunq
92 }
93}
94
Alexander Gavrilove439e092008-07-13 12:40:4795proc reg_instance {fd} {
96 global commfd leftover loginstance
97
98 set i [incr loginstance]
99 set commfd($i) $fd
100 set leftover($i) {}
101 return $i
102}
103
Paul Mackerras3ed31a82008-04-26 06:00:00104proc unmerged_files {files} {
105 global nr_unmerged
106
107 # find the list of unmerged files
108 set mlist {}
109 set nr_unmerged 0
110 if {[catch {
111 set fd [open "| git ls-files -u" r]
112 } err]} {
113 show_error {} . "[mc "Couldn't get list of unmerged files:"] $err"
114 exit 1
115 }
116 while {[gets $fd line] >= 0} {
117 set i [string first "\t" $line]
118 if {$i < 0} continue
119 set fname [string range $line [expr {$i+1}] end]
120 if {[lsearch -exact $mlist $fname] >= 0} continue
121 incr nr_unmerged
122 if {$files eq {} || [path_filter $files $fname]} {
123 lappend mlist $fname
124 }
125 }
126 catch {close $fd}
127 return $mlist
128}
129
130proc parseviewargs {n arglist} {
Paul Mackerrasee66e082008-05-09 00:14:07131 global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs
Paul Mackerras3ed31a82008-04-26 06:00:00132
133 set vdatemode($n) 0
134 set vmergeonly($n) 0
Paul Mackerrasee66e082008-05-09 00:14:07135 set glflags {}
136 set diffargs {}
137 set nextisval 0
138 set revargs {}
139 set origargs $arglist
140 set allknown 1
141 set filtered 0
142 set i -1
143 foreach arg $arglist {
144 incr i
145 if {$nextisval} {
146 lappend glflags $arg
147 set nextisval 0
148 continue
149 }
Paul Mackerras3ed31a82008-04-26 06:00:00150 switch -glob -- $arg {
151 "-d" -
152 "--date-order" {
153 set vdatemode($n) 1
Paul Mackerrasee66e082008-05-09 00:14:07154 # remove from origargs in case we hit an unknown option
155 set origargs [lreplace $origargs $i $i]
156 incr i -1
157 }
Paul Mackerrasee66e082008-05-09 00:14:07158 "-[puabwcrRBMC]" -
159 "--no-renames" - "--full-index" - "--binary" - "--abbrev=*" -
160 "--find-copies-harder" - "-l*" - "--ext-diff" - "--no-ext-diff" -
161 "--src-prefix=*" - "--dst-prefix=*" - "--no-prefix" -
162 "-O*" - "--text" - "--full-diff" - "--ignore-space-at-eol" -
163 "--ignore-space-change" - "-U*" - "--unified=*" {
Paul Mackerras29582282008-11-18 08:44:20164 # These request or affect diff output, which we don't want.
165 # Some could be used to set our defaults for diff display.
Paul Mackerrasee66e082008-05-09 00:14:07166 lappend diffargs $arg
167 }
Paul Mackerrasee66e082008-05-09 00:14:07168 "--raw" - "--patch-with-raw" - "--patch-with-stat" -
169 "--name-only" - "--name-status" - "--color" - "--color-words" -
170 "--log-size" - "--pretty=*" - "--decorate" - "--abbrev-commit" -
171 "--cc" - "-z" - "--header" - "--parents" - "--boundary" -
172 "--no-color" - "-g" - "--walk-reflogs" - "--no-walk" -
173 "--timestamp" - "relative-date" - "--date=*" - "--stdin" -
174 "--objects" - "--objects-edge" - "--reverse" {
Paul Mackerras29582282008-11-18 08:44:20175 # These cause our parsing of git log's output to fail, or else
176 # they're options we want to set ourselves, so ignore them.
Paul Mackerrasee66e082008-05-09 00:14:07177 }
Paul Mackerrasee66e082008-05-09 00:14:07178 "--stat=*" - "--numstat" - "--shortstat" - "--summary" -
179 "--check" - "--exit-code" - "--quiet" - "--topo-order" -
180 "--full-history" - "--dense" - "--sparse" -
181 "--follow" - "--left-right" - "--encoding=*" {
Paul Mackerras29582282008-11-18 08:44:20182 # These are harmless, and some are even useful
Paul Mackerrasee66e082008-05-09 00:14:07183 lappend glflags $arg
184 }
Paul Mackerrasee66e082008-05-09 00:14:07185 "--diff-filter=*" - "--no-merges" - "--unpacked" -
186 "--max-count=*" - "--skip=*" - "--since=*" - "--after=*" -
187 "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
188 "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
189 "--remove-empty" - "--first-parent" - "--cherry-pick" -
Dirk Suesserottf687aaa2009-05-21 13:35:40190 "-S*" - "--pickaxe-all" - "--pickaxe-regex" -
191 "--simplify-by-decoration" {
Paul Mackerras29582282008-11-18 08:44:20192 # These mean that we get a subset of the commits
Paul Mackerrasee66e082008-05-09 00:14:07193 set filtered 1
194 lappend glflags $arg
195 }
Paul Mackerrasee66e082008-05-09 00:14:07196 "-n" {
Paul Mackerras29582282008-11-18 08:44:20197 # This appears to be the only one that has a value as a
198 # separate word following it
Paul Mackerrasee66e082008-05-09 00:14:07199 set filtered 1
200 set nextisval 1
201 lappend glflags $arg
202 }
Paul Mackerras6e7e87c2008-12-01 22:17:46203 "--not" - "--all" {
Paul Mackerrasee66e082008-05-09 00:14:07204 lappend revargs $arg
Paul Mackerras3ed31a82008-04-26 06:00:00205 }
206 "--merge" {
207 set vmergeonly($n) 1
Paul Mackerrasee66e082008-05-09 00:14:07208 # git rev-parse doesn't understand --merge
209 lappend revargs --gitk-symmetric-diff-marker MERGE_HEAD...HEAD
Paul Mackerras3ed31a82008-04-26 06:00:00210 }
Paul Mackerrasee66e082008-05-09 00:14:07211 "-*" {
Paul Mackerras29582282008-11-18 08:44:20212 # Other flag arguments including -<n>
Paul Mackerrasee66e082008-05-09 00:14:07213 if {[string is digit -strict [string range $arg 1 end]]} {
214 set filtered 1
215 } else {
216 # a flag argument that we don't recognize;
217 # that means we can't optimize
218 set allknown 0
219 }
220 lappend glflags $arg
221 }
Paul Mackerras3ed31a82008-04-26 06:00:00222 default {
Paul Mackerras29582282008-11-18 08:44:20223 # Non-flag arguments specify commits or ranges of commits
Paul Mackerrasee66e082008-05-09 00:14:07224 if {[string match "*...*" $arg]} {
225 lappend revargs --gitk-symmetric-diff-marker
226 }
227 lappend revargs $arg
Paul Mackerras3ed31a82008-04-26 06:00:00228 }
229 }
230 }
Paul Mackerrasee66e082008-05-09 00:14:07231 set vdflags($n) $diffargs
232 set vflags($n) $glflags
233 set vrevs($n) $revargs
234 set vfiltered($n) $filtered
235 set vorigargs($n) $origargs
236 return $allknown
237}
238
239proc parseviewrevs {view revs} {
240 global vposids vnegids
241
242 if {$revs eq {}} {
243 set revs HEAD
244 }
245 if {[catch {set ids [eval exec git rev-parse $revs]} err]} {
246 # we get stdout followed by stderr in $err
247 # for an unknown rev, git rev-parse echoes it and then errors out
248 set errlines [split $err "\n"]
249 set badrev {}
250 for {set l 0} {$l < [llength $errlines]} {incr l} {
251 set line [lindex $errlines $l]
252 if {!([string length $line] == 40 && [string is xdigit $line])} {
253 if {[string match "fatal:*" $line]} {
254 if {[string match "fatal: ambiguous argument*" $line]
255 && $badrev ne {}} {
256 if {[llength $badrev] == 1} {
257 set err "unknown revision $badrev"
258 } else {
259 set err "unknown revisions: [join $badrev ", "]"
260 }
261 } else {
262 set err [join [lrange $errlines $l end] "\n"]
263 }
264 break
265 }
266 lappend badrev $line
267 }
268 }
Christian Stimming3945d2c2008-09-12 09:39:43269 error_popup "[mc "Error parsing revisions:"] $err"
Paul Mackerrasee66e082008-05-09 00:14:07270 return {}
271 }
272 set ret {}
273 set pos {}
274 set neg {}
275 set sdm 0
276 foreach id [split $ids "\n"] {
277 if {$id eq "--gitk-symmetric-diff-marker"} {
278 set sdm 4
279 } elseif {[string match "^*" $id]} {
280 if {$sdm != 1} {
281 lappend ret $id
282 if {$sdm == 3} {
283 set sdm 0
284 }
285 }
286 lappend neg [string range $id 1 end]
287 } else {
288 if {$sdm != 2} {
289 lappend ret $id
290 } else {
291 lset ret end [lindex $ret end]...$id
292 }
293 lappend pos $id
294 }
295 incr sdm -1
296 }
297 set vposids($view) $pos
298 set vnegids($view) $neg
299 return $ret
Paul Mackerras3ed31a82008-04-26 06:00:00300}
301
Paul Mackerrasf9e0b6f2008-03-04 10:14:17302# Start off a git log process and arrange to read its output
Paul Mackerrasda7c24d2006-05-02 01:15:29303proc start_rev_list {view} {
Paul Mackerras6df74032008-05-11 12:13:02304 global startmsecs commitidx viewcomplete curview
Alexander Gavrilove439e092008-07-13 12:40:47305 global tclencoding
Paul Mackerrasee66e082008-05-09 00:14:07306 global viewargs viewargscmd viewfiles vfilelimit
Paul Mackerrasd375ef92008-10-20 23:18:12307 global showlocalchanges
Alexander Gavrilove439e092008-07-13 12:40:47308 global viewactive viewinstances vmergeonly
Paul Mackerrascdc84292008-11-18 08:54:14309 global mainheadid viewmainheadid viewmainheadid_orig
Paul Mackerrasee66e082008-05-09 00:14:07310 global vcanopt vflags vrevs vorigargs
Paul Mackerras38ad0912005-12-01 11:42:46311
312 set startmsecs [clock clicks -milliseconds]
Paul Mackerrasda7c24d2006-05-02 01:15:29313 set commitidx($view) 0
Paul Mackerras3ed31a82008-04-26 06:00:00314 # these are set this way for the error exits
315 set viewcomplete($view) 1
316 set viewactive($view) 0
Paul Mackerras7fcc92b2007-12-02 23:33:01317 varcinit $view
318
Yann Dirson2d480852008-02-21 20:23:31319 set args $viewargs($view)
320 if {$viewargscmd($view) ne {}} {
321 if {[catch {
322 set str [exec sh -c $viewargscmd($view)]
323 } err]} {
Christian Stimming3945d2c2008-09-12 09:39:43324 error_popup "[mc "Error executing --argscmd command:"] $err"
Paul Mackerras3ed31a82008-04-26 06:00:00325 return 0
Yann Dirson2d480852008-02-21 20:23:31326 }
327 set args [concat $args [split $str "\n"]]
328 }
Paul Mackerrasee66e082008-05-09 00:14:07329 set vcanopt($view) [parseviewargs $view $args]
Paul Mackerras3ed31a82008-04-26 06:00:00330
331 set files $viewfiles($view)
332 if {$vmergeonly($view)} {
333 set files [unmerged_files $files]
334 if {$files eq {}} {
335 global nr_unmerged
336 if {$nr_unmerged == 0} {
337 error_popup [mc "No files selected: --merge specified but\
338 no files are unmerged."]
339 } else {
340 error_popup [mc "No files selected: --merge specified but\
341 no unmerged files are within file limit."]
342 }
343 return 0
344 }
345 }
346 set vfilelimit($view) $files
347
Paul Mackerrasee66e082008-05-09 00:14:07348 if {$vcanopt($view)} {
349 set revs [parseviewrevs $view $vrevs($view)]
350 if {$revs eq {}} {
351 return 0
352 }
353 set args [concat $vflags($view) $revs]
354 } else {
355 set args $vorigargs($view)
356 }
357
Paul Mackerras418c4c72006-02-06 22:10:18358 if {[catch {
Paul Mackerras7fcc92b2007-12-02 23:33:01359 set fd [open [concat | git log --no-color -z --pretty=raw --parents \
Paul Mackerras3ed31a82008-04-26 06:00:00360 --boundary $args "--" $files] r]
Paul Mackerras418c4c72006-02-06 22:10:18361 } err]} {
Paul Mackerras00abadb2007-12-19 23:25:50362 error_popup "[mc "Error executing git log:"] $err"
Paul Mackerras3ed31a82008-04-26 06:00:00363 return 0
Paul Mackerras38ad0912005-12-01 11:42:46364 }
Alexander Gavrilove439e092008-07-13 12:40:47365 set i [reg_instance $fd]
Paul Mackerras7fcc92b2007-12-02 23:33:01366 set viewinstances($view) [list $i]
Paul Mackerrascdc84292008-11-18 08:54:14367 set viewmainheadid($view) $mainheadid
368 set viewmainheadid_orig($view) $mainheadid
369 if {$files ne {} && $mainheadid ne {}} {
370 get_viewmainhead $view
371 }
372 if {$showlocalchanges && $viewmainheadid($view) ne {}} {
373 interestedin $viewmainheadid($view) dodiffindex
Paul Mackerras3e6b8932007-09-14 23:33:39374 }
Mark Levedahl86da5b62007-07-17 22:42:04375 fconfigure $fd -blocking 0 -translation lf -eofchar {}
Paul Mackerrasfd8ccbe2005-12-07 12:28:22376 if {$tclencoding != {}} {
Paul Mackerrasda7c24d2006-05-02 01:15:29377 fconfigure $fd -encoding $tclencoding
Paul Mackerrasfd8ccbe2005-12-07 12:28:22378 }
Paul Mackerrasf806f0f2008-02-24 01:16:56379 filerun $fd [list getcommitlines $fd $i $view 0]
Christian Stimmingd990ced2007-11-07 17:42:55380 nowbusy $view [mc "Reading"]
Paul Mackerras3ed31a82008-04-26 06:00:00381 set viewcomplete($view) 0
382 set viewactive($view) 1
383 return 1
Paul Mackerras38ad0912005-12-01 11:42:46384}
385
Alexander Gavrilove2f90ee2008-07-12 12:09:28386proc stop_instance {inst} {
387 global commfd leftover
388
389 set fd $commfd($inst)
390 catch {
391 set pid [pid $fd]
Alexander Gavrilovb6326e92008-07-14 20:35:42392
393 if {$::tcl_platform(platform) eq {windows}} {
394 exec kill -f $pid
395 } else {
396 exec kill $pid
397 }
Alexander Gavrilove2f90ee2008-07-12 12:09:28398 }
399 catch {close $fd}
400 nukefile $fd
401 unset commfd($inst)
402 unset leftover($inst)
403}
404
405proc stop_backends {} {
406 global commfd
407
408 foreach inst [array names commfd] {
409 stop_instance $inst
410 }
411}
412
Paul Mackerras7fcc92b2007-12-02 23:33:01413proc stop_rev_list {view} {
Alexander Gavrilove2f90ee2008-07-12 12:09:28414 global viewinstances
Paul Mackerras22626ef2006-04-16 23:56:02415
Paul Mackerras7fcc92b2007-12-02 23:33:01416 foreach inst $viewinstances($view) {
Alexander Gavrilove2f90ee2008-07-12 12:09:28417 stop_instance $inst
Paul Mackerras22626ef2006-04-16 23:56:02418 }
Paul Mackerras7fcc92b2007-12-02 23:33:01419 set viewinstances($view) {}
Paul Mackerras22626ef2006-04-16 23:56:02420}
421
Alexander Gavrilov567c34e2008-07-26 16:13:45422proc reset_pending_select {selid} {
Alexander Gavrilov39816d62008-08-23 08:27:44423 global pending_select mainheadid selectheadid
Alexander Gavrilov567c34e2008-07-26 16:13:45424
425 if {$selid ne {}} {
426 set pending_select $selid
Alexander Gavrilov39816d62008-08-23 08:27:44427 } elseif {$selectheadid ne {}} {
428 set pending_select $selectheadid
Alexander Gavrilov567c34e2008-07-26 16:13:45429 } else {
430 set pending_select $mainheadid
431 }
432}
433
434proc getcommits {selid} {
Paul Mackerras3ed31a82008-04-26 06:00:00435 global canv curview need_redisplay viewactive
Sven Verdoolaegeb5c2f302005-11-29 21:15:51436
Paul Mackerrasda7c24d2006-05-02 01:15:29437 initlayout
Paul Mackerras3ed31a82008-04-26 06:00:00438 if {[start_rev_list $curview]} {
Alexander Gavrilov567c34e2008-07-26 16:13:45439 reset_pending_select $selid
Paul Mackerras3ed31a82008-04-26 06:00:00440 show_status [mc "Reading commits..."]
441 set need_redisplay 1
442 } else {
443 show_status [mc "No commits selected"]
444 }
Paul Mackerras1d10f362005-05-15 12:55:47445}
446
Paul Mackerras7fcc92b2007-12-02 23:33:01447proc updatecommits {} {
Paul Mackerrasee66e082008-05-09 00:14:07448 global curview vcanopt vorigargs vfilelimit viewinstances
Alexander Gavrilove439e092008-07-13 12:40:47449 global viewactive viewcomplete tclencoding
450 global startmsecs showneartags showlocalchanges
Paul Mackerrascdc84292008-11-18 08:54:14451 global mainheadid viewmainheadid viewmainheadid_orig pending_select
Paul Mackerras92e22ca2008-03-11 11:21:39452 global isworktree
Paul Mackerrasee66e082008-05-09 00:14:07453 global varcid vposids vnegids vflags vrevs
Paul Mackerras7fcc92b2007-12-02 23:33:01454
Paul Mackerras92e22ca2008-03-11 11:21:39455 set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
Paul Mackerrasfc2a2562007-12-26 12:03:43456 rereadrefs
Paul Mackerrascdc84292008-11-18 08:54:14457 set view $curview
458 if {$mainheadid ne $viewmainheadid_orig($view)} {
459 if {$showlocalchanges} {
Paul Mackerraseb5f8c92007-12-29 10:13:34460 dohidelocalchanges
461 }
Paul Mackerrascdc84292008-11-18 08:54:14462 set viewmainheadid($view) $mainheadid
463 set viewmainheadid_orig($view) $mainheadid
464 if {$vfilelimit($view) ne {}} {
465 get_viewmainhead $view
Paul Mackerraseb5f8c92007-12-29 10:13:34466 }
467 }
Paul Mackerrascdc84292008-11-18 08:54:14468 if {$showlocalchanges} {
469 doshowlocalchanges
470 }
Paul Mackerrasee66e082008-05-09 00:14:07471 if {$vcanopt($view)} {
472 set oldpos $vposids($view)
473 set oldneg $vnegids($view)
474 set revs [parseviewrevs $view $vrevs($view)]
475 if {$revs eq {}} {
476 return
477 }
478 # note: getting the delta when negative refs change is hard,
479 # and could require multiple git log invocations, so in that
480 # case we ask git log for all the commits (not just the delta)
481 if {$oldneg eq $vnegids($view)} {
482 set newrevs {}
483 set npos 0
484 # take out positive refs that we asked for before or
485 # that we have already seen
486 foreach rev $revs {
487 if {[string length $rev] == 40} {
488 if {[lsearch -exact $oldpos $rev] < 0
489 && ![info exists varcid($view,$rev)]} {
490 lappend newrevs $rev
491 incr npos
492 }
493 } else {
494 lappend $newrevs $rev
495 }
496 }
497 if {$npos == 0} return
498 set revs $newrevs
499 set vposids($view) [lsort -unique [concat $oldpos $vposids($view)]]
500 }
501 set args [concat $vflags($view) $revs --not $oldpos]
502 } else {
503 set args $vorigargs($view)
504 }
Paul Mackerras7fcc92b2007-12-02 23:33:01505 if {[catch {
506 set fd [open [concat | git log --no-color -z --pretty=raw --parents \
Paul Mackerrasee66e082008-05-09 00:14:07507 --boundary $args "--" $vfilelimit($view)] r]
Paul Mackerras7fcc92b2007-12-02 23:33:01508 } err]} {
Christian Stimming3945d2c2008-09-12 09:39:43509 error_popup "[mc "Error executing git log:"] $err"
Paul Mackerrasee66e082008-05-09 00:14:07510 return
Paul Mackerras7fcc92b2007-12-02 23:33:01511 }
512 if {$viewactive($view) == 0} {
513 set startmsecs [clock clicks -milliseconds]
514 }
Alexander Gavrilove439e092008-07-13 12:40:47515 set i [reg_instance $fd]
Paul Mackerras7fcc92b2007-12-02 23:33:01516 lappend viewinstances($view) $i
Paul Mackerras7fcc92b2007-12-02 23:33:01517 fconfigure $fd -blocking 0 -translation lf -eofchar {}
518 if {$tclencoding != {}} {
519 fconfigure $fd -encoding $tclencoding
520 }
Paul Mackerrasf806f0f2008-02-24 01:16:56521 filerun $fd [list getcommitlines $fd $i $view 1]
Paul Mackerras7fcc92b2007-12-02 23:33:01522 incr viewactive($view)
523 set viewcomplete($view) 0
Alexander Gavrilov567c34e2008-07-26 16:13:45524 reset_pending_select {}
Michele Ballabiob56e0a92009-03-30 19:17:25525 nowbusy $view [mc "Reading"]
Paul Mackerras7fcc92b2007-12-02 23:33:01526 if {$showneartags} {
527 getallcommits
528 }
529}
530
531proc reloadcommits {} {
532 global curview viewcomplete selectedline currentid thickerline
533 global showneartags treediffs commitinterest cached_commitrow
Paul Mackerras6df74032008-05-11 12:13:02534 global targetid
Paul Mackerras7fcc92b2007-12-02 23:33:01535
Alexander Gavrilov567c34e2008-07-26 16:13:45536 set selid {}
537 if {$selectedline ne {}} {
538 set selid $currentid
539 }
540
Paul Mackerras7fcc92b2007-12-02 23:33:01541 if {!$viewcomplete($curview)} {
542 stop_rev_list $curview
Paul Mackerras7fcc92b2007-12-02 23:33:01543 }
544 resetvarcs $curview
Paul Mackerras94b4a692008-05-20 10:51:06545 set selectedline {}
Paul Mackerras7fcc92b2007-12-02 23:33:01546 catch {unset currentid}
547 catch {unset thickerline}
548 catch {unset treediffs}
549 readrefs
550 changedrefs
551 if {$showneartags} {
552 getallcommits
553 }
554 clear_display
555 catch {unset commitinterest}
556 catch {unset cached_commitrow}
Paul Mackerras42a671f2008-01-01 22:59:39557 catch {unset targetid}
Paul Mackerras7fcc92b2007-12-02 23:33:01558 setcanvscroll
Alexander Gavrilov567c34e2008-07-26 16:13:45559 getcommits $selid
Paul Mackerrase7297a12008-01-15 11:30:40560 return 0
Paul Mackerras7fcc92b2007-12-02 23:33:01561}
562
Paul Mackerras6e8c8702007-07-31 11:03:06563# This makes a string representation of a positive integer which
564# sorts as a string in numerical order
565proc strrep {n} {
566 if {$n < 16} {
567 return [format "%x" $n]
568 } elseif {$n < 256} {
569 return [format "x%.2x" $n]
570 } elseif {$n < 65536} {
571 return [format "y%.4x" $n]
572 }
573 return [format "z%.8x" $n]
574}
575
Paul Mackerras7fcc92b2007-12-02 23:33:01576# Procedures used in reordering commits from git log (without
577# --topo-order) into the order for display.
578
579proc varcinit {view} {
Paul Mackerrasf3ea5ed2007-12-19 23:03:35580 global varcstart vupptr vdownptr vleftptr vbackptr varctok varcrow
581 global vtokmod varcmod vrowmod varcix vlastins
Paul Mackerras7fcc92b2007-12-02 23:33:01582
Paul Mackerras7fcc92b2007-12-02 23:33:01583 set varcstart($view) {{}}
584 set vupptr($view) {0}
585 set vdownptr($view) {0}
586 set vleftptr($view) {0}
Paul Mackerrasf3ea5ed2007-12-19 23:03:35587 set vbackptr($view) {0}
Paul Mackerras7fcc92b2007-12-02 23:33:01588 set varctok($view) {{}}
589 set varcrow($view) {{}}
590 set vtokmod($view) {}
591 set varcmod($view) 0
Paul Mackerrase5b37ac2007-12-12 07:13:51592 set vrowmod($view) 0
Paul Mackerras7fcc92b2007-12-02 23:33:01593 set varcix($view) {{}}
Paul Mackerrasf3ea5ed2007-12-19 23:03:35594 set vlastins($view) {0}
Paul Mackerras7fcc92b2007-12-02 23:33:01595}
596
597proc resetvarcs {view} {
598 global varcid varccommits parents children vseedcount ordertok
599
600 foreach vid [array names varcid $view,*] {
601 unset varcid($vid)
602 unset children($vid)
603 unset parents($vid)
604 }
605 # some commits might have children but haven't been seen yet
606 foreach vid [array names children $view,*] {
607 unset children($vid)
608 }
609 foreach va [array names varccommits $view,*] {
610 unset varccommits($va)
611 }
612 foreach vd [array names vseedcount $view,*] {
613 unset vseedcount($vd)
614 }
Paul Mackerras9257d8f2007-12-10 23:45:38615 catch {unset ordertok}
Paul Mackerras7fcc92b2007-12-02 23:33:01616}
617
Paul Mackerras468bcae2008-03-02 23:19:35618# returns a list of the commits with no children
619proc seeds {v} {
620 global vdownptr vleftptr varcstart
621
622 set ret {}
623 set a [lindex $vdownptr($v) 0]
624 while {$a != 0} {
625 lappend ret [lindex $varcstart($v) $a]
626 set a [lindex $vleftptr($v) $a]
627 }
628 return $ret
629}
630
Paul Mackerras7fcc92b2007-12-02 23:33:01631proc newvarc {view id} {
Paul Mackerras3ed31a82008-04-26 06:00:00632 global varcid varctok parents children vdatemode
Paul Mackerrasf3ea5ed2007-12-19 23:03:35633 global vupptr vdownptr vleftptr vbackptr varcrow varcix varcstart
634 global commitdata commitinfo vseedcount varccommits vlastins
Paul Mackerras7fcc92b2007-12-02 23:33:01635
636 set a [llength $varctok($view)]
637 set vid $view,$id
Paul Mackerras3ed31a82008-04-26 06:00:00638 if {[llength $children($vid)] == 0 || $vdatemode($view)} {
Paul Mackerras7fcc92b2007-12-02 23:33:01639 if {![info exists commitinfo($id)]} {
640 parsecommit $id $commitdata($id) 1
641 }
642 set cdate [lindex $commitinfo($id) 4]
643 if {![string is integer -strict $cdate]} {
644 set cdate 0
645 }
646 if {![info exists vseedcount($view,$cdate)]} {
647 set vseedcount($view,$cdate) -1
648 }
649 set c [incr vseedcount($view,$cdate)]
650 set cdate [expr {$cdate ^ 0xffffffff}]
651 set tok "s[strrep $cdate][strrep $c]"
Paul Mackerras7fcc92b2007-12-02 23:33:01652 } else {
653 set tok {}
Paul Mackerrasf3ea5ed2007-12-19 23:03:35654 }
655 set ka 0
656 if {[llength $children($vid)] > 0} {
657 set kid [lindex $children($vid) end]
658 set k $varcid($view,$kid)
659 if {[string compare [lindex $varctok($view) $k] $tok] > 0} {
660 set ki $kid
661 set ka $k
662 set tok [lindex $varctok($view) $k]
Paul Mackerras7fcc92b2007-12-02 23:33:01663 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:35664 }
665 if {$ka != 0} {
Paul Mackerras7fcc92b2007-12-02 23:33:01666 set i [lsearch -exact $parents($view,$ki) $id]
667 set j [expr {[llength $parents($view,$ki)] - 1 - $i}]
Paul Mackerras7fcc92b2007-12-02 23:33:01668 append tok [strrep $j]
669 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:35670 set c [lindex $vlastins($view) $ka]
671 if {$c == 0 || [string compare $tok [lindex $varctok($view) $c]] < 0} {
672 set c $ka
673 set b [lindex $vdownptr($view) $ka]
674 } else {
675 set b [lindex $vleftptr($view) $c]
676 }
677 while {$b != 0 && [string compare $tok [lindex $varctok($view) $b]] >= 0} {
678 set c $b
679 set b [lindex $vleftptr($view) $c]
680 }
681 if {$c == $ka} {
682 lset vdownptr($view) $ka $a
683 lappend vbackptr($view) 0
684 } else {
685 lset vleftptr($view) $c $a
686 lappend vbackptr($view) $c
687 }
688 lset vlastins($view) $ka $a
689 lappend vupptr($view) $ka
690 lappend vleftptr($view) $b
691 if {$b != 0} {
692 lset vbackptr($view) $b $a
693 }
Paul Mackerras7fcc92b2007-12-02 23:33:01694 lappend varctok($view) $tok
695 lappend varcstart($view) $id
696 lappend vdownptr($view) 0
697 lappend varcrow($view) {}
698 lappend varcix($view) {}
Paul Mackerrase5b37ac2007-12-12 07:13:51699 set varccommits($view,$a) {}
Paul Mackerrasf3ea5ed2007-12-19 23:03:35700 lappend vlastins($view) 0
Paul Mackerras7fcc92b2007-12-02 23:33:01701 return $a
702}
703
704proc splitvarc {p v} {
Paul Mackerras52b8ea92009-03-01 22:38:17705 global varcid varcstart varccommits varctok vtokmod
Paul Mackerrasf3ea5ed2007-12-19 23:03:35706 global vupptr vdownptr vleftptr vbackptr varcix varcrow vlastins
Paul Mackerras7fcc92b2007-12-02 23:33:01707
708 set oa $varcid($v,$p)
Paul Mackerras52b8ea92009-03-01 22:38:17709 set otok [lindex $varctok($v) $oa]
Paul Mackerras7fcc92b2007-12-02 23:33:01710 set ac $varccommits($v,$oa)
711 set i [lsearch -exact $varccommits($v,$oa) $p]
712 if {$i <= 0} return
713 set na [llength $varctok($v)]
714 # "%" sorts before "0"...
Paul Mackerras52b8ea92009-03-01 22:38:17715 set tok "$otok%[strrep $i]"
Paul Mackerras7fcc92b2007-12-02 23:33:01716 lappend varctok($v) $tok
717 lappend varcrow($v) {}
718 lappend varcix($v) {}
719 set varccommits($v,$oa) [lrange $ac 0 [expr {$i - 1}]]
720 set varccommits($v,$na) [lrange $ac $i end]
721 lappend varcstart($v) $p
722 foreach id $varccommits($v,$na) {
723 set varcid($v,$id) $na
724 }
725 lappend vdownptr($v) [lindex $vdownptr($v) $oa]
Paul Mackerras841ea822008-02-17 23:44:33726 lappend vlastins($v) [lindex $vlastins($v) $oa]
Paul Mackerras7fcc92b2007-12-02 23:33:01727 lset vdownptr($v) $oa $na
Paul Mackerras841ea822008-02-17 23:44:33728 lset vlastins($v) $oa 0
Paul Mackerras7fcc92b2007-12-02 23:33:01729 lappend vupptr($v) $oa
730 lappend vleftptr($v) 0
Paul Mackerrasf3ea5ed2007-12-19 23:03:35731 lappend vbackptr($v) 0
Paul Mackerras7fcc92b2007-12-02 23:33:01732 for {set b [lindex $vdownptr($v) $na]} {$b != 0} {set b [lindex $vleftptr($v) $b]} {
733 lset vupptr($v) $b $na
734 }
Paul Mackerras52b8ea92009-03-01 22:38:17735 if {[string compare $otok $vtokmod($v)] <= 0} {
736 modify_arc $v $oa
737 }
Paul Mackerras7fcc92b2007-12-02 23:33:01738}
739
740proc renumbervarc {a v} {
741 global parents children varctok varcstart varccommits
Paul Mackerras3ed31a82008-04-26 06:00:00742 global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod vdatemode
Paul Mackerras7fcc92b2007-12-02 23:33:01743
744 set t1 [clock clicks -milliseconds]
745 set todo {}
746 set isrelated($a) 1
Paul Mackerrasf3ea5ed2007-12-19 23:03:35747 set kidchanged($a) 1
Paul Mackerras7fcc92b2007-12-02 23:33:01748 set ntot 0
749 while {$a != 0} {
750 if {[info exists isrelated($a)]} {
751 lappend todo $a
752 set id [lindex $varccommits($v,$a) end]
753 foreach p $parents($v,$id) {
754 if {[info exists varcid($v,$p)]} {
755 set isrelated($varcid($v,$p)) 1
756 }
757 }
758 }
759 incr ntot
760 set b [lindex $vdownptr($v) $a]
761 if {$b == 0} {
762 while {$a != 0} {
763 set b [lindex $vleftptr($v) $a]
764 if {$b != 0} break
765 set a [lindex $vupptr($v) $a]
766 }
767 }
768 set a $b
769 }
770 foreach a $todo {
Paul Mackerrasf3ea5ed2007-12-19 23:03:35771 if {![info exists kidchanged($a)]} continue
Paul Mackerras7fcc92b2007-12-02 23:33:01772 set id [lindex $varcstart($v) $a]
Paul Mackerrasf3ea5ed2007-12-19 23:03:35773 if {[llength $children($v,$id)] > 1} {
774 set children($v,$id) [lsort -command [list vtokcmp $v] \
775 $children($v,$id)]
776 }
777 set oldtok [lindex $varctok($v) $a]
Paul Mackerras3ed31a82008-04-26 06:00:00778 if {!$vdatemode($v)} {
Paul Mackerrasf3ea5ed2007-12-19 23:03:35779 set tok {}
780 } else {
781 set tok $oldtok
782 }
783 set ka 0
Paul Mackerrasc8c9f3d2008-01-06 02:54:58784 set kid [last_real_child $v,$id]
785 if {$kid ne {}} {
Paul Mackerrasf3ea5ed2007-12-19 23:03:35786 set k $varcid($v,$kid)
787 if {[string compare [lindex $varctok($v) $k] $tok] > 0} {
788 set ki $kid
789 set ka $k
790 set tok [lindex $varctok($v) $k]
Paul Mackerras7fcc92b2007-12-02 23:33:01791 }
792 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:35793 if {$ka != 0} {
Paul Mackerras7fcc92b2007-12-02 23:33:01794 set i [lsearch -exact $parents($v,$ki) $id]
795 set j [expr {[llength $parents($v,$ki)] - 1 - $i}]
796 append tok [strrep $j]
Paul Mackerras7fcc92b2007-12-02 23:33:01797 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:35798 if {$tok eq $oldtok} {
799 continue
800 }
801 set id [lindex $varccommits($v,$a) end]
802 foreach p $parents($v,$id) {
803 if {[info exists varcid($v,$p)]} {
804 set kidchanged($varcid($v,$p)) 1
805 } else {
806 set sortkids($p) 1
807 }
808 }
809 lset varctok($v) $a $tok
Paul Mackerras7fcc92b2007-12-02 23:33:01810 set b [lindex $vupptr($v) $a]
811 if {$b != $ka} {
Paul Mackerras9257d8f2007-12-10 23:45:38812 if {[string compare [lindex $varctok($v) $ka] $vtokmod($v)] < 0} {
813 modify_arc $v $ka
Paul Mackerras38dfe932007-12-06 09:50:31814 }
Paul Mackerras9257d8f2007-12-10 23:45:38815 if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
816 modify_arc $v $b
Paul Mackerras38dfe932007-12-06 09:50:31817 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:35818 set c [lindex $vbackptr($v) $a]
819 set d [lindex $vleftptr($v) $a]
820 if {$c == 0} {
821 lset vdownptr($v) $b $d
Paul Mackerras7fcc92b2007-12-02 23:33:01822 } else {
Paul Mackerrasf3ea5ed2007-12-19 23:03:35823 lset vleftptr($v) $c $d
824 }
825 if {$d != 0} {
826 lset vbackptr($v) $d $c
Paul Mackerras7fcc92b2007-12-02 23:33:01827 }
Paul Mackerras841ea822008-02-17 23:44:33828 if {[lindex $vlastins($v) $b] == $a} {
829 lset vlastins($v) $b $c
830 }
Paul Mackerras7fcc92b2007-12-02 23:33:01831 lset vupptr($v) $a $ka
Paul Mackerrasf3ea5ed2007-12-19 23:03:35832 set c [lindex $vlastins($v) $ka]
833 if {$c == 0 || \
834 [string compare $tok [lindex $varctok($v) $c]] < 0} {
835 set c $ka
836 set b [lindex $vdownptr($v) $ka]
837 } else {
838 set b [lindex $vleftptr($v) $c]
Paul Mackerras7fcc92b2007-12-02 23:33:01839 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:35840 while {$b != 0 && \
841 [string compare $tok [lindex $varctok($v) $b]] >= 0} {
842 set c $b
843 set b [lindex $vleftptr($v) $c]
Paul Mackerras7fcc92b2007-12-02 23:33:01844 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:35845 if {$c == $ka} {
846 lset vdownptr($v) $ka $a
847 lset vbackptr($v) $a 0
848 } else {
849 lset vleftptr($v) $c $a
850 lset vbackptr($v) $a $c
851 }
852 lset vleftptr($v) $a $b
853 if {$b != 0} {
854 lset vbackptr($v) $b $a
855 }
856 lset vlastins($v) $ka $a
857 }
858 }
859 foreach id [array names sortkids] {
860 if {[llength $children($v,$id)] > 1} {
861 set children($v,$id) [lsort -command [list vtokcmp $v] \
862 $children($v,$id)]
Paul Mackerras7fcc92b2007-12-02 23:33:01863 }
864 }
865 set t2 [clock clicks -milliseconds]
866 #puts "renumbervarc did [llength $todo] of $ntot arcs in [expr {$t2-$t1}]ms"
867}
868
Paul Mackerrasf806f0f2008-02-24 01:16:56869# Fix up the graph after we have found out that in view $v,
870# $p (a commit that we have already seen) is actually the parent
871# of the last commit in arc $a.
Paul Mackerras7fcc92b2007-12-02 23:33:01872proc fix_reversal {p a v} {
Paul Mackerras24f7a662007-12-18 22:35:33873 global varcid varcstart varctok vupptr
Paul Mackerras7fcc92b2007-12-02 23:33:01874
875 set pa $varcid($v,$p)
876 if {$p ne [lindex $varcstart($v) $pa]} {
877 splitvarc $p $v
878 set pa $varcid($v,$p)
879 }
Paul Mackerras24f7a662007-12-18 22:35:33880 # seeds always need to be renumbered
881 if {[lindex $vupptr($v) $pa] == 0 ||
882 [string compare [lindex $varctok($v) $a] \
883 [lindex $varctok($v) $pa]] > 0} {
Paul Mackerras7fcc92b2007-12-02 23:33:01884 renumbervarc $pa $v
885 }
886}
887
888proc insertrow {id p v} {
Paul Mackerrasb8a938c2008-02-13 11:12:31889 global cmitlisted children parents varcid varctok vtokmod
890 global varccommits ordertok commitidx numcommits curview
891 global targetid targetrow
Paul Mackerras7fcc92b2007-12-02 23:33:01892
Paul Mackerrasb8a938c2008-02-13 11:12:31893 readcommit $id
894 set vid $v,$id
895 set cmitlisted($vid) 1
896 set children($vid) {}
897 set parents($vid) [list $p]
898 set a [newvarc $v $id]
899 set varcid($vid) $a
900 if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
901 modify_arc $v $a
902 }
903 lappend varccommits($v,$a) $id
904 set vp $v,$p
905 if {[llength [lappend children($vp) $id]] > 1} {
906 set children($vp) [lsort -command [list vtokcmp $v] $children($vp)]
907 catch {unset ordertok}
908 }
909 fix_reversal $p $a $v
910 incr commitidx($v)
911 if {$v == $curview} {
912 set numcommits $commitidx($v)
913 setcanvscroll
914 if {[info exists targetid]} {
915 if {![comes_before $targetid $p]} {
916 incr targetrow
917 }
918 }
919 }
920}
921
922proc insertfakerow {id p} {
923 global varcid varccommits parents children cmitlisted
924 global commitidx varctok vtokmod targetid targetrow curview numcommits
925
926 set v $curview
Paul Mackerras7fcc92b2007-12-02 23:33:01927 set a $varcid($v,$p)
928 set i [lsearch -exact $varccommits($v,$a) $p]
929 if {$i < 0} {
Paul Mackerrasb8a938c2008-02-13 11:12:31930 puts "oops: insertfakerow can't find [shortids $p] on arc $a"
Paul Mackerras7fcc92b2007-12-02 23:33:01931 return
932 }
933 set children($v,$id) {}
934 set parents($v,$id) [list $p]
935 set varcid($v,$id) $a
Paul Mackerras9257d8f2007-12-10 23:45:38936 lappend children($v,$p) $id
Paul Mackerras7fcc92b2007-12-02 23:33:01937 set cmitlisted($v,$id) 1
Paul Mackerrasb8a938c2008-02-13 11:12:31938 set numcommits [incr commitidx($v)]
Paul Mackerras7fcc92b2007-12-02 23:33:01939 # note we deliberately don't update varcstart($v) even if $i == 0
940 set varccommits($v,$a) [linsert $varccommits($v,$a) $i $id]
Paul Mackerrasc9cfdc92008-03-04 10:32:38941 modify_arc $v $a $i
Paul Mackerras42a671f2008-01-01 22:59:39942 if {[info exists targetid]} {
943 if {![comes_before $targetid $p]} {
944 incr targetrow
945 }
946 }
Paul Mackerrasb8a938c2008-02-13 11:12:31947 setcanvscroll
Paul Mackerras9257d8f2007-12-10 23:45:38948 drawvisible
Paul Mackerras7fcc92b2007-12-02 23:33:01949}
950
Paul Mackerrasb8a938c2008-02-13 11:12:31951proc removefakerow {id} {
Paul Mackerras9257d8f2007-12-10 23:45:38952 global varcid varccommits parents children commitidx
Paul Mackerrasfc2a2562007-12-26 12:03:43953 global varctok vtokmod cmitlisted currentid selectedline
Paul Mackerrasb8a938c2008-02-13 11:12:31954 global targetid curview numcommits
Paul Mackerras7fcc92b2007-12-02 23:33:01955
Paul Mackerrasb8a938c2008-02-13 11:12:31956 set v $curview
Paul Mackerras7fcc92b2007-12-02 23:33:01957 if {[llength $parents($v,$id)] != 1} {
Paul Mackerrasb8a938c2008-02-13 11:12:31958 puts "oops: removefakerow [shortids $id] has [llength $parents($v,$id)] parents"
Paul Mackerras7fcc92b2007-12-02 23:33:01959 return
960 }
961 set p [lindex $parents($v,$id) 0]
962 set a $varcid($v,$id)
963 set i [lsearch -exact $varccommits($v,$a) $id]
964 if {$i < 0} {
Paul Mackerrasb8a938c2008-02-13 11:12:31965 puts "oops: removefakerow can't find [shortids $id] on arc $a"
Paul Mackerras7fcc92b2007-12-02 23:33:01966 return
967 }
968 unset varcid($v,$id)
969 set varccommits($v,$a) [lreplace $varccommits($v,$a) $i $i]
970 unset parents($v,$id)
971 unset children($v,$id)
972 unset cmitlisted($v,$id)
Paul Mackerrasb8a938c2008-02-13 11:12:31973 set numcommits [incr commitidx($v) -1]
Paul Mackerras7fcc92b2007-12-02 23:33:01974 set j [lsearch -exact $children($v,$p) $id]
975 if {$j >= 0} {
976 set children($v,$p) [lreplace $children($v,$p) $j $j]
977 }
Paul Mackerrasc9cfdc92008-03-04 10:32:38978 modify_arc $v $a $i
Paul Mackerrasfc2a2562007-12-26 12:03:43979 if {[info exist currentid] && $id eq $currentid} {
980 unset currentid
Paul Mackerras94b4a692008-05-20 10:51:06981 set selectedline {}
Paul Mackerrasfc2a2562007-12-26 12:03:43982 }
Paul Mackerras42a671f2008-01-01 22:59:39983 if {[info exists targetid] && $targetid eq $id} {
984 set targetid $p
985 }
Paul Mackerrasb8a938c2008-02-13 11:12:31986 setcanvscroll
Paul Mackerras9257d8f2007-12-10 23:45:38987 drawvisible
Paul Mackerras7fcc92b2007-12-02 23:33:01988}
989
Paul Mackerrasc8c9f3d2008-01-06 02:54:58990proc first_real_child {vp} {
991 global children nullid nullid2
992
993 foreach id $children($vp) {
994 if {$id ne $nullid && $id ne $nullid2} {
995 return $id
996 }
997 }
998 return {}
999}
1000
1001proc last_real_child {vp} {
1002 global children nullid nullid2
1003
1004 set kids $children($vp)
1005 for {set i [llength $kids]} {[incr i -1] >= 0} {} {
1006 set id [lindex $kids $i]
1007 if {$id ne $nullid && $id ne $nullid2} {
1008 return $id
1009 }
1010 }
1011 return {}
1012}
1013
Paul Mackerras7fcc92b2007-12-02 23:33:011014proc vtokcmp {v a b} {
1015 global varctok varcid
1016
1017 return [string compare [lindex $varctok($v) $varcid($v,$a)] \
1018 [lindex $varctok($v) $varcid($v,$b)]]
1019}
1020
Paul Mackerrasc9cfdc92008-03-04 10:32:381021# This assumes that if lim is not given, the caller has checked that
1022# arc a's token is less than $vtokmod($v)
Paul Mackerrase5b37ac2007-12-12 07:13:511023proc modify_arc {v a {lim {}}} {
1024 global varctok vtokmod varcmod varcrow vupptr curview vrowmod varccommits
Paul Mackerras9257d8f2007-12-10 23:45:381025
Paul Mackerrasc9cfdc92008-03-04 10:32:381026 if {$lim ne {}} {
1027 set c [string compare [lindex $varctok($v) $a] $vtokmod($v)]
1028 if {$c > 0} return
1029 if {$c == 0} {
1030 set r [lindex $varcrow($v) $a]
1031 if {$r ne {} && $vrowmod($v) <= $r + $lim} return
1032 }
1033 }
Paul Mackerras9257d8f2007-12-10 23:45:381034 set vtokmod($v) [lindex $varctok($v) $a]
1035 set varcmod($v) $a
1036 if {$v == $curview} {
1037 while {$a != 0 && [lindex $varcrow($v) $a] eq {}} {
1038 set a [lindex $vupptr($v) $a]
Paul Mackerrase5b37ac2007-12-12 07:13:511039 set lim {}
Paul Mackerras9257d8f2007-12-10 23:45:381040 }
Paul Mackerrase5b37ac2007-12-12 07:13:511041 set r 0
1042 if {$a != 0} {
1043 if {$lim eq {}} {
1044 set lim [llength $varccommits($v,$a)]
1045 }
1046 set r [expr {[lindex $varcrow($v) $a] + $lim}]
1047 }
1048 set vrowmod($v) $r
Paul Mackerras0c278862007-12-11 09:09:531049 undolayout $r
Paul Mackerras9257d8f2007-12-10 23:45:381050 }
1051}
1052
Paul Mackerras7fcc92b2007-12-02 23:33:011053proc update_arcrows {v} {
Paul Mackerrase5b37ac2007-12-12 07:13:511054 global vtokmod varcmod vrowmod varcrow commitidx currentid selectedline
Paul Mackerras24f7a662007-12-18 22:35:331055 global varcid vrownum varcorder varcix varccommits
Paul Mackerras7fcc92b2007-12-02 23:33:011056 global vupptr vdownptr vleftptr varctok
Paul Mackerras24f7a662007-12-18 22:35:331057 global displayorder parentlist curview cached_commitrow
Paul Mackerras7fcc92b2007-12-02 23:33:011058
Paul Mackerrasc9cfdc92008-03-04 10:32:381059 if {$vrowmod($v) == $commitidx($v)} return
1060 if {$v == $curview} {
1061 if {[llength $displayorder] > $vrowmod($v)} {
1062 set displayorder [lrange $displayorder 0 [expr {$vrowmod($v) - 1}]]
1063 set parentlist [lrange $parentlist 0 [expr {$vrowmod($v) - 1}]]
1064 }
1065 catch {unset cached_commitrow}
1066 }
Paul Mackerras7fcc92b2007-12-02 23:33:011067 set narctot [expr {[llength $varctok($v)] - 1}]
1068 set a $varcmod($v)
1069 while {$a != 0 && [lindex $varcix($v) $a] eq {}} {
1070 # go up the tree until we find something that has a row number,
1071 # or we get to a seed
1072 set a [lindex $vupptr($v) $a]
1073 }
1074 if {$a == 0} {
1075 set a [lindex $vdownptr($v) 0]
1076 if {$a == 0} return
1077 set vrownum($v) {0}
1078 set varcorder($v) [list $a]
1079 lset varcix($v) $a 0
1080 lset varcrow($v) $a 0
1081 set arcn 0
1082 set row 0
1083 } else {
1084 set arcn [lindex $varcix($v) $a]
Paul Mackerras7fcc92b2007-12-02 23:33:011085 if {[llength $vrownum($v)] > $arcn + 1} {
1086 set vrownum($v) [lrange $vrownum($v) 0 $arcn]
1087 set varcorder($v) [lrange $varcorder($v) 0 $arcn]
1088 }
1089 set row [lindex $varcrow($v) $a]
1090 }
Paul Mackerras7fcc92b2007-12-02 23:33:011091 while {1} {
1092 set p $a
1093 incr row [llength $varccommits($v,$a)]
1094 # go down if possible
1095 set b [lindex $vdownptr($v) $a]
1096 if {$b == 0} {
1097 # if not, go left, or go up until we can go left
1098 while {$a != 0} {
1099 set b [lindex $vleftptr($v) $a]
1100 if {$b != 0} break
1101 set a [lindex $vupptr($v) $a]
1102 }
1103 if {$a == 0} break
1104 }
1105 set a $b
1106 incr arcn
1107 lappend vrownum($v) $row
1108 lappend varcorder($v) $a
1109 lset varcix($v) $a $arcn
1110 lset varcrow($v) $a $row
1111 }
Paul Mackerrase5b37ac2007-12-12 07:13:511112 set vtokmod($v) [lindex $varctok($v) $p]
1113 set varcmod($v) $p
1114 set vrowmod($v) $row
Paul Mackerras7fcc92b2007-12-02 23:33:011115 if {[info exists currentid]} {
1116 set selectedline [rowofcommit $currentid]
1117 }
Paul Mackerras7fcc92b2007-12-02 23:33:011118}
1119
1120# Test whether view $v contains commit $id
1121proc commitinview {id v} {
1122 global varcid
1123
1124 return [info exists varcid($v,$id)]
1125}
1126
1127# Return the row number for commit $id in the current view
1128proc rowofcommit {id} {
1129 global varcid varccommits varcrow curview cached_commitrow
Paul Mackerras9257d8f2007-12-10 23:45:381130 global varctok vtokmod
Paul Mackerras7fcc92b2007-12-02 23:33:011131
Paul Mackerras7fcc92b2007-12-02 23:33:011132 set v $curview
1133 if {![info exists varcid($v,$id)]} {
1134 puts "oops rowofcommit no arc for [shortids $id]"
1135 return {}
1136 }
1137 set a $varcid($v,$id)
Paul Mackerrasfc2a2562007-12-26 12:03:431138 if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] >= 0} {
Paul Mackerras9257d8f2007-12-10 23:45:381139 update_arcrows $v
1140 }
Paul Mackerras31c0eaa2007-12-30 11:41:141141 if {[info exists cached_commitrow($id)]} {
1142 return $cached_commitrow($id)
1143 }
Paul Mackerras7fcc92b2007-12-02 23:33:011144 set i [lsearch -exact $varccommits($v,$a) $id]
1145 if {$i < 0} {
1146 puts "oops didn't find commit [shortids $id] in arc $a"
1147 return {}
1148 }
1149 incr i [lindex $varcrow($v) $a]
1150 set cached_commitrow($id) $i
1151 return $i
1152}
1153
Paul Mackerras42a671f2008-01-01 22:59:391154# Returns 1 if a is on an earlier row than b, otherwise 0
1155proc comes_before {a b} {
1156 global varcid varctok curview
1157
1158 set v $curview
1159 if {$a eq $b || ![info exists varcid($v,$a)] || \
1160 ![info exists varcid($v,$b)]} {
1161 return 0
1162 }
1163 if {$varcid($v,$a) != $varcid($v,$b)} {
1164 return [expr {[string compare [lindex $varctok($v) $varcid($v,$a)] \
1165 [lindex $varctok($v) $varcid($v,$b)]] < 0}]
1166 }
1167 return [expr {[rowofcommit $a] < [rowofcommit $b]}]
1168}
1169
Paul Mackerras7fcc92b2007-12-02 23:33:011170proc bsearch {l elt} {
1171 if {[llength $l] == 0 || $elt <= [lindex $l 0]} {
1172 return 0
1173 }
1174 set lo 0
1175 set hi [llength $l]
1176 while {$hi - $lo > 1} {
1177 set mid [expr {int(($lo + $hi) / 2)}]
1178 set t [lindex $l $mid]
1179 if {$elt < $t} {
1180 set hi $mid
1181 } elseif {$elt > $t} {
1182 set lo $mid
1183 } else {
1184 return $mid
1185 }
1186 }
1187 return $lo
1188}
1189
1190# Make sure rows $start..$end-1 are valid in displayorder and parentlist
1191proc make_disporder {start end} {
1192 global vrownum curview commitidx displayorder parentlist
Paul Mackerrase5b37ac2007-12-12 07:13:511193 global varccommits varcorder parents vrowmod varcrow
Paul Mackerras7fcc92b2007-12-02 23:33:011194 global d_valid_start d_valid_end
1195
Paul Mackerrase5b37ac2007-12-12 07:13:511196 if {$end > $vrowmod($curview)} {
Paul Mackerras9257d8f2007-12-10 23:45:381197 update_arcrows $curview
1198 }
Paul Mackerras7fcc92b2007-12-02 23:33:011199 set ai [bsearch $vrownum($curview) $start]
1200 set start [lindex $vrownum($curview) $ai]
1201 set narc [llength $vrownum($curview)]
1202 for {set r $start} {$ai < $narc && $r < $end} {incr ai} {
1203 set a [lindex $varcorder($curview) $ai]
1204 set l [llength $displayorder]
1205 set al [llength $varccommits($curview,$a)]
1206 if {$l < $r + $al} {
1207 if {$l < $r} {
1208 set pad [ntimes [expr {$r - $l}] {}]
1209 set displayorder [concat $displayorder $pad]
1210 set parentlist [concat $parentlist $pad]
1211 } elseif {$l > $r} {
1212 set displayorder [lrange $displayorder 0 [expr {$r - 1}]]
1213 set parentlist [lrange $parentlist 0 [expr {$r - 1}]]
1214 }
1215 foreach id $varccommits($curview,$a) {
1216 lappend displayorder $id
1217 lappend parentlist $parents($curview,$id)
1218 }
Paul Mackerras17529cf2008-01-12 10:46:311219 } elseif {[lindex $displayorder [expr {$r + $al - 1}]] eq {}} {
Paul Mackerras7fcc92b2007-12-02 23:33:011220 set i $r
1221 foreach id $varccommits($curview,$a) {
1222 lset displayorder $i $id
1223 lset parentlist $i $parents($curview,$id)
1224 incr i
1225 }
1226 }
1227 incr r $al
1228 }
1229}
1230
1231proc commitonrow {row} {
1232 global displayorder
1233
1234 set id [lindex $displayorder $row]
1235 if {$id eq {}} {
1236 make_disporder $row [expr {$row + 1}]
1237 set id [lindex $displayorder $row]
1238 }
1239 return $id
1240}
1241
1242proc closevarcs {v} {
1243 global varctok varccommits varcid parents children
Paul Mackerrasd375ef92008-10-20 23:18:121244 global cmitlisted commitidx vtokmod
Paul Mackerras7fcc92b2007-12-02 23:33:011245
1246 set missing_parents 0
1247 set scripts {}
1248 set narcs [llength $varctok($v)]
1249 for {set a 1} {$a < $narcs} {incr a} {
1250 set id [lindex $varccommits($v,$a) end]
1251 foreach p $parents($v,$id) {
1252 if {[info exists varcid($v,$p)]} continue
1253 # add p as a new commit
1254 incr missing_parents
1255 set cmitlisted($v,$p) 0
1256 set parents($v,$p) {}
1257 if {[llength $children($v,$p)] == 1 &&
1258 [llength $parents($v,$id)] == 1} {
1259 set b $a
1260 } else {
1261 set b [newvarc $v $p]
1262 }
1263 set varcid($v,$p) $b
Paul Mackerras9257d8f2007-12-10 23:45:381264 if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
1265 modify_arc $v $b
Paul Mackerras7fcc92b2007-12-02 23:33:011266 }
Paul Mackerrase5b37ac2007-12-12 07:13:511267 lappend varccommits($v,$b) $p
Paul Mackerras7fcc92b2007-12-02 23:33:011268 incr commitidx($v)
Paul Mackerrasd375ef92008-10-20 23:18:121269 set scripts [check_interest $p $scripts]
Paul Mackerras7fcc92b2007-12-02 23:33:011270 }
1271 }
1272 if {$missing_parents > 0} {
Paul Mackerras7fcc92b2007-12-02 23:33:011273 foreach s $scripts {
1274 eval $s
1275 }
1276 }
1277}
1278
Paul Mackerrasf806f0f2008-02-24 01:16:561279# Use $rwid as a substitute for $id, i.e. reparent $id's children to $rwid
1280# Assumes we already have an arc for $rwid.
1281proc rewrite_commit {v id rwid} {
1282 global children parents varcid varctok vtokmod varccommits
1283
1284 foreach ch $children($v,$id) {
1285 # make $rwid be $ch's parent in place of $id
1286 set i [lsearch -exact $parents($v,$ch) $id]
1287 if {$i < 0} {
1288 puts "oops rewrite_commit didn't find $id in parent list for $ch"
1289 }
1290 set parents($v,$ch) [lreplace $parents($v,$ch) $i $i $rwid]
1291 # add $ch to $rwid's children and sort the list if necessary
1292 if {[llength [lappend children($v,$rwid) $ch]] > 1} {
1293 set children($v,$rwid) [lsort -command [list vtokcmp $v] \
1294 $children($v,$rwid)]
1295 }
1296 # fix the graph after joining $id to $rwid
1297 set a $varcid($v,$ch)
1298 fix_reversal $rwid $a $v
Paul Mackerrasc9cfdc92008-03-04 10:32:381299 # parentlist is wrong for the last element of arc $a
1300 # even if displayorder is right, hence the 3rd arg here
1301 modify_arc $v $a [expr {[llength $varccommits($v,$a)] - 1}]
Paul Mackerrasf806f0f2008-02-24 01:16:561302 }
1303}
1304
Paul Mackerrasd375ef92008-10-20 23:18:121305# Mechanism for registering a command to be executed when we come
1306# across a particular commit. To handle the case when only the
1307# prefix of the commit is known, the commitinterest array is now
1308# indexed by the first 4 characters of the ID. Each element is a
1309# list of id, cmd pairs.
1310proc interestedin {id cmd} {
1311 global commitinterest
1312
1313 lappend commitinterest([string range $id 0 3]) $id $cmd
1314}
1315
1316proc check_interest {id scripts} {
1317 global commitinterest
1318
1319 set prefix [string range $id 0 3]
1320 if {[info exists commitinterest($prefix)]} {
1321 set newlist {}
1322 foreach {i script} $commitinterest($prefix) {
1323 if {[string match "$i*" $id]} {
1324 lappend scripts [string map [list "%I" $id "%P" $i] $script]
1325 } else {
1326 lappend newlist $i $script
1327 }
1328 }
1329 if {$newlist ne {}} {
1330 set commitinterest($prefix) $newlist
1331 } else {
1332 unset commitinterest($prefix)
1333 }
1334 }
1335 return $scripts
1336}
1337
Paul Mackerrasf806f0f2008-02-24 01:16:561338proc getcommitlines {fd inst view updating} {
Paul Mackerrasd375ef92008-10-20 23:18:121339 global cmitlisted leftover
Paul Mackerras3ed31a82008-04-26 06:00:001340 global commitidx commitdata vdatemode
Paul Mackerras7fcc92b2007-12-02 23:33:011341 global parents children curview hlview
Paul Mackerras468bcae2008-03-02 23:19:351342 global idpending ordertok
Paul Mackerras3ed31a82008-04-26 06:00:001343 global varccommits varcid varctok vtokmod vfilelimit
Paul Mackerras9ccbdfb2005-06-16 00:27:231344
Paul Mackerrasd1e46752006-08-16 10:02:321345 set stuff [read $fd 500000]
Paul Mackerras005a2f42007-07-26 12:36:391346 # git log doesn't terminate the last commit with a null...
Paul Mackerras7fcc92b2007-12-02 23:33:011347 if {$stuff == {} && $leftover($inst) ne {} && [eof $fd]} {
Paul Mackerras005a2f42007-07-26 12:36:391348 set stuff "\0"
1349 }
Paul Mackerrasb490a992005-06-22 00:25:381350 if {$stuff == {}} {
Paul Mackerras7eb3cb92007-06-17 04:45:001351 if {![eof $fd]} {
1352 return 1
1353 }
Paul Mackerras6df74032008-05-11 12:13:021354 global commfd viewcomplete viewactive viewname
Paul Mackerras7fcc92b2007-12-02 23:33:011355 global viewinstances
1356 unset commfd($inst)
1357 set i [lsearch -exact $viewinstances($view) $inst]
1358 if {$i >= 0} {
1359 set viewinstances($view) [lreplace $viewinstances($view) $i $i]
Paul Mackerrasb0cdca92007-08-23 09:35:511360 }
Paul Mackerrasf0654862005-07-18 18:29:031361 # set it blocking so we wait for the process to terminate
Paul Mackerrasda7c24d2006-05-02 01:15:291362 fconfigure $fd -blocking 1
Paul Mackerras098dd8a2006-05-02 23:32:531363 if {[catch {close $fd} err]} {
1364 set fv {}
1365 if {$view != $curview} {
1366 set fv " for the \"$viewname($view)\" view"
Paul Mackerrasda7c24d2006-05-02 01:15:291367 }
Paul Mackerras098dd8a2006-05-02 23:32:531368 if {[string range $err 0 4] == "usage"} {
1369 set err "Gitk: error reading commits$fv:\
Paul Mackerrasf9e0b6f2008-03-04 10:14:171370 bad arguments to git log."
Paul Mackerras098dd8a2006-05-02 23:32:531371 if {$viewname($view) eq "Command line"} {
1372 append err \
Paul Mackerrasf9e0b6f2008-03-04 10:14:171373 " (Note: arguments to gitk are passed to git log\
Paul Mackerras098dd8a2006-05-02 23:32:531374 to allow selection of commits to be displayed.)"
1375 }
1376 } else {
1377 set err "Error reading commits$fv: $err"
1378 }
1379 error_popup $err
Paul Mackerras1d10f362005-05-15 12:55:471380 }
Paul Mackerras7fcc92b2007-12-02 23:33:011381 if {[incr viewactive($view) -1] <= 0} {
1382 set viewcomplete($view) 1
1383 # Check if we have seen any ids listed as parents that haven't
1384 # appeared in the list
1385 closevarcs $view
1386 notbusy $view
Paul Mackerras7fcc92b2007-12-02 23:33:011387 }
Paul Mackerras098dd8a2006-05-02 23:32:531388 if {$view == $curview} {
Paul Mackerrasac1276a2008-03-02 23:11:081389 run chewcommits
Paul Mackerras9a40c502005-05-12 23:46:161390 }
Paul Mackerras7eb3cb92007-06-17 04:45:001391 return 0
Paul Mackerras9a40c502005-05-12 23:46:161392 }
Paul Mackerrasb490a992005-06-22 00:25:381393 set start 0
Paul Mackerras8f7d0ce2006-02-28 11:10:191394 set gotsome 0
Paul Mackerras7fcc92b2007-12-02 23:33:011395 set scripts {}
Paul Mackerrasb490a992005-06-22 00:25:381396 while 1 {
1397 set i [string first "\0" $stuff $start]
1398 if {$i < 0} {
Paul Mackerras7fcc92b2007-12-02 23:33:011399 append leftover($inst) [string range $stuff $start end]
Paul Mackerras9f1afe02006-02-19 11:44:471400 break
Paul Mackerras9ccbdfb2005-06-16 00:27:231401 }
Paul Mackerrasb490a992005-06-22 00:25:381402 if {$start == 0} {
Paul Mackerras7fcc92b2007-12-02 23:33:011403 set cmit $leftover($inst)
Paul Mackerras8f7d0ce2006-02-28 11:10:191404 append cmit [string range $stuff 0 [expr {$i - 1}]]
Paul Mackerras7fcc92b2007-12-02 23:33:011405 set leftover($inst) {}
Paul Mackerras8f7d0ce2006-02-28 11:10:191406 } else {
1407 set cmit [string range $stuff $start [expr {$i - 1}]]
Paul Mackerrasb490a992005-06-22 00:25:381408 }
1409 set start [expr {$i + 1}]
Paul Mackerrase5ea7012005-08-18 10:40:391410 set j [string first "\n" $cmit]
1411 set ok 0
Paul Mackerras16c1ff92006-03-30 07:43:511412 set listed 1
Paul Mackerrasc961b222007-07-09 12:45:471413 if {$j >= 0 && [string match "commit *" $cmit]} {
1414 set ids [string range $cmit 7 [expr {$j - 1}]]
Linus Torvalds1407ade2008-02-09 22:02:071415 if {[string match {[-^<>]*} $ids]} {
Paul Mackerrasc961b222007-07-09 12:45:471416 switch -- [string index $ids 0] {
1417 "-" {set listed 0}
Linus Torvalds1407ade2008-02-09 22:02:071418 "^" {set listed 2}
1419 "<" {set listed 3}
1420 ">" {set listed 4}
Paul Mackerrasc961b222007-07-09 12:45:471421 }
Paul Mackerras16c1ff92006-03-30 07:43:511422 set ids [string range $ids 1 end]
1423 }
Paul Mackerrase5ea7012005-08-18 10:40:391424 set ok 1
1425 foreach id $ids {
Paul Mackerras8f7d0ce2006-02-28 11:10:191426 if {[string length $id] != 40} {
Paul Mackerrase5ea7012005-08-18 10:40:391427 set ok 0
1428 break
1429 }
1430 }
1431 }
1432 if {!$ok} {
Paul Mackerras7e952e72005-06-27 10:04:261433 set shortcmit $cmit
1434 if {[string length $shortcmit] > 80} {
1435 set shortcmit "[string range $shortcmit 0 80]..."
1436 }
Christian Stimmingd990ced2007-11-07 17:42:551437 error_popup "[mc "Can't parse git log output:"] {$shortcmit}"
Paul Mackerrasb490a992005-06-22 00:25:381438 exit 1
1439 }
Paul Mackerrase5ea7012005-08-18 10:40:391440 set id [lindex $ids 0]
Paul Mackerras7fcc92b2007-12-02 23:33:011441 set vid $view,$id
Paul Mackerrasf806f0f2008-02-24 01:16:561442
1443 if {!$listed && $updating && ![info exists varcid($vid)] &&
Paul Mackerras3ed31a82008-04-26 06:00:001444 $vfilelimit($view) ne {}} {
Paul Mackerrasf806f0f2008-02-24 01:16:561445 # git log doesn't rewrite parents for unlisted commits
1446 # when doing path limiting, so work around that here
1447 # by working out the rewritten parent with git rev-list
1448 # and if we already know about it, using the rewritten
1449 # parent as a substitute parent for $id's children.
1450 if {![catch {
1451 set rwid [exec git rev-list --first-parent --max-count=1 \
Paul Mackerras3ed31a82008-04-26 06:00:001452 $id -- $vfilelimit($view)]
Paul Mackerrasf806f0f2008-02-24 01:16:561453 }]} {
1454 if {$rwid ne {} && [info exists varcid($view,$rwid)]} {
1455 # use $rwid in place of $id
1456 rewrite_commit $view $id $rwid
1457 continue
1458 }
1459 }
1460 }
1461
Paul Mackerrasf1bf4ee2008-02-16 06:47:311462 set a 0
1463 if {[info exists varcid($vid)]} {
1464 if {$cmitlisted($vid) || !$listed} continue
1465 set a $varcid($vid)
1466 }
Paul Mackerras16c1ff92006-03-30 07:43:511467 if {$listed} {
1468 set olds [lrange $ids 1 end]
Paul Mackerras16c1ff92006-03-30 07:43:511469 } else {
1470 set olds {}
1471 }
Paul Mackerrasf7a3e8d2006-03-17 23:04:481472 set commitdata($id) [string range $cmit [expr {$j + 1}] end]
Paul Mackerras7fcc92b2007-12-02 23:33:011473 set cmitlisted($vid) $listed
1474 set parents($vid) $olds
Paul Mackerras7fcc92b2007-12-02 23:33:011475 if {![info exists children($vid)]} {
1476 set children($vid) {}
Paul Mackerrasf1bf4ee2008-02-16 06:47:311477 } elseif {$a == 0 && [llength $children($vid)] == 1} {
Paul Mackerrasf3ea5ed2007-12-19 23:03:351478 set k [lindex $children($vid) 0]
1479 if {[llength $parents($view,$k)] == 1 &&
Paul Mackerras3ed31a82008-04-26 06:00:001480 (!$vdatemode($view) ||
Paul Mackerrasf3ea5ed2007-12-19 23:03:351481 $varcid($view,$k) == [llength $varctok($view)] - 1)} {
1482 set a $varcid($view,$k)
Paul Mackerras7fcc92b2007-12-02 23:33:011483 }
Paul Mackerrasda7c24d2006-05-02 01:15:291484 }
Paul Mackerras7fcc92b2007-12-02 23:33:011485 if {$a == 0} {
1486 # new arc
1487 set a [newvarc $view $id]
1488 }
Paul Mackerrase5b37ac2007-12-12 07:13:511489 if {[string compare [lindex $varctok($view) $a] $vtokmod($view)] < 0} {
1490 modify_arc $view $a
1491 }
Paul Mackerrasf1bf4ee2008-02-16 06:47:311492 if {![info exists varcid($vid)]} {
1493 set varcid($vid) $a
1494 lappend varccommits($view,$a) $id
1495 incr commitidx($view)
1496 }
Paul Mackerrase5b37ac2007-12-12 07:13:511497
Paul Mackerras7fcc92b2007-12-02 23:33:011498 set i 0
1499 foreach p $olds {
1500 if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
1501 set vp $view,$p
1502 if {[llength [lappend children($vp) $id]] > 1 &&
1503 [vtokcmp $view [lindex $children($vp) end-1] $id] > 0} {
1504 set children($vp) [lsort -command [list vtokcmp $view] \
1505 $children($vp)]
Paul Mackerras9257d8f2007-12-10 23:45:381506 catch {unset ordertok}
Paul Mackerras7fcc92b2007-12-02 23:33:011507 }
Paul Mackerrasf3ea5ed2007-12-19 23:03:351508 if {[info exists varcid($view,$p)]} {
1509 fix_reversal $p $a $view
1510 }
Paul Mackerras7fcc92b2007-12-02 23:33:011511 }
1512 incr i
1513 }
Paul Mackerras7fcc92b2007-12-02 23:33:011514
Paul Mackerrasd375ef92008-10-20 23:18:121515 set scripts [check_interest $id $scripts]
Paul Mackerras8f7d0ce2006-02-28 11:10:191516 set gotsome 1
Paul Mackerras9f1afe02006-02-19 11:44:471517 }
Paul Mackerras8f7d0ce2006-02-28 11:10:191518 if {$gotsome} {
Paul Mackerrasac1276a2008-03-02 23:11:081519 global numcommits hlview
1520
1521 if {$view == $curview} {
1522 set numcommits $commitidx($view)
1523 run chewcommits
1524 }
1525 if {[info exists hlview] && $view == $hlview} {
1526 # we never actually get here...
1527 run vhighlightmore
1528 }
Paul Mackerras7fcc92b2007-12-02 23:33:011529 foreach s $scripts {
1530 eval $s
1531 }
Paul Mackerras8f7d0ce2006-02-28 11:10:191532 }
Paul Mackerras7eb3cb92007-06-17 04:45:001533 return 2
Paul Mackerrascfb45632005-05-31 12:14:421534}
1535
Paul Mackerrasac1276a2008-03-02 23:11:081536proc chewcommits {} {
Paul Mackerrasf5f3c2e2007-09-04 16:19:561537 global curview hlview viewcomplete
Paul Mackerras7fcc92b2007-12-02 23:33:011538 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:231539
Paul Mackerrasac1276a2008-03-02 23:11:081540 layoutmore
1541 if {$viewcomplete($curview)} {
1542 global commitidx varctok
1543 global numcommits startmsecs
Paul Mackerras7eb3cb92007-06-17 04:45:001544
Paul Mackerrasac1276a2008-03-02 23:11:081545 if {[info exists pending_select]} {
Alexander Gavrilov835e62a2008-07-26 16:15:541546 update
1547 reset_pending_select {}
1548
1549 if {[commitinview $pending_select $curview]} {
1550 selectline [rowofcommit $pending_select] 1
1551 } else {
1552 set row [first_real_row]
1553 selectline $row 1
1554 }
Paul Mackerras7eb3cb92007-06-17 04:45:001555 }
Paul Mackerrasac1276a2008-03-02 23:11:081556 if {$commitidx($curview) > 0} {
1557 #set ms [expr {[clock clicks -milliseconds] - $startmsecs}]
1558 #puts "overall $ms ms for $numcommits commits"
1559 #puts "[llength $varctok($view)] arcs, $commitidx($view) commits"
1560 } else {
1561 show_status [mc "No commits selected"]
1562 }
1563 notbusy layout
Paul Mackerrasb6645502005-08-10 23:56:231564 }
Paul Mackerrasf5f3c2e2007-09-04 16:19:561565 return 0
Paul Mackerras1db95b02005-05-09 04:08:391566}
1567
Alexander Gavrilov590915d2008-11-09 15:06:071568proc do_readcommit {id} {
1569 global tclencoding
1570
1571 # Invoke git-log to handle automatic encoding conversion
1572 set fd [open [concat | git log --no-color --pretty=raw -1 $id] r]
1573 # Read the results using i18n.logoutputencoding
1574 fconfigure $fd -translation lf -eofchar {}
1575 if {$tclencoding != {}} {
1576 fconfigure $fd -encoding $tclencoding
1577 }
1578 set contents [read $fd]
1579 close $fd
1580 # Remove the heading line
1581 regsub {^commit [0-9a-f]+\n} $contents {} contents
1582
1583 return $contents
1584}
1585
Paul Mackerras1db95b02005-05-09 04:08:391586proc readcommit {id} {
Alexander Gavrilov590915d2008-11-09 15:06:071587 if {[catch {set contents [do_readcommit $id]}]} return
1588 parsecommit $id $contents 1
Paul Mackerrasb490a992005-06-22 00:25:381589}
1590
Paul Mackerras8f7d0ce2006-02-28 11:10:191591proc parsecommit {id contents listed} {
Sven Verdoolaegeb5c2f302005-11-29 21:15:511592 global commitinfo cdate
1593
1594 set inhdr 1
1595 set comment {}
1596 set headline {}
1597 set auname {}
1598 set audate {}
1599 set comname {}
1600 set comdate {}
Paul Mackerras232475d2005-11-14 23:34:031601 set hdrend [string first "\n\n" $contents]
1602 if {$hdrend < 0} {
1603 # should never happen...
1604 set hdrend [string length $contents]
1605 }
1606 set header [string range $contents 0 [expr {$hdrend - 1}]]
1607 set comment [string range $contents [expr {$hdrend + 2}] end]
1608 foreach line [split $header "\n"] {
Kevin Ballard61f57cb2008-12-18 09:26:481609 set line [split $line " "]
Paul Mackerras232475d2005-11-14 23:34:031610 set tag [lindex $line 0]
1611 if {$tag == "author"} {
1612 set audate [lindex $line end-1]
Kevin Ballard61f57cb2008-12-18 09:26:481613 set auname [join [lrange $line 1 end-2] " "]
Paul Mackerras232475d2005-11-14 23:34:031614 } elseif {$tag == "committer"} {
1615 set comdate [lindex $line end-1]
Kevin Ballard61f57cb2008-12-18 09:26:481616 set comname [join [lrange $line 1 end-2] " "]
Paul Mackerras1db95b02005-05-09 04:08:391617 }
1618 }
Paul Mackerras232475d2005-11-14 23:34:031619 set headline {}
Paul Mackerras43c25072006-09-27 00:56:021620 # take the first non-blank line of the comment as the headline
1621 set headline [string trimleft $comment]
1622 set i [string first "\n" $headline]
Paul Mackerras232475d2005-11-14 23:34:031623 if {$i >= 0} {
Paul Mackerras43c25072006-09-27 00:56:021624 set headline [string range $headline 0 $i]
1625 }
1626 set headline [string trimright $headline]
1627 set i [string first "\r" $headline]
1628 if {$i >= 0} {
1629 set headline [string trimright [string range $headline 0 $i]]
Paul Mackerras232475d2005-11-14 23:34:031630 }
1631 if {!$listed} {
Paul Mackerrasf9e0b6f2008-03-04 10:14:171632 # git log indents the comment by 4 spaces;
Timo Hirvonen8974c6f2006-05-24 07:57:401633 # if we got this via git cat-file, add the indentation
Paul Mackerras232475d2005-11-14 23:34:031634 set newcomment {}
1635 foreach line [split $comment "\n"] {
1636 append newcomment " "
1637 append newcomment $line
Paul Mackerrasf6e28692005-11-20 12:08:221638 append newcomment "\n"
Paul Mackerras232475d2005-11-14 23:34:031639 }
1640 set comment $newcomment
Paul Mackerras1db95b02005-05-09 04:08:391641 }
1642 if {$comdate != {}} {
Paul Mackerrascfb45632005-05-31 12:14:421643 set cdate($id) $comdate
Paul Mackerras1db95b02005-05-09 04:08:391644 }
Paul Mackerrase5c2d852005-05-11 23:44:541645 set commitinfo($id) [list $headline $auname $audate \
1646 $comname $comdate $comment]
Paul Mackerras1db95b02005-05-09 04:08:391647}
1648
Paul Mackerrasf7a3e8d2006-03-17 23:04:481649proc getcommit {id} {
Paul Mackerras79b2c752006-04-02 10:47:401650 global commitdata commitinfo
Paul Mackerras8ed16482006-03-02 11:56:441651
Paul Mackerrasf7a3e8d2006-03-17 23:04:481652 if {[info exists commitdata($id)]} {
1653 parsecommit $id $commitdata($id) 1
Paul Mackerras8ed16482006-03-02 11:56:441654 } else {
1655 readcommit $id
1656 if {![info exists commitinfo($id)]} {
Christian Stimmingd990ced2007-11-07 17:42:551657 set commitinfo($id) [list [mc "No commit information available"]]
Paul Mackerras8ed16482006-03-02 11:56:441658 }
1659 }
1660 return 1
1661}
1662
Paul Mackerrasd375ef92008-10-20 23:18:121663# Expand an abbreviated commit ID to a list of full 40-char IDs that match
1664# and are present in the current view.
1665# This is fairly slow...
1666proc longid {prefix} {
1667 global varcid curview
1668
1669 set ids {}
1670 foreach match [array names varcid "$curview,$prefix*"] {
1671 lappend ids [lindex [split $match ","] 1]
1672 }
1673 return $ids
1674}
1675
Paul Mackerras887fe3c2005-05-21 07:35:371676proc readrefs {} {
Paul Mackerras62d3ea62006-09-11 00:36:531677 global tagids idtags headids idheads tagobjid
Paul Mackerras219ea3a2006-09-07 00:21:391678 global otherrefids idotherrefs mainhead mainheadid
Alexander Gavrilov39816d62008-08-23 08:27:441679 global selecthead selectheadid
Paul Mackerrasf1d83ba2005-08-19 12:14:281680
Sven Verdoolaegeb5c2f302005-11-29 21:15:511681 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
1682 catch {unset $v}
1683 }
Paul Mackerras62d3ea62006-09-11 00:36:531684 set refd [open [list | git show-ref -d] r]
1685 while {[gets $refd line] >= 0} {
1686 if {[string index $line 40] ne " "} continue
1687 set id [string range $line 0 39]
1688 set ref [string range $line 41 end]
1689 if {![string match "refs/*" $ref]} continue
1690 set name [string range $ref 5 end]
1691 if {[string match "remotes/*" $name]} {
1692 if {![string match "*/HEAD" $name]} {
1693 set headids($name) $id
1694 lappend idheads($id) $name
Paul Mackerrasf1d83ba2005-08-19 12:14:281695 }
Paul Mackerras62d3ea62006-09-11 00:36:531696 } elseif {[string match "heads/*" $name]} {
1697 set name [string range $name 6 end]
Junio C Hamano36a7cad2005-11-19 07:54:171698 set headids($name) $id
1699 lappend idheads($id) $name
Paul Mackerras62d3ea62006-09-11 00:36:531700 } elseif {[string match "tags/*" $name]} {
1701 # this lets refs/tags/foo^{} overwrite refs/tags/foo,
1702 # which is what we want since the former is the commit ID
1703 set name [string range $name 5 end]
1704 if {[string match "*^{}" $name]} {
1705 set name [string range $name 0 end-3]
1706 } else {
1707 set tagobjid($name) $id
1708 }
1709 set tagids($name) $id
1710 lappend idtags($id) $name
Junio C Hamano36a7cad2005-11-19 07:54:171711 } else {
1712 set otherrefids($name) $id
1713 lappend idotherrefs($id) $name
Paul Mackerrasf1d83ba2005-08-19 12:14:281714 }
1715 }
Alex Riesen062d6712007-07-29 20:28:401716 catch {close $refd}
Paul Mackerras8a485712006-07-06 00:21:231717 set mainhead {}
Paul Mackerras219ea3a2006-09-07 00:21:391718 set mainheadid {}
Paul Mackerras8a485712006-07-06 00:21:231719 catch {
Paul Mackerrasc11ff122008-05-26 00:11:331720 set mainheadid [exec git rev-parse HEAD]
Paul Mackerras8a485712006-07-06 00:21:231721 set thehead [exec git symbolic-ref HEAD]
1722 if {[string match "refs/heads/*" $thehead]} {
1723 set mainhead [string range $thehead 11 end]
Paul Mackerras8a485712006-07-06 00:21:231724 }
1725 }
Alexander Gavrilov39816d62008-08-23 08:27:441726 set selectheadid {}
1727 if {$selecthead ne {}} {
1728 catch {
1729 set selectheadid [exec git rev-parse --verify $selecthead]
1730 }
1731 }
Paul Mackerras887fe3c2005-05-21 07:35:371732}
1733
Paul Mackerras8f489362007-07-13 09:49:371734# skip over fake commits
1735proc first_real_row {} {
Paul Mackerras7fcc92b2007-12-02 23:33:011736 global nullid nullid2 numcommits
Paul Mackerras8f489362007-07-13 09:49:371737
1738 for {set row 0} {$row < $numcommits} {incr row} {
Paul Mackerras7fcc92b2007-12-02 23:33:011739 set id [commitonrow $row]
Paul Mackerras8f489362007-07-13 09:49:371740 if {$id ne $nullid && $id ne $nullid2} {
1741 break
1742 }
1743 }
1744 return $row
1745}
1746
Paul Mackerrase11f1232007-06-16 10:29:251747# update things for a head moved to a child of its previous location
1748proc movehead {id name} {
1749 global headids idheads
1750
1751 removehead $headids($name) $name
1752 set headids($name) $id
1753 lappend idheads($id) $name
1754}
1755
1756# update things when a head has been removed
1757proc removehead {id name} {
1758 global headids idheads
1759
1760 if {$idheads($id) eq $name} {
1761 unset idheads($id)
1762 } else {
1763 set i [lsearch -exact $idheads($id) $name]
1764 if {$i >= 0} {
1765 set idheads($id) [lreplace $idheads($id) $i $i]
1766 }
1767 }
1768 unset headids($name)
1769}
1770
Alexander Gavrilove7d64002008-11-11 20:55:421771proc make_transient {window origin} {
1772 global have_tk85
1773
1774 # In MacOS Tk 8.4 transient appears to work by setting
1775 # overrideredirect, which is utterly useless, since the
1776 # windows get no border, and are not even kept above
1777 # the parent.
1778 if {!$have_tk85 && [tk windowingsystem] eq {aqua}} return
1779
1780 wm transient $window $origin
1781
1782 # Windows fails to place transient windows normally, so
1783 # schedule a callback to center them on the parent.
1784 if {[tk windowingsystem] eq {win32}} {
1785 after idle [list tk::PlaceWindow $window widget $origin]
1786 }
1787}
1788
Paul Mackerrase54be9e2006-05-26 12:34:301789proc show_error {w top msg} {
Paul Mackerrasdf3d83b2005-05-17 23:23:071790 message $w.m -text $msg -justify center -aspect 400
1791 pack $w.m -side top -fill x -padx 20 -pady 20
Christian Stimmingd990ced2007-11-07 17:42:551792 button $w.ok -text [mc OK] -command "destroy $top"
Paul Mackerrasdf3d83b2005-05-17 23:23:071793 pack $w.ok -side bottom -fill x
Paul Mackerrase54be9e2006-05-26 12:34:301794 bind $top <Visibility> "grab $top; focus $top"
1795 bind $top <Key-Return> "destroy $top"
Alexander Gavrilov76f15942008-11-02 18:59:441796 bind $top <Key-space> "destroy $top"
1797 bind $top <Key-Escape> "destroy $top"
Paul Mackerrase54be9e2006-05-26 12:34:301798 tkwait window $top
Paul Mackerrasdf3d83b2005-05-17 23:23:071799}
1800
Alexander Gavrilov84a76f12008-11-02 18:59:451801proc error_popup {msg {owner .}} {
Paul Mackerras098dd8a2006-05-02 23:32:531802 set w .error
1803 toplevel $w
Alexander Gavrilove7d64002008-11-11 20:55:421804 make_transient $w $owner
Paul Mackerrase54be9e2006-05-26 12:34:301805 show_error $w $w $msg
Paul Mackerras098dd8a2006-05-02 23:32:531806}
1807
Alexander Gavrilov84a76f12008-11-02 18:59:451808proc confirm_popup {msg {owner .}} {
Paul Mackerras10299152006-08-01 23:52:011809 global confirm_ok
1810 set confirm_ok 0
1811 set w .confirm
1812 toplevel $w
Alexander Gavrilove7d64002008-11-11 20:55:421813 make_transient $w $owner
Paul Mackerras10299152006-08-01 23:52:011814 message $w.m -text $msg -justify center -aspect 400
1815 pack $w.m -side top -fill x -padx 20 -pady 20
Christian Stimmingd990ced2007-11-07 17:42:551816 button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
Paul Mackerras10299152006-08-01 23:52:011817 pack $w.ok -side left -fill x
Christian Stimmingd990ced2007-11-07 17:42:551818 button $w.cancel -text [mc Cancel] -command "destroy $w"
Paul Mackerras10299152006-08-01 23:52:011819 pack $w.cancel -side right -fill x
1820 bind $w <Visibility> "grab $w; focus $w"
Alexander Gavrilov76f15942008-11-02 18:59:441821 bind $w <Key-Return> "set confirm_ok 1; destroy $w"
1822 bind $w <Key-space> "set confirm_ok 1; destroy $w"
1823 bind $w <Key-Escape> "destroy $w"
Paul Mackerras10299152006-08-01 23:52:011824 tkwait window $w
1825 return $confirm_ok
1826}
1827
Paul Mackerrasb039f0a2008-01-06 04:54:461828proc setoptions {} {
1829 option add *Panedwindow.showHandle 1 startupFile
1830 option add *Panedwindow.sashRelief raised startupFile
1831 option add *Button.font uifont startupFile
1832 option add *Checkbutton.font uifont startupFile
1833 option add *Radiobutton.font uifont startupFile
Daniel A. Steffen5fdcbb12009-03-23 11:17:381834 if {[tk windowingsystem] ne "aqua"} {
1835 option add *Menu.font uifont startupFile
1836 }
Paul Mackerrasb039f0a2008-01-06 04:54:461837 option add *Menubutton.font uifont startupFile
1838 option add *Label.font uifont startupFile
1839 option add *Message.font uifont startupFile
1840 option add *Entry.font uifont startupFile
1841}
1842
Paul Mackerras79056032008-10-18 05:24:461843# Make a menu and submenus.
1844# m is the window name for the menu, items is the list of menu items to add.
1845# Each item is a list {mc label type description options...}
1846# mc is ignored; it's so we can put mc there to alert xgettext
1847# label is the string that appears in the menu
1848# type is cascade, command or radiobutton (should add checkbutton)
1849# description depends on type; it's the sublist for cascade, the
1850# command to invoke for command, or {variable value} for radiobutton
Paul Mackerrasf2d0bbb2008-10-17 11:44:421851proc makemenu {m items} {
1852 menu $m
Alexander Gavrilovcea07cf2008-11-09 10:00:451853 if {[tk windowingsystem] eq {aqua}} {
1854 set Meta1 Cmd
1855 } else {
1856 set Meta1 Ctrl
1857 }
Paul Mackerrasf2d0bbb2008-10-17 11:44:421858 foreach i $items {
Paul Mackerras79056032008-10-18 05:24:461859 set name [mc [lindex $i 1]]
1860 set type [lindex $i 2]
1861 set thing [lindex $i 3]
Paul Mackerrasf2d0bbb2008-10-17 11:44:421862 set params [list $type]
1863 if {$name ne {}} {
1864 set u [string first "&" [string map {&& x} $name]]
1865 lappend params -label [string map {&& & & {}} $name]
1866 if {$u >= 0} {
1867 lappend params -underline $u
1868 }
1869 }
1870 switch -- $type {
1871 "cascade" {
Paul Mackerras79056032008-10-18 05:24:461872 set submenu [string tolower [string map {& ""} [lindex $i 1]]]
Paul Mackerrasf2d0bbb2008-10-17 11:44:421873 lappend params -menu $m.$submenu
1874 }
1875 "command" {
1876 lappend params -command $thing
1877 }
1878 "radiobutton" {
1879 lappend params -variable [lindex $thing 0] \
1880 -value [lindex $thing 1]
1881 }
1882 }
Alexander Gavrilovcea07cf2008-11-09 10:00:451883 set tail [lrange $i 4 end]
1884 regsub -all {\yMeta1\y} $tail $Meta1 tail
1885 eval $m add $params $tail
Paul Mackerrasf2d0bbb2008-10-17 11:44:421886 if {$type eq "cascade"} {
1887 makemenu $m.$submenu $thing
1888 }
1889 }
1890}
1891
1892# translate string and remove ampersands
1893proc mca {str} {
1894 return [string map {&& & & {}} [mc $str]]
1895}
1896
Paul Mackerrasd94f8cd2006-04-06 00:18:231897proc makewindow {} {
Paul Mackerras31c0eaa2007-12-30 11:41:141898 global canv canv2 canv3 linespc charspc ctext cflist cscroll
Paul Mackerras9c311b32007-10-04 12:27:131899 global tabstop
Paul Mackerrasb74fd572005-07-16 11:46:131900 global findtype findtypemenu findloc findstring fstring geometry
Paul Mackerras887fe3c2005-05-21 07:35:371901 global entries sha1entry sha1string sha1but
Steffen Prohaska890fae72007-08-12 10:05:461902 global diffcontextstring diffcontext
Steffen Prohaskab9b86002008-01-17 22:42:551903 global ignorespace
Paul Mackerras94a2eed2005-08-07 05:27:571904 global maincursor textcursor curtextcursor
Paul Mackerras219ea3a2006-09-07 00:21:391905 global rowctxmenu fakerowmenu mergemax wrapcomment
Paul Mackerras60f7a7d2006-05-26 00:43:471906 global highlight_files gdttype
Paul Mackerras3ea06f92006-05-24 00:16:031907 global searchstring sstring
Mark Levedahl60378c02007-05-20 16:12:481908 global bgcolor fgcolor bglist fglist diffcolors selectbgcolor
Paul Mackerrasbb3edc82007-09-27 01:00:251909 global headctxmenu progresscanv progressitem progresscoords statusw
1910 global fprogitem fprogcoord lastprogupdate progupdatepending
Paul Mackerras6df74032008-05-11 12:13:021911 global rprogitem rprogcoord rownumsel numcommits
Paul Mackerras32f1b3e2007-09-28 11:27:391912 global have_tk85
Paul Mackerras9a40c502005-05-12 23:46:161913
Paul Mackerras79056032008-10-18 05:24:461914 # The "mc" arguments here are purely so that xgettext
1915 # sees the following string as needing to be translated
Daniel A. Steffen5fdcbb12009-03-23 11:17:381916 set file {
1917 mc "File" cascade {
Paul Mackerras79056032008-10-18 05:24:461918 {mc "Update" command updatecommits -accelerator F5}
Alexander Gavrilovcea07cf2008-11-09 10:00:451919 {mc "Reload" command reloadcommits -accelerator Meta1-F5}
Paul Mackerras79056032008-10-18 05:24:461920 {mc "Reread references" command rereadrefs}
Alexander Gavrilovcea07cf2008-11-09 10:00:451921 {mc "List references" command showrefs -accelerator F2}
Alexander Gavrilov7fb0abb2008-11-13 20:12:421922 {xx "" separator}
1923 {mc "Start git gui" command {exec git gui &}}
1924 {xx "" separator}
Alexander Gavrilovcea07cf2008-11-09 10:00:451925 {mc "Quit" command doquit -accelerator Meta1-Q}
Paul Mackerrasf2d0bbb2008-10-17 11:44:421926 }}
Daniel A. Steffen5fdcbb12009-03-23 11:17:381927 set edit {
1928 mc "Edit" cascade {
Paul Mackerras79056032008-10-18 05:24:461929 {mc "Preferences" command doprefs}
Paul Mackerrasf2d0bbb2008-10-17 11:44:421930 }}
Daniel A. Steffen5fdcbb12009-03-23 11:17:381931 set view {
1932 mc "View" cascade {
Alexander Gavrilovcea07cf2008-11-09 10:00:451933 {mc "New view..." command {newview 0} -accelerator Shift-F4}
1934 {mc "Edit view..." command editview -state disabled -accelerator F4}
Paul Mackerras79056032008-10-18 05:24:461935 {mc "Delete view" command delview -state disabled}
1936 {xx "" separator}
1937 {mc "All files" radiobutton {selectedview 0} -command {showview 0}}
Paul Mackerrasf2d0bbb2008-10-17 11:44:421938 }}
Daniel A. Steffen5fdcbb12009-03-23 11:17:381939 if {[tk windowingsystem] ne "aqua"} {
1940 set help {
1941 mc "Help" cascade {
Paul Mackerras79056032008-10-18 05:24:461942 {mc "About gitk" command about}
1943 {mc "Key bindings" command keys}
Paul Mackerrasf2d0bbb2008-10-17 11:44:421944 }}
Daniel A. Steffen5fdcbb12009-03-23 11:17:381945 set bar [list $file $edit $view $help]
1946 } else {
1947 proc ::tk::mac::ShowPreferences {} {doprefs}
1948 proc ::tk::mac::Quit {} {doquit}
1949 lset file end [lreplace [lindex $file end] end-1 end]
1950 set apple {
1951 xx "Apple" cascade {
1952 {mc "About gitk" command about}
1953 {xx "" separator}
1954 }}
1955 set help {
1956 mc "Help" cascade {
1957 {mc "Key bindings" command keys}
1958 }}
1959 set bar [list $apple $file $view $help]
Paul Mackerrasf2d0bbb2008-10-17 11:44:421960 }
Daniel A. Steffen5fdcbb12009-03-23 11:17:381961 makemenu .bar $bar
Paul Mackerras9a40c502005-05-12 23:46:161962 . configure -menu .bar
1963
Junio C Hamanoe9937d22007-02-01 13:46:381964 # the gui has upper and lower half, parts of a paned window.
Paul Mackerras0327d272005-05-10 00:23:421965 panedwindow .ctop -orient vertical
Junio C Hamanoe9937d22007-02-01 13:46:381966
1967 # possibly use assumed geometry
Mark Levedahl9ca72f42007-02-13 00:19:341968 if {![info exists geometry(pwsash0)]} {
Junio C Hamanoe9937d22007-02-01 13:46:381969 set geometry(topheight) [expr {15 * $linespc}]
1970 set geometry(topwidth) [expr {80 * $charspc}]
1971 set geometry(botheight) [expr {15 * $linespc}]
1972 set geometry(botwidth) [expr {50 * $charspc}]
Mark Levedahl9ca72f42007-02-13 00:19:341973 set geometry(pwsash0) "[expr {40 * $charspc}] 2"
1974 set geometry(pwsash1) "[expr {60 * $charspc}] 2"
Paul Mackerras0fba86b2005-05-16 23:54:581975 }
Junio C Hamanoe9937d22007-02-01 13:46:381976
1977 # the upper half will have a paned window, a scroll bar to the right, and some stuff below
1978 frame .tf -height $geometry(topheight) -width $geometry(topwidth)
1979 frame .tf.histframe
1980 panedwindow .tf.histframe.pwclist -orient horizontal -sashpad 0 -handlesize 4
1981
1982 # create three canvases
1983 set cscroll .tf.histframe.csb
1984 set canv .tf.histframe.pwclist.canv
Mark Levedahl9ca72f42007-02-13 00:19:341985 canvas $canv \
Mark Levedahl60378c02007-05-20 16:12:481986 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 12:56:371987 -background $bgcolor -bd 0 \
Paul Mackerras9f1afe02006-02-19 11:44:471988 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
Junio C Hamanoe9937d22007-02-01 13:46:381989 .tf.histframe.pwclist add $canv
1990 set canv2 .tf.histframe.pwclist.canv2
Mark Levedahl9ca72f42007-02-13 00:19:341991 canvas $canv2 \
Mark Levedahl60378c02007-05-20 16:12:481992 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 12:56:371993 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 13:46:381994 .tf.histframe.pwclist add $canv2
1995 set canv3 .tf.histframe.pwclist.canv3
Mark Levedahl9ca72f42007-02-13 00:19:341996 canvas $canv3 \
Mark Levedahl60378c02007-05-20 16:12:481997 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 12:56:371998 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 13:46:381999 .tf.histframe.pwclist add $canv3
Mark Levedahl9ca72f42007-02-13 00:19:342000 eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
2001 eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
Paul Mackerras98f350e2005-05-15 05:56:512002
Junio C Hamanoe9937d22007-02-01 13:46:382003 # a scroll bar to rule them
2004 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
2005 pack $cscroll -side right -fill y
2006 bind .tf.histframe.pwclist <Configure> {resizeclistpanes %W %w}
2007 lappend bglist $canv $canv2 $canv3
2008 pack .tf.histframe.pwclist -fill both -expand 1 -side left
2009
2010 # we have two button bars at bottom of top frame. Bar 1
2011 frame .tf.bar
2012 frame .tf.lbar -height 15
2013
2014 set sha1entry .tf.bar.sha1
Paul Mackerras887fe3c2005-05-21 07:35:372015 set entries $sha1entry
Junio C Hamanoe9937d22007-02-01 13:46:382016 set sha1but .tf.bar.sha1label
Christian Stimmingd990ced2007-11-07 17:42:552017 button $sha1but -text [mc "SHA1 ID: "] -state disabled -relief flat \
Paul Mackerrasb039f0a2008-01-06 04:54:462018 -command gotocommit -width 8
Paul Mackerras887fe3c2005-05-21 07:35:372019 $sha1but conf -disabledforeground [$sha1but cget -foreground]
Junio C Hamanoe9937d22007-02-01 13:46:382020 pack .tf.bar.sha1label -side left
Paul Mackerras9c311b32007-10-04 12:27:132021 entry $sha1entry -width 40 -font textfont -textvariable sha1string
Paul Mackerras887fe3c2005-05-21 07:35:372022 trace add variable sha1string write sha1change
Paul Mackerras98f350e2005-05-15 05:56:512023 pack $sha1entry -side left -pady 2
Paul Mackerrasd6982062005-08-06 12:06:062024
2025 image create bitmap bm-left -data {
2026 #define left_width 16
2027 #define left_height 16
2028 static unsigned char left_bits[] = {
2029 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
2030 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
2031 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
2032 }
2033 image create bitmap bm-right -data {
2034 #define right_width 16
2035 #define right_height 16
2036 static unsigned char right_bits[] = {
2037 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
2038 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
2039 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
2040 }
Junio C Hamanoe9937d22007-02-01 13:46:382041 button .tf.bar.leftbut -image bm-left -command goback \
Paul Mackerrasd6982062005-08-06 12:06:062042 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 13:46:382043 pack .tf.bar.leftbut -side left -fill y
2044 button .tf.bar.rightbut -image bm-right -command goforw \
Paul Mackerrasd6982062005-08-06 12:06:062045 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 13:46:382046 pack .tf.bar.rightbut -side left -fill y
Paul Mackerrasd6982062005-08-06 12:06:062047
Paul Mackerras6df74032008-05-11 12:13:022048 label .tf.bar.rowlabel -text [mc "Row"]
2049 set rownumsel {}
2050 label .tf.bar.rownum -width 7 -font textfont -textvariable rownumsel \
2051 -relief sunken -anchor e
2052 label .tf.bar.rowlabel2 -text "/"
2053 label .tf.bar.numcommits -width 7 -font textfont -textvariable numcommits \
2054 -relief sunken -anchor e
2055 pack .tf.bar.rowlabel .tf.bar.rownum .tf.bar.rowlabel2 .tf.bar.numcommits \
2056 -side left
2057 global selectedline
Paul Mackerras94b4a692008-05-20 10:51:062058 trace add variable selectedline write selectedline_change
Paul Mackerras6df74032008-05-11 12:13:022059
Paul Mackerrasbb3edc82007-09-27 01:00:252060 # Status label and progress bar
2061 set statusw .tf.bar.status
Paul Mackerrasb039f0a2008-01-06 04:54:462062 label $statusw -width 15 -relief sunken
Paul Mackerrasbb3edc82007-09-27 01:00:252063 pack $statusw -side left -padx 5
Paul Mackerras9c311b32007-10-04 12:27:132064 set h [expr {[font metrics uifont -linespace] + 2}]
Paul Mackerrasbb3edc82007-09-27 01:00:252065 set progresscanv .tf.bar.progress
2066 canvas $progresscanv -relief sunken -height $h -borderwidth 2
2067 set progressitem [$progresscanv create rect -1 0 0 $h -fill green]
2068 set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
Paul Mackerrasa137a902007-10-23 11:12:492069 set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
Paul Mackerrasbb3edc82007-09-27 01:00:252070 pack $progresscanv -side right -expand 1 -fill x
2071 set progresscoords {0 0}
2072 set fprogcoord 0
Paul Mackerrasa137a902007-10-23 11:12:492073 set rprogcoord 0
Paul Mackerrasbb3edc82007-09-27 01:00:252074 bind $progresscanv <Configure> adjustprogress
2075 set lastprogupdate [clock clicks -milliseconds]
2076 set progupdatepending 0
Paul Mackerrasb5721c72005-05-10 12:08:222077
Junio C Hamanoe9937d22007-02-01 13:46:382078 # build up the bottom bar of upper window
Paul Mackerrasb039f0a2008-01-06 04:54:462079 label .tf.lbar.flabel -text "[mc "Find"] "
2080 button .tf.lbar.fnext -text [mc "next"] -command {dofind 1 1}
2081 button .tf.lbar.fprev -text [mc "prev"] -command {dofind -1 1}
2082 label .tf.lbar.flab2 -text " [mc "commit"] "
Paul Mackerras687c8762007-09-22 02:49:332083 pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \
2084 -side left -fill y
Christian Stimmingb007ee22007-11-07 17:44:352085 set gdttype [mc "containing:"]
Paul Mackerras687c8762007-09-22 02:49:332086 set gm [tk_optionMenu .tf.lbar.gdttype gdttype \
Christian Stimmingb007ee22007-11-07 17:44:352087 [mc "containing:"] \
2088 [mc "touching paths:"] \
2089 [mc "adding/removing string:"]]
Paul Mackerras687c8762007-09-22 02:49:332090 trace add variable gdttype write gdttype_change
Junio C Hamanoe9937d22007-02-01 13:46:382091 pack .tf.lbar.gdttype -side left -fill y
Paul Mackerras687c8762007-09-22 02:49:332092
2093 set findstring {}
2094 set fstring .tf.lbar.findstring
2095 lappend entries $fstring
Paul Mackerras9c311b32007-10-04 12:27:132096 entry $fstring -width 30 -font textfont -textvariable findstring
Paul Mackerras687c8762007-09-22 02:49:332097 trace add variable findstring write find_change
Christian Stimmingb007ee22007-11-07 17:44:352098 set findtype [mc "Exact"]
Paul Mackerras687c8762007-09-22 02:49:332099 set findtypemenu [tk_optionMenu .tf.lbar.findtype \
Christian Stimmingb007ee22007-11-07 17:44:352100 findtype [mc "Exact"] [mc "IgnCase"] [mc "Regexp"]]
Paul Mackerras687c8762007-09-22 02:49:332101 trace add variable findtype write findcom_change
Christian Stimmingb007ee22007-11-07 17:44:352102 set findloc [mc "All fields"]
2103 tk_optionMenu .tf.lbar.findloc findloc [mc "All fields"] [mc "Headline"] \
2104 [mc "Comments"] [mc "Author"] [mc "Committer"]
Paul Mackerras687c8762007-09-22 02:49:332105 trace add variable findloc write find_change
Paul Mackerras687c8762007-09-22 02:49:332106 pack .tf.lbar.findloc -side right
2107 pack .tf.lbar.findtype -side right
2108 pack $fstring -side left -expand 1 -fill x
Paul Mackerras908c3582006-05-19 23:38:112109
Junio C Hamanoe9937d22007-02-01 13:46:382110 # Finish putting the upper half of the viewer together
2111 pack .tf.lbar -in .tf -side bottom -fill x
2112 pack .tf.bar -in .tf -side bottom -fill x
2113 pack .tf.histframe -fill both -side top -expand 1
2114 .ctop add .tf
Mark Levedahl9ca72f42007-02-13 00:19:342115 .ctop paneconfigure .tf -height $geometry(topheight)
2116 .ctop paneconfigure .tf -width $geometry(topwidth)
Junio C Hamanoe9937d22007-02-01 13:46:382117
2118 # now build up the bottom
2119 panedwindow .pwbottom -orient horizontal
2120
2121 # lower left, a text box over search bar, scroll bar to the right
2122 # if we know window height, then that will set the lower text height, otherwise
2123 # we set lower text height which will drive window height
2124 if {[info exists geometry(main)]} {
2125 frame .bleft -width $geometry(botwidth)
2126 } else {
2127 frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
2128 }
2129 frame .bleft.top
Paul Mackerrasa8d610a2007-04-19 01:39:122130 frame .bleft.mid
Pekka Kaitaniemi8809d692008-03-08 12:27:232131 frame .bleft.bottom
Junio C Hamanoe9937d22007-02-01 13:46:382132
Paul Mackerrasb039f0a2008-01-06 04:54:462133 button .bleft.top.search -text [mc "Search"] -command dosearch
Junio C Hamanoe9937d22007-02-01 13:46:382134 pack .bleft.top.search -side left -padx 5
2135 set sstring .bleft.top.sstring
Paul Mackerras9c311b32007-10-04 12:27:132136 entry $sstring -width 20 -font textfont -textvariable searchstring
Paul Mackerras3ea06f92006-05-24 00:16:032137 lappend entries $sstring
2138 trace add variable searchstring write incrsearch
2139 pack $sstring -side left -expand 1 -fill x
Paul Mackerrasb039f0a2008-01-06 04:54:462140 radiobutton .bleft.mid.diff -text [mc "Diff"] \
Paul Mackerrasa8d610a2007-04-19 01:39:122141 -command changediffdisp -variable diffelide -value {0 0}
Paul Mackerrasb039f0a2008-01-06 04:54:462142 radiobutton .bleft.mid.old -text [mc "Old version"] \
Paul Mackerrasa8d610a2007-04-19 01:39:122143 -command changediffdisp -variable diffelide -value {0 1}
Paul Mackerrasb039f0a2008-01-06 04:54:462144 radiobutton .bleft.mid.new -text [mc "New version"] \
Paul Mackerrasa8d610a2007-04-19 01:39:122145 -command changediffdisp -variable diffelide -value {1 0}
Paul Mackerrasb039f0a2008-01-06 04:54:462146 label .bleft.mid.labeldiffcontext -text " [mc "Lines of context"]: "
Paul Mackerrasa8d610a2007-04-19 01:39:122147 pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
Paul Mackerras9c311b32007-10-04 12:27:132148 spinbox .bleft.mid.diffcontext -width 5 -font textfont \
Markus Heidelberga41ddbb2009-05-23 17:31:372149 -from 0 -increment 1 -to 10000000 \
Steffen Prohaska890fae72007-08-12 10:05:462150 -validate all -validatecommand "diffcontextvalidate %P" \
2151 -textvariable diffcontextstring
2152 .bleft.mid.diffcontext set $diffcontext
2153 trace add variable diffcontextstring write diffcontextchange
2154 lappend entries .bleft.mid.diffcontext
2155 pack .bleft.mid.labeldiffcontext .bleft.mid.diffcontext -side left
Steffen Prohaskab9b86002008-01-17 22:42:552156 checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
2157 -command changeignorespace -variable ignorespace
2158 pack .bleft.mid.ignspace -side left -padx 5
Pekka Kaitaniemi8809d692008-03-08 12:27:232159 set ctext .bleft.bottom.ctext
Paul Mackerrasf8a2c0d2006-07-05 12:56:372160 text $ctext -background $bgcolor -foreground $fgcolor \
Paul Mackerras9c311b32007-10-04 12:27:132161 -state disabled -font textfont \
Pekka Kaitaniemi8809d692008-03-08 12:27:232162 -yscrollcommand scrolltext -wrap none \
2163 -xscrollcommand ".bleft.bottom.sbhorizontal set"
Paul Mackerras32f1b3e2007-09-28 11:27:392164 if {$have_tk85} {
2165 $ctext conf -tabstyle wordprocessor
2166 }
Pekka Kaitaniemi8809d692008-03-08 12:27:232167 scrollbar .bleft.bottom.sb -command "$ctext yview"
2168 scrollbar .bleft.bottom.sbhorizontal -command "$ctext xview" -orient h \
2169 -width 10
Junio C Hamanoe9937d22007-02-01 13:46:382170 pack .bleft.top -side top -fill x
Paul Mackerrasa8d610a2007-04-19 01:39:122171 pack .bleft.mid -side top -fill x
Pekka Kaitaniemi8809d692008-03-08 12:27:232172 grid $ctext .bleft.bottom.sb -sticky nsew
2173 grid .bleft.bottom.sbhorizontal -sticky ew
2174 grid columnconfigure .bleft.bottom 0 -weight 1
2175 grid rowconfigure .bleft.bottom 0 -weight 1
2176 grid rowconfigure .bleft.bottom 1 -weight 0
2177 pack .bleft.bottom -side top -fill both -expand 1
Paul Mackerrasf8a2c0d2006-07-05 12:56:372178 lappend bglist $ctext
2179 lappend fglist $ctext
Paul Mackerrasd2610d12005-05-11 00:45:382180
Sergey Vlasovf1b86292006-05-15 15:13:142181 $ctext tag conf comment -wrap $wrapcomment
Paul Mackerras9c311b32007-10-04 12:27:132182 $ctext tag conf filesep -font textfontbold -back "#aaaaaa"
Paul Mackerrasf8a2c0d2006-07-05 12:56:372183 $ctext tag conf hunksep -fore [lindex $diffcolors 2]
2184 $ctext tag conf d0 -fore [lindex $diffcolors 0]
Paul Mackerras8b07dca2008-11-02 11:34:472185 $ctext tag conf dresult -fore [lindex $diffcolors 1]
Paul Mackerras712fcc02005-11-29 22:28:162186 $ctext tag conf m0 -fore red
2187 $ctext tag conf m1 -fore blue
2188 $ctext tag conf m2 -fore green
2189 $ctext tag conf m3 -fore purple
2190 $ctext tag conf m4 -fore brown
Paul Mackerrasb77b0272006-02-06 22:13:522191 $ctext tag conf m5 -fore "#009090"
2192 $ctext tag conf m6 -fore magenta
2193 $ctext tag conf m7 -fore "#808000"
2194 $ctext tag conf m8 -fore "#009000"
2195 $ctext tag conf m9 -fore "#ff0080"
2196 $ctext tag conf m10 -fore cyan
2197 $ctext tag conf m11 -fore "#b07070"
2198 $ctext tag conf m12 -fore "#70b0f0"
2199 $ctext tag conf m13 -fore "#70f0b0"
2200 $ctext tag conf m14 -fore "#f0b070"
2201 $ctext tag conf m15 -fore "#ff70b0"
Paul Mackerras712fcc02005-11-29 22:28:162202 $ctext tag conf mmax -fore darkgrey
Paul Mackerrasb77b0272006-02-06 22:13:522203 set mergemax 16
Paul Mackerras9c311b32007-10-04 12:27:132204 $ctext tag conf mresult -font textfontbold
2205 $ctext tag conf msep -font textfontbold
Paul Mackerras712fcc02005-11-29 22:28:162206 $ctext tag conf found -back yellow
Paul Mackerrase5c2d852005-05-11 23:44:542207
Junio C Hamanoe9937d22007-02-01 13:46:382208 .pwbottom add .bleft
Mark Levedahl9ca72f42007-02-13 00:19:342209 .pwbottom paneconfigure .bleft -width $geometry(botwidth)
Junio C Hamanoe9937d22007-02-01 13:46:382210
2211 # lower right
2212 frame .bright
2213 frame .bright.mode
Christian Stimmingd990ced2007-11-07 17:42:552214 radiobutton .bright.mode.patch -text [mc "Patch"] \
Paul Mackerrasf8b28a42006-04-30 23:50:572215 -command reselectline -variable cmitmode -value "patch"
Christian Stimmingd990ced2007-11-07 17:42:552216 radiobutton .bright.mode.tree -text [mc "Tree"] \
Paul Mackerrasf8b28a42006-04-30 23:50:572217 -command reselectline -variable cmitmode -value "tree"
Junio C Hamanoe9937d22007-02-01 13:46:382218 grid .bright.mode.patch .bright.mode.tree -sticky ew
2219 pack .bright.mode -side top -fill x
2220 set cflist .bright.cfiles
Paul Mackerras9c311b32007-10-04 12:27:132221 set indent [font measure mainfont "nn"]
Junio C Hamanoe9937d22007-02-01 13:46:382222 text $cflist \
Mark Levedahl60378c02007-05-20 16:12:482223 -selectbackground $selectbgcolor \
Paul Mackerrasf8a2c0d2006-07-05 12:56:372224 -background $bgcolor -foreground $fgcolor \
Paul Mackerras9c311b32007-10-04 12:27:132225 -font mainfont \
Paul Mackerras7fcceed2006-04-27 09:21:492226 -tabs [list $indent [expr {2 * $indent}]] \
Junio C Hamanoe9937d22007-02-01 13:46:382227 -yscrollcommand ".bright.sb set" \
Paul Mackerras7fcceed2006-04-27 09:21:492228 -cursor [. cget -cursor] \
2229 -spacing1 1 -spacing3 1
Paul Mackerrasf8a2c0d2006-07-05 12:56:372230 lappend bglist $cflist
2231 lappend fglist $cflist
Junio C Hamanoe9937d22007-02-01 13:46:382232 scrollbar .bright.sb -command "$cflist yview"
2233 pack .bright.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:382234 pack $cflist -side left -fill both -expand 1
Paul Mackerras89b11d32006-05-02 09:55:312235 $cflist tag configure highlight \
2236 -background [$cflist cget -selectbackground]
Paul Mackerras9c311b32007-10-04 12:27:132237 $cflist tag configure bold -font mainfontbold
Paul Mackerrasd2610d12005-05-11 00:45:382238
Junio C Hamanoe9937d22007-02-01 13:46:382239 .pwbottom add .bright
2240 .ctop add .pwbottom
Paul Mackerras1db95b02005-05-09 04:08:392241
Paul Mackerrasb9bee112008-03-10 05:50:342242 # restore window width & height if known
Junio C Hamanoe9937d22007-02-01 13:46:382243 if {[info exists geometry(main)]} {
Paul Mackerrasb9bee112008-03-10 05:50:342244 if {[scan $geometry(main) "%dx%d" w h] >= 2} {
2245 if {$w > [winfo screenwidth .]} {
2246 set w [winfo screenwidth .]
2247 }
2248 if {$h > [winfo screenheight .]} {
2249 set h [winfo screenheight .]
2250 }
2251 wm geometry . "${w}x$h"
2252 }
Junio C Hamanoe9937d22007-02-01 13:46:382253 }
2254
Pat Thoytsc876dba2009-04-14 21:09:532255 if {[info exists geometry(state)] && $geometry(state) eq "zoomed"} {
2256 wm state . $geometry(state)
2257 }
2258
Shawn O. Pearced23d98d2007-07-19 04:37:582259 if {[tk windowingsystem] eq {aqua}} {
2260 set M1B M1
Daniel A. Steffen5fdcbb12009-03-23 11:17:382261 set ::BM "3"
Shawn O. Pearced23d98d2007-07-19 04:37:582262 } else {
2263 set M1B Control
Daniel A. Steffen5fdcbb12009-03-23 11:17:382264 set ::BM "2"
Shawn O. Pearced23d98d2007-07-19 04:37:582265 }
2266
Junio C Hamanoe9937d22007-02-01 13:46:382267 bind .pwbottom <Configure> {resizecdetpanes %W %w}
2268 pack .ctop -fill both -expand 1
Paul Mackerrasc8dfbcf2005-06-25 05:39:212269 bindall <1> {selcanvline %W %x %y}
2270 #bindall <B1-Motion> {selcanvline %W %x %y}
Mark Levedahl314c3092007-08-08 01:40:352271 if {[tk windowingsystem] == "win32"} {
2272 bind . <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D }
2273 bind $ctext <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D ; break }
2274 } else {
2275 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
2276 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
Jonathan del Strother5dd57d52007-10-15 09:33:072277 if {[tk windowingsystem] eq "aqua"} {
2278 bindall <MouseWheel> {
2279 set delta [expr {- (%D)}]
2280 allcanvs yview scroll $delta units
2281 }
Daniel A. Steffen5fdcbb12009-03-23 11:17:382282 bindall <Shift-MouseWheel> {
2283 set delta [expr {- (%D)}]
2284 $canv xview scroll $delta units
2285 }
Jonathan del Strother5dd57d52007-10-15 09:33:072286 }
Mark Levedahl314c3092007-08-08 01:40:352287 }
Daniel A. Steffen5fdcbb12009-03-23 11:17:382288 bindall <$::BM> "canvscan mark %W %x %y"
2289 bindall <B$::BM-Motion> "canvscan dragto %W %x %y"
Rutger Nijlunsing6e5f7202006-04-05 00:24:032290 bindkey <Home> selfirstline
2291 bindkey <End> sellastline
Paul Mackerras17386062005-05-18 22:51:002292 bind . <Key-Up> "selnextline -1"
2293 bind . <Key-Down> "selnextline 1"
Paul Mackerrascca5d942007-10-27 11:16:562294 bind . <Shift-Key-Up> "dofind -1 0"
2295 bind . <Shift-Key-Down> "dofind 1 0"
Rutger Nijlunsing6e5f7202006-04-05 00:24:032296 bindkey <Key-Right> "goforw"
2297 bindkey <Key-Left> "goback"
2298 bind . <Key-Prior> "selnextpage -1"
2299 bind . <Key-Next> "selnextpage 1"
Shawn O. Pearced23d98d2007-07-19 04:37:582300 bind . <$M1B-Home> "allcanvs yview moveto 0.0"
2301 bind . <$M1B-End> "allcanvs yview moveto 1.0"
2302 bind . <$M1B-Key-Up> "allcanvs yview scroll -1 units"
2303 bind . <$M1B-Key-Down> "allcanvs yview scroll 1 units"
2304 bind . <$M1B-Key-Prior> "allcanvs yview scroll -1 pages"
2305 bind . <$M1B-Key-Next> "allcanvs yview scroll 1 pages"
Paul Mackerrascfb45632005-05-31 12:14:422306 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
2307 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
2308 bindkey <Key-space> "$ctext yview scroll 1 pages"
Paul Mackerrasdf3d83b2005-05-17 23:23:072309 bindkey p "selnextline -1"
2310 bindkey n "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 00:07:362311 bindkey z "goback"
2312 bindkey x "goforw"
2313 bindkey i "selnextline -1"
2314 bindkey k "selnextline 1"
2315 bindkey j "goback"
2316 bindkey l "goforw"
Paul Mackerrasf4c54b32008-05-10 03:15:362317 bindkey b prevfile
Paul Mackerrascfb45632005-05-31 12:14:422318 bindkey d "$ctext yview scroll 18 units"
2319 bindkey u "$ctext yview scroll -18 units"
Giuseppe Bilotta97bed032008-12-02 01:19:222320 bindkey / {focus $fstring}
Michele Ballabiob6e192d2009-03-30 12:55:212321 bindkey <Key-KP_Divide> {focus $fstring}
Paul Mackerrascca5d942007-10-27 11:16:562322 bindkey <Key-Return> {dofind 1 1}
2323 bindkey ? {dofind -1 1}
Paul Mackerras39ad8572005-05-19 12:35:532324 bindkey f nextfile
Alexander Gavrilovcea07cf2008-11-09 10:00:452325 bind . <F5> updatecommits
2326 bind . <$M1B-F5> reloadcommits
2327 bind . <F2> showrefs
2328 bind . <Shift-F4> {newview 0}
2329 catch { bind . <Shift-Key-XF86_Switch_VT_4> {newview 0} }
2330 bind . <F4> edit_or_newview
Shawn O. Pearced23d98d2007-07-19 04:37:582331 bind . <$M1B-q> doquit
Paul Mackerrascca5d942007-10-27 11:16:562332 bind . <$M1B-f> {dofind 1 1}
2333 bind . <$M1B-g> {dofind 1 0}
Shawn O. Pearced23d98d2007-07-19 04:37:582334 bind . <$M1B-r> dosearchback
2335 bind . <$M1B-s> dosearch
2336 bind . <$M1B-equal> {incrfont 1}
Johannes Schindelin646f3a12008-01-11 12:39:332337 bind . <$M1B-plus> {incrfont 1}
Shawn O. Pearced23d98d2007-07-19 04:37:582338 bind . <$M1B-KP_Add> {incrfont 1}
2339 bind . <$M1B-minus> {incrfont -1}
2340 bind . <$M1B-KP_Subtract> {incrfont -1}
Mark Levedahlb6047c52007-02-09 03:22:242341 wm protocol . WM_DELETE_WINDOW doquit
Alexander Gavrilove2f90ee2008-07-12 12:09:282342 bind . <Destroy> {stop_backends}
Paul Mackerrasdf3d83b2005-05-17 23:23:072343 bind . <Button-1> "click %W"
Paul Mackerrascca5d942007-10-27 11:16:562344 bind $fstring <Key-Return> {dofind 1 1}
Paul Mackerras968ce452008-10-15 22:57:022345 bind $sha1entry <Key-Return> {gotocommit; break}
Paul Mackerrasee3dc722005-06-25 06:37:132346 bind $sha1entry <<PasteSelection>> clearsha1
Paul Mackerras7fcceed2006-04-27 09:21:492347 bind $cflist <1> {sel_flist %W %x %y; break}
2348 bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
Paul Mackerrasf8b28a42006-04-30 23:50:572349 bind $cflist <ButtonRelease-1> {treeclick %W %x %y}
Paul Mackerrasd277e892008-09-21 23:11:372350 global ctxbut
2351 bind $cflist $ctxbut {pop_flist_menu %W %X %Y %x %y}
Alexander Gavrilov7cdc3552008-10-24 08:13:012352 bind $ctext $ctxbut {pop_diff_menu %W %X %Y %x %y}
Paul Mackerrasea13cba2005-06-16 10:54:042353
2354 set maincursor [. cget -cursor]
2355 set textcursor [$ctext cget -cursor]
Paul Mackerras94a2eed2005-08-07 05:27:572356 set curtextcursor $textcursor
Paul Mackerras84ba7342005-06-17 00:12:262357
Paul Mackerrasc8dfbcf2005-06-25 05:39:212358 set rowctxmenu .rowctxmenu
Paul Mackerrasf2d0bbb2008-10-17 11:44:422359 makemenu $rowctxmenu {
Paul Mackerras79056032008-10-18 05:24:462360 {mc "Diff this -> selected" command {diffvssel 0}}
2361 {mc "Diff selected -> this" command {diffvssel 1}}
2362 {mc "Make patch" command mkpatch}
2363 {mc "Create tag" command mktag}
2364 {mc "Write commit to file" command writecommit}
2365 {mc "Create new branch" command mkbranch}
2366 {mc "Cherry-pick this commit" command cherrypick}
2367 {mc "Reset HEAD branch to here" command resethead}
Paul Mackerrasb9fdba72009-04-08 23:34:462368 {mc "Mark this commit" command markhere}
2369 {mc "Return to mark" command gotomark}
2370 {mc "Find descendant of this and mark" command find_common_desc}
Paul Mackerras010509f2009-04-09 12:10:202371 {mc "Compare with marked commit" command compare_commits}
Paul Mackerrasf2d0bbb2008-10-17 11:44:422372 }
2373 $rowctxmenu configure -tearoff 0
Paul Mackerras10299152006-08-01 23:52:012374
Paul Mackerras219ea3a2006-09-07 00:21:392375 set fakerowmenu .fakerowmenu
Paul Mackerrasf2d0bbb2008-10-17 11:44:422376 makemenu $fakerowmenu {
Paul Mackerras79056032008-10-18 05:24:462377 {mc "Diff this -> selected" command {diffvssel 0}}
2378 {mc "Diff selected -> this" command {diffvssel 1}}
2379 {mc "Make patch" command mkpatch}
Paul Mackerrasf2d0bbb2008-10-17 11:44:422380 }
2381 $fakerowmenu configure -tearoff 0
Paul Mackerras219ea3a2006-09-07 00:21:392382
Paul Mackerras10299152006-08-01 23:52:012383 set headctxmenu .headctxmenu
Paul Mackerrasf2d0bbb2008-10-17 11:44:422384 makemenu $headctxmenu {
Paul Mackerras79056032008-10-18 05:24:462385 {mc "Check out this branch" command cobranch}
2386 {mc "Remove this branch" command rmbranch}
Paul Mackerrasf2d0bbb2008-10-17 11:44:422387 }
2388 $headctxmenu configure -tearoff 0
Paul Mackerras32447292007-07-27 12:30:152389
2390 global flist_menu
2391 set flist_menu .flistctxmenu
Paul Mackerrasf2d0bbb2008-10-17 11:44:422392 makemenu $flist_menu {
Paul Mackerras79056032008-10-18 05:24:462393 {mc "Highlight this too" command {flist_hl 0}}
2394 {mc "Highlight this only" command {flist_hl 1}}
2395 {mc "External diff" command {external_diff}}
2396 {mc "Blame parent commit" command {external_blame 1}}
Paul Mackerrasf2d0bbb2008-10-17 11:44:422397 }
2398 $flist_menu configure -tearoff 0
Alexander Gavrilov7cdc3552008-10-24 08:13:012399
2400 global diff_menu
2401 set diff_menu .diffctxmenu
2402 makemenu $diff_menu {
Paul Mackerras8a897742008-10-27 10:36:252403 {mc "Show origin of this line" command show_line_source}
Alexander Gavrilov7cdc3552008-10-24 08:13:012404 {mc "Run git gui blame on this line" command {external_blame_diff}}
2405 }
2406 $diff_menu configure -tearoff 0
Paul Mackerrasdf3d83b2005-05-17 23:23:072407}
2408
Mark Levedahl314c3092007-08-08 01:40:352409# Windows sends all mouse wheel events to the current focused window, not
2410# the one where the mouse hovers, so bind those events here and redirect
2411# to the correct window
2412proc windows_mousewheel_redirector {W X Y D} {
2413 global canv canv2 canv3
2414 set w [winfo containing -displayof $W $X $Y]
2415 if {$w ne ""} {
2416 set u [expr {$D < 0 ? 5 : -5}]
2417 if {$w == $canv || $w == $canv2 || $w == $canv3} {
2418 allcanvs yview scroll $u units
2419 } else {
2420 catch {
2421 $w yview scroll $u units
2422 }
2423 }
2424 }
2425}
2426
Paul Mackerras6df74032008-05-11 12:13:022427# Update row number label when selectedline changes
2428proc selectedline_change {n1 n2 op} {
2429 global selectedline rownumsel
2430
Paul Mackerras94b4a692008-05-20 10:51:062431 if {$selectedline eq {}} {
Paul Mackerras6df74032008-05-11 12:13:022432 set rownumsel {}
2433 } else {
2434 set rownumsel [expr {$selectedline + 1}]
2435 }
2436}
2437
Paul Mackerrasbe0cd092006-03-30 22:55:112438# mouse-2 makes all windows scan vertically, but only the one
2439# the cursor is in scans horizontally
2440proc canvscan {op w x y} {
2441 global canv canv2 canv3
2442 foreach c [list $canv $canv2 $canv3] {
2443 if {$c == $w} {
2444 $c scan $op $x $y
2445 } else {
2446 $c scan $op 0 $y
2447 }
2448 }
2449}
2450
Paul Mackerras9f1afe02006-02-19 11:44:472451proc scrollcanv {cscroll f0 f1} {
2452 $cscroll set $f0 $f1
Paul Mackerras31c0eaa2007-12-30 11:41:142453 drawvisible
Paul Mackerras908c3582006-05-19 23:38:112454 flushhighlights
Paul Mackerras9f1afe02006-02-19 11:44:472455}
2456
Paul Mackerrasdf3d83b2005-05-17 23:23:072457# when we make a key binding for the toplevel, make sure
2458# it doesn't get triggered when that key is pressed in the
2459# find string entry widget.
2460proc bindkey {ev script} {
Paul Mackerras887fe3c2005-05-21 07:35:372461 global entries
Paul Mackerrasdf3d83b2005-05-17 23:23:072462 bind . $ev $script
2463 set escript [bind Entry $ev]
2464 if {$escript == {}} {
2465 set escript [bind Entry <Key>]
2466 }
Paul Mackerras887fe3c2005-05-21 07:35:372467 foreach e $entries {
2468 bind $e $ev "$escript; break"
2469 }
Paul Mackerrasdf3d83b2005-05-17 23:23:072470}
2471
2472# set the focus back to the toplevel for any click outside
Paul Mackerras887fe3c2005-05-21 07:35:372473# the entry widgets
Paul Mackerrasdf3d83b2005-05-17 23:23:072474proc click {w} {
Mark Levedahlbd441de2007-08-08 01:40:342475 global ctext entries
2476 foreach e [concat $entries $ctext] {
Paul Mackerras887fe3c2005-05-21 07:35:372477 if {$w == $e} return
Paul Mackerrasdf3d83b2005-05-17 23:23:072478 }
Paul Mackerras887fe3c2005-05-21 07:35:372479 focus .
Paul Mackerras0fba86b2005-05-16 23:54:582480}
2481
Paul Mackerrasbb3edc82007-09-27 01:00:252482# Adjust the progress bar for a change in requested extent or canvas size
2483proc adjustprogress {} {
2484 global progresscanv progressitem progresscoords
2485 global fprogitem fprogcoord lastprogupdate progupdatepending
Paul Mackerrasa137a902007-10-23 11:12:492486 global rprogitem rprogcoord
Paul Mackerrasbb3edc82007-09-27 01:00:252487
2488 set w [expr {[winfo width $progresscanv] - 4}]
2489 set x0 [expr {$w * [lindex $progresscoords 0]}]
2490 set x1 [expr {$w * [lindex $progresscoords 1]}]
2491 set h [winfo height $progresscanv]
2492 $progresscanv coords $progressitem $x0 0 $x1 $h
2493 $progresscanv coords $fprogitem 0 0 [expr {$w * $fprogcoord}] $h
Paul Mackerrasa137a902007-10-23 11:12:492494 $progresscanv coords $rprogitem 0 0 [expr {$w * $rprogcoord}] $h
Paul Mackerrasbb3edc82007-09-27 01:00:252495 set now [clock clicks -milliseconds]
2496 if {$now >= $lastprogupdate + 100} {
2497 set progupdatepending 0
2498 update
2499 } elseif {!$progupdatepending} {
2500 set progupdatepending 1
2501 after [expr {$lastprogupdate + 100 - $now}] doprogupdate
2502 }
2503}
2504
2505proc doprogupdate {} {
2506 global lastprogupdate progupdatepending
2507
2508 if {$progupdatepending} {
2509 set progupdatepending 0
2510 set lastprogupdate [clock clicks -milliseconds]
2511 update
2512 }
2513}
2514
Paul Mackerras0fba86b2005-05-16 23:54:582515proc savestuff {w} {
Paul Mackerras32f1b3e2007-09-28 11:27:392516 global canv canv2 canv3 mainfont textfont uifont tabstop
Paul Mackerras712fcc02005-11-29 22:28:162517 global stuffsaved findmergefiles maxgraphpct
Paul Mackerras219ea3a2006-09-07 00:21:392518 global maxwidth showneartags showlocalchanges
Yann Dirson2d480852008-02-21 20:23:312519 global viewname viewfiles viewargs viewargscmd viewperm nextviewnum
Paul Mackerras7a39a172007-10-23 00:15:112520 global cmitmode wrapcomment datetimeformat limitdiffs
Steffen Prohaska890fae72007-08-12 10:05:462521 global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
Paul Mackerrase3e901b2008-10-27 11:37:212522 global autoselect extdifftool perfile_attrs markbgcolor
Paul Mackerras4ef17532005-07-28 03:16:512523
Paul Mackerras0fba86b2005-05-16 23:54:582524 if {$stuffsaved} return
Paul Mackerrasdf3d83b2005-05-17 23:23:072525 if {![winfo viewable .]} return
Paul Mackerras0fba86b2005-05-16 23:54:582526 catch {
2527 set f [open "~/.gitk-new" w]
Paul Mackerras9832e4f2009-03-23 10:37:512528 if {$::tcl_platform(platform) eq {windows}} {
2529 file attributes "~/.gitk-new" -hidden true
2530 }
Paul Mackerrasf0654862005-07-18 18:29:032531 puts $f [list set mainfont $mainfont]
2532 puts $f [list set textfont $textfont]
Keith Packard4840be62006-04-04 07:19:452533 puts $f [list set uifont $uifont]
Mark Levedahl7e12f1a2007-05-20 15:45:502534 puts $f [list set tabstop $tabstop]
Paul Mackerrasf0654862005-07-18 18:29:032535 puts $f [list set findmergefiles $findmergefiles]
Paul Mackerras8d858d12005-08-04 23:52:162536 puts $f [list set maxgraphpct $maxgraphpct]
Paul Mackerras04c13d32005-08-19 00:22:242537 puts $f [list set maxwidth $maxwidth]
Paul Mackerrasf8b28a42006-04-30 23:50:572538 puts $f [list set cmitmode $cmitmode]
Sergey Vlasovf1b86292006-05-15 15:13:142539 puts $f [list set wrapcomment $wrapcomment]
Jeff King95293b52008-03-06 11:49:252540 puts $f [list set autoselect $autoselect]
Paul Mackerrasb8ab2e12006-06-03 09:11:132541 puts $f [list set showneartags $showneartags]
Paul Mackerras219ea3a2006-09-07 00:21:392542 puts $f [list set showlocalchanges $showlocalchanges]
Arjen Laarhovene8b5f4b2007-08-14 20:02:042543 puts $f [list set datetimeformat $datetimeformat]
Paul Mackerras7a39a172007-10-23 00:15:112544 puts $f [list set limitdiffs $limitdiffs]
Paul Mackerrasf8a2c0d2006-07-05 12:56:372545 puts $f [list set bgcolor $bgcolor]
2546 puts $f [list set fgcolor $fgcolor]
2547 puts $f [list set colors $colors]
2548 puts $f [list set diffcolors $diffcolors]
Paul Mackerrase3e901b2008-10-27 11:37:212549 puts $f [list set markbgcolor $markbgcolor]
Steffen Prohaska890fae72007-08-12 10:05:462550 puts $f [list set diffcontext $diffcontext]
Mark Levedahl60378c02007-05-20 16:12:482551 puts $f [list set selectbgcolor $selectbgcolor]
Thomas Arcila314f5de2008-03-24 11:55:362552 puts $f [list set extdifftool $extdifftool]
Paul Mackerras39ee47e2008-10-15 11:23:032553 puts $f [list set perfile_attrs $perfile_attrs]
Junio C Hamanoe9937d22007-02-01 13:46:382554
Mark Levedahlb6047c52007-02-09 03:22:242555 puts $f "set geometry(main) [wm geometry .]"
Pat Thoytsc876dba2009-04-14 21:09:532556 puts $f "set geometry(state) [wm state .]"
Junio C Hamanoe9937d22007-02-01 13:46:382557 puts $f "set geometry(topwidth) [winfo width .tf]"
2558 puts $f "set geometry(topheight) [winfo height .tf]"
Mark Levedahl9ca72f42007-02-13 00:19:342559 puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
2560 puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
Junio C Hamanoe9937d22007-02-01 13:46:382561 puts $f "set geometry(botwidth) [winfo width .bleft]"
2562 puts $f "set geometry(botheight) [winfo height .bleft]"
2563
Paul Mackerrasa90a6d22006-04-25 07:12:462564 puts -nonewline $f "set permviews {"
2565 for {set v 0} {$v < $nextviewnum} {incr v} {
2566 if {$viewperm($v)} {
Yann Dirson2d480852008-02-21 20:23:312567 puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v) $viewargscmd($v)]}"
Paul Mackerrasa90a6d22006-04-25 07:12:462568 }
2569 }
2570 puts $f "}"
Paul Mackerras0fba86b2005-05-16 23:54:582571 close $f
2572 file rename -force "~/.gitk-new" "~/.gitk"
2573 }
2574 set stuffsaved 1
Paul Mackerras1db95b02005-05-09 04:08:392575}
2576
Paul Mackerras43bddeb2005-05-15 23:19:182577proc resizeclistpanes {win w} {
2578 global oldwidth
Paul Mackerras418c4c72006-02-06 22:10:182579 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:182580 set s0 [$win sash coord 0]
2581 set s1 [$win sash coord 1]
2582 if {$w < 60} {
2583 set sash0 [expr {int($w/2 - 2)}]
2584 set sash1 [expr {int($w*5/6 - 2)}]
2585 } else {
2586 set factor [expr {1.0 * $w / $oldwidth($win)}]
2587 set sash0 [expr {int($factor * [lindex $s0 0])}]
2588 set sash1 [expr {int($factor * [lindex $s1 0])}]
2589 if {$sash0 < 30} {
2590 set sash0 30
2591 }
2592 if {$sash1 < $sash0 + 20} {
Jeff Hobbs2ed49d52005-11-23 01:39:532593 set sash1 [expr {$sash0 + 20}]
Paul Mackerras43bddeb2005-05-15 23:19:182594 }
2595 if {$sash1 > $w - 10} {
Jeff Hobbs2ed49d52005-11-23 01:39:532596 set sash1 [expr {$w - 10}]
Paul Mackerras43bddeb2005-05-15 23:19:182597 if {$sash0 > $sash1 - 20} {
Jeff Hobbs2ed49d52005-11-23 01:39:532598 set sash0 [expr {$sash1 - 20}]
Paul Mackerras43bddeb2005-05-15 23:19:182599 }
2600 }
2601 }
2602 $win sash place 0 $sash0 [lindex $s0 1]
2603 $win sash place 1 $sash1 [lindex $s1 1]
2604 }
2605 set oldwidth($win) $w
2606}
2607
2608proc resizecdetpanes {win w} {
2609 global oldwidth
Paul Mackerras418c4c72006-02-06 22:10:182610 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:182611 set s0 [$win sash coord 0]
2612 if {$w < 60} {
2613 set sash0 [expr {int($w*3/4 - 2)}]
2614 } else {
2615 set factor [expr {1.0 * $w / $oldwidth($win)}]
2616 set sash0 [expr {int($factor * [lindex $s0 0])}]
2617 if {$sash0 < 45} {
2618 set sash0 45
2619 }
2620 if {$sash0 > $w - 15} {
Jeff Hobbs2ed49d52005-11-23 01:39:532621 set sash0 [expr {$w - 15}]
Paul Mackerras43bddeb2005-05-15 23:19:182622 }
2623 }
2624 $win sash place 0 $sash0 [lindex $s0 1]
2625 }
2626 set oldwidth($win) $w
2627}
2628
Paul Mackerrasb5721c72005-05-10 12:08:222629proc allcanvs args {
2630 global canv canv2 canv3
2631 eval $canv $args
2632 eval $canv2 $args
2633 eval $canv3 $args
2634}
2635
2636proc bindall {event action} {
2637 global canv canv2 canv3
2638 bind $canv $event $action
2639 bind $canv2 $event $action
2640 bind $canv3 $event $action
2641}
2642
Paul Mackerras9a40c502005-05-12 23:46:162643proc about {} {
Eygene Ryabinkind59c4b62007-03-27 10:36:122644 global uifont
Paul Mackerras9a40c502005-05-12 23:46:162645 set w .about
2646 if {[winfo exists $w]} {
2647 raise $w
2648 return
2649 }
2650 toplevel $w
Christian Stimmingd990ced2007-11-07 17:42:552651 wm title $w [mc "About gitk"]
Alexander Gavrilove7d64002008-11-11 20:55:422652 make_transient $w .
Christian Stimmingd990ced2007-11-07 17:42:552653 message $w.m -text [mc "
Paul Mackerras9f1afe02006-02-19 11:44:472654Gitk - a commit viewer for git
Paul Mackerras9a40c502005-05-12 23:46:162655
Paul Mackerrasee66e082008-05-09 00:14:072656Copyright © 2005-2008 Paul Mackerras
Paul Mackerras9a40c502005-05-12 23:46:162657
Christian Stimmingd990ced2007-11-07 17:42:552658Use and redistribute under the terms of the GNU General Public License"] \
Eygene Ryabinkin3a950e92007-03-27 10:36:592659 -justify center -aspect 400 -border 2 -bg white -relief groove
2660 pack $w.m -side top -fill x -padx 2 -pady 2
Christian Stimmingd990ced2007-11-07 17:42:552661 button $w.ok -text [mc "Close"] -command "destroy $w" -default active
Paul Mackerras9a40c502005-05-12 23:46:162662 pack $w.ok -side bottom
Eygene Ryabinkin3a950e92007-03-27 10:36:592663 bind $w <Visibility> "focus $w.ok"
2664 bind $w <Key-Escape> "destroy $w"
2665 bind $w <Key-Return> "destroy $w"
Paul Mackerras9a40c502005-05-12 23:46:162666}
2667
Paul Mackerras4e95e1f2006-04-04 23:39:512668proc keys {} {
Paul Mackerras4e95e1f2006-04-04 23:39:512669 set w .keys
2670 if {[winfo exists $w]} {
2671 raise $w
2672 return
2673 }
Shawn O. Pearced23d98d2007-07-19 04:37:582674 if {[tk windowingsystem] eq {aqua}} {
2675 set M1T Cmd
2676 } else {
2677 set M1T Ctrl
2678 }
Paul Mackerras4e95e1f2006-04-04 23:39:512679 toplevel $w
Christian Stimmingd990ced2007-11-07 17:42:552680 wm title $w [mc "Gitk key bindings"]
Alexander Gavrilove7d64002008-11-11 20:55:422681 make_transient $w .
Michele Ballabio3d2c9982008-01-15 22:31:492682 message $w.m -text "
2683[mc "Gitk key bindings:"]
Paul Mackerras4e95e1f2006-04-04 23:39:512684
Michele Ballabio3d2c9982008-01-15 22:31:492685[mc "<%s-Q> Quit" $M1T]
2686[mc "<Home> Move to first commit"]
2687[mc "<End> Move to last commit"]
2688[mc "<Up>, p, i Move up one commit"]
2689[mc "<Down>, n, k Move down one commit"]
2690[mc "<Left>, z, j Go back in history list"]
2691[mc "<Right>, x, l Go forward in history list"]
2692[mc "<PageUp> Move up one page in commit list"]
2693[mc "<PageDown> Move down one page in commit list"]
2694[mc "<%s-Home> Scroll to top of commit list" $M1T]
2695[mc "<%s-End> Scroll to bottom of commit list" $M1T]
2696[mc "<%s-Up> Scroll commit list up one line" $M1T]
2697[mc "<%s-Down> Scroll commit list down one line" $M1T]
2698[mc "<%s-PageUp> Scroll commit list up one page" $M1T]
2699[mc "<%s-PageDown> Scroll commit list down one page" $M1T]
2700[mc "<Shift-Up> Find backwards (upwards, later commits)"]
2701[mc "<Shift-Down> Find forwards (downwards, earlier commits)"]
2702[mc "<Delete>, b Scroll diff view up one page"]
2703[mc "<Backspace> Scroll diff view up one page"]
2704[mc "<Space> Scroll diff view down one page"]
2705[mc "u Scroll diff view up 18 lines"]
2706[mc "d Scroll diff view down 18 lines"]
2707[mc "<%s-F> Find" $M1T]
2708[mc "<%s-G> Move to next find hit" $M1T]
2709[mc "<Return> Move to next find hit"]
Giuseppe Bilotta97bed032008-12-02 01:19:222710[mc "/ Focus the search box"]
Michele Ballabio3d2c9982008-01-15 22:31:492711[mc "? Move to previous find hit"]
2712[mc "f Scroll diff view to next file"]
2713[mc "<%s-S> Search for next hit in diff view" $M1T]
2714[mc "<%s-R> Search for previous hit in diff view" $M1T]
2715[mc "<%s-KP+> Increase font size" $M1T]
2716[mc "<%s-plus> Increase font size" $M1T]
2717[mc "<%s-KP-> Decrease font size" $M1T]
2718[mc "<%s-minus> Decrease font size" $M1T]
2719[mc "<F5> Update"]
2720" \
Eygene Ryabinkin3a950e92007-03-27 10:36:592721 -justify left -bg white -border 2 -relief groove
2722 pack $w.m -side top -fill both -padx 2 -pady 2
Christian Stimmingd990ced2007-11-07 17:42:552723 button $w.ok -text [mc "Close"] -command "destroy $w" -default active
Alexander Gavrilov76f15942008-11-02 18:59:442724 bind $w <Key-Escape> [list destroy $w]
Paul Mackerras4e95e1f2006-04-04 23:39:512725 pack $w.ok -side bottom
Eygene Ryabinkin3a950e92007-03-27 10:36:592726 bind $w <Visibility> "focus $w.ok"
2727 bind $w <Key-Escape> "destroy $w"
2728 bind $w <Key-Return> "destroy $w"
Paul Mackerras4e95e1f2006-04-04 23:39:512729}
2730
Paul Mackerras7fcceed2006-04-27 09:21:492731# Procedures for manipulating the file list window at the
2732# bottom right of the overall window.
Paul Mackerrasf8b28a42006-04-30 23:50:572733
2734proc treeview {w l openlevs} {
2735 global treecontents treediropen treeheight treeparent treeindex
2736
2737 set ix 0
2738 set treeindex() 0
2739 set lev 0
2740 set prefix {}
2741 set prefixend -1
2742 set prefendstack {}
2743 set htstack {}
2744 set ht 0
2745 set treecontents() {}
2746 $w conf -state normal
2747 foreach f $l {
2748 while {[string range $f 0 $prefixend] ne $prefix} {
2749 if {$lev <= $openlevs} {
2750 $w mark set e:$treeindex($prefix) "end -1c"
2751 $w mark gravity e:$treeindex($prefix) left
2752 }
2753 set treeheight($prefix) $ht
2754 incr ht [lindex $htstack end]
2755 set htstack [lreplace $htstack end end]
2756 set prefixend [lindex $prefendstack end]
2757 set prefendstack [lreplace $prefendstack end end]
2758 set prefix [string range $prefix 0 $prefixend]
2759 incr lev -1
2760 }
2761 set tail [string range $f [expr {$prefixend+1}] end]
2762 while {[set slash [string first "/" $tail]] >= 0} {
2763 lappend htstack $ht
2764 set ht 0
2765 lappend prefendstack $prefixend
2766 incr prefixend [expr {$slash + 1}]
2767 set d [string range $tail 0 $slash]
2768 lappend treecontents($prefix) $d
2769 set oldprefix $prefix
2770 append prefix $d
2771 set treecontents($prefix) {}
2772 set treeindex($prefix) [incr ix]
2773 set treeparent($prefix) $oldprefix
2774 set tail [string range $tail [expr {$slash+1}] end]
2775 if {$lev <= $openlevs} {
2776 set ht 1
2777 set treediropen($prefix) [expr {$lev < $openlevs}]
2778 set bm [expr {$lev == $openlevs? "tri-rt": "tri-dn"}]
2779 $w mark set d:$ix "end -1c"
2780 $w mark gravity d:$ix left
2781 set str "\n"
2782 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
2783 $w insert end $str
2784 $w image create end -align center -image $bm -padx 1 \
2785 -name a:$ix
Paul Mackerras45a9d502006-05-20 12:56:272786 $w insert end $d [highlight_tag $prefix]
Paul Mackerrasf8b28a42006-04-30 23:50:572787 $w mark set s:$ix "end -1c"
2788 $w mark gravity s:$ix left
2789 }
2790 incr lev
2791 }
2792 if {$tail ne {}} {
2793 if {$lev <= $openlevs} {
2794 incr ht
2795 set str "\n"
2796 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
2797 $w insert end $str
Paul Mackerras45a9d502006-05-20 12:56:272798 $w insert end $tail [highlight_tag $f]
Paul Mackerrasf8b28a42006-04-30 23:50:572799 }
2800 lappend treecontents($prefix) $tail
2801 }
2802 }
2803 while {$htstack ne {}} {
2804 set treeheight($prefix) $ht
2805 incr ht [lindex $htstack end]
2806 set htstack [lreplace $htstack end end]
Brian Downing096e96b2007-07-05 11:33:022807 set prefixend [lindex $prefendstack end]
2808 set prefendstack [lreplace $prefendstack end end]
2809 set prefix [string range $prefix 0 $prefixend]
Paul Mackerrasf8b28a42006-04-30 23:50:572810 }
2811 $w conf -state disabled
2812}
2813
2814proc linetoelt {l} {
2815 global treeheight treecontents
2816
2817 set y 2
2818 set prefix {}
2819 while {1} {
2820 foreach e $treecontents($prefix) {
2821 if {$y == $l} {
2822 return "$prefix$e"
2823 }
2824 set n 1
2825 if {[string index $e end] eq "/"} {
2826 set n $treeheight($prefix$e)
2827 if {$y + $n > $l} {
2828 append prefix $e
2829 incr y
2830 break
2831 }
2832 }
2833 incr y $n
2834 }
2835 }
2836}
2837
Paul Mackerras45a9d502006-05-20 12:56:272838proc highlight_tree {y prefix} {
2839 global treeheight treecontents cflist
2840
2841 foreach e $treecontents($prefix) {
2842 set path $prefix$e
2843 if {[highlight_tag $path] ne {}} {
2844 $cflist tag add bold $y.0 "$y.0 lineend"
2845 }
2846 incr y
2847 if {[string index $e end] eq "/" && $treeheight($path) > 1} {
2848 set y [highlight_tree $y $path]
2849 }
2850 }
2851 return $y
2852}
2853
Paul Mackerrasf8b28a42006-04-30 23:50:572854proc treeclosedir {w dir} {
2855 global treediropen treeheight treeparent treeindex
2856
2857 set ix $treeindex($dir)
2858 $w conf -state normal
2859 $w delete s:$ix e:$ix
2860 set treediropen($dir) 0
2861 $w image configure a:$ix -image tri-rt
2862 $w conf -state disabled
2863 set n [expr {1 - $treeheight($dir)}]
2864 while {$dir ne {}} {
2865 incr treeheight($dir) $n
2866 set dir $treeparent($dir)
2867 }
2868}
2869
2870proc treeopendir {w dir} {
2871 global treediropen treeheight treeparent treecontents treeindex
2872
2873 set ix $treeindex($dir)
2874 $w conf -state normal
2875 $w image configure a:$ix -image tri-dn
2876 $w mark set e:$ix s:$ix
2877 $w mark gravity e:$ix right
2878 set lev 0
2879 set str "\n"
2880 set n [llength $treecontents($dir)]
2881 for {set x $dir} {$x ne {}} {set x $treeparent($x)} {
2882 incr lev
2883 append str "\t"
2884 incr treeheight($x) $n
2885 }
2886 foreach e $treecontents($dir) {
Paul Mackerras45a9d502006-05-20 12:56:272887 set de $dir$e
Paul Mackerrasf8b28a42006-04-30 23:50:572888 if {[string index $e end] eq "/"} {
Paul Mackerrasf8b28a42006-04-30 23:50:572889 set iy $treeindex($de)
2890 $w mark set d:$iy e:$ix
2891 $w mark gravity d:$iy left
2892 $w insert e:$ix $str
2893 set treediropen($de) 0
2894 $w image create e:$ix -align center -image tri-rt -padx 1 \
2895 -name a:$iy
Paul Mackerras45a9d502006-05-20 12:56:272896 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-04-30 23:50:572897 $w mark set s:$iy e:$ix
2898 $w mark gravity s:$iy left
2899 set treeheight($de) 1
2900 } else {
2901 $w insert e:$ix $str
Paul Mackerras45a9d502006-05-20 12:56:272902 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-04-30 23:50:572903 }
2904 }
Alexander Gavrilovb8a640e2008-09-08 07:28:162905 $w mark gravity e:$ix right
Paul Mackerrasf8b28a42006-04-30 23:50:572906 $w conf -state disabled
2907 set treediropen($dir) 1
2908 set top [lindex [split [$w index @0,0] .] 0]
2909 set ht [$w cget -height]
2910 set l [lindex [split [$w index s:$ix] .] 0]
2911 if {$l < $top} {
2912 $w yview $l.0
2913 } elseif {$l + $n + 1 > $top + $ht} {
2914 set top [expr {$l + $n + 2 - $ht}]
2915 if {$l < $top} {
2916 set top $l
2917 }
2918 $w yview $top.0
2919 }
2920}
2921
2922proc treeclick {w x y} {
2923 global treediropen cmitmode ctext cflist cflist_top
2924
2925 if {$cmitmode ne "tree"} return
2926 if {![info exists cflist_top]} return
2927 set l [lindex [split [$w index "@$x,$y"] "."] 0]
2928 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
2929 $cflist tag add highlight $l.0 "$l.0 lineend"
2930 set cflist_top $l
2931 if {$l == 1} {
2932 $ctext yview 1.0
2933 return
2934 }
2935 set e [linetoelt $l]
2936 if {[string index $e end] ne "/"} {
2937 showfile $e
2938 } elseif {$treediropen($e)} {
2939 treeclosedir $w $e
2940 } else {
2941 treeopendir $w $e
2942 }
2943}
2944
2945proc setfilelist {id} {
Paul Mackerras8a897742008-10-27 10:36:252946 global treefilelist cflist jump_to_here
Paul Mackerrasf8b28a42006-04-30 23:50:572947
2948 treeview $cflist $treefilelist($id) 0
Paul Mackerras8a897742008-10-27 10:36:252949 if {$jump_to_here ne {}} {
2950 set f [lindex $jump_to_here 0]
2951 if {[lsearch -exact $treefilelist($id) $f] >= 0} {
2952 showfile $f
2953 }
2954 }
Paul Mackerrasf8b28a42006-04-30 23:50:572955}
2956
2957image create bitmap tri-rt -background black -foreground blue -data {
2958 #define tri-rt_width 13
2959 #define tri-rt_height 13
2960 static unsigned char tri-rt_bits[] = {
2961 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x70, 0x00, 0xf0, 0x00,
2962 0xf0, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x30, 0x00, 0x10, 0x00, 0x00, 0x00,
2963 0x00, 0x00};
2964} -maskdata {
2965 #define tri-rt-mask_width 13
2966 #define tri-rt-mask_height 13
2967 static unsigned char tri-rt-mask_bits[] = {
2968 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00, 0xf8, 0x01,
2969 0xf8, 0x03, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0x38, 0x00, 0x18, 0x00,
2970 0x08, 0x00};
2971}
2972image create bitmap tri-dn -background black -foreground blue -data {
2973 #define tri-dn_width 13
2974 #define tri-dn_height 13
2975 static unsigned char tri-dn_bits[] = {
2976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xf8, 0x03,
2977 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2978 0x00, 0x00};
2979} -maskdata {
2980 #define tri-dn-mask_width 13
2981 #define tri-dn-mask_height 13
2982 static unsigned char tri-dn-mask_bits[] = {
2983 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xfe, 0x0f, 0xfc, 0x07,
2984 0xf8, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
2985 0x00, 0x00};
2986}
2987
Paul Mackerras887c9962007-08-20 09:36:202988image create bitmap reficon-T -background black -foreground yellow -data {
2989 #define tagicon_width 13
2990 #define tagicon_height 9
2991 static unsigned char tagicon_bits[] = {
2992 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xf8, 0x07,
2993 0xfc, 0x07, 0xf8, 0x07, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00};
2994} -maskdata {
2995 #define tagicon-mask_width 13
2996 #define tagicon-mask_height 9
2997 static unsigned char tagicon-mask_bits[] = {
2998 0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x0f, 0xfc, 0x0f,
2999 0xfe, 0x0f, 0xfc, 0x0f, 0xf8, 0x0f, 0xf0, 0x0f, 0x00, 0x00};
3000}
3001set rectdata {
3002 #define headicon_width 13
3003 #define headicon_height 9
3004 static unsigned char headicon_bits[] = {
3005 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xf8, 0x07,
3006 0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00};
3007}
3008set rectmask {
3009 #define headicon-mask_width 13
3010 #define headicon-mask_height 9
3011 static unsigned char headicon-mask_bits[] = {
3012 0x00, 0x00, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
3013 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0x00, 0x00};
3014}
3015image create bitmap reficon-H -background black -foreground green \
3016 -data $rectdata -maskdata $rectmask
3017image create bitmap reficon-o -background black -foreground "#ddddff" \
3018 -data $rectdata -maskdata $rectmask
3019
Paul Mackerras7fcceed2006-04-27 09:21:493020proc init_flist {first} {
Paul Mackerras7fcc92b2007-12-02 23:33:013021 global cflist cflist_top difffilestart
Paul Mackerras7fcceed2006-04-27 09:21:493022
3023 $cflist conf -state normal
3024 $cflist delete 0.0 end
3025 if {$first ne {}} {
3026 $cflist insert end $first
3027 set cflist_top 1
Paul Mackerras7fcceed2006-04-27 09:21:493028 $cflist tag add highlight 1.0 "1.0 lineend"
3029 } else {
3030 catch {unset cflist_top}
3031 }
3032 $cflist conf -state disabled
3033 set difffilestart {}
3034}
3035
Paul Mackerras63b79192006-05-20 11:31:523036proc highlight_tag {f} {
3037 global highlight_paths
3038
3039 foreach p $highlight_paths {
3040 if {[string match $p $f]} {
3041 return "bold"
3042 }
3043 }
3044 return {}
3045}
3046
3047proc highlight_filelist {} {
Paul Mackerras45a9d502006-05-20 12:56:273048 global cmitmode cflist
Paul Mackerras63b79192006-05-20 11:31:523049
Paul Mackerras45a9d502006-05-20 12:56:273050 $cflist conf -state normal
3051 if {$cmitmode ne "tree"} {
Paul Mackerras63b79192006-05-20 11:31:523052 set end [lindex [split [$cflist index end] .] 0]
3053 for {set l 2} {$l < $end} {incr l} {
3054 set line [$cflist get $l.0 "$l.0 lineend"]
3055 if {[highlight_tag $line] ne {}} {
3056 $cflist tag add bold $l.0 "$l.0 lineend"
3057 }
3058 }
Paul Mackerras45a9d502006-05-20 12:56:273059 } else {
3060 highlight_tree 2 {}
Paul Mackerras63b79192006-05-20 11:31:523061 }
Paul Mackerras45a9d502006-05-20 12:56:273062 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 11:31:523063}
3064
3065proc unhighlight_filelist {} {
Paul Mackerras45a9d502006-05-20 12:56:273066 global cflist
Paul Mackerras63b79192006-05-20 11:31:523067
Paul Mackerras45a9d502006-05-20 12:56:273068 $cflist conf -state normal
3069 $cflist tag remove bold 1.0 end
3070 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 11:31:523071}
3072
Paul Mackerrasf8b28a42006-04-30 23:50:573073proc add_flist {fl} {
Paul Mackerras45a9d502006-05-20 12:56:273074 global cflist
Paul Mackerras7fcceed2006-04-27 09:21:493075
Paul Mackerras45a9d502006-05-20 12:56:273076 $cflist conf -state normal
3077 foreach f $fl {
3078 $cflist insert end "\n"
3079 $cflist insert end $f [highlight_tag $f]
Paul Mackerras7fcceed2006-04-27 09:21:493080 }
Paul Mackerras45a9d502006-05-20 12:56:273081 $cflist conf -state disabled
Paul Mackerras7fcceed2006-04-27 09:21:493082}
3083
3084proc sel_flist {w x y} {
Paul Mackerras45a9d502006-05-20 12:56:273085 global ctext difffilestart cflist cflist_top cmitmode
Paul Mackerras7fcceed2006-04-27 09:21:493086
Paul Mackerrasf8b28a42006-04-30 23:50:573087 if {$cmitmode eq "tree"} return
Paul Mackerras7fcceed2006-04-27 09:21:493088 if {![info exists cflist_top]} return
3089 set l [lindex [split [$w index "@$x,$y"] "."] 0]
Paul Mackerras89b11d32006-05-02 09:55:313090 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
3091 $cflist tag add highlight $l.0 "$l.0 lineend"
3092 set cflist_top $l
Paul Mackerrasf8b28a42006-04-30 23:50:573093 if {$l == 1} {
3094 $ctext yview 1.0
3095 } else {
3096 catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
Paul Mackerras7fcceed2006-04-27 09:21:493097 }
Paul Mackerras7fcceed2006-04-27 09:21:493098}
3099
Paul Mackerras32447292007-07-27 12:30:153100proc pop_flist_menu {w X Y x y} {
3101 global ctext cflist cmitmode flist_menu flist_menu_file
3102 global treediffs diffids
3103
Paul Mackerrasbb3edc82007-09-27 01:00:253104 stopfinding
Paul Mackerras32447292007-07-27 12:30:153105 set l [lindex [split [$w index "@$x,$y"] "."] 0]
3106 if {$l <= 1} return
3107 if {$cmitmode eq "tree"} {
3108 set e [linetoelt $l]
3109 if {[string index $e end] eq "/"} return
3110 } else {
3111 set e [lindex $treediffs($diffids) [expr {$l-2}]]
3112 }
3113 set flist_menu_file $e
Thomas Arcila314f5de2008-03-24 11:55:363114 set xdiffstate "normal"
3115 if {$cmitmode eq "tree"} {
3116 set xdiffstate "disabled"
3117 }
3118 # Disable "External diff" item in tree mode
3119 $flist_menu entryconf 2 -state $xdiffstate
Paul Mackerras32447292007-07-27 12:30:153120 tk_popup $flist_menu $X $Y
3121}
3122
Alexander Gavrilov7cdc3552008-10-24 08:13:013123proc find_ctext_fileinfo {line} {
3124 global ctext_file_names ctext_file_lines
3125
3126 set ok [bsearch $ctext_file_lines $line]
3127 set tline [lindex $ctext_file_lines $ok]
3128
3129 if {$ok >= [llength $ctext_file_lines] || $line < $tline} {
3130 return {}
3131 } else {
3132 return [list [lindex $ctext_file_names $ok] $tline]
3133 }
3134}
3135
3136proc pop_diff_menu {w X Y x y} {
3137 global ctext diff_menu flist_menu_file
3138 global diff_menu_txtpos diff_menu_line
3139 global diff_menu_filebase
3140
Alexander Gavrilov7cdc3552008-10-24 08:13:013141 set diff_menu_txtpos [split [$w index "@$x,$y"] "."]
3142 set diff_menu_line [lindex $diff_menu_txtpos 0]
Paul Mackerras190ec522008-10-27 10:13:373143 # don't pop up the menu on hunk-separator or file-separator lines
3144 if {[lsearch -glob [$ctext tag names $diff_menu_line.0] "*sep"] >= 0} {
3145 return
3146 }
3147 stopfinding
Alexander Gavrilov7cdc3552008-10-24 08:13:013148 set f [find_ctext_fileinfo $diff_menu_line]
3149 if {$f eq {}} return
3150 set flist_menu_file [lindex $f 0]
3151 set diff_menu_filebase [lindex $f 1]
3152 tk_popup $diff_menu $X $Y
3153}
3154
Paul Mackerras32447292007-07-27 12:30:153155proc flist_hl {only} {
Paul Mackerrasbb3edc82007-09-27 01:00:253156 global flist_menu_file findstring gdttype
Paul Mackerras32447292007-07-27 12:30:153157
3158 set x [shellquote $flist_menu_file]
Christian Stimmingb007ee22007-11-07 17:44:353159 if {$only || $findstring eq {} || $gdttype ne [mc "touching paths:"]} {
Paul Mackerrasbb3edc82007-09-27 01:00:253160 set findstring $x
Paul Mackerras32447292007-07-27 12:30:153161 } else {
Paul Mackerrasbb3edc82007-09-27 01:00:253162 append findstring " " $x
Paul Mackerras32447292007-07-27 12:30:153163 }
Christian Stimmingb007ee22007-11-07 17:44:353164 set gdttype [mc "touching paths:"]
Paul Mackerras32447292007-07-27 12:30:153165}
3166
Thomas Arcila314f5de2008-03-24 11:55:363167proc save_file_from_commit {filename output what} {
3168 global nullfile
3169
3170 if {[catch {exec git show $filename -- > $output} err]} {
3171 if {[string match "fatal: bad revision *" $err]} {
3172 return $nullfile
3173 }
Christian Stimming3945d2c2008-09-12 09:39:433174 error_popup "[mc "Error getting \"%s\" from %s:" $filename $what] $err"
Thomas Arcila314f5de2008-03-24 11:55:363175 return {}
3176 }
3177 return $output
3178}
3179
3180proc external_diff_get_one_file {diffid filename diffdir} {
3181 global nullid nullid2 nullfile
3182 global gitdir
3183
3184 if {$diffid == $nullid} {
3185 set difffile [file join [file dirname $gitdir] $filename]
3186 if {[file exists $difffile]} {
3187 return $difffile
3188 }
3189 return $nullfile
3190 }
3191 if {$diffid == $nullid2} {
3192 set difffile [file join $diffdir "\[index\] [file tail $filename]"]
3193 return [save_file_from_commit :$filename $difffile index]
3194 }
3195 set difffile [file join $diffdir "\[$diffid\] [file tail $filename]"]
3196 return [save_file_from_commit $diffid:$filename $difffile \
3197 "revision $diffid"]
3198}
3199
3200proc external_diff {} {
3201 global gitktmpdir nullid nullid2
3202 global flist_menu_file
3203 global diffids
3204 global diffnum
3205 global gitdir extdifftool
3206
3207 if {[llength $diffids] == 1} {
3208 # no reference commit given
3209 set diffidto [lindex $diffids 0]
3210 if {$diffidto eq $nullid} {
3211 # diffing working copy with index
3212 set diffidfrom $nullid2
3213 } elseif {$diffidto eq $nullid2} {
3214 # diffing index with HEAD
3215 set diffidfrom "HEAD"
3216 } else {
3217 # use first parent commit
3218 global parentlist selectedline
3219 set diffidfrom [lindex $parentlist $selectedline 0]
3220 }
3221 } else {
3222 set diffidfrom [lindex $diffids 0]
3223 set diffidto [lindex $diffids 1]
3224 }
3225
3226 # make sure that several diffs wont collide
3227 if {![info exists gitktmpdir]} {
3228 set gitktmpdir [file join [file dirname $gitdir] \
3229 [format ".gitk-tmp.%s" [pid]]]
3230 if {[catch {file mkdir $gitktmpdir} err]} {
Christian Stimming3945d2c2008-09-12 09:39:433231 error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
Thomas Arcila314f5de2008-03-24 11:55:363232 unset gitktmpdir
3233 return
3234 }
3235 set diffnum 0
3236 }
3237 incr diffnum
3238 set diffdir [file join $gitktmpdir $diffnum]
3239 if {[catch {file mkdir $diffdir} err]} {
Christian Stimming3945d2c2008-09-12 09:39:433240 error_popup "[mc "Error creating temporary directory %s:" $diffdir] $err"
Thomas Arcila314f5de2008-03-24 11:55:363241 return
3242 }
3243
3244 # gather files to diff
3245 set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
3246 set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir]
3247
3248 if {$difffromfile ne {} && $difftofile ne {}} {
Pat Thoytsb575b2f2009-04-15 15:54:193249 set cmd [list [shellsplit $extdifftool] $difffromfile $difftofile]
3250 if {[catch {set fl [open |$cmd r]} err]} {
Thomas Arcila314f5de2008-03-24 11:55:363251 file delete -force $diffdir
Christian Stimming3945d2c2008-09-12 09:39:433252 error_popup "$extdifftool: [mc "command failed:"] $err"
Thomas Arcila314f5de2008-03-24 11:55:363253 } else {
3254 fconfigure $fl -blocking 0
3255 filerun $fl [list delete_at_eof $fl $diffdir]
3256 }
3257 }
3258}
3259
Alexander Gavrilov7cdc3552008-10-24 08:13:013260proc find_hunk_blamespec {base line} {
3261 global ctext
3262
3263 # Find and parse the hunk header
3264 set s_lix [$ctext search -backwards -regexp ^@@ "$line.0 lineend" $base.0]
3265 if {$s_lix eq {}} return
3266
3267 set s_line [$ctext get $s_lix "$s_lix + 1 lines"]
3268 if {![regexp {^@@@*(( -\d+(,\d+)?)+) \+(\d+)(,\d+)? @@} $s_line \
3269 s_line old_specs osz osz1 new_line nsz]} {
3270 return
3271 }
3272
3273 # base lines for the parents
3274 set base_lines [list $new_line]
3275 foreach old_spec [lrange [split $old_specs " "] 1 end] {
3276 if {![regexp -- {-(\d+)(,\d+)?} $old_spec \
3277 old_spec old_line osz]} {
3278 return
3279 }
3280 lappend base_lines $old_line
3281 }
3282
3283 # Now scan the lines to determine offset within the hunk
Alexander Gavrilov7cdc3552008-10-24 08:13:013284 set max_parent [expr {[llength $base_lines]-2}]
3285 set dline 0
3286 set s_lno [lindex [split $s_lix "."] 0]
3287
Paul Mackerras190ec522008-10-27 10:13:373288 # Determine if the line is removed
3289 set chunk [$ctext get $line.0 "$line.1 + $max_parent chars"]
3290 if {[string match {[-+ ]*} $chunk]} {
Alexander Gavrilov7cdc3552008-10-24 08:13:013291 set removed_idx [string first "-" $chunk]
3292 # Choose a parent index
Paul Mackerras190ec522008-10-27 10:13:373293 if {$removed_idx >= 0} {
3294 set parent $removed_idx
3295 } else {
3296 set unchanged_idx [string first " " $chunk]
3297 if {$unchanged_idx >= 0} {
3298 set parent $unchanged_idx
Alexander Gavrilov7cdc3552008-10-24 08:13:013299 } else {
Paul Mackerras190ec522008-10-27 10:13:373300 # blame the current commit
3301 set parent -1
Alexander Gavrilov7cdc3552008-10-24 08:13:013302 }
3303 }
3304 # then count other lines that belong to it
Paul Mackerras190ec522008-10-27 10:13:373305 for {set i $line} {[incr i -1] > $s_lno} {} {
3306 set chunk [$ctext get $i.0 "$i.1 + $max_parent chars"]
3307 # Determine if the line is removed
3308 set removed_idx [string first "-" $chunk]
3309 if {$parent >= 0} {
3310 set code [string index $chunk $parent]
3311 if {$code eq "-" || ($removed_idx < 0 && $code ne "+")} {
3312 incr dline
3313 }
3314 } else {
3315 if {$removed_idx < 0} {
3316 incr dline
3317 }
Alexander Gavrilov7cdc3552008-10-24 08:13:013318 }
3319 }
Paul Mackerras190ec522008-10-27 10:13:373320 incr parent
3321 } else {
3322 set parent 0
Alexander Gavrilov7cdc3552008-10-24 08:13:013323 }
3324
Alexander Gavrilov7cdc3552008-10-24 08:13:013325 incr dline [lindex $base_lines $parent]
3326 return [list $parent $dline]
3327}
3328
3329proc external_blame_diff {} {
Paul Mackerras8b07dca2008-11-02 11:34:473330 global currentid cmitmode
Alexander Gavrilov7cdc3552008-10-24 08:13:013331 global diff_menu_txtpos diff_menu_line
3332 global diff_menu_filebase flist_menu_file
3333
3334 if {$cmitmode eq "tree"} {
3335 set parent_idx 0
Paul Mackerras190ec522008-10-27 10:13:373336 set line [expr {$diff_menu_line - $diff_menu_filebase}]
Alexander Gavrilov7cdc3552008-10-24 08:13:013337 } else {
3338 set hinfo [find_hunk_blamespec $diff_menu_filebase $diff_menu_line]
3339 if {$hinfo ne {}} {
3340 set parent_idx [lindex $hinfo 0]
3341 set line [lindex $hinfo 1]
3342 } else {
3343 set parent_idx 0
3344 set line 0
3345 }
3346 }
3347
3348 external_blame $parent_idx $line
3349}
3350
Paul Mackerrasfc4977e2008-11-04 01:57:443351# Find the SHA1 ID of the blob for file $fname in the index
3352# at stage 0 or 2
3353proc index_sha1 {fname} {
3354 set f [open [list | git ls-files -s $fname] r]
3355 while {[gets $f line] >= 0} {
3356 set info [lindex [split $line "\t"] 0]
3357 set stage [lindex $info 2]
3358 if {$stage eq "0" || $stage eq "2"} {
3359 close $f
3360 return [lindex $info 1]
3361 }
3362 }
3363 close $f
3364 return {}
3365}
3366
Paul Mackerras9712b812008-12-06 10:44:053367# Turn an absolute path into one relative to the current directory
3368proc make_relative {f} {
3369 set elts [file split $f]
3370 set here [file split [pwd]]
3371 set ei 0
3372 set hi 0
3373 set res {}
3374 foreach d $here {
3375 if {$ei < $hi || $ei >= [llength $elts] || [lindex $elts $ei] ne $d} {
3376 lappend res ".."
3377 } else {
3378 incr ei
3379 }
3380 incr hi
3381 }
3382 set elts [concat $res [lrange $elts $ei end]]
3383 return [eval file join $elts]
3384}
3385
Alexander Gavrilov7cdc3552008-10-24 08:13:013386proc external_blame {parent_idx {line {}}} {
Paul Mackerras9712b812008-12-06 10:44:053387 global flist_menu_file gitdir
Alexander Gavrilov77aa0ae2008-08-23 08:29:083388 global nullid nullid2
3389 global parentlist selectedline currentid
3390
3391 if {$parent_idx > 0} {
3392 set base_commit [lindex $parentlist $selectedline [expr {$parent_idx-1}]]
3393 } else {
3394 set base_commit $currentid
3395 }
3396
3397 if {$base_commit eq {} || $base_commit eq $nullid || $base_commit eq $nullid2} {
3398 error_popup [mc "No such commit"]
3399 return
3400 }
3401
Alexander Gavrilov7cdc3552008-10-24 08:13:013402 set cmdline [list git gui blame]
3403 if {$line ne {} && $line > 1} {
3404 lappend cmdline "--line=$line"
3405 }
Paul Mackerras9712b812008-12-06 10:44:053406 set f [file join [file dirname $gitdir] $flist_menu_file]
3407 # Unfortunately it seems git gui blame doesn't like
3408 # being given an absolute path...
3409 set f [make_relative $f]
3410 lappend cmdline $base_commit $f
Alexander Gavrilov7cdc3552008-10-24 08:13:013411 if {[catch {eval exec $cmdline &} err]} {
Christian Stimming3945d2c2008-09-12 09:39:433412 error_popup "[mc "git gui blame: command failed:"] $err"
Alexander Gavrilov77aa0ae2008-08-23 08:29:083413 }
3414}
3415
Paul Mackerras8a897742008-10-27 10:36:253416proc show_line_source {} {
3417 global cmitmode currentid parents curview blamestuff blameinst
3418 global diff_menu_line diff_menu_filebase flist_menu_file
Paul Mackerrasfc4977e2008-11-04 01:57:443419 global nullid nullid2 gitdir
Paul Mackerras8a897742008-10-27 10:36:253420
Paul Mackerrasfc4977e2008-11-04 01:57:443421 set from_index {}
Paul Mackerras8a897742008-10-27 10:36:253422 if {$cmitmode eq "tree"} {
3423 set id $currentid
3424 set line [expr {$diff_menu_line - $diff_menu_filebase}]
3425 } else {
3426 set h [find_hunk_blamespec $diff_menu_filebase $diff_menu_line]
3427 if {$h eq {}} return
3428 set pi [lindex $h 0]
3429 if {$pi == 0} {
3430 mark_ctext_line $diff_menu_line
3431 return
3432 }
Paul Mackerrasfc4977e2008-11-04 01:57:443433 incr pi -1
3434 if {$currentid eq $nullid} {
3435 if {$pi > 0} {
3436 # must be a merge in progress...
3437 if {[catch {
3438 # get the last line from .git/MERGE_HEAD
3439 set f [open [file join $gitdir MERGE_HEAD] r]
3440 set id [lindex [split [read $f] "\n"] end-1]
3441 close $f
3442 } err]} {
3443 error_popup [mc "Couldn't read merge head: %s" $err]
3444 return
3445 }
3446 } elseif {$parents($curview,$currentid) eq $nullid2} {
3447 # need to do the blame from the index
3448 if {[catch {
3449 set from_index [index_sha1 $flist_menu_file]
3450 } err]} {
3451 error_popup [mc "Error reading index: %s" $err]
3452 return
3453 }
Paul Mackerras9712b812008-12-06 10:44:053454 } else {
3455 set id $parents($curview,$currentid)
Paul Mackerrasfc4977e2008-11-04 01:57:443456 }
3457 } else {
3458 set id [lindex $parents($curview,$currentid) $pi]
3459 }
Paul Mackerras8a897742008-10-27 10:36:253460 set line [lindex $h 1]
3461 }
Paul Mackerrasfc4977e2008-11-04 01:57:443462 set blameargs {}
3463 if {$from_index ne {}} {
3464 lappend blameargs | git cat-file blob $from_index
3465 }
3466 lappend blameargs | git blame -p -L$line,+1
3467 if {$from_index ne {}} {
3468 lappend blameargs --contents -
3469 } else {
3470 lappend blameargs $id
3471 }
Paul Mackerras9712b812008-12-06 10:44:053472 lappend blameargs -- [file join [file dirname $gitdir] $flist_menu_file]
Paul Mackerras8a897742008-10-27 10:36:253473 if {[catch {
Paul Mackerrasfc4977e2008-11-04 01:57:443474 set f [open $blameargs r]
Paul Mackerras8a897742008-10-27 10:36:253475 } err]} {
3476 error_popup [mc "Couldn't start git blame: %s" $err]
3477 return
3478 }
Alexander Gavrilovf3413072008-12-01 17:30:093479 nowbusy blaming [mc "Searching"]
Paul Mackerras8a897742008-10-27 10:36:253480 fconfigure $f -blocking 0
3481 set i [reg_instance $f]
3482 set blamestuff($i) {}
3483 set blameinst $i
3484 filerun $f [list read_line_source $f $i]
3485}
3486
3487proc stopblaming {} {
3488 global blameinst
3489
3490 if {[info exists blameinst]} {
3491 stop_instance $blameinst
3492 unset blameinst
Alexander Gavrilovf3413072008-12-01 17:30:093493 notbusy blaming
Paul Mackerras8a897742008-10-27 10:36:253494 }
3495}
3496
3497proc read_line_source {fd inst} {
Paul Mackerrasfc4977e2008-11-04 01:57:443498 global blamestuff curview commfd blameinst nullid nullid2
Paul Mackerras8a897742008-10-27 10:36:253499
3500 while {[gets $fd line] >= 0} {
3501 lappend blamestuff($inst) $line
3502 }
3503 if {![eof $fd]} {
3504 return 1
3505 }
3506 unset commfd($inst)
3507 unset blameinst
Alexander Gavrilovf3413072008-12-01 17:30:093508 notbusy blaming
Paul Mackerras8a897742008-10-27 10:36:253509 fconfigure $fd -blocking 1
3510 if {[catch {close $fd} err]} {
3511 error_popup [mc "Error running git blame: %s" $err]
3512 return 0
3513 }
3514
3515 set fname {}
3516 set line [split [lindex $blamestuff($inst) 0] " "]
3517 set id [lindex $line 0]
3518 set lnum [lindex $line 1]
3519 if {[string length $id] == 40 && [string is xdigit $id] &&
3520 [string is digit -strict $lnum]} {
3521 # look for "filename" line
3522 foreach l $blamestuff($inst) {
3523 if {[string match "filename *" $l]} {
3524 set fname [string range $l 9 end]
3525 break
3526 }
3527 }
3528 }
3529 if {$fname ne {}} {
3530 # all looks good, select it
Paul Mackerrasfc4977e2008-11-04 01:57:443531 if {$id eq $nullid} {
3532 # blame uses all-zeroes to mean not committed,
3533 # which would mean a change in the index
3534 set id $nullid2
3535 }
Paul Mackerras8a897742008-10-27 10:36:253536 if {[commitinview $id $curview]} {
3537 selectline [rowofcommit $id] 1 [list $fname $lnum]
3538 } else {
3539 error_popup [mc "That line comes from commit %s, \
3540 which is not in this view" [shortids $id]]
3541 }
3542 } else {
3543 puts "oops couldn't parse git blame output"
3544 }
3545 return 0
3546}
3547
Thomas Arcila314f5de2008-03-24 11:55:363548# delete $dir when we see eof on $f (presumably because the child has exited)
3549proc delete_at_eof {f dir} {
3550 while {[gets $f line] >= 0} {}
3551 if {[eof $f]} {
3552 if {[catch {close $f} err]} {
Christian Stimming3945d2c2008-09-12 09:39:433553 error_popup "[mc "External diff viewer failed:"] $err"
Thomas Arcila314f5de2008-03-24 11:55:363554 }
3555 file delete -force $dir
3556 return 0
3557 }
3558 return 1
3559}
3560
Paul Mackerras098dd8a2006-05-02 23:32:533561# Functions for adding and removing shell-type quoting
3562
3563proc shellquote {str} {
3564 if {![string match "*\['\"\\ \t]*" $str]} {
3565 return $str
3566 }
3567 if {![string match "*\['\"\\]*" $str]} {
3568 return "\"$str\""
3569 }
3570 if {![string match "*'*" $str]} {
3571 return "'$str'"
3572 }
3573 return "\"[string map {\" \\\" \\ \\\\} $str]\""
3574}
3575
3576proc shellarglist {l} {
3577 set str {}
3578 foreach a $l {
3579 if {$str ne {}} {
3580 append str " "
3581 }
3582 append str [shellquote $a]
3583 }
3584 return $str
3585}
3586
3587proc shelldequote {str} {
3588 set ret {}
3589 set used -1
3590 while {1} {
3591 incr used
3592 if {![regexp -start $used -indices "\['\"\\\\ \t]" $str first]} {
3593 append ret [string range $str $used end]
3594 set used [string length $str]
3595 break
3596 }
3597 set first [lindex $first 0]
3598 set ch [string index $str $first]
3599 if {$first > $used} {
3600 append ret [string range $str $used [expr {$first - 1}]]
3601 set used $first
3602 }
3603 if {$ch eq " " || $ch eq "\t"} break
3604 incr used
3605 if {$ch eq "'"} {
3606 set first [string first "'" $str $used]
3607 if {$first < 0} {
3608 error "unmatched single-quote"
3609 }
3610 append ret [string range $str $used [expr {$first - 1}]]
3611 set used $first
3612 continue
3613 }
3614 if {$ch eq "\\"} {
3615 if {$used >= [string length $str]} {
3616 error "trailing backslash"
3617 }
3618 append ret [string index $str $used]
3619 continue
3620 }
3621 # here ch == "\""
3622 while {1} {
3623 if {![regexp -start $used -indices "\[\"\\\\]" $str first]} {
3624 error "unmatched double-quote"
3625 }
3626 set first [lindex $first 0]
3627 set ch [string index $str $first]
3628 if {$first > $used} {
3629 append ret [string range $str $used [expr {$first - 1}]]
3630 set used $first
3631 }
3632 if {$ch eq "\""} break
3633 incr used
3634 append ret [string index $str $used]
3635 incr used
3636 }
3637 }
3638 return [list $used $ret]
3639}
3640
3641proc shellsplit {str} {
3642 set l {}
3643 while {1} {
3644 set str [string trimleft $str]
3645 if {$str eq {}} break
3646 set dq [shelldequote $str]
3647 set n [lindex $dq 0]
3648 set word [lindex $dq 1]
3649 set str [string range $str $n end]
3650 lappend l $word
3651 }
3652 return $l
3653}
3654
Paul Mackerras7fcceed2006-04-27 09:21:493655# Code to implement multiple views
3656
Paul Mackerrasda7c24d2006-05-02 01:15:293657proc newview {ishighlight} {
Alexander Gavrilov218a9002008-11-02 18:59:483658 global nextviewnum newviewname newishighlight
3659 global revtreeargs viewargscmd newviewopts curview
Paul Mackerras50b44ec2006-04-04 00:16:223660
Paul Mackerrasda7c24d2006-05-02 01:15:293661 set newishighlight $ishighlight
Paul Mackerras50b44ec2006-04-04 00:16:223662 set top .gitkview
3663 if {[winfo exists $top]} {
3664 raise $top
3665 return
3666 }
Michele Ballabioa3a1f572008-03-03 20:12:473667 set newviewname($nextviewnum) "[mc "View"] $nextviewnum"
Alexander Gavrilov218a9002008-11-02 18:59:483668 set newviewopts($nextviewnum,perm) 0
3669 set newviewopts($nextviewnum,cmd) $viewargscmd($curview)
3670 decode_view_opts $nextviewnum $revtreeargs
Christian Stimmingd990ced2007-11-07 17:42:553671 vieweditor $top $nextviewnum [mc "Gitk view definition"]
Paul Mackerrasd16c0812006-04-25 11:21:103672}
3673
Alexander Gavrilov218a9002008-11-02 18:59:483674set known_view_options {
Elijah Newren13d40b62009-03-23 17:57:463675 {perm b . {} {mc "Remember this view"}}
3676 {reflabel l + {} {mc "References (space separated list):"}}
3677 {refs t15 .. {} {mc "Branches & tags:"}}
3678 {allrefs b *. "--all" {mc "All refs"}}
3679 {branches b . "--branches" {mc "All (local) branches"}}
3680 {tags b . "--tags" {mc "All tags"}}
3681 {remotes b . "--remotes" {mc "All remote-tracking branches"}}
3682 {commitlbl l + {} {mc "Commit Info (regular expressions):"}}
3683 {author t15 .. "--author=*" {mc "Author:"}}
3684 {committer t15 . "--committer=*" {mc "Committer:"}}
3685 {loginfo t15 .. "--grep=*" {mc "Commit Message:"}}
3686 {allmatch b .. "--all-match" {mc "Matches all Commit Info criteria"}}
3687 {changes_l l + {} {mc "Changes to Files:"}}
3688 {pickaxe_s r0 . {} {mc "Fixed String"}}
3689 {pickaxe_t r1 . "--pickaxe-regex" {mc "Regular Expression"}}
3690 {pickaxe t15 .. "-S*" {mc "Search string:"}}
3691 {datelabel l + {} {mc "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 15:27:38\"):"}}
3692 {since t15 .. {"--since=*" "--after=*"} {mc "Since:"}}
3693 {until t15 . {"--until=*" "--before=*"} {mc "Until:"}}
3694 {limit_lbl l + {} {mc "Limit and/or skip a number of revisions (positive integer):"}}
3695 {limit t10 *. "--max-count=*" {mc "Number to show:"}}
3696 {skip t10 . "--skip=*" {mc "Number to skip:"}}
3697 {misc_lbl l + {} {mc "Miscellaneous options:"}}
3698 {dorder b *. {"--date-order" "-d"} {mc "Strictly sort by date"}}
3699 {lright b . "--left-right" {mc "Mark branch sides"}}
3700 {first b . "--first-parent" {mc "Limit to first parent"}}
Dirk Suesserottf687aaa2009-05-21 13:35:403701 {smplhst b . "--simplify-by-decoration" {mc "Simple history"}}
Elijah Newren13d40b62009-03-23 17:57:463702 {args t50 *. {} {mc "Additional arguments to git log:"}}
3703 {allpaths path + {} {mc "Enter files and directories to include, one per line:"}}
3704 {cmd t50= + {} {mc "Command to generate more commits to include:"}}
Alexander Gavrilov218a9002008-11-02 18:59:483705 }
3706
3707proc encode_view_opts {n} {
3708 global known_view_options newviewopts
3709
3710 set rargs [list]
3711 foreach opt $known_view_options {
3712 set patterns [lindex $opt 3]
3713 if {$patterns eq {}} continue
3714 set pattern [lindex $patterns 0]
3715
Alexander Gavrilov218a9002008-11-02 18:59:483716 if {[lindex $opt 1] eq "b"} {
Elijah Newren13d40b62009-03-23 17:57:463717 set val $newviewopts($n,[lindex $opt 0])
Alexander Gavrilov218a9002008-11-02 18:59:483718 if {$val} {
3719 lappend rargs $pattern
3720 }
Elijah Newren13d40b62009-03-23 17:57:463721 } elseif {[regexp {^r(\d+)$} [lindex $opt 1] type value]} {
3722 regexp {^(.*_)} [lindex $opt 0] uselessvar button_id
3723 set val $newviewopts($n,$button_id)
3724 if {$val eq $value} {
3725 lappend rargs $pattern
3726 }
Alexander Gavrilov218a9002008-11-02 18:59:483727 } else {
Elijah Newren13d40b62009-03-23 17:57:463728 set val $newviewopts($n,[lindex $opt 0])
Alexander Gavrilov218a9002008-11-02 18:59:483729 set val [string trim $val]
3730 if {$val ne {}} {
3731 set pfix [string range $pattern 0 end-1]
3732 lappend rargs $pfix$val
3733 }
3734 }
3735 }
Elijah Newren13d40b62009-03-23 17:57:463736 set rargs [concat $rargs [shellsplit $newviewopts($n,refs)]]
Alexander Gavrilov218a9002008-11-02 18:59:483737 return [concat $rargs [shellsplit $newviewopts($n,args)]]
3738}
3739
3740proc decode_view_opts {n view_args} {
3741 global known_view_options newviewopts
3742
3743 foreach opt $known_view_options {
Elijah Newren13d40b62009-03-23 17:57:463744 set id [lindex $opt 0]
Alexander Gavrilov218a9002008-11-02 18:59:483745 if {[lindex $opt 1] eq "b"} {
Elijah Newren13d40b62009-03-23 17:57:463746 # Checkboxes
3747 set val 0
3748 } elseif {[regexp {^r(\d+)$} [lindex $opt 1]]} {
3749 # Radiobuttons
3750 regexp {^(.*_)} $id uselessvar id
Alexander Gavrilov218a9002008-11-02 18:59:483751 set val 0
3752 } else {
Elijah Newren13d40b62009-03-23 17:57:463753 # Text fields
Alexander Gavrilov218a9002008-11-02 18:59:483754 set val {}
3755 }
Elijah Newren13d40b62009-03-23 17:57:463756 set newviewopts($n,$id) $val
Alexander Gavrilov218a9002008-11-02 18:59:483757 }
3758 set oargs [list]
Elijah Newren13d40b62009-03-23 17:57:463759 set refargs [list]
Alexander Gavrilov218a9002008-11-02 18:59:483760 foreach arg $view_args {
3761 if {[regexp -- {^-([0-9]+)$} $arg arg cnt]
3762 && ![info exists found(limit)]} {
3763 set newviewopts($n,limit) $cnt
3764 set found(limit) 1
3765 continue
3766 }
3767 catch { unset val }
3768 foreach opt $known_view_options {
3769 set id [lindex $opt 0]
3770 if {[info exists found($id)]} continue
3771 foreach pattern [lindex $opt 3] {
3772 if {![string match $pattern $arg]} continue
Elijah Newren13d40b62009-03-23 17:57:463773 if {[lindex $opt 1] eq "b"} {
3774 # Check buttons
3775 set val 1
3776 } elseif {[regexp {^r(\d+)$} [lindex $opt 1] match num]} {
3777 # Radio buttons
3778 regexp {^(.*_)} $id uselessvar id
3779 set val $num
3780 } else {
3781 # Text input fields
Alexander Gavrilov218a9002008-11-02 18:59:483782 set size [string length $pattern]
3783 set val [string range $arg [expr {$size-1}] end]
Alexander Gavrilov218a9002008-11-02 18:59:483784 }
3785 set newviewopts($n,$id) $val
3786 set found($id) 1
3787 break
3788 }
3789 if {[info exists val]} break
3790 }
3791 if {[info exists val]} continue
Elijah Newren13d40b62009-03-23 17:57:463792 if {[regexp {^-} $arg]} {
3793 lappend oargs $arg
3794 } else {
3795 lappend refargs $arg
3796 }
Alexander Gavrilov218a9002008-11-02 18:59:483797 }
Elijah Newren13d40b62009-03-23 17:57:463798 set newviewopts($n,refs) [shellarglist $refargs]
Alexander Gavrilov218a9002008-11-02 18:59:483799 set newviewopts($n,args) [shellarglist $oargs]
3800}
3801
Alexander Gavrilovcea07cf2008-11-09 10:00:453802proc edit_or_newview {} {
3803 global curview
3804
3805 if {$curview > 0} {
3806 editview
3807 } else {
3808 newview 0
3809 }
3810}
3811
Paul Mackerrasd16c0812006-04-25 11:21:103812proc editview {} {
3813 global curview
Alexander Gavrilov218a9002008-11-02 18:59:483814 global viewname viewperm newviewname newviewopts
3815 global viewargs viewargscmd
Paul Mackerrasd16c0812006-04-25 11:21:103816
3817 set top .gitkvedit-$curview
3818 if {[winfo exists $top]} {
3819 raise $top
3820 return
3821 }
Alexander Gavrilov218a9002008-11-02 18:59:483822 set newviewname($curview) $viewname($curview)
3823 set newviewopts($curview,perm) $viewperm($curview)
3824 set newviewopts($curview,cmd) $viewargscmd($curview)
3825 decode_view_opts $curview $viewargs($curview)
Michele Ballabiob56e0a92009-03-30 19:17:253826 vieweditor $top $curview "[mc "Gitk: edit view"] $viewname($curview)"
Paul Mackerrasd16c0812006-04-25 11:21:103827}
3828
3829proc vieweditor {top n title} {
Alexander Gavrilov218a9002008-11-02 18:59:483830 global newviewname newviewopts viewfiles bgcolor
3831 global known_view_options
Paul Mackerrasd16c0812006-04-25 11:21:103832
Paul Mackerras50b44ec2006-04-04 00:16:223833 toplevel $top
Michele Ballabioe0a01992009-05-23 09:48:253834 wm title $top [concat $title [mc "-- criteria for selecting revisions"]]
Alexander Gavrilove7d64002008-11-11 20:55:423835 make_transient $top .
Alexander Gavrilov218a9002008-11-02 18:59:483836
3837 # View name
3838 frame $top.nfr
Elijah Newren13d40b62009-03-23 17:57:463839 label $top.nl -text [mc "View Name:"]
Paul Mackerrasb039f0a2008-01-06 04:54:463840 entry $top.name -width 20 -textvariable newviewname($n)
Alexander Gavrilov218a9002008-11-02 18:59:483841 pack $top.nfr -in $top -fill x -pady 5 -padx 3
Elijah Newren13d40b62009-03-23 17:57:463842 pack $top.nl -in $top.nfr -side left -padx {0 5}
3843 pack $top.name -in $top.nfr -side left -padx {0 25}
Yann Dirson2d480852008-02-21 20:23:313844
Alexander Gavrilov218a9002008-11-02 18:59:483845 # View options
3846 set cframe $top.nfr
3847 set cexpand 0
3848 set cnt 0
3849 foreach opt $known_view_options {
3850 set id [lindex $opt 0]
3851 set type [lindex $opt 1]
3852 set flags [lindex $opt 2]
3853 set title [eval [lindex $opt 4]]
3854 set lxpad 0
Yann Dirson2d480852008-02-21 20:23:313855
Alexander Gavrilov218a9002008-11-02 18:59:483856 if {$flags eq "+" || $flags eq "*"} {
3857 set cframe $top.fr$cnt
3858 incr cnt
3859 frame $cframe
3860 pack $cframe -in $top -fill x -pady 3 -padx 3
3861 set cexpand [expr {$flags eq "*"}]
Elijah Newren13d40b62009-03-23 17:57:463862 } elseif {$flags eq ".." || $flags eq "*."} {
3863 set cframe $top.fr$cnt
3864 incr cnt
3865 frame $cframe
3866 pack $cframe -in $top -fill x -pady 3 -padx [list 15 3]
3867 set cexpand [expr {$flags eq "*."}]
Alexander Gavrilov218a9002008-11-02 18:59:483868 } else {
3869 set lxpad 5
3870 }
3871
Elijah Newren13d40b62009-03-23 17:57:463872 if {$type eq "l"} {
3873 label $cframe.l_$id -text $title
3874 pack $cframe.l_$id -in $cframe -side left -pady [list 3 0] -anchor w
3875 } elseif {$type eq "b"} {
Alexander Gavrilov218a9002008-11-02 18:59:483876 checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
3877 pack $cframe.c_$id -in $cframe -side left \
3878 -padx [list $lxpad 0] -expand $cexpand -anchor w
Elijah Newren13d40b62009-03-23 17:57:463879 } elseif {[regexp {^r(\d+)$} $type type sz]} {
3880 regexp {^(.*_)} $id uselessvar button_id
3881 radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
3882 pack $cframe.c_$id -in $cframe -side left \
3883 -padx [list $lxpad 0] -expand $cexpand -anchor w
Alexander Gavrilov218a9002008-11-02 18:59:483884 } elseif {[regexp {^t(\d+)$} $type type sz]} {
3885 message $cframe.l_$id -aspect 1500 -text $title
3886 entry $cframe.e_$id -width $sz -background $bgcolor \
3887 -textvariable newviewopts($n,$id)
3888 pack $cframe.l_$id -in $cframe -side left -padx [list $lxpad 0]
3889 pack $cframe.e_$id -in $cframe -side left -expand 1 -fill x
3890 } elseif {[regexp {^t(\d+)=$} $type type sz]} {
3891 message $cframe.l_$id -aspect 1500 -text $title
3892 entry $cframe.e_$id -width $sz -background $bgcolor \
3893 -textvariable newviewopts($n,$id)
3894 pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w
3895 pack $cframe.e_$id -in $cframe -side top -fill x
Elijah Newren13d40b62009-03-23 17:57:463896 } elseif {$type eq "path"} {
3897 message $top.l -aspect 1500 -text $title
3898 pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
3899 text $top.t -width 40 -height 5 -background $bgcolor -font uifont
3900 if {[info exists viewfiles($n)]} {
3901 foreach f $viewfiles($n) {
3902 $top.t insert end $f
3903 $top.t insert end "\n"
3904 }
3905 $top.t delete {end - 1c} end
3906 $top.t mark set insert 0.0
3907 }
3908 pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
Alexander Gavrilov218a9002008-11-02 18:59:483909 }
3910 }
3911
Paul Mackerras50b44ec2006-04-04 00:16:223912 frame $top.buts
Paul Mackerrasb039f0a2008-01-06 04:54:463913 button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n]
Alexander Gavrilov218a9002008-11-02 18:59:483914 button $top.buts.apply -text [mc "Apply (F5)"] -command [list newviewok $top $n 1]
Paul Mackerrasb039f0a2008-01-06 04:54:463915 button $top.buts.can -text [mc "Cancel"] -command [list destroy $top]
Alexander Gavrilov218a9002008-11-02 18:59:483916 bind $top <Control-Return> [list newviewok $top $n]
3917 bind $top <F5> [list newviewok $top $n 1]
Alexander Gavrilov76f15942008-11-02 18:59:443918 bind $top <Escape> [list destroy $top]
Alexander Gavrilov218a9002008-11-02 18:59:483919 grid $top.buts.ok $top.buts.apply $top.buts.can
Paul Mackerras50b44ec2006-04-04 00:16:223920 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3921 grid columnconfigure $top.buts 1 -weight 1 -uniform a
Alexander Gavrilov218a9002008-11-02 18:59:483922 grid columnconfigure $top.buts 2 -weight 1 -uniform a
3923 pack $top.buts -in $top -side top -fill x
Paul Mackerras50b44ec2006-04-04 00:16:223924 focus $top.t
3925}
3926
Paul Mackerras908c3582006-05-19 23:38:113927proc doviewmenu {m first cmd op argv} {
Paul Mackerrasda7c24d2006-05-02 01:15:293928 set nmenu [$m index end]
3929 for {set i $first} {$i <= $nmenu} {incr i} {
3930 if {[$m entrycget $i -command] eq $cmd} {
Paul Mackerras908c3582006-05-19 23:38:113931 eval $m $op $i $argv
Paul Mackerrasda7c24d2006-05-02 01:15:293932 break
Paul Mackerrasd16c0812006-04-25 11:21:103933 }
3934 }
Paul Mackerrasda7c24d2006-05-02 01:15:293935}
3936
3937proc allviewmenus {n op args} {
Paul Mackerras687c8762007-09-22 02:49:333938 # global viewhlmenu
Paul Mackerras908c3582006-05-19 23:38:113939
Paul Mackerras3cd204e2006-11-23 10:06:163940 doviewmenu .bar.view 5 [list showview $n] $op $args
Paul Mackerras687c8762007-09-22 02:49:333941 # doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args
Paul Mackerrasd16c0812006-04-25 11:21:103942}
Paul Mackerras50b44ec2006-04-04 00:16:223943
Alexander Gavrilov218a9002008-11-02 18:59:483944proc newviewok {top n {apply 0}} {
Paul Mackerrasda7c24d2006-05-02 01:15:293945 global nextviewnum newviewperm newviewname newishighlight
Paul Mackerrasd16c0812006-04-25 11:21:103946 global viewname viewfiles viewperm selectedview curview
Alexander Gavrilov218a9002008-11-02 18:59:483947 global viewargs viewargscmd newviewopts viewhlmenu
Paul Mackerrasd16c0812006-04-25 11:21:103948
Paul Mackerras098dd8a2006-05-02 23:32:533949 if {[catch {
Alexander Gavrilov218a9002008-11-02 18:59:483950 set newargs [encode_view_opts $n]
Paul Mackerras098dd8a2006-05-02 23:32:533951 } err]} {
Alexander Gavrilov84a76f12008-11-02 18:59:453952 error_popup "[mc "Error in commit selection arguments:"] $err" $top
Paul Mackerras098dd8a2006-05-02 23:32:533953 return
3954 }
Paul Mackerras50b44ec2006-04-04 00:16:223955 set files {}
Paul Mackerrasd16c0812006-04-25 11:21:103956 foreach f [split [$top.t get 0.0 end] "\n"] {
Paul Mackerras50b44ec2006-04-04 00:16:223957 set ft [string trim $f]
3958 if {$ft ne {}} {
3959 lappend files $ft
3960 }
3961 }
Paul Mackerrasd16c0812006-04-25 11:21:103962 if {![info exists viewfiles($n)]} {
3963 # creating a new view
3964 incr nextviewnum
3965 set viewname($n) $newviewname($n)
Alexander Gavrilov218a9002008-11-02 18:59:483966 set viewperm($n) $newviewopts($n,perm)
Paul Mackerrasd16c0812006-04-25 11:21:103967 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-02 23:32:533968 set viewargs($n) $newargs
Alexander Gavrilov218a9002008-11-02 18:59:483969 set viewargscmd($n) $newviewopts($n,cmd)
Paul Mackerrasda7c24d2006-05-02 01:15:293970 addviewmenu $n
3971 if {!$newishighlight} {
Paul Mackerras7eb3cb92007-06-17 04:45:003972 run showview $n
Paul Mackerrasda7c24d2006-05-02 01:15:293973 } else {
Paul Mackerras7eb3cb92007-06-17 04:45:003974 run addvhighlight $n
Paul Mackerrasda7c24d2006-05-02 01:15:293975 }
Paul Mackerrasd16c0812006-04-25 11:21:103976 } else {
3977 # editing an existing view
Alexander Gavrilov218a9002008-11-02 18:59:483978 set viewperm($n) $newviewopts($n,perm)
Paul Mackerrasd16c0812006-04-25 11:21:103979 if {$newviewname($n) ne $viewname($n)} {
3980 set viewname($n) $newviewname($n)
Paul Mackerras3cd204e2006-11-23 10:06:163981 doviewmenu .bar.view 5 [list showview $n] \
Paul Mackerras908c3582006-05-19 23:38:113982 entryconf [list -label $viewname($n)]
Paul Mackerras687c8762007-09-22 02:49:333983 # doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
3984 # entryconf [list -label $viewname($n) -value $viewname($n)]
Paul Mackerrasd16c0812006-04-25 11:21:103985 }
Yann Dirson2d480852008-02-21 20:23:313986 if {$files ne $viewfiles($n) || $newargs ne $viewargs($n) || \
Alexander Gavrilov218a9002008-11-02 18:59:483987 $newviewopts($n,cmd) ne $viewargscmd($n)} {
Paul Mackerrasd16c0812006-04-25 11:21:103988 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-02 23:32:533989 set viewargs($n) $newargs
Alexander Gavrilov218a9002008-11-02 18:59:483990 set viewargscmd($n) $newviewopts($n,cmd)
Paul Mackerrasd16c0812006-04-25 11:21:103991 if {$curview == $n} {
Paul Mackerras7fcc92b2007-12-02 23:33:013992 run reloadcommits
Paul Mackerrasd16c0812006-04-25 11:21:103993 }
3994 }
3995 }
Alexander Gavrilov218a9002008-11-02 18:59:483996 if {$apply} return
Paul Mackerrasd16c0812006-04-25 11:21:103997 catch {destroy $top}
Paul Mackerras50b44ec2006-04-04 00:16:223998}
3999
4000proc delview {} {
Paul Mackerras7fcc92b2007-12-02 23:33:014001 global curview viewperm hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 00:16:224002
4003 if {$curview == 0} return
Paul Mackerras908c3582006-05-19 23:38:114004 if {[info exists hlview] && $hlview == $curview} {
Christian Stimmingb007ee22007-11-07 17:44:354005 set selectedhlview [mc "None"]
Paul Mackerras908c3582006-05-19 23:38:114006 unset hlview
4007 }
Paul Mackerrasda7c24d2006-05-02 01:15:294008 allviewmenus $curview delete
Paul Mackerrasa90a6d22006-04-25 07:12:464009 set viewperm($curview) 0
Paul Mackerras50b44ec2006-04-04 00:16:224010 showview 0
4011}
4012
Paul Mackerrasda7c24d2006-05-02 01:15:294013proc addviewmenu {n} {
Paul Mackerras908c3582006-05-19 23:38:114014 global viewname viewhlmenu
Paul Mackerrasda7c24d2006-05-02 01:15:294015
4016 .bar.view add radiobutton -label $viewname($n) \
4017 -command [list showview $n] -variable selectedview -value $n
Paul Mackerras687c8762007-09-22 02:49:334018 #$viewhlmenu add radiobutton -label $viewname($n) \
4019 # -command [list addvhighlight $n] -variable selectedhlview
Paul Mackerrasda7c24d2006-05-02 01:15:294020}
4021
Paul Mackerras50b44ec2006-04-04 00:16:224022proc showview {n} {
Paul Mackerras3ed31a82008-04-26 06:00:004023 global curview cached_commitrow ordertok
Paul Mackerrasf5f3c2e2007-09-04 16:19:564024 global displayorder parentlist rowidlist rowisopt rowfinal
Paul Mackerras7fcc92b2007-12-02 23:33:014025 global colormap rowtextx nextcolor canvxmax
4026 global numcommits viewcomplete
Paul Mackerras50b44ec2006-04-04 00:16:224027 global selectedline currentid canv canvy0
Paul Mackerras4fb0fa12007-07-04 09:43:514028 global treediffs
Paul Mackerras3e766082008-01-13 06:26:304029 global pending_select mainheadid
Paul Mackerras03800812007-08-29 11:45:214030 global commitidx
Paul Mackerras3e766082008-01-13 06:26:304031 global selectedview
Paul Mackerras97645682007-08-23 12:24:384032 global hlview selectedhlview commitinterest
Paul Mackerras50b44ec2006-04-04 00:16:224033
4034 if {$n == $curview} return
4035 set selid {}
Paul Mackerras7fcc92b2007-12-02 23:33:014036 set ymax [lindex [$canv cget -scrollregion] 3]
4037 set span [$canv yview]
4038 set ytop [expr {[lindex $span 0] * $ymax}]
4039 set ybot [expr {[lindex $span 1] * $ymax}]
4040 set yscreen [expr {($ybot - $ytop) / 2}]
Paul Mackerras94b4a692008-05-20 10:51:064041 if {$selectedline ne {}} {
Paul Mackerras50b44ec2006-04-04 00:16:224042 set selid $currentid
4043 set y [yc $selectedline]
Paul Mackerras50b44ec2006-04-04 00:16:224044 if {$ytop < $y && $y < $ybot} {
4045 set yscreen [expr {$y - $ytop}]
Paul Mackerras50b44ec2006-04-04 00:16:224046 }
Paul Mackerrase507fd42007-06-16 11:51:084047 } elseif {[info exists pending_select]} {
4048 set selid $pending_select
4049 unset pending_select
Paul Mackerras50b44ec2006-04-04 00:16:224050 }
4051 unselectline
Paul Mackerrasfdedbcf2006-04-06 11:22:524052 normalline
Paul Mackerras50b44ec2006-04-04 00:16:224053 catch {unset treediffs}
4054 clear_display
Paul Mackerras908c3582006-05-19 23:38:114055 if {[info exists hlview] && $hlview == $n} {
4056 unset hlview
Christian Stimmingb007ee22007-11-07 17:44:354057 set selectedhlview [mc "None"]
Paul Mackerras908c3582006-05-19 23:38:114058 }
Paul Mackerras97645682007-08-23 12:24:384059 catch {unset commitinterest}
Paul Mackerras7fcc92b2007-12-02 23:33:014060 catch {unset cached_commitrow}
Paul Mackerras9257d8f2007-12-10 23:45:384061 catch {unset ordertok}
Paul Mackerras50b44ec2006-04-04 00:16:224062
4063 set curview $n
Paul Mackerrasa90a6d22006-04-25 07:12:464064 set selectedview $n
Paul Mackerrasf2d0bbb2008-10-17 11:44:424065 .bar.view entryconf [mca "Edit view..."] -state [expr {$n == 0? "disabled": "normal"}]
4066 .bar.view entryconf [mca "Delete view"] -state [expr {$n == 0? "disabled": "normal"}]
Paul Mackerras50b44ec2006-04-04 00:16:224067
Paul Mackerrasdf904492007-08-29 12:03:074068 run refill_reflist
Paul Mackerras7fcc92b2007-12-02 23:33:014069 if {![info exists viewcomplete($n)]} {
Alexander Gavrilov567c34e2008-07-26 16:13:454070 getcommits $selid
Paul Mackerras50b44ec2006-04-04 00:16:224071 return
4072 }
4073
Paul Mackerras7fcc92b2007-12-02 23:33:014074 set displayorder {}
4075 set parentlist {}
4076 set rowidlist {}
4077 set rowisopt {}
4078 set rowfinal {}
Paul Mackerrasf5f3c2e2007-09-04 16:19:564079 set numcommits $commitidx($n)
Paul Mackerras22626ef2006-04-16 23:56:024080
Paul Mackerras50b44ec2006-04-04 00:16:224081 catch {unset colormap}
4082 catch {unset rowtextx}
Paul Mackerrasda7c24d2006-05-02 01:15:294083 set nextcolor 0
4084 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 00:16:224085 set curview $n
4086 set row 0
Paul Mackerras50b44ec2006-04-04 00:16:224087 setcanvscroll
4088 set yf 0
Paul Mackerrase507fd42007-06-16 11:51:084089 set row {}
Paul Mackerras7fcc92b2007-12-02 23:33:014090 if {$selid ne {} && [commitinview $selid $n]} {
4091 set row [rowofcommit $selid]
Paul Mackerras50b44ec2006-04-04 00:16:224092 # try to get the selected row in the same position on the screen
4093 set ymax [lindex [$canv cget -scrollregion] 3]
4094 set ytop [expr {[yc $row] - $yscreen}]
4095 if {$ytop < 0} {
4096 set ytop 0
4097 }
4098 set yf [expr {$ytop * 1.0 / $ymax}]
4099 }
4100 allcanvs yview moveto $yf
4101 drawvisible
Paul Mackerrase507fd42007-06-16 11:51:084102 if {$row ne {}} {
4103 selectline $row 0
Paul Mackerras3e766082008-01-13 06:26:304104 } elseif {!$viewcomplete($n)} {
Alexander Gavrilov567c34e2008-07-26 16:13:454105 reset_pending_select $selid
Paul Mackerrase507fd42007-06-16 11:51:084106 } else {
Alexander Gavrilov835e62a2008-07-26 16:15:544107 reset_pending_select {}
4108
4109 if {[commitinview $pending_select $curview]} {
4110 selectline [rowofcommit $pending_select] 1
4111 } else {
4112 set row [first_real_row]
4113 if {$row < $numcommits} {
4114 selectline $row 0
4115 }
Paul Mackerrase507fd42007-06-16 11:51:084116 }
4117 }
Paul Mackerras7fcc92b2007-12-02 23:33:014118 if {!$viewcomplete($n)} {
4119 if {$numcommits == 0} {
Christian Stimmingd990ced2007-11-07 17:42:554120 show_status [mc "Reading commits..."]
Paul Mackerrasd16c0812006-04-25 11:21:104121 }
Paul Mackerras098dd8a2006-05-02 23:32:534122 } elseif {$numcommits == 0} {
Christian Stimmingd990ced2007-11-07 17:42:554123 show_status [mc "No commits selected"]
Paul Mackerras2516dae2006-04-21 00:35:314124 }
Paul Mackerras50b44ec2006-04-04 00:16:224125}
4126
Paul Mackerras908c3582006-05-19 23:38:114127# Stuff relating to the highlighting facility
4128
Paul Mackerras476ca632008-01-07 11:16:314129proc ishighlighted {id} {
Paul Mackerras164ff272006-05-29 09:50:024130 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras908c3582006-05-19 23:38:114131
Paul Mackerras476ca632008-01-07 11:16:314132 if {[info exists nhighlights($id)] && $nhighlights($id) > 0} {
4133 return $nhighlights($id)
Paul Mackerras908c3582006-05-19 23:38:114134 }
Paul Mackerras476ca632008-01-07 11:16:314135 if {[info exists vhighlights($id)] && $vhighlights($id) > 0} {
4136 return $vhighlights($id)
Paul Mackerras908c3582006-05-19 23:38:114137 }
Paul Mackerras476ca632008-01-07 11:16:314138 if {[info exists fhighlights($id)] && $fhighlights($id) > 0} {
4139 return $fhighlights($id)
Paul Mackerras908c3582006-05-19 23:38:114140 }
Paul Mackerras476ca632008-01-07 11:16:314141 if {[info exists rhighlights($id)] && $rhighlights($id) > 0} {
4142 return $rhighlights($id)
Paul Mackerras164ff272006-05-29 09:50:024143 }
Paul Mackerras908c3582006-05-19 23:38:114144 return 0
4145}
4146
Paul Mackerras28593d32008-11-13 12:01:464147proc bolden {id font} {
Paul Mackerrasb9fdba72009-04-08 23:34:464148 global canv linehtag currentid boldids need_redisplay markedid
Paul Mackerras908c3582006-05-19 23:38:114149
Paul Mackerrasd98d50e2008-11-13 11:39:004150 # need_redisplay = 1 means the display is stale and about to be redrawn
4151 if {$need_redisplay} return
Paul Mackerras28593d32008-11-13 12:01:464152 lappend boldids $id
4153 $canv itemconf $linehtag($id) -font $font
4154 if {[info exists currentid] && $id eq $currentid} {
Paul Mackerras908c3582006-05-19 23:38:114155 $canv delete secsel
Paul Mackerras28593d32008-11-13 12:01:464156 set t [eval $canv create rect [$canv bbox $linehtag($id)] \
Paul Mackerras908c3582006-05-19 23:38:114157 -outline {{}} -tags secsel \
4158 -fill [$canv cget -selectbackground]]
4159 $canv lower $t
4160 }
Paul Mackerrasb9fdba72009-04-08 23:34:464161 if {[info exists markedid] && $id eq $markedid} {
4162 make_idmark $id
4163 }
Paul Mackerras908c3582006-05-19 23:38:114164}
4165
Paul Mackerras28593d32008-11-13 12:01:464166proc bolden_name {id font} {
4167 global canv2 linentag currentid boldnameids need_redisplay
Paul Mackerras908c3582006-05-19 23:38:114168
Paul Mackerrasd98d50e2008-11-13 11:39:004169 if {$need_redisplay} return
Paul Mackerras28593d32008-11-13 12:01:464170 lappend boldnameids $id
4171 $canv2 itemconf $linentag($id) -font $font
4172 if {[info exists currentid] && $id eq $currentid} {
Paul Mackerras908c3582006-05-19 23:38:114173 $canv2 delete secsel
Paul Mackerras28593d32008-11-13 12:01:464174 set t [eval $canv2 create rect [$canv2 bbox $linentag($id)] \
Paul Mackerras908c3582006-05-19 23:38:114175 -outline {{}} -tags secsel \
4176 -fill [$canv2 cget -selectbackground]]
4177 $canv2 lower $t
4178 }
4179}
4180
Paul Mackerras4e7d6772006-05-30 11:33:074181proc unbolden {} {
Paul Mackerras28593d32008-11-13 12:01:464182 global boldids
Paul Mackerras908c3582006-05-19 23:38:114183
Paul Mackerras4e7d6772006-05-30 11:33:074184 set stillbold {}
Paul Mackerras28593d32008-11-13 12:01:464185 foreach id $boldids {
4186 if {![ishighlighted $id]} {
4187 bolden $id mainfont
Paul Mackerras4e7d6772006-05-30 11:33:074188 } else {
Paul Mackerras28593d32008-11-13 12:01:464189 lappend stillbold $id
Paul Mackerras908c3582006-05-19 23:38:114190 }
4191 }
Paul Mackerras28593d32008-11-13 12:01:464192 set boldids $stillbold
Paul Mackerras908c3582006-05-19 23:38:114193}
4194
4195proc addvhighlight {n} {
Paul Mackerras476ca632008-01-07 11:16:314196 global hlview viewcomplete curview vhl_done commitidx
Paul Mackerrasda7c24d2006-05-02 01:15:294197
4198 if {[info exists hlview]} {
Paul Mackerras908c3582006-05-19 23:38:114199 delvhighlight
Paul Mackerrasda7c24d2006-05-02 01:15:294200 }
4201 set hlview $n
Paul Mackerras7fcc92b2007-12-02 23:33:014202 if {$n != $curview && ![info exists viewcomplete($n)]} {
Paul Mackerrasda7c24d2006-05-02 01:15:294203 start_rev_list $n
Paul Mackerras908c3582006-05-19 23:38:114204 }
4205 set vhl_done $commitidx($hlview)
4206 if {$vhl_done > 0} {
4207 drawvisible
Paul Mackerrasda7c24d2006-05-02 01:15:294208 }
4209}
4210
Paul Mackerras908c3582006-05-19 23:38:114211proc delvhighlight {} {
4212 global hlview vhighlights
Paul Mackerrasda7c24d2006-05-02 01:15:294213
4214 if {![info exists hlview]} return
4215 unset hlview
Paul Mackerras4e7d6772006-05-30 11:33:074216 catch {unset vhighlights}
4217 unbolden
Paul Mackerrasda7c24d2006-05-02 01:15:294218}
4219
Paul Mackerras908c3582006-05-19 23:38:114220proc vhighlightmore {} {
Paul Mackerras7fcc92b2007-12-02 23:33:014221 global hlview vhl_done commitidx vhighlights curview
Paul Mackerrasda7c24d2006-05-02 01:15:294222
Paul Mackerrasda7c24d2006-05-02 01:15:294223 set max $commitidx($hlview)
Paul Mackerras908c3582006-05-19 23:38:114224 set vr [visiblerows]
4225 set r0 [lindex $vr 0]
4226 set r1 [lindex $vr 1]
4227 for {set i $vhl_done} {$i < $max} {incr i} {
Paul Mackerras7fcc92b2007-12-02 23:33:014228 set id [commitonrow $i $hlview]
4229 if {[commitinview $id $curview]} {
4230 set row [rowofcommit $id]
Paul Mackerras908c3582006-05-19 23:38:114231 if {$r0 <= $row && $row <= $r1} {
4232 if {![highlighted $row]} {
Paul Mackerras28593d32008-11-13 12:01:464233 bolden $id mainfontbold
Paul Mackerrasda7c24d2006-05-02 01:15:294234 }
Paul Mackerras476ca632008-01-07 11:16:314235 set vhighlights($id) 1
Paul Mackerrasda7c24d2006-05-02 01:15:294236 }
4237 }
4238 }
Paul Mackerras908c3582006-05-19 23:38:114239 set vhl_done $max
Paul Mackerrasac1276a2008-03-02 23:11:084240 return 0
Paul Mackerras908c3582006-05-19 23:38:114241}
4242
4243proc askvhighlight {row id} {
Paul Mackerras7fcc92b2007-12-02 23:33:014244 global hlview vhighlights iddrawn
Paul Mackerras908c3582006-05-19 23:38:114245
Paul Mackerras7fcc92b2007-12-02 23:33:014246 if {[commitinview $id $hlview]} {
Paul Mackerras476ca632008-01-07 11:16:314247 if {[info exists iddrawn($id)] && ![ishighlighted $id]} {
Paul Mackerras28593d32008-11-13 12:01:464248 bolden $id mainfontbold
Paul Mackerras908c3582006-05-19 23:38:114249 }
Paul Mackerras476ca632008-01-07 11:16:314250 set vhighlights($id) 1
Paul Mackerras908c3582006-05-19 23:38:114251 } else {
Paul Mackerras476ca632008-01-07 11:16:314252 set vhighlights($id) 0
Paul Mackerras908c3582006-05-19 23:38:114253 }
4254}
4255
Paul Mackerras687c8762007-09-22 02:49:334256proc hfiles_change {} {
Paul Mackerras908c3582006-05-19 23:38:114257 global highlight_files filehighlight fhighlights fh_serial
Paul Mackerras8b39e042008-12-01 22:02:464258 global highlight_paths
Paul Mackerras908c3582006-05-19 23:38:114259
4260 if {[info exists filehighlight]} {
4261 # delete previous highlights
4262 catch {close $filehighlight}
4263 unset filehighlight
Paul Mackerras4e7d6772006-05-30 11:33:074264 catch {unset fhighlights}
4265 unbolden
Paul Mackerras63b79192006-05-20 11:31:524266 unhighlight_filelist
Paul Mackerras908c3582006-05-19 23:38:114267 }
Paul Mackerras63b79192006-05-20 11:31:524268 set highlight_paths {}
Paul Mackerras908c3582006-05-19 23:38:114269 after cancel do_file_hl $fh_serial
4270 incr fh_serial
4271 if {$highlight_files ne {}} {
4272 after 300 do_file_hl $fh_serial
4273 }
4274}
4275
Paul Mackerras687c8762007-09-22 02:49:334276proc gdttype_change {name ix op} {
4277 global gdttype highlight_files findstring findpattern
4278
Paul Mackerrasbb3edc82007-09-27 01:00:254279 stopfinding
Paul Mackerras687c8762007-09-22 02:49:334280 if {$findstring ne {}} {
Christian Stimmingb007ee22007-11-07 17:44:354281 if {$gdttype eq [mc "containing:"]} {
Paul Mackerras687c8762007-09-22 02:49:334282 if {$highlight_files ne {}} {
4283 set highlight_files {}
4284 hfiles_change
4285 }
4286 findcom_change
4287 } else {
4288 if {$findpattern ne {}} {
4289 set findpattern {}
4290 findcom_change
4291 }
4292 set highlight_files $findstring
4293 hfiles_change
4294 }
4295 drawvisible
4296 }
4297 # enable/disable findtype/findloc menus too
4298}
4299
4300proc find_change {name ix op} {
4301 global gdttype findstring highlight_files
4302
Paul Mackerrasbb3edc82007-09-27 01:00:254303 stopfinding
Christian Stimmingb007ee22007-11-07 17:44:354304 if {$gdttype eq [mc "containing:"]} {
Paul Mackerras687c8762007-09-22 02:49:334305 findcom_change
4306 } else {
4307 if {$highlight_files ne $findstring} {
4308 set highlight_files $findstring
4309 hfiles_change
4310 }
4311 }
4312 drawvisible
4313}
4314
Paul Mackerras64b5f142007-10-04 12:19:244315proc findcom_change args {
Paul Mackerras28593d32008-11-13 12:01:464316 global nhighlights boldnameids
Paul Mackerras687c8762007-09-22 02:49:334317 global findpattern findtype findstring gdttype
4318
Paul Mackerrasbb3edc82007-09-27 01:00:254319 stopfinding
Paul Mackerras687c8762007-09-22 02:49:334320 # delete previous highlights, if any
Paul Mackerras28593d32008-11-13 12:01:464321 foreach id $boldnameids {
4322 bolden_name $id mainfont
Paul Mackerras687c8762007-09-22 02:49:334323 }
Paul Mackerras28593d32008-11-13 12:01:464324 set boldnameids {}
Paul Mackerras687c8762007-09-22 02:49:334325 catch {unset nhighlights}
4326 unbolden
4327 unmarkmatches
Christian Stimmingb007ee22007-11-07 17:44:354328 if {$gdttype ne [mc "containing:"] || $findstring eq {}} {
Paul Mackerras687c8762007-09-22 02:49:334329 set findpattern {}
Christian Stimmingb007ee22007-11-07 17:44:354330 } elseif {$findtype eq [mc "Regexp"]} {
Paul Mackerras687c8762007-09-22 02:49:334331 set findpattern $findstring
4332 } else {
4333 set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
4334 $findstring]
4335 set findpattern "*$e*"
4336 }
4337}
4338
Paul Mackerras63b79192006-05-20 11:31:524339proc makepatterns {l} {
4340 set ret {}
4341 foreach e $l {
4342 set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e]
4343 if {[string index $ee end] eq "/"} {
4344 lappend ret "$ee*"
4345 } else {
4346 lappend ret $ee
4347 lappend ret "$ee/*"
4348 }
4349 }
4350 return $ret
4351}
4352
Paul Mackerras908c3582006-05-19 23:38:114353proc do_file_hl {serial} {
Paul Mackerras4e7d6772006-05-30 11:33:074354 global highlight_files filehighlight highlight_paths gdttype fhl_list
Paul Mackerras908c3582006-05-19 23:38:114355
Christian Stimmingb007ee22007-11-07 17:44:354356 if {$gdttype eq [mc "touching paths:"]} {
Paul Mackerras60f7a7d2006-05-26 00:43:474357 if {[catch {set paths [shellsplit $highlight_files]}]} return
4358 set highlight_paths [makepatterns $paths]
4359 highlight_filelist
4360 set gdtargs [concat -- $paths]
Christian Stimmingb007ee22007-11-07 17:44:354361 } elseif {$gdttype eq [mc "adding/removing string:"]} {
Paul Mackerras60f7a7d2006-05-26 00:43:474362 set gdtargs [list "-S$highlight_files"]
Paul Mackerras687c8762007-09-22 02:49:334363 } else {
4364 # must be "containing:", i.e. we're searching commit info
4365 return
Paul Mackerras60f7a7d2006-05-26 00:43:474366 }
Brandon Casey1ce09dd2007-03-19 23:00:374367 set cmd [concat | git diff-tree -r -s --stdin $gdtargs]
Paul Mackerras908c3582006-05-19 23:38:114368 set filehighlight [open $cmd r+]
4369 fconfigure $filehighlight -blocking 0
Paul Mackerras7eb3cb92007-06-17 04:45:004370 filerun $filehighlight readfhighlight
Paul Mackerras4e7d6772006-05-30 11:33:074371 set fhl_list {}
Paul Mackerras908c3582006-05-19 23:38:114372 drawvisible
4373 flushhighlights
4374}
4375
4376proc flushhighlights {} {
Paul Mackerras4e7d6772006-05-30 11:33:074377 global filehighlight fhl_list
Paul Mackerras908c3582006-05-19 23:38:114378
4379 if {[info exists filehighlight]} {
Paul Mackerras4e7d6772006-05-30 11:33:074380 lappend fhl_list {}
Paul Mackerras908c3582006-05-19 23:38:114381 puts $filehighlight ""
4382 flush $filehighlight
4383 }
4384}
4385
4386proc askfilehighlight {row id} {
Paul Mackerras4e7d6772006-05-30 11:33:074387 global filehighlight fhighlights fhl_list
Paul Mackerras908c3582006-05-19 23:38:114388
Paul Mackerras4e7d6772006-05-30 11:33:074389 lappend fhl_list $id
Paul Mackerras476ca632008-01-07 11:16:314390 set fhighlights($id) -1
Paul Mackerras908c3582006-05-19 23:38:114391 puts $filehighlight $id
4392}
4393
4394proc readfhighlight {} {
Paul Mackerras7fcc92b2007-12-02 23:33:014395 global filehighlight fhighlights curview iddrawn
Paul Mackerras687c8762007-09-22 02:49:334396 global fhl_list find_dirn
Paul Mackerras908c3582006-05-19 23:38:114397
Paul Mackerras7eb3cb92007-06-17 04:45:004398 if {![info exists filehighlight]} {
4399 return 0
4400 }
4401 set nr 0
4402 while {[incr nr] <= 100 && [gets $filehighlight line] >= 0} {
Paul Mackerras4e7d6772006-05-30 11:33:074403 set line [string trim $line]
4404 set i [lsearch -exact $fhl_list $line]
4405 if {$i < 0} continue
4406 for {set j 0} {$j < $i} {incr j} {
4407 set id [lindex $fhl_list $j]
Paul Mackerras476ca632008-01-07 11:16:314408 set fhighlights($id) 0
Paul Mackerras908c3582006-05-19 23:38:114409 }
Paul Mackerras4e7d6772006-05-30 11:33:074410 set fhl_list [lrange $fhl_list [expr {$i+1}] end]
4411 if {$line eq {}} continue
Paul Mackerras7fcc92b2007-12-02 23:33:014412 if {![commitinview $line $curview]} continue
Paul Mackerras476ca632008-01-07 11:16:314413 if {[info exists iddrawn($line)] && ![ishighlighted $line]} {
Paul Mackerras28593d32008-11-13 12:01:464414 bolden $line mainfontbold
Paul Mackerras4e7d6772006-05-30 11:33:074415 }
Paul Mackerras476ca632008-01-07 11:16:314416 set fhighlights($line) 1
Paul Mackerras908c3582006-05-19 23:38:114417 }
Paul Mackerras4e7d6772006-05-30 11:33:074418 if {[eof $filehighlight]} {
4419 # strange...
Brandon Casey1ce09dd2007-03-19 23:00:374420 puts "oops, git diff-tree died"
Paul Mackerras4e7d6772006-05-30 11:33:074421 catch {close $filehighlight}
4422 unset filehighlight
Paul Mackerras7eb3cb92007-06-17 04:45:004423 return 0
Paul Mackerras908c3582006-05-19 23:38:114424 }
Paul Mackerras687c8762007-09-22 02:49:334425 if {[info exists find_dirn]} {
Paul Mackerrascca5d942007-10-27 11:16:564426 run findmore
Paul Mackerras687c8762007-09-22 02:49:334427 }
Paul Mackerras7eb3cb92007-06-17 04:45:004428 return 1
Paul Mackerras908c3582006-05-19 23:38:114429}
4430
Paul Mackerras4fb0fa12007-07-04 09:43:514431proc doesmatch {f} {
Paul Mackerras687c8762007-09-22 02:49:334432 global findtype findpattern
Paul Mackerras4fb0fa12007-07-04 09:43:514433
Christian Stimmingb007ee22007-11-07 17:44:354434 if {$findtype eq [mc "Regexp"]} {
Paul Mackerras687c8762007-09-22 02:49:334435 return [regexp $findpattern $f]
Christian Stimmingb007ee22007-11-07 17:44:354436 } elseif {$findtype eq [mc "IgnCase"]} {
Paul Mackerras4fb0fa12007-07-04 09:43:514437 return [string match -nocase $findpattern $f]
4438 } else {
4439 return [string match $findpattern $f]
4440 }
4441}
4442
Paul Mackerras60f7a7d2006-05-26 00:43:474443proc askfindhighlight {row id} {
Paul Mackerras9c311b32007-10-04 12:27:134444 global nhighlights commitinfo iddrawn
Paul Mackerras4fb0fa12007-07-04 09:43:514445 global findloc
4446 global markingmatches
Paul Mackerras908c3582006-05-19 23:38:114447
4448 if {![info exists commitinfo($id)]} {
4449 getcommit $id
4450 }
Paul Mackerras60f7a7d2006-05-26 00:43:474451 set info $commitinfo($id)
Paul Mackerras908c3582006-05-19 23:38:114452 set isbold 0
Christian Stimmingb007ee22007-11-07 17:44:354453 set fldtypes [list [mc Headline] [mc Author] [mc Date] [mc Committer] [mc CDate] [mc Comments]]
Paul Mackerras60f7a7d2006-05-26 00:43:474454 foreach f $info ty $fldtypes {
Christian Stimmingb007ee22007-11-07 17:44:354455 if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
Paul Mackerras4fb0fa12007-07-04 09:43:514456 [doesmatch $f]} {
Christian Stimmingb007ee22007-11-07 17:44:354457 if {$ty eq [mc "Author"]} {
Paul Mackerras60f7a7d2006-05-26 00:43:474458 set isbold 2
Paul Mackerras4fb0fa12007-07-04 09:43:514459 break
Paul Mackerras60f7a7d2006-05-26 00:43:474460 }
Paul Mackerras4fb0fa12007-07-04 09:43:514461 set isbold 1
Paul Mackerras908c3582006-05-19 23:38:114462 }
4463 }
Paul Mackerras4fb0fa12007-07-04 09:43:514464 if {$isbold && [info exists iddrawn($id)]} {
Paul Mackerras476ca632008-01-07 11:16:314465 if {![ishighlighted $id]} {
Paul Mackerras28593d32008-11-13 12:01:464466 bolden $id mainfontbold
Paul Mackerras4fb0fa12007-07-04 09:43:514467 if {$isbold > 1} {
Paul Mackerras28593d32008-11-13 12:01:464468 bolden_name $id mainfontbold
Paul Mackerras4fb0fa12007-07-04 09:43:514469 }
Paul Mackerras908c3582006-05-19 23:38:114470 }
Paul Mackerras4fb0fa12007-07-04 09:43:514471 if {$markingmatches} {
Paul Mackerras005a2f42007-07-26 12:36:394472 markrowmatches $row $id
Paul Mackerras908c3582006-05-19 23:38:114473 }
4474 }
Paul Mackerras476ca632008-01-07 11:16:314475 set nhighlights($id) $isbold
Paul Mackerrasda7c24d2006-05-02 01:15:294476}
4477
Paul Mackerras005a2f42007-07-26 12:36:394478proc markrowmatches {row id} {
4479 global canv canv2 linehtag linentag commitinfo findloc
Paul Mackerras4fb0fa12007-07-04 09:43:514480
Paul Mackerras005a2f42007-07-26 12:36:394481 set headline [lindex $commitinfo($id) 0]
4482 set author [lindex $commitinfo($id) 1]
Paul Mackerras4fb0fa12007-07-04 09:43:514483 $canv delete match$row
4484 $canv2 delete match$row
Christian Stimmingb007ee22007-11-07 17:44:354485 if {$findloc eq [mc "All fields"] || $findloc eq [mc "Headline"]} {
Paul Mackerras005a2f42007-07-26 12:36:394486 set m [findmatches $headline]
4487 if {$m ne {}} {
Paul Mackerras28593d32008-11-13 12:01:464488 markmatches $canv $row $headline $linehtag($id) $m \
4489 [$canv itemcget $linehtag($id) -font] $row
Paul Mackerras005a2f42007-07-26 12:36:394490 }
Paul Mackerras4fb0fa12007-07-04 09:43:514491 }
Christian Stimmingb007ee22007-11-07 17:44:354492 if {$findloc eq [mc "All fields"] || $findloc eq [mc "Author"]} {
Paul Mackerras005a2f42007-07-26 12:36:394493 set m [findmatches $author]
4494 if {$m ne {}} {
Paul Mackerras28593d32008-11-13 12:01:464495 markmatches $canv2 $row $author $linentag($id) $m \
4496 [$canv2 itemcget $linentag($id) -font] $row
Paul Mackerras005a2f42007-07-26 12:36:394497 }
Paul Mackerras4fb0fa12007-07-04 09:43:514498 }
4499}
4500
Paul Mackerras164ff272006-05-29 09:50:024501proc vrel_change {name ix op} {
4502 global highlight_related
4503
4504 rhighlight_none
Christian Stimmingb007ee22007-11-07 17:44:354505 if {$highlight_related ne [mc "None"]} {
Paul Mackerras7eb3cb92007-06-17 04:45:004506 run drawvisible
Paul Mackerras164ff272006-05-29 09:50:024507 }
4508}
4509
4510# prepare for testing whether commits are descendents or ancestors of a
4511proc rhighlight_sel {a} {
4512 global descendent desc_todo ancestor anc_todo
Paul Mackerras476ca632008-01-07 11:16:314513 global highlight_related
Paul Mackerras164ff272006-05-29 09:50:024514
4515 catch {unset descendent}
4516 set desc_todo [list $a]
4517 catch {unset ancestor}
4518 set anc_todo [list $a]
Christian Stimmingb007ee22007-11-07 17:44:354519 if {$highlight_related ne [mc "None"]} {
Paul Mackerras164ff272006-05-29 09:50:024520 rhighlight_none
Paul Mackerras7eb3cb92007-06-17 04:45:004521 run drawvisible
Paul Mackerras164ff272006-05-29 09:50:024522 }
4523}
4524
4525proc rhighlight_none {} {
4526 global rhighlights
4527
Paul Mackerras4e7d6772006-05-30 11:33:074528 catch {unset rhighlights}
4529 unbolden
Paul Mackerras164ff272006-05-29 09:50:024530}
4531
4532proc is_descendent {a} {
Paul Mackerras7fcc92b2007-12-02 23:33:014533 global curview children descendent desc_todo
Paul Mackerras164ff272006-05-29 09:50:024534
4535 set v $curview
Paul Mackerras7fcc92b2007-12-02 23:33:014536 set la [rowofcommit $a]
Paul Mackerras164ff272006-05-29 09:50:024537 set todo $desc_todo
4538 set leftover {}
4539 set done 0
4540 for {set i 0} {$i < [llength $todo]} {incr i} {
4541 set do [lindex $todo $i]
Paul Mackerras7fcc92b2007-12-02 23:33:014542 if {[rowofcommit $do] < $la} {
Paul Mackerras164ff272006-05-29 09:50:024543 lappend leftover $do
4544 continue
4545 }
4546 foreach nk $children($v,$do) {
4547 if {![info exists descendent($nk)]} {
4548 set descendent($nk) 1
4549 lappend todo $nk
4550 if {$nk eq $a} {
4551 set done 1
4552 }
4553 }
4554 }
4555 if {$done} {
4556 set desc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
4557 return
4558 }
4559 }
4560 set descendent($a) 0
4561 set desc_todo $leftover
4562}
4563
4564proc is_ancestor {a} {
Paul Mackerras7fcc92b2007-12-02 23:33:014565 global curview parents ancestor anc_todo
Paul Mackerras164ff272006-05-29 09:50:024566
4567 set v $curview
Paul Mackerras7fcc92b2007-12-02 23:33:014568 set la [rowofcommit $a]
Paul Mackerras164ff272006-05-29 09:50:024569 set todo $anc_todo
4570 set leftover {}
4571 set done 0
4572 for {set i 0} {$i < [llength $todo]} {incr i} {
4573 set do [lindex $todo $i]
Paul Mackerras7fcc92b2007-12-02 23:33:014574 if {![commitinview $do $v] || [rowofcommit $do] > $la} {
Paul Mackerras164ff272006-05-29 09:50:024575 lappend leftover $do
4576 continue
4577 }
Paul Mackerras7fcc92b2007-12-02 23:33:014578 foreach np $parents($v,$do) {
Paul Mackerras164ff272006-05-29 09:50:024579 if {![info exists ancestor($np)]} {
4580 set ancestor($np) 1
4581 lappend todo $np
4582 if {$np eq $a} {
4583 set done 1
4584 }
4585 }
4586 }
4587 if {$done} {
4588 set anc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
4589 return
4590 }
4591 }
4592 set ancestor($a) 0
4593 set anc_todo $leftover
4594}
4595
4596proc askrelhighlight {row id} {
Paul Mackerras9c311b32007-10-04 12:27:134597 global descendent highlight_related iddrawn rhighlights
Paul Mackerras164ff272006-05-29 09:50:024598 global selectedline ancestor
4599
Paul Mackerras94b4a692008-05-20 10:51:064600 if {$selectedline eq {}} return
Paul Mackerras164ff272006-05-29 09:50:024601 set isbold 0
Christian Stimming55e34432008-01-09 21:23:184602 if {$highlight_related eq [mc "Descendant"] ||
4603 $highlight_related eq [mc "Not descendant"]} {
Paul Mackerras164ff272006-05-29 09:50:024604 if {![info exists descendent($id)]} {
4605 is_descendent $id
4606 }
Christian Stimming55e34432008-01-09 21:23:184607 if {$descendent($id) == ($highlight_related eq [mc "Descendant"])} {
Paul Mackerras164ff272006-05-29 09:50:024608 set isbold 1
4609 }
Christian Stimmingb007ee22007-11-07 17:44:354610 } elseif {$highlight_related eq [mc "Ancestor"] ||
4611 $highlight_related eq [mc "Not ancestor"]} {
Paul Mackerras164ff272006-05-29 09:50:024612 if {![info exists ancestor($id)]} {
4613 is_ancestor $id
4614 }
Christian Stimmingb007ee22007-11-07 17:44:354615 if {$ancestor($id) == ($highlight_related eq [mc "Ancestor"])} {
Paul Mackerras164ff272006-05-29 09:50:024616 set isbold 1
4617 }
4618 }
4619 if {[info exists iddrawn($id)]} {
Paul Mackerras476ca632008-01-07 11:16:314620 if {$isbold && ![ishighlighted $id]} {
Paul Mackerras28593d32008-11-13 12:01:464621 bolden $id mainfontbold
Paul Mackerras164ff272006-05-29 09:50:024622 }
4623 }
Paul Mackerras476ca632008-01-07 11:16:314624 set rhighlights($id) $isbold
Paul Mackerras164ff272006-05-29 09:50:024625}
4626
Paul Mackerrasda7c24d2006-05-02 01:15:294627# Graph layout functions
4628
Paul Mackerras9f1afe02006-02-19 11:44:474629proc shortids {ids} {
4630 set res {}
4631 foreach id $ids {
4632 if {[llength $id] > 1} {
4633 lappend res [shortids $id]
4634 } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
4635 lappend res [string range $id 0 7]
4636 } else {
4637 lappend res $id
4638 }
4639 }
4640 return $res
4641}
4642
Paul Mackerras9f1afe02006-02-19 11:44:474643proc ntimes {n o} {
4644 set ret {}
Paul Mackerras03800812007-08-29 11:45:214645 set o [list $o]
4646 for {set mask 1} {$mask <= $n} {incr mask $mask} {
4647 if {($n & $mask) != 0} {
4648 set ret [concat $ret $o]
4649 }
4650 set o [concat $o $o]
Paul Mackerras9f1afe02006-02-19 11:44:474651 }
4652 return $ret
4653}
4654
Paul Mackerras9257d8f2007-12-10 23:45:384655proc ordertoken {id} {
4656 global ordertok curview varcid varcstart varctok curview parents children
4657 global nullid nullid2
4658
4659 if {[info exists ordertok($id)]} {
4660 return $ordertok($id)
4661 }
4662 set origid $id
4663 set todo {}
4664 while {1} {
4665 if {[info exists varcid($curview,$id)]} {
4666 set a $varcid($curview,$id)
4667 set p [lindex $varcstart($curview) $a]
4668 } else {
4669 set p [lindex $children($curview,$id) 0]
4670 }
4671 if {[info exists ordertok($p)]} {
4672 set tok $ordertok($p)
4673 break
4674 }
Paul Mackerrasc8c9f3d2008-01-06 02:54:584675 set id [first_real_child $curview,$p]
4676 if {$id eq {}} {
Paul Mackerras9257d8f2007-12-10 23:45:384677 # it's a root
Paul Mackerras46308ea2008-01-15 11:16:324678 set tok [lindex $varctok($curview) $varcid($curview,$p)]
Paul Mackerras9257d8f2007-12-10 23:45:384679 break
4680 }
Paul Mackerras9257d8f2007-12-10 23:45:384681 if {[llength $parents($curview,$id)] == 1} {
4682 lappend todo [list $p {}]
4683 } else {
4684 set j [lsearch -exact $parents($curview,$id) $p]
4685 if {$j < 0} {
4686 puts "oops didn't find [shortids $p] in parents of [shortids $id]"
4687 }
4688 lappend todo [list $p [strrep $j]]
4689 }
4690 }
4691 for {set i [llength $todo]} {[incr i -1] >= 0} {} {
4692 set p [lindex $todo $i 0]
4693 append tok [lindex $todo $i 1]
4694 set ordertok($p) $tok
4695 }
4696 set ordertok($origid) $tok
4697 return $tok
4698}
4699
Paul Mackerras6e8c8702007-07-31 11:03:064700# Work out where id should go in idlist so that order-token
4701# values increase from left to right
4702proc idcol {idlist id {i 0}} {
Paul Mackerras9257d8f2007-12-10 23:45:384703 set t [ordertoken $id]
Paul Mackerrase5b37ac2007-12-12 07:13:514704 if {$i < 0} {
4705 set i 0
4706 }
Paul Mackerras9257d8f2007-12-10 23:45:384707 if {$i >= [llength $idlist] || $t < [ordertoken [lindex $idlist $i]]} {
Paul Mackerras6e8c8702007-07-31 11:03:064708 if {$i > [llength $idlist]} {
4709 set i [llength $idlist]
Paul Mackerras9f1afe02006-02-19 11:44:474710 }
Paul Mackerras9257d8f2007-12-10 23:45:384711 while {[incr i -1] >= 0 && $t < [ordertoken [lindex $idlist $i]]} {}
Paul Mackerras6e8c8702007-07-31 11:03:064712 incr i
4713 } else {
Paul Mackerras9257d8f2007-12-10 23:45:384714 if {$t > [ordertoken [lindex $idlist $i]]} {
Paul Mackerras6e8c8702007-07-31 11:03:064715 while {[incr i] < [llength $idlist] &&
Paul Mackerras9257d8f2007-12-10 23:45:384716 $t >= [ordertoken [lindex $idlist $i]]} {}
Paul Mackerras9f1afe02006-02-19 11:44:474717 }
4718 }
Paul Mackerras6e8c8702007-07-31 11:03:064719 return $i
Paul Mackerras9f1afe02006-02-19 11:44:474720}
4721
4722proc initlayout {} {
Paul Mackerras7fcc92b2007-12-02 23:33:014723 global rowidlist rowisopt rowfinal displayorder parentlist
Paul Mackerrasda7c24d2006-05-02 01:15:294724 global numcommits canvxmax canv
Paul Mackerras8f7d0ce2006-02-28 11:10:194725 global nextcolor
Paul Mackerrasda7c24d2006-05-02 01:15:294726 global colormap rowtextx
Paul Mackerras9f1afe02006-02-19 11:44:474727
Paul Mackerras8f7d0ce2006-02-28 11:10:194728 set numcommits 0
4729 set displayorder {}
Paul Mackerras79b2c752006-04-02 10:47:404730 set parentlist {}
Paul Mackerras8f7d0ce2006-02-28 11:10:194731 set nextcolor 0
Paul Mackerras03800812007-08-29 11:45:214732 set rowidlist {}
4733 set rowisopt {}
Paul Mackerrasf5f3c2e2007-09-04 16:19:564734 set rowfinal {}
Paul Mackerrasbe0cd092006-03-30 22:55:114735 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 00:16:224736 catch {unset colormap}
4737 catch {unset rowtextx}
Paul Mackerrasac1276a2008-03-02 23:11:084738 setcanvscroll
Paul Mackerrasbe0cd092006-03-30 22:55:114739}
4740
4741proc setcanvscroll {} {
4742 global canv canv2 canv3 numcommits linespc canvxmax canvy0
Paul Mackerrasac1276a2008-03-02 23:11:084743 global lastscrollset lastscrollrows
Paul Mackerrasbe0cd092006-03-30 22:55:114744
4745 set ymax [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]
4746 $canv conf -scrollregion [list 0 0 $canvxmax $ymax]
4747 $canv2 conf -scrollregion [list 0 0 0 $ymax]
4748 $canv3 conf -scrollregion [list 0 0 0 $ymax]
Paul Mackerrasac1276a2008-03-02 23:11:084749 set lastscrollset [clock clicks -milliseconds]
4750 set lastscrollrows $numcommits
Paul Mackerras9f1afe02006-02-19 11:44:474751}
4752
4753proc visiblerows {} {
4754 global canv numcommits linespc
4755
4756 set ymax [lindex [$canv cget -scrollregion] 3]
4757 if {$ymax eq {} || $ymax == 0} return
4758 set f [$canv yview]
4759 set y0 [expr {int([lindex $f 0] * $ymax)}]
4760 set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
4761 if {$r0 < 0} {
4762 set r0 0
4763 }
4764 set y1 [expr {int([lindex $f 1] * $ymax)}]
4765 set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
4766 if {$r1 >= $numcommits} {
4767 set r1 [expr {$numcommits - 1}]
4768 }
4769 return [list $r0 $r1]
4770}
4771
Paul Mackerrasf5f3c2e2007-09-04 16:19:564772proc layoutmore {} {
Paul Mackerras38dfe932007-12-06 09:50:314773 global commitidx viewcomplete curview
Paul Mackerras94b4a692008-05-20 10:51:064774 global numcommits pending_select curview
Paul Mackerrasd375ef92008-10-20 23:18:124775 global lastscrollset lastscrollrows
Paul Mackerras9f1afe02006-02-19 11:44:474776
Paul Mackerrasac1276a2008-03-02 23:11:084777 if {$lastscrollrows < 100 || $viewcomplete($curview) ||
4778 [clock clicks -milliseconds] - $lastscrollset > 500} {
Paul Mackerrasa2c22362006-10-31 04:00:534779 setcanvscroll
4780 }
Paul Mackerrasd94f8cd2006-04-06 00:18:234781 if {[info exists pending_select] &&
Paul Mackerras7fcc92b2007-12-02 23:33:014782 [commitinview $pending_select $curview]} {
Alexander Gavrilov567c34e2008-07-26 16:13:454783 update
Paul Mackerras7fcc92b2007-12-02 23:33:014784 selectline [rowofcommit $pending_select] 1
Paul Mackerrasd94f8cd2006-04-06 00:18:234785 }
Paul Mackerrasac1276a2008-03-02 23:11:084786 drawvisible
Paul Mackerras219ea3a2006-09-07 00:21:394787}
4788
Paul Mackerrascdc84292008-11-18 08:54:144789# With path limiting, we mightn't get the actual HEAD commit,
4790# so ask git rev-list what is the first ancestor of HEAD that
4791# touches a file in the path limit.
4792proc get_viewmainhead {view} {
4793 global viewmainheadid vfilelimit viewinstances mainheadid
Paul Mackerras219ea3a2006-09-07 00:21:394794
Paul Mackerrascdc84292008-11-18 08:54:144795 catch {
4796 set rfd [open [concat | git rev-list -1 $mainheadid \
4797 -- $vfilelimit($view)] r]
4798 set j [reg_instance $rfd]
4799 lappend viewinstances($view) $j
4800 fconfigure $rfd -blocking 0
4801 filerun $rfd [list getviewhead $rfd $j $view]
4802 set viewmainheadid($curview) {}
4803 }
4804}
4805
4806# git rev-list should give us just 1 line to use as viewmainheadid($view)
4807proc getviewhead {fd inst view} {
4808 global viewmainheadid commfd curview viewinstances showlocalchanges
4809
4810 set id {}
4811 if {[gets $fd line] < 0} {
4812 if {![eof $fd]} {
4813 return 1
4814 }
4815 } elseif {[string length $line] == 40 && [string is xdigit $line]} {
4816 set id $line
4817 }
4818 set viewmainheadid($view) $id
4819 close $fd
4820 unset commfd($inst)
4821 set i [lsearch -exact $viewinstances($view) $inst]
4822 if {$i >= 0} {
4823 set viewinstances($view) [lreplace $viewinstances($view) $i $i]
4824 }
4825 if {$showlocalchanges && $id ne {} && $view == $curview} {
4826 doshowlocalchanges
4827 }
4828 return 0
4829}
4830
4831proc doshowlocalchanges {} {
4832 global curview viewmainheadid
4833
4834 if {$viewmainheadid($curview) eq {}} return
4835 if {[commitinview $viewmainheadid($curview) $curview]} {
Paul Mackerras219ea3a2006-09-07 00:21:394836 dodiffindex
Paul Mackerras38dfe932007-12-06 09:50:314837 } else {
Paul Mackerrascdc84292008-11-18 08:54:144838 interestedin $viewmainheadid($curview) dodiffindex
Paul Mackerras219ea3a2006-09-07 00:21:394839 }
4840}
4841
4842proc dohidelocalchanges {} {
Paul Mackerras7fcc92b2007-12-02 23:33:014843 global nullid nullid2 lserial curview
Paul Mackerras219ea3a2006-09-07 00:21:394844
Paul Mackerras7fcc92b2007-12-02 23:33:014845 if {[commitinview $nullid $curview]} {
Paul Mackerrasb8a938c2008-02-13 11:12:314846 removefakerow $nullid
Paul Mackerras8f489362007-07-13 09:49:374847 }
Paul Mackerras7fcc92b2007-12-02 23:33:014848 if {[commitinview $nullid2 $curview]} {
Paul Mackerrasb8a938c2008-02-13 11:12:314849 removefakerow $nullid2
Paul Mackerras219ea3a2006-09-07 00:21:394850 }
4851 incr lserial
4852}
4853
Paul Mackerras8f489362007-07-13 09:49:374854# spawn off a process to do git diff-index --cached HEAD
Paul Mackerras219ea3a2006-09-07 00:21:394855proc dodiffindex {} {
Paul Mackerrascdc84292008-11-18 08:54:144856 global lserial showlocalchanges vfilelimit curview
David Aguilarcb8329a2008-03-10 10:54:564857 global isworktree
Paul Mackerras219ea3a2006-09-07 00:21:394858
David Aguilarcb8329a2008-03-10 10:54:564859 if {!$showlocalchanges || !$isworktree} return
Paul Mackerras219ea3a2006-09-07 00:21:394860 incr lserial
Paul Mackerrascdc84292008-11-18 08:54:144861 set cmd "|git diff-index --cached HEAD"
4862 if {$vfilelimit($curview) ne {}} {
4863 set cmd [concat $cmd -- $vfilelimit($curview)]
4864 }
4865 set fd [open $cmd r]
Paul Mackerras219ea3a2006-09-07 00:21:394866 fconfigure $fd -blocking 0
Alexander Gavrilove439e092008-07-13 12:40:474867 set i [reg_instance $fd]
4868 filerun $fd [list readdiffindex $fd $lserial $i]
Paul Mackerras219ea3a2006-09-07 00:21:394869}
4870
Alexander Gavrilove439e092008-07-13 12:40:474871proc readdiffindex {fd serial inst} {
Paul Mackerrascdc84292008-11-18 08:54:144872 global viewmainheadid nullid nullid2 curview commitinfo commitdata lserial
4873 global vfilelimit
Paul Mackerras219ea3a2006-09-07 00:21:394874
Paul Mackerras8f489362007-07-13 09:49:374875 set isdiff 1
Paul Mackerras219ea3a2006-09-07 00:21:394876 if {[gets $fd line] < 0} {
Paul Mackerras8f489362007-07-13 09:49:374877 if {![eof $fd]} {
4878 return 1
Paul Mackerras219ea3a2006-09-07 00:21:394879 }
Paul Mackerras8f489362007-07-13 09:49:374880 set isdiff 0
Paul Mackerras219ea3a2006-09-07 00:21:394881 }
4882 # we only need to see one line and we don't really care what it says...
Alexander Gavrilove439e092008-07-13 12:40:474883 stop_instance $inst
Paul Mackerras219ea3a2006-09-07 00:21:394884
Paul Mackerras24f7a662007-12-18 22:35:334885 if {$serial != $lserial} {
4886 return 0
Paul Mackerras8f489362007-07-13 09:49:374887 }
4888
Paul Mackerras24f7a662007-12-18 22:35:334889 # now see if there are any local changes not checked in to the index
Paul Mackerrascdc84292008-11-18 08:54:144890 set cmd "|git diff-files"
4891 if {$vfilelimit($curview) ne {}} {
4892 set cmd [concat $cmd -- $vfilelimit($curview)]
4893 }
4894 set fd [open $cmd r]
Paul Mackerras24f7a662007-12-18 22:35:334895 fconfigure $fd -blocking 0
Alexander Gavrilove439e092008-07-13 12:40:474896 set i [reg_instance $fd]
4897 filerun $fd [list readdifffiles $fd $serial $i]
Paul Mackerras24f7a662007-12-18 22:35:334898
4899 if {$isdiff && ![commitinview $nullid2 $curview]} {
Paul Mackerras8f489362007-07-13 09:49:374900 # add the line for the changes in the index to the graph
Christian Stimmingd990ced2007-11-07 17:42:554901 set hl [mc "Local changes checked in to index but not committed"]
Paul Mackerras8f489362007-07-13 09:49:374902 set commitinfo($nullid2) [list $hl {} {} {} {} " $hl\n"]
4903 set commitdata($nullid2) "\n $hl\n"
Paul Mackerrasfc2a2562007-12-26 12:03:434904 if {[commitinview $nullid $curview]} {
Paul Mackerrasb8a938c2008-02-13 11:12:314905 removefakerow $nullid
Paul Mackerrasfc2a2562007-12-26 12:03:434906 }
Paul Mackerrascdc84292008-11-18 08:54:144907 insertfakerow $nullid2 $viewmainheadid($curview)
Paul Mackerras24f7a662007-12-18 22:35:334908 } elseif {!$isdiff && [commitinview $nullid2 $curview]} {
Paul Mackerrascdc84292008-11-18 08:54:144909 if {[commitinview $nullid $curview]} {
4910 removefakerow $nullid
4911 }
Paul Mackerrasb8a938c2008-02-13 11:12:314912 removefakerow $nullid2
Paul Mackerras8f489362007-07-13 09:49:374913 }
4914 return 0
4915}
4916
Alexander Gavrilove439e092008-07-13 12:40:474917proc readdifffiles {fd serial inst} {
Paul Mackerrascdc84292008-11-18 08:54:144918 global viewmainheadid nullid nullid2 curview
Paul Mackerras8f489362007-07-13 09:49:374919 global commitinfo commitdata lserial
4920
4921 set isdiff 1
4922 if {[gets $fd line] < 0} {
4923 if {![eof $fd]} {
4924 return 1
4925 }
4926 set isdiff 0
4927 }
4928 # we only need to see one line and we don't really care what it says...
Alexander Gavrilove439e092008-07-13 12:40:474929 stop_instance $inst
Paul Mackerras8f489362007-07-13 09:49:374930
Paul Mackerras24f7a662007-12-18 22:35:334931 if {$serial != $lserial} {
4932 return 0
4933 }
4934
4935 if {$isdiff && ![commitinview $nullid $curview]} {
Paul Mackerras219ea3a2006-09-07 00:21:394936 # add the line for the local diff to the graph
Christian Stimmingd990ced2007-11-07 17:42:554937 set hl [mc "Local uncommitted changes, not checked in to index"]
Paul Mackerras219ea3a2006-09-07 00:21:394938 set commitinfo($nullid) [list $hl {} {} {} {} " $hl\n"]
4939 set commitdata($nullid) "\n $hl\n"
Paul Mackerras7fcc92b2007-12-02 23:33:014940 if {[commitinview $nullid2 $curview]} {
4941 set p $nullid2
4942 } else {
Paul Mackerrascdc84292008-11-18 08:54:144943 set p $viewmainheadid($curview)
Paul Mackerras7fcc92b2007-12-02 23:33:014944 }
Paul Mackerrasb8a938c2008-02-13 11:12:314945 insertfakerow $nullid $p
Paul Mackerras24f7a662007-12-18 22:35:334946 } elseif {!$isdiff && [commitinview $nullid $curview]} {
Paul Mackerrasb8a938c2008-02-13 11:12:314947 removefakerow $nullid
Paul Mackerras219ea3a2006-09-07 00:21:394948 }
4949 return 0
Paul Mackerras9f1afe02006-02-19 11:44:474950}
4951
Paul Mackerras8f0bc7e2007-08-24 12:16:424952proc nextuse {id row} {
Paul Mackerras7fcc92b2007-12-02 23:33:014953 global curview children
Paul Mackerras8f0bc7e2007-08-24 12:16:424954
4955 if {[info exists children($curview,$id)]} {
4956 foreach kid $children($curview,$id) {
Paul Mackerras7fcc92b2007-12-02 23:33:014957 if {![commitinview $kid $curview]} {
Paul Mackerras03800812007-08-29 11:45:214958 return -1
4959 }
Paul Mackerras7fcc92b2007-12-02 23:33:014960 if {[rowofcommit $kid] > $row} {
4961 return [rowofcommit $kid]
Paul Mackerras8f0bc7e2007-08-24 12:16:424962 }
4963 }
4964 }
Paul Mackerras7fcc92b2007-12-02 23:33:014965 if {[commitinview $id $curview]} {
4966 return [rowofcommit $id]
Paul Mackerras8f0bc7e2007-08-24 12:16:424967 }
4968 return -1
4969}
4970
Paul Mackerrasf5f3c2e2007-09-04 16:19:564971proc prevuse {id row} {
Paul Mackerras7fcc92b2007-12-02 23:33:014972 global curview children
Paul Mackerrasf5f3c2e2007-09-04 16:19:564973
4974 set ret -1
4975 if {[info exists children($curview,$id)]} {
4976 foreach kid $children($curview,$id) {
Paul Mackerras7fcc92b2007-12-02 23:33:014977 if {![commitinview $kid $curview]} break
4978 if {[rowofcommit $kid] < $row} {
4979 set ret [rowofcommit $kid]
Paul Mackerrasf5f3c2e2007-09-04 16:19:564980 }
4981 }
4982 }
4983 return $ret
4984}
4985
Paul Mackerras03800812007-08-29 11:45:214986proc make_idlist {row} {
4987 global displayorder parentlist uparrowlen downarrowlen mingaplen
Paul Mackerras9257d8f2007-12-10 23:45:384988 global commitidx curview children
Paul Mackerras03800812007-08-29 11:45:214989
4990 set r [expr {$row - $mingaplen - $downarrowlen - 1}]
4991 if {$r < 0} {
4992 set r 0
4993 }
4994 set ra [expr {$row - $downarrowlen}]
4995 if {$ra < 0} {
4996 set ra 0
4997 }
4998 set rb [expr {$row + $uparrowlen}]
4999 if {$rb > $commitidx($curview)} {
5000 set rb $commitidx($curview)
5001 }
Paul Mackerras7fcc92b2007-12-02 23:33:015002 make_disporder $r [expr {$rb + 1}]
Paul Mackerras03800812007-08-29 11:45:215003 set ids {}
5004 for {} {$r < $ra} {incr r} {
5005 set nextid [lindex $displayorder [expr {$r + 1}]]
5006 foreach p [lindex $parentlist $r] {
5007 if {$p eq $nextid} continue
5008 set rn [nextuse $p $r]
5009 if {$rn >= $row &&
5010 $rn <= $r + $downarrowlen + $mingaplen + $uparrowlen} {
Paul Mackerras9257d8f2007-12-10 23:45:385011 lappend ids [list [ordertoken $p] $p]
Paul Mackerras03800812007-08-29 11:45:215012 }
5013 }
5014 }
5015 for {} {$r < $row} {incr r} {
5016 set nextid [lindex $displayorder [expr {$r + 1}]]
5017 foreach p [lindex $parentlist $r] {
5018 if {$p eq $nextid} continue
5019 set rn [nextuse $p $r]
5020 if {$rn < 0 || $rn >= $row} {
Paul Mackerras9257d8f2007-12-10 23:45:385021 lappend ids [list [ordertoken $p] $p]
Paul Mackerras03800812007-08-29 11:45:215022 }
5023 }
5024 }
5025 set id [lindex $displayorder $row]
Paul Mackerras9257d8f2007-12-10 23:45:385026 lappend ids [list [ordertoken $id] $id]
Paul Mackerras03800812007-08-29 11:45:215027 while {$r < $rb} {
5028 foreach p [lindex $parentlist $r] {
5029 set firstkid [lindex $children($curview,$p) 0]
Paul Mackerras7fcc92b2007-12-02 23:33:015030 if {[rowofcommit $firstkid] < $row} {
Paul Mackerras9257d8f2007-12-10 23:45:385031 lappend ids [list [ordertoken $p] $p]
Paul Mackerras03800812007-08-29 11:45:215032 }
5033 }
5034 incr r
5035 set id [lindex $displayorder $r]
5036 if {$id ne {}} {
5037 set firstkid [lindex $children($curview,$id) 0]
Paul Mackerras7fcc92b2007-12-02 23:33:015038 if {$firstkid ne {} && [rowofcommit $firstkid] < $row} {
Paul Mackerras9257d8f2007-12-10 23:45:385039 lappend ids [list [ordertoken $id] $id]
Paul Mackerras03800812007-08-29 11:45:215040 }
5041 }
5042 }
5043 set idlist {}
5044 foreach idx [lsort -unique $ids] {
5045 lappend idlist [lindex $idx 1]
5046 }
5047 return $idlist
5048}
5049
Paul Mackerrasf5f3c2e2007-09-04 16:19:565050proc rowsequal {a b} {
5051 while {[set i [lsearch -exact $a {}]] >= 0} {
5052 set a [lreplace $a $i $i]
5053 }
5054 while {[set i [lsearch -exact $b {}]] >= 0} {
5055 set b [lreplace $b $i $i]
5056 }
5057 return [expr {$a eq $b}]
5058}
5059
5060proc makeupline {id row rend col} {
5061 global rowidlist uparrowlen downarrowlen mingaplen
5062
5063 for {set r $rend} {1} {set r $rstart} {
5064 set rstart [prevuse $id $r]
5065 if {$rstart < 0} return
5066 if {$rstart < $row} break
5067 }
5068 if {$rstart + $uparrowlen + $mingaplen + $downarrowlen < $rend} {
5069 set rstart [expr {$rend - $uparrowlen - 1}]
5070 }
5071 for {set r $rstart} {[incr r] <= $row} {} {
5072 set idlist [lindex $rowidlist $r]
5073 if {$idlist ne {} && [lsearch -exact $idlist $id] < 0} {
5074 set col [idcol $idlist $id $col]
5075 lset rowidlist $r [linsert $idlist $col $id]
5076 changedrow $r
5077 }
5078 }
5079}
5080
Paul Mackerras03800812007-08-29 11:45:215081proc layoutrows {row endrow} {
Paul Mackerrasf5f3c2e2007-09-04 16:19:565082 global rowidlist rowisopt rowfinal displayorder
Paul Mackerras9f1afe02006-02-19 11:44:475083 global uparrowlen downarrowlen maxwidth mingaplen
Paul Mackerras6a90bff2007-06-17 23:48:235084 global children parentlist
Paul Mackerras7fcc92b2007-12-02 23:33:015085 global commitidx viewcomplete curview
Paul Mackerras9f1afe02006-02-19 11:44:475086
Paul Mackerras7fcc92b2007-12-02 23:33:015087 make_disporder [expr {$row - 1}] [expr {$endrow + $uparrowlen}]
Paul Mackerras03800812007-08-29 11:45:215088 set idlist {}
5089 if {$row > 0} {
Paul Mackerrasf56782a2007-09-14 23:04:115090 set rm1 [expr {$row - 1}]
5091 foreach id [lindex $rowidlist $rm1] {
Paul Mackerras03800812007-08-29 11:45:215092 if {$id ne {}} {
5093 lappend idlist $id
Paul Mackerras9f1afe02006-02-19 11:44:475094 }
5095 }
Paul Mackerrasf56782a2007-09-14 23:04:115096 set final [lindex $rowfinal $rm1]
Paul Mackerras8f0bc7e2007-08-24 12:16:425097 }
Paul Mackerras03800812007-08-29 11:45:215098 for {} {$row < $endrow} {incr row} {
5099 set rm1 [expr {$row - 1}]
Paul Mackerrasf56782a2007-09-14 23:04:115100 if {$rm1 < 0 || $idlist eq {}} {
Paul Mackerras03800812007-08-29 11:45:215101 set idlist [make_idlist $row]
Paul Mackerrasf5f3c2e2007-09-04 16:19:565102 set final 1
Paul Mackerras03800812007-08-29 11:45:215103 } else {
5104 set id [lindex $displayorder $rm1]
5105 set col [lsearch -exact $idlist $id]
5106 set idlist [lreplace $idlist $col $col]
5107 foreach p [lindex $parentlist $rm1] {
5108 if {[lsearch -exact $idlist $p] < 0} {
5109 set col [idcol $idlist $p $col]
5110 set idlist [linsert $idlist $col $p]
Paul Mackerrasf5f3c2e2007-09-04 16:19:565111 # if not the first child, we have to insert a line going up
5112 if {$id ne [lindex $children($curview,$p) 0]} {
5113 makeupline $p $rm1 $row $col
Paul Mackerras9f1afe02006-02-19 11:44:475114 }
Paul Mackerras9f1afe02006-02-19 11:44:475115 }
5116 }
Paul Mackerras03800812007-08-29 11:45:215117 set id [lindex $displayorder $row]
5118 if {$row > $downarrowlen} {
5119 set termrow [expr {$row - $downarrowlen - 1}]
5120 foreach p [lindex $parentlist $termrow] {
5121 set i [lsearch -exact $idlist $p]
5122 if {$i < 0} continue
5123 set nr [nextuse $p $termrow]
5124 if {$nr < 0 || $nr >= $row + $mingaplen + $uparrowlen} {
5125 set idlist [lreplace $idlist $i $i]
5126 }
5127 }
5128 }
5129 set col [lsearch -exact $idlist $id]
5130 if {$col < 0} {
5131 set col [idcol $idlist $id]
5132 set idlist [linsert $idlist $col $id]
Paul Mackerrasf5f3c2e2007-09-04 16:19:565133 if {$children($curview,$id) ne {}} {
5134 makeupline $id $rm1 $row $col
5135 }
Paul Mackerras03800812007-08-29 11:45:215136 }
5137 set r [expr {$row + $uparrowlen - 1}]
5138 if {$r < $commitidx($curview)} {
5139 set x $col
5140 foreach p [lindex $parentlist $r] {
5141 if {[lsearch -exact $idlist $p] >= 0} continue
5142 set fk [lindex $children($curview,$p) 0]
Paul Mackerras7fcc92b2007-12-02 23:33:015143 if {[rowofcommit $fk] < $row} {
Paul Mackerras03800812007-08-29 11:45:215144 set x [idcol $idlist $p $x]
5145 set idlist [linsert $idlist $x $p]
5146 }
5147 }
5148 if {[incr r] < $commitidx($curview)} {
5149 set p [lindex $displayorder $r]
5150 if {[lsearch -exact $idlist $p] < 0} {
5151 set fk [lindex $children($curview,$p) 0]
Paul Mackerras7fcc92b2007-12-02 23:33:015152 if {$fk ne {} && [rowofcommit $fk] < $row} {
Paul Mackerras03800812007-08-29 11:45:215153 set x [idcol $idlist $p $x]
5154 set idlist [linsert $idlist $x $p]
5155 }
5156 }
5157 }
Paul Mackerras7b459a12007-08-13 04:52:005158 }
Paul Mackerras9f1afe02006-02-19 11:44:475159 }
Paul Mackerrasf5f3c2e2007-09-04 16:19:565160 if {$final && !$viewcomplete($curview) &&
5161 $row + $uparrowlen + $mingaplen + $downarrowlen
5162 >= $commitidx($curview)} {
5163 set final 0
Paul Mackerras7b459a12007-08-13 04:52:005164 }
Paul Mackerras03800812007-08-29 11:45:215165 set l [llength $rowidlist]
5166 if {$row == $l} {
5167 lappend rowidlist $idlist
5168 lappend rowisopt 0
Paul Mackerrasf5f3c2e2007-09-04 16:19:565169 lappend rowfinal $final
Paul Mackerras03800812007-08-29 11:45:215170 } elseif {$row < $l} {
Paul Mackerrasf5f3c2e2007-09-04 16:19:565171 if {![rowsequal $idlist [lindex $rowidlist $row]]} {
Paul Mackerras03800812007-08-29 11:45:215172 lset rowidlist $row $idlist
5173 changedrow $row
Paul Mackerras9f1afe02006-02-19 11:44:475174 }
Paul Mackerrasf56782a2007-09-14 23:04:115175 lset rowfinal $row $final
Paul Mackerras9f1afe02006-02-19 11:44:475176 } else {
Paul Mackerrasf5f3c2e2007-09-04 16:19:565177 set pad [ntimes [expr {$row - $l}] {}]
5178 set rowidlist [concat $rowidlist $pad]
Paul Mackerras03800812007-08-29 11:45:215179 lappend rowidlist $idlist
Paul Mackerrasf5f3c2e2007-09-04 16:19:565180 set rowfinal [concat $rowfinal $pad]
5181 lappend rowfinal $final
Paul Mackerras03800812007-08-29 11:45:215182 set rowisopt [concat $rowisopt [ntimes [expr {$row - $l + 1}] 0]]
Paul Mackerras9f1afe02006-02-19 11:44:475183 }
Paul Mackerras9f1afe02006-02-19 11:44:475184 }
5185 return $row
5186}
5187
Paul Mackerras03800812007-08-29 11:45:215188proc changedrow {row} {
5189 global displayorder iddrawn rowisopt need_redisplay
Paul Mackerras9f1afe02006-02-19 11:44:475190
Paul Mackerras03800812007-08-29 11:45:215191 set l [llength $rowisopt]
5192 if {$row < $l} {
5193 lset rowisopt $row 0
5194 if {$row + 1 < $l} {
5195 lset rowisopt [expr {$row + 1}] 0
5196 if {$row + 2 < $l} {
5197 lset rowisopt [expr {$row + 2}] 0
5198 }
5199 }
Paul Mackerras79b2c752006-04-02 10:47:405200 }
Paul Mackerras03800812007-08-29 11:45:215201 set id [lindex $displayorder $row]
5202 if {[info exists iddrawn($id)]} {
5203 set need_redisplay 1
Paul Mackerras9f1afe02006-02-19 11:44:475204 }
5205}
5206
5207proc insert_pad {row col npad} {
Paul Mackerras6e8c8702007-07-31 11:03:065208 global rowidlist
Paul Mackerras9f1afe02006-02-19 11:44:475209
5210 set pad [ntimes $npad {}]
Paul Mackerrase341c062007-08-12 02:42:575211 set idlist [lindex $rowidlist $row]
5212 set bef [lrange $idlist 0 [expr {$col - 1}]]
5213 set aft [lrange $idlist $col end]
5214 set i [lsearch -exact $aft {}]
5215 if {$i > 0} {
5216 set aft [lreplace $aft $i $i]
5217 }
5218 lset rowidlist $row [concat $bef $pad $aft]
Paul Mackerras03800812007-08-29 11:45:215219 changedrow $row
Paul Mackerras9f1afe02006-02-19 11:44:475220}
5221
5222proc optimize_rows {row col endrow} {
Paul Mackerras03800812007-08-29 11:45:215223 global rowidlist rowisopt displayorder curview children
Paul Mackerras9f1afe02006-02-19 11:44:475224
Paul Mackerras6e8c8702007-07-31 11:03:065225 if {$row < 1} {
5226 set row 1
5227 }
Paul Mackerras03800812007-08-29 11:45:215228 for {} {$row < $endrow} {incr row; set col 0} {
5229 if {[lindex $rowisopt $row]} continue
Paul Mackerras9f1afe02006-02-19 11:44:475230 set haspad 0
Paul Mackerras6e8c8702007-07-31 11:03:065231 set y0 [expr {$row - 1}]
5232 set ym [expr {$row - 2}]
Paul Mackerras03800812007-08-29 11:45:215233 set idlist [lindex $rowidlist $row]
5234 set previdlist [lindex $rowidlist $y0]
5235 if {$idlist eq {} || $previdlist eq {}} continue
5236 if {$ym >= 0} {
5237 set pprevidlist [lindex $rowidlist $ym]
5238 if {$pprevidlist eq {}} continue
5239 } else {
5240 set pprevidlist {}
5241 }
Paul Mackerras6e8c8702007-07-31 11:03:065242 set x0 -1
5243 set xm -1
5244 for {} {$col < [llength $idlist]} {incr col} {
5245 set id [lindex $idlist $col]
5246 if {[lindex $previdlist $col] eq $id} continue
5247 if {$id eq {}} {
Paul Mackerras9f1afe02006-02-19 11:44:475248 set haspad 1
5249 continue
5250 }
Paul Mackerras6e8c8702007-07-31 11:03:065251 set x0 [lsearch -exact $previdlist $id]
5252 if {$x0 < 0} continue
5253 set z [expr {$x0 - $col}]
Paul Mackerras9f1afe02006-02-19 11:44:475254 set isarrow 0
Paul Mackerras6e8c8702007-07-31 11:03:065255 set z0 {}
5256 if {$ym >= 0} {
5257 set xm [lsearch -exact $pprevidlist $id]
5258 if {$xm >= 0} {
5259 set z0 [expr {$xm - $x0}]
5260 }
5261 }
Paul Mackerras9f1afe02006-02-19 11:44:475262 if {$z0 eq {}} {
Paul Mackerras92ed6662007-08-22 12:35:285263 # if row y0 is the first child of $id then it's not an arrow
5264 if {[lindex $children($curview,$id) 0] ne
5265 [lindex $displayorder $y0]} {
Paul Mackerras9f1afe02006-02-19 11:44:475266 set isarrow 1
5267 }
5268 }
Paul Mackerrase341c062007-08-12 02:42:575269 if {!$isarrow && $id ne [lindex $displayorder $row] &&
5270 [lsearch -exact [lindex $rowidlist [expr {$row+1}]] $id] < 0} {
5271 set isarrow 1
5272 }
Paul Mackerras3fc42792006-09-14 23:45:235273 # Looking at lines from this row to the previous row,
5274 # make them go straight up if they end in an arrow on
5275 # the previous row; otherwise make them go straight up
5276 # or at 45 degrees.
Paul Mackerras9f1afe02006-02-19 11:44:475277 if {$z < -1 || ($z < 0 && $isarrow)} {
Paul Mackerras3fc42792006-09-14 23:45:235278 # Line currently goes left too much;
5279 # insert pads in the previous row, then optimize it
Paul Mackerras9f1afe02006-02-19 11:44:475280 set npad [expr {-1 - $z + $isarrow}]
Paul Mackerras9f1afe02006-02-19 11:44:475281 insert_pad $y0 $x0 $npad
5282 if {$y0 > 0} {
5283 optimize_rows $y0 $x0 $row
5284 }
Paul Mackerras6e8c8702007-07-31 11:03:065285 set previdlist [lindex $rowidlist $y0]
5286 set x0 [lsearch -exact $previdlist $id]
5287 set z [expr {$x0 - $col}]
5288 if {$z0 ne {}} {
5289 set pprevidlist [lindex $rowidlist $ym]
5290 set xm [lsearch -exact $pprevidlist $id]
5291 set z0 [expr {$xm - $x0}]
5292 }
Paul Mackerras9f1afe02006-02-19 11:44:475293 } elseif {$z > 1 || ($z > 0 && $isarrow)} {
Paul Mackerras3fc42792006-09-14 23:45:235294 # Line currently goes right too much;
Paul Mackerras6e8c8702007-07-31 11:03:065295 # insert pads in this line
Paul Mackerras9f1afe02006-02-19 11:44:475296 set npad [expr {$z - 1 + $isarrow}]
Paul Mackerrase341c062007-08-12 02:42:575297 insert_pad $row $col $npad
5298 set idlist [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 11:44:475299 incr col $npad
Paul Mackerras6e8c8702007-07-31 11:03:065300 set z [expr {$x0 - $col}]
Paul Mackerras9f1afe02006-02-19 11:44:475301 set haspad 1
5302 }
Paul Mackerras6e8c8702007-07-31 11:03:065303 if {$z0 eq {} && !$isarrow && $ym >= 0} {
Paul Mackerraseb447a12006-03-18 12:11:375304 # this line links to its first child on row $row-2
Paul Mackerras6e8c8702007-07-31 11:03:065305 set id [lindex $displayorder $ym]
5306 set xc [lsearch -exact $pprevidlist $id]
Paul Mackerraseb447a12006-03-18 12:11:375307 if {$xc >= 0} {
5308 set z0 [expr {$xc - $x0}]
5309 }
5310 }
Paul Mackerras3fc42792006-09-14 23:45:235311 # avoid lines jigging left then immediately right
Paul Mackerras9f1afe02006-02-19 11:44:475312 if {$z0 ne {} && $z < 0 && $z0 > 0} {
5313 insert_pad $y0 $x0 1
Paul Mackerras6e8c8702007-07-31 11:03:065314 incr x0
5315 optimize_rows $y0 $x0 $row
5316 set previdlist [lindex $rowidlist $y0]
Paul Mackerras9f1afe02006-02-19 11:44:475317 }
5318 }
5319 if {!$haspad} {
Paul Mackerras3fc42792006-09-14 23:45:235320 # Find the first column that doesn't have a line going right
Paul Mackerras9f1afe02006-02-19 11:44:475321 for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
Paul Mackerras6e8c8702007-07-31 11:03:065322 set id [lindex $idlist $col]
5323 if {$id eq {}} break
5324 set x0 [lsearch -exact $previdlist $id]
5325 if {$x0 < 0} {
Paul Mackerraseb447a12006-03-18 12:11:375326 # check if this is the link to the first child
Paul Mackerras92ed6662007-08-22 12:35:285327 set kid [lindex $displayorder $y0]
5328 if {[lindex $children($curview,$id) 0] eq $kid} {
Paul Mackerraseb447a12006-03-18 12:11:375329 # it is, work out offset to child
Paul Mackerras92ed6662007-08-22 12:35:285330 set x0 [lsearch -exact $previdlist $kid]
Paul Mackerraseb447a12006-03-18 12:11:375331 }
5332 }
Paul Mackerras6e8c8702007-07-31 11:03:065333 if {$x0 <= $col} break
Paul Mackerras9f1afe02006-02-19 11:44:475334 }
Paul Mackerras3fc42792006-09-14 23:45:235335 # Insert a pad at that column as long as it has a line and
Paul Mackerras6e8c8702007-07-31 11:03:065336 # isn't the last column
5337 if {$x0 >= 0 && [incr col] < [llength $idlist]} {
Paul Mackerras9f1afe02006-02-19 11:44:475338 set idlist [linsert $idlist $col {}]
Paul Mackerras03800812007-08-29 11:45:215339 lset rowidlist $row $idlist
5340 changedrow $row
Paul Mackerras9f1afe02006-02-19 11:44:475341 }
5342 }
Paul Mackerras9f1afe02006-02-19 11:44:475343 }
5344}
5345
5346proc xc {row col} {
5347 global canvx0 linespc
5348 return [expr {$canvx0 + $col * $linespc}]
5349}
5350
5351proc yc {row} {
5352 global canvy0 linespc
5353 return [expr {$canvy0 + $row * $linespc}]
5354}
5355
Paul Mackerrasc934a8a2006-03-02 12:00:445356proc linewidth {id} {
5357 global thickerline lthickness
5358
5359 set wid $lthickness
5360 if {[info exists thickerline] && $id eq $thickerline} {
5361 set wid [expr {2 * $lthickness}]
5362 }
5363 return $wid
5364}
5365
Paul Mackerras50b44ec2006-04-04 00:16:225366proc rowranges {id} {
Paul Mackerras7fcc92b2007-12-02 23:33:015367 global curview children uparrowlen downarrowlen
Paul Mackerras92ed6662007-08-22 12:35:285368 global rowidlist
Paul Mackerras50b44ec2006-04-04 00:16:225369
Paul Mackerras92ed6662007-08-22 12:35:285370 set kids $children($curview,$id)
5371 if {$kids eq {}} {
5372 return {}
Paul Mackerras50b44ec2006-04-04 00:16:225373 }
Paul Mackerras92ed6662007-08-22 12:35:285374 set ret {}
5375 lappend kids $id
5376 foreach child $kids {
Paul Mackerras7fcc92b2007-12-02 23:33:015377 if {![commitinview $child $curview]} break
5378 set row [rowofcommit $child]
Paul Mackerras92ed6662007-08-22 12:35:285379 if {![info exists prev]} {
5380 lappend ret [expr {$row + 1}]
Paul Mackerras322a8cc2006-10-15 08:03:465381 } else {
Paul Mackerras92ed6662007-08-22 12:35:285382 if {$row <= $prevrow} {
Paul Mackerras7fcc92b2007-12-02 23:33:015383 puts "oops children of [shortids $id] out of order [shortids $child] $row <= [shortids $prev] $prevrow"
Paul Mackerras92ed6662007-08-22 12:35:285384 }
5385 # see if the line extends the whole way from prevrow to row
5386 if {$row > $prevrow + $uparrowlen + $downarrowlen &&
5387 [lsearch -exact [lindex $rowidlist \
5388 [expr {int(($row + $prevrow) / 2)}]] $id] < 0} {
5389 # it doesn't, see where it ends
5390 set r [expr {$prevrow + $downarrowlen}]
5391 if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
5392 while {[incr r -1] > $prevrow &&
5393 [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
5394 } else {
5395 while {[incr r] <= $row &&
5396 [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
5397 incr r -1
5398 }
5399 lappend ret $r
5400 # see where it starts up again
5401 set r [expr {$row - $uparrowlen}]
5402 if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
5403 while {[incr r] < $row &&
5404 [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
5405 } else {
5406 while {[incr r -1] >= $prevrow &&
5407 [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
5408 incr r
5409 }
5410 lappend ret $r
5411 }
Paul Mackerraseb447a12006-03-18 12:11:375412 }
Paul Mackerras92ed6662007-08-22 12:35:285413 if {$child eq $id} {
5414 lappend ret $row
5415 }
Paul Mackerras7fcc92b2007-12-02 23:33:015416 set prev $child
Paul Mackerras92ed6662007-08-22 12:35:285417 set prevrow $row
Paul Mackerraseb447a12006-03-18 12:11:375418 }
Paul Mackerras92ed6662007-08-22 12:35:285419 return $ret
Paul Mackerras9f1afe02006-02-19 11:44:475420}
5421
Paul Mackerras322a8cc2006-10-15 08:03:465422proc drawlineseg {id row endrow arrowlow} {
5423 global rowidlist displayorder iddrawn linesegs
Paul Mackerrase341c062007-08-12 02:42:575424 global canv colormap linespc curview maxlinelen parentlist
Paul Mackerras9f1afe02006-02-19 11:44:475425
Paul Mackerras322a8cc2006-10-15 08:03:465426 set cols [list [lsearch -exact [lindex $rowidlist $row] $id]]
5427 set le [expr {$row + 1}]
5428 set arrowhigh 1
5429 while {1} {
5430 set c [lsearch -exact [lindex $rowidlist $le] $id]
5431 if {$c < 0} {
5432 incr le -1
5433 break
5434 }
5435 lappend cols $c
5436 set x [lindex $displayorder $le]
5437 if {$x eq $id} {
5438 set arrowhigh 0
5439 break
5440 }
5441 if {[info exists iddrawn($x)] || $le == $endrow} {
5442 set c [lsearch -exact [lindex $rowidlist [expr {$le+1}]] $id]
5443 if {$c >= 0} {
5444 lappend cols $c
5445 set arrowhigh 0
5446 }
5447 break
5448 }
5449 incr le
5450 }
5451 if {$le <= $row} {
5452 return $row
5453 }
5454
5455 set lines {}
5456 set i 0
5457 set joinhigh 0
5458 if {[info exists linesegs($id)]} {
5459 set lines $linesegs($id)
5460 foreach li $lines {
5461 set r0 [lindex $li 0]
5462 if {$r0 > $row} {
5463 if {$r0 == $le && [lindex $li 1] - $row <= $maxlinelen} {
5464 set joinhigh 1
5465 }
5466 break
5467 }
5468 incr i
5469 }
5470 }
5471 set joinlow 0
5472 if {$i > 0} {
5473 set li [lindex $lines [expr {$i-1}]]
5474 set r1 [lindex $li 1]
5475 if {$r1 == $row && $le - [lindex $li 0] <= $maxlinelen} {
5476 set joinlow 1
5477 }
5478 }
5479
5480 set x [lindex $cols [expr {$le - $row}]]
5481 set xp [lindex $cols [expr {$le - 1 - $row}]]
5482 set dir [expr {$xp - $x}]
5483 if {$joinhigh} {
5484 set ith [lindex $lines $i 2]
5485 set coords [$canv coords $ith]
5486 set ah [$canv itemcget $ith -arrow]
5487 set arrowhigh [expr {$ah eq "first" || $ah eq "both"}]
5488 set x2 [lindex $cols [expr {$le + 1 - $row}]]
5489 if {$x2 ne {} && $x - $x2 == $dir} {
5490 set coords [lrange $coords 0 end-2]
5491 }
5492 } else {
5493 set coords [list [xc $le $x] [yc $le]]
5494 }
5495 if {$joinlow} {
5496 set itl [lindex $lines [expr {$i-1}] 2]
5497 set al [$canv itemcget $itl -arrow]
5498 set arrowlow [expr {$al eq "last" || $al eq "both"}]
Paul Mackerrase341c062007-08-12 02:42:575499 } elseif {$arrowlow} {
5500 if {[lsearch -exact [lindex $rowidlist [expr {$row-1}]] $id] >= 0 ||
5501 [lsearch -exact [lindex $parentlist [expr {$row-1}]] $id] >= 0} {
5502 set arrowlow 0
5503 }
Paul Mackerras322a8cc2006-10-15 08:03:465504 }
5505 set arrow [lindex {none first last both} [expr {$arrowhigh + 2*$arrowlow}]]
5506 for {set y $le} {[incr y -1] > $row} {} {
5507 set x $xp
5508 set xp [lindex $cols [expr {$y - 1 - $row}]]
5509 set ndir [expr {$xp - $x}]
5510 if {$dir != $ndir || $xp < 0} {
5511 lappend coords [xc $y $x] [yc $y]
5512 }
5513 set dir $ndir
5514 }
5515 if {!$joinlow} {
5516 if {$xp < 0} {
5517 # join parent line to first child
5518 set ch [lindex $displayorder $row]
5519 set xc [lsearch -exact [lindex $rowidlist $row] $ch]
5520 if {$xc < 0} {
5521 puts "oops: drawlineseg: child $ch not on row $row"
Paul Mackerrase341c062007-08-12 02:42:575522 } elseif {$xc != $x} {
5523 if {($arrowhigh && $le == $row + 1) || $dir == 0} {
5524 set d [expr {int(0.5 * $linespc)}]
5525 set x1 [xc $row $x]
5526 if {$xc < $x} {
5527 set x2 [expr {$x1 - $d}]
5528 } else {
5529 set x2 [expr {$x1 + $d}]
5530 }
5531 set y2 [yc $row]
5532 set y1 [expr {$y2 + $d}]
5533 lappend coords $x1 $y1 $x2 $y2
5534 } elseif {$xc < $x - 1} {
Paul Mackerras322a8cc2006-10-15 08:03:465535 lappend coords [xc $row [expr {$x-1}]] [yc $row]
5536 } elseif {$xc > $x + 1} {
5537 lappend coords [xc $row [expr {$x+1}]] [yc $row]
5538 }
5539 set x $xc
5540 }
5541 lappend coords [xc $row $x] [yc $row]
5542 } else {
5543 set xn [xc $row $xp]
5544 set yn [yc $row]
Paul Mackerrase341c062007-08-12 02:42:575545 lappend coords $xn $yn
Paul Mackerras322a8cc2006-10-15 08:03:465546 }
5547 if {!$joinhigh} {
Paul Mackerras322a8cc2006-10-15 08:03:465548 assigncolor $id
5549 set t [$canv create line $coords -width [linewidth $id] \
5550 -fill $colormap($id) -tags lines.$id -arrow $arrow]
5551 $canv lower $t
5552 bindline $t $id
5553 set lines [linsert $lines $i [list $row $le $t]]
5554 } else {
5555 $canv coords $ith $coords
5556 if {$arrow ne $ah} {
5557 $canv itemconf $ith -arrow $arrow
5558 }
5559 lset lines $i 0 $row
5560 }
5561 } else {
5562 set xo [lsearch -exact [lindex $rowidlist [expr {$row - 1}]] $id]
5563 set ndir [expr {$xo - $xp}]
5564 set clow [$canv coords $itl]
5565 if {$dir == $ndir} {
5566 set clow [lrange $clow 2 end]
5567 }
5568 set coords [concat $coords $clow]
5569 if {!$joinhigh} {
5570 lset lines [expr {$i-1}] 1 $le
Paul Mackerras322a8cc2006-10-15 08:03:465571 } else {
5572 # coalesce two pieces
5573 $canv delete $ith
5574 set b [lindex $lines [expr {$i-1}] 0]
5575 set e [lindex $lines $i 1]
5576 set lines [lreplace $lines [expr {$i-1}] $i [list $b $e $itl]]
5577 }
5578 $canv coords $itl $coords
5579 if {$arrow ne $al} {
5580 $canv itemconf $itl -arrow $arrow
5581 }
5582 }
5583
5584 set linesegs($id) $lines
5585 return $le
5586}
5587
5588proc drawparentlinks {id row} {
5589 global rowidlist canv colormap curview parentlist
Paul Mackerras513a54d2007-08-01 12:27:575590 global idpos linespc
Paul Mackerras322a8cc2006-10-15 08:03:465591
5592 set rowids [lindex $rowidlist $row]
5593 set col [lsearch -exact $rowids $id]
5594 if {$col < 0} return
5595 set olds [lindex $parentlist $row]
Paul Mackerras9f1afe02006-02-19 11:44:475596 set row2 [expr {$row + 1}]
5597 set x [xc $row $col]
5598 set y [yc $row]
5599 set y2 [yc $row2]
Paul Mackerrase341c062007-08-12 02:42:575600 set d [expr {int(0.5 * $linespc)}]
Paul Mackerras513a54d2007-08-01 12:27:575601 set ymid [expr {$y + $d}]
Paul Mackerras8f7d0ce2006-02-28 11:10:195602 set ids [lindex $rowidlist $row2]
Paul Mackerras9f1afe02006-02-19 11:44:475603 # rmx = right-most X coord used
5604 set rmx 0
Paul Mackerras9f1afe02006-02-19 11:44:475605 foreach p $olds {
Paul Mackerrasf3408442006-03-30 22:54:245606 set i [lsearch -exact $ids $p]
5607 if {$i < 0} {
5608 puts "oops, parent $p of $id not in list"
5609 continue
5610 }
5611 set x2 [xc $row2 $i]
5612 if {$x2 > $rmx} {
5613 set rmx $x2
5614 }
Paul Mackerras513a54d2007-08-01 12:27:575615 set j [lsearch -exact $rowids $p]
5616 if {$j < 0} {
Paul Mackerraseb447a12006-03-18 12:11:375617 # drawlineseg will do this one for us
5618 continue
5619 }
Paul Mackerras9f1afe02006-02-19 11:44:475620 assigncolor $p
5621 # should handle duplicated parents here...
5622 set coords [list $x $y]
Paul Mackerras513a54d2007-08-01 12:27:575623 if {$i != $col} {
5624 # if attaching to a vertical segment, draw a smaller
5625 # slant for visual distinctness
5626 if {$i == $j} {
5627 if {$i < $col} {
5628 lappend coords [expr {$x2 + $d}] $y $x2 $ymid
5629 } else {
5630 lappend coords [expr {$x2 - $d}] $y $x2 $ymid
5631 }
5632 } elseif {$i < $col && $i < $j} {
5633 # segment slants towards us already
5634 lappend coords [xc $row $j] $y
5635 } else {
5636 if {$i < $col - 1} {
5637 lappend coords [expr {$x2 + $linespc}] $y
5638 } elseif {$i > $col + 1} {
5639 lappend coords [expr {$x2 - $linespc}] $y
5640 }
5641 lappend coords $x2 $y2
5642 }
5643 } else {
5644 lappend coords $x2 $y2
Paul Mackerras9f1afe02006-02-19 11:44:475645 }
Paul Mackerrasc934a8a2006-03-02 12:00:445646 set t [$canv create line $coords -width [linewidth $p] \
Paul Mackerras9f1afe02006-02-19 11:44:475647 -fill $colormap($p) -tags lines.$p]
5648 $canv lower $t
5649 bindline $t $p
5650 }
Paul Mackerras322a8cc2006-10-15 08:03:465651 if {$rmx > [lindex $idpos($id) 1]} {
5652 lset idpos($id) 1 $rmx
5653 redrawtags $id
5654 }
Paul Mackerras9f1afe02006-02-19 11:44:475655}
5656
Paul Mackerrasc934a8a2006-03-02 12:00:445657proc drawlines {id} {
Paul Mackerras322a8cc2006-10-15 08:03:465658 global canv
Paul Mackerras9f1afe02006-02-19 11:44:475659
Paul Mackerras322a8cc2006-10-15 08:03:465660 $canv itemconf lines.$id -width [linewidth $id]
Paul Mackerras9f1afe02006-02-19 11:44:475661}
5662
Paul Mackerras322a8cc2006-10-15 08:03:465663proc drawcmittext {id row col} {
Paul Mackerras7fcc92b2007-12-02 23:33:015664 global linespc canv canv2 canv3 fgcolor curview
5665 global cmitlisted commitinfo rowidlist parentlist
Paul Mackerras9f1afe02006-02-19 11:44:475666 global rowtextx idpos idtags idheads idotherrefs
Paul Mackerras03800812007-08-29 11:45:215667 global linehtag linentag linedtag selectedline
Paul Mackerrasb9fdba72009-04-08 23:34:465668 global canvxmax boldids boldnameids fgcolor markedid
Paul Mackerrasd277e892008-09-21 23:11:375669 global mainheadid nullid nullid2 circleitem circlecolors ctxbut
Paul Mackerras9f1afe02006-02-19 11:44:475670
Linus Torvalds1407ade2008-02-09 22:02:075671 # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 for right
Paul Mackerras7fcc92b2007-12-02 23:33:015672 set listed $cmitlisted($curview,$id)
Paul Mackerras219ea3a2006-09-07 00:21:395673 if {$id eq $nullid} {
5674 set ofill red
Paul Mackerras8f489362007-07-13 09:49:375675 } elseif {$id eq $nullid2} {
Paul Mackerrasef3192b2007-07-22 12:05:305676 set ofill green
Paul Mackerrasc11ff122008-05-26 00:11:335677 } elseif {$id eq $mainheadid} {
5678 set ofill yellow
Paul Mackerras219ea3a2006-09-07 00:21:395679 } else {
Paul Mackerrasc11ff122008-05-26 00:11:335680 set ofill [lindex $circlecolors $listed]
Paul Mackerras219ea3a2006-09-07 00:21:395681 }
Paul Mackerras9f1afe02006-02-19 11:44:475682 set x [xc $row $col]
5683 set y [yc $row]
5684 set orad [expr {$linespc / 3}]
Linus Torvalds1407ade2008-02-09 22:02:075685 if {$listed <= 2} {
Paul Mackerrasc961b222007-07-09 12:45:475686 set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
5687 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
5688 -fill $ofill -outline $fgcolor -width 1 -tags circle]
Linus Torvalds1407ade2008-02-09 22:02:075689 } elseif {$listed == 3} {
Paul Mackerrasc961b222007-07-09 12:45:475690 # triangle pointing left for left-side commits
5691 set t [$canv create polygon \
5692 [expr {$x - $orad}] $y \
5693 [expr {$x + $orad - 1}] [expr {$y - $orad}] \
5694 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
5695 -fill $ofill -outline $fgcolor -width 1 -tags circle]
5696 } else {
5697 # triangle pointing right for right-side commits
5698 set t [$canv create polygon \
5699 [expr {$x + $orad - 1}] $y \
5700 [expr {$x - $orad}] [expr {$y - $orad}] \
5701 [expr {$x - $orad}] [expr {$y + $orad - 1}] \
5702 -fill $ofill -outline $fgcolor -width 1 -tags circle]
5703 }
Paul Mackerrasc11ff122008-05-26 00:11:335704 set circleitem($row) $t
Paul Mackerras9f1afe02006-02-19 11:44:475705 $canv raise $t
5706 $canv bind $t <1> {selcanvline {} %x %y}
Paul Mackerras322a8cc2006-10-15 08:03:465707 set rmx [llength [lindex $rowidlist $row]]
5708 set olds [lindex $parentlist $row]
5709 if {$olds ne {}} {
5710 set nextids [lindex $rowidlist [expr {$row + 1}]]
5711 foreach p $olds {
5712 set i [lsearch -exact $nextids $p]
5713 if {$i > $rmx} {
5714 set rmx $i
5715 }
5716 }
Paul Mackerras9f1afe02006-02-19 11:44:475717 }
Paul Mackerras322a8cc2006-10-15 08:03:465718 set xt [xc $row $rmx]
Paul Mackerras9f1afe02006-02-19 11:44:475719 set rowtextx($row) $xt
5720 set idpos($id) [list $x $xt $y]
5721 if {[info exists idtags($id)] || [info exists idheads($id)]
5722 || [info exists idotherrefs($id)]} {
5723 set xt [drawtags $id $x $xt $y]
5724 }
5725 set headline [lindex $commitinfo($id) 0]
5726 set name [lindex $commitinfo($id) 1]
5727 set date [lindex $commitinfo($id) 2]
5728 set date [formatdate $date]
Paul Mackerras9c311b32007-10-04 12:27:135729 set font mainfont
5730 set nfont mainfont
Paul Mackerras476ca632008-01-07 11:16:315731 set isbold [ishighlighted $id]
Paul Mackerras908c3582006-05-19 23:38:115732 if {$isbold > 0} {
Paul Mackerras28593d32008-11-13 12:01:465733 lappend boldids $id
Paul Mackerras9c311b32007-10-04 12:27:135734 set font mainfontbold
Paul Mackerras908c3582006-05-19 23:38:115735 if {$isbold > 1} {
Paul Mackerras28593d32008-11-13 12:01:465736 lappend boldnameids $id
Paul Mackerras9c311b32007-10-04 12:27:135737 set nfont mainfontbold
Paul Mackerras908c3582006-05-19 23:38:115738 }
Paul Mackerrasda7c24d2006-05-02 01:15:295739 }
Paul Mackerras28593d32008-11-13 12:01:465740 set linehtag($id) [$canv create text $xt $y -anchor w -fill $fgcolor \
5741 -text $headline -font $font -tags text]
5742 $canv bind $linehtag($id) $ctxbut "rowmenu %X %Y $id"
5743 set linentag($id) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
5744 -text $name -font $nfont -tags text]
5745 set linedtag($id) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
5746 -text $date -font mainfont -tags text]
Paul Mackerras94b4a692008-05-20 10:51:065747 if {$selectedline == $row} {
Paul Mackerras28593d32008-11-13 12:01:465748 make_secsel $id
Paul Mackerras03800812007-08-29 11:45:215749 }
Paul Mackerrasb9fdba72009-04-08 23:34:465750 if {[info exists markedid] && $markedid eq $id} {
5751 make_idmark $id
5752 }
Paul Mackerras9c311b32007-10-04 12:27:135753 set xr [expr {$xt + [font measure $font $headline]}]
Paul Mackerrasbe0cd092006-03-30 22:55:115754 if {$xr > $canvxmax} {
5755 set canvxmax $xr
5756 setcanvscroll
5757 }
Paul Mackerras9f1afe02006-02-19 11:44:475758}
5759
5760proc drawcmitrow {row} {
Paul Mackerras03800812007-08-29 11:45:215761 global displayorder rowidlist nrows_drawn
Paul Mackerras005a2f42007-07-26 12:36:395762 global iddrawn markingmatches
Paul Mackerras7fcc92b2007-12-02 23:33:015763 global commitinfo numcommits
Paul Mackerras687c8762007-09-22 02:49:335764 global filehighlight fhighlights findpattern nhighlights
Paul Mackerras908c3582006-05-19 23:38:115765 global hlview vhighlights
Paul Mackerras164ff272006-05-29 09:50:025766 global highlight_related rhighlights
Paul Mackerras9f1afe02006-02-19 11:44:475767
Paul Mackerras8f7d0ce2006-02-28 11:10:195768 if {$row >= $numcommits} return
Paul Mackerras9f1afe02006-02-19 11:44:475769
5770 set id [lindex $displayorder $row]
Paul Mackerras476ca632008-01-07 11:16:315771 if {[info exists hlview] && ![info exists vhighlights($id)]} {
Paul Mackerras908c3582006-05-19 23:38:115772 askvhighlight $row $id
5773 }
Paul Mackerras476ca632008-01-07 11:16:315774 if {[info exists filehighlight] && ![info exists fhighlights($id)]} {
Paul Mackerras908c3582006-05-19 23:38:115775 askfilehighlight $row $id
5776 }
Paul Mackerras476ca632008-01-07 11:16:315777 if {$findpattern ne {} && ![info exists nhighlights($id)]} {
Paul Mackerras60f7a7d2006-05-26 00:43:475778 askfindhighlight $row $id
Paul Mackerras908c3582006-05-19 23:38:115779 }
Paul Mackerras476ca632008-01-07 11:16:315780 if {$highlight_related ne [mc "None"] && ![info exists rhighlights($id)]} {
Paul Mackerras164ff272006-05-29 09:50:025781 askrelhighlight $row $id
5782 }
Paul Mackerras005a2f42007-07-26 12:36:395783 if {![info exists iddrawn($id)]} {
5784 set col [lsearch -exact [lindex $rowidlist $row] $id]
5785 if {$col < 0} {
5786 puts "oops, row $row id $id not in list"
5787 return
5788 }
5789 if {![info exists commitinfo($id)]} {
5790 getcommit $id
5791 }
5792 assigncolor $id
5793 drawcmittext $id $row $col
5794 set iddrawn($id) 1
Paul Mackerras03800812007-08-29 11:45:215795 incr nrows_drawn
Paul Mackerras9f1afe02006-02-19 11:44:475796 }
Paul Mackerras005a2f42007-07-26 12:36:395797 if {$markingmatches} {
5798 markrowmatches $row $id
Paul Mackerras9f1afe02006-02-19 11:44:475799 }
Paul Mackerras9f1afe02006-02-19 11:44:475800}
5801
Paul Mackerras322a8cc2006-10-15 08:03:465802proc drawcommits {row {endrow {}}} {
Paul Mackerras03800812007-08-29 11:45:215803 global numcommits iddrawn displayorder curview need_redisplay
Paul Mackerrasf5f3c2e2007-09-04 16:19:565804 global parentlist rowidlist rowfinal uparrowlen downarrowlen nrows_drawn
Paul Mackerras322a8cc2006-10-15 08:03:465805
5806 if {$row < 0} {
5807 set row 0
5808 }
5809 if {$endrow eq {}} {
5810 set endrow $row
5811 }
5812 if {$endrow >= $numcommits} {
5813 set endrow [expr {$numcommits - 1}]
5814 }
5815
Paul Mackerras03800812007-08-29 11:45:215816 set rl1 [expr {$row - $downarrowlen - 3}]
5817 if {$rl1 < 0} {
5818 set rl1 0
5819 }
5820 set ro1 [expr {$row - 3}]
5821 if {$ro1 < 0} {
5822 set ro1 0
5823 }
5824 set r2 [expr {$endrow + $uparrowlen + 3}]
5825 if {$r2 > $numcommits} {
5826 set r2 $numcommits
5827 }
5828 for {set r $rl1} {$r < $r2} {incr r} {
Paul Mackerrasf5f3c2e2007-09-04 16:19:565829 if {[lindex $rowidlist $r] ne {} && [lindex $rowfinal $r]} {
Paul Mackerras03800812007-08-29 11:45:215830 if {$rl1 < $r} {
5831 layoutrows $rl1 $r
5832 }
5833 set rl1 [expr {$r + 1}]
5834 }
5835 }
5836 if {$rl1 < $r} {
5837 layoutrows $rl1 $r
5838 }
5839 optimize_rows $ro1 0 $r2
5840 if {$need_redisplay || $nrows_drawn > 2000} {
5841 clear_display
Paul Mackerras03800812007-08-29 11:45:215842 }
5843
Paul Mackerras322a8cc2006-10-15 08:03:465844 # make the lines join to already-drawn rows either side
5845 set r [expr {$row - 1}]
5846 if {$r < 0 || ![info exists iddrawn([lindex $displayorder $r])]} {
5847 set r $row
5848 }
5849 set er [expr {$endrow + 1}]
5850 if {$er >= $numcommits ||
5851 ![info exists iddrawn([lindex $displayorder $er])]} {
5852 set er $endrow
5853 }
5854 for {} {$r <= $er} {incr r} {
5855 set id [lindex $displayorder $r]
5856 set wasdrawn [info exists iddrawn($id)]
Paul Mackerras4fb0fa12007-07-04 09:43:515857 drawcmitrow $r
Paul Mackerras322a8cc2006-10-15 08:03:465858 if {$r == $er} break
5859 set nextid [lindex $displayorder [expr {$r + 1}]]
Paul Mackerrase5ef6f92007-10-21 02:58:425860 if {$wasdrawn && [info exists iddrawn($nextid)]} continue
Paul Mackerras322a8cc2006-10-15 08:03:465861 drawparentlinks $id $r
5862
Paul Mackerras322a8cc2006-10-15 08:03:465863 set rowids [lindex $rowidlist $r]
5864 foreach lid $rowids {
5865 if {$lid eq {}} continue
Paul Mackerrase5ef6f92007-10-21 02:58:425866 if {[info exists lineend($lid)] && $lineend($lid) > $r} continue
Paul Mackerras322a8cc2006-10-15 08:03:465867 if {$lid eq $id} {
5868 # see if this is the first child of any of its parents
5869 foreach p [lindex $parentlist $r] {
5870 if {[lsearch -exact $rowids $p] < 0} {
5871 # make this line extend up to the child
Paul Mackerrase5ef6f92007-10-21 02:58:425872 set lineend($p) [drawlineseg $p $r $er 0]
Paul Mackerras322a8cc2006-10-15 08:03:465873 }
5874 }
Paul Mackerrase5ef6f92007-10-21 02:58:425875 } else {
5876 set lineend($lid) [drawlineseg $lid $r $er 1]
Paul Mackerras322a8cc2006-10-15 08:03:465877 }
5878 }
5879 }
5880}
5881
Paul Mackerras7fcc92b2007-12-02 23:33:015882proc undolayout {row} {
5883 global uparrowlen mingaplen downarrowlen
5884 global rowidlist rowisopt rowfinal need_redisplay
5885
5886 set r [expr {$row - ($uparrowlen + $mingaplen + $downarrowlen)}]
5887 if {$r < 0} {
5888 set r 0
5889 }
5890 if {[llength $rowidlist] > $r} {
5891 incr r -1
5892 set rowidlist [lrange $rowidlist 0 $r]
5893 set rowfinal [lrange $rowfinal 0 $r]
5894 set rowisopt [lrange $rowisopt 0 $r]
5895 set need_redisplay 1
5896 run drawvisible
5897 }
5898}
5899
Paul Mackerras31c0eaa2007-12-30 11:41:145900proc drawvisible {} {
5901 global canv linespc curview vrowmod selectedline targetrow targetid
Paul Mackerras42a671f2008-01-01 22:59:395902 global need_redisplay cscroll numcommits
Paul Mackerras9f1afe02006-02-19 11:44:475903
Paul Mackerras31c0eaa2007-12-30 11:41:145904 set fs [$canv yview]
Paul Mackerras9f1afe02006-02-19 11:44:475905 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras5a7f5772008-01-15 11:45:365906 if {$ymax eq {} || $ymax == 0 || $numcommits == 0} return
Paul Mackerras31c0eaa2007-12-30 11:41:145907 set f0 [lindex $fs 0]
5908 set f1 [lindex $fs 1]
Paul Mackerras9f1afe02006-02-19 11:44:475909 set y0 [expr {int($f0 * $ymax)}]
Paul Mackerras9f1afe02006-02-19 11:44:475910 set y1 [expr {int($f1 * $ymax)}]
Paul Mackerras9f1afe02006-02-19 11:44:475911
Paul Mackerras31c0eaa2007-12-30 11:41:145912 if {[info exists targetid]} {
Paul Mackerras42a671f2008-01-01 22:59:395913 if {[commitinview $targetid $curview]} {
5914 set r [rowofcommit $targetid]
5915 if {$r != $targetrow} {
5916 # Fix up the scrollregion and change the scrolling position
5917 # now that our target row has moved.
5918 set diff [expr {($r - $targetrow) * $linespc}]
5919 set targetrow $r
5920 setcanvscroll
5921 set ymax [lindex [$canv cget -scrollregion] 3]
5922 incr y0 $diff
5923 incr y1 $diff
5924 set f0 [expr {$y0 / $ymax}]
5925 set f1 [expr {$y1 / $ymax}]
5926 allcanvs yview moveto $f0
5927 $cscroll set $f0 $f1
5928 set need_redisplay 1
5929 }
5930 } else {
5931 unset targetid
Paul Mackerras31c0eaa2007-12-30 11:41:145932 }
5933 }
5934
5935 set row [expr {int(($y0 - 3) / $linespc) - 1}]
5936 set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
5937 if {$endrow >= $vrowmod($curview)} {
5938 update_arcrows $curview
5939 }
Paul Mackerras94b4a692008-05-20 10:51:065940 if {$selectedline ne {} &&
Paul Mackerras31c0eaa2007-12-30 11:41:145941 $row <= $selectedline && $selectedline <= $endrow} {
5942 set targetrow $selectedline
Paul Mackerrasac1276a2008-03-02 23:11:085943 } elseif {[info exists targetid]} {
Paul Mackerras31c0eaa2007-12-30 11:41:145944 set targetrow [expr {int(($row + $endrow) / 2)}]
5945 }
Paul Mackerrasac1276a2008-03-02 23:11:085946 if {[info exists targetrow]} {
5947 if {$targetrow >= $numcommits} {
5948 set targetrow [expr {$numcommits - 1}]
5949 }
5950 set targetid [commitonrow $targetrow]
Paul Mackerras42a671f2008-01-01 22:59:395951 }
Paul Mackerras31c0eaa2007-12-30 11:41:145952 drawcommits $row $endrow
Paul Mackerras9f1afe02006-02-19 11:44:475953}
5954
5955proc clear_display {} {
Paul Mackerras03800812007-08-29 11:45:215956 global iddrawn linesegs need_redisplay nrows_drawn
Paul Mackerras164ff272006-05-29 09:50:025957 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras28593d32008-11-13 12:01:465958 global linehtag linentag linedtag boldids boldnameids
Paul Mackerras9f1afe02006-02-19 11:44:475959
5960 allcanvs delete all
5961 catch {unset iddrawn}
Paul Mackerras322a8cc2006-10-15 08:03:465962 catch {unset linesegs}
Paul Mackerras94503a62008-05-18 23:48:455963 catch {unset linehtag}
5964 catch {unset linentag}
5965 catch {unset linedtag}
Paul Mackerras28593d32008-11-13 12:01:465966 set boldids {}
5967 set boldnameids {}
Paul Mackerras908c3582006-05-19 23:38:115968 catch {unset vhighlights}
5969 catch {unset fhighlights}
5970 catch {unset nhighlights}
Paul Mackerras164ff272006-05-29 09:50:025971 catch {unset rhighlights}
Paul Mackerras03800812007-08-29 11:45:215972 set need_redisplay 0
5973 set nrows_drawn 0
Paul Mackerras9f1afe02006-02-19 11:44:475974}
5975
Paul Mackerras50b44ec2006-04-04 00:16:225976proc findcrossings {id} {
Paul Mackerras6e8c8702007-07-31 11:03:065977 global rowidlist parentlist numcommits displayorder
Paul Mackerras50b44ec2006-04-04 00:16:225978
5979 set cross {}
5980 set ccross {}
5981 foreach {s e} [rowranges $id] {
5982 if {$e >= $numcommits} {
5983 set e [expr {$numcommits - 1}]
Paul Mackerras50b44ec2006-04-04 00:16:225984 }
Paul Mackerrasd94f8cd2006-04-06 00:18:235985 if {$e <= $s} continue
Paul Mackerras50b44ec2006-04-04 00:16:225986 for {set row $e} {[incr row -1] >= $s} {} {
Paul Mackerras6e8c8702007-07-31 11:03:065987 set x [lsearch -exact [lindex $rowidlist $row] $id]
5988 if {$x < 0} break
Paul Mackerras50b44ec2006-04-04 00:16:225989 set olds [lindex $parentlist $row]
5990 set kid [lindex $displayorder $row]
5991 set kidx [lsearch -exact [lindex $rowidlist $row] $kid]
5992 if {$kidx < 0} continue
5993 set nextrow [lindex $rowidlist [expr {$row + 1}]]
5994 foreach p $olds {
5995 set px [lsearch -exact $nextrow $p]
5996 if {$px < 0} continue
5997 if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} {
5998 if {[lsearch -exact $ccross $p] >= 0} continue
5999 if {$x == $px + ($kidx < $px? -1: 1)} {
6000 lappend ccross $p
6001 } elseif {[lsearch -exact $cross $p] < 0} {
6002 lappend cross $p
6003 }
6004 }
6005 }
Paul Mackerras50b44ec2006-04-04 00:16:226006 }
6007 }
6008 return [concat $ccross {{}} $cross]
6009}
6010
Paul Mackerrase5c2d852005-05-11 23:44:546011proc assigncolor {id} {
Paul Mackerrasaa81d972006-02-28 00:27:126012 global colormap colors nextcolor
Paul Mackerras7fcc92b2007-12-02 23:33:016013 global parents children children curview
Paul Mackerras6c20ff32005-06-22 09:53:326014
Paul Mackerras418c4c72006-02-06 22:10:186015 if {[info exists colormap($id)]} return
Paul Mackerrase5c2d852005-05-11 23:44:546016 set ncolors [llength $colors]
Paul Mackerrasda7c24d2006-05-02 01:15:296017 if {[info exists children($curview,$id)]} {
6018 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 10:47:406019 } else {
6020 set kids {}
6021 }
6022 if {[llength $kids] == 1} {
6023 set child [lindex $kids 0]
Paul Mackerras9ccbdfb2005-06-16 00:27:236024 if {[info exists colormap($child)]
Paul Mackerras7fcc92b2007-12-02 23:33:016025 && [llength $parents($curview,$child)] == 1} {
Paul Mackerras9ccbdfb2005-06-16 00:27:236026 set colormap($id) $colormap($child)
6027 return
Paul Mackerrase5c2d852005-05-11 23:44:546028 }
Paul Mackerras9ccbdfb2005-06-16 00:27:236029 }
6030 set badcolors {}
Paul Mackerras50b44ec2006-04-04 00:16:226031 set origbad {}
6032 foreach x [findcrossings $id] {
6033 if {$x eq {}} {
6034 # delimiter between corner crossings and other crossings
6035 if {[llength $badcolors] >= $ncolors - 1} break
6036 set origbad $badcolors
Paul Mackerrase5c2d852005-05-11 23:44:546037 }
Paul Mackerras50b44ec2006-04-04 00:16:226038 if {[info exists colormap($x)]
6039 && [lsearch -exact $badcolors $colormap($x)] < 0} {
6040 lappend badcolors $colormap($x)
Paul Mackerras6c20ff32005-06-22 09:53:326041 }
6042 }
Paul Mackerras50b44ec2006-04-04 00:16:226043 if {[llength $badcolors] >= $ncolors} {
6044 set badcolors $origbad
6045 }
Paul Mackerras6c20ff32005-06-22 09:53:326046 set origbad $badcolors
6047 if {[llength $badcolors] < $ncolors - 1} {
Paul Mackerras79b2c752006-04-02 10:47:406048 foreach child $kids {
Paul Mackerras6c20ff32005-06-22 09:53:326049 if {[info exists colormap($child)]
6050 && [lsearch -exact $badcolors $colormap($child)] < 0} {
6051 lappend badcolors $colormap($child)
6052 }
Paul Mackerras7fcc92b2007-12-02 23:33:016053 foreach p $parents($curview,$child) {
Paul Mackerras79b2c752006-04-02 10:47:406054 if {[info exists colormap($p)]
6055 && [lsearch -exact $badcolors $colormap($p)] < 0} {
6056 lappend badcolors $colormap($p)
Paul Mackerrase5c2d852005-05-11 23:44:546057 }
6058 }
6059 }
Paul Mackerras6c20ff32005-06-22 09:53:326060 if {[llength $badcolors] >= $ncolors} {
6061 set badcolors $origbad
6062 }
Paul Mackerras9ccbdfb2005-06-16 00:27:236063 }
6064 for {set i 0} {$i <= $ncolors} {incr i} {
6065 set c [lindex $colors $nextcolor]
6066 if {[incr nextcolor] >= $ncolors} {
6067 set nextcolor 0
Paul Mackerrase5c2d852005-05-11 23:44:546068 }
Paul Mackerras9ccbdfb2005-06-16 00:27:236069 if {[lsearch -exact $badcolors $c]} break
6070 }
6071 set colormap($id) $c
6072}
6073
Paul Mackerrasa823a912005-06-21 00:01:386074proc bindline {t id} {
6075 global canv
6076
Paul Mackerrasa823a912005-06-21 00:01:386077 $canv bind $t <Enter> "lineenter %x %y $id"
6078 $canv bind $t <Motion> "linemotion %x %y $id"
6079 $canv bind $t <Leave> "lineleave $id"
Paul Mackerrasfa4da7b2005-08-07 23:47:226080 $canv bind $t <Button-1> "lineclick %x %y $id 1"
Paul Mackerrasa823a912005-06-21 00:01:386081}
6082
Paul Mackerrasbdbfbe32005-06-27 12:56:406083proc drawtags {id x xt y1} {
Paul Mackerras8a485712006-07-06 00:21:236084 global idtags idheads idotherrefs mainhead
Paul Mackerrasbdbfbe32005-06-27 12:56:406085 global linespc lthickness
Paul Mackerrasd277e892008-09-21 23:11:376086 global canv rowtextx curview fgcolor bgcolor ctxbut
Paul Mackerrasbdbfbe32005-06-27 12:56:406087
6088 set marks {}
6089 set ntags 0
Paul Mackerrasf1d83ba2005-08-19 12:14:286090 set nheads 0
Paul Mackerrasbdbfbe32005-06-27 12:56:406091 if {[info exists idtags($id)]} {
6092 set marks $idtags($id)
6093 set ntags [llength $marks]
6094 }
6095 if {[info exists idheads($id)]} {
6096 set marks [concat $marks $idheads($id)]
Paul Mackerrasf1d83ba2005-08-19 12:14:286097 set nheads [llength $idheads($id)]
6098 }
6099 if {[info exists idotherrefs($id)]} {
6100 set marks [concat $marks $idotherrefs($id)]
Paul Mackerrasbdbfbe32005-06-27 12:56:406101 }
6102 if {$marks eq {}} {
6103 return $xt
6104 }
6105
6106 set delta [expr {int(0.5 * ($linespc - $lthickness))}]
Jeff Hobbs2ed49d52005-11-23 01:39:536107 set yt [expr {$y1 - 0.5 * $linespc}]
6108 set yb [expr {$yt + $linespc - 1}]
Paul Mackerrasbdbfbe32005-06-27 12:56:406109 set xvals {}
6110 set wvals {}
Paul Mackerras8a485712006-07-06 00:21:236111 set i -1
Paul Mackerrasbdbfbe32005-06-27 12:56:406112 foreach tag $marks {
Paul Mackerras8a485712006-07-06 00:21:236113 incr i
6114 if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
Paul Mackerras9c311b32007-10-04 12:27:136115 set wid [font measure mainfontbold $tag]
Paul Mackerras8a485712006-07-06 00:21:236116 } else {
Paul Mackerras9c311b32007-10-04 12:27:136117 set wid [font measure mainfont $tag]
Paul Mackerras8a485712006-07-06 00:21:236118 }
Paul Mackerrasbdbfbe32005-06-27 12:56:406119 lappend xvals $xt
6120 lappend wvals $wid
6121 set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
6122 }
6123 set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
6124 -width $lthickness -fill black -tags tag.$id]
6125 $canv lower $t
6126 foreach tag $marks x $xvals wid $wvals {
Jeff Hobbs2ed49d52005-11-23 01:39:536127 set xl [expr {$x + $delta}]
6128 set xr [expr {$x + $delta + $wid + $lthickness}]
Paul Mackerras9c311b32007-10-04 12:27:136129 set font mainfont
Paul Mackerrasbdbfbe32005-06-27 12:56:406130 if {[incr ntags -1] >= 0} {
6131 # draw a tag
Jeff Hobbs2ed49d52005-11-23 01:39:536132 set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
6133 $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
Paul Mackerras106288c2005-08-19 13:11:396134 -width 1 -outline black -fill yellow -tags tag.$id]
6135 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras7fcc92b2007-12-02 23:33:016136 set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}]
Paul Mackerrasbdbfbe32005-06-27 12:56:406137 } else {
Paul Mackerrasf1d83ba2005-08-19 12:14:286138 # draw a head or other ref
6139 if {[incr nheads -1] >= 0} {
6140 set col green
Paul Mackerras8a485712006-07-06 00:21:236141 if {$tag eq $mainhead} {
Paul Mackerras9c311b32007-10-04 12:27:136142 set font mainfontbold
Paul Mackerras8a485712006-07-06 00:21:236143 }
Paul Mackerrasf1d83ba2005-08-19 12:14:286144 } else {
6145 set col "#ddddff"
6146 }
Jeff Hobbs2ed49d52005-11-23 01:39:536147 set xl [expr {$xl - $delta/2}]
Paul Mackerrasbdbfbe32005-06-27 12:56:406148 $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
Paul Mackerrasf1d83ba2005-08-19 12:14:286149 -width 1 -outline black -fill $col -tags tag.$id
Josef Weidendorfera970fcf2006-04-18 21:53:076150 if {[regexp {^(remotes/.*/|remotes/)} $tag match remoteprefix]} {
Paul Mackerras9c311b32007-10-04 12:27:136151 set rwid [font measure mainfont $remoteprefix]
Josef Weidendorfera970fcf2006-04-18 21:53:076152 set xi [expr {$x + 1}]
6153 set yti [expr {$yt + 1}]
6154 set xri [expr {$x + $rwid}]
6155 $canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \
6156 -width 0 -fill "#ffddaa" -tags tag.$id
6157 }
Paul Mackerrasbdbfbe32005-06-27 12:56:406158 }
Paul Mackerrasf8a2c0d2006-07-05 12:56:376159 set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \
Paul Mackerras8a485712006-07-06 00:21:236160 -font $font -tags [list tag.$id text]]
Paul Mackerras106288c2005-08-19 13:11:396161 if {$ntags >= 0} {
6162 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras10299152006-08-01 23:52:016163 } elseif {$nheads >= 0} {
Paul Mackerrasd277e892008-09-21 23:11:376164 $canv bind $t $ctxbut [list headmenu %X %Y $id $tag]
Paul Mackerras106288c2005-08-19 13:11:396165 }
Paul Mackerrasbdbfbe32005-06-27 12:56:406166 }
6167 return $xt
6168}
6169
Paul Mackerras8d858d12005-08-04 23:52:166170proc xcoord {i level ln} {
6171 global canvx0 xspc1 xspc2
Paul Mackerras9ccbdfb2005-06-16 00:27:236172
Paul Mackerras8d858d12005-08-04 23:52:166173 set x [expr {$canvx0 + $i * $xspc1($ln)}]
6174 if {$i > 0 && $i == $level} {
6175 set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
6176 } elseif {$i > $level} {
6177 set x [expr {$x + $xspc2 - $xspc1($ln)}]
6178 }
6179 return $x
6180}
6181
Paul Mackerras098dd8a2006-05-02 23:32:536182proc show_status {msg} {
Paul Mackerras9c311b32007-10-04 12:27:136183 global canv fgcolor
Paul Mackerras098dd8a2006-05-02 23:32:536184
6185 clear_display
Paul Mackerras9c311b32007-10-04 12:27:136186 $canv create text 3 3 -anchor nw -text $msg -font mainfont \
Paul Mackerrasf8a2c0d2006-07-05 12:56:376187 -tags text -fill $fgcolor
Paul Mackerras098dd8a2006-05-02 23:32:536188}
6189
Paul Mackerras94a2eed2005-08-07 05:27:576190# Don't change the text pane cursor if it is currently the hand cursor,
6191# showing that we are over a sha1 ID link.
6192proc settextcursor {c} {
6193 global ctext curtextcursor
6194
6195 if {[$ctext cget -cursor] == $curtextcursor} {
6196 $ctext config -cursor $c
6197 }
6198 set curtextcursor $c
Paul Mackerras9ccbdfb2005-06-16 00:27:236199}
6200
Paul Mackerrasa137a902007-10-23 11:12:496201proc nowbusy {what {name {}}} {
6202 global isbusy busyname statusw
Paul Mackerrasda7c24d2006-05-02 01:15:296203
6204 if {[array names isbusy] eq {}} {
6205 . config -cursor watch
6206 settextcursor watch
6207 }
6208 set isbusy($what) 1
Paul Mackerrasa137a902007-10-23 11:12:496209 set busyname($what) $name
6210 if {$name ne {}} {
6211 $statusw conf -text $name
6212 }
Paul Mackerrasda7c24d2006-05-02 01:15:296213}
6214
6215proc notbusy {what} {
Paul Mackerrasa137a902007-10-23 11:12:496216 global isbusy maincursor textcursor busyname statusw
Paul Mackerrasda7c24d2006-05-02 01:15:296217
Paul Mackerrasa137a902007-10-23 11:12:496218 catch {
6219 unset isbusy($what)
6220 if {$busyname($what) ne {} &&
6221 [$statusw cget -text] eq $busyname($what)} {
6222 $statusw conf -text {}
6223 }
6224 }
Paul Mackerrasda7c24d2006-05-02 01:15:296225 if {[array names isbusy] eq {}} {
6226 . config -cursor $maincursor
6227 settextcursor $textcursor
6228 }
6229}
6230
Paul Mackerrasdf3d83b2005-05-17 23:23:076231proc findmatches {f} {
Paul Mackerras4fb0fa12007-07-04 09:43:516232 global findtype findstring
Christian Stimmingb007ee22007-11-07 17:44:356233 if {$findtype == [mc "Regexp"]} {
Paul Mackerras4fb0fa12007-07-04 09:43:516234 set matches [regexp -indices -all -inline $findstring $f]
Paul Mackerrasdf3d83b2005-05-17 23:23:076235 } else {
Paul Mackerras4fb0fa12007-07-04 09:43:516236 set fs $findstring
Christian Stimmingb007ee22007-11-07 17:44:356237 if {$findtype == [mc "IgnCase"]} {
Paul Mackerras4fb0fa12007-07-04 09:43:516238 set f [string tolower $f]
6239 set fs [string tolower $fs]
Paul Mackerrasdf3d83b2005-05-17 23:23:076240 }
6241 set matches {}
6242 set i 0
Paul Mackerras4fb0fa12007-07-04 09:43:516243 set l [string length $fs]
6244 while {[set j [string first $fs $f $i]] >= 0} {
6245 lappend matches [list $j [expr {$j+$l-1}]]
6246 set i [expr {$j + $l}]
Paul Mackerrasdf3d83b2005-05-17 23:23:076247 }
6248 }
6249 return $matches
6250}
6251
Paul Mackerrascca5d942007-10-27 11:16:566252proc dofind {{dirn 1} {wrap 1}} {
Paul Mackerras4fb0fa12007-07-04 09:43:516253 global findstring findstartline findcurline selectedline numcommits
Paul Mackerrascca5d942007-10-27 11:16:566254 global gdttype filehighlight fh_serial find_dirn findallowwrap
Paul Mackerrasb74fd572005-07-16 11:46:136255
Paul Mackerrascca5d942007-10-27 11:16:566256 if {[info exists find_dirn]} {
6257 if {$find_dirn == $dirn} return
6258 stopfinding
6259 }
Paul Mackerrasdf3d83b2005-05-17 23:23:076260 focus .
Paul Mackerras4fb0fa12007-07-04 09:43:516261 if {$findstring eq {} || $numcommits == 0} return
Paul Mackerras94b4a692008-05-20 10:51:066262 if {$selectedline eq {}} {
Paul Mackerrascca5d942007-10-27 11:16:566263 set findstartline [lindex [visiblerows] [expr {$dirn < 0}]]
Paul Mackerras98f350e2005-05-15 05:56:516264 } else {
Paul Mackerras4fb0fa12007-07-04 09:43:516265 set findstartline $selectedline
Paul Mackerras98f350e2005-05-15 05:56:516266 }
Paul Mackerras4fb0fa12007-07-04 09:43:516267 set findcurline $findstartline
Christian Stimmingb007ee22007-11-07 17:44:356268 nowbusy finding [mc "Searching"]
6269 if {$gdttype ne [mc "containing:"] && ![info exists filehighlight]} {
Paul Mackerras687c8762007-09-22 02:49:336270 after cancel do_file_hl $fh_serial
6271 do_file_hl $fh_serial
Paul Mackerras4fb0fa12007-07-04 09:43:516272 }
Paul Mackerrascca5d942007-10-27 11:16:566273 set find_dirn $dirn
6274 set findallowwrap $wrap
6275 run findmore
Paul Mackerras4fb0fa12007-07-04 09:43:516276}
6277
Paul Mackerrasbb3edc82007-09-27 01:00:256278proc stopfinding {} {
6279 global find_dirn findcurline fprogcoord
Paul Mackerras4fb0fa12007-07-04 09:43:516280
Paul Mackerrasbb3edc82007-09-27 01:00:256281 if {[info exists find_dirn]} {
6282 unset find_dirn
6283 unset findcurline
6284 notbusy finding
6285 set fprogcoord 0
6286 adjustprogress
Paul Mackerras4fb0fa12007-07-04 09:43:516287 }
Paul Mackerras8a897742008-10-27 10:36:256288 stopblaming
Paul Mackerras4fb0fa12007-07-04 09:43:516289}
6290
6291proc findmore {} {
Paul Mackerras687c8762007-09-22 02:49:336292 global commitdata commitinfo numcommits findpattern findloc
Paul Mackerras7fcc92b2007-12-02 23:33:016293 global findstartline findcurline findallowwrap
Paul Mackerrasbb3edc82007-09-27 01:00:256294 global find_dirn gdttype fhighlights fprogcoord
Paul Mackerrascd2bcae2008-01-02 10:44:066295 global curview varcorder vrownum varccommits vrowmod
Paul Mackerras4fb0fa12007-07-04 09:43:516296
Paul Mackerrasbb3edc82007-09-27 01:00:256297 if {![info exists find_dirn]} {
Paul Mackerras4fb0fa12007-07-04 09:43:516298 return 0
Paul Mackerrasdf3d83b2005-05-17 23:23:076299 }
Christian Stimmingb007ee22007-11-07 17:44:356300 set fldtypes [list [mc "Headline"] [mc "Author"] [mc "Date"] [mc "Committer"] [mc "CDate"] [mc "Comments"]]
Paul Mackerras4fb0fa12007-07-04 09:43:516301 set l $findcurline
Paul Mackerrascca5d942007-10-27 11:16:566302 set moretodo 0
6303 if {$find_dirn > 0} {
6304 incr l
6305 if {$l >= $numcommits} {
6306 set l 0
Paul Mackerras4fb0fa12007-07-04 09:43:516307 }
Paul Mackerrascca5d942007-10-27 11:16:566308 if {$l <= $findstartline} {
6309 set lim [expr {$findstartline + 1}]
6310 } else {
6311 set lim $numcommits
6312 set moretodo $findallowwrap
6313 }
Paul Mackerras4fb0fa12007-07-04 09:43:516314 } else {
Paul Mackerrascca5d942007-10-27 11:16:566315 if {$l == 0} {
6316 set l $numcommits
6317 }
6318 incr l -1
6319 if {$l >= $findstartline} {
6320 set lim [expr {$findstartline - 1}]
6321 } else {
6322 set lim -1
6323 set moretodo $findallowwrap
6324 }
Paul Mackerras4fb0fa12007-07-04 09:43:516325 }
Paul Mackerrascca5d942007-10-27 11:16:566326 set n [expr {($lim - $l) * $find_dirn}]
6327 if {$n > 500} {
6328 set n 500
6329 set moretodo 1
Paul Mackerras4fb0fa12007-07-04 09:43:516330 }
Paul Mackerrascd2bcae2008-01-02 10:44:066331 if {$l + ($find_dirn > 0? $n: 1) > $vrowmod($curview)} {
6332 update_arcrows $curview
6333 }
Paul Mackerras687c8762007-09-22 02:49:336334 set found 0
6335 set domore 1
Paul Mackerras7fcc92b2007-12-02 23:33:016336 set ai [bsearch $vrownum($curview) $l]
6337 set a [lindex $varcorder($curview) $ai]
6338 set arow [lindex $vrownum($curview) $ai]
6339 set ids [lindex $varccommits($curview,$a)]
6340 set arowend [expr {$arow + [llength $ids]}]
Christian Stimmingb007ee22007-11-07 17:44:356341 if {$gdttype eq [mc "containing:"]} {
Paul Mackerrascca5d942007-10-27 11:16:566342 for {} {$n > 0} {incr n -1; incr l $find_dirn} {
Paul Mackerras7fcc92b2007-12-02 23:33:016343 if {$l < $arow || $l >= $arowend} {
6344 incr ai $find_dirn
6345 set a [lindex $varcorder($curview) $ai]
6346 set arow [lindex $vrownum($curview) $ai]
6347 set ids [lindex $varccommits($curview,$a)]
6348 set arowend [expr {$arow + [llength $ids]}]
6349 }
6350 set id [lindex $ids [expr {$l - $arow}]]
Paul Mackerras687c8762007-09-22 02:49:336351 # shouldn't happen unless git log doesn't give all the commits...
Paul Mackerras7fcc92b2007-12-02 23:33:016352 if {![info exists commitdata($id)] ||
6353 ![doesmatch $commitdata($id)]} {
6354 continue
6355 }
Paul Mackerras687c8762007-09-22 02:49:336356 if {![info exists commitinfo($id)]} {
6357 getcommit $id
6358 }
6359 set info $commitinfo($id)
6360 foreach f $info ty $fldtypes {
Christian Stimmingb007ee22007-11-07 17:44:356361 if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
Paul Mackerras687c8762007-09-22 02:49:336362 [doesmatch $f]} {
6363 set found 1
6364 break
6365 }
6366 }
6367 if {$found} break
Paul Mackerras8ed16482006-03-02 11:56:446368 }
Paul Mackerras687c8762007-09-22 02:49:336369 } else {
Paul Mackerrascca5d942007-10-27 11:16:566370 for {} {$n > 0} {incr n -1; incr l $find_dirn} {
Paul Mackerras7fcc92b2007-12-02 23:33:016371 if {$l < $arow || $l >= $arowend} {
6372 incr ai $find_dirn
6373 set a [lindex $varcorder($curview) $ai]
6374 set arow [lindex $vrownum($curview) $ai]
6375 set ids [lindex $varccommits($curview,$a)]
6376 set arowend [expr {$arow + [llength $ids]}]
6377 }
6378 set id [lindex $ids [expr {$l - $arow}]]
Paul Mackerras476ca632008-01-07 11:16:316379 if {![info exists fhighlights($id)]} {
6380 # this sets fhighlights($id) to -1
Paul Mackerras687c8762007-09-22 02:49:336381 askfilehighlight $l $id
Paul Mackerrascd2bcae2008-01-02 10:44:066382 }
Paul Mackerras476ca632008-01-07 11:16:316383 if {$fhighlights($id) > 0} {
Paul Mackerrascd2bcae2008-01-02 10:44:066384 set found $domore
6385 break
6386 }
Paul Mackerras476ca632008-01-07 11:16:316387 if {$fhighlights($id) < 0} {
Paul Mackerras687c8762007-09-22 02:49:336388 if {$domore} {
6389 set domore 0
Paul Mackerrascca5d942007-10-27 11:16:566390 set findcurline [expr {$l - $find_dirn}]
Paul Mackerras687c8762007-09-22 02:49:336391 }
Paul Mackerras4fb0fa12007-07-04 09:43:516392 }
6393 }
6394 }
Paul Mackerrascca5d942007-10-27 11:16:566395 if {$found || ($domore && !$moretodo)} {
Paul Mackerras4fb0fa12007-07-04 09:43:516396 unset findcurline
Paul Mackerras687c8762007-09-22 02:49:336397 unset find_dirn
Paul Mackerras4fb0fa12007-07-04 09:43:516398 notbusy finding
Paul Mackerrasbb3edc82007-09-27 01:00:256399 set fprogcoord 0
6400 adjustprogress
6401 if {$found} {
6402 findselectline $l
6403 } else {
6404 bell
6405 }
Paul Mackerras4fb0fa12007-07-04 09:43:516406 return 0
6407 }
Paul Mackerras687c8762007-09-22 02:49:336408 if {!$domore} {
6409 flushhighlights
Paul Mackerrasbb3edc82007-09-27 01:00:256410 } else {
Paul Mackerrascca5d942007-10-27 11:16:566411 set findcurline [expr {$l - $find_dirn}]
Paul Mackerras687c8762007-09-22 02:49:336412 }
Paul Mackerrascca5d942007-10-27 11:16:566413 set n [expr {($findcurline - $findstartline) * $find_dirn - 1}]
Paul Mackerrasbb3edc82007-09-27 01:00:256414 if {$n < 0} {
6415 incr n $numcommits
Paul Mackerras4fb0fa12007-07-04 09:43:516416 }
Paul Mackerrasbb3edc82007-09-27 01:00:256417 set fprogcoord [expr {$n * 1.0 / $numcommits}]
6418 adjustprogress
6419 return $domore
Paul Mackerrasdf3d83b2005-05-17 23:23:076420}
6421
6422proc findselectline {l} {
Paul Mackerras687c8762007-09-22 02:49:336423 global findloc commentend ctext findcurline markingmatches gdttype
Paul Mackerras005a2f42007-07-26 12:36:396424
Paul Mackerras8b39e042008-12-01 22:02:466425 set markingmatches [expr {$gdttype eq [mc "containing:"]}]
Paul Mackerras005a2f42007-07-26 12:36:396426 set findcurline $l
Paul Mackerrasd6982062005-08-06 12:06:066427 selectline $l 1
Paul Mackerras8b39e042008-12-01 22:02:466428 if {$markingmatches &&
6429 ($findloc eq [mc "All fields"] || $findloc eq [mc "Comments"])} {
Paul Mackerrasdf3d83b2005-05-17 23:23:076430 # highlight the matches in the comments
6431 set f [$ctext get 1.0 $commentend]
6432 set matches [findmatches $f]
6433 foreach match $matches {
6434 set start [lindex $match 0]
Jeff Hobbs2ed49d52005-11-23 01:39:536435 set end [expr {[lindex $match 1] + 1}]
Paul Mackerrasdf3d83b2005-05-17 23:23:076436 $ctext tag add found "1.0 + $start c" "1.0 + $end c"
6437 }
Paul Mackerras98f350e2005-05-15 05:56:516438 }
Paul Mackerras005a2f42007-07-26 12:36:396439 drawvisible
Paul Mackerras98f350e2005-05-15 05:56:516440}
6441
Paul Mackerras4fb0fa12007-07-04 09:43:516442# mark the bits of a headline or author that match a find string
Paul Mackerras005a2f42007-07-26 12:36:396443proc markmatches {canv l str tag matches font row} {
6444 global selectedline
6445
Paul Mackerras98f350e2005-05-15 05:56:516446 set bbox [$canv bbox $tag]
6447 set x0 [lindex $bbox 0]
6448 set y0 [lindex $bbox 1]
6449 set y1 [lindex $bbox 3]
6450 foreach match $matches {
6451 set start [lindex $match 0]
6452 set end [lindex $match 1]
6453 if {$start > $end} continue
Jeff Hobbs2ed49d52005-11-23 01:39:536454 set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
6455 set xlen [font measure $font [string range $str 0 [expr {$end}]]]
6456 set t [$canv create rect [expr {$x0+$xoff}] $y0 \
6457 [expr {$x0+$xlen+2}] $y1 \
Paul Mackerras4fb0fa12007-07-04 09:43:516458 -outline {} -tags [list match$l matches] -fill yellow]
Paul Mackerras98f350e2005-05-15 05:56:516459 $canv lower $t
Paul Mackerras94b4a692008-05-20 10:51:066460 if {$row == $selectedline} {
Paul Mackerras005a2f42007-07-26 12:36:396461 $canv raise $t secsel
6462 }
Paul Mackerras98f350e2005-05-15 05:56:516463 }
6464}
6465
6466proc unmarkmatches {} {
Paul Mackerrasbb3edc82007-09-27 01:00:256467 global markingmatches
Paul Mackerras4fb0fa12007-07-04 09:43:516468
Paul Mackerras98f350e2005-05-15 05:56:516469 allcanvs delete matches
Paul Mackerras4fb0fa12007-07-04 09:43:516470 set markingmatches 0
Paul Mackerrasbb3edc82007-09-27 01:00:256471 stopfinding
Paul Mackerras98f350e2005-05-15 05:56:516472}
6473
Paul Mackerrasc8dfbcf2005-06-25 05:39:216474proc selcanvline {w x y} {
Paul Mackerrasfa4da7b2005-08-07 23:47:226475 global canv canvy0 ctext linespc
Paul Mackerras9f1afe02006-02-19 11:44:476476 global rowtextx
Paul Mackerras1db95b02005-05-09 04:08:396477 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerrascfb45632005-05-31 12:14:426478 if {$ymax == {}} return
Paul Mackerras1db95b02005-05-09 04:08:396479 set yfrac [lindex [$canv yview] 0]
6480 set y [expr {$y + $yfrac * $ymax}]
6481 set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
6482 if {$l < 0} {
6483 set l 0
6484 }
Paul Mackerrasc8dfbcf2005-06-25 05:39:216485 if {$w eq $canv} {
Paul Mackerrasfc2a2562007-12-26 12:03:436486 set xmax [lindex [$canv cget -scrollregion] 2]
6487 set xleft [expr {[lindex [$canv xview] 0] * $xmax}]
6488 if {![info exists rowtextx($l)] || $xleft + $x < $rowtextx($l)} return
Paul Mackerrasc8dfbcf2005-06-25 05:39:216489 }
Paul Mackerras98f350e2005-05-15 05:56:516490 unmarkmatches
Paul Mackerrasd6982062005-08-06 12:06:066491 selectline $l 1
Paul Mackerras5ad588d2005-05-10 01:02:556492}
6493
Linus Torvaldsb1ba39e2005-08-09 03:04:206494proc commit_descriptor {p} {
6495 global commitinfo
Paul Mackerrasb0934482006-05-14 23:56:086496 if {![info exists commitinfo($p)]} {
6497 getcommit $p
6498 }
Linus Torvaldsb1ba39e2005-08-09 03:04:206499 set l "..."
Paul Mackerrasb0934482006-05-14 23:56:086500 if {[llength $commitinfo($p)] > 1} {
Linus Torvaldsb1ba39e2005-08-09 03:04:206501 set l [lindex $commitinfo($p) 0]
6502 }
Paul Mackerrasb8ab2e12006-06-03 09:11:136503 return "$p ($l)\n"
Linus Torvaldsb1ba39e2005-08-09 03:04:206504}
6505
Paul Mackerras106288c2005-08-19 13:11:396506# append some text to the ctext widget, and make any SHA1 ID
6507# that we know about be a clickable link.
Sergey Vlasovf1b86292006-05-15 15:13:146508proc appendwithlinks {text tags} {
Paul Mackerrasd375ef92008-10-20 23:18:126509 global ctext linknum curview
Paul Mackerras106288c2005-08-19 13:11:396510
6511 set start [$ctext index "end - 1c"]
Sergey Vlasovf1b86292006-05-15 15:13:146512 $ctext insert end $text $tags
Paul Mackerrasd375ef92008-10-20 23:18:126513 set links [regexp -indices -all -inline {\m[0-9a-f]{6,40}\M} $text]
Paul Mackerras106288c2005-08-19 13:11:396514 foreach l $links {
6515 set s [lindex $l 0]
6516 set e [lindex $l 1]
6517 set linkid [string range $text $s $e]
Paul Mackerras106288c2005-08-19 13:11:396518 incr e
Paul Mackerrasc73adce2007-09-27 00:35:056519 $ctext tag delete link$linknum
Paul Mackerras106288c2005-08-19 13:11:396520 $ctext tag add link$linknum "$start + $s c" "$start + $e c"
Paul Mackerras97645682007-08-23 12:24:386521 setlink $linkid link$linknum
Paul Mackerras106288c2005-08-19 13:11:396522 incr linknum
6523 }
Paul Mackerras97645682007-08-23 12:24:386524}
6525
6526proc setlink {id lk} {
Paul Mackerrasd375ef92008-10-20 23:18:126527 global curview ctext pendinglinks
Paul Mackerras97645682007-08-23 12:24:386528
Paul Mackerrasd375ef92008-10-20 23:18:126529 set known 0
6530 if {[string length $id] < 40} {
6531 set matches [longid $id]
6532 if {[llength $matches] > 0} {
6533 if {[llength $matches] > 1} return
6534 set known 1
6535 set id [lindex $matches 0]
6536 }
6537 } else {
6538 set known [commitinview $id $curview]
6539 }
6540 if {$known} {
Paul Mackerras97645682007-08-23 12:24:386541 $ctext tag conf $lk -foreground blue -underline 1
Paul Mackerrasd375ef92008-10-20 23:18:126542 $ctext tag bind $lk <1> [list selbyid $id]
Paul Mackerras97645682007-08-23 12:24:386543 $ctext tag bind $lk <Enter> {linkcursor %W 1}
6544 $ctext tag bind $lk <Leave> {linkcursor %W -1}
6545 } else {
6546 lappend pendinglinks($id) $lk
Paul Mackerrasd375ef92008-10-20 23:18:126547 interestedin $id {makelink %P}
Paul Mackerras97645682007-08-23 12:24:386548 }
6549}
6550
Paul Mackerras6f63fc12009-04-21 12:22:316551proc appendshortlink {id {pre {}} {post {}}} {
6552 global ctext linknum
6553
6554 $ctext insert end $pre
6555 $ctext tag delete link$linknum
6556 $ctext insert end [string range $id 0 7] link$linknum
6557 $ctext insert end $post
6558 setlink $id link$linknum
6559 incr linknum
6560}
6561
Paul Mackerras97645682007-08-23 12:24:386562proc makelink {id} {
6563 global pendinglinks
6564
6565 if {![info exists pendinglinks($id)]} return
6566 foreach lk $pendinglinks($id) {
6567 setlink $id $lk
6568 }
6569 unset pendinglinks($id)
6570}
6571
6572proc linkcursor {w inc} {
6573 global linkentercount curtextcursor
6574
6575 if {[incr linkentercount $inc] > 0} {
6576 $w configure -cursor hand2
6577 } else {
6578 $w configure -cursor $curtextcursor
6579 if {$linkentercount < 0} {
6580 set linkentercount 0
6581 }
6582 }
Paul Mackerras106288c2005-08-19 13:11:396583}
6584
Rutger Nijlunsing6e5f7202006-04-05 00:24:036585proc viewnextline {dir} {
6586 global canv linespc
6587
6588 $canv delete hover
6589 set ymax [lindex [$canv cget -scrollregion] 3]
6590 set wnow [$canv yview]
6591 set wtop [expr {[lindex $wnow 0] * $ymax}]
6592 set newtop [expr {$wtop + $dir * $linespc}]
6593 if {$newtop < 0} {
6594 set newtop 0
6595 } elseif {$newtop > $ymax} {
6596 set newtop $ymax
6597 }
6598 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
6599}
6600
Paul Mackerrasef030b82006-06-04 01:50:386601# add a list of tag or branch names at position pos
6602# returns the number of names inserted
Paul Mackerrase11f1232007-06-16 10:29:256603proc appendrefs {pos ids var} {
Paul Mackerras7fcc92b2007-12-02 23:33:016604 global ctext linknum curview $var maxrefs
Paul Mackerrasb8ab2e12006-06-03 09:11:136605
Paul Mackerrasef030b82006-06-04 01:50:386606 if {[catch {$ctext index $pos}]} {
6607 return 0
6608 }
Paul Mackerrase11f1232007-06-16 10:29:256609 $ctext conf -state normal
6610 $ctext delete $pos "$pos lineend"
6611 set tags {}
6612 foreach id $ids {
6613 foreach tag [set $var\($id\)] {
6614 lappend tags [list $tag $id]
6615 }
6616 }
Paul Mackerras0a4dd8b2007-06-16 11:21:576617 if {[llength $tags] > $maxrefs} {
Christian Stimming84b4b832009-03-26 20:13:456618 $ctext insert $pos "[mc "many"] ([llength $tags])"
Paul Mackerras0a4dd8b2007-06-16 11:21:576619 } else {
6620 set tags [lsort -index 0 -decreasing $tags]
6621 set sep {}
6622 foreach ti $tags {
6623 set id [lindex $ti 1]
6624 set lk link$linknum
6625 incr linknum
6626 $ctext tag delete $lk
6627 $ctext insert $pos $sep
6628 $ctext insert $pos [lindex $ti 0] $lk
Paul Mackerras97645682007-08-23 12:24:386629 setlink $id $lk
Paul Mackerras0a4dd8b2007-06-16 11:21:576630 set sep ", "
Paul Mackerrasb8ab2e12006-06-03 09:11:136631 }
Paul Mackerrasb8ab2e12006-06-03 09:11:136632 }
Paul Mackerrase11f1232007-06-16 10:29:256633 $ctext conf -state disabled
Paul Mackerrasef030b82006-06-04 01:50:386634 return [llength $tags]
Paul Mackerrasb8ab2e12006-06-03 09:11:136635}
6636
6637# called when we have finished computing the nearby tags
Paul Mackerrase11f1232007-06-16 10:29:256638proc dispneartags {delay} {
6639 global selectedline currentid showneartags tagphase
Paul Mackerrasb8ab2e12006-06-03 09:11:136640
Paul Mackerras94b4a692008-05-20 10:51:066641 if {$selectedline eq {} || !$showneartags} return
Paul Mackerrase11f1232007-06-16 10:29:256642 after cancel dispnexttag
6643 if {$delay} {
6644 after 200 dispnexttag
6645 set tagphase -1
6646 } else {
6647 after idle dispnexttag
6648 set tagphase 0
6649 }
6650}
6651
6652proc dispnexttag {} {
6653 global selectedline currentid showneartags tagphase ctext
6654
Paul Mackerras94b4a692008-05-20 10:51:066655 if {$selectedline eq {} || !$showneartags} return
Paul Mackerrase11f1232007-06-16 10:29:256656 switch -- $tagphase {
6657 0 {
6658 set dtags [desctags $currentid]
6659 if {$dtags ne {}} {
6660 appendrefs precedes $dtags idtags
6661 }
6662 }
6663 1 {
6664 set atags [anctags $currentid]
6665 if {$atags ne {}} {
6666 appendrefs follows $atags idtags
6667 }
6668 }
6669 2 {
6670 set dheads [descheads $currentid]
6671 if {$dheads ne {}} {
6672 if {[appendrefs branch $dheads idheads] > 1
6673 && [$ctext get "branch -3c"] eq "h"} {
6674 # turn "Branch" into "Branches"
6675 $ctext conf -state normal
6676 $ctext insert "branch -2c" "es"
6677 $ctext conf -state disabled
6678 }
6679 }
Paul Mackerrasef030b82006-06-04 01:50:386680 }
6681 }
Paul Mackerrase11f1232007-06-16 10:29:256682 if {[incr tagphase] <= 2} {
6683 after idle dispnexttag
Paul Mackerrasb8ab2e12006-06-03 09:11:136684 }
Paul Mackerrasb8ab2e12006-06-03 09:11:136685}
6686
Paul Mackerras28593d32008-11-13 12:01:466687proc make_secsel {id} {
Paul Mackerras03800812007-08-29 11:45:216688 global linehtag linentag linedtag canv canv2 canv3
6689
Paul Mackerras28593d32008-11-13 12:01:466690 if {![info exists linehtag($id)]} return
Paul Mackerras03800812007-08-29 11:45:216691 $canv delete secsel
Paul Mackerras28593d32008-11-13 12:01:466692 set t [eval $canv create rect [$canv bbox $linehtag($id)] -outline {{}} \
Paul Mackerras03800812007-08-29 11:45:216693 -tags secsel -fill [$canv cget -selectbackground]]
6694 $canv lower $t
6695 $canv2 delete secsel
Paul Mackerras28593d32008-11-13 12:01:466696 set t [eval $canv2 create rect [$canv2 bbox $linentag($id)] -outline {{}} \
Paul Mackerras03800812007-08-29 11:45:216697 -tags secsel -fill [$canv2 cget -selectbackground]]
6698 $canv2 lower $t
6699 $canv3 delete secsel
Paul Mackerras28593d32008-11-13 12:01:466700 set t [eval $canv3 create rect [$canv3 bbox $linedtag($id)] -outline {{}} \
Paul Mackerras03800812007-08-29 11:45:216701 -tags secsel -fill [$canv3 cget -selectbackground]]
6702 $canv3 lower $t
6703}
6704
Paul Mackerrasb9fdba72009-04-08 23:34:466705proc make_idmark {id} {
6706 global linehtag canv fgcolor
6707
6708 if {![info exists linehtag($id)]} return
6709 $canv delete markid
6710 set t [eval $canv create rect [$canv bbox $linehtag($id)] \
6711 -tags markid -outline $fgcolor]
6712 $canv raise $t
6713}
6714
Paul Mackerras8a897742008-10-27 10:36:256715proc selectline {l isnew {desired_loc {}}} {
Paul Mackerras03800812007-08-29 11:45:216716 global canv ctext commitinfo selectedline
Paul Mackerras7fcc92b2007-12-02 23:33:016717 global canvy0 linespc parents children curview
Paul Mackerras7fcceed2006-04-27 09:21:496718 global currentid sha1entry
Paul Mackerras9f1afe02006-02-19 11:44:476719 global commentend idtags linknum
Paul Mackerrasd94f8cd2006-04-06 00:18:236720 global mergemax numcommits pending_select
Paul Mackerrase11f1232007-06-16 10:29:256721 global cmitmode showneartags allcommits
Paul Mackerrasc30acc72008-03-07 11:51:556722 global targetrow targetid lastscrollrows
Paul Mackerras8a897742008-10-27 10:36:256723 global autoselect jump_to_here
Paul Mackerrasd6982062005-08-06 12:06:066724
Paul Mackerrasd94f8cd2006-04-06 00:18:236725 catch {unset pending_select}
Paul Mackerras84ba7342005-06-17 00:12:266726 $canv delete hover
Paul Mackerras9843c302005-08-30 00:57:116727 normalline
Paul Mackerras887c9962007-08-20 09:36:206728 unsel_reflist
Paul Mackerrasbb3edc82007-09-27 01:00:256729 stopfinding
Paul Mackerras8f7d0ce2006-02-28 11:10:196730 if {$l < 0 || $l >= $numcommits} return
Paul Mackerrasac1276a2008-03-02 23:11:086731 set id [commitonrow $l]
6732 set targetid $id
6733 set targetrow $l
Paul Mackerrasc30acc72008-03-07 11:51:556734 set selectedline $l
6735 set currentid $id
6736 if {$lastscrollrows < $numcommits} {
6737 setcanvscroll
6738 }
Paul Mackerrasac1276a2008-03-02 23:11:086739
Paul Mackerras5ad588d2005-05-10 01:02:556740 set y [expr {$canvy0 + $l * $linespc}]
Paul Mackerras17386062005-05-18 22:51:006741 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras58422152005-05-19 10:56:426742 set ytop [expr {$y - $linespc - 1}]
6743 set ybot [expr {$y + $linespc + 1}]
Paul Mackerras5ad588d2005-05-10 01:02:556744 set wnow [$canv yview]
Jeff Hobbs2ed49d52005-11-23 01:39:536745 set wtop [expr {[lindex $wnow 0] * $ymax}]
6746 set wbot [expr {[lindex $wnow 1] * $ymax}]
Paul Mackerras58422152005-05-19 10:56:426747 set wh [expr {$wbot - $wtop}]
6748 set newtop $wtop
Paul Mackerras17386062005-05-18 22:51:006749 if {$ytop < $wtop} {
Paul Mackerras58422152005-05-19 10:56:426750 if {$ybot < $wtop} {
6751 set newtop [expr {$y - $wh / 2.0}]
6752 } else {
6753 set newtop $ytop
6754 if {$newtop > $wtop - $linespc} {
6755 set newtop [expr {$wtop - $linespc}]
6756 }
Paul Mackerras17386062005-05-18 22:51:006757 }
Paul Mackerras58422152005-05-19 10:56:426758 } elseif {$ybot > $wbot} {
6759 if {$ytop > $wbot} {
6760 set newtop [expr {$y - $wh / 2.0}]
6761 } else {
6762 set newtop [expr {$ybot - $wh}]
6763 if {$newtop < $wtop + $linespc} {
6764 set newtop [expr {$wtop + $linespc}]
6765 }
Paul Mackerras17386062005-05-18 22:51:006766 }
Paul Mackerras58422152005-05-19 10:56:426767 }
6768 if {$newtop != $wtop} {
6769 if {$newtop < 0} {
6770 set newtop 0
6771 }
Jeff Hobbs2ed49d52005-11-23 01:39:536772 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
Paul Mackerras9f1afe02006-02-19 11:44:476773 drawvisible
Paul Mackerras5ad588d2005-05-10 01:02:556774 }
Paul Mackerrasd6982062005-08-06 12:06:066775
Paul Mackerras28593d32008-11-13 12:01:466776 make_secsel $id
Paul Mackerras9f1afe02006-02-19 11:44:476777
Paul Mackerrasfa4da7b2005-08-07 23:47:226778 if {$isnew} {
Paul Mackerrasfc2a2562007-12-26 12:03:436779 addtohistory [list selbyid $id]
Paul Mackerrasd6982062005-08-06 12:06:066780 }
6781
Paul Mackerras98f350e2005-05-15 05:56:516782 $sha1entry delete 0 end
6783 $sha1entry insert 0 $id
Jeff King95293b52008-03-06 11:49:256784 if {$autoselect} {
6785 $sha1entry selection from 0
6786 $sha1entry selection to end
6787 }
Paul Mackerras164ff272006-05-29 09:50:026788 rhighlight_sel $id
Paul Mackerras98f350e2005-05-15 05:56:516789
Paul Mackerras5ad588d2005-05-10 01:02:556790 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 00:16:036791 clear_ctext
Paul Mackerras106288c2005-08-19 13:11:396792 set linknum 0
Paul Mackerrasd76afb12008-03-07 10:19:186793 if {![info exists commitinfo($id)]} {
6794 getcommit $id
6795 }
Paul Mackerras1db95b02005-05-09 04:08:396796 set info $commitinfo($id)
Paul Mackerras232475d2005-11-14 23:34:036797 set date [formatdate [lindex $info 2]]
Christian Stimmingd990ced2007-11-07 17:42:556798 $ctext insert end "[mc "Author"]: [lindex $info 1] $date\n"
Paul Mackerras232475d2005-11-14 23:34:036799 set date [formatdate [lindex $info 4]]
Christian Stimmingd990ced2007-11-07 17:42:556800 $ctext insert end "[mc "Committer"]: [lindex $info 3] $date\n"
Paul Mackerras887fe3c2005-05-21 07:35:376801 if {[info exists idtags($id)]} {
Christian Stimmingd990ced2007-11-07 17:42:556802 $ctext insert end [mc "Tags:"]
Paul Mackerras887fe3c2005-05-21 07:35:376803 foreach tag $idtags($id) {
6804 $ctext insert end " $tag"
6805 }
6806 $ctext insert end "\n"
6807 }
Mark Levedahl40b87ff2007-02-01 13:44:466808
Sergey Vlasovf1b86292006-05-15 15:13:146809 set headers {}
Paul Mackerras7fcc92b2007-12-02 23:33:016810 set olds $parents($curview,$id)
Paul Mackerras79b2c752006-04-02 10:47:406811 if {[llength $olds] > 1} {
Paul Mackerrasb77b0272006-02-06 22:13:526812 set np 0
Paul Mackerras79b2c752006-04-02 10:47:406813 foreach p $olds {
Paul Mackerrasb77b0272006-02-06 22:13:526814 if {$np >= $mergemax} {
6815 set tag mmax
6816 } else {
6817 set tag m$np
6818 }
Christian Stimmingd990ced2007-11-07 17:42:556819 $ctext insert end "[mc "Parent"]: " $tag
Sergey Vlasovf1b86292006-05-15 15:13:146820 appendwithlinks [commit_descriptor $p] {}
Paul Mackerrasb77b0272006-02-06 22:13:526821 incr np
6822 }
6823 } else {
Paul Mackerras79b2c752006-04-02 10:47:406824 foreach p $olds {
Christian Stimmingd990ced2007-11-07 17:42:556825 append headers "[mc "Parent"]: [commit_descriptor $p]"
Linus Torvalds8b192802005-08-07 20:58:566826 }
Linus Torvaldsb1ba39e2005-08-09 03:04:206827 }
Paul Mackerrasb77b0272006-02-06 22:13:526828
Paul Mackerras6a90bff2007-06-17 23:48:236829 foreach c $children($curview,$id) {
Christian Stimmingd990ced2007-11-07 17:42:556830 append headers "[mc "Child"]: [commit_descriptor $c]"
Linus Torvalds8b192802005-08-07 20:58:566831 }
Paul Mackerrasd6982062005-08-06 12:06:066832
6833 # make anything that looks like a SHA1 ID be a clickable link
Sergey Vlasovf1b86292006-05-15 15:13:146834 appendwithlinks $headers {}
Paul Mackerrasb8ab2e12006-06-03 09:11:136835 if {$showneartags} {
6836 if {![info exists allcommits]} {
6837 getallcommits
6838 }
Christian Stimmingd990ced2007-11-07 17:42:556839 $ctext insert end "[mc "Branch"]: "
Paul Mackerrasef030b82006-06-04 01:50:386840 $ctext mark set branch "end -1c"
6841 $ctext mark gravity branch left
Christian Stimmingd990ced2007-11-07 17:42:556842 $ctext insert end "\n[mc "Follows"]: "
Paul Mackerrasb8ab2e12006-06-03 09:11:136843 $ctext mark set follows "end -1c"
6844 $ctext mark gravity follows left
Christian Stimmingd990ced2007-11-07 17:42:556845 $ctext insert end "\n[mc "Precedes"]: "
Paul Mackerrasb8ab2e12006-06-03 09:11:136846 $ctext mark set precedes "end -1c"
6847 $ctext mark gravity precedes left
Paul Mackerrasb8ab2e12006-06-03 09:11:136848 $ctext insert end "\n"
Paul Mackerrase11f1232007-06-16 10:29:256849 dispneartags 1
Paul Mackerrasb8ab2e12006-06-03 09:11:136850 }
6851 $ctext insert end "\n"
Paul Mackerras43c25072006-09-27 00:56:026852 set comment [lindex $info 5]
6853 if {[string first "\r" $comment] >= 0} {
6854 set comment [string map {"\r" "\n "} $comment]
6855 }
6856 appendwithlinks $comment {comment}
Paul Mackerrasd6982062005-08-06 12:06:066857
Paul Mackerrasdf3d83b2005-05-17 23:23:076858 $ctext tag remove found 1.0 end
Paul Mackerras5ad588d2005-05-10 01:02:556859 $ctext conf -state disabled
Paul Mackerrasdf3d83b2005-05-17 23:23:076860 set commentend [$ctext index "end - 1c"]
Paul Mackerras5ad588d2005-05-10 01:02:556861
Paul Mackerras8a897742008-10-27 10:36:256862 set jump_to_here $desired_loc
Christian Stimmingb007ee22007-11-07 17:44:356863 init_flist [mc "Comments"]
Paul Mackerrasf8b28a42006-04-30 23:50:576864 if {$cmitmode eq "tree"} {
6865 gettree $id
6866 } elseif {[llength $olds] <= 1} {
Paul Mackerrasd3272442005-11-28 09:41:566867 startdiff $id
Paul Mackerras7b5ff7e2006-03-30 09:50:406868 } else {
Paul Mackerras7fcc92b2007-12-02 23:33:016869 mergediff $id
Paul Mackerrasc8dfbcf2005-06-25 05:39:216870 }
6871}
6872
Rutger Nijlunsing6e5f7202006-04-05 00:24:036873proc selfirstline {} {
6874 unmarkmatches
6875 selectline 0 1
6876}
6877
6878proc sellastline {} {
6879 global numcommits
6880 unmarkmatches
6881 set l [expr {$numcommits - 1}]
6882 selectline $l 1
6883}
6884
Paul Mackerrase5c2d852005-05-11 23:44:546885proc selnextline {dir} {
6886 global selectedline
Mark Levedahlbd441de2007-08-08 01:40:346887 focus .
Paul Mackerras94b4a692008-05-20 10:51:066888 if {$selectedline eq {}} return
Jeff Hobbs2ed49d52005-11-23 01:39:536889 set l [expr {$selectedline + $dir}]
Paul Mackerras98f350e2005-05-15 05:56:516890 unmarkmatches
Paul Mackerrasd6982062005-08-06 12:06:066891 selectline $l 1
6892}
6893
Rutger Nijlunsing6e5f7202006-04-05 00:24:036894proc selnextpage {dir} {
6895 global canv linespc selectedline numcommits
6896
6897 set lpp [expr {([winfo height $canv] - 2) / $linespc}]
6898 if {$lpp < 1} {
6899 set lpp 1
6900 }
6901 allcanvs yview scroll [expr {$dir * $lpp}] units
Paul Mackerrase72ee5e2006-05-19 23:58:496902 drawvisible
Paul Mackerras94b4a692008-05-20 10:51:066903 if {$selectedline eq {}} return
Rutger Nijlunsing6e5f7202006-04-05 00:24:036904 set l [expr {$selectedline + $dir * $lpp}]
6905 if {$l < 0} {
6906 set l 0
6907 } elseif {$l >= $numcommits} {
6908 set l [expr $numcommits - 1]
6909 }
6910 unmarkmatches
Mark Levedahl40b87ff2007-02-01 13:44:466911 selectline $l 1
Rutger Nijlunsing6e5f7202006-04-05 00:24:036912}
6913
Paul Mackerrasfa4da7b2005-08-07 23:47:226914proc unselectline {} {
Paul Mackerras50b44ec2006-04-04 00:16:226915 global selectedline currentid
Paul Mackerrasfa4da7b2005-08-07 23:47:226916
Paul Mackerras94b4a692008-05-20 10:51:066917 set selectedline {}
Paul Mackerras50b44ec2006-04-04 00:16:226918 catch {unset currentid}
Paul Mackerrasfa4da7b2005-08-07 23:47:226919 allcanvs delete secsel
Paul Mackerras164ff272006-05-29 09:50:026920 rhighlight_none
Paul Mackerrasfa4da7b2005-08-07 23:47:226921}
6922
Paul Mackerrasf8b28a42006-04-30 23:50:576923proc reselectline {} {
6924 global selectedline
6925
Paul Mackerras94b4a692008-05-20 10:51:066926 if {$selectedline ne {}} {
Paul Mackerrasf8b28a42006-04-30 23:50:576927 selectline $selectedline 0
6928 }
6929}
6930
Paul Mackerrasfa4da7b2005-08-07 23:47:226931proc addtohistory {cmd} {
Paul Mackerras2516dae2006-04-21 00:35:316932 global history historyindex curview
Paul Mackerrasfa4da7b2005-08-07 23:47:226933
Paul Mackerras2516dae2006-04-21 00:35:316934 set elt [list $curview $cmd]
Paul Mackerrasfa4da7b2005-08-07 23:47:226935 if {$historyindex > 0
Paul Mackerras2516dae2006-04-21 00:35:316936 && [lindex $history [expr {$historyindex - 1}]] == $elt} {
Paul Mackerrasfa4da7b2005-08-07 23:47:226937 return
6938 }
6939
6940 if {$historyindex < [llength $history]} {
Paul Mackerras2516dae2006-04-21 00:35:316941 set history [lreplace $history $historyindex end $elt]
Paul Mackerrasfa4da7b2005-08-07 23:47:226942 } else {
Paul Mackerras2516dae2006-04-21 00:35:316943 lappend history $elt
Paul Mackerrasfa4da7b2005-08-07 23:47:226944 }
6945 incr historyindex
6946 if {$historyindex > 1} {
Junio C Hamanoe9937d22007-02-01 13:46:386947 .tf.bar.leftbut conf -state normal
Paul Mackerrasfa4da7b2005-08-07 23:47:226948 } else {
Junio C Hamanoe9937d22007-02-01 13:46:386949 .tf.bar.leftbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-07 23:47:226950 }
Junio C Hamanoe9937d22007-02-01 13:46:386951 .tf.bar.rightbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-07 23:47:226952}
6953
Paul Mackerras2516dae2006-04-21 00:35:316954proc godo {elt} {
6955 global curview
6956
6957 set view [lindex $elt 0]
6958 set cmd [lindex $elt 1]
6959 if {$curview != $view} {
6960 showview $view
6961 }
6962 eval $cmd
6963}
6964
Paul Mackerrasd6982062005-08-06 12:06:066965proc goback {} {
6966 global history historyindex
Mark Levedahlbd441de2007-08-08 01:40:346967 focus .
Paul Mackerrasd6982062005-08-06 12:06:066968
6969 if {$historyindex > 1} {
6970 incr historyindex -1
Paul Mackerras2516dae2006-04-21 00:35:316971 godo [lindex $history [expr {$historyindex - 1}]]
Junio C Hamanoe9937d22007-02-01 13:46:386972 .tf.bar.rightbut conf -state normal
Paul Mackerrasd6982062005-08-06 12:06:066973 }
6974 if {$historyindex <= 1} {
Junio C Hamanoe9937d22007-02-01 13:46:386975 .tf.bar.leftbut conf -state disabled
Paul Mackerrasd6982062005-08-06 12:06:066976 }
6977}
6978
6979proc goforw {} {
6980 global history historyindex
Mark Levedahlbd441de2007-08-08 01:40:346981 focus .
Paul Mackerrasd6982062005-08-06 12:06:066982
6983 if {$historyindex < [llength $history]} {
Paul Mackerrasfa4da7b2005-08-07 23:47:226984 set cmd [lindex $history $historyindex]
Paul Mackerrasd6982062005-08-06 12:06:066985 incr historyindex
Paul Mackerras2516dae2006-04-21 00:35:316986 godo $cmd
Junio C Hamanoe9937d22007-02-01 13:46:386987 .tf.bar.leftbut conf -state normal
Paul Mackerrasd6982062005-08-06 12:06:066988 }
6989 if {$historyindex >= [llength $history]} {
Junio C Hamanoe9937d22007-02-01 13:46:386990 .tf.bar.rightbut conf -state disabled
Paul Mackerrasd6982062005-08-06 12:06:066991 }
Paul Mackerras5ad588d2005-05-10 01:02:556992}
6993
Paul Mackerrasf8b28a42006-04-30 23:50:576994proc gettree {id} {
Paul Mackerras8f489362007-07-13 09:49:376995 global treefilelist treeidlist diffids diffmergeid treepending
6996 global nullid nullid2
Paul Mackerrasf8b28a42006-04-30 23:50:576997
6998 set diffids $id
6999 catch {unset diffmergeid}
7000 if {![info exists treefilelist($id)]} {
7001 if {![info exists treepending]} {
Paul Mackerras8f489362007-07-13 09:49:377002 if {$id eq $nullid} {
7003 set cmd [list | git ls-files]
7004 } elseif {$id eq $nullid2} {
7005 set cmd [list | git ls-files --stage -t]
Paul Mackerras219ea3a2006-09-07 00:21:397006 } else {
Paul Mackerras8f489362007-07-13 09:49:377007 set cmd [list | git ls-tree -r $id]
Paul Mackerras219ea3a2006-09-07 00:21:397008 }
7009 if {[catch {set gtf [open $cmd r]}]} {
Paul Mackerrasf8b28a42006-04-30 23:50:577010 return
7011 }
7012 set treepending $id
7013 set treefilelist($id) {}
7014 set treeidlist($id) {}
Alexander Gavrilov09c70292008-10-13 08:12:317015 fconfigure $gtf -blocking 0 -encoding binary
Paul Mackerras7eb3cb92007-06-17 04:45:007016 filerun $gtf [list gettreeline $gtf $id]
Paul Mackerrasf8b28a42006-04-30 23:50:577017 }
7018 } else {
7019 setfilelist $id
7020 }
7021}
7022
7023proc gettreeline {gtf id} {
Paul Mackerras8f489362007-07-13 09:49:377024 global treefilelist treeidlist treepending cmitmode diffids nullid nullid2
Paul Mackerrasf8b28a42006-04-30 23:50:577025
Paul Mackerras7eb3cb92007-06-17 04:45:007026 set nl 0
7027 while {[incr nl] <= 1000 && [gets $gtf line] >= 0} {
Paul Mackerras8f489362007-07-13 09:49:377028 if {$diffids eq $nullid} {
7029 set fname $line
7030 } else {
Paul Mackerras9396cd32007-06-23 10:28:157031 set i [string first "\t" $line]
7032 if {$i < 0} continue
Paul Mackerras9396cd32007-06-23 10:28:157033 set fname [string range $line [expr {$i+1}] end]
Paul Mackerrasf31fa2c2008-04-27 23:40:507034 set line [string range $line 0 [expr {$i-1}]]
7035 if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
7036 set sha1 [lindex $line 2]
Paul Mackerras219ea3a2006-09-07 00:21:397037 lappend treeidlist($id) $sha1
Paul Mackerras7eb3cb92007-06-17 04:45:007038 }
Alexander Gavrilov09c70292008-10-13 08:12:317039 if {[string index $fname 0] eq "\""} {
7040 set fname [lindex $fname 0]
7041 }
7042 set fname [encoding convertfrom $fname]
Paul Mackerras7eb3cb92007-06-17 04:45:007043 lappend treefilelist($id) $fname
Paul Mackerrasf8b28a42006-04-30 23:50:577044 }
Paul Mackerras7eb3cb92007-06-17 04:45:007045 if {![eof $gtf]} {
7046 return [expr {$nl >= 1000? 2: 1}]
7047 }
Paul Mackerrasf8b28a42006-04-30 23:50:577048 close $gtf
7049 unset treepending
7050 if {$cmitmode ne "tree"} {
7051 if {![info exists diffmergeid]} {
7052 gettreediffs $diffids
7053 }
7054 } elseif {$id ne $diffids} {
7055 gettree $diffids
7056 } else {
7057 setfilelist $id
7058 }
Paul Mackerras7eb3cb92007-06-17 04:45:007059 return 0
Paul Mackerrasf8b28a42006-04-30 23:50:577060}
7061
7062proc showfile {f} {
Paul Mackerras8f489362007-07-13 09:49:377063 global treefilelist treeidlist diffids nullid nullid2
Alexander Gavrilov7cdc3552008-10-24 08:13:017064 global ctext_file_names ctext_file_lines
Paul Mackerrasf8b28a42006-04-30 23:50:577065 global ctext commentend
7066
7067 set i [lsearch -exact $treefilelist($diffids) $f]
7068 if {$i < 0} {
7069 puts "oops, $f not in list for id $diffids"
7070 return
7071 }
Paul Mackerras8f489362007-07-13 09:49:377072 if {$diffids eq $nullid} {
7073 if {[catch {set bf [open $f r]} err]} {
7074 puts "oops, can't read $f: $err"
Paul Mackerras219ea3a2006-09-07 00:21:397075 return
7076 }
7077 } else {
Paul Mackerras8f489362007-07-13 09:49:377078 set blob [lindex $treeidlist($diffids) $i]
7079 if {[catch {set bf [open [concat | git cat-file blob $blob] r]} err]} {
7080 puts "oops, error reading blob $blob: $err"
Paul Mackerras219ea3a2006-09-07 00:21:397081 return
7082 }
Paul Mackerrasf8b28a42006-04-30 23:50:577083 }
Alexander Gavrilov09c70292008-10-13 08:12:317084 fconfigure $bf -blocking 0 -encoding [get_path_encoding $f]
Paul Mackerras7eb3cb92007-06-17 04:45:007085 filerun $bf [list getblobline $bf $diffids]
Paul Mackerrasf8b28a42006-04-30 23:50:577086 $ctext config -state normal
Paul Mackerras3ea06f92006-05-24 00:16:037087 clear_ctext $commentend
Alexander Gavrilov7cdc3552008-10-24 08:13:017088 lappend ctext_file_names $f
7089 lappend ctext_file_lines [lindex [split $commentend "."] 0]
Paul Mackerrasf8b28a42006-04-30 23:50:577090 $ctext insert end "\n"
7091 $ctext insert end "$f\n" filesep
7092 $ctext config -state disabled
7093 $ctext yview $commentend
Paul Mackerras32f1b3e2007-09-28 11:27:397094 settabs 0
Paul Mackerrasf8b28a42006-04-30 23:50:577095}
7096
7097proc getblobline {bf id} {
7098 global diffids cmitmode ctext
7099
7100 if {$id ne $diffids || $cmitmode ne "tree"} {
7101 catch {close $bf}
Paul Mackerras7eb3cb92007-06-17 04:45:007102 return 0
Paul Mackerrasf8b28a42006-04-30 23:50:577103 }
7104 $ctext config -state normal
Paul Mackerras7eb3cb92007-06-17 04:45:007105 set nl 0
7106 while {[incr nl] <= 1000 && [gets $bf line] >= 0} {
Paul Mackerrasf8b28a42006-04-30 23:50:577107 $ctext insert end "$line\n"
7108 }
7109 if {[eof $bf]} {
Paul Mackerras8a897742008-10-27 10:36:257110 global jump_to_here ctext_file_names commentend
7111
Paul Mackerrasf8b28a42006-04-30 23:50:577112 # delete last newline
7113 $ctext delete "end - 2c" "end - 1c"
7114 close $bf
Paul Mackerras8a897742008-10-27 10:36:257115 if {$jump_to_here ne {} &&
7116 [lindex $jump_to_here 0] eq [lindex $ctext_file_names 0]} {
7117 set lnum [expr {[lindex $jump_to_here 1] +
7118 [lindex [split $commentend .] 0]}]
7119 mark_ctext_line $lnum
7120 }
Paul Mackerras7eb3cb92007-06-17 04:45:007121 return 0
Paul Mackerrasf8b28a42006-04-30 23:50:577122 }
7123 $ctext config -state disabled
Paul Mackerras7eb3cb92007-06-17 04:45:007124 return [expr {$nl >= 1000? 2: 1}]
Paul Mackerrasf8b28a42006-04-30 23:50:577125}
7126
Paul Mackerras8a897742008-10-27 10:36:257127proc mark_ctext_line {lnum} {
Paul Mackerrase3e901b2008-10-27 11:37:217128 global ctext markbgcolor
Paul Mackerras8a897742008-10-27 10:36:257129
7130 $ctext tag delete omark
7131 $ctext tag add omark $lnum.0 "$lnum.0 + 1 line"
Paul Mackerrase3e901b2008-10-27 11:37:217132 $ctext tag conf omark -background $markbgcolor
Paul Mackerras8a897742008-10-27 10:36:257133 $ctext see $lnum.0
7134}
7135
Paul Mackerras7fcc92b2007-12-02 23:33:017136proc mergediff {id} {
Paul Mackerras8b07dca2008-11-02 11:34:477137 global diffmergeid
Alexander Gavrilov2df64422008-10-08 07:05:377138 global diffids treediffs
Paul Mackerras8b07dca2008-11-02 11:34:477139 global parents curview
Paul Mackerrase2ed4322005-07-17 07:39:447140
Paul Mackerras3c461ff2005-07-20 13:13:467141 set diffmergeid $id
Paul Mackerras7a1d9d12006-03-21 23:21:457142 set diffids $id
Alexander Gavrilov2df64422008-10-08 07:05:377143 set treediffs($id) {}
Paul Mackerras7fcc92b2007-12-02 23:33:017144 set np [llength $parents($curview,$id)]
Paul Mackerras32f1b3e2007-09-28 11:27:397145 settabs $np
Paul Mackerras8b07dca2008-11-02 11:34:477146 getblobdiffs $id
Paul Mackerrasc8a4acb2005-07-29 14:23:037147}
7148
Paul Mackerras3c461ff2005-07-20 13:13:467149proc startdiff {ids} {
Paul Mackerras8f489362007-07-13 09:49:377150 global treediffs diffids treepending diffmergeid nullid nullid2
Paul Mackerras3c461ff2005-07-20 13:13:467151
Paul Mackerras32f1b3e2007-09-28 11:27:397152 settabs 1
Paul Mackerras3c461ff2005-07-20 13:13:467153 set diffids $ids
7154 catch {unset diffmergeid}
Paul Mackerras8f489362007-07-13 09:49:377155 if {![info exists treediffs($ids)] ||
7156 [lsearch -exact $ids $nullid] >= 0 ||
7157 [lsearch -exact $ids $nullid2] >= 0} {
Paul Mackerras3c461ff2005-07-20 13:13:467158 if {![info exists treepending]} {
7159 gettreediffs $ids
7160 }
7161 } else {
7162 addtocflist $ids
7163 }
7164}
7165
Paul Mackerras7a39a172007-10-23 00:15:117166proc path_filter {filter name} {
7167 foreach p $filter {
7168 set l [string length $p]
Paul Mackerras74a40c72007-10-24 00:16:567169 if {[string index $p end] eq "/"} {
7170 if {[string compare -length $l $p $name] == 0} {
7171 return 1
7172 }
7173 } else {
7174 if {[string compare -length $l $p $name] == 0 &&
7175 ([string length $name] == $l ||
7176 [string index $name $l] eq "/")} {
7177 return 1
7178 }
Paul Mackerras7a39a172007-10-23 00:15:117179 }
7180 }
7181 return 0
7182}
7183
Paul Mackerras3c461ff2005-07-20 13:13:467184proc addtocflist {ids} {
Paul Mackerras74a40c72007-10-24 00:16:567185 global treediffs
Paul Mackerras7a39a172007-10-23 00:15:117186
Paul Mackerras74a40c72007-10-24 00:16:567187 add_flist $treediffs($ids)
Paul Mackerrasc8dfbcf2005-06-25 05:39:217188 getblobdiffs $ids
Paul Mackerrasd2610d12005-05-11 00:45:387189}
7190
Paul Mackerras219ea3a2006-09-07 00:21:397191proc diffcmd {ids flags} {
Paul Mackerras8f489362007-07-13 09:49:377192 global nullid nullid2
Paul Mackerras219ea3a2006-09-07 00:21:397193
7194 set i [lsearch -exact $ids $nullid]
Paul Mackerras8f489362007-07-13 09:49:377195 set j [lsearch -exact $ids $nullid2]
Paul Mackerras219ea3a2006-09-07 00:21:397196 if {$i >= 0} {
Paul Mackerras8f489362007-07-13 09:49:377197 if {[llength $ids] > 1 && $j < 0} {
7198 # comparing working directory with some specific revision
7199 set cmd [concat | git diff-index $flags]
Paul Mackerras219ea3a2006-09-07 00:21:397200 if {$i == 0} {
7201 lappend cmd -R [lindex $ids 1]
7202 } else {
7203 lappend cmd [lindex $ids 0]
7204 }
7205 } else {
Paul Mackerras8f489362007-07-13 09:49:377206 # comparing working directory with index
7207 set cmd [concat | git diff-files $flags]
7208 if {$j == 1} {
7209 lappend cmd -R
7210 }
7211 }
7212 } elseif {$j >= 0} {
7213 set cmd [concat | git diff-index --cached $flags]
7214 if {[llength $ids] > 1} {
7215 # comparing index with specific revision
7216 if {$i == 0} {
7217 lappend cmd -R [lindex $ids 1]
7218 } else {
7219 lappend cmd [lindex $ids 0]
7220 }
7221 } else {
7222 # comparing index with HEAD
Paul Mackerras219ea3a2006-09-07 00:21:397223 lappend cmd HEAD
7224 }
7225 } else {
Paul Mackerras8f489362007-07-13 09:49:377226 set cmd [concat | git diff-tree -r $flags $ids]
Paul Mackerras219ea3a2006-09-07 00:21:397227 }
7228 return $cmd
7229}
7230
Paul Mackerrasc8dfbcf2005-06-25 05:39:217231proc gettreediffs {ids} {
Paul Mackerras79b2c752006-04-02 10:47:407232 global treediff treepending
Paul Mackerras219ea3a2006-09-07 00:21:397233
Alexander Gavrilov72721312008-07-26 14:48:417234 if {[catch {set gdtf [open [diffcmd $ids {--no-commit-id}] r]}]} return
7235
Paul Mackerrasc8dfbcf2005-06-25 05:39:217236 set treepending $ids
Paul Mackerras3c461ff2005-07-20 13:13:467237 set treediff {}
Alexander Gavrilov09c70292008-10-13 08:12:317238 fconfigure $gdtf -blocking 0 -encoding binary
Paul Mackerras7eb3cb92007-06-17 04:45:007239 filerun $gdtf [list gettreediffline $gdtf $ids]
Paul Mackerrasd2610d12005-05-11 00:45:387240}
7241
Paul Mackerrasc8dfbcf2005-06-25 05:39:217242proc gettreediffline {gdtf ids} {
Paul Mackerras3c461ff2005-07-20 13:13:467243 global treediff treediffs treepending diffids diffmergeid
Paul Mackerras39ee47e2008-10-15 11:23:037244 global cmitmode vfilelimit curview limitdiffs perfile_attrs
Paul Mackerras3c461ff2005-07-20 13:13:467245
Paul Mackerras7eb3cb92007-06-17 04:45:007246 set nr 0
Alexander Gavrilov4db09302008-10-13 08:12:337247 set sublist {}
Paul Mackerras39ee47e2008-10-15 11:23:037248 set max 1000
7249 if {$perfile_attrs} {
7250 # cache_gitattr is slow, and even slower on win32 where we
7251 # have to invoke it for only about 30 paths at a time
7252 set max 500
7253 if {[tk windowingsystem] == "win32"} {
7254 set max 120
7255 }
7256 }
7257 while {[incr nr] <= $max && [gets $gdtf line] >= 0} {
Paul Mackerras9396cd32007-06-23 10:28:157258 set i [string first "\t" $line]
7259 if {$i >= 0} {
7260 set file [string range $line [expr {$i+1}] end]
7261 if {[string index $file 0] eq "\""} {
7262 set file [lindex $file 0]
7263 }
Alexander Gavrilov09c70292008-10-13 08:12:317264 set file [encoding convertfrom $file]
Paul Mackerras48a81b72008-11-04 10:09:007265 if {$file ne [lindex $treediff end]} {
7266 lappend treediff $file
7267 lappend sublist $file
7268 }
Paul Mackerras9396cd32007-06-23 10:28:157269 }
Paul Mackerrasd2610d12005-05-11 00:45:387270 }
Paul Mackerras39ee47e2008-10-15 11:23:037271 if {$perfile_attrs} {
7272 cache_gitattr encoding $sublist
7273 }
Paul Mackerras7eb3cb92007-06-17 04:45:007274 if {![eof $gdtf]} {
Paul Mackerras39ee47e2008-10-15 11:23:037275 return [expr {$nr >= $max? 2: 1}]
Paul Mackerras7eb3cb92007-06-17 04:45:007276 }
7277 close $gdtf
Paul Mackerras3ed31a82008-04-26 06:00:007278 if {$limitdiffs && $vfilelimit($curview) ne {}} {
Paul Mackerras74a40c72007-10-24 00:16:567279 set flist {}
7280 foreach f $treediff {
Paul Mackerras3ed31a82008-04-26 06:00:007281 if {[path_filter $vfilelimit($curview) $f]} {
Paul Mackerras74a40c72007-10-24 00:16:567282 lappend flist $f
7283 }
7284 }
7285 set treediffs($ids) $flist
7286 } else {
7287 set treediffs($ids) $treediff
7288 }
Paul Mackerras7eb3cb92007-06-17 04:45:007289 unset treepending
Paul Mackerrase1160132008-11-18 10:40:327290 if {$cmitmode eq "tree" && [llength $diffids] == 1} {
Paul Mackerras7eb3cb92007-06-17 04:45:007291 gettree $diffids
7292 } elseif {$ids != $diffids} {
7293 if {![info exists diffmergeid]} {
7294 gettreediffs $diffids
7295 }
7296 } else {
7297 addtocflist $ids
7298 }
7299 return 0
Paul Mackerrasd2610d12005-05-11 00:45:387300}
7301
Steffen Prohaska890fae72007-08-12 10:05:467302# empty string or positive integer
7303proc diffcontextvalidate {v} {
7304 return [regexp {^(|[1-9][0-9]*)$} $v]
7305}
7306
7307proc diffcontextchange {n1 n2 op} {
7308 global diffcontextstring diffcontext
7309
7310 if {[string is integer -strict $diffcontextstring]} {
Markus Heidelberga41ddbb2009-05-23 17:31:377311 if {$diffcontextstring >= 0} {
Steffen Prohaska890fae72007-08-12 10:05:467312 set diffcontext $diffcontextstring
7313 reselectline
7314 }
7315 }
7316}
7317
Steffen Prohaskab9b86002008-01-17 22:42:557318proc changeignorespace {} {
7319 reselectline
7320}
7321
Paul Mackerrasc8dfbcf2005-06-25 05:39:217322proc getblobdiffs {ids} {
Paul Mackerras8d73b242007-10-06 10:22:007323 global blobdifffd diffids env
Paul Mackerras7eb3cb92007-06-17 04:45:007324 global diffinhdr treediffs
Steffen Prohaska890fae72007-08-12 10:05:467325 global diffcontext
Steffen Prohaskab9b86002008-01-17 22:42:557326 global ignorespace
Paul Mackerras3ed31a82008-04-26 06:00:007327 global limitdiffs vfilelimit curview
Paul Mackerras8b07dca2008-11-02 11:34:477328 global diffencoding targetline diffnparents
Paul Mackerrasa8138732009-05-16 11:06:017329 global git_version
Paul Mackerrasc8dfbcf2005-06-25 05:39:217330
Paul Mackerrasa8138732009-05-16 11:06:017331 set textconv {}
7332 if {[package vcompare $git_version "1.6.1"] >= 0} {
7333 set textconv "--textconv"
7334 }
7335 set cmd [diffcmd $ids "-p $textconv -C --cc --no-commit-id -U$diffcontext"]
Steffen Prohaskab9b86002008-01-17 22:42:557336 if {$ignorespace} {
7337 append cmd " -w"
7338 }
Paul Mackerras3ed31a82008-04-26 06:00:007339 if {$limitdiffs && $vfilelimit($curview) ne {}} {
7340 set cmd [concat $cmd -- $vfilelimit($curview)]
Paul Mackerras7a39a172007-10-23 00:15:117341 }
7342 if {[catch {set bdf [open $cmd r]} err]} {
Paul Mackerras8b07dca2008-11-02 11:34:477343 error_popup [mc "Error getting diffs: %s" $err]
Paul Mackerrase5c2d852005-05-11 23:44:547344 return
7345 }
Paul Mackerras8a897742008-10-27 10:36:257346 set targetline {}
Paul Mackerras8b07dca2008-11-02 11:34:477347 set diffnparents 0
Paul Mackerras4f2c2642005-07-17 15:11:447348 set diffinhdr 0
Alexander Gavrilov09c70292008-10-13 08:12:317349 set diffencoding [get_path_encoding {}]
Pat Thoyts681c3292009-03-16 10:24:407350 fconfigure $bdf -blocking 0 -encoding binary -eofchar {}
Paul Mackerrasc8dfbcf2005-06-25 05:39:217351 set blobdifffd($ids) $bdf
Paul Mackerras7eb3cb92007-06-17 04:45:007352 filerun $bdf [list getblobdiffline $bdf $diffids]
Paul Mackerrase5c2d852005-05-11 23:44:547353}
7354
Paul Mackerras89b11d32006-05-02 09:55:317355proc setinlist {var i val} {
7356 global $var
7357
7358 while {[llength [set $var]] < $i} {
7359 lappend $var {}
7360 }
7361 if {[llength [set $var]] == $i} {
7362 lappend $var $val
7363 } else {
7364 lset $var $i $val
7365 }
7366}
7367
Paul Mackerras9396cd32007-06-23 10:28:157368proc makediffhdr {fname ids} {
Paul Mackerras8b07dca2008-11-02 11:34:477369 global ctext curdiffstart treediffs diffencoding
Paul Mackerras8a897742008-10-27 10:36:257370 global ctext_file_names jump_to_here targetline diffline
Paul Mackerras9396cd32007-06-23 10:28:157371
Paul Mackerras8b07dca2008-11-02 11:34:477372 set fname [encoding convertfrom $fname]
7373 set diffencoding [get_path_encoding $fname]
Paul Mackerras9396cd32007-06-23 10:28:157374 set i [lsearch -exact $treediffs($ids) $fname]
7375 if {$i >= 0} {
7376 setinlist difffilestart $i $curdiffstart
7377 }
Paul Mackerras48a81b72008-11-04 10:09:007378 lset ctext_file_names end $fname
Paul Mackerras9396cd32007-06-23 10:28:157379 set l [expr {(78 - [string length $fname]) / 2}]
7380 set pad [string range "----------------------------------------" 1 $l]
7381 $ctext insert $curdiffstart "$pad $fname $pad" filesep
Paul Mackerras8a897742008-10-27 10:36:257382 set targetline {}
7383 if {$jump_to_here ne {} && [lindex $jump_to_here 0] eq $fname} {
7384 set targetline [lindex $jump_to_here 1]
7385 }
7386 set diffline 0
Paul Mackerras9396cd32007-06-23 10:28:157387}
7388
Paul Mackerrasc8dfbcf2005-06-25 05:39:217389proc getblobdiffline {bdf ids} {
Paul Mackerras9396cd32007-06-23 10:28:157390 global diffids blobdifffd ctext curdiffstart
Paul Mackerras7eab2932005-07-20 16:25:547391 global diffnexthead diffnextnote difffilestart
Alexander Gavrilov7cdc3552008-10-24 08:13:017392 global ctext_file_names ctext_file_lines
Paul Mackerras8b07dca2008-11-02 11:34:477393 global diffinhdr treediffs mergemax diffnparents
Paul Mackerras8a897742008-10-27 10:36:257394 global diffencoding jump_to_here targetline diffline
Paul Mackerrasc8dfbcf2005-06-25 05:39:217395
Paul Mackerras7eb3cb92007-06-17 04:45:007396 set nr 0
Paul Mackerrase5c2d852005-05-11 23:44:547397 $ctext conf -state normal
Paul Mackerras7eb3cb92007-06-17 04:45:007398 while {[incr nr] <= 1000 && [gets $bdf line] >= 0} {
7399 if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
7400 close $bdf
7401 return 0
Paul Mackerras89b11d32006-05-02 09:55:317402 }
Paul Mackerras8b07dca2008-11-02 11:34:477403 if {![string compare -length 5 "diff " $line]} {
7404 if {![regexp {^diff (--cc|--git) } $line m type]} {
7405 set line [encoding convertfrom $line]
7406 $ctext insert end "$line\n" hunksep
7407 continue
7408 }
Paul Mackerras7eb3cb92007-06-17 04:45:007409 # start of a new file
Paul Mackerras8b07dca2008-11-02 11:34:477410 set diffinhdr 1
Paul Mackerras7eb3cb92007-06-17 04:45:007411 $ctext insert end "\n"
Paul Mackerras9396cd32007-06-23 10:28:157412 set curdiffstart [$ctext index "end - 1c"]
Alexander Gavrilov7cdc3552008-10-24 08:13:017413 lappend ctext_file_names ""
7414 lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
Paul Mackerras9396cd32007-06-23 10:28:157415 $ctext insert end "\n" filesep
Paul Mackerras8b07dca2008-11-02 11:34:477416
7417 if {$type eq "--cc"} {
7418 # start of a new file in a merge diff
7419 set fname [string range $line 10 end]
7420 if {[lsearch -exact $treediffs($ids) $fname] < 0} {
7421 lappend treediffs($ids) $fname
7422 add_flist [list $fname]
7423 }
7424
Paul Mackerras9396cd32007-06-23 10:28:157425 } else {
Paul Mackerras8b07dca2008-11-02 11:34:477426 set line [string range $line 11 end]
7427 # If the name hasn't changed the length will be odd,
7428 # the middle char will be a space, and the two bits either
7429 # side will be a/name and b/name, or "a/name" and "b/name".
7430 # If the name has changed we'll get "rename from" and
7431 # "rename to" or "copy from" and "copy to" lines following
7432 # this, and we'll use them to get the filenames.
7433 # This complexity is necessary because spaces in the
7434 # filename(s) don't get escaped.
7435 set l [string length $line]
7436 set i [expr {$l / 2}]
7437 if {!(($l & 1) && [string index $line $i] eq " " &&
7438 [string range $line 2 [expr {$i - 1}]] eq \
7439 [string range $line [expr {$i + 3}] end])} {
7440 continue
7441 }
7442 # unescape if quoted and chop off the a/ from the front
7443 if {[string index $line 0] eq "\""} {
7444 set fname [string range [lindex $line 0] 2 end]
7445 } else {
7446 set fname [string range $line 2 [expr {$i - 1}]]
7447 }
Paul Mackerrase5c2d852005-05-11 23:44:547448 }
Paul Mackerras9396cd32007-06-23 10:28:157449 makediffhdr $fname $ids
7450
Paul Mackerras48a81b72008-11-04 10:09:007451 } elseif {![string compare -length 16 "* Unmerged path " $line]} {
7452 set fname [encoding convertfrom [string range $line 16 end]]
7453 $ctext insert end "\n"
7454 set curdiffstart [$ctext index "end - 1c"]
7455 lappend ctext_file_names $fname
7456 lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
7457 $ctext insert end "$line\n" filesep
7458 set i [lsearch -exact $treediffs($ids) $fname]
7459 if {$i >= 0} {
7460 setinlist difffilestart $i $curdiffstart
7461 }
7462
Paul Mackerras8b07dca2008-11-02 11:34:477463 } elseif {![string compare -length 2 "@@" $line]} {
7464 regexp {^@@+} $line ats
Alexander Gavrilov09c70292008-10-13 08:12:317465 set line [encoding convertfrom $diffencoding $line]
Paul Mackerras7eb3cb92007-06-17 04:45:007466 $ctext insert end "$line\n" hunksep
Paul Mackerras8b07dca2008-11-02 11:34:477467 if {[regexp { \+(\d+),\d+ @@} $line m nl]} {
7468 set diffline $nl
7469 }
7470 set diffnparents [expr {[string length $ats] - 1}]
Paul Mackerras7eb3cb92007-06-17 04:45:007471 set diffinhdr 0
Paul Mackerras9396cd32007-06-23 10:28:157472
7473 } elseif {$diffinhdr} {
Johannes Sixt5e85ec42007-10-02 14:16:547474 if {![string compare -length 12 "rename from " $line]} {
Johannes Sixtd1cb2982007-08-16 12:32:297475 set fname [string range $line [expr 6 + [string first " from " $line] ] end]
Paul Mackerras9396cd32007-06-23 10:28:157476 if {[string index $fname 0] eq "\""} {
7477 set fname [lindex $fname 0]
7478 }
Alexander Gavrilov09c70292008-10-13 08:12:317479 set fname [encoding convertfrom $fname]
Paul Mackerras9396cd32007-06-23 10:28:157480 set i [lsearch -exact $treediffs($ids) $fname]
7481 if {$i >= 0} {
7482 setinlist difffilestart $i $curdiffstart
7483 }
Johannes Sixtd1cb2982007-08-16 12:32:297484 } elseif {![string compare -length 10 $line "rename to "] ||
7485 ![string compare -length 8 $line "copy to "]} {
7486 set fname [string range $line [expr 4 + [string first " to " $line] ] end]
Paul Mackerras9396cd32007-06-23 10:28:157487 if {[string index $fname 0] eq "\""} {
7488 set fname [lindex $fname 0]
7489 }
7490 makediffhdr $fname $ids
7491 } elseif {[string compare -length 3 $line "---"] == 0} {
7492 # do nothing
7493 continue
7494 } elseif {[string compare -length 3 $line "+++"] == 0} {
7495 set diffinhdr 0
7496 continue
7497 }
7498 $ctext insert end "$line\n" filesep
7499
Paul Mackerras7eb3cb92007-06-17 04:45:007500 } else {
Pat Thoyts681c3292009-03-16 10:24:407501 set line [string map {\x1A ^Z} \
7502 [encoding convertfrom $diffencoding $line]]
Paul Mackerras8b07dca2008-11-02 11:34:477503 # parse the prefix - one ' ', '-' or '+' for each parent
7504 set prefix [string range $line 0 [expr {$diffnparents - 1}]]
7505 set tag [expr {$diffnparents > 1? "m": "d"}]
7506 if {[string trim $prefix " -+"] eq {}} {
7507 # prefix only has " ", "-" and "+" in it: normal diff line
7508 set num [string first "-" $prefix]
7509 if {$num >= 0} {
7510 # removed line, first parent with line is $num
7511 if {$num >= $mergemax} {
7512 set num "max"
7513 }
7514 $ctext insert end "$line\n" $tag$num
7515 } else {
7516 set tags {}
7517 if {[string first "+" $prefix] >= 0} {
7518 # added line
7519 lappend tags ${tag}result
7520 if {$diffnparents > 1} {
7521 set num [string first " " $prefix]
7522 if {$num >= 0} {
7523 if {$num >= $mergemax} {
7524 set num "max"
7525 }
7526 lappend tags m$num
7527 }
7528 }
7529 }
7530 if {$targetline ne {}} {
7531 if {$diffline == $targetline} {
7532 set seehere [$ctext index "end - 1 chars"]
7533 set targetline {}
7534 } else {
7535 incr diffline
7536 }
7537 }
7538 $ctext insert end "$line\n" $tags
7539 }
Paul Mackerras7eb3cb92007-06-17 04:45:007540 } else {
Paul Mackerras9396cd32007-06-23 10:28:157541 # "\ No newline at end of file",
7542 # or something else we don't recognize
7543 $ctext insert end "$line\n" hunksep
Paul Mackerras7eb3cb92007-06-17 04:45:007544 }
Paul Mackerrase5c2d852005-05-11 23:44:547545 }
7546 }
Paul Mackerras8b07dca2008-11-02 11:34:477547 if {[info exists seehere]} {
7548 mark_ctext_line [lindex [split $seehere .] 0]
7549 }
Paul Mackerrase5c2d852005-05-11 23:44:547550 $ctext conf -state disabled
Paul Mackerras7eb3cb92007-06-17 04:45:007551 if {[eof $bdf]} {
7552 close $bdf
Paul Mackerras7eb3cb92007-06-17 04:45:007553 return 0
Paul Mackerrasc8dfbcf2005-06-25 05:39:217554 }
Paul Mackerras7eb3cb92007-06-17 04:45:007555 return [expr {$nr >= 1000? 2: 1}]
Paul Mackerrase5c2d852005-05-11 23:44:547556}
7557
Paul Mackerrasa8d610a2007-04-19 01:39:127558proc changediffdisp {} {
7559 global ctext diffelide
7560
7561 $ctext tag conf d0 -elide [lindex $diffelide 0]
Paul Mackerras8b07dca2008-11-02 11:34:477562 $ctext tag conf dresult -elide [lindex $diffelide 1]
Paul Mackerrasa8d610a2007-04-19 01:39:127563}
7564
Paul Mackerrasf4c54b32008-05-10 03:15:367565proc highlightfile {loc cline} {
7566 global ctext cflist cflist_top
7567
7568 $ctext yview $loc
7569 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
7570 $cflist tag add highlight $cline.0 "$cline.0 lineend"
7571 $cflist see $cline.0
7572 set cflist_top $cline
7573}
7574
OGAWA Hirofumi67c22872006-09-27 03:32:197575proc prevfile {} {
Paul Mackerrasf4c54b32008-05-10 03:15:367576 global difffilestart ctext cmitmode
7577
7578 if {$cmitmode eq "tree"} return
7579 set prev 0.0
7580 set prevline 1
OGAWA Hirofumi67c22872006-09-27 03:32:197581 set here [$ctext index @0,0]
7582 foreach loc $difffilestart {
7583 if {[$ctext compare $loc >= $here]} {
Paul Mackerrasf4c54b32008-05-10 03:15:367584 highlightfile $prev $prevline
OGAWA Hirofumi67c22872006-09-27 03:32:197585 return
7586 }
7587 set prev $loc
Paul Mackerrasf4c54b32008-05-10 03:15:367588 incr prevline
OGAWA Hirofumi67c22872006-09-27 03:32:197589 }
Paul Mackerrasf4c54b32008-05-10 03:15:367590 highlightfile $prev $prevline
OGAWA Hirofumi67c22872006-09-27 03:32:197591}
7592
Paul Mackerras39ad8572005-05-19 12:35:537593proc nextfile {} {
Paul Mackerrasf4c54b32008-05-10 03:15:367594 global difffilestart ctext cmitmode
7595
7596 if {$cmitmode eq "tree"} return
Paul Mackerras39ad8572005-05-19 12:35:537597 set here [$ctext index @0,0]
Paul Mackerrasf4c54b32008-05-10 03:15:367598 set line 1
Paul Mackerras7fcceed2006-04-27 09:21:497599 foreach loc $difffilestart {
Paul Mackerrasf4c54b32008-05-10 03:15:367600 incr line
Paul Mackerras7fcceed2006-04-27 09:21:497601 if {[$ctext compare $loc > $here]} {
Paul Mackerrasf4c54b32008-05-10 03:15:367602 highlightfile $loc $line
OGAWA Hirofumi67c22872006-09-27 03:32:197603 return
Paul Mackerras39ad8572005-05-19 12:35:537604 }
7605 }
Paul Mackerras1db95b02005-05-09 04:08:397606}
7607
Paul Mackerras3ea06f92006-05-24 00:16:037608proc clear_ctext {{first 1.0}} {
7609 global ctext smarktop smarkbot
Alexander Gavrilov7cdc3552008-10-24 08:13:017610 global ctext_file_names ctext_file_lines
Paul Mackerras97645682007-08-23 12:24:387611 global pendinglinks
Paul Mackerras3ea06f92006-05-24 00:16:037612
Paul Mackerras1902c272006-05-25 11:25:137613 set l [lindex [split $first .] 0]
7614 if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
7615 set smarktop $l
Paul Mackerras3ea06f92006-05-24 00:16:037616 }
Paul Mackerras1902c272006-05-25 11:25:137617 if {![info exists smarkbot] || [$ctext compare $first < $smarkbot.0]} {
7618 set smarkbot $l
Paul Mackerras3ea06f92006-05-24 00:16:037619 }
7620 $ctext delete $first end
Paul Mackerras97645682007-08-23 12:24:387621 if {$first eq "1.0"} {
7622 catch {unset pendinglinks}
7623 }
Alexander Gavrilov7cdc3552008-10-24 08:13:017624 set ctext_file_names {}
7625 set ctext_file_lines {}
Paul Mackerras3ea06f92006-05-24 00:16:037626}
7627
Paul Mackerras32f1b3e2007-09-28 11:27:397628proc settabs {{firstab {}}} {
Paul Mackerras9c311b32007-10-04 12:27:137629 global firsttabstop tabstop ctext have_tk85
Paul Mackerras32f1b3e2007-09-28 11:27:397630
7631 if {$firstab ne {} && $have_tk85} {
7632 set firsttabstop $firstab
7633 }
Paul Mackerras9c311b32007-10-04 12:27:137634 set w [font measure textfont "0"]
Paul Mackerras32f1b3e2007-09-28 11:27:397635 if {$firsttabstop != 0} {
Paul Mackerras64b5f142007-10-04 12:19:247636 $ctext conf -tabs [list [expr {($firsttabstop + $tabstop) * $w}] \
7637 [expr {($firsttabstop + 2 * $tabstop) * $w}]]
Paul Mackerras32f1b3e2007-09-28 11:27:397638 } elseif {$have_tk85 || $tabstop != 8} {
7639 $ctext conf -tabs [expr {$tabstop * $w}]
7640 } else {
7641 $ctext conf -tabs {}
7642 }
Paul Mackerras3ea06f92006-05-24 00:16:037643}
7644
7645proc incrsearch {name ix op} {
Paul Mackerras1902c272006-05-25 11:25:137646 global ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 00:16:037647
7648 $ctext tag remove found 1.0 end
Paul Mackerras1902c272006-05-25 11:25:137649 if {[catch {$ctext index anchor}]} {
7650 # no anchor set, use start of selection, or of visible area
7651 set sel [$ctext tag ranges sel]
7652 if {$sel ne {}} {
7653 $ctext mark set anchor [lindex $sel 0]
7654 } elseif {$searchdirn eq "-forwards"} {
7655 $ctext mark set anchor @0,0
7656 } else {
7657 $ctext mark set anchor @0,[winfo height $ctext]
7658 }
7659 }
Paul Mackerras3ea06f92006-05-24 00:16:037660 if {$searchstring ne {}} {
Paul Mackerras1902c272006-05-25 11:25:137661 set here [$ctext search $searchdirn -- $searchstring anchor]
7662 if {$here ne {}} {
7663 $ctext see $here
7664 }
Paul Mackerras3ea06f92006-05-24 00:16:037665 searchmarkvisible 1
7666 }
7667}
7668
7669proc dosearch {} {
Paul Mackerras1902c272006-05-25 11:25:137670 global sstring ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 00:16:037671
7672 focus $sstring
7673 $sstring icursor end
Paul Mackerras1902c272006-05-25 11:25:137674 set searchdirn -forwards
7675 if {$searchstring ne {}} {
7676 set sel [$ctext tag ranges sel]
7677 if {$sel ne {}} {
7678 set start "[lindex $sel 0] + 1c"
7679 } elseif {[catch {set start [$ctext index anchor]}]} {
7680 set start "@0,0"
7681 }
7682 set match [$ctext search -count mlen -- $searchstring $start]
7683 $ctext tag remove sel 1.0 end
7684 if {$match eq {}} {
7685 bell
7686 return
7687 }
7688 $ctext see $match
7689 set mend "$match + $mlen c"
7690 $ctext tag add sel $match $mend
7691 $ctext mark unset anchor
Paul Mackerras3ea06f92006-05-24 00:16:037692 }
Paul Mackerras1902c272006-05-25 11:25:137693}
7694
7695proc dosearchback {} {
7696 global sstring ctext searchstring searchdirn
7697
7698 focus $sstring
7699 $sstring icursor end
7700 set searchdirn -backwards
7701 if {$searchstring ne {}} {
7702 set sel [$ctext tag ranges sel]
7703 if {$sel ne {}} {
7704 set start [lindex $sel 0]
7705 } elseif {[catch {set start [$ctext index anchor]}]} {
7706 set start @0,[winfo height $ctext]
7707 }
7708 set match [$ctext search -backwards -count ml -- $searchstring $start]
7709 $ctext tag remove sel 1.0 end
7710 if {$match eq {}} {
7711 bell
7712 return
7713 }
7714 $ctext see $match
7715 set mend "$match + $ml c"
7716 $ctext tag add sel $match $mend
7717 $ctext mark unset anchor
7718 }
Paul Mackerras3ea06f92006-05-24 00:16:037719}
7720
7721proc searchmark {first last} {
7722 global ctext searchstring
7723
7724 set mend $first.0
7725 while {1} {
7726 set match [$ctext search -count mlen -- $searchstring $mend $last.end]
7727 if {$match eq {}} break
7728 set mend "$match + $mlen c"
7729 $ctext tag add found $match $mend
7730 }
7731}
7732
7733proc searchmarkvisible {doall} {
7734 global ctext smarktop smarkbot
7735
7736 set topline [lindex [split [$ctext index @0,0] .] 0]
7737 set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
7738 if {$doall || $botline < $smarktop || $topline > $smarkbot} {
7739 # no overlap with previous
7740 searchmark $topline $botline
7741 set smarktop $topline
7742 set smarkbot $botline
7743 } else {
7744 if {$topline < $smarktop} {
7745 searchmark $topline [expr {$smarktop-1}]
7746 set smarktop $topline
7747 }
7748 if {$botline > $smarkbot} {
7749 searchmark [expr {$smarkbot+1}] $botline
7750 set smarkbot $botline
7751 }
7752 }
7753}
7754
7755proc scrolltext {f0 f1} {
Paul Mackerras1902c272006-05-25 11:25:137756 global searchstring
Paul Mackerras3ea06f92006-05-24 00:16:037757
Pekka Kaitaniemi8809d692008-03-08 12:27:237758 .bleft.bottom.sb set $f0 $f1
Paul Mackerras3ea06f92006-05-24 00:16:037759 if {$searchstring ne {}} {
7760 searchmarkvisible 0
7761 }
7762}
7763
Paul Mackerras1d10f362005-05-15 12:55:477764proc setcoords {} {
Paul Mackerras9c311b32007-10-04 12:27:137765 global linespc charspc canvx0 canvy0
Paul Mackerrasf6075eb2005-08-17 23:30:107766 global xspc1 xspc2 lthickness
Paul Mackerras8d858d12005-08-04 23:52:167767
Paul Mackerras9c311b32007-10-04 12:27:137768 set linespc [font metrics mainfont -linespace]
7769 set charspc [font measure mainfont "m"]
Paul Mackerras9f1afe02006-02-19 11:44:477770 set canvy0 [expr {int(3 + 0.5 * $linespc)}]
7771 set canvx0 [expr {int(3 + 0.5 * $linespc)}]
Paul Mackerrasf6075eb2005-08-17 23:30:107772 set lthickness [expr {int($linespc / 9) + 1}]
Paul Mackerras8d858d12005-08-04 23:52:167773 set xspc1(0) $linespc
7774 set xspc2 $linespc
Paul Mackerras9a40c502005-05-12 23:46:167775}
Paul Mackerras1db95b02005-05-09 04:08:397776
Paul Mackerras1d10f362005-05-15 12:55:477777proc redisplay {} {
Paul Mackerrasbe0cd092006-03-30 22:55:117778 global canv
Paul Mackerras9f1afe02006-02-19 11:44:477779 global selectedline
7780
7781 set ymax [lindex [$canv cget -scrollregion] 3]
7782 if {$ymax eq {} || $ymax == 0} return
7783 set span [$canv yview]
7784 clear_display
Paul Mackerrasbe0cd092006-03-30 22:55:117785 setcanvscroll
Paul Mackerras9f1afe02006-02-19 11:44:477786 allcanvs yview moveto [lindex $span 0]
7787 drawvisible
Paul Mackerras94b4a692008-05-20 10:51:067788 if {$selectedline ne {}} {
Paul Mackerras9f1afe02006-02-19 11:44:477789 selectline $selectedline 0
Paul Mackerrasca6d8f52006-08-06 11:08:057790 allcanvs yview moveto [lindex $span 0]
Paul Mackerras1db95b02005-05-09 04:08:397791 }
7792}
Paul Mackerras1d10f362005-05-15 12:55:477793
Paul Mackerras0ed1dd32007-10-06 08:27:377794proc parsefont {f n} {
7795 global fontattr
7796
7797 set fontattr($f,family) [lindex $n 0]
7798 set s [lindex $n 1]
7799 if {$s eq {} || $s == 0} {
7800 set s 10
7801 } elseif {$s < 0} {
7802 set s [expr {int(-$s / [winfo fpixels . 1p] + 0.5)}]
Paul Mackerras9c311b32007-10-04 12:27:137803 }
Paul Mackerras0ed1dd32007-10-06 08:27:377804 set fontattr($f,size) $s
7805 set fontattr($f,weight) normal
7806 set fontattr($f,slant) roman
7807 foreach style [lrange $n 2 end] {
7808 switch -- $style {
7809 "normal" -
7810 "bold" {set fontattr($f,weight) $style}
7811 "roman" -
7812 "italic" {set fontattr($f,slant) $style}
7813 }
Paul Mackerras9c311b32007-10-04 12:27:137814 }
Paul Mackerras0ed1dd32007-10-06 08:27:377815}
7816
7817proc fontflags {f {isbold 0}} {
7818 global fontattr
7819
7820 return [list -family $fontattr($f,family) -size $fontattr($f,size) \
7821 -weight [expr {$isbold? "bold": $fontattr($f,weight)}] \
7822 -slant $fontattr($f,slant)]
7823}
7824
7825proc fontname {f} {
7826 global fontattr
7827
7828 set n [list $fontattr($f,family) $fontattr($f,size)]
7829 if {$fontattr($f,weight) eq "bold"} {
7830 lappend n "bold"
Paul Mackerras9c311b32007-10-04 12:27:137831 }
Paul Mackerras0ed1dd32007-10-06 08:27:377832 if {$fontattr($f,slant) eq "italic"} {
7833 lappend n "italic"
Paul Mackerras9c311b32007-10-04 12:27:137834 }
Paul Mackerras0ed1dd32007-10-06 08:27:377835 return $n
Paul Mackerras9c311b32007-10-04 12:27:137836}
7837
Paul Mackerras1d10f362005-05-15 12:55:477838proc incrfont {inc} {
Paul Mackerras7fcc92b2007-12-02 23:33:017839 global mainfont textfont ctext canv cflist showrefstop
Paul Mackerras0ed1dd32007-10-06 08:27:377840 global stopped entries fontattr
7841
Paul Mackerras1d10f362005-05-15 12:55:477842 unmarkmatches
Paul Mackerras0ed1dd32007-10-06 08:27:377843 set s $fontattr(mainfont,size)
Paul Mackerras9c311b32007-10-04 12:27:137844 incr s $inc
7845 if {$s < 1} {
7846 set s 1
7847 }
Paul Mackerras0ed1dd32007-10-06 08:27:377848 set fontattr(mainfont,size) $s
Paul Mackerras9c311b32007-10-04 12:27:137849 font config mainfont -size $s
7850 font config mainfontbold -size $s
Paul Mackerras0ed1dd32007-10-06 08:27:377851 set mainfont [fontname mainfont]
7852 set s $fontattr(textfont,size)
Paul Mackerras9c311b32007-10-04 12:27:137853 incr s $inc
7854 if {$s < 1} {
7855 set s 1
7856 }
Paul Mackerras0ed1dd32007-10-06 08:27:377857 set fontattr(textfont,size) $s
Paul Mackerras9c311b32007-10-04 12:27:137858 font config textfont -size $s
7859 font config textfontbold -size $s
Paul Mackerras0ed1dd32007-10-06 08:27:377860 set textfont [fontname textfont]
Paul Mackerras1d10f362005-05-15 12:55:477861 setcoords
Paul Mackerras32f1b3e2007-09-28 11:27:397862 settabs
Paul Mackerras1d10f362005-05-15 12:55:477863 redisplay
Paul Mackerras1db95b02005-05-09 04:08:397864}
Paul Mackerras1d10f362005-05-15 12:55:477865
Paul Mackerrasee3dc722005-06-25 06:37:137866proc clearsha1 {} {
7867 global sha1entry sha1string
7868 if {[string length $sha1string] == 40} {
7869 $sha1entry delete 0 end
7870 }
7871}
7872
Paul Mackerras887fe3c2005-05-21 07:35:377873proc sha1change {n1 n2 op} {
7874 global sha1string currentid sha1but
7875 if {$sha1string == {}
7876 || ([info exists currentid] && $sha1string == $currentid)} {
7877 set state disabled
7878 } else {
7879 set state normal
7880 }
7881 if {[$sha1but cget -state] == $state} return
7882 if {$state == "normal"} {
Christian Stimmingd990ced2007-11-07 17:42:557883 $sha1but conf -state normal -relief raised -text "[mc "Goto:"] "
Paul Mackerras887fe3c2005-05-21 07:35:377884 } else {
Christian Stimmingd990ced2007-11-07 17:42:557885 $sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] "
Paul Mackerras887fe3c2005-05-21 07:35:377886 }
7887}
7888
7889proc gotocommit {} {
Paul Mackerras7fcc92b2007-12-02 23:33:017890 global sha1string tagids headids curview varcid
Paul Mackerrasf3b8b3c2005-07-18 16:16:357891
Paul Mackerras887fe3c2005-05-21 07:35:377892 if {$sha1string == {}
7893 || ([info exists currentid] && $sha1string == $currentid)} return
7894 if {[info exists tagids($sha1string)]} {
7895 set id $tagids($sha1string)
Stephen Rothwelle1007122006-03-30 05:13:127896 } elseif {[info exists headids($sha1string)]} {
7897 set id $headids($sha1string)
Paul Mackerras887fe3c2005-05-21 07:35:377898 } else {
7899 set id [string tolower $sha1string]
Paul Mackerrasf3b8b3c2005-07-18 16:16:357900 if {[regexp {^[0-9a-f]{4,39}$} $id]} {
Paul Mackerrasd375ef92008-10-20 23:18:127901 set matches [longid $id]
Paul Mackerrasf3b8b3c2005-07-18 16:16:357902 if {$matches ne {}} {
7903 if {[llength $matches] > 1} {
Christian Stimmingd990ced2007-11-07 17:42:557904 error_popup [mc "Short SHA1 id %s is ambiguous" $id]
Paul Mackerrasf3b8b3c2005-07-18 16:16:357905 return
7906 }
Paul Mackerrasd375ef92008-10-20 23:18:127907 set id [lindex $matches 0]
Paul Mackerrasf3b8b3c2005-07-18 16:16:357908 }
7909 }
Paul Mackerras887fe3c2005-05-21 07:35:377910 }
Paul Mackerras7fcc92b2007-12-02 23:33:017911 if {[commitinview $id $curview]} {
7912 selectline [rowofcommit $id] 1
Paul Mackerras887fe3c2005-05-21 07:35:377913 return
7914 }
Paul Mackerrasf3b8b3c2005-07-18 16:16:357915 if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
Christian Stimmingd990ced2007-11-07 17:42:557916 set msg [mc "SHA1 id %s is not known" $sha1string]
Paul Mackerras887fe3c2005-05-21 07:35:377917 } else {
Christian Stimmingd990ced2007-11-07 17:42:557918 set msg [mc "Tag/Head %s is not known" $sha1string]
Paul Mackerras887fe3c2005-05-21 07:35:377919 }
Christian Stimmingd990ced2007-11-07 17:42:557920 error_popup $msg
Paul Mackerras887fe3c2005-05-21 07:35:377921}
7922
Paul Mackerras84ba7342005-06-17 00:12:267923proc lineenter {x y id} {
7924 global hoverx hovery hoverid hovertimer
7925 global commitinfo canv
7926
Paul Mackerras8ed16482006-03-02 11:56:447927 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerras84ba7342005-06-17 00:12:267928 set hoverx $x
7929 set hovery $y
7930 set hoverid $id
7931 if {[info exists hovertimer]} {
7932 after cancel $hovertimer
7933 }
7934 set hovertimer [after 500 linehover]
7935 $canv delete hover
7936}
7937
7938proc linemotion {x y id} {
7939 global hoverx hovery hoverid hovertimer
7940
7941 if {[info exists hoverid] && $id == $hoverid} {
7942 set hoverx $x
7943 set hovery $y
7944 if {[info exists hovertimer]} {
7945 after cancel $hovertimer
7946 }
7947 set hovertimer [after 500 linehover]
7948 }
7949}
7950
7951proc lineleave {id} {
7952 global hoverid hovertimer canv
7953
7954 if {[info exists hoverid] && $id == $hoverid} {
7955 $canv delete hover
7956 if {[info exists hovertimer]} {
7957 after cancel $hovertimer
7958 unset hovertimer
7959 }
7960 unset hoverid
7961 }
7962}
7963
7964proc linehover {} {
7965 global hoverx hovery hoverid hovertimer
7966 global canv linespc lthickness
Paul Mackerras9c311b32007-10-04 12:27:137967 global commitinfo
Paul Mackerras84ba7342005-06-17 00:12:267968
7969 set text [lindex $commitinfo($hoverid) 0]
7970 set ymax [lindex [$canv cget -scrollregion] 3]
7971 if {$ymax == {}} return
7972 set yfrac [lindex [$canv yview] 0]
7973 set x [expr {$hoverx + 2 * $linespc}]
7974 set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
7975 set x0 [expr {$x - 2 * $lthickness}]
7976 set y0 [expr {$y - 2 * $lthickness}]
Paul Mackerras9c311b32007-10-04 12:27:137977 set x1 [expr {$x + [font measure mainfont $text] + 2 * $lthickness}]
Paul Mackerras84ba7342005-06-17 00:12:267978 set y1 [expr {$y + $linespc + 2 * $lthickness}]
7979 set t [$canv create rectangle $x0 $y0 $x1 $y1 \
7980 -fill \#ffff80 -outline black -width 1 -tags hover]
7981 $canv raise $t
Paul Mackerrasf8a2c0d2006-07-05 12:56:377982 set t [$canv create text $x $y -anchor nw -text $text -tags hover \
Paul Mackerras9c311b32007-10-04 12:27:137983 -font mainfont]
Paul Mackerras84ba7342005-06-17 00:12:267984 $canv raise $t
7985}
7986
Paul Mackerras9843c302005-08-30 00:57:117987proc clickisonarrow {id y} {
Paul Mackerras50b44ec2006-04-04 00:16:227988 global lthickness
Paul Mackerras9843c302005-08-30 00:57:117989
Paul Mackerras50b44ec2006-04-04 00:16:227990 set ranges [rowranges $id]
Paul Mackerras9843c302005-08-30 00:57:117991 set thresh [expr {2 * $lthickness + 6}]
Paul Mackerras50b44ec2006-04-04 00:16:227992 set n [expr {[llength $ranges] - 1}]
Paul Mackerrasf6342482006-02-27 23:02:037993 for {set i 1} {$i < $n} {incr i} {
Paul Mackerras50b44ec2006-04-04 00:16:227994 set row [lindex $ranges $i]
Paul Mackerrasf6342482006-02-27 23:02:037995 if {abs([yc $row] - $y) < $thresh} {
7996 return $i
Paul Mackerras9843c302005-08-30 00:57:117997 }
7998 }
7999 return {}
8000}
8001
Paul Mackerrasf6342482006-02-27 23:02:038002proc arrowjump {id n y} {
Paul Mackerras50b44ec2006-04-04 00:16:228003 global canv
Paul Mackerras9843c302005-08-30 00:57:118004
Paul Mackerrasf6342482006-02-27 23:02:038005 # 1 <-> 2, 3 <-> 4, etc...
8006 set n [expr {(($n - 1) ^ 1) + 1}]
Paul Mackerras50b44ec2006-04-04 00:16:228007 set row [lindex [rowranges $id] $n]
Paul Mackerrasf6342482006-02-27 23:02:038008 set yt [yc $row]
Paul Mackerras9843c302005-08-30 00:57:118009 set ymax [lindex [$canv cget -scrollregion] 3]
8010 if {$ymax eq {} || $ymax <= 0} return
8011 set view [$canv yview]
8012 set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
8013 set yfrac [expr {$yt / $ymax - $yspan / 2}]
8014 if {$yfrac < 0} {
8015 set yfrac 0
8016 }
Paul Mackerrasf6342482006-02-27 23:02:038017 allcanvs yview moveto $yfrac
Paul Mackerras9843c302005-08-30 00:57:118018}
8019
Paul Mackerrasfa4da7b2005-08-07 23:47:228020proc lineclick {x y id isnew} {
Paul Mackerras7fcc92b2007-12-02 23:33:018021 global ctext commitinfo children canv thickerline curview
Paul Mackerrasc8dfbcf2005-06-25 05:39:218022
Paul Mackerras8ed16482006-03-02 11:56:448023 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerrasc8dfbcf2005-06-25 05:39:218024 unmarkmatches
Paul Mackerrasfa4da7b2005-08-07 23:47:228025 unselectline
Paul Mackerras9843c302005-08-30 00:57:118026 normalline
Paul Mackerrasc8dfbcf2005-06-25 05:39:218027 $canv delete hover
Paul Mackerras9843c302005-08-30 00:57:118028 # draw this line thicker than normal
Paul Mackerras9843c302005-08-30 00:57:118029 set thickerline $id
Paul Mackerrasc934a8a2006-03-02 12:00:448030 drawlines $id
Paul Mackerras9843c302005-08-30 00:57:118031 if {$isnew} {
8032 set ymax [lindex [$canv cget -scrollregion] 3]
8033 if {$ymax eq {}} return
8034 set yfrac [lindex [$canv yview] 0]
8035 set y [expr {$y + $yfrac * $ymax}]
8036 }
8037 set dirn [clickisonarrow $id $y]
8038 if {$dirn ne {}} {
8039 arrowjump $id $dirn $y
8040 return
8041 }
8042
8043 if {$isnew} {
8044 addtohistory [list lineclick $x $y $id 0]
8045 }
Paul Mackerrasc8dfbcf2005-06-25 05:39:218046 # fill the details pane with info about this line
8047 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 00:16:038048 clear_ctext
Paul Mackerras32f1b3e2007-09-28 11:27:398049 settabs 0
Christian Stimmingd990ced2007-11-07 17:42:558050 $ctext insert end "[mc "Parent"]:\t"
Paul Mackerras97645682007-08-23 12:24:388051 $ctext insert end $id link0
8052 setlink $id link0
Paul Mackerrasc8dfbcf2005-06-25 05:39:218053 set info $commitinfo($id)
Paul Mackerrasfa4da7b2005-08-07 23:47:228054 $ctext insert end "\n\t[lindex $info 0]\n"
Christian Stimmingd990ced2007-11-07 17:42:558055 $ctext insert end "\t[mc "Author"]:\t[lindex $info 1]\n"
Paul Mackerras232475d2005-11-14 23:34:038056 set date [formatdate [lindex $info 2]]
Christian Stimmingd990ced2007-11-07 17:42:558057 $ctext insert end "\t[mc "Date"]:\t$date\n"
Paul Mackerrasda7c24d2006-05-02 01:15:298058 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 10:47:408059 if {$kids ne {}} {
Christian Stimmingd990ced2007-11-07 17:42:558060 $ctext insert end "\n[mc "Children"]:"
Paul Mackerrasfa4da7b2005-08-07 23:47:228061 set i 0
Paul Mackerras79b2c752006-04-02 10:47:408062 foreach child $kids {
Paul Mackerrasfa4da7b2005-08-07 23:47:228063 incr i
Paul Mackerras8ed16482006-03-02 11:56:448064 if {![info exists commitinfo($child)] && ![getcommit $child]} continue
Paul Mackerrasc8dfbcf2005-06-25 05:39:218065 set info $commitinfo($child)
Paul Mackerrasfa4da7b2005-08-07 23:47:228066 $ctext insert end "\n\t"
Paul Mackerras97645682007-08-23 12:24:388067 $ctext insert end $child link$i
8068 setlink $child link$i
Paul Mackerrasfa4da7b2005-08-07 23:47:228069 $ctext insert end "\n\t[lindex $info 0]"
Christian Stimmingd990ced2007-11-07 17:42:558070 $ctext insert end "\n\t[mc "Author"]:\t[lindex $info 1]"
Paul Mackerras232475d2005-11-14 23:34:038071 set date [formatdate [lindex $info 2]]
Christian Stimmingd990ced2007-11-07 17:42:558072 $ctext insert end "\n\t[mc "Date"]:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 05:39:218073 }
8074 }
8075 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 09:21:498076 init_flist {}
Paul Mackerrasc8dfbcf2005-06-25 05:39:218077}
8078
Paul Mackerras9843c302005-08-30 00:57:118079proc normalline {} {
8080 global thickerline
8081 if {[info exists thickerline]} {
Paul Mackerrasc934a8a2006-03-02 12:00:448082 set id $thickerline
Paul Mackerras9843c302005-08-30 00:57:118083 unset thickerline
Paul Mackerrasc934a8a2006-03-02 12:00:448084 drawlines $id
Paul Mackerras9843c302005-08-30 00:57:118085 }
8086}
8087
Paul Mackerrasc8dfbcf2005-06-25 05:39:218088proc selbyid {id} {
Paul Mackerras7fcc92b2007-12-02 23:33:018089 global curview
8090 if {[commitinview $id $curview]} {
8091 selectline [rowofcommit $id] 1
Paul Mackerrasc8dfbcf2005-06-25 05:39:218092 }
8093}
8094
8095proc mstime {} {
8096 global startmstime
8097 if {![info exists startmstime]} {
8098 set startmstime [clock clicks -milliseconds]
8099 }
8100 return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
8101}
8102
8103proc rowmenu {x y id} {
Paul Mackerras7fcc92b2007-12-02 23:33:018104 global rowctxmenu selectedline rowmenuid curview
Paul Mackerrasb9fdba72009-04-08 23:34:468105 global nullid nullid2 fakerowmenu mainhead markedid
Paul Mackerrasc8dfbcf2005-06-25 05:39:218106
Paul Mackerrasbb3edc82007-09-27 01:00:258107 stopfinding
Paul Mackerras219ea3a2006-09-07 00:21:398108 set rowmenuid $id
Paul Mackerras94b4a692008-05-20 10:51:068109 if {$selectedline eq {} || [rowofcommit $id] eq $selectedline} {
Paul Mackerrasc8dfbcf2005-06-25 05:39:218110 set state disabled
8111 } else {
8112 set state normal
8113 }
Paul Mackerras8f489362007-07-13 09:49:378114 if {$id ne $nullid && $id ne $nullid2} {
Paul Mackerras219ea3a2006-09-07 00:21:398115 set menu $rowctxmenu
Michele Ballabio5e3502d2008-05-02 15:46:208116 if {$mainhead ne {}} {
Johannes Sixtda12e592008-12-03 12:43:208117 $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] -state normal
Michele Ballabio5e3502d2008-05-02 15:46:208118 } else {
8119 $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled
8120 }
Paul Mackerrasb9fdba72009-04-08 23:34:468121 if {[info exists markedid] && $markedid ne $id} {
8122 $menu entryconfigure 9 -state normal
8123 $menu entryconfigure 10 -state normal
Paul Mackerras010509f2009-04-09 12:10:208124 $menu entryconfigure 11 -state normal
Paul Mackerrasb9fdba72009-04-08 23:34:468125 } else {
8126 $menu entryconfigure 9 -state disabled
8127 $menu entryconfigure 10 -state disabled
Paul Mackerras010509f2009-04-09 12:10:208128 $menu entryconfigure 11 -state disabled
Paul Mackerrasb9fdba72009-04-08 23:34:468129 }
Paul Mackerras219ea3a2006-09-07 00:21:398130 } else {
8131 set menu $fakerowmenu
8132 }
Paul Mackerrasf2d0bbb2008-10-17 11:44:428133 $menu entryconfigure [mca "Diff this -> selected"] -state $state
8134 $menu entryconfigure [mca "Diff selected -> this"] -state $state
8135 $menu entryconfigure [mca "Make patch"] -state $state
Paul Mackerras219ea3a2006-09-07 00:21:398136 tk_popup $menu $x $y
Paul Mackerrasc8dfbcf2005-06-25 05:39:218137}
8138
Paul Mackerrasb9fdba72009-04-08 23:34:468139proc markhere {} {
8140 global rowmenuid markedid canv
8141
8142 set markedid $rowmenuid
8143 make_idmark $markedid
8144}
8145
8146proc gotomark {} {
8147 global markedid
8148
8149 if {[info exists markedid]} {
8150 selbyid $markedid
8151 }
8152}
8153
8154proc replace_by_kids {l r} {
8155 global curview children
8156
8157 set id [commitonrow $r]
8158 set l [lreplace $l 0 0]
8159 foreach kid $children($curview,$id) {
8160 lappend l [rowofcommit $kid]
8161 }
8162 return [lsort -integer -decreasing -unique $l]
8163}
8164
8165proc find_common_desc {} {
8166 global markedid rowmenuid curview children
8167
8168 if {![info exists markedid]} return
8169 if {![commitinview $markedid $curview] ||
8170 ![commitinview $rowmenuid $curview]} return
8171 #set t1 [clock clicks -milliseconds]
8172 set l1 [list [rowofcommit $markedid]]
8173 set l2 [list [rowofcommit $rowmenuid]]
8174 while 1 {
8175 set r1 [lindex $l1 0]
8176 set r2 [lindex $l2 0]
8177 if {$r1 eq {} || $r2 eq {}} break
8178 if {$r1 == $r2} {
8179 selectline $r1 1
8180 break
8181 }
8182 if {$r1 > $r2} {
8183 set l1 [replace_by_kids $l1 $r1]
8184 } else {
8185 set l2 [replace_by_kids $l2 $r2]
8186 }
8187 }
8188 #set t2 [clock clicks -milliseconds]
8189 #puts "took [expr {$t2-$t1}]ms"
8190}
8191
Paul Mackerras010509f2009-04-09 12:10:208192proc compare_commits {} {
8193 global markedid rowmenuid curview children
8194
8195 if {![info exists markedid]} return
8196 if {![commitinview $markedid $curview]} return
8197 addtohistory [list do_cmp_commits $markedid $rowmenuid]
8198 do_cmp_commits $markedid $rowmenuid
8199}
8200
8201proc getpatchid {id} {
8202 global patchids
8203
8204 if {![info exists patchids($id)]} {
Paul Mackerras6f63fc12009-04-21 12:22:318205 set cmd [diffcmd [list $id] {-p --root}]
8206 # trim off the initial "|"
8207 set cmd [lrange $cmd 1 end]
8208 if {[catch {
8209 set x [eval exec $cmd | git patch-id]
8210 set patchids($id) [lindex $x 0]
8211 }]} {
8212 set patchids($id) "error"
8213 }
Paul Mackerras010509f2009-04-09 12:10:208214 }
8215 return $patchids($id)
8216}
8217
8218proc do_cmp_commits {a b} {
8219 global ctext curview parents children patchids commitinfo
8220
8221 $ctext conf -state normal
8222 clear_ctext
8223 init_flist {}
8224 for {set i 0} {$i < 100} {incr i} {
Paul Mackerras010509f2009-04-09 12:10:208225 set skipa 0
8226 set skipb 0
8227 if {[llength $parents($curview,$a)] > 1} {
Paul Mackerras6f63fc12009-04-21 12:22:318228 appendshortlink $a [mc "Skipping merge commit "] "\n"
Paul Mackerras010509f2009-04-09 12:10:208229 set skipa 1
8230 } else {
8231 set patcha [getpatchid $a]
8232 }
8233 if {[llength $parents($curview,$b)] > 1} {
Paul Mackerras6f63fc12009-04-21 12:22:318234 appendshortlink $b [mc "Skipping merge commit "] "\n"
Paul Mackerras010509f2009-04-09 12:10:208235 set skipb 1
8236 } else {
8237 set patchb [getpatchid $b]
8238 }
8239 if {!$skipa && !$skipb} {
8240 set heada [lindex $commitinfo($a) 0]
8241 set headb [lindex $commitinfo($b) 0]
Paul Mackerras6f63fc12009-04-21 12:22:318242 if {$patcha eq "error"} {
8243 appendshortlink $a [mc "Error getting patch ID for "] \
8244 [mc " - stopping\n"]
8245 break
8246 }
8247 if {$patchb eq "error"} {
8248 appendshortlink $b [mc "Error getting patch ID for "] \
8249 [mc " - stopping\n"]
8250 break
8251 }
Paul Mackerras010509f2009-04-09 12:10:208252 if {$patcha eq $patchb} {
8253 if {$heada eq $headb} {
Paul Mackerras6f63fc12009-04-21 12:22:318254 appendshortlink $a [mc "Commit "]
8255 appendshortlink $b " == " " $heada\n"
Paul Mackerras010509f2009-04-09 12:10:208256 } else {
Paul Mackerras6f63fc12009-04-21 12:22:318257 appendshortlink $a [mc "Commit "] " $heada\n"
8258 appendshortlink $b [mc " is the same patch as\n "] \
8259 " $headb\n"
Paul Mackerras010509f2009-04-09 12:10:208260 }
8261 set skipa 1
8262 set skipb 1
8263 } else {
8264 $ctext insert end "\n"
Paul Mackerras6f63fc12009-04-21 12:22:318265 appendshortlink $a [mc "Commit "] " $heada\n"
8266 appendshortlink $b [mc " differs from\n "] \
8267 " $headb\n"
8268 $ctext insert end [mc "- stopping\n"]
Paul Mackerras010509f2009-04-09 12:10:208269 break
8270 }
8271 }
8272 if {$skipa} {
8273 if {[llength $children($curview,$a)] != 1} {
8274 $ctext insert end "\n"
Paul Mackerras6f63fc12009-04-21 12:22:318275 appendshortlink $a [mc "Commit "] \
8276 [mc " has %s children - stopping\n" \
8277 [llength $children($curview,$a)]]
Paul Mackerras010509f2009-04-09 12:10:208278 break
8279 }
8280 set a [lindex $children($curview,$a) 0]
8281 }
8282 if {$skipb} {
8283 if {[llength $children($curview,$b)] != 1} {
Paul Mackerras6f63fc12009-04-21 12:22:318284 appendshortlink $b [mc "Commit "] \
8285 [mc " has %s children - stopping\n" \
8286 [llength $children($curview,$b)]]
Paul Mackerras010509f2009-04-09 12:10:208287 break
8288 }
8289 set b [lindex $children($curview,$b) 0]
8290 }
8291 }
8292 $ctext conf -state disabled
8293}
8294
Paul Mackerrasc8dfbcf2005-06-25 05:39:218295proc diffvssel {dirn} {
Paul Mackerras7fcc92b2007-12-02 23:33:018296 global rowmenuid selectedline
Paul Mackerrasc8dfbcf2005-06-25 05:39:218297
Paul Mackerras94b4a692008-05-20 10:51:068298 if {$selectedline eq {}} return
Paul Mackerrasc8dfbcf2005-06-25 05:39:218299 if {$dirn} {
Paul Mackerras7fcc92b2007-12-02 23:33:018300 set oldid [commitonrow $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 05:39:218301 set newid $rowmenuid
8302 } else {
8303 set oldid $rowmenuid
Paul Mackerras7fcc92b2007-12-02 23:33:018304 set newid [commitonrow $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 05:39:218305 }
Paul Mackerrasfa4da7b2005-08-07 23:47:228306 addtohistory [list doseldiff $oldid $newid]
8307 doseldiff $oldid $newid
8308}
8309
8310proc doseldiff {oldid newid} {
Paul Mackerras7fcceed2006-04-27 09:21:498311 global ctext
Paul Mackerrasfa4da7b2005-08-07 23:47:228312 global commitinfo
8313
Paul Mackerrasc8dfbcf2005-06-25 05:39:218314 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 00:16:038315 clear_ctext
Christian Stimmingd990ced2007-11-07 17:42:558316 init_flist [mc "Top"]
8317 $ctext insert end "[mc "From"] "
Paul Mackerras97645682007-08-23 12:24:388318 $ctext insert end $oldid link0
8319 setlink $oldid link0
Paul Mackerrasfa4da7b2005-08-07 23:47:228320 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 05:39:218321 $ctext insert end [lindex $commitinfo($oldid) 0]
Christian Stimmingd990ced2007-11-07 17:42:558322 $ctext insert end "\n\n[mc "To"] "
Paul Mackerras97645682007-08-23 12:24:388323 $ctext insert end $newid link1
8324 setlink $newid link1
Paul Mackerrasfa4da7b2005-08-07 23:47:228325 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 05:39:218326 $ctext insert end [lindex $commitinfo($newid) 0]
8327 $ctext insert end "\n"
8328 $ctext conf -state disabled
Paul Mackerrasc8dfbcf2005-06-25 05:39:218329 $ctext tag remove found 1.0 end
Paul Mackerrasd3272442005-11-28 09:41:568330 startdiff [list $oldid $newid]
Paul Mackerrasc8dfbcf2005-06-25 05:39:218331}
8332
Paul Mackerras74daedb2005-06-27 09:27:328333proc mkpatch {} {
8334 global rowmenuid currentid commitinfo patchtop patchnum
8335
8336 if {![info exists currentid]} return
8337 set oldid $currentid
8338 set oldhead [lindex $commitinfo($oldid) 0]
8339 set newid $rowmenuid
8340 set newhead [lindex $commitinfo($newid) 0]
8341 set top .patch
8342 set patchtop $top
8343 catch {destroy $top}
8344 toplevel $top
Alexander Gavrilove7d64002008-11-11 20:55:428345 make_transient $top .
Christian Stimmingd990ced2007-11-07 17:42:558346 label $top.title -text [mc "Generate patch"]
Paul Mackerras4a2139f2005-06-28 23:47:488347 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 17:42:558348 label $top.from -text [mc "From:"]
Paul Mackerras4a2139f2005-06-28 23:47:488349 entry $top.fromsha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:328350 $top.fromsha1 insert 0 $oldid
8351 $top.fromsha1 conf -state readonly
8352 grid $top.from $top.fromsha1 -sticky w
Paul Mackerras4a2139f2005-06-28 23:47:488353 entry $top.fromhead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:328354 $top.fromhead insert 0 $oldhead
8355 $top.fromhead conf -state readonly
8356 grid x $top.fromhead -sticky w
Christian Stimmingd990ced2007-11-07 17:42:558357 label $top.to -text [mc "To:"]
Paul Mackerras4a2139f2005-06-28 23:47:488358 entry $top.tosha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:328359 $top.tosha1 insert 0 $newid
8360 $top.tosha1 conf -state readonly
8361 grid $top.to $top.tosha1 -sticky w
Paul Mackerras4a2139f2005-06-28 23:47:488362 entry $top.tohead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 09:27:328363 $top.tohead insert 0 $newhead
8364 $top.tohead conf -state readonly
8365 grid x $top.tohead -sticky w
Christian Stimmingd990ced2007-11-07 17:42:558366 button $top.rev -text [mc "Reverse"] -command mkpatchrev -padx 5
Paul Mackerras74daedb2005-06-27 09:27:328367 grid $top.rev x -pady 10
Christian Stimmingd990ced2007-11-07 17:42:558368 label $top.flab -text [mc "Output file:"]
Paul Mackerras74daedb2005-06-27 09:27:328369 entry $top.fname -width 60
8370 $top.fname insert 0 [file normalize "patch$patchnum.patch"]
8371 incr patchnum
Paul Mackerrasbdbfbe32005-06-27 12:56:408372 grid $top.flab $top.fname -sticky w
Paul Mackerras74daedb2005-06-27 09:27:328373 frame $top.buts
Christian Stimmingd990ced2007-11-07 17:42:558374 button $top.buts.gen -text [mc "Generate"] -command mkpatchgo
8375 button $top.buts.can -text [mc "Cancel"] -command mkpatchcan
Alexander Gavrilov76f15942008-11-02 18:59:448376 bind $top <Key-Return> mkpatchgo
8377 bind $top <Key-Escape> mkpatchcan
Paul Mackerras74daedb2005-06-27 09:27:328378 grid $top.buts.gen $top.buts.can
8379 grid columnconfigure $top.buts 0 -weight 1 -uniform a
8380 grid columnconfigure $top.buts 1 -weight 1 -uniform a
8381 grid $top.buts - -pady 10 -sticky ew
Paul Mackerrasbdbfbe32005-06-27 12:56:408382 focus $top.fname
Paul Mackerras74daedb2005-06-27 09:27:328383}
8384
8385proc mkpatchrev {} {
8386 global patchtop
8387
8388 set oldid [$patchtop.fromsha1 get]
8389 set oldhead [$patchtop.fromhead get]
8390 set newid [$patchtop.tosha1 get]
8391 set newhead [$patchtop.tohead get]
8392 foreach e [list fromsha1 fromhead tosha1 tohead] \
8393 v [list $newid $newhead $oldid $oldhead] {
8394 $patchtop.$e conf -state normal
8395 $patchtop.$e delete 0 end
8396 $patchtop.$e insert 0 $v
8397 $patchtop.$e conf -state readonly
8398 }
8399}
8400
8401proc mkpatchgo {} {
Paul Mackerras8f489362007-07-13 09:49:378402 global patchtop nullid nullid2
Paul Mackerras74daedb2005-06-27 09:27:328403
8404 set oldid [$patchtop.fromsha1 get]
8405 set newid [$patchtop.tosha1 get]
8406 set fname [$patchtop.fname get]
Paul Mackerras8f489362007-07-13 09:49:378407 set cmd [diffcmd [list $oldid $newid] -p]
Paul Mackerrasd372e212007-09-15 02:08:388408 # trim off the initial "|"
8409 set cmd [lrange $cmd 1 end]
Paul Mackerras219ea3a2006-09-07 00:21:398410 lappend cmd >$fname &
8411 if {[catch {eval exec $cmd} err]} {
Alexander Gavrilov84a76f12008-11-02 18:59:458412 error_popup "[mc "Error creating patch:"] $err" $patchtop
Paul Mackerras74daedb2005-06-27 09:27:328413 }
8414 catch {destroy $patchtop}
8415 unset patchtop
8416}
8417
8418proc mkpatchcan {} {
8419 global patchtop
8420
8421 catch {destroy $patchtop}
8422 unset patchtop
8423}
8424
Paul Mackerrasbdbfbe32005-06-27 12:56:408425proc mktag {} {
8426 global rowmenuid mktagtop commitinfo
8427
8428 set top .maketag
8429 set mktagtop $top
8430 catch {destroy $top}
8431 toplevel $top
Alexander Gavrilove7d64002008-11-11 20:55:428432 make_transient $top .
Christian Stimmingd990ced2007-11-07 17:42:558433 label $top.title -text [mc "Create tag"]
Paul Mackerras4a2139f2005-06-28 23:47:488434 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 17:42:558435 label $top.id -text [mc "ID:"]
Paul Mackerras4a2139f2005-06-28 23:47:488436 entry $top.sha1 -width 40 -relief flat
Paul Mackerrasbdbfbe32005-06-27 12:56:408437 $top.sha1 insert 0 $rowmenuid
8438 $top.sha1 conf -state readonly
8439 grid $top.id $top.sha1 -sticky w
Paul Mackerras4a2139f2005-06-28 23:47:488440 entry $top.head -width 60 -relief flat
Paul Mackerrasbdbfbe32005-06-27 12:56:408441 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
8442 $top.head conf -state readonly
8443 grid x $top.head -sticky w
Christian Stimmingd990ced2007-11-07 17:42:558444 label $top.tlab -text [mc "Tag name:"]
Paul Mackerras4a2139f2005-06-28 23:47:488445 entry $top.tag -width 60
Paul Mackerrasbdbfbe32005-06-27 12:56:408446 grid $top.tlab $top.tag -sticky w
8447 frame $top.buts
Christian Stimmingd990ced2007-11-07 17:42:558448 button $top.buts.gen -text [mc "Create"] -command mktaggo
8449 button $top.buts.can -text [mc "Cancel"] -command mktagcan
Alexander Gavrilov76f15942008-11-02 18:59:448450 bind $top <Key-Return> mktaggo
8451 bind $top <Key-Escape> mktagcan
Paul Mackerrasbdbfbe32005-06-27 12:56:408452 grid $top.buts.gen $top.buts.can
8453 grid columnconfigure $top.buts 0 -weight 1 -uniform a
8454 grid columnconfigure $top.buts 1 -weight 1 -uniform a
8455 grid $top.buts - -pady 10 -sticky ew
8456 focus $top.tag
8457}
8458
8459proc domktag {} {
8460 global mktagtop env tagids idtags
Paul Mackerrasbdbfbe32005-06-27 12:56:408461
8462 set id [$mktagtop.sha1 get]
8463 set tag [$mktagtop.tag get]
8464 if {$tag == {}} {
Alexander Gavrilov84a76f12008-11-02 18:59:458465 error_popup [mc "No tag name specified"] $mktagtop
8466 return 0
Paul Mackerrasbdbfbe32005-06-27 12:56:408467 }
8468 if {[info exists tagids($tag)]} {
Alexander Gavrilov84a76f12008-11-02 18:59:458469 error_popup [mc "Tag \"%s\" already exists" $tag] $mktagtop
8470 return 0
Paul Mackerrasbdbfbe32005-06-27 12:56:408471 }
8472 if {[catch {
Gerrit Pape48750d62008-02-11 10:57:408473 exec git tag $tag $id
Paul Mackerrasbdbfbe32005-06-27 12:56:408474 } err]} {
Alexander Gavrilov84a76f12008-11-02 18:59:458475 error_popup "[mc "Error creating tag:"] $err" $mktagtop
8476 return 0
Paul Mackerrasbdbfbe32005-06-27 12:56:408477 }
8478
8479 set tagids($tag) $id
8480 lappend idtags($id) $tag
Paul Mackerrasf1d83ba2005-08-19 12:14:288481 redrawtags $id
Paul Mackerrasceadfe92006-08-08 10:55:368482 addedtag $id
Paul Mackerras887c9962007-08-20 09:36:208483 dispneartags 0
8484 run refill_reflist
Alexander Gavrilov84a76f12008-11-02 18:59:458485 return 1
Paul Mackerrasf1d83ba2005-08-19 12:14:288486}
8487
8488proc redrawtags {id} {
Paul Mackerrasb9fdba72009-04-08 23:34:468489 global canv linehtag idpos currentid curview cmitlisted markedid
Paul Mackerrasc11ff122008-05-26 00:11:338490 global canvxmax iddrawn circleitem mainheadid circlecolors
Paul Mackerrasf1d83ba2005-08-19 12:14:288491
Paul Mackerras7fcc92b2007-12-02 23:33:018492 if {![commitinview $id $curview]} return
Paul Mackerras322a8cc2006-10-15 08:03:468493 if {![info exists iddrawn($id)]} return
Paul Mackerrasfc2a2562007-12-26 12:03:438494 set row [rowofcommit $id]
Paul Mackerrasc11ff122008-05-26 00:11:338495 if {$id eq $mainheadid} {
8496 set ofill yellow
8497 } else {
8498 set ofill [lindex $circlecolors $cmitlisted($curview,$id)]
8499 }
8500 $canv itemconf $circleitem($row) -fill $ofill
Paul Mackerrasbdbfbe32005-06-27 12:56:408501 $canv delete tag.$id
8502 set xt [eval drawtags $id $idpos($id)]
Paul Mackerras28593d32008-11-13 12:01:468503 $canv coords $linehtag($id) $xt [lindex $idpos($id) 2]
8504 set text [$canv itemcget $linehtag($id) -text]
8505 set font [$canv itemcget $linehtag($id) -font]
Paul Mackerrasfc2a2562007-12-26 12:03:438506 set xr [expr {$xt + [font measure $font $text]}]
Paul Mackerrasb8ab2e12006-06-03 09:11:138507 if {$xr > $canvxmax} {
8508 set canvxmax $xr
8509 setcanvscroll
8510 }
Paul Mackerrasfc2a2562007-12-26 12:03:438511 if {[info exists currentid] && $currentid == $id} {
Paul Mackerras28593d32008-11-13 12:01:468512 make_secsel $id
Paul Mackerrasbdbfbe32005-06-27 12:56:408513 }
Paul Mackerrasb9fdba72009-04-08 23:34:468514 if {[info exists markedid] && $markedid eq $id} {
8515 make_idmark $id
8516 }
Paul Mackerrasbdbfbe32005-06-27 12:56:408517}
8518
8519proc mktagcan {} {
8520 global mktagtop
8521
8522 catch {destroy $mktagtop}
8523 unset mktagtop
8524}
8525
8526proc mktaggo {} {
Alexander Gavrilov84a76f12008-11-02 18:59:458527 if {![domktag]} return
Paul Mackerrasbdbfbe32005-06-27 12:56:408528 mktagcan
8529}
8530
Paul Mackerras4a2139f2005-06-28 23:47:488531proc writecommit {} {
8532 global rowmenuid wrcomtop commitinfo wrcomcmd
8533
8534 set top .writecommit
8535 set wrcomtop $top
8536 catch {destroy $top}
8537 toplevel $top
Alexander Gavrilove7d64002008-11-11 20:55:428538 make_transient $top .
Christian Stimmingd990ced2007-11-07 17:42:558539 label $top.title -text [mc "Write commit to file"]
Paul Mackerras4a2139f2005-06-28 23:47:488540 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 17:42:558541 label $top.id -text [mc "ID:"]
Paul Mackerras4a2139f2005-06-28 23:47:488542 entry $top.sha1 -width 40 -relief flat
8543 $top.sha1 insert 0 $rowmenuid
8544 $top.sha1 conf -state readonly
8545 grid $top.id $top.sha1 -sticky w
8546 entry $top.head -width 60 -relief flat
8547 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
8548 $top.head conf -state readonly
8549 grid x $top.head -sticky w
Christian Stimmingd990ced2007-11-07 17:42:558550 label $top.clab -text [mc "Command:"]
Paul Mackerras4a2139f2005-06-28 23:47:488551 entry $top.cmd -width 60 -textvariable wrcomcmd
8552 grid $top.clab $top.cmd -sticky w -pady 10
Christian Stimmingd990ced2007-11-07 17:42:558553 label $top.flab -text [mc "Output file:"]
Paul Mackerras4a2139f2005-06-28 23:47:488554 entry $top.fname -width 60
8555 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
8556 grid $top.flab $top.fname -sticky w
8557 frame $top.buts
Christian Stimmingd990ced2007-11-07 17:42:558558 button $top.buts.gen -text [mc "Write"] -command wrcomgo
8559 button $top.buts.can -text [mc "Cancel"] -command wrcomcan
Alexander Gavrilov76f15942008-11-02 18:59:448560 bind $top <Key-Return> wrcomgo
8561 bind $top <Key-Escape> wrcomcan
Paul Mackerras4a2139f2005-06-28 23:47:488562 grid $top.buts.gen $top.buts.can
8563 grid columnconfigure $top.buts 0 -weight 1 -uniform a
8564 grid columnconfigure $top.buts 1 -weight 1 -uniform a
8565 grid $top.buts - -pady 10 -sticky ew
8566 focus $top.fname
8567}
8568
8569proc wrcomgo {} {
8570 global wrcomtop
8571
8572 set id [$wrcomtop.sha1 get]
8573 set cmd "echo $id | [$wrcomtop.cmd get]"
8574 set fname [$wrcomtop.fname get]
8575 if {[catch {exec sh -c $cmd >$fname &} err]} {
Alexander Gavrilov84a76f12008-11-02 18:59:458576 error_popup "[mc "Error writing commit:"] $err" $wrcomtop
Paul Mackerras4a2139f2005-06-28 23:47:488577 }
8578 catch {destroy $wrcomtop}
8579 unset wrcomtop
8580}
8581
8582proc wrcomcan {} {
8583 global wrcomtop
8584
8585 catch {destroy $wrcomtop}
8586 unset wrcomtop
8587}
8588
Paul Mackerrasd6ac1a82006-08-01 23:41:048589proc mkbranch {} {
8590 global rowmenuid mkbrtop
8591
8592 set top .makebranch
8593 catch {destroy $top}
8594 toplevel $top
Alexander Gavrilove7d64002008-11-11 20:55:428595 make_transient $top .
Christian Stimmingd990ced2007-11-07 17:42:558596 label $top.title -text [mc "Create new branch"]
Paul Mackerrasd6ac1a82006-08-01 23:41:048597 grid $top.title - -pady 10
Christian Stimmingd990ced2007-11-07 17:42:558598 label $top.id -text [mc "ID:"]
Paul Mackerrasd6ac1a82006-08-01 23:41:048599 entry $top.sha1 -width 40 -relief flat
8600 $top.sha1 insert 0 $rowmenuid
8601 $top.sha1 conf -state readonly
8602 grid $top.id $top.sha1 -sticky w
Christian Stimmingd990ced2007-11-07 17:42:558603 label $top.nlab -text [mc "Name:"]
Paul Mackerrasd6ac1a82006-08-01 23:41:048604 entry $top.name -width 40
8605 grid $top.nlab $top.name -sticky w
8606 frame $top.buts
Christian Stimmingd990ced2007-11-07 17:42:558607 button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top]
8608 button $top.buts.can -text [mc "Cancel"] -command "catch {destroy $top}"
Alexander Gavrilov76f15942008-11-02 18:59:448609 bind $top <Key-Return> [list mkbrgo $top]
8610 bind $top <Key-Escape> "catch {destroy $top}"
Paul Mackerrasd6ac1a82006-08-01 23:41:048611 grid $top.buts.go $top.buts.can
8612 grid columnconfigure $top.buts 0 -weight 1 -uniform a
8613 grid columnconfigure $top.buts 1 -weight 1 -uniform a
8614 grid $top.buts - -pady 10 -sticky ew
8615 focus $top.name
8616}
8617
8618proc mkbrgo {top} {
8619 global headids idheads
8620
8621 set name [$top.name get]
8622 set id [$top.sha1 get]
Alexander Gavrilovbee866f2008-10-08 07:05:358623 set cmdargs {}
8624 set old_id {}
Paul Mackerrasd6ac1a82006-08-01 23:41:048625 if {$name eq {}} {
Alexander Gavrilov84a76f12008-11-02 18:59:458626 error_popup [mc "Please specify a name for the new branch"] $top
Paul Mackerrasd6ac1a82006-08-01 23:41:048627 return
8628 }
Alexander Gavrilovbee866f2008-10-08 07:05:358629 if {[info exists headids($name)]} {
8630 if {![confirm_popup [mc \
Alexander Gavrilov84a76f12008-11-02 18:59:458631 "Branch '%s' already exists. Overwrite?" $name] $top]} {
Alexander Gavrilovbee866f2008-10-08 07:05:358632 return
8633 }
8634 set old_id $headids($name)
8635 lappend cmdargs -f
8636 }
Paul Mackerrasd6ac1a82006-08-01 23:41:048637 catch {destroy $top}
Alexander Gavrilovbee866f2008-10-08 07:05:358638 lappend cmdargs $name $id
Paul Mackerrasd6ac1a82006-08-01 23:41:048639 nowbusy newbranch
8640 update
8641 if {[catch {
Alexander Gavrilovbee866f2008-10-08 07:05:358642 eval exec git branch $cmdargs
Paul Mackerrasd6ac1a82006-08-01 23:41:048643 } err]} {
8644 notbusy newbranch
8645 error_popup $err
8646 } else {
Paul Mackerrasd6ac1a82006-08-01 23:41:048647 notbusy newbranch
Alexander Gavrilovbee866f2008-10-08 07:05:358648 if {$old_id ne {}} {
8649 movehead $id $name
8650 movedhead $id $name
8651 redrawtags $old_id
8652 redrawtags $id
8653 } else {
8654 set headids($name) $id
8655 lappend idheads($id) $name
8656 addedhead $id $name
8657 redrawtags $id
8658 }
Paul Mackerrase11f1232007-06-16 10:29:258659 dispneartags 0
Paul Mackerras887c9962007-08-20 09:36:208660 run refill_reflist
Paul Mackerrasd6ac1a82006-08-01 23:41:048661 }
8662}
8663
Alexander Gavrilov15e35052008-11-02 18:59:478664proc exec_citool {tool_args {baseid {}}} {
8665 global commitinfo env
8666
8667 set save_env [array get env GIT_AUTHOR_*]
8668
8669 if {$baseid ne {}} {
8670 if {![info exists commitinfo($baseid)]} {
8671 getcommit $baseid
8672 }
8673 set author [lindex $commitinfo($baseid) 1]
8674 set date [lindex $commitinfo($baseid) 2]
8675 if {[regexp {^\s*(\S.*\S|\S)\s*<(.*)>\s*$} \
8676 $author author name email]
8677 && $date ne {}} {
8678 set env(GIT_AUTHOR_NAME) $name
8679 set env(GIT_AUTHOR_EMAIL) $email
8680 set env(GIT_AUTHOR_DATE) $date
8681 }
8682 }
8683
8684 eval exec git citool $tool_args &
8685
8686 array unset env GIT_AUTHOR_*
8687 array set env $save_env
8688}
8689
Paul Mackerrasca6d8f52006-08-06 11:08:058690proc cherrypick {} {
Paul Mackerras468bcae2008-03-02 23:19:358691 global rowmenuid curview
Paul Mackerrasb8a938c2008-02-13 11:12:318692 global mainhead mainheadid
Paul Mackerrasca6d8f52006-08-06 11:08:058693
Paul Mackerrase11f1232007-06-16 10:29:258694 set oldhead [exec git rev-parse HEAD]
8695 set dheads [descheads $rowmenuid]
8696 if {$dheads ne {} && [lsearch -exact $dheads $oldhead] >= 0} {
Christian Stimmingd990ced2007-11-07 17:42:558697 set ok [confirm_popup [mc "Commit %s is already\
8698 included in branch %s -- really re-apply it?" \
8699 [string range $rowmenuid 0 7] $mainhead]]
Paul Mackerrasca6d8f52006-08-06 11:08:058700 if {!$ok} return
8701 }
Christian Stimmingd990ced2007-11-07 17:42:558702 nowbusy cherrypick [mc "Cherry-picking"]
Paul Mackerrasca6d8f52006-08-06 11:08:058703 update
Paul Mackerrasca6d8f52006-08-06 11:08:058704 # Unfortunately git-cherry-pick writes stuff to stderr even when
8705 # no error occurs, and exec takes that as an indication of error...
8706 if {[catch {exec sh -c "git cherry-pick -r $rowmenuid 2>&1"} err]} {
8707 notbusy cherrypick
Alexander Gavrilov15e35052008-11-02 18:59:478708 if {[regexp -line \
Paul Mackerras887a7912008-11-08 10:37:098709 {Entry '(.*)' (would be overwritten by merge|not uptodate)} \
8710 $err msg fname]} {
8711 error_popup [mc "Cherry-pick failed because of local changes\
8712 to file '%s'.\nPlease commit, reset or stash\
8713 your changes and try again." $fname]
8714 } elseif {[regexp -line \
8715 {^(CONFLICT \(.*\):|Automatic cherry-pick failed)} \
8716 $err]} {
8717 if {[confirm_popup [mc "Cherry-pick failed because of merge\
8718 conflict.\nDo you wish to run git citool to\
8719 resolve it?"]]} {
8720 # Force citool to read MERGE_MSG
8721 file delete [file join [gitdir] "GITGUI_MSG"]
8722 exec_citool {} $rowmenuid
8723 }
Alexander Gavrilov15e35052008-11-02 18:59:478724 } else {
8725 error_popup $err
8726 }
Paul Mackerras887a7912008-11-08 10:37:098727 run updatecommits
Paul Mackerrasca6d8f52006-08-06 11:08:058728 return
8729 }
8730 set newhead [exec git rev-parse HEAD]
8731 if {$newhead eq $oldhead} {
8732 notbusy cherrypick
Christian Stimmingd990ced2007-11-07 17:42:558733 error_popup [mc "No changes committed"]
Paul Mackerrasca6d8f52006-08-06 11:08:058734 return
8735 }
Paul Mackerrase11f1232007-06-16 10:29:258736 addnewchild $newhead $oldhead
Paul Mackerras7fcc92b2007-12-02 23:33:018737 if {[commitinview $oldhead $curview]} {
Paul Mackerrascdc84292008-11-18 08:54:148738 # XXX this isn't right if we have a path limit...
Paul Mackerras7fcc92b2007-12-02 23:33:018739 insertrow $newhead $oldhead $curview
Paul Mackerrasca6d8f52006-08-06 11:08:058740 if {$mainhead ne {}} {
Paul Mackerrase11f1232007-06-16 10:29:258741 movehead $newhead $mainhead
Paul Mackerrasca6d8f52006-08-06 11:08:058742 movedhead $newhead $mainhead
8743 }
Paul Mackerrasc11ff122008-05-26 00:11:338744 set mainheadid $newhead
Paul Mackerrasca6d8f52006-08-06 11:08:058745 redrawtags $oldhead
8746 redrawtags $newhead
Paul Mackerras46308ea2008-01-15 11:16:328747 selbyid $newhead
Paul Mackerrasca6d8f52006-08-06 11:08:058748 }
8749 notbusy cherrypick
8750}
8751
Paul Mackerras6fb735a2006-10-19 00:09:068752proc resethead {} {
Paul Mackerrasb8a938c2008-02-13 11:12:318753 global mainhead rowmenuid confirm_ok resettype
Paul Mackerras6fb735a2006-10-19 00:09:068754
8755 set confirm_ok 0
8756 set w ".confirmreset"
8757 toplevel $w
Alexander Gavrilove7d64002008-11-11 20:55:428758 make_transient $w .
Christian Stimmingd990ced2007-11-07 17:42:558759 wm title $w [mc "Confirm reset"]
Paul Mackerras6fb735a2006-10-19 00:09:068760 message $w.m -text \
Christian Stimmingd990ced2007-11-07 17:42:558761 [mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]] \
Paul Mackerras6fb735a2006-10-19 00:09:068762 -justify center -aspect 1000
8763 pack $w.m -side top -fill x -padx 20 -pady 20
8764 frame $w.f -relief sunken -border 2
Christian Stimmingd990ced2007-11-07 17:42:558765 message $w.f.rt -text [mc "Reset type:"] -aspect 1000
Paul Mackerras6fb735a2006-10-19 00:09:068766 grid $w.f.rt -sticky w
8767 set resettype mixed
8768 radiobutton $w.f.soft -value soft -variable resettype -justify left \
Christian Stimmingd990ced2007-11-07 17:42:558769 -text [mc "Soft: Leave working tree and index untouched"]
Paul Mackerras6fb735a2006-10-19 00:09:068770 grid $w.f.soft -sticky w
8771 radiobutton $w.f.mixed -value mixed -variable resettype -justify left \
Christian Stimmingd990ced2007-11-07 17:42:558772 -text [mc "Mixed: Leave working tree untouched, reset index"]
Paul Mackerras6fb735a2006-10-19 00:09:068773 grid $w.f.mixed -sticky w
8774 radiobutton $w.f.hard -value hard -variable resettype -justify left \
Christian Stimmingd990ced2007-11-07 17:42:558775 -text [mc "Hard: Reset working tree and index\n(discard ALL local changes)"]
Paul Mackerras6fb735a2006-10-19 00:09:068776 grid $w.f.hard -sticky w
8777 pack $w.f -side top -fill x
Christian Stimmingd990ced2007-11-07 17:42:558778 button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
Paul Mackerras6fb735a2006-10-19 00:09:068779 pack $w.ok -side left -fill x -padx 20 -pady 20
Christian Stimmingd990ced2007-11-07 17:42:558780 button $w.cancel -text [mc Cancel] -command "destroy $w"
Alexander Gavrilov76f15942008-11-02 18:59:448781 bind $w <Key-Escape> [list destroy $w]
Paul Mackerras6fb735a2006-10-19 00:09:068782 pack $w.cancel -side right -fill x -padx 20 -pady 20
8783 bind $w <Visibility> "grab $w; focus $w"
8784 tkwait window $w
8785 if {!$confirm_ok} return
Paul Mackerras706d6c32007-06-26 01:09:498786 if {[catch {set fd [open \
Paul Mackerras08ba8202008-05-12 00:18:388787 [list | git reset --$resettype $rowmenuid 2>@1] r]} err]} {
Paul Mackerras6fb735a2006-10-19 00:09:068788 error_popup $err
8789 } else {
Paul Mackerras706d6c32007-06-26 01:09:498790 dohidelocalchanges
Paul Mackerrasa137a902007-10-23 11:12:498791 filerun $fd [list readresetstat $fd]
Christian Stimmingd990ced2007-11-07 17:42:558792 nowbusy reset [mc "Resetting"]
Paul Mackerras46308ea2008-01-15 11:16:328793 selbyid $rowmenuid
Paul Mackerras706d6c32007-06-26 01:09:498794 }
8795}
8796
Paul Mackerrasa137a902007-10-23 11:12:498797proc readresetstat {fd} {
8798 global mainhead mainheadid showlocalchanges rprogcoord
Paul Mackerras706d6c32007-06-26 01:09:498799
8800 if {[gets $fd line] >= 0} {
8801 if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
Paul Mackerrasa137a902007-10-23 11:12:498802 set rprogcoord [expr {1.0 * $m / $n}]
8803 adjustprogress
Paul Mackerras706d6c32007-06-26 01:09:498804 }
8805 return 1
8806 }
Paul Mackerrasa137a902007-10-23 11:12:498807 set rprogcoord 0
8808 adjustprogress
Paul Mackerras706d6c32007-06-26 01:09:498809 notbusy reset
8810 if {[catch {close $fd} err]} {
8811 error_popup $err
8812 }
8813 set oldhead $mainheadid
8814 set newhead [exec git rev-parse HEAD]
8815 if {$newhead ne $oldhead} {
8816 movehead $newhead $mainhead
8817 movedhead $newhead $mainhead
8818 set mainheadid $newhead
Paul Mackerras6fb735a2006-10-19 00:09:068819 redrawtags $oldhead
Paul Mackerras706d6c32007-06-26 01:09:498820 redrawtags $newhead
Paul Mackerras6fb735a2006-10-19 00:09:068821 }
8822 if {$showlocalchanges} {
8823 doshowlocalchanges
8824 }
Paul Mackerras706d6c32007-06-26 01:09:498825 return 0
Paul Mackerras6fb735a2006-10-19 00:09:068826}
8827
Paul Mackerras10299152006-08-01 23:52:018828# context menu for a head
8829proc headmenu {x y id head} {
Paul Mackerras00609462007-06-17 07:08:358830 global headmenuid headmenuhead headctxmenu mainhead
Paul Mackerras10299152006-08-01 23:52:018831
Paul Mackerrasbb3edc82007-09-27 01:00:258832 stopfinding
Paul Mackerras10299152006-08-01 23:52:018833 set headmenuid $id
8834 set headmenuhead $head
Paul Mackerras00609462007-06-17 07:08:358835 set state normal
8836 if {$head eq $mainhead} {
8837 set state disabled
8838 }
8839 $headctxmenu entryconfigure 0 -state $state
8840 $headctxmenu entryconfigure 1 -state $state
Paul Mackerras10299152006-08-01 23:52:018841 tk_popup $headctxmenu $x $y
8842}
8843
8844proc cobranch {} {
Paul Mackerrasc11ff122008-05-26 00:11:338845 global headmenuid headmenuhead headids
Paul Mackerrascdc84292008-11-18 08:54:148846 global showlocalchanges
Paul Mackerras10299152006-08-01 23:52:018847
8848 # check the tree is clean first??
Christian Stimmingd990ced2007-11-07 17:42:558849 nowbusy checkout [mc "Checking out"]
Paul Mackerras10299152006-08-01 23:52:018850 update
Paul Mackerras219ea3a2006-09-07 00:21:398851 dohidelocalchanges
Paul Mackerras10299152006-08-01 23:52:018852 if {[catch {
Paul Mackerras08ba8202008-05-12 00:18:388853 set fd [open [list | git checkout $headmenuhead 2>@1] r]
Paul Mackerras10299152006-08-01 23:52:018854 } err]} {
8855 notbusy checkout
8856 error_popup $err
Paul Mackerras08ba8202008-05-12 00:18:388857 if {$showlocalchanges} {
8858 dodiffindex
Paul Mackerras10299152006-08-01 23:52:018859 }
Paul Mackerras08ba8202008-05-12 00:18:388860 } else {
8861 filerun $fd [list readcheckoutstat $fd $headmenuhead $headmenuid]
Paul Mackerras6fb735a2006-10-19 00:09:068862 }
Paul Mackerras08ba8202008-05-12 00:18:388863}
8864
8865proc readcheckoutstat {fd newhead newheadid} {
8866 global mainhead mainheadid headids showlocalchanges progresscoords
Paul Mackerrascdc84292008-11-18 08:54:148867 global viewmainheadid curview
Paul Mackerras08ba8202008-05-12 00:18:388868
8869 if {[gets $fd line] >= 0} {
8870 if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
8871 set progresscoords [list 0 [expr {1.0 * $m / $n}]]
8872 adjustprogress
8873 }
8874 return 1
8875 }
8876 set progresscoords {0 0}
8877 adjustprogress
8878 notbusy checkout
8879 if {[catch {close $fd} err]} {
8880 error_popup $err
8881 }
Paul Mackerrasc11ff122008-05-26 00:11:338882 set oldmainid $mainheadid
Paul Mackerras08ba8202008-05-12 00:18:388883 set mainhead $newhead
8884 set mainheadid $newheadid
Paul Mackerrascdc84292008-11-18 08:54:148885 set viewmainheadid($curview) $newheadid
Paul Mackerrasc11ff122008-05-26 00:11:338886 redrawtags $oldmainid
Paul Mackerras08ba8202008-05-12 00:18:388887 redrawtags $newheadid
8888 selbyid $newheadid
Paul Mackerras6fb735a2006-10-19 00:09:068889 if {$showlocalchanges} {
8890 dodiffindex
Paul Mackerras10299152006-08-01 23:52:018891 }
8892}
8893
8894proc rmbranch {} {
Paul Mackerrase11f1232007-06-16 10:29:258895 global headmenuid headmenuhead mainhead
Paul Mackerrasb1054ac2007-08-15 00:09:478896 global idheads
Paul Mackerras10299152006-08-01 23:52:018897
8898 set head $headmenuhead
8899 set id $headmenuid
Paul Mackerras00609462007-06-17 07:08:358900 # this check shouldn't be needed any more...
Paul Mackerras10299152006-08-01 23:52:018901 if {$head eq $mainhead} {
Christian Stimmingd990ced2007-11-07 17:42:558902 error_popup [mc "Cannot delete the currently checked-out branch"]
Paul Mackerras10299152006-08-01 23:52:018903 return
8904 }
Paul Mackerrase11f1232007-06-16 10:29:258905 set dheads [descheads $id]
Paul Mackerrasd7b16112007-08-17 07:57:318906 if {[llength $dheads] == 1 && $idheads($dheads) eq $head} {
Paul Mackerras10299152006-08-01 23:52:018907 # the stuff on this branch isn't on any other branch
Christian Stimmingd990ced2007-11-07 17:42:558908 if {![confirm_popup [mc "The commits on branch %s aren't on any other\
8909 branch.\nReally delete branch %s?" $head $head]]} return
Paul Mackerras10299152006-08-01 23:52:018910 }
8911 nowbusy rmbranch
8912 update
8913 if {[catch {exec git branch -D $head} err]} {
8914 notbusy rmbranch
8915 error_popup $err
8916 return
8917 }
Paul Mackerrase11f1232007-06-16 10:29:258918 removehead $id $head
Paul Mackerrasca6d8f52006-08-06 11:08:058919 removedhead $id $head
Paul Mackerras10299152006-08-01 23:52:018920 redrawtags $id
8921 notbusy rmbranch
Paul Mackerrase11f1232007-06-16 10:29:258922 dispneartags 0
Paul Mackerras887c9962007-08-20 09:36:208923 run refill_reflist
8924}
8925
8926# Display a list of tags and heads
8927proc showrefs {} {
Paul Mackerras9c311b32007-10-04 12:27:138928 global showrefstop bgcolor fgcolor selectbgcolor
8929 global bglist fglist reflistfilter reflist maincursor
Paul Mackerras887c9962007-08-20 09:36:208930
8931 set top .showrefs
8932 set showrefstop $top
8933 if {[winfo exists $top]} {
8934 raise $top
8935 refill_reflist
8936 return
8937 }
8938 toplevel $top
Christian Stimmingd990ced2007-11-07 17:42:558939 wm title $top [mc "Tags and heads: %s" [file tail [pwd]]]
Alexander Gavrilove7d64002008-11-11 20:55:428940 make_transient $top .
Paul Mackerras887c9962007-08-20 09:36:208941 text $top.list -background $bgcolor -foreground $fgcolor \
Paul Mackerras9c311b32007-10-04 12:27:138942 -selectbackground $selectbgcolor -font mainfont \
Paul Mackerras887c9962007-08-20 09:36:208943 -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \
8944 -width 30 -height 20 -cursor $maincursor \
8945 -spacing1 1 -spacing3 1 -state disabled
8946 $top.list tag configure highlight -background $selectbgcolor
8947 lappend bglist $top.list
8948 lappend fglist $top.list
8949 scrollbar $top.ysb -command "$top.list yview" -orient vertical
8950 scrollbar $top.xsb -command "$top.list xview" -orient horizontal
8951 grid $top.list $top.ysb -sticky nsew
8952 grid $top.xsb x -sticky ew
8953 frame $top.f
Paul Mackerrasb039f0a2008-01-06 04:54:468954 label $top.f.l -text "[mc "Filter"]: "
8955 entry $top.f.e -width 20 -textvariable reflistfilter
Paul Mackerras887c9962007-08-20 09:36:208956 set reflistfilter "*"
8957 trace add variable reflistfilter write reflistfilter_change
8958 pack $top.f.e -side right -fill x -expand 1
8959 pack $top.f.l -side left
8960 grid $top.f - -sticky ew -pady 2
Paul Mackerrasb039f0a2008-01-06 04:54:468961 button $top.close -command [list destroy $top] -text [mc "Close"]
Alexander Gavrilov76f15942008-11-02 18:59:448962 bind $top <Key-Escape> [list destroy $top]
Paul Mackerras887c9962007-08-20 09:36:208963 grid $top.close -
8964 grid columnconfigure $top 0 -weight 1
8965 grid rowconfigure $top 0 -weight 1
8966 bind $top.list <1> {break}
8967 bind $top.list <B1-Motion> {break}
8968 bind $top.list <ButtonRelease-1> {sel_reflist %W %x %y; break}
8969 set reflist {}
8970 refill_reflist
8971}
8972
8973proc sel_reflist {w x y} {
8974 global showrefstop reflist headids tagids otherrefids
8975
8976 if {![winfo exists $showrefstop]} return
8977 set l [lindex [split [$w index "@$x,$y"] "."] 0]
8978 set ref [lindex $reflist [expr {$l-1}]]
8979 set n [lindex $ref 0]
8980 switch -- [lindex $ref 1] {
8981 "H" {selbyid $headids($n)}
8982 "T" {selbyid $tagids($n)}
8983 "o" {selbyid $otherrefids($n)}
8984 }
8985 $showrefstop.list tag add highlight $l.0 "$l.0 lineend"
8986}
8987
8988proc unsel_reflist {} {
8989 global showrefstop
8990
8991 if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
8992 $showrefstop.list tag remove highlight 0.0 end
8993}
8994
8995proc reflistfilter_change {n1 n2 op} {
8996 global reflistfilter
8997
8998 after cancel refill_reflist
8999 after 200 refill_reflist
9000}
9001
9002proc refill_reflist {} {
9003 global reflist reflistfilter showrefstop headids tagids otherrefids
Paul Mackerrasd375ef92008-10-20 23:18:129004 global curview
Paul Mackerras887c9962007-08-20 09:36:209005
9006 if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
9007 set refs {}
9008 foreach n [array names headids] {
9009 if {[string match $reflistfilter $n]} {
Paul Mackerras7fcc92b2007-12-02 23:33:019010 if {[commitinview $headids($n) $curview]} {
Paul Mackerras887c9962007-08-20 09:36:209011 lappend refs [list $n H]
9012 } else {
Paul Mackerrasd375ef92008-10-20 23:18:129013 interestedin $headids($n) {run refill_reflist}
Paul Mackerras887c9962007-08-20 09:36:209014 }
9015 }
9016 }
9017 foreach n [array names tagids] {
9018 if {[string match $reflistfilter $n]} {
Paul Mackerras7fcc92b2007-12-02 23:33:019019 if {[commitinview $tagids($n) $curview]} {
Paul Mackerras887c9962007-08-20 09:36:209020 lappend refs [list $n T]
9021 } else {
Paul Mackerrasd375ef92008-10-20 23:18:129022 interestedin $tagids($n) {run refill_reflist}
Paul Mackerras887c9962007-08-20 09:36:209023 }
9024 }
9025 }
9026 foreach n [array names otherrefids] {
9027 if {[string match $reflistfilter $n]} {
Paul Mackerras7fcc92b2007-12-02 23:33:019028 if {[commitinview $otherrefids($n) $curview]} {
Paul Mackerras887c9962007-08-20 09:36:209029 lappend refs [list $n o]
9030 } else {
Paul Mackerrasd375ef92008-10-20 23:18:129031 interestedin $otherrefids($n) {run refill_reflist}
Paul Mackerras887c9962007-08-20 09:36:209032 }
9033 }
9034 }
9035 set refs [lsort -index 0 $refs]
9036 if {$refs eq $reflist} return
9037
9038 # Update the contents of $showrefstop.list according to the
9039 # differences between $reflist (old) and $refs (new)
9040 $showrefstop.list conf -state normal
9041 $showrefstop.list insert end "\n"
9042 set i 0
9043 set j 0
9044 while {$i < [llength $reflist] || $j < [llength $refs]} {
9045 if {$i < [llength $reflist]} {
9046 if {$j < [llength $refs]} {
9047 set cmp [string compare [lindex $reflist $i 0] \
9048 [lindex $refs $j 0]]
9049 if {$cmp == 0} {
9050 set cmp [string compare [lindex $reflist $i 1] \
9051 [lindex $refs $j 1]]
9052 }
9053 } else {
9054 set cmp -1
9055 }
9056 } else {
9057 set cmp 1
9058 }
9059 switch -- $cmp {
9060 -1 {
9061 $showrefstop.list delete "[expr {$j+1}].0" "[expr {$j+2}].0"
9062 incr i
9063 }
9064 0 {
9065 incr i
9066 incr j
9067 }
9068 1 {
9069 set l [expr {$j + 1}]
9070 $showrefstop.list image create $l.0 -align baseline \
9071 -image reficon-[lindex $refs $j 1] -padx 2
9072 $showrefstop.list insert $l.1 "[lindex $refs $j 0]\n"
9073 incr j
9074 }
9075 }
9076 }
9077 set reflist $refs
9078 # delete last newline
9079 $showrefstop.list delete end-2c end-1c
9080 $showrefstop.list conf -state disabled
Paul Mackerras10299152006-08-01 23:52:019081}
9082
Paul Mackerrasb8ab2e12006-06-03 09:11:139083# Stuff for finding nearby tags
9084proc getallcommits {} {
Paul Mackerras5cd15b62007-08-30 11:54:179085 global allcommits nextarc seeds allccache allcwait cachedarcs allcupdate
9086 global idheads idtags idotherrefs allparents tagobjid
Paul Mackerrasf1d83ba2005-08-19 12:14:289087
Paul Mackerrasa69b2d12007-08-13 05:02:029088 if {![info exists allcommits]} {
Paul Mackerrasa69b2d12007-08-13 05:02:029089 set nextarc 0
9090 set allcommits 0
9091 set seeds {}
Paul Mackerras5cd15b62007-08-30 11:54:179092 set allcwait 0
9093 set cachedarcs 0
9094 set allccache [file join [gitdir] "gitk.cache"]
9095 if {![catch {
9096 set f [open $allccache r]
9097 set allcwait 1
9098 getcache $f
9099 }]} return
Paul Mackerrasa69b2d12007-08-13 05:02:029100 }
Paul Mackerrase11f1232007-06-16 10:29:259101
Paul Mackerras5cd15b62007-08-30 11:54:179102 if {$allcwait} {
9103 return
Paul Mackerrase11f1232007-06-16 10:29:259104 }
Paul Mackerras5cd15b62007-08-30 11:54:179105 set cmd [list | git rev-list --parents]
9106 set allcupdate [expr {$seeds ne {}}]
9107 if {!$allcupdate} {
9108 set ids "--all"
9109 } else {
9110 set refs [concat [array names idheads] [array names idtags] \
9111 [array names idotherrefs]]
9112 set ids {}
9113 set tagobjs {}
9114 foreach name [array names tagobjid] {
9115 lappend tagobjs $tagobjid($name)
9116 }
9117 foreach id [lsort -unique $refs] {
9118 if {![info exists allparents($id)] &&
9119 [lsearch -exact $tagobjs $id] < 0} {
9120 lappend ids $id
9121 }
9122 }
9123 if {$ids ne {}} {
9124 foreach id $seeds {
9125 lappend ids "^$id"
9126 }
9127 }
9128 }
9129 if {$ids ne {}} {
9130 set fd [open [concat $cmd $ids] r]
9131 fconfigure $fd -blocking 0
9132 incr allcommits
9133 nowbusy allcommits
9134 filerun $fd [list getallclines $fd]
9135 } else {
9136 dispneartags 0
9137 }
Paul Mackerrasb8ab2e12006-06-03 09:11:139138}
9139
Paul Mackerrase11f1232007-06-16 10:29:259140# Since most commits have 1 parent and 1 child, we group strings of
9141# such commits into "arcs" joining branch/merge points (BMPs), which
9142# are commits that either don't have 1 parent or don't have 1 child.
9143#
9144# arcnos(id) - incoming arcs for BMP, arc we're on for other nodes
9145# arcout(id) - outgoing arcs for BMP
9146# arcids(a) - list of IDs on arc including end but not start
9147# arcstart(a) - BMP ID at start of arc
9148# arcend(a) - BMP ID at end of arc
9149# growing(a) - arc a is still growing
9150# arctags(a) - IDs out of arcids (excluding end) that have tags
9151# archeads(a) - IDs out of arcids (excluding end) that have heads
9152# The start of an arc is at the descendent end, so "incoming" means
9153# coming from descendents, and "outgoing" means going towards ancestors.
Paul Mackerrascec7bec2006-08-01 23:38:109154
Paul Mackerrasb8ab2e12006-06-03 09:11:139155proc getallclines {fd} {
Paul Mackerras5cd15b62007-08-30 11:54:179156 global allparents allchildren idtags idheads nextarc
Paul Mackerrase11f1232007-06-16 10:29:259157 global arcnos arcids arctags arcout arcend arcstart archeads growing
Paul Mackerras5cd15b62007-08-30 11:54:179158 global seeds allcommits cachedarcs allcupdate
9159
Paul Mackerrase11f1232007-06-16 10:29:259160 set nid 0
Paul Mackerras7eb3cb92007-06-17 04:45:009161 while {[incr nid] <= 1000 && [gets $fd line] >= 0} {
Paul Mackerrasb8ab2e12006-06-03 09:11:139162 set id [lindex $line 0]
Paul Mackerrase11f1232007-06-16 10:29:259163 if {[info exists allparents($id)]} {
9164 # seen it already
9165 continue
9166 }
Paul Mackerras5cd15b62007-08-30 11:54:179167 set cachedarcs 0
Paul Mackerrasb8ab2e12006-06-03 09:11:139168 set olds [lrange $line 1 end]
9169 set allparents($id) $olds
9170 if {![info exists allchildren($id)]} {
9171 set allchildren($id) {}
Paul Mackerrase11f1232007-06-16 10:29:259172 set arcnos($id) {}
9173 lappend seeds $id
9174 } else {
9175 set a $arcnos($id)
9176 if {[llength $olds] == 1 && [llength $a] == 1} {
9177 lappend arcids($a) $id
9178 if {[info exists idtags($id)]} {
9179 lappend arctags($a) $id
9180 }
9181 if {[info exists idheads($id)]} {
9182 lappend archeads($a) $id
9183 }
9184 if {[info exists allparents($olds)]} {
9185 # seen parent already
9186 if {![info exists arcout($olds)]} {
9187 splitarc $olds
9188 }
9189 lappend arcids($a) $olds
9190 set arcend($a) $olds
9191 unset growing($a)
9192 }
9193 lappend allchildren($olds) $id
9194 lappend arcnos($olds) $a
9195 continue
9196 }
Paul Mackerrasb8ab2e12006-06-03 09:11:139197 }
Paul Mackerrase11f1232007-06-16 10:29:259198 foreach a $arcnos($id) {
9199 lappend arcids($a) $id
9200 set arcend($a) $id
9201 unset growing($a)
9202 }
9203
9204 set ao {}
Paul Mackerrasb8ab2e12006-06-03 09:11:139205 foreach p $olds {
9206 lappend allchildren($p) $id
Paul Mackerrase11f1232007-06-16 10:29:259207 set a [incr nextarc]
9208 set arcstart($a) $id
9209 set archeads($a) {}
9210 set arctags($a) {}
9211 set archeads($a) {}
9212 set arcids($a) {}
9213 lappend ao $a
9214 set growing($a) 1
9215 if {[info exists allparents($p)]} {
9216 # seen it already, may need to make a new branch
9217 if {![info exists arcout($p)]} {
9218 splitarc $p
9219 }
9220 lappend arcids($a) $p
9221 set arcend($a) $p
9222 unset growing($a)
9223 }
9224 lappend arcnos($p) $a
Paul Mackerrasb8ab2e12006-06-03 09:11:139225 }
Paul Mackerrase11f1232007-06-16 10:29:259226 set arcout($id) $ao
Paul Mackerrasf1d83ba2005-08-19 12:14:289227 }
Paul Mackerrasf3326b62007-06-18 12:39:219228 if {$nid > 0} {
9229 global cached_dheads cached_dtags cached_atags
9230 catch {unset cached_dheads}
9231 catch {unset cached_dtags}
9232 catch {unset cached_atags}
9233 }
Paul Mackerras7eb3cb92007-06-17 04:45:009234 if {![eof $fd]} {
9235 return [expr {$nid >= 1000? 2: 1}]
9236 }
Paul Mackerras5cd15b62007-08-30 11:54:179237 set cacheok 1
9238 if {[catch {
9239 fconfigure $fd -blocking 1
9240 close $fd
9241 } err]} {
9242 # got an error reading the list of commits
9243 # if we were updating, try rereading the whole thing again
9244 if {$allcupdate} {
9245 incr allcommits -1
9246 dropcache $err
9247 return
9248 }
Christian Stimmingd990ced2007-11-07 17:42:559249 error_popup "[mc "Error reading commit topology information;\
Paul Mackerras5cd15b62007-08-30 11:54:179250 branch and preceding/following tag information\
Christian Stimmingd990ced2007-11-07 17:42:559251 will be incomplete."]\n($err)"
Paul Mackerras5cd15b62007-08-30 11:54:179252 set cacheok 0
9253 }
Paul Mackerrase11f1232007-06-16 10:29:259254 if {[incr allcommits -1] == 0} {
9255 notbusy allcommits
Paul Mackerras5cd15b62007-08-30 11:54:179256 if {$cacheok} {
9257 run savecache
9258 }
Paul Mackerrase11f1232007-06-16 10:29:259259 }
9260 dispneartags 0
Paul Mackerras7eb3cb92007-06-17 04:45:009261 return 0
Paul Mackerrase11f1232007-06-16 10:29:259262}
9263
9264proc recalcarc {a} {
9265 global arctags archeads arcids idtags idheads
9266
9267 set at {}
9268 set ah {}
9269 foreach id [lrange $arcids($a) 0 end-1] {
9270 if {[info exists idtags($id)]} {
9271 lappend at $id
Paul Mackerrasb8ab2e12006-06-03 09:11:139272 }
Paul Mackerrase11f1232007-06-16 10:29:259273 if {[info exists idheads($id)]} {
9274 lappend ah $id
9275 }
9276 }
9277 set arctags($a) $at
9278 set archeads($a) $ah
9279}
9280
9281proc splitarc {p} {
Paul Mackerras5cd15b62007-08-30 11:54:179282 global arcnos arcids nextarc arctags archeads idtags idheads
Paul Mackerrase11f1232007-06-16 10:29:259283 global arcstart arcend arcout allparents growing
9284
9285 set a $arcnos($p)
9286 if {[llength $a] != 1} {
9287 puts "oops splitarc called but [llength $a] arcs already"
9288 return
9289 }
9290 set a [lindex $a 0]
9291 set i [lsearch -exact $arcids($a) $p]
9292 if {$i < 0} {
9293 puts "oops splitarc $p not in arc $a"
9294 return
9295 }
9296 set na [incr nextarc]
9297 if {[info exists arcend($a)]} {
9298 set arcend($na) $arcend($a)
9299 } else {
9300 set l [lindex $allparents([lindex $arcids($a) end]) 0]
9301 set j [lsearch -exact $arcnos($l) $a]
9302 set arcnos($l) [lreplace $arcnos($l) $j $j $na]
9303 }
9304 set tail [lrange $arcids($a) [expr {$i+1}] end]
9305 set arcids($a) [lrange $arcids($a) 0 $i]
9306 set arcend($a) $p
9307 set arcstart($na) $p
9308 set arcout($p) $na
9309 set arcids($na) $tail
9310 if {[info exists growing($a)]} {
9311 set growing($na) 1
9312 unset growing($a)
9313 }
Paul Mackerrase11f1232007-06-16 10:29:259314
9315 foreach id $tail {
9316 if {[llength $arcnos($id)] == 1} {
9317 set arcnos($id) $na
9318 } else {
9319 set j [lsearch -exact $arcnos($id) $a]
9320 set arcnos($id) [lreplace $arcnos($id) $j $j $na]
9321 }
9322 }
9323
9324 # reconstruct tags and heads lists
9325 if {$arctags($a) ne {} || $archeads($a) ne {}} {
9326 recalcarc $a
9327 recalcarc $na
9328 } else {
9329 set arctags($na) {}
9330 set archeads($na) {}
Paul Mackerrasb8ab2e12006-06-03 09:11:139331 }
9332}
9333
Paul Mackerrase11f1232007-06-16 10:29:259334# Update things for a new commit added that is a child of one
9335# existing commit. Used when cherry-picking.
9336proc addnewchild {id p} {
Paul Mackerras5cd15b62007-08-30 11:54:179337 global allparents allchildren idtags nextarc
Paul Mackerrase11f1232007-06-16 10:29:259338 global arcnos arcids arctags arcout arcend arcstart archeads growing
Paul Mackerras719c2b92007-08-29 12:41:349339 global seeds allcommits
Paul Mackerrasb8ab2e12006-06-03 09:11:139340
Paul Mackerras3ebba3c2007-10-20 12:10:529341 if {![info exists allcommits] || ![info exists arcnos($p)]} return
Paul Mackerrase11f1232007-06-16 10:29:259342 set allparents($id) [list $p]
9343 set allchildren($id) {}
9344 set arcnos($id) {}
9345 lappend seeds $id
Paul Mackerrase11f1232007-06-16 10:29:259346 lappend allchildren($p) $id
9347 set a [incr nextarc]
9348 set arcstart($a) $id
9349 set archeads($a) {}
9350 set arctags($a) {}
9351 set arcids($a) [list $p]
9352 set arcend($a) $p
9353 if {![info exists arcout($p)]} {
9354 splitarc $p
9355 }
9356 lappend arcnos($p) $a
9357 set arcout($id) [list $a]
9358}
9359
Paul Mackerras5cd15b62007-08-30 11:54:179360# This implements a cache for the topology information.
9361# The cache saves, for each arc, the start and end of the arc,
9362# the ids on the arc, and the outgoing arcs from the end.
9363proc readcache {f} {
9364 global arcnos arcids arcout arcstart arcend arctags archeads nextarc
9365 global idtags idheads allparents cachedarcs possible_seeds seeds growing
9366 global allcwait
9367
9368 set a $nextarc
9369 set lim $cachedarcs
9370 if {$lim - $a > 500} {
9371 set lim [expr {$a + 500}]
9372 }
9373 if {[catch {
9374 if {$a == $lim} {
9375 # finish reading the cache and setting up arctags, etc.
9376 set line [gets $f]
9377 if {$line ne "1"} {error "bad final version"}
9378 close $f
9379 foreach id [array names idtags] {
9380 if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
9381 [llength $allparents($id)] == 1} {
9382 set a [lindex $arcnos($id) 0]
9383 if {$arctags($a) eq {}} {
9384 recalcarc $a
9385 }
9386 }
9387 }
9388 foreach id [array names idheads] {
9389 if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
9390 [llength $allparents($id)] == 1} {
9391 set a [lindex $arcnos($id) 0]
9392 if {$archeads($a) eq {}} {
9393 recalcarc $a
9394 }
9395 }
9396 }
9397 foreach id [lsort -unique $possible_seeds] {
9398 if {$arcnos($id) eq {}} {
9399 lappend seeds $id
9400 }
9401 }
9402 set allcwait 0
9403 } else {
9404 while {[incr a] <= $lim} {
9405 set line [gets $f]
9406 if {[llength $line] != 3} {error "bad line"}
9407 set s [lindex $line 0]
9408 set arcstart($a) $s
9409 lappend arcout($s) $a
9410 if {![info exists arcnos($s)]} {
9411 lappend possible_seeds $s
9412 set arcnos($s) {}
9413 }
9414 set e [lindex $line 1]
9415 if {$e eq {}} {
9416 set growing($a) 1
9417 } else {
9418 set arcend($a) $e
9419 if {![info exists arcout($e)]} {
9420 set arcout($e) {}
9421 }
9422 }
9423 set arcids($a) [lindex $line 2]
9424 foreach id $arcids($a) {
9425 lappend allparents($s) $id
9426 set s $id
9427 lappend arcnos($id) $a
9428 }
9429 if {![info exists allparents($s)]} {
9430 set allparents($s) {}
9431 }
9432 set arctags($a) {}
9433 set archeads($a) {}
9434 }
9435 set nextarc [expr {$a - 1}]
9436 }
9437 } err]} {
9438 dropcache $err
9439 return 0
9440 }
9441 if {!$allcwait} {
9442 getallcommits
9443 }
9444 return $allcwait
9445}
9446
9447proc getcache {f} {
9448 global nextarc cachedarcs possible_seeds
9449
9450 if {[catch {
9451 set line [gets $f]
9452 if {[llength $line] != 2 || [lindex $line 0] ne "1"} {error "bad version"}
9453 # make sure it's an integer
9454 set cachedarcs [expr {int([lindex $line 1])}]
9455 if {$cachedarcs < 0} {error "bad number of arcs"}
9456 set nextarc 0
9457 set possible_seeds {}
9458 run readcache $f
9459 } err]} {
9460 dropcache $err
9461 }
9462 return 0
9463}
9464
9465proc dropcache {err} {
9466 global allcwait nextarc cachedarcs seeds
9467
9468 #puts "dropping cache ($err)"
9469 foreach v {arcnos arcout arcids arcstart arcend growing \
9470 arctags archeads allparents allchildren} {
9471 global $v
9472 catch {unset $v}
9473 }
9474 set allcwait 0
9475 set nextarc 0
9476 set cachedarcs 0
9477 set seeds {}
9478 getallcommits
9479}
9480
9481proc writecache {f} {
9482 global cachearc cachedarcs allccache
9483 global arcstart arcend arcnos arcids arcout
9484
9485 set a $cachearc
9486 set lim $cachedarcs
9487 if {$lim - $a > 1000} {
9488 set lim [expr {$a + 1000}]
9489 }
9490 if {[catch {
9491 while {[incr a] <= $lim} {
9492 if {[info exists arcend($a)]} {
9493 puts $f [list $arcstart($a) $arcend($a) $arcids($a)]
9494 } else {
9495 puts $f [list $arcstart($a) {} $arcids($a)]
9496 }
9497 }
9498 } err]} {
9499 catch {close $f}
9500 catch {file delete $allccache}
9501 #puts "writing cache failed ($err)"
9502 return 0
9503 }
9504 set cachearc [expr {$a - 1}]
9505 if {$a > $cachedarcs} {
9506 puts $f "1"
9507 close $f
9508 return 0
9509 }
9510 return 1
9511}
9512
9513proc savecache {} {
9514 global nextarc cachedarcs cachearc allccache
9515
9516 if {$nextarc == $cachedarcs} return
9517 set cachearc 0
9518 set cachedarcs $nextarc
9519 catch {
9520 set f [open $allccache w]
9521 puts $f [list 1 $cachedarcs]
9522 run writecache $f
9523 }
9524}
9525
Paul Mackerrase11f1232007-06-16 10:29:259526# Returns 1 if a is an ancestor of b, -1 if b is an ancestor of a,
9527# or 0 if neither is true.
9528proc anc_or_desc {a b} {
9529 global arcout arcstart arcend arcnos cached_isanc
9530
9531 if {$arcnos($a) eq $arcnos($b)} {
9532 # Both are on the same arc(s); either both are the same BMP,
9533 # or if one is not a BMP, the other is also not a BMP or is
9534 # the BMP at end of the arc (and it only has 1 incoming arc).
Paul Mackerras69c0b5d2007-07-04 11:57:049535 # Or both can be BMPs with no incoming arcs.
9536 if {$a eq $b || $arcnos($a) eq {}} {
Paul Mackerrase11f1232007-06-16 10:29:259537 return 0
9538 }
9539 # assert {[llength $arcnos($a)] == 1}
9540 set arc [lindex $arcnos($a) 0]
9541 set i [lsearch -exact $arcids($arc) $a]
9542 set j [lsearch -exact $arcids($arc) $b]
9543 if {$i < 0 || $i > $j} {
9544 return 1
9545 } else {
9546 return -1
9547 }
9548 }
9549
9550 if {![info exists arcout($a)]} {
9551 set arc [lindex $arcnos($a) 0]
9552 if {[info exists arcend($arc)]} {
9553 set aend $arcend($arc)
9554 } else {
9555 set aend {}
9556 }
9557 set a $arcstart($arc)
9558 } else {
9559 set aend $a
9560 }
9561 if {![info exists arcout($b)]} {
9562 set arc [lindex $arcnos($b) 0]
9563 if {[info exists arcend($arc)]} {
9564 set bend $arcend($arc)
9565 } else {
9566 set bend {}
9567 }
9568 set b $arcstart($arc)
9569 } else {
9570 set bend $b
9571 }
9572 if {$a eq $bend} {
9573 return 1
9574 }
9575 if {$b eq $aend} {
9576 return -1
9577 }
9578 if {[info exists cached_isanc($a,$bend)]} {
9579 if {$cached_isanc($a,$bend)} {
9580 return 1
9581 }
9582 }
9583 if {[info exists cached_isanc($b,$aend)]} {
9584 if {$cached_isanc($b,$aend)} {
9585 return -1
9586 }
9587 if {[info exists cached_isanc($a,$bend)]} {
9588 return 0
9589 }
9590 }
9591
9592 set todo [list $a $b]
9593 set anc($a) a
9594 set anc($b) b
9595 for {set i 0} {$i < [llength $todo]} {incr i} {
9596 set x [lindex $todo $i]
9597 if {$anc($x) eq {}} {
9598 continue
9599 }
9600 foreach arc $arcnos($x) {
9601 set xd $arcstart($arc)
9602 if {$xd eq $bend} {
9603 set cached_isanc($a,$bend) 1
9604 set cached_isanc($b,$aend) 0
9605 return 1
9606 } elseif {$xd eq $aend} {
9607 set cached_isanc($b,$aend) 1
9608 set cached_isanc($a,$bend) 0
9609 return -1
9610 }
9611 if {![info exists anc($xd)]} {
9612 set anc($xd) $anc($x)
9613 lappend todo $xd
9614 } elseif {$anc($xd) ne $anc($x)} {
9615 set anc($xd) {}
9616 }
9617 }
9618 }
9619 set cached_isanc($a,$bend) 0
9620 set cached_isanc($b,$aend) 0
9621 return 0
9622}
9623
9624# This identifies whether $desc has an ancestor that is
9625# a growing tip of the graph and which is not an ancestor of $anc
9626# and returns 0 if so and 1 if not.
9627# If we subsequently discover a tag on such a growing tip, and that
9628# turns out to be a descendent of $anc (which it could, since we
9629# don't necessarily see children before parents), then $desc
9630# isn't a good choice to display as a descendent tag of
9631# $anc (since it is the descendent of another tag which is
9632# a descendent of $anc). Similarly, $anc isn't a good choice to
9633# display as a ancestor tag of $desc.
9634#
9635proc is_certain {desc anc} {
9636 global arcnos arcout arcstart arcend growing problems
9637
9638 set certain {}
9639 if {[llength $arcnos($anc)] == 1} {
9640 # tags on the same arc are certain
9641 if {$arcnos($desc) eq $arcnos($anc)} {
9642 return 1
9643 }
9644 if {![info exists arcout($anc)]} {
9645 # if $anc is partway along an arc, use the start of the arc instead
9646 set a [lindex $arcnos($anc) 0]
9647 set anc $arcstart($a)
9648 }
9649 }
9650 if {[llength $arcnos($desc)] > 1 || [info exists arcout($desc)]} {
9651 set x $desc
9652 } else {
9653 set a [lindex $arcnos($desc) 0]
9654 set x $arcend($a)
9655 }
9656 if {$x == $anc} {
9657 return 1
9658 }
9659 set anclist [list $x]
9660 set dl($x) 1
9661 set nnh 1
9662 set ngrowanc 0
9663 for {set i 0} {$i < [llength $anclist] && ($nnh > 0 || $ngrowanc > 0)} {incr i} {
9664 set x [lindex $anclist $i]
9665 if {$dl($x)} {
9666 incr nnh -1
9667 }
9668 set done($x) 1
9669 foreach a $arcout($x) {
9670 if {[info exists growing($a)]} {
9671 if {![info exists growanc($x)] && $dl($x)} {
9672 set growanc($x) 1
9673 incr ngrowanc
9674 }
Paul Mackerrasb8ab2e12006-06-03 09:11:139675 } else {
Paul Mackerrase11f1232007-06-16 10:29:259676 set y $arcend($a)
9677 if {[info exists dl($y)]} {
9678 if {$dl($y)} {
9679 if {!$dl($x)} {
9680 set dl($y) 0
9681 if {![info exists done($y)]} {
9682 incr nnh -1
9683 }
9684 if {[info exists growanc($x)]} {
9685 incr ngrowanc -1
9686 }
9687 set xl [list $y]
9688 for {set k 0} {$k < [llength $xl]} {incr k} {
9689 set z [lindex $xl $k]
9690 foreach c $arcout($z) {
9691 if {[info exists arcend($c)]} {
9692 set v $arcend($c)
9693 if {[info exists dl($v)] && $dl($v)} {
9694 set dl($v) 0
9695 if {![info exists done($v)]} {
9696 incr nnh -1
9697 }
9698 if {[info exists growanc($v)]} {
9699 incr ngrowanc -1
9700 }
9701 lappend xl $v
9702 }
9703 }
9704 }
9705 }
9706 }
9707 }
9708 } elseif {$y eq $anc || !$dl($x)} {
9709 set dl($y) 0
9710 lappend anclist $y
9711 } else {
9712 set dl($y) 1
9713 lappend anclist $y
9714 incr nnh
9715 }
Paul Mackerrasb8ab2e12006-06-03 09:11:139716 }
Paul Mackerrasb8ab2e12006-06-03 09:11:139717 }
9718 }
Paul Mackerrase11f1232007-06-16 10:29:259719 foreach x [array names growanc] {
9720 if {$dl($x)} {
9721 return 0
9722 }
Paul Mackerras7eb3cb92007-06-17 04:45:009723 return 0
Paul Mackerrase11f1232007-06-16 10:29:259724 }
9725 return 1
Paul Mackerrasf1d83ba2005-08-19 12:14:289726}
9727
Paul Mackerrase11f1232007-06-16 10:29:259728proc validate_arctags {a} {
9729 global arctags idtags
9730
9731 set i -1
9732 set na $arctags($a)
9733 foreach id $arctags($a) {
9734 incr i
9735 if {![info exists idtags($id)]} {
9736 set na [lreplace $na $i $i]
9737 incr i -1
9738 }
9739 }
9740 set arctags($a) $na
9741}
9742
9743proc validate_archeads {a} {
9744 global archeads idheads
9745
9746 set i -1
9747 set na $archeads($a)
9748 foreach id $archeads($a) {
9749 incr i
9750 if {![info exists idheads($id)]} {
9751 set na [lreplace $na $i $i]
9752 incr i -1
9753 }
9754 }
9755 set archeads($a) $na
9756}
9757
9758# Return the list of IDs that have tags that are descendents of id,
9759# ignoring IDs that are descendents of IDs already reported.
9760proc desctags {id} {
9761 global arcnos arcstart arcids arctags idtags allparents
9762 global growing cached_dtags
9763
9764 if {![info exists allparents($id)]} {
9765 return {}
9766 }
9767 set t1 [clock clicks -milliseconds]
9768 set argid $id
9769 if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
9770 # part-way along an arc; check that arc first
9771 set a [lindex $arcnos($id) 0]
9772 if {$arctags($a) ne {}} {
9773 validate_arctags $a
9774 set i [lsearch -exact $arcids($a) $id]
9775 set tid {}
9776 foreach t $arctags($a) {
9777 set j [lsearch -exact $arcids($a) $t]
9778 if {$j >= $i} break
9779 set tid $t
9780 }
9781 if {$tid ne {}} {
9782 return $tid
9783 }
9784 }
9785 set id $arcstart($a)
9786 if {[info exists idtags($id)]} {
9787 return $id
9788 }
9789 }
9790 if {[info exists cached_dtags($id)]} {
9791 return $cached_dtags($id)
9792 }
9793
9794 set origid $id
9795 set todo [list $id]
9796 set queued($id) 1
9797 set nc 1
9798 for {set i 0} {$i < [llength $todo] && $nc > 0} {incr i} {
9799 set id [lindex $todo $i]
9800 set done($id) 1
9801 set ta [info exists hastaggedancestor($id)]
9802 if {!$ta} {
9803 incr nc -1
9804 }
9805 # ignore tags on starting node
9806 if {!$ta && $i > 0} {
9807 if {[info exists idtags($id)]} {
9808 set tagloc($id) $id
9809 set ta 1
9810 } elseif {[info exists cached_dtags($id)]} {
9811 set tagloc($id) $cached_dtags($id)
9812 set ta 1
9813 }
9814 }
9815 foreach a $arcnos($id) {
9816 set d $arcstart($a)
9817 if {!$ta && $arctags($a) ne {}} {
9818 validate_arctags $a
9819 if {$arctags($a) ne {}} {
9820 lappend tagloc($id) [lindex $arctags($a) end]
9821 }
9822 }
9823 if {$ta || $arctags($a) ne {}} {
9824 set tomark [list $d]
9825 for {set j 0} {$j < [llength $tomark]} {incr j} {
9826 set dd [lindex $tomark $j]
9827 if {![info exists hastaggedancestor($dd)]} {
9828 if {[info exists done($dd)]} {
9829 foreach b $arcnos($dd) {
9830 lappend tomark $arcstart($b)
9831 }
9832 if {[info exists tagloc($dd)]} {
9833 unset tagloc($dd)
9834 }
9835 } elseif {[info exists queued($dd)]} {
9836 incr nc -1
9837 }
9838 set hastaggedancestor($dd) 1
9839 }
9840 }
9841 }
9842 if {![info exists queued($d)]} {
9843 lappend todo $d
9844 set queued($d) 1
9845 if {![info exists hastaggedancestor($d)]} {
9846 incr nc
9847 }
9848 }
9849 }
9850 }
9851 set tags {}
9852 foreach id [array names tagloc] {
9853 if {![info exists hastaggedancestor($id)]} {
9854 foreach t $tagloc($id) {
9855 if {[lsearch -exact $tags $t] < 0} {
9856 lappend tags $t
9857 }
9858 }
9859 }
9860 }
9861 set t2 [clock clicks -milliseconds]
9862 set loopix $i
9863
9864 # remove tags that are descendents of other tags
9865 for {set i 0} {$i < [llength $tags]} {incr i} {
9866 set a [lindex $tags $i]
9867 for {set j 0} {$j < $i} {incr j} {
9868 set b [lindex $tags $j]
9869 set r [anc_or_desc $a $b]
9870 if {$r == 1} {
9871 set tags [lreplace $tags $j $j]
9872 incr j -1
9873 incr i -1
9874 } elseif {$r == -1} {
9875 set tags [lreplace $tags $i $i]
9876 incr i -1
9877 break
9878 }
9879 }
9880 }
9881
9882 if {[array names growing] ne {}} {
9883 # graph isn't finished, need to check if any tag could get
9884 # eclipsed by another tag coming later. Simply ignore any
9885 # tags that could later get eclipsed.
9886 set ctags {}
9887 foreach t $tags {
9888 if {[is_certain $t $origid]} {
9889 lappend ctags $t
9890 }
9891 }
9892 if {$tags eq $ctags} {
9893 set cached_dtags($origid) $tags
9894 } else {
9895 set tags $ctags
9896 }
9897 } else {
9898 set cached_dtags($origid) $tags
9899 }
9900 set t3 [clock clicks -milliseconds]
9901 if {0 && $t3 - $t1 >= 100} {
9902 puts "iterating descendents ($loopix/[llength $todo] nodes) took\
9903 [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
9904 }
9905 return $tags
9906}
9907
9908proc anctags {id} {
9909 global arcnos arcids arcout arcend arctags idtags allparents
9910 global growing cached_atags
9911
9912 if {![info exists allparents($id)]} {
9913 return {}
9914 }
9915 set t1 [clock clicks -milliseconds]
9916 set argid $id
9917 if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
9918 # part-way along an arc; check that arc first
9919 set a [lindex $arcnos($id) 0]
9920 if {$arctags($a) ne {}} {
9921 validate_arctags $a
9922 set i [lsearch -exact $arcids($a) $id]
9923 foreach t $arctags($a) {
9924 set j [lsearch -exact $arcids($a) $t]
9925 if {$j > $i} {
9926 return $t
9927 }
9928 }
9929 }
9930 if {![info exists arcend($a)]} {
9931 return {}
9932 }
9933 set id $arcend($a)
9934 if {[info exists idtags($id)]} {
9935 return $id
9936 }
9937 }
9938 if {[info exists cached_atags($id)]} {
9939 return $cached_atags($id)
9940 }
9941
9942 set origid $id
9943 set todo [list $id]
9944 set queued($id) 1
9945 set taglist {}
9946 set nc 1
9947 for {set i 0} {$i < [llength $todo] && $nc > 0} {incr i} {
9948 set id [lindex $todo $i]
9949 set done($id) 1
9950 set td [info exists hastaggeddescendent($id)]
9951 if {!$td} {
9952 incr nc -1
9953 }
9954 # ignore tags on starting node
9955 if {!$td && $i > 0} {
9956 if {[info exists idtags($id)]} {
9957 set tagloc($id) $id
9958 set td 1
9959 } elseif {[info exists cached_atags($id)]} {
9960 set tagloc($id) $cached_atags($id)
9961 set td 1
9962 }
9963 }
9964 foreach a $arcout($id) {
9965 if {!$td && $arctags($a) ne {}} {
9966 validate_arctags $a
9967 if {$arctags($a) ne {}} {
9968 lappend tagloc($id) [lindex $arctags($a) 0]
9969 }
9970 }
9971 if {![info exists arcend($a)]} continue
9972 set d $arcend($a)
9973 if {$td || $arctags($a) ne {}} {
9974 set tomark [list $d]
9975 for {set j 0} {$j < [llength $tomark]} {incr j} {
9976 set dd [lindex $tomark $j]
9977 if {![info exists hastaggeddescendent($dd)]} {
9978 if {[info exists done($dd)]} {
9979 foreach b $arcout($dd) {
9980 if {[info exists arcend($b)]} {
9981 lappend tomark $arcend($b)
9982 }
9983 }
9984 if {[info exists tagloc($dd)]} {
9985 unset tagloc($dd)
9986 }
9987 } elseif {[info exists queued($dd)]} {
9988 incr nc -1
9989 }
9990 set hastaggeddescendent($dd) 1
9991 }
9992 }
9993 }
9994 if {![info exists queued($d)]} {
9995 lappend todo $d
9996 set queued($d) 1
9997 if {![info exists hastaggeddescendent($d)]} {
9998 incr nc
9999 }
10000 }
10001 }
10002 }
10003 set t2 [clock clicks -milliseconds]
10004 set loopix $i
10005 set tags {}
10006 foreach id [array names tagloc] {
10007 if {![info exists hastaggeddescendent($id)]} {
10008 foreach t $tagloc($id) {
10009 if {[lsearch -exact $tags $t] < 0} {
10010 lappend tags $t
10011 }
10012 }
10013 }
10014 }
10015
10016 # remove tags that are ancestors of other tags
10017 for {set i 0} {$i < [llength $tags]} {incr i} {
10018 set a [lindex $tags $i]
10019 for {set j 0} {$j < $i} {incr j} {
10020 set b [lindex $tags $j]
10021 set r [anc_or_desc $a $b]
10022 if {$r == -1} {
10023 set tags [lreplace $tags $j $j]
10024 incr j -1
10025 incr i -1
10026 } elseif {$r == 1} {
10027 set tags [lreplace $tags $i $i]
10028 incr i -1
10029 break
10030 }
10031 }
10032 }
10033
10034 if {[array names growing] ne {}} {
10035 # graph isn't finished, need to check if any tag could get
10036 # eclipsed by another tag coming later. Simply ignore any
10037 # tags that could later get eclipsed.
10038 set ctags {}
10039 foreach t $tags {
10040 if {[is_certain $origid $t]} {
10041 lappend ctags $t
10042 }
10043 }
10044 if {$tags eq $ctags} {
10045 set cached_atags($origid) $tags
10046 } else {
10047 set tags $ctags
10048 }
10049 } else {
10050 set cached_atags($origid) $tags
10051 }
10052 set t3 [clock clicks -milliseconds]
10053 if {0 && $t3 - $t1 >= 100} {
10054 puts "iterating ancestors ($loopix/[llength $todo] nodes) took\
10055 [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
10056 }
10057 return $tags
10058}
10059
10060# Return the list of IDs that have heads that are descendents of id,
10061# including id itself if it has a head.
10062proc descheads {id} {
10063 global arcnos arcstart arcids archeads idheads cached_dheads
10064 global allparents
10065
10066 if {![info exists allparents($id)]} {
10067 return {}
10068 }
Paul Mackerrasf3326b62007-06-18 12:39:2110069 set aret {}
Paul Mackerrase11f1232007-06-16 10:29:2510070 if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
10071 # part-way along an arc; check it first
10072 set a [lindex $arcnos($id) 0]
10073 if {$archeads($a) ne {}} {
10074 validate_archeads $a
10075 set i [lsearch -exact $arcids($a) $id]
10076 foreach t $archeads($a) {
10077 set j [lsearch -exact $arcids($a) $t]
10078 if {$j > $i} break
Paul Mackerrasf3326b62007-06-18 12:39:2110079 lappend aret $t
Paul Mackerrase11f1232007-06-16 10:29:2510080 }
10081 }
10082 set id $arcstart($a)
10083 }
10084 set origid $id
10085 set todo [list $id]
10086 set seen($id) 1
Paul Mackerrasf3326b62007-06-18 12:39:2110087 set ret {}
Paul Mackerrase11f1232007-06-16 10:29:2510088 for {set i 0} {$i < [llength $todo]} {incr i} {
10089 set id [lindex $todo $i]
10090 if {[info exists cached_dheads($id)]} {
10091 set ret [concat $ret $cached_dheads($id)]
10092 } else {
10093 if {[info exists idheads($id)]} {
10094 lappend ret $id
10095 }
10096 foreach a $arcnos($id) {
10097 if {$archeads($a) ne {}} {
Paul Mackerras706d6c32007-06-26 01:09:4910098 validate_archeads $a
10099 if {$archeads($a) ne {}} {
10100 set ret [concat $ret $archeads($a)]
10101 }
Paul Mackerrase11f1232007-06-16 10:29:2510102 }
10103 set d $arcstart($a)
10104 if {![info exists seen($d)]} {
10105 lappend todo $d
10106 set seen($d) 1
10107 }
10108 }
10109 }
10110 }
10111 set ret [lsort -unique $ret]
10112 set cached_dheads($origid) $ret
Paul Mackerrasf3326b62007-06-18 12:39:2110113 return [concat $ret $aret]
Paul Mackerrase11f1232007-06-16 10:29:2510114}
10115
Paul Mackerrasceadfe92006-08-08 10:55:3610116proc addedtag {id} {
Paul Mackerrase11f1232007-06-16 10:29:2510117 global arcnos arcout cached_dtags cached_atags
Paul Mackerrasceadfe92006-08-08 10:55:3610118
Paul Mackerrase11f1232007-06-16 10:29:2510119 if {![info exists arcnos($id)]} return
10120 if {![info exists arcout($id)]} {
10121 recalcarc [lindex $arcnos($id) 0]
Paul Mackerrasceadfe92006-08-08 10:55:3610122 }
Paul Mackerrase11f1232007-06-16 10:29:2510123 catch {unset cached_dtags}
10124 catch {unset cached_atags}
Paul Mackerrasceadfe92006-08-08 10:55:3610125}
10126
Paul Mackerrasca6d8f52006-08-06 11:08:0510127proc addedhead {hid head} {
Paul Mackerrase11f1232007-06-16 10:29:2510128 global arcnos arcout cached_dheads
Paul Mackerrasca6d8f52006-08-06 11:08:0510129
Paul Mackerrase11f1232007-06-16 10:29:2510130 if {![info exists arcnos($hid)]} return
10131 if {![info exists arcout($hid)]} {
10132 recalcarc [lindex $arcnos($hid) 0]
Paul Mackerrasd6ac1a82006-08-01 23:41:0410133 }
Paul Mackerrase11f1232007-06-16 10:29:2510134 catch {unset cached_dheads}
Paul Mackerrasd6ac1a82006-08-01 23:41:0410135}
10136
Paul Mackerrasca6d8f52006-08-06 11:08:0510137proc removedhead {hid head} {
Paul Mackerrase11f1232007-06-16 10:29:2510138 global cached_dheads
Paul Mackerrasca6d8f52006-08-06 11:08:0510139
Paul Mackerrase11f1232007-06-16 10:29:2510140 catch {unset cached_dheads}
Paul Mackerras10299152006-08-01 23:52:0110141}
10142
Paul Mackerrase11f1232007-06-16 10:29:2510143proc movedhead {hid head} {
10144 global arcnos arcout cached_dheads
Paul Mackerrasca6d8f52006-08-06 11:08:0510145
Paul Mackerrase11f1232007-06-16 10:29:2510146 if {![info exists arcnos($hid)]} return
10147 if {![info exists arcout($hid)]} {
10148 recalcarc [lindex $arcnos($hid) 0]
Paul Mackerrasca6d8f52006-08-06 11:08:0510149 }
Paul Mackerrase11f1232007-06-16 10:29:2510150 catch {unset cached_dheads}
Paul Mackerrasca6d8f52006-08-06 11:08:0510151}
10152
Paul Mackerrascec7bec2006-08-01 23:38:1010153proc changedrefs {} {
Paul Mackerrase11f1232007-06-16 10:29:2510154 global cached_dheads cached_dtags cached_atags
10155 global arctags archeads arcnos arcout idheads idtags
Paul Mackerrascec7bec2006-08-01 23:38:1010156
Paul Mackerrase11f1232007-06-16 10:29:2510157 foreach id [concat [array names idheads] [array names idtags]] {
10158 if {[info exists arcnos($id)] && ![info exists arcout($id)]} {
10159 set a [lindex $arcnos($id) 0]
10160 if {![info exists donearc($a)]} {
10161 recalcarc $a
10162 set donearc($a) 1
10163 }
Paul Mackerrascec7bec2006-08-01 23:38:1010164 }
10165 }
Paul Mackerrase11f1232007-06-16 10:29:2510166 catch {unset cached_dtags}
10167 catch {unset cached_atags}
10168 catch {unset cached_dheads}
Paul Mackerrascec7bec2006-08-01 23:38:1010169}
10170
Paul Mackerrasf1d83ba2005-08-19 12:14:2810171proc rereadrefs {} {
Paul Mackerrasfc2a2562007-12-26 12:03:4310172 global idtags idheads idotherrefs mainheadid
Paul Mackerrasf1d83ba2005-08-19 12:14:2810173
10174 set refids [concat [array names idtags] \
10175 [array names idheads] [array names idotherrefs]]
10176 foreach id $refids {
10177 if {![info exists ref($id)]} {
10178 set ref($id) [listrefs $id]
10179 }
10180 }
Paul Mackerrasfc2a2562007-12-26 12:03:4310181 set oldmainhead $mainheadid
Paul Mackerrasf1d83ba2005-08-19 12:14:2810182 readrefs
Paul Mackerrascec7bec2006-08-01 23:38:1010183 changedrefs
Paul Mackerrasf1d83ba2005-08-19 12:14:2810184 set refids [lsort -unique [concat $refids [array names idtags] \
10185 [array names idheads] [array names idotherrefs]]]
10186 foreach id $refids {
10187 set v [listrefs $id]
Paul Mackerrasc11ff122008-05-26 00:11:3310188 if {![info exists ref($id)] || $ref($id) != $v} {
Paul Mackerrasf1d83ba2005-08-19 12:14:2810189 redrawtags $id
10190 }
10191 }
Paul Mackerrasc11ff122008-05-26 00:11:3310192 if {$oldmainhead ne $mainheadid} {
10193 redrawtags $oldmainhead
10194 redrawtags $mainheadid
10195 }
Paul Mackerras887c9962007-08-20 09:36:2010196 run refill_reflist
Paul Mackerrasf1d83ba2005-08-19 12:14:2810197}
10198
Junio C Hamano2e1ded42006-06-11 16:50:4710199proc listrefs {id} {
10200 global idtags idheads idotherrefs
10201
10202 set x {}
10203 if {[info exists idtags($id)]} {
10204 set x $idtags($id)
10205 }
10206 set y {}
10207 if {[info exists idheads($id)]} {
10208 set y $idheads($id)
10209 }
10210 set z {}
10211 if {[info exists idotherrefs($id)]} {
10212 set z $idotherrefs($id)
10213 }
10214 return [list $x $y $z]
10215}
10216
Paul Mackerras106288c2005-08-19 13:11:3910217proc showtag {tag isnew} {
Paul Mackerras62d3ea62006-09-11 00:36:5310218 global ctext tagcontents tagids linknum tagobjid
Paul Mackerras106288c2005-08-19 13:11:3910219
10220 if {$isnew} {
10221 addtohistory [list showtag $tag 0]
10222 }
10223 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 00:16:0310224 clear_ctext
Paul Mackerras32f1b3e2007-09-28 11:27:3910225 settabs 0
Paul Mackerras106288c2005-08-19 13:11:3910226 set linknum 0
Paul Mackerras62d3ea62006-09-11 00:36:5310227 if {![info exists tagcontents($tag)]} {
10228 catch {
10229 set tagcontents($tag) [exec git cat-file tag $tagobjid($tag)]
10230 }
10231 }
Paul Mackerras106288c2005-08-19 13:11:3910232 if {[info exists tagcontents($tag)]} {
10233 set text $tagcontents($tag)
10234 } else {
Christian Stimmingd990ced2007-11-07 17:42:5510235 set text "[mc "Tag"]: $tag\n[mc "Id"]: $tagids($tag)"
Paul Mackerras106288c2005-08-19 13:11:3910236 }
Sergey Vlasovf1b86292006-05-15 15:13:1410237 appendwithlinks $text {}
Paul Mackerras106288c2005-08-19 13:11:3910238 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 09:21:4910239 init_flist {}
Paul Mackerras106288c2005-08-19 13:11:3910240}
10241
Paul Mackerras1d10f362005-05-15 12:55:4710242proc doquit {} {
10243 global stopped
Thomas Arcila314f5de2008-03-24 11:55:3610244 global gitktmpdir
10245
Paul Mackerras1d10f362005-05-15 12:55:4710246 set stopped 100
Mark Levedahlb6047c52007-02-09 03:22:2410247 savestuff .
Paul Mackerras1d10f362005-05-15 12:55:4710248 destroy .
Thomas Arcila314f5de2008-03-24 11:55:3610249
10250 if {[info exists gitktmpdir]} {
10251 catch {file delete -force $gitktmpdir}
10252 }
Paul Mackerras1d10f362005-05-15 12:55:4710253}
10254
Paul Mackerras9a7558f2007-10-06 10:16:0610255proc mkfontdisp {font top which} {
10256 global fontattr fontpref $font
10257
10258 set fontpref($font) [set $font]
10259 button $top.${font}but -text $which -font optionfont \
10260 -command [list choosefont $font $which]
10261 label $top.$font -relief flat -font $font \
10262 -text $fontattr($font,family) -justify left
10263 grid x $top.${font}but $top.$font -sticky w
10264}
10265
10266proc choosefont {font which} {
10267 global fontparam fontlist fonttop fontattr
Alexander Gavrilov84a76f12008-11-02 18:59:4510268 global prefstop
Paul Mackerras9a7558f2007-10-06 10:16:0610269
10270 set fontparam(which) $which
10271 set fontparam(font) $font
10272 set fontparam(family) [font actual $font -family]
10273 set fontparam(size) $fontattr($font,size)
10274 set fontparam(weight) $fontattr($font,weight)
10275 set fontparam(slant) $fontattr($font,slant)
10276 set top .gitkfont
10277 set fonttop $top
10278 if {![winfo exists $top]} {
10279 font create sample
10280 eval font config sample [font actual $font]
10281 toplevel $top
Alexander Gavrilove7d64002008-11-11 20:55:4210282 make_transient $top $prefstop
Christian Stimmingd990ced2007-11-07 17:42:5510283 wm title $top [mc "Gitk font chooser"]
Paul Mackerrasb039f0a2008-01-06 04:54:4610284 label $top.l -textvariable fontparam(which)
Paul Mackerras9a7558f2007-10-06 10:16:0610285 pack $top.l -side top
10286 set fontlist [lsort [font families]]
10287 frame $top.f
10288 listbox $top.f.fam -listvariable fontlist \
10289 -yscrollcommand [list $top.f.sb set]
10290 bind $top.f.fam <<ListboxSelect>> selfontfam
10291 scrollbar $top.f.sb -command [list $top.f.fam yview]
10292 pack $top.f.sb -side right -fill y
10293 pack $top.f.fam -side left -fill both -expand 1
10294 pack $top.f -side top -fill both -expand 1
10295 frame $top.g
10296 spinbox $top.g.size -from 4 -to 40 -width 4 \
10297 -textvariable fontparam(size) \
10298 -validatecommand {string is integer -strict %s}
10299 checkbutton $top.g.bold -padx 5 \
Christian Stimmingd990ced2007-11-07 17:42:5510300 -font {{Times New Roman} 12 bold} -text [mc "B"] -indicatoron 0 \
Paul Mackerras9a7558f2007-10-06 10:16:0610301 -variable fontparam(weight) -onvalue bold -offvalue normal
10302 checkbutton $top.g.ital -padx 5 \
Christian Stimmingd990ced2007-11-07 17:42:5510303 -font {{Times New Roman} 12 italic} -text [mc "I"] -indicatoron 0 \
Paul Mackerras9a7558f2007-10-06 10:16:0610304 -variable fontparam(slant) -onvalue italic -offvalue roman
10305 pack $top.g.size $top.g.bold $top.g.ital -side left
10306 pack $top.g -side top
10307 canvas $top.c -width 150 -height 50 -border 2 -relief sunk \
10308 -background white
10309 $top.c create text 100 25 -anchor center -text $which -font sample \
10310 -fill black -tags text
10311 bind $top.c <Configure> [list centertext $top.c]
10312 pack $top.c -side top -fill x
10313 frame $top.buts
Paul Mackerrasb039f0a2008-01-06 04:54:4610314 button $top.buts.ok -text [mc "OK"] -command fontok -default active
10315 button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal
Alexander Gavrilov76f15942008-11-02 18:59:4410316 bind $top <Key-Return> fontok
10317 bind $top <Key-Escape> fontcan
Paul Mackerras9a7558f2007-10-06 10:16:0610318 grid $top.buts.ok $top.buts.can
10319 grid columnconfigure $top.buts 0 -weight 1 -uniform a
10320 grid columnconfigure $top.buts 1 -weight 1 -uniform a
10321 pack $top.buts -side bottom -fill x
10322 trace add variable fontparam write chg_fontparam
10323 } else {
10324 raise $top
10325 $top.c itemconf text -text $which
10326 }
10327 set i [lsearch -exact $fontlist $fontparam(family)]
10328 if {$i >= 0} {
10329 $top.f.fam selection set $i
10330 $top.f.fam see $i
10331 }
10332}
10333
10334proc centertext {w} {
10335 $w coords text [expr {[winfo width $w] / 2}] [expr {[winfo height $w] / 2}]
10336}
10337
10338proc fontok {} {
10339 global fontparam fontpref prefstop
10340
10341 set f $fontparam(font)
10342 set fontpref($f) [list $fontparam(family) $fontparam(size)]
10343 if {$fontparam(weight) eq "bold"} {
10344 lappend fontpref($f) "bold"
10345 }
10346 if {$fontparam(slant) eq "italic"} {
10347 lappend fontpref($f) "italic"
10348 }
10349 set w $prefstop.$f
10350 $w conf -text $fontparam(family) -font $fontpref($f)
10351
10352 fontcan
10353}
10354
10355proc fontcan {} {
10356 global fonttop fontparam
10357
10358 if {[info exists fonttop]} {
10359 catch {destroy $fonttop}
10360 catch {font delete sample}
10361 unset fonttop
10362 unset fontparam
10363 }
10364}
10365
10366proc selfontfam {} {
10367 global fonttop fontparam
10368
10369 set i [$fonttop.f.fam curselection]
10370 if {$i ne {}} {
10371 set fontparam(family) [$fonttop.f.fam get $i]
10372 }
10373}
10374
10375proc chg_fontparam {v sub op} {
10376 global fontparam
10377
10378 font config sample -$sub $fontparam($sub)
10379}
10380
Paul Mackerras712fcc02005-11-29 22:28:1610381proc doprefs {} {
Paul Mackerras8d73b242007-10-06 10:22:0010382 global maxwidth maxgraphpct
Paul Mackerras219ea3a2006-09-07 00:21:3910383 global oldprefs prefstop showneartags showlocalchanges
Paul Mackerrase3e901b2008-10-27 11:37:2110384 global bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor
Paul Mackerras39ee47e2008-10-15 11:23:0310385 global tabstop limitdiffs autoselect extdifftool perfile_attrs
Paul Mackerras232475d2005-11-14 23:34:0310386
Paul Mackerras712fcc02005-11-29 22:28:1610387 set top .gitkprefs
10388 set prefstop $top
10389 if {[winfo exists $top]} {
10390 raise $top
10391 return
Paul Mackerras757f17b2005-11-20 22:56:0710392 }
Paul Mackerras3de07112007-10-23 12:40:5010393 foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
Paul Mackerras39ee47e2008-10-15 11:23:0310394 limitdiffs tabstop perfile_attrs} {
Paul Mackerras712fcc02005-11-29 22:28:1610395 set oldprefs($v) [set $v]
Paul Mackerras232475d2005-11-14 23:34:0310396 }
Paul Mackerras712fcc02005-11-29 22:28:1610397 toplevel $top
Christian Stimmingd990ced2007-11-07 17:42:5510398 wm title $top [mc "Gitk preferences"]
Alexander Gavrilove7d64002008-11-11 20:55:4210399 make_transient $top .
Christian Stimmingd990ced2007-11-07 17:42:5510400 label $top.ldisp -text [mc "Commit list display options"]
Paul Mackerras712fcc02005-11-29 22:28:1610401 grid $top.ldisp - -sticky w -pady 10
10402 label $top.spacer -text " "
Christian Stimmingd990ced2007-11-07 17:42:5510403 label $top.maxwidthl -text [mc "Maximum graph width (lines)"] \
Paul Mackerras712fcc02005-11-29 22:28:1610404 -font optionfont
10405 spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
10406 grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
Christian Stimmingd990ced2007-11-07 17:42:5510407 label $top.maxpctl -text [mc "Maximum graph width (% of pane)"] \
Paul Mackerras712fcc02005-11-29 22:28:1610408 -font optionfont
10409 spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
10410 grid x $top.maxpctl $top.maxpct -sticky w
Johannes Sixtadcbec12008-12-02 20:42:1610411 checkbutton $top.showlocal -text [mc "Show local changes"] \
10412 -font optionfont -variable showlocalchanges
Paul Mackerras219ea3a2006-09-07 00:21:3910413 grid x $top.showlocal -sticky w
Johannes Sixtadcbec12008-12-02 20:42:1610414 checkbutton $top.autoselect -text [mc "Auto-select SHA1"] \
10415 -font optionfont -variable autoselect
Jeff King95293b52008-03-06 11:49:2510416 grid x $top.autoselect -sticky w
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710417
Christian Stimmingd990ced2007-11-07 17:42:5510418 label $top.ddisp -text [mc "Diff display options"]
Paul Mackerras712fcc02005-11-29 22:28:1610419 grid $top.ddisp - -sticky w -pady 10
Christian Stimmingd990ced2007-11-07 17:42:5510420 label $top.tabstopl -text [mc "Tab spacing"] -font optionfont
Paul Mackerras94503912007-10-23 00:33:3810421 spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop
10422 grid x $top.tabstopl $top.tabstop -sticky w
Johannes Sixtadcbec12008-12-02 20:42:1610423 checkbutton $top.ntag -text [mc "Display nearby tags"] \
10424 -font optionfont -variable showneartags
Paul Mackerrasb8ab2e12006-06-03 09:11:1310425 grid x $top.ntag -sticky w
Johannes Sixtadcbec12008-12-02 20:42:1610426 checkbutton $top.ldiff -text [mc "Limit diffs to listed paths"] \
10427 -font optionfont -variable limitdiffs
Paul Mackerras7a39a172007-10-23 00:15:1110428 grid x $top.ldiff -sticky w
Johannes Sixtadcbec12008-12-02 20:42:1610429 checkbutton $top.lattr -text [mc "Support per-file encodings"] \
10430 -font optionfont -variable perfile_attrs
Paul Mackerras39ee47e2008-10-15 11:23:0310431 grid x $top.lattr -sticky w
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710432
Thomas Arcila314f5de2008-03-24 11:55:3610433 entry $top.extdifft -textvariable extdifftool
10434 frame $top.extdifff
10435 label $top.extdifff.l -text [mc "External diff tool" ] -font optionfont \
10436 -padx 10
10437 button $top.extdifff.b -text [mc "Choose..."] -font optionfont \
10438 -command choose_extdiff
10439 pack $top.extdifff.l $top.extdifff.b -side left
10440 grid x $top.extdifff $top.extdifft -sticky w
10441
Christian Stimmingd990ced2007-11-07 17:42:5510442 label $top.cdisp -text [mc "Colors: press to choose"]
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710443 grid $top.cdisp - -sticky w -pady 10
10444 label $top.bg -padx 40 -relief sunk -background $bgcolor
Christian Stimmingd990ced2007-11-07 17:42:5510445 button $top.bgbut -text [mc "Background"] -font optionfont \
Christian Stimming968b0162008-12-06 19:48:3010446 -command [list choosecolor bgcolor {} $top.bg [mc "background"] setbg]
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710447 grid x $top.bgbut $top.bg -sticky w
10448 label $top.fg -padx 40 -relief sunk -background $fgcolor
Christian Stimmingd990ced2007-11-07 17:42:5510449 button $top.fgbut -text [mc "Foreground"] -font optionfont \
Christian Stimming968b0162008-12-06 19:48:3010450 -command [list choosecolor fgcolor {} $top.fg [mc "foreground"] setfg]
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710451 grid x $top.fgbut $top.fg -sticky w
10452 label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
Christian Stimmingd990ced2007-11-07 17:42:5510453 button $top.diffoldbut -text [mc "Diff: old lines"] -font optionfont \
Christian Stimming968b0162008-12-06 19:48:3010454 -command [list choosecolor diffcolors 0 $top.diffold [mc "diff old lines"] \
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710455 [list $ctext tag conf d0 -foreground]]
10456 grid x $top.diffoldbut $top.diffold -sticky w
10457 label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
Christian Stimmingd990ced2007-11-07 17:42:5510458 button $top.diffnewbut -text [mc "Diff: new lines"] -font optionfont \
Christian Stimming968b0162008-12-06 19:48:3010459 -command [list choosecolor diffcolors 1 $top.diffnew [mc "diff new lines"] \
Paul Mackerras8b07dca2008-11-02 11:34:4710460 [list $ctext tag conf dresult -foreground]]
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710461 grid x $top.diffnewbut $top.diffnew -sticky w
10462 label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
Christian Stimmingd990ced2007-11-07 17:42:5510463 button $top.hunksepbut -text [mc "Diff: hunk header"] -font optionfont \
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710464 -command [list choosecolor diffcolors 2 $top.hunksep \
Christian Stimming968b0162008-12-06 19:48:3010465 [mc "diff hunk header"] \
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710466 [list $ctext tag conf hunksep -foreground]]
10467 grid x $top.hunksepbut $top.hunksep -sticky w
Paul Mackerrase3e901b2008-10-27 11:37:2110468 label $top.markbgsep -padx 40 -relief sunk -background $markbgcolor
10469 button $top.markbgbut -text [mc "Marked line bg"] -font optionfont \
10470 -command [list choosecolor markbgcolor {} $top.markbgsep \
10471 [mc "marked line background"] \
10472 [list $ctext tag conf omark -background]]
10473 grid x $top.markbgbut $top.markbgsep -sticky w
Mark Levedahl60378c02007-05-20 16:12:4810474 label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor
Christian Stimmingd990ced2007-11-07 17:42:5510475 button $top.selbgbut -text [mc "Select bg"] -font optionfont \
Christian Stimming968b0162008-12-06 19:48:3010476 -command [list choosecolor selectbgcolor {} $top.selbgsep [mc "background"] setselbg]
Mark Levedahl60378c02007-05-20 16:12:4810477 grid x $top.selbgbut $top.selbgsep -sticky w
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710478
Christian Stimmingd990ced2007-11-07 17:42:5510479 label $top.cfont -text [mc "Fonts: press to choose"]
Paul Mackerras9a7558f2007-10-06 10:16:0610480 grid $top.cfont - -sticky w -pady 10
Christian Stimmingd990ced2007-11-07 17:42:5510481 mkfontdisp mainfont $top [mc "Main font"]
10482 mkfontdisp textfont $top [mc "Diff display font"]
10483 mkfontdisp uifont $top [mc "User interface font"]
Paul Mackerras9a7558f2007-10-06 10:16:0610484
Paul Mackerras712fcc02005-11-29 22:28:1610485 frame $top.buts
Christian Stimmingd990ced2007-11-07 17:42:5510486 button $top.buts.ok -text [mc "OK"] -command prefsok -default active
Christian Stimmingd990ced2007-11-07 17:42:5510487 button $top.buts.can -text [mc "Cancel"] -command prefscan -default normal
Alexander Gavrilov76f15942008-11-02 18:59:4410488 bind $top <Key-Return> prefsok
10489 bind $top <Key-Escape> prefscan
Paul Mackerras712fcc02005-11-29 22:28:1610490 grid $top.buts.ok $top.buts.can
10491 grid columnconfigure $top.buts 0 -weight 1 -uniform a
10492 grid columnconfigure $top.buts 1 -weight 1 -uniform a
10493 grid $top.buts - - -pady 10 -sticky ew
Eygene Ryabinkin3a950e92007-03-27 10:36:5910494 bind $top <Visibility> "focus $top.buts.ok"
Paul Mackerras712fcc02005-11-29 22:28:1610495}
10496
Thomas Arcila314f5de2008-03-24 11:55:3610497proc choose_extdiff {} {
10498 global extdifftool
10499
Michele Ballabiob56e0a92009-03-30 19:17:2510500 set prog [tk_getOpenFile -title [mc "External diff tool"] -multiple false]
Thomas Arcila314f5de2008-03-24 11:55:3610501 if {$prog ne {}} {
10502 set extdifftool $prog
10503 }
10504}
10505
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710506proc choosecolor {v vi w x cmd} {
10507 global $v
10508
10509 set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
Christian Stimmingd990ced2007-11-07 17:42:5510510 -title [mc "Gitk: choose color for %s" $x]]
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710511 if {$c eq {}} return
10512 $w conf -background $c
10513 lset $v $vi $c
10514 eval $cmd $c
10515}
10516
Mark Levedahl60378c02007-05-20 16:12:4810517proc setselbg {c} {
10518 global bglist cflist
10519 foreach w $bglist {
10520 $w configure -selectbackground $c
10521 }
10522 $cflist tag configure highlight \
10523 -background [$cflist cget -selectbackground]
10524 allcanvs itemconf secsel -fill $c
10525}
10526
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710527proc setbg {c} {
10528 global bglist
10529
10530 foreach w $bglist {
10531 $w conf -background $c
10532 }
10533}
10534
10535proc setfg {c} {
10536 global fglist canv
10537
10538 foreach w $fglist {
10539 $w conf -foreground $c
10540 }
10541 allcanvs itemconf text -fill $c
10542 $canv itemconf circle -outline $c
Paul Mackerrasb9fdba72009-04-08 23:34:4610543 $canv itemconf markid -outline $c
Paul Mackerrasf8a2c0d2006-07-05 12:56:3710544}
10545
Paul Mackerras712fcc02005-11-29 22:28:1610546proc prefscan {} {
Paul Mackerras94503912007-10-23 00:33:3810547 global oldprefs prefstop
Paul Mackerras712fcc02005-11-29 22:28:1610548
Paul Mackerras3de07112007-10-23 12:40:5010549 foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
Paul Mackerras39ee47e2008-10-15 11:23:0310550 limitdiffs tabstop perfile_attrs} {
Paul Mackerras94503912007-10-23 00:33:3810551 global $v
Paul Mackerras712fcc02005-11-29 22:28:1610552 set $v $oldprefs($v)
10553 }
10554 catch {destroy $prefstop}
10555 unset prefstop
Paul Mackerras9a7558f2007-10-06 10:16:0610556 fontcan
Paul Mackerras712fcc02005-11-29 22:28:1610557}
10558
10559proc prefsok {} {
10560 global maxwidth maxgraphpct
Paul Mackerras219ea3a2006-09-07 00:21:3910561 global oldprefs prefstop showneartags showlocalchanges
Paul Mackerras9a7558f2007-10-06 10:16:0610562 global fontpref mainfont textfont uifont
Paul Mackerras39ee47e2008-10-15 11:23:0310563 global limitdiffs treediffs perfile_attrs
Paul Mackerras712fcc02005-11-29 22:28:1610564
10565 catch {destroy $prefstop}
10566 unset prefstop
Paul Mackerras9a7558f2007-10-06 10:16:0610567 fontcan
10568 set fontchanged 0
10569 if {$mainfont ne $fontpref(mainfont)} {
10570 set mainfont $fontpref(mainfont)
10571 parsefont mainfont $mainfont
10572 eval font configure mainfont [fontflags mainfont]
10573 eval font configure mainfontbold [fontflags mainfont 1]
10574 setcoords
10575 set fontchanged 1
10576 }
10577 if {$textfont ne $fontpref(textfont)} {
10578 set textfont $fontpref(textfont)
10579 parsefont textfont $textfont
10580 eval font configure textfont [fontflags textfont]
10581 eval font configure textfontbold [fontflags textfont 1]
10582 }
10583 if {$uifont ne $fontpref(uifont)} {
10584 set uifont $fontpref(uifont)
10585 parsefont uifont $uifont
10586 eval font configure uifont [fontflags uifont]
10587 }
Paul Mackerras32f1b3e2007-09-28 11:27:3910588 settabs
Paul Mackerras219ea3a2006-09-07 00:21:3910589 if {$showlocalchanges != $oldprefs(showlocalchanges)} {
10590 if {$showlocalchanges} {
10591 doshowlocalchanges
10592 } else {
10593 dohidelocalchanges
10594 }
10595 }
Paul Mackerras39ee47e2008-10-15 11:23:0310596 if {$limitdiffs != $oldprefs(limitdiffs) ||
10597 ($perfile_attrs && !$oldprefs(perfile_attrs))} {
10598 # treediffs elements are limited by path;
10599 # won't have encodings cached if perfile_attrs was just turned on
Paul Mackerras74a40c72007-10-24 00:16:5610600 catch {unset treediffs}
10601 }
Paul Mackerras9a7558f2007-10-06 10:16:0610602 if {$fontchanged || $maxwidth != $oldprefs(maxwidth)
Paul Mackerras712fcc02005-11-29 22:28:1610603 || $maxgraphpct != $oldprefs(maxgraphpct)} {
10604 redisplay
Paul Mackerras7a39a172007-10-23 00:15:1110605 } elseif {$showneartags != $oldprefs(showneartags) ||
10606 $limitdiffs != $oldprefs(limitdiffs)} {
Paul Mackerrasb8ab2e12006-06-03 09:11:1310607 reselectline
Paul Mackerras712fcc02005-11-29 22:28:1610608 }
10609}
10610
10611proc formatdate {d} {
Arjen Laarhovene8b5f4b2007-08-14 20:02:0410612 global datetimeformat
Paul Mackerras219ea3a2006-09-07 00:21:3910613 if {$d ne {}} {
Arjen Laarhovene8b5f4b2007-08-14 20:02:0410614 set d [clock format $d -format $datetimeformat]
Paul Mackerras219ea3a2006-09-07 00:21:3910615 }
10616 return $d
Paul Mackerras232475d2005-11-14 23:34:0310617}
10618
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210619# This list of encoding names and aliases is distilled from
10620# http://www.iana.org/assignments/character-sets.
10621# Not all of them are supported by Tcl.
10622set encoding_aliases {
10623 { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
10624 ISO646-US US-ASCII us IBM367 cp367 csASCII }
10625 { ISO-10646-UTF-1 csISO10646UTF1 }
10626 { ISO_646.basic:1983 ref csISO646basic1983 }
10627 { INVARIANT csINVARIANT }
10628 { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
10629 { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
10630 { NATS-SEFI iso-ir-8-1 csNATSSEFI }
10631 { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
10632 { NATS-DANO iso-ir-9-1 csNATSDANO }
10633 { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
10634 { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
10635 { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
10636 { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
10637 { ISO-2022-KR csISO2022KR }
10638 { EUC-KR csEUCKR }
10639 { ISO-2022-JP csISO2022JP }
10640 { ISO-2022-JP-2 csISO2022JP2 }
10641 { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
10642 csISO13JISC6220jp }
10643 { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
10644 { IT iso-ir-15 ISO646-IT csISO15Italian }
10645 { PT iso-ir-16 ISO646-PT csISO16Portuguese }
10646 { ES iso-ir-17 ISO646-ES csISO17Spanish }
10647 { greek7-old iso-ir-18 csISO18Greek7Old }
10648 { latin-greek iso-ir-19 csISO19LatinGreek }
10649 { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
10650 { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
10651 { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
10652 { ISO_5427 iso-ir-37 csISO5427Cyrillic }
10653 { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
10654 { BS_viewdata iso-ir-47 csISO47BSViewdata }
10655 { INIS iso-ir-49 csISO49INIS }
10656 { INIS-8 iso-ir-50 csISO50INIS8 }
10657 { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
10658 { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
10659 { ISO_5428:1980 iso-ir-55 csISO5428Greek }
10660 { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
10661 { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
10662 { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
10663 csISO60Norwegian1 }
10664 { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
10665 { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
10666 { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
10667 { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
10668 { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
10669 { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
10670 { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
10671 { greek7 iso-ir-88 csISO88Greek7 }
10672 { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
10673 { iso-ir-90 csISO90 }
10674 { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
10675 { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
10676 csISO92JISC62991984b }
10677 { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
10678 { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
10679 { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
10680 csISO95JIS62291984handadd }
10681 { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
10682 { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
10683 { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
10684 { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
10685 CP819 csISOLatin1 }
10686 { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
10687 { T.61-7bit iso-ir-102 csISO102T617bit }
10688 { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
10689 { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
10690 { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
10691 { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
10692 { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
10693 { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
10694 { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
10695 { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
10696 arabic csISOLatinArabic }
10697 { ISO_8859-6-E csISO88596E ISO-8859-6-E }
10698 { ISO_8859-6-I csISO88596I ISO-8859-6-I }
10699 { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
10700 greek greek8 csISOLatinGreek }
10701 { T.101-G2 iso-ir-128 csISO128T101G2 }
10702 { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
10703 csISOLatinHebrew }
10704 { ISO_8859-8-E csISO88598E ISO-8859-8-E }
10705 { ISO_8859-8-I csISO88598I ISO-8859-8-I }
10706 { CSN_369103 iso-ir-139 csISO139CSN369103 }
10707 { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
10708 { ISO_6937-2-add iso-ir-142 csISOTextComm }
10709 { IEC_P27-1 iso-ir-143 csISO143IECP271 }
10710 { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
10711 csISOLatinCyrillic }
10712 { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
10713 { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
10714 { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
10715 { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
10716 { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
10717 { ISO_6937-2-25 iso-ir-152 csISO6937Add }
10718 { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
10719 { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
10720 { ISO_10367-box iso-ir-155 csISO10367Box }
10721 { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
10722 { latin-lap lap iso-ir-158 csISO158Lap }
10723 { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
10724 { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
10725 { us-dk csUSDK }
10726 { dk-us csDKUS }
10727 { JIS_X0201 X0201 csHalfWidthKatakana }
10728 { KSC5636 ISO646-KR csKSC5636 }
10729 { ISO-10646-UCS-2 csUnicode }
10730 { ISO-10646-UCS-4 csUCS4 }
10731 { DEC-MCS dec csDECMCS }
10732 { hp-roman8 roman8 r8 csHPRoman8 }
10733 { macintosh mac csMacintosh }
10734 { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
10735 csIBM037 }
10736 { IBM038 EBCDIC-INT cp038 csIBM038 }
10737 { IBM273 CP273 csIBM273 }
10738 { IBM274 EBCDIC-BE CP274 csIBM274 }
10739 { IBM275 EBCDIC-BR cp275 csIBM275 }
10740 { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
10741 { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
10742 { IBM280 CP280 ebcdic-cp-it csIBM280 }
10743 { IBM281 EBCDIC-JP-E cp281 csIBM281 }
10744 { IBM284 CP284 ebcdic-cp-es csIBM284 }
10745 { IBM285 CP285 ebcdic-cp-gb csIBM285 }
10746 { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
10747 { IBM297 cp297 ebcdic-cp-fr csIBM297 }
10748 { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
10749 { IBM423 cp423 ebcdic-cp-gr csIBM423 }
10750 { IBM424 cp424 ebcdic-cp-he csIBM424 }
10751 { IBM437 cp437 437 csPC8CodePage437 }
10752 { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
10753 { IBM775 cp775 csPC775Baltic }
10754 { IBM850 cp850 850 csPC850Multilingual }
10755 { IBM851 cp851 851 csIBM851 }
10756 { IBM852 cp852 852 csPCp852 }
10757 { IBM855 cp855 855 csIBM855 }
10758 { IBM857 cp857 857 csIBM857 }
10759 { IBM860 cp860 860 csIBM860 }
10760 { IBM861 cp861 861 cp-is csIBM861 }
10761 { IBM862 cp862 862 csPC862LatinHebrew }
10762 { IBM863 cp863 863 csIBM863 }
10763 { IBM864 cp864 csIBM864 }
10764 { IBM865 cp865 865 csIBM865 }
10765 { IBM866 cp866 866 csIBM866 }
10766 { IBM868 CP868 cp-ar csIBM868 }
10767 { IBM869 cp869 869 cp-gr csIBM869 }
10768 { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
10769 { IBM871 CP871 ebcdic-cp-is csIBM871 }
10770 { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
10771 { IBM891 cp891 csIBM891 }
10772 { IBM903 cp903 csIBM903 }
10773 { IBM904 cp904 904 csIBBM904 }
10774 { IBM905 CP905 ebcdic-cp-tr csIBM905 }
10775 { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
10776 { IBM1026 CP1026 csIBM1026 }
10777 { EBCDIC-AT-DE csIBMEBCDICATDE }
10778 { EBCDIC-AT-DE-A csEBCDICATDEA }
10779 { EBCDIC-CA-FR csEBCDICCAFR }
10780 { EBCDIC-DK-NO csEBCDICDKNO }
10781 { EBCDIC-DK-NO-A csEBCDICDKNOA }
10782 { EBCDIC-FI-SE csEBCDICFISE }
10783 { EBCDIC-FI-SE-A csEBCDICFISEA }
10784 { EBCDIC-FR csEBCDICFR }
10785 { EBCDIC-IT csEBCDICIT }
10786 { EBCDIC-PT csEBCDICPT }
10787 { EBCDIC-ES csEBCDICES }
10788 { EBCDIC-ES-A csEBCDICESA }
10789 { EBCDIC-ES-S csEBCDICESS }
10790 { EBCDIC-UK csEBCDICUK }
10791 { EBCDIC-US csEBCDICUS }
10792 { UNKNOWN-8BIT csUnknown8BiT }
10793 { MNEMONIC csMnemonic }
10794 { MNEM csMnem }
10795 { VISCII csVISCII }
10796 { VIQR csVIQR }
10797 { KOI8-R csKOI8R }
10798 { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
10799 { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
10800 { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
10801 { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
10802 { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
10803 { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
10804 { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
10805 { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
10806 { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
10807 { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
10808 { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
10809 { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
10810 { IBM1047 IBM-1047 }
10811 { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
10812 { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
10813 { UNICODE-1-1 csUnicode11 }
10814 { CESU-8 csCESU-8 }
10815 { BOCU-1 csBOCU-1 }
10816 { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
10817 { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
10818 l8 }
10819 { ISO-8859-15 ISO_8859-15 Latin-9 }
10820 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
10821 { GBK CP936 MS936 windows-936 }
10822 { JIS_Encoding csJISEncoding }
Alexander Gavrilov09c70292008-10-13 08:12:3110823 { Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS }
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210824 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
10825 EUC-JP }
10826 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
10827 { ISO-10646-UCS-Basic csUnicodeASCII }
10828 { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
10829 { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
10830 { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
10831 { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
10832 { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
10833 { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
10834 { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
10835 { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
10836 { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
10837 { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
10838 { Adobe-Standard-Encoding csAdobeStandardEncoding }
10839 { Ventura-US csVenturaUS }
10840 { Ventura-International csVenturaInternational }
10841 { PC8-Danish-Norwegian csPC8DanishNorwegian }
10842 { PC8-Turkish csPC8Turkish }
10843 { IBM-Symbols csIBMSymbols }
10844 { IBM-Thai csIBMThai }
10845 { HP-Legal csHPLegal }
10846 { HP-Pi-font csHPPiFont }
10847 { HP-Math8 csHPMath8 }
10848 { Adobe-Symbol-Encoding csHPPSMath }
10849 { HP-DeskTop csHPDesktop }
10850 { Ventura-Math csVenturaMath }
10851 { Microsoft-Publishing csMicrosoftPublishing }
10852 { Windows-31J csWindows31J }
10853 { GB2312 csGB2312 }
10854 { Big5 csBig5 }
10855}
10856
10857proc tcl_encoding {enc} {
Paul Mackerras39ee47e2008-10-15 11:23:0310858 global encoding_aliases tcl_encoding_cache
10859 if {[info exists tcl_encoding_cache($enc)]} {
10860 return $tcl_encoding_cache($enc)
10861 }
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210862 set names [encoding names]
10863 set lcnames [string tolower $names]
10864 set enc [string tolower $enc]
10865 set i [lsearch -exact $lcnames $enc]
10866 if {$i < 0} {
10867 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
Alexander Gavrilov09c70292008-10-13 08:12:3110868 if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} {
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210869 set i [lsearch -exact $lcnames $encx]
10870 }
10871 }
10872 if {$i < 0} {
10873 foreach l $encoding_aliases {
10874 set ll [string tolower $l]
10875 if {[lsearch -exact $ll $enc] < 0} continue
10876 # look through the aliases for one that tcl knows about
10877 foreach e $ll {
10878 set i [lsearch -exact $lcnames $e]
10879 if {$i < 0} {
Alexander Gavrilov09c70292008-10-13 08:12:3110880 if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\1} ex]} {
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210881 set i [lsearch -exact $lcnames $ex]
10882 }
10883 }
10884 if {$i >= 0} break
10885 }
10886 break
10887 }
10888 }
Paul Mackerras39ee47e2008-10-15 11:23:0310889 set tclenc {}
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210890 if {$i >= 0} {
Paul Mackerras39ee47e2008-10-15 11:23:0310891 set tclenc [lindex $names $i]
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210892 }
Paul Mackerras39ee47e2008-10-15 11:23:0310893 set tcl_encoding_cache($enc) $tclenc
10894 return $tclenc
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210895}
10896
Alexander Gavrilov09c70292008-10-13 08:12:3110897proc gitattr {path attr default} {
Paul Mackerras39ee47e2008-10-15 11:23:0310898 global path_attr_cache
10899 if {[info exists path_attr_cache($attr,$path)]} {
10900 set r $path_attr_cache($attr,$path)
10901 } else {
10902 set r "unspecified"
10903 if {![catch {set line [exec git check-attr $attr -- $path]}]} {
10904 regexp "(.*): encoding: (.*)" $line m f r
Alexander Gavrilov09c70292008-10-13 08:12:3110905 }
Alexander Gavrilov4db09302008-10-13 08:12:3310906 set path_attr_cache($attr,$path) $r
Paul Mackerras39ee47e2008-10-15 11:23:0310907 }
10908 if {$r eq "unspecified"} {
10909 return $default
10910 }
10911 return $r
Alexander Gavrilov09c70292008-10-13 08:12:3110912}
10913
Alexander Gavrilov4db09302008-10-13 08:12:3310914proc cache_gitattr {attr pathlist} {
Paul Mackerras39ee47e2008-10-15 11:23:0310915 global path_attr_cache
10916 set newlist {}
10917 foreach path $pathlist {
10918 if {![info exists path_attr_cache($attr,$path)]} {
10919 lappend newlist $path
Alexander Gavrilov4db09302008-10-13 08:12:3310920 }
Paul Mackerras39ee47e2008-10-15 11:23:0310921 }
10922 set lim 1000
10923 if {[tk windowingsystem] == "win32"} {
10924 # windows has a 32k limit on the arguments to a command...
10925 set lim 30
10926 }
10927 while {$newlist ne {}} {
10928 set head [lrange $newlist 0 [expr {$lim - 1}]]
10929 set newlist [lrange $newlist $lim end]
10930 if {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {
10931 foreach row [split $rlist "\n"] {
10932 if {[regexp "(.*): encoding: (.*)" $row m path value]} {
10933 if {[string index $path 0] eq "\""} {
10934 set path [encoding convertfrom [lindex $path 0]]
10935 }
10936 set path_attr_cache($attr,$path) $value
Alexander Gavrilov4db09302008-10-13 08:12:3310937 }
Paul Mackerras39ee47e2008-10-15 11:23:0310938 }
Alexander Gavrilov4db09302008-10-13 08:12:3310939 }
Paul Mackerras39ee47e2008-10-15 11:23:0310940 }
Alexander Gavrilov4db09302008-10-13 08:12:3310941}
10942
Alexander Gavrilov09c70292008-10-13 08:12:3110943proc get_path_encoding {path} {
Paul Mackerras39ee47e2008-10-15 11:23:0310944 global gui_encoding perfile_attrs
10945 set tcl_enc $gui_encoding
10946 if {$path ne {} && $perfile_attrs} {
10947 set enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]
10948 if {$enc2 ne {}} {
10949 set tcl_enc $enc2
Alexander Gavrilov09c70292008-10-13 08:12:3110950 }
Paul Mackerras39ee47e2008-10-15 11:23:0310951 }
10952 return $tcl_enc
Alexander Gavrilov09c70292008-10-13 08:12:3110953}
10954
Paul Mackerras5d7589d2007-10-20 11:21:0310955# First check that Tcl/Tk is recent enough
10956if {[catch {package require Tk 8.4} err]} {
Christian Stimmingd990ced2007-11-07 17:42:5510957 show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
10958 Gitk requires at least Tcl/Tk 8.4."]
Paul Mackerras5d7589d2007-10-20 11:21:0310959 exit 1
10960}
10961
Paul Mackerras1d10f362005-05-15 12:55:4710962# defaults...
Timo Hirvonen8974c6f2006-05-24 07:57:4010963set wrcomcmd "git diff-tree --stdin -p --pretty"
Junio C Hamano671bc152005-11-28 00:12:5110964
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210965set gitencoding {}
Junio C Hamano671bc152005-11-28 00:12:5110966catch {
Paul Mackerras27cb61c2007-02-14 21:54:3410967 set gitencoding [exec git config --get i18n.commitencoding]
Junio C Hamano671bc152005-11-28 00:12:5110968}
Alexander Gavrilov590915d2008-11-09 15:06:0710969catch {
10970 set gitencoding [exec git config --get i18n.logoutputencoding]
10971}
Junio C Hamano671bc152005-11-28 00:12:5110972if {$gitencoding == ""} {
Paul Mackerrasfd8ccbe2005-12-07 12:28:2210973 set gitencoding "utf-8"
10974}
10975set tclencoding [tcl_encoding $gitencoding]
10976if {$tclencoding == {}} {
10977 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
Junio C Hamano671bc152005-11-28 00:12:5110978}
Paul Mackerras1d10f362005-05-15 12:55:4710979
Alexander Gavrilov09c70292008-10-13 08:12:3110980set gui_encoding [encoding system]
10981catch {
Paul Mackerras39ee47e2008-10-15 11:23:0310982 set enc [exec git config --get gui.encoding]
10983 if {$enc ne {}} {
10984 set tclenc [tcl_encoding $enc]
10985 if {$tclenc ne {}} {
10986 set gui_encoding $tclenc
10987 } else {
10988 puts stderr "Warning: encoding $enc is not supported by Tcl/Tk"
10989 }
10990 }
Alexander Gavrilov09c70292008-10-13 08:12:3110991}
10992
Daniel A. Steffen5fdcbb12009-03-23 11:17:3810993if {[tk windowingsystem] eq "aqua"} {
10994 set mainfont {{Lucida Grande} 9}
10995 set textfont {Monaco 9}
10996 set uifont {{Lucida Grande} 9 bold}
10997} else {
10998 set mainfont {Helvetica 9}
10999 set textfont {Courier 9}
11000 set uifont {Helvetica 9 bold}
11001}
Mark Levedahl7e12f1a2007-05-20 15:45:5011002set tabstop 8
Paul Mackerrasb74fd572005-07-16 11:46:1311003set findmergefiles 0
Paul Mackerras8d858d12005-08-04 23:52:1611004set maxgraphpct 50
Paul Mackerrasf6075eb2005-08-17 23:30:1011005set maxwidth 16
Paul Mackerras232475d2005-11-14 23:34:0311006set revlistorder 0
Paul Mackerras757f17b2005-11-20 22:56:0711007set fastdate 0
Paul Mackerras6e8c8702007-07-31 11:03:0611008set uparrowlen 5
11009set downarrowlen 5
11010set mingaplen 100
Paul Mackerrasf8b28a42006-04-30 23:50:5711011set cmitmode "patch"
Sergey Vlasovf1b86292006-05-15 15:13:1411012set wrapcomment "none"
Paul Mackerrasb8ab2e12006-06-03 09:11:1311013set showneartags 1
Paul Mackerras0a4dd8b2007-06-16 11:21:5711014set maxrefs 20
Paul Mackerras322a8cc2006-10-15 08:03:4611015set maxlinelen 200
Paul Mackerras219ea3a2006-09-07 00:21:3911016set showlocalchanges 1
Paul Mackerras7a39a172007-10-23 00:15:1111017set limitdiffs 1
Arjen Laarhovene8b5f4b2007-08-14 20:02:0411018set datetimeformat "%Y-%m-%d %H:%M:%S"
Jeff King95293b52008-03-06 11:49:2511019set autoselect 1
Paul Mackerras39ee47e2008-10-15 11:23:0311020set perfile_attrs 0
Paul Mackerras1d10f362005-05-15 12:55:4711021
Daniel A. Steffen5fdcbb12009-03-23 11:17:3811022if {[tk windowingsystem] eq "aqua"} {
11023 set extdifftool "opendiff"
11024} else {
11025 set extdifftool "meld"
11026}
Thomas Arcila314f5de2008-03-24 11:55:3611027
Paul Mackerras1d10f362005-05-15 12:55:4711028set colors {green red blue magenta darkgrey brown orange}
Paul Mackerrasf8a2c0d2006-07-05 12:56:3711029set bgcolor white
11030set fgcolor black
11031set diffcolors {red "#00a000" blue}
Steffen Prohaska890fae72007-08-12 10:05:4611032set diffcontext 3
Steffen Prohaskab9b86002008-01-17 22:42:5511033set ignorespace 0
Mark Levedahl60378c02007-05-20 16:12:4811034set selectbgcolor gray85
Paul Mackerrase3e901b2008-10-27 11:37:2111035set markbgcolor "#e0e0ff"
Paul Mackerras1d10f362005-05-15 12:55:4711036
Paul Mackerrasc11ff122008-05-26 00:11:3311037set circlecolors {white blue gray blue blue}
11038
Paul Mackerrasd277e892008-09-21 23:11:3711039# button for popping up context menus
11040if {[tk windowingsystem] eq "aqua"} {
11041 set ctxbut <Button-2>
11042} else {
11043 set ctxbut <Button-3>
11044}
11045
Christian Stimming663c3aa2007-11-07 17:40:5911046## For msgcat loading, first locate the installation location.
11047if { [info exists ::env(GITK_MSGSDIR)] } {
11048 ## Msgsdir was manually set in the environment.
11049 set gitk_msgsdir $::env(GITK_MSGSDIR)
11050} else {
11051 ## Let's guess the prefix from argv0.
11052 set gitk_prefix [file dirname [file dirname [file normalize $argv0]]]
11053 set gitk_libdir [file join $gitk_prefix share gitk lib]
11054 set gitk_msgsdir [file join $gitk_libdir msgs]
11055 unset gitk_prefix
11056}
11057
11058## Internationalization (i18n) through msgcat and gettext. See
11059## http://www.gnu.org/software/gettext/manual/html_node/Tcl.html
11060package require msgcat
11061namespace import ::msgcat::mc
11062## And eventually load the actual message catalog
11063::msgcat::mcload $gitk_msgsdir
11064
Paul Mackerras1d10f362005-05-15 12:55:4711065catch {source ~/.gitk}
11066
Paul Mackerras712fcc02005-11-29 22:28:1611067font create optionfont -family sans-serif -size -12
Paul Mackerras17386062005-05-18 22:51:0011068
Paul Mackerras0ed1dd32007-10-06 08:27:3711069parsefont mainfont $mainfont
11070eval font create mainfont [fontflags mainfont]
11071eval font create mainfontbold [fontflags mainfont 1]
11072
11073parsefont textfont $textfont
11074eval font create textfont [fontflags textfont]
11075eval font create textfontbold [fontflags textfont 1]
11076
11077parsefont uifont $uifont
11078eval font create uifont [fontflags uifont]
Paul Mackerras17386062005-05-18 22:51:0011079
Paul Mackerrasb039f0a2008-01-06 04:54:4611080setoptions
11081
Paul Mackerrasaa81d972006-02-28 00:27:1211082# check that we can find a .git directory somewhere...
Alex Riesen6c87d602007-07-29 20:29:4511083if {[catch {set gitdir [gitdir]}]} {
Christian Stimmingd990ced2007-11-07 17:42:5511084 show_error {} . [mc "Cannot find a git repository here."]
Alex Riesen6c87d602007-07-29 20:29:4511085 exit 1
11086}
Paul Mackerrasaa81d972006-02-28 00:27:1211087if {![file isdirectory $gitdir]} {
Christian Stimmingd990ced2007-11-07 17:42:5511088 show_error {} . [mc "Cannot find the git directory \"%s\"." $gitdir]
Paul Mackerrasaa81d972006-02-28 00:27:1211089 exit 1
11090}
11091
Alexander Gavrilov39816d62008-08-23 08:27:4411092set selecthead {}
11093set selectheadid {}
11094
Paul Mackerrascdaee5d2007-07-12 12:29:4911095set revtreeargs {}
Paul Mackerras098dd8a2006-05-02 23:32:5311096set cmdline_files {}
Paul Mackerrascdaee5d2007-07-12 12:29:4911097set i 0
Yann Dirson2d480852008-02-21 20:23:3111098set revtreeargscmd {}
Paul Mackerrascdaee5d2007-07-12 12:29:4911099foreach arg $argv {
Yann Dirson2d480852008-02-21 20:23:3111100 switch -glob -- $arg {
Paul Mackerras6ebedab2007-07-13 03:45:5511101 "" { }
Paul Mackerrascdaee5d2007-07-12 12:29:4911102 "--" {
11103 set cmdline_files [lrange $argv [expr {$i + 1}] end]
11104 break
11105 }
Alexander Gavrilov39816d62008-08-23 08:27:4411106 "--select-commit=*" {
11107 set selecthead [string range $arg 16 end]
11108 }
Yann Dirson2d480852008-02-21 20:23:3111109 "--argscmd=*" {
11110 set revtreeargscmd [string range $arg 10 end]
11111 }
Paul Mackerrascdaee5d2007-07-12 12:29:4911112 default {
11113 lappend revtreeargs $arg
11114 }
11115 }
11116 incr i
11117}
11118
Alexander Gavrilov39816d62008-08-23 08:27:4411119if {$selecthead eq "HEAD"} {
11120 set selecthead {}
11121}
11122
Paul Mackerrascdaee5d2007-07-12 12:29:4911123if {$i >= [llength $argv] && $revtreeargs ne {}} {
Paul Mackerras3ed31a82008-04-26 06:00:0011124 # no -- on command line, but some arguments (other than --argscmd)
Paul Mackerras098dd8a2006-05-02 23:32:5311125 if {[catch {
Timo Hirvonen8974c6f2006-05-24 07:57:4011126 set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
Paul Mackerras098dd8a2006-05-02 23:32:5311127 set cmdline_files [split $f "\n"]
11128 set n [llength $cmdline_files]
11129 set revtreeargs [lrange $revtreeargs 0 end-$n]
Paul Mackerrascdaee5d2007-07-12 12:29:4911130 # Unfortunately git rev-parse doesn't produce an error when
11131 # something is both a revision and a filename. To be consistent
11132 # with git log and git rev-list, check revtreeargs for filenames.
11133 foreach arg $revtreeargs {
11134 if {[file exists $arg]} {
Christian Stimmingd990ced2007-11-07 17:42:5511135 show_error {} . [mc "Ambiguous argument '%s': both revision\
11136 and filename" $arg]
Paul Mackerrascdaee5d2007-07-12 12:29:4911137 exit 1
11138 }
11139 }
Paul Mackerras098dd8a2006-05-02 23:32:5311140 } err]} {
11141 # unfortunately we get both stdout and stderr in $err,
11142 # so look for "fatal:".
11143 set i [string first "fatal:" $err]
11144 if {$i > 0} {
Junio C Hamanob5e09632006-05-26 07:07:1511145 set err [string range $err [expr {$i + 6}] end]
Paul Mackerras098dd8a2006-05-02 23:32:5311146 }
Christian Stimmingd990ced2007-11-07 17:42:5511147 show_error {} . "[mc "Bad arguments to gitk:"]\n$err"
Paul Mackerras098dd8a2006-05-02 23:32:5311148 exit 1
11149 }
11150}
11151
Paul Mackerras219ea3a2006-09-07 00:21:3911152set nullid "0000000000000000000000000000000000000000"
Paul Mackerras8f489362007-07-13 09:49:3711153set nullid2 "0000000000000000000000000000000000000001"
Thomas Arcila314f5de2008-03-24 11:55:3611154set nullfile "/dev/null"
Paul Mackerras8f489362007-07-13 09:49:3711155
Paul Mackerras32f1b3e2007-09-28 11:27:3911156set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
Pat Thoyts194bbf62009-05-18 21:46:0111157set git_version [join [lrange [split [lindex [exec git version] end] .] 0 2] .]
Paul Mackerras219ea3a2006-09-07 00:21:3911158
Paul Mackerras7eb3cb92007-06-17 04:45:0011159set runq {}
Paul Mackerrasd6982062005-08-06 12:06:0611160set history {}
11161set historyindex 0
Paul Mackerras908c3582006-05-19 23:38:1111162set fh_serial 0
Paul Mackerras908c3582006-05-19 23:38:1111163set nhl_names {}
Paul Mackerras63b79192006-05-20 11:31:5211164set highlight_paths {}
Paul Mackerras687c8762007-09-22 02:49:3311165set findpattern {}
Paul Mackerras1902c272006-05-25 11:25:1311166set searchdirn -forwards
Paul Mackerras28593d32008-11-13 12:01:4611167set boldids {}
11168set boldnameids {}
Paul Mackerrasa8d610a2007-04-19 01:39:1211169set diffelide {0 0}
Paul Mackerras4fb0fa12007-07-04 09:43:5111170set markingmatches 0
Paul Mackerras97645682007-08-23 12:24:3811171set linkentercount 0
Paul Mackerras03800812007-08-29 11:45:2111172set need_redisplay 0
11173set nrows_drawn 0
Paul Mackerras32f1b3e2007-09-28 11:27:3911174set firsttabstop 0
Paul Mackerras9f1afe02006-02-19 11:44:4711175
Paul Mackerras50b44ec2006-04-04 00:16:2211176set nextviewnum 1
11177set curview 0
Paul Mackerrasa90a6d22006-04-25 07:12:4611178set selectedview 0
Christian Stimmingb007ee22007-11-07 17:44:3511179set selectedhlview [mc "None"]
11180set highlight_related [mc "None"]
Paul Mackerras687c8762007-09-22 02:49:3311181set highlight_files {}
Paul Mackerras50b44ec2006-04-04 00:16:2211182set viewfiles(0) {}
Paul Mackerrasa90a6d22006-04-25 07:12:4611183set viewperm(0) 0
Paul Mackerras098dd8a2006-05-02 23:32:5311184set viewargs(0) {}
Yann Dirson2d480852008-02-21 20:23:3111185set viewargscmd(0) {}
Paul Mackerras50b44ec2006-04-04 00:16:2211186
Paul Mackerras94b4a692008-05-20 10:51:0611187set selectedline {}
Paul Mackerras6df74032008-05-11 12:13:0211188set numcommits 0
Paul Mackerras7fcc92b2007-12-02 23:33:0111189set loginstance 0
Paul Mackerras098dd8a2006-05-02 23:32:5311190set cmdlineok 0
Paul Mackerras1d10f362005-05-15 12:55:4711191set stopped 0
Paul Mackerras0fba86b2005-05-16 23:54:5811192set stuffsaved 0
Paul Mackerras74daedb2005-06-27 09:27:3211193set patchnum 0
Paul Mackerras219ea3a2006-09-07 00:21:3911194set lserial 0
David Aguilarcb8329a2008-03-10 10:54:5611195set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
Paul Mackerras1d10f362005-05-15 12:55:4711196setcoords
Paul Mackerrasd94f8cd2006-04-06 00:18:2311197makewindow
Giuseppe Bilotta37871b72009-03-19 08:54:1711198catch {
11199 image create photo gitlogo -width 16 -height 16
11200
11201 image create photo gitlogominus -width 4 -height 2
11202 gitlogominus put #C00000 -to 0 0 4 2
11203 gitlogo copy gitlogominus -to 1 5
11204 gitlogo copy gitlogominus -to 6 5
11205 gitlogo copy gitlogominus -to 11 5
11206 image delete gitlogominus
11207
11208 image create photo gitlogoplus -width 4 -height 4
11209 gitlogoplus put #008000 -to 1 0 3 4
11210 gitlogoplus put #008000 -to 0 1 4 3
11211 gitlogo copy gitlogoplus -to 1 9
11212 gitlogo copy gitlogoplus -to 6 9
11213 gitlogo copy gitlogoplus -to 11 9
11214 image delete gitlogoplus
11215
Stephen Boydd38d7d42009-03-19 08:54:1811216 image create photo gitlogo32 -width 32 -height 32
11217 gitlogo32 copy gitlogo -zoom 2 2
11218
11219 wm iconphoto . -default gitlogo gitlogo32
Giuseppe Bilotta37871b72009-03-19 08:54:1711220}
Paul Mackerras0eafba12007-07-23 11:35:0311221# wait for the window to become visible
11222tkwait visibility .
Doug Maxey6c283322006-12-10 20:31:4611223wm title . "[file tail $argv0]: [file tail [pwd]]"
Pat Thoyts478afad2009-04-15 16:14:0311224update
Paul Mackerras887fe3c2005-05-21 07:35:3711225readrefs
Paul Mackerrasa8aaf192006-04-23 12:45:5511226
Yann Dirson2d480852008-02-21 20:23:3111227if {$cmdline_files ne {} || $revtreeargs ne {} || $revtreeargscmd ne {}} {
Paul Mackerras50b44ec2006-04-04 00:16:2211228 # create a view for the files/dirs specified on the command line
11229 set curview 1
Paul Mackerrasa90a6d22006-04-25 07:12:4611230 set selectedview 1
Paul Mackerras50b44ec2006-04-04 00:16:2211231 set nextviewnum 2
Christian Stimmingd990ced2007-11-07 17:42:5511232 set viewname(1) [mc "Command line"]
Paul Mackerras50b44ec2006-04-04 00:16:2211233 set viewfiles(1) $cmdline_files
Paul Mackerras098dd8a2006-05-02 23:32:5311234 set viewargs(1) $revtreeargs
Yann Dirson2d480852008-02-21 20:23:3111235 set viewargscmd(1) $revtreeargscmd
Paul Mackerrasa90a6d22006-04-25 07:12:4611236 set viewperm(1) 0
Paul Mackerras3ed31a82008-04-26 06:00:0011237 set vdatemode(1) 0
Paul Mackerrasda7c24d2006-05-02 01:15:2911238 addviewmenu 1
Paul Mackerrasf2d0bbb2008-10-17 11:44:4211239 .bar.view entryconf [mca "Edit view..."] -state normal
11240 .bar.view entryconf [mca "Delete view"] -state normal
Paul Mackerras50b44ec2006-04-04 00:16:2211241}
Paul Mackerrasa90a6d22006-04-25 07:12:4611242
11243if {[info exists permviews]} {
11244 foreach v $permviews {
11245 set n $nextviewnum
11246 incr nextviewnum
11247 set viewname($n) [lindex $v 0]
11248 set viewfiles($n) [lindex $v 1]
Paul Mackerras098dd8a2006-05-02 23:32:5311249 set viewargs($n) [lindex $v 2]
Yann Dirson2d480852008-02-21 20:23:3111250 set viewargscmd($n) [lindex $v 3]
Paul Mackerrasa90a6d22006-04-25 07:12:4611251 set viewperm($n) 1
Paul Mackerrasda7c24d2006-05-02 01:15:2911252 addviewmenu $n
Paul Mackerrasa90a6d22006-04-25 07:12:4611253 }
11254}
Johannes Sixte4df5192008-12-18 07:30:4911255
11256if {[tk windowingsystem] eq "win32"} {
11257 focus -force .
11258}
11259
Alexander Gavrilov567c34e2008-07-26 16:13:4511260getcommits {}