︙ | | | ︙ | |
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# Add a dummy if it does not exists.
proc addBalloon {args} {}
} else {
namespace import -force psballoon::addBalloon
}
set debug 0
set diffver "Version 2.0b1 2003-12-05"
set thisScript [file join [pwd] [info script]]
set thisDir [file dirname $thisScript]
# Follow any link
set tmplink $thisScript
while {[file type $tmplink] == "link"} {
set tmplink [file readlink $tmplink]
set tmplink [file normalize [file join $thisDir $tmplink]]
set thisDir [file dirname $tmplink]
}
unset tmplink
set ::util(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
set ::util(diffexe) diff
set ::util(diffWrapped) 0
# Experimenting with DiffUtil package
#set ::diff(diffutil) [expr {![catch {package require DiffUtil}]}]
set ::diff(diffutil) 0
# Figure out a place to store temporary files.
if {[info exists env(TEMP)] && [file writable $env(TEMP)]} {
set ::diff(tmpdir) $env(TEMP)
} elseif {[info exists env(TMP)] && [file writable $env(TMP)]} {
set ::diff(tmpdir) $env(TMP)
} elseif {[file writable /tmp]} {
set ::diff(tmpdir) /tmp
} elseif {[file writable .]} {
set ::diff(tmpdir) .
} elseif {[file writable ~]} {
set ::diff(tmpdir) ~
} else {
# Panic?
set ::diff(tmpdir) .
}
# Locate a diff executable on windows.
proc locateDiffExe {} {
global thisDir util
# Build a list of possible directories.
set dirs [list $thisDir]
# Are we in a starkit?
if {[string match "*/lib/app-diff" $thisDir]} {
lappend dirs [file dirname [file dirname [file dirname $thisDir]]]
# And for a starpack
lappend dirs [file dirname [info nameofexecutable]]
}
lappend dirs c:/bin
foreach dir $dirs {
set try [file join $dir diff.exe]
if {[file exists $try]} {
set util(diffexe) $try
return
}
}
if {[string equal [auto_execok diff] ""]} {
tk_messageBox -icon error -title "Diff Error" -message \
"Could not locate any external diff executable." \
|
|
|
|
<
<
|
|
|
|
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# Add a dummy if it does not exists.
proc addBalloon {args} {}
} else {
namespace import -force psballoon::addBalloon
}
set debug 0
set diffver "Version 2.0b1+ 2003-12-09"
set thisScript [file join [pwd] [info script]]
set thisDir [file dirname $thisScript]
# Follow any link
set tmplink $thisScript
while {[file type $tmplink] == "link"} {
set tmplink [file readlink $tmplink]
set tmplink [file normalize [file join $thisDir $tmplink]]
set thisDir [file dirname $tmplink]
}
unset tmplink
set ::util(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
set ::util(diffexe) diff
set ::util(diffWrapped) 0
# Experimenting with DiffUtil package
#set ::util(diffutil) [expr {![catch {package require DiffUtil}]}]
set ::util(diffutil) 0
# Figure out a place to store temporary files.
if {[info exists env(TEMP)] && [file writable $env(TEMP)]} {
set ::diff(tmpdir) $env(TEMP)
} elseif {[info exists env(TMP)] && [file writable $env(TMP)]} {
set ::diff(tmpdir) $env(TMP)
} elseif {[file writable /tmp]} {
set ::diff(tmpdir) /tmp
} elseif {[file writable .]} {
set ::diff(tmpdir) .
} elseif {[file writable ~]} {
set ::diff(tmpdir) ~
} else {
# Panic?
set ::diff(tmpdir) .
}
# Locate a diff executable on windows.
proc locateDiffExe {} {
# Build a list of possible directories.
set dirs [list $::thisDir]
# Are we in a starkit?
if {[string match "*/lib/app-diff" $::thisDir]} {
lappend dirs [file dirname [file dirname [file dirname $::thisDir]]]
# And for a starpack
lappend dirs [file dirname [info nameofexecutable]]
}
lappend dirs c:/bin
foreach dir $dirs {
set try [file join $dir diff.exe]
if {[file exists $try]} {
set ::util(diffexe) $try
return
}
}
if {[string equal [auto_execok diff] ""]} {
tk_messageBox -icon error -title "Diff Error" -message \
"Could not locate any external diff executable." \
|
︙ | | | ︙ | |
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
set ::util(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
}
}
# This is called when an editor is needed to display a file.
# It sets up the util(editor) variable.
proc locateEditor {} {
global util
if {[info exists util(editor)]} return
if {$::tcl_platform(platform) == "unix"} {
set util(editor) emacs
} else {
set util(editor) wordpad
foreach dir [lsort -decreasing -dictionary \
[glob -nocomplain c:/apps/emacs*]] {
set em [file join $dir bin runemacs.exe]
set em [file normalize $em]
if {[file exists $em]} {
set util(editor) $em
break
}
}
}
}
# This function is called when a toplevel is closed.
|
<
|
|
|
|
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
set ::util(cvsExists) [expr {![string equal [auto_execok cvs] ""]}]
}
}
# This is called when an editor is needed to display a file.
# It sets up the util(editor) variable.
proc locateEditor {} {
if {[info exists ::util(editor)]} return
if {$::tcl_platform(platform) == "unix"} {
set ::util(editor) emacs
} else {
set ::util(editor) wordpad
foreach dir [lsort -decreasing -dictionary \
[glob -nocomplain c:/apps/emacs*]] {
set em [file join $dir bin runemacs.exe]
set em [file normalize $em]
if {[file exists $em]} {
set ::util(editor) $em
break
}
}
}
}
# This function is called when a toplevel is closed.
|
︙ | | | ︙ | |
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
|
}
# Compare two lines and rate how much they resemble each other.
# This has never worked well. Some day I'll sit down, think this through,
# and come up with a better algorithm.
proc compareLines2 {line1 line2} {
compareLines $line1 $line2 res1 res2 1
if {$::diff(diffutil)} {
compareLinesX $line1 $line2 xres1 xres2 1
if {$res1 != $xres1 || $res2 != $xres2} {
tk_messageBox -title "Rate Mismatch!" \
-message ":$res1:\n:$res2:\n:$xres1:\n:$xres2:"
}
}
# Collect identical pieces and different pieces
|
|
|
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
|
}
# Compare two lines and rate how much they resemble each other.
# This has never worked well. Some day I'll sit down, think this through,
# and come up with a better algorithm.
proc compareLines2 {line1 line2} {
compareLines $line1 $line2 res1 res2 1
if {$::util(diffutil)} {
compareLinesX $line1 $line2 xres1 xres2 1
if {$res1 != $xres1 || $res2 != $xres2} {
tk_messageBox -title "Rate Mismatch!" \
-message ":$res1:\n:$res2:\n:$xres1:\n:$xres2:"
}
}
# Collect identical pieces and different pieces
|
︙ | | | ︙ | |
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
|
return
}
set ::diff(filterflag) 0
}
if {$Pref(parse) != 0} {
compareLines $line1 $line2 res1 res2
if {$::diff(diffutil)} {
compareLinesX $line1 $line2 xres1 xres2
if {$res1 != $xres1 || $res2 != $xres2} {
tk_messageBox -title Mismatch! \
-message ":$res1:\n:$res2:\n:$xres1:\n:$xres2:"
}
}
set dotag 0
|
|
|
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
|
return
}
set ::diff(filterflag) 0
}
if {$Pref(parse) != 0} {
compareLines $line1 $line2 res1 res2
if {$::util(diffutil)} {
compareLinesX $line1 $line2 xres1 xres2
if {$res1 != $xres1 || $res2 != $xres2} {
tk_messageBox -title Mismatch! \
-message ":$res1:\n:$res2:\n:$xres1:\n:$xres2:"
}
}
set dotag 0
|
︙ | | | ︙ | |
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
|
# Process one of the change/add/delete blocks reported by diff.
# ch1 is a file channel for the left file
# ch2 is a file channel for the right file
# n1/n2 is the number of lines involved
# line1/line2 says on what lines this block starts
proc doText {top ch1 ch2 n1 n2 line1 line2} {
global doingLine1 doingLine2 Pref mapMax changesList
if {$n1 == 0 && $n2 == 0} {
# All blocks have been processed. Continue until end of file.
# If "only diffs" is on, just display a couple of context lines.
set limit -1
if {$Pref(onlydiffs) == 1} {
set limit $Pref(context)
}
# Consider any total limit on displayed lines.
if {$::diff($top,limitlines)} {
set limit [expr {$::diff($top,limitlines) - $mapMax}]
if {$limit < 0} {
set limit 0
}
}
set t 0
while {[gets $ch2 apa] != -1} {
insertLine $top 2 $doingLine2 $apa
incr doingLine2
incr mapMax
incr t
if {$limit >= 0 && $t >= $limit} break
}
set t 0
while {[gets $ch1 apa] != -1} {
insertLine $top 1 $doingLine1 $apa
incr doingLine1
|
|
|
|
|
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
|
# Process one of the change/add/delete blocks reported by diff.
# ch1 is a file channel for the left file
# ch2 is a file channel for the right file
# n1/n2 is the number of lines involved
# line1/line2 says on what lines this block starts
proc doText {top ch1 ch2 n1 n2 line1 line2} {
global doingLine1 doingLine2 Pref
if {$n1 == 0 && $n2 == 0} {
# All blocks have been processed. Continue until end of file.
# If "only diffs" is on, just display a couple of context lines.
set limit -1
if {$Pref(onlydiffs) == 1} {
set limit $Pref(context)
}
# Consider any total limit on displayed lines.
if {$::diff($top,limitlines)} {
set limit [expr {$::diff($top,limitlines) - $::diff($top,mapMax)}]
if {$limit < 0} {
set limit 0
}
}
set t 0
while {[gets $ch2 apa] != -1} {
insertLine $top 2 $doingLine2 $apa
incr doingLine2
incr ::diff($top,mapMax)
incr t
if {$limit >= 0 && $t >= $limit} break
}
set t 0
while {[gets $ch1 apa] != -1} {
insertLine $top 1 $doingLine1 $apa
incr doingLine1
|
︙ | | | ︙ | |
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
|
while {$doingLine1 < $line1} {
gets $ch1 apa
gets $ch2 bepa
if {$limit < 0 || ($t < $limit && $doingLine1 > $limit) || \
($line1 - $doingLine1) <= $limit} {
insertLine $top 1 $doingLine1 $apa
insertLine $top 2 $doingLine2 $bepa
incr mapMax
} elseif {$t == $limit} {
emptyLine $top 1 0
emptyLine $top 2 0
incr mapMax
}
incr doingLine1
incr doingLine2
incr t
if {$::diff($top,limitlines) && $mapMax > $::diff($top,limitlines)} {
return
}
}
# This should not happen unless something is wrong...
if {$doingLine2 != $line2} {
$::diff($top,wDiff1) insert end \
"**Bad alignment here!! $doingLine2 $line2**\n"
|
|
|
|
>
|
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
|
while {$doingLine1 < $line1} {
gets $ch1 apa
gets $ch2 bepa
if {$limit < 0 || ($t < $limit && $doingLine1 > $limit) || \
($line1 - $doingLine1) <= $limit} {
insertLine $top 1 $doingLine1 $apa
insertLine $top 2 $doingLine2 $bepa
incr ::diff($top,mapMax)
} elseif {$t == $limit} {
emptyLine $top 1 0
emptyLine $top 2 0
incr ::diff($top,mapMax)
}
incr doingLine1
incr doingLine2
incr t
if {$::diff($top,limitlines) && \
($::diff($top,mapMax) > $::diff($top,limitlines))} {
return
}
}
# This should not happen unless something is wrong...
if {$doingLine2 != $line2} {
$::diff($top,wDiff1) insert end \
"**Bad alignment here!! $doingLine2 $line2**\n"
|
︙ | | | ︙ | |
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
|
gets $ch1 textline1
gets $ch2 textline2
insertMatchingLines $top $textline1 $textline2
}
if {$::diff(filter) != "" && $::diff(filterflag)} {
} else {
lappend changesList $mapMax $n1 change $line1 $n1 $line2 $n2
}
incr mapMax $n1
} else {
if {$n1 != 0 && $n2 != 0 && $Pref(parse) >= 2 && \
($n1 * $n2 < 1000 || $Pref(parse) == 3)} {
# Full block parsing
set block1 {}
for {set t 0} {$t < $n1} {incr t} {
gets $ch1 apa
lappend block1 $apa
}
set block2 {}
for {set t 0} {$t < $n2} {incr t} {
gets $ch2 apa
lappend block2 $apa
}
set apa [insertMatchingBlocks $top $block1 $block2]
lappend changesList $mapMax $apa change \
$line1 $n1 $line2 $n2
incr mapMax $apa
} else {
# No extra parsing at all.
for {set t 0} {$t < $n1} {incr t} {
gets $ch1 apa
insertLine $top 1 $doingLine1 $apa $tag1
incr doingLine1
}
for {set t 0} {$t < $n2} {incr t} {
gets $ch2 apa
insertLine $top 2 $doingLine2 $apa $tag2
incr doingLine2
}
if {$n1 <= $n2} {
for {set t $n1} {$t < $n2} {incr t} {
emptyLine $top 1
}
lappend changesList $mapMax $n2 $tag2 \
$line1 $n1 $line2 $n2
incr mapMax $n2
} elseif {$n2 < $n1} {
for {set t $n2} {$t < $n1} {incr t} {
emptyLine $top 2
}
lappend changesList $mapMax $n1 $tag1 \
$line1 $n1 $line2 $n2
incr mapMax $n1
}
}
}
}
proc enableRedo {top} {
$top.mf.m entryconfigure "Redo Diff" -state normal
$top.mt.m entryconfigure "Merge" -state normal
}
proc disableRedo {top} {
$top.mf.m entryconfigure "Redo Diff" -state disabled
$top.mt.m entryconfigure "Merge" -state disabled
}
proc busyCursor {top} {
global oldcursor oldcursor2 diff
if {![info exists oldcursor]} {
set oldcursor [. cget -cursor]
set oldcursor2 [$diff($top,wDiff1) cget -cursor]
}
$top config -cursor watch
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
if {[info exists diff($top,$item)]} {
set w $diff($top,$item)
$w config -cursor watch
}
}
}
proc normalCursor {top} {
global oldcursor oldcursor2 diff
$top config -cursor $oldcursor
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
if {[info exists diff($top,$item)]} {
set w $diff($top,$item)
$w config -cursor $oldcursor2
}
}
}
# Read a conflict file and extract the two versions.
proc prepareConflict {top} {
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
|
gets $ch1 textline1
gets $ch2 textline2
insertMatchingLines $top $textline1 $textline2
}
if {$::diff(filter) != "" && $::diff(filterflag)} {
} else {
lappend ::diff($top,changes) [list $::diff($top,mapMax) $n1 \
change $line1 $n1 $line2 $n2]
}
incr ::diff($top,mapMax) $n1
} else {
if {$n1 != 0 && $n2 != 0 && $Pref(parse) >= 2 && \
($n1 * $n2 < 1000 || $Pref(parse) == 3)} {
# Full block parsing
set block1 {}
for {set t 0} {$t < $n1} {incr t} {
gets $ch1 apa
lappend block1 $apa
}
set block2 {}
for {set t 0} {$t < $n2} {incr t} {
gets $ch2 apa
lappend block2 $apa
}
set apa [insertMatchingBlocks $top $block1 $block2]
lappend ::diff($top,changes) [list $::diff($top,mapMax) $apa \
change $line1 $n1 $line2 $n2]
incr ::diff($top,mapMax) $apa
} else {
# No extra parsing at all.
for {set t 0} {$t < $n1} {incr t} {
gets $ch1 apa
insertLine $top 1 $doingLine1 $apa $tag1
incr doingLine1
}
for {set t 0} {$t < $n2} {incr t} {
gets $ch2 apa
insertLine $top 2 $doingLine2 $apa $tag2
incr doingLine2
}
if {$n1 <= $n2} {
for {set t $n1} {$t < $n2} {incr t} {
emptyLine $top 1
}
lappend ::diff($top,changes) [list $::diff($top,mapMax) \
$n2 $tag2 $line1 $n1 $line2 $n2]
incr ::diff($top,mapMax) $n2
} elseif {$n2 < $n1} {
for {set t $n2} {$t < $n1} {incr t} {
emptyLine $top 2
}
lappend ::diff($top,changes) [list $::diff($top,mapMax) \
$n1 $tag1 $line1 $n1 $line2 $n2]
incr ::diff($top,mapMax) $n1
}
}
}
}
proc enableRedo {top} {
$top.mf.m entryconfigure "Redo Diff" -state normal
$top.mt.m entryconfigure "Merge" -state normal
}
proc disableRedo {top} {
$top.mf.m entryconfigure "Redo Diff" -state disabled
$top.mt.m entryconfigure "Merge" -state disabled
}
proc busyCursor {top} {
global oldcursor oldcursor2
if {![info exists oldcursor]} {
set oldcursor [. cget -cursor]
set oldcursor2 [$::diff($top,wDiff1) cget -cursor]
}
$top config -cursor watch
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
if {[info exists ::diff($top,$item)]} {
set w $::diff($top,$item)
$w config -cursor watch
}
}
}
proc normalCursor {top} {
global oldcursor oldcursor2
$top config -cursor $oldcursor
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
if {[info exists ::diff($top,$item)]} {
set w $::diff($top,$item)
$w config -cursor $oldcursor2
}
}
}
# Read a conflict file and extract the two versions.
proc prepareConflict {top} {
|
︙ | | | ︙ | |
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
|
}
continue
}
# No change block anymore. If one just ended, display it.
if {[llength $lblock] > 0 || [llength $rblock] > 0} {
set ::doingLine1 $lblockl
set ::doingLine2 $rblockl
incr ::mapMax [insertMatchingBlocks $top $lblock $rblock]
set lblock {}
set rblock {}
}
if {$lmode == "" && $rmode == ""} {
insertLine $top 1 $lline $lstr
insertLine $top 2 $rline $rstr
incr leftc
incr rightc
incr ::mapMax
continue
}
if {$lmode == "-"} {
insertLine $top 1 $lline $lstr new1
emptyLine $top 2
incr leftc
incr ::mapMax
continue
}
if {$rmode == "+"} {
insertLine $top 2 $rline $rstr new2
emptyLine $top 1
incr rightc
incr ::mapMax
continue
}
}
}
# Read a patch file and display it
proc displayPatch {top} {
global diff Pref changesList mapMax
set diff($top,leftLabel) "Patch $diff($top,patchFile): old"
set diff($top,rightLabel) "Patch $diff($top,patchFile): new"
update idletasks
set ch [open $diff($top,patchFile) r]
|
|
|
|
|
|
|
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
|
}
continue
}
# No change block anymore. If one just ended, display it.
if {[llength $lblock] > 0 || [llength $rblock] > 0} {
set ::doingLine1 $lblockl
set ::doingLine2 $rblockl
incr ::diff($top,mapMax) [insertMatchingBlocks $top $lblock $rblock]
set lblock {}
set rblock {}
}
if {$lmode == "" && $rmode == ""} {
insertLine $top 1 $lline $lstr
insertLine $top 2 $rline $rstr
incr leftc
incr rightc
incr ::diff($top,mapMax)
continue
}
if {$lmode == "-"} {
insertLine $top 1 $lline $lstr new1
emptyLine $top 2
incr leftc
incr ::diff($top,mapMax)
continue
}
if {$rmode == "+"} {
insertLine $top 2 $rline $rstr new2
emptyLine $top 1
incr rightc
incr ::diff($top,mapMax)
continue
}
}
}
# Read a patch file and display it
proc displayPatch {top} {
global diff Pref
set diff($top,leftLabel) "Patch $diff($top,patchFile): old"
set diff($top,rightLabel) "Patch $diff($top,patchFile): new"
update idletasks
set ch [open $diff($top,patchFile) r]
|
︙ | | | ︙ | |
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
|
set rightRE {^\+\+\+\s+(.*)$}
}
if {$state == "newfile" && [regexp $leftRE $line -> sub]} {
emptyLine $top 1
insertLine $top 1 "" $divider
insertLine $top 1 "" $sub
insertLine $top 1 "" $divider
lappend ::changesList $mapMax 4 change 0 0 0 0
incr mapMax 4
continue
}
if {$state == "newfile" && [regexp $rightRE $line -> sub]} {
emptyLine $top 2
insertLine $top 2 "" $divider
insertLine $top 2 "" $sub
insertLine $top 2 "" $divider
|
>
|
|
|
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
|
set rightRE {^\+\+\+\s+(.*)$}
}
if {$state == "newfile" && [regexp $leftRE $line -> sub]} {
emptyLine $top 1
insertLine $top 1 "" $divider
insertLine $top 1 "" $sub
insertLine $top 1 "" $divider
lappend ::diff($top,changes) [list $::diff($top,mapMax) 4 \
change 0 0 0 0]
incr ::diff($top,mapMax) 4
continue
}
if {$state == "newfile" && [regexp $rightRE $line -> sub]} {
emptyLine $top 2
insertLine $top 2 "" $divider
insertLine $top 2 "" $sub
insertLine $top 2 "" $divider
|
︙ | | | ︙ | |
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
|
}
}
# Main diff function.
proc doDiff {top} {
global diff Pref
global doingLine1 doingLine2
global mapMax changesList
if {$diff($top,mode) == "" && ($diff($top,leftOK) == 0 || $diff($top,rightOK) == 0)} {
disableRedo $top
return
} else {
enableRedo $top
}
busyCursor $top
# Clear up everything before starting processing
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::diff($top,$item)
$w configure -state normal
$w delete 1.0 end
}
set changesList {}
set mapMax 0
set ::HighLightCount 0
highLightChange $top -1
drawMap $top -1
# Display a star during diff execution, to know when the internal
# processing starts, and when the label is "valid".
set ::diff($top,eqLabel) "*"
|
<
|
|
|
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
|
}
}
# Main diff function.
proc doDiff {top} {
global diff Pref
global doingLine1 doingLine2
if {$diff($top,mode) == "" && ($diff($top,leftOK) == 0 || $diff($top,rightOK) == 0)} {
disableRedo $top
return
} else {
enableRedo $top
}
busyCursor $top
# Clear up everything before starting processing
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::diff($top,$item)
$w configure -state normal
$w delete 1.0 end
}
set ::diff($top,changes) {}
set ::diff($top,mapMax) 0
set ::HighLightCount 0
highLightChange $top -1
drawMap $top -1
# Display a star during diff execution, to know when the internal
# processing starts, and when the label is "valid".
set ::diff($top,eqLabel) "*"
|
︙ | | | ︙ | |
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
|
normalCursor $top
return
} else {
prepareFiles $top
}
# Run diff and parse the result.
if {$::diff(diffutil)} {
set differr [catch {eval DiffUtil::diffFiles $Pref(ignore) \
\$diff($top,leftFile) \$diff($top,rightFile)} diffres]
} else {
set differr [catch {eval exec \$::util(diffexe) \
$diff($top,dopt) $Pref(ignore) \
\$diff($top,leftFile) \$diff($top,rightFile)} diffres]
}
|
|
|
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
|
normalCursor $top
return
} else {
prepareFiles $top
}
# Run diff and parse the result.
if {$::util(diffutil)} {
set differr [catch {eval DiffUtil::diffFiles $Pref(ignore) \
\$diff($top,leftFile) \$diff($top,rightFile)} diffres]
} else {
set differr [catch {eval exec \$::util(diffexe) \
$diff($top,dopt) $Pref(ignore) \
\$diff($top,leftFile) \$diff($top,rightFile)} diffres]
}
|
︙ | | | ︙ | |
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
|
}
d {
# Gap in right, new in left
doText $top $ch1 $ch2 $n1 0 $line1 [expr {$line2 + 1}]
}
}
}
if {$::diff($top,limitlines) && $::mapMax > $::diff($top,limitlines)} {
break
}
bindHighlight $top
incr ::HighLightCount
# Get one update when the screen has been filled.
# Show the first diff.
if {$firstview && $::mapMax > 100} {
set firstview 0
showDiff $top 0
update idletasks
}
if {0 && [incr t] >= 10} {
update idletasks
$::diff($top,wLine2) see end
|
|
>
|
|
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
|
}
d {
# Gap in right, new in left
doText $top $ch1 $ch2 $n1 0 $line1 [expr {$line2 + 1}]
}
}
}
if {$::diff($top,limitlines) && \
($::diff($top,mapMax) > $::diff($top,limitlines))} {
break
}
bindHighlight $top
incr ::HighLightCount
# Get one update when the screen has been filled.
# Show the first diff.
if {$firstview && $::diff($top,mapMax) > 100} {
set firstview 0
showDiff $top 0
update idletasks
}
if {0 && [incr t] >= 10} {
update idletasks
$::diff($top,wLine2) see end
|
︙ | | | ︙ | |
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
|
#####################################
# Highlight and navigation stuff
#####################################
# Scroll windows to next/previous diff
proc findDiff {top delta} {
# FIXA: currenthighlight per top
global CurrentHighLight
showDiff $top [expr {$CurrentHighLight + $delta}]
}
# Scroll a text window to view a certain range, and possibly some
# lines before and after.
proc seeText {w si ei} {
$w see $ei
$w see $si
$w see $si-5lines
$w see $ei+5lines
if {[llength [$w bbox $si]] == 0} {
$w yview $si-5lines
}
if {[llength [$w bbox $ei]] == 0} {
$w yview $si
}
}
# Highlight a diff
proc highLightChange {top n} {
global CurrentHighLight changesList
if {[info exists CurrentHighLight] && $CurrentHighLight >= 0} {
$::diff($top,wLine1) tag configure hl$CurrentHighLight -background {}
$::diff($top,wLine2) tag configure hl$CurrentHighLight -background {}
}
set CurrentHighLight $n
if {$CurrentHighLight < 0} {
set CurrentHighLight -1
} elseif {$CurrentHighLight * 7 >= [llength $changesList]} {
set CurrentHighLight [expr {[llength $changesList] / 7}]
} else {
$::diff($top,wLine1) tag configure hl$CurrentHighLight \
-background yellow
$::diff($top,wLine2) tag configure hl$CurrentHighLight \
-background yellow
}
}
# Highlight a diff and scroll windows to it.
proc showDiff {top num} {
global CurrentHighLight changesList
highLightChange $top $num
set line1 [lindex $changesList [expr {$CurrentHighLight * 7}]]
if {$CurrentHighLight < 0} {
set line1 1.0
set line2 1.0
} elseif {$line1 == ""} {
set line1 end
set line2 end
} else {
set line2 [expr {$line1 + \
[lindex $changesList [expr {$CurrentHighLight * 7 + 1}]]}]
incr line1
set line1 $line1.0
set line2 $line2.0
}
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::diff($top,$item)
|
<
<
<
|
|
|
|
>
|
>
|
|
|
|
|
|
|
<
<
>
|
|
|
<
|
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
|
#####################################
# Highlight and navigation stuff
#####################################
# Scroll windows to next/previous diff
proc findDiff {top delta} {
showDiff $top [expr {$::diff($top,currHighLight) + $delta}]
}
# Scroll a text window to view a certain range, and possibly some
# lines before and after.
proc seeText {w si ei} {
$w see $ei
$w see $si
$w see $si-5lines
$w see $ei+5lines
if {[llength [$w bbox $si]] == 0} {
$w yview $si-5lines
}
if {[llength [$w bbox $ei]] == 0} {
$w yview $si
}
}
# Highlight a diff
proc highLightChange {top n} {
if {[info exists ::diff($top,currHighLight)] && \
$::diff($top,currHighLight) >= 0} {
$::diff($top,wLine1) tag configure hl$::diff($top,currHighLight) \
-background {}
$::diff($top,wLine2) tag configure hl$::diff($top,currHighLight) \
-background {}
}
set ::diff($top,currHighLight) $n
if {$::diff($top,currHighLight) < 0} {
set ::diff($top,currHighLight) -1
} elseif {$::diff($top,currHighLight) >= [llength $::diff($top,changes)]} {
set ::diff($top,currHighLight) [llength $::diff($top,changes)]
} else {
$::diff($top,wLine1) tag configure hl$::diff($top,currHighLight) \
-background yellow
$::diff($top,wLine2) tag configure hl$::diff($top,currHighLight) \
-background yellow
}
}
# Highlight a diff and scroll windows to it.
proc showDiff {top num} {
highLightChange $top $num
set change [lindex $::diff($top,changes) $::diff($top,currHighLight)]
set line1 [lindex $change 0]
if {$::diff($top,currHighLight) < 0} {
set line1 1.0
set line2 1.0
} elseif {$line1 == ""} {
set line1 end
set line2 end
} else {
set line2 [expr {$line1 + [lindex $change 1]}]
incr line1
set line1 $line1.0
set line2 $line2.0
}
foreach item {wLine1 wDiff1 wLine2 wDiff2} {
set w $::diff($top,$item)
|
︙ | | | ︙ | |
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
|
}
#####################################
# Map stuff
#####################################
proc drawMap {top newh} {
global mapMax Pref changesList
set oldh [map$top cget -height]
if {$oldh == $newh} return
map$top blank
if {![info exists changesList] || [llength $changesList] == 0} return
set w [winfo width $top.c]
set h [winfo height $top.c]
set x2 [expr {$w - 1}]
map$top configure -width $w -height $h
incr h -1
foreach {start length type dum1 dum2 dum3 dum4} $changesList {
set y1 [expr {$start * $h / $mapMax + 1}]
if {$y1 < 1} {set y1 1}
if {$y1 > $h} {set y1 $h}
set y2 [expr {($start + $length) * $h / $mapMax + 1}]
if {$y2 < 1} {set y2 1}
if {$y2 <= $y1} {set y2 [expr {$y1 + 1}]}
if {$y2 > $h} {set y2 $h}
incr y2
map$top put $Pref(color$type) -to 1 $y1 $x2 $y2
}
}
######################################
# Merge stuff
#####################################
# Get all data from the files to merge
proc collectMergeData {top} {
global diff
global changesList mergeSelection
global leftMergeData rightMergeData
set leftMergeData {}
set rightMergeData {}
if {![info exists changesList]} {
set changesList {}
}
if {$diff($top,mode) == "RCS" || $diff($top,mode) == "CVS"} {
prepareRCS $top
} elseif {[string match "conflict*" $diff($top,mode)]} {
prepareConflict $top
}
set ch1 [open $diff($top,leftFile) r]
set ch2 [open $diff($top,rightFile) r]
set doingLine1 1
set doingLine2 1
set changeNo 0
foreach {start length type line1 n1 line2 n2} $changesList {
set data1 {}
set data2 {}
while {$doingLine1 < $line1} {
gets $ch1 apa
append data1 $apa\n
incr doingLine1
}
|
|
|
>
>
|
|
|
>
|
|
|
>
|
|
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
|
}
#####################################
# Map stuff
#####################################
proc drawMap {top newh} {
global Pref
set oldh [map$top cget -height]
if {$oldh == $newh} return
map$top blank
if {![info exists ::diff($top,changes)] || \
[llength $::diff($top,changes)] == 0} return
set w [winfo width $top.c]
set h [winfo height $top.c]
set x2 [expr {$w - 1}]
map$top configure -width $w -height $h
incr h -1
foreach change $::diff($top,changes) {
foreach {start length type dum1 dum2 dum3 dum4} $change break
set y1 [expr {$start * $h / $::diff($top,mapMax) + 1}]
if {$y1 < 1} {set y1 1}
if {$y1 > $h} {set y1 $h}
set y2 [expr {($start + $length) * $h / $::diff($top,mapMax) + 1}]
if {$y2 < 1} {set y2 1}
if {$y2 <= $y1} {set y2 [expr {$y1 + 1}]}
if {$y2 > $h} {set y2 $h}
incr y2
map$top put $Pref(color$type) -to 1 $y1 $x2 $y2
}
}
######################################
# Merge stuff
#####################################
# Get all data from the files to merge
proc collectMergeData {top} {
global diff
# FIXA separate merge variables per top
global mergeSelection
global leftMergeData rightMergeData
set leftMergeData {}
set rightMergeData {}
if {![info exists ::diff($top,changes)]} {
set ::diff($top,changes) {}
}
if {$diff($top,mode) == "RCS" || $diff($top,mode) == "CVS"} {
prepareRCS $top
} elseif {[string match "conflict*" $diff($top,mode)]} {
prepareConflict $top
}
set ch1 [open $diff($top,leftFile) r]
set ch2 [open $diff($top,rightFile) r]
set doingLine1 1
set doingLine2 1
set changeNo 0
foreach change $::diff($top,changes) {
foreach {start length type line1 n1 line2 n2} $change break
set data1 {}
set data2 {}
while {$doingLine1 < $line1} {
gets $ch1 apa
append data1 $apa\n
incr doingLine1
}
|
︙ | | | ︙ | |
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
|
proc unzoomRow {w} {
set top [winfo toplevel $w]
destroy $top.balloon
}
# Procedures for common y-scroll
proc commonYScroll_YView {sby args} {
global yscroll
foreach w $yscroll($sby) {
eval [list $w yview] $args
}
}
|
>
>
|
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
|
proc unzoomRow {w} {
set top [winfo toplevel $w]
destroy $top.balloon
}
# Procedures for common y-scroll
# FIXA: Move these to a package
proc commonYScroll_YView {sby args} {
global yscroll
foreach w $yscroll($sby) {
eval [list $w yview] $args
}
}
|
︙ | | | ︙ | |
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
|
grid columnconfigure $top {0 3} -weight 1
grid rowconfigure $top 2 -weight 1
grid $top.c -pady [expr {[$top.sby cget -width] + 2}]
grid $top.ls -sticky ""
image create photo map$top
$top.c create image 0 0 -anchor nw -image map$top
bind $top.c <Configure> [list drawMap $top %h]
bind $top <Key-Up> [list scrollText $top -1 u]
bind $top <Key-Down> [list scrollText $top 1 u]
bind $top <Key-Prior> [list scrollText $top -1 p]
bind $top <Key-Next> [list scrollText $top 1 p]
bind $top <Key-Escape> [list focus $top]
|
>
|
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
|
grid columnconfigure $top {0 3} -weight 1
grid rowconfigure $top 2 -weight 1
grid $top.c -pady [expr {[$top.sby cget -width] + 2}]
grid $top.ls -sticky ""
image create photo map$top
$top.c create image 0 0 -anchor nw -image map$top
bind $top.c <Destroy> [list image delete map$top]
bind $top.c <Configure> [list drawMap $top %h]
bind $top <Key-Up> [list scrollText $top -1 u]
bind $top <Key-Down> [list scrollText $top 1 u]
bind $top <Key-Prior> [list scrollText $top -1 p]
bind $top <Key-Next> [list scrollText $top 1 p]
bind $top <Key-Escape> [list focus $top]
|
︙ | | | ︙ | |
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
|
grid $l.old1 $l.old2 -sticky w -padx 4 -pady 4
grid $l.new1 $l.new2 -sticky w -padx 4 -pady 4
grid $l.change - -sticky e -padx 4 -pady 4
grid columnconfigure $l 1 -weight 1
}
proc makeRegistryWin {} {
global thisDir thisScript util
# Locate executable for this program
set exe [info nameofexecutable]
if {[regexp {^(.*wish)\d+\.exe$} $exe -> pre]} {
set alt $pre.exe
if {[file exists $alt]} {
set a [tk_messageBox -icon question -title "Which Wish" -message \
|
|
|
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
|
grid $l.old1 $l.old2 -sticky w -padx 4 -pady 4
grid $l.new1 $l.new2 -sticky w -padx 4 -pady 4
grid $l.change - -sticky e -padx 4 -pady 4
grid columnconfigure $l 1 -weight 1
}
proc makeRegistryWin {} {
global thisScript
# Locate executable for this program
set exe [info nameofexecutable]
if {[regexp {^(.*wish)\d+\.exe$} $exe -> pre]} {
set alt $pre.exe
if {[file exists $alt]} {
set a [tk_messageBox -icon question -title "Which Wish" -message \
|
︙ | | | ︙ | |
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
|
set new "$valbase \"%1\""
makeRegistryFrame $top.dd "Directory Diff" $keydd $new
pack $top.d $top.c $top.dd -side top -fill x -padx 4 -pady 4
locateEditor
if {[string match "*runemacs.exe" $util(editor)]} {
# Set up emacs
set newkey "\"[file nativename $util(editor)]\" \"%1\""
makeRegistryFrame $top.e "Emacs" $keye $newkey
pack $top.e -side top -fill x -padx 4 -pady 4
}
button $top.close -text "Close" -width 10 -command [list destroy $top] \
-default active
pack $top.close -side bottom -pady 4
|
|
|
|
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
|
set new "$valbase \"%1\""
makeRegistryFrame $top.dd "Directory Diff" $keydd $new
pack $top.d $top.c $top.dd -side top -fill x -padx 4 -pady 4
locateEditor
if {[string match "*runemacs.exe" $::util(editor)]} {
# Set up emacs
set newkey "\"[file nativename $::util(editor)]\" \"%1\""
makeRegistryFrame $top.e "Emacs" $keye $newkey
pack $top.e -side top -fill x -padx 4 -pady 4
}
button $top.close -text "Close" -width 10 -command [list destroy $top] \
-default active
pack $top.close -side bottom -pady 4
|
︙ | | | ︙ | |
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
|
}
#####################################
# Help and startup functions
#####################################
proc makeNuisance {top {str {Hi there!}}} {
global thisDir
if {[lsearch [image names] nuisance] < 0} {
set file [file join $thisDir Nuisance.gif]
if {![file exists $file]} return
image create photo nuisance -file $file
}
destroy $top.nui
toplevel $top.nui
wm transient $top.nui $top
|
<
<
|
|
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
|
}
#####################################
# Help and startup functions
#####################################
proc makeNuisance {top {str {Hi there!}}} {
if {[lsearch [image names] nuisance] < 0} {
set file [file join $::thisDir Nuisance.gif]
if {![file exists $file]} return
image create photo nuisance -file $file
}
destroy $top.nui
toplevel $top.nui
wm transient $top.nui $top
|
︙ | | | ︙ | |