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