gitk: Refactor per-line part of getblobdiffline and its support
For later use with data sources other than a pipe, refactor the big worker part of getblobdiffline to a separate function parseblobdiffline. Also refactor its initialization and wrap-up to separate routines. Signed-off-by: Thomas Rast <trast@inf.ethz.ch> Signed-off-by: Paul Mackerras <paulus@samba.org>
Thomas Rast committed
Nov 16, 2013 at 18:37 UTC
5de460a2cfdd4acbadd41355a5b34dc69e93b89e
1 file changed
+213
-195
gitk
+213
-195
@@ -7752,15 +7752,25 @@ proc changeworddiff {name ix op} {
7752
reselectline
7753
}
7754
7755
+proc initblobdiffvars {} {
7756
+ global diffencoding targetline diffnparents
7757
+ global diffinhdr currdiffsubmod diffseehere
7758
+ set targetline {}
7759
+ set diffnparents 0
7760
+ set diffinhdr 0
7761
+ set diffencoding [get_path_encoding {}]
7762
+ set currdiffsubmod ""
7763
+ set diffseehere -1
7764
+}
7765
+
7766
proc getblobdiffs {ids} {
7767
global blobdifffd diffids env
7757
- global diffinhdr treediffs
7768
+ global treediffs
7769
global diffcontext
7770
global ignorespace
7771
global worddiff
7772
global limitdiffs vfilelimit curview
7762
- global diffencoding targetline diffnparents
7763
- global git_version currdiffsubmod
7773
+ global git_version
7774
7775
set textconv {}
7776
if {[package vcompare $git_version "1.6.1"] >= 0} {
@@ -7784,13 +7794,9 @@ proc getblobdiffs {ids} {
7794
error_popup [mc "Error getting diffs: %s" $err]
7795
return
7796
}
7787
- set targetline {}
7788
- set diffnparents 0
7789
- set diffinhdr 0
7790
- set diffencoding [get_path_encoding {}]
7797
fconfigure $bdf -blocking 0 -encoding binary -eofchar {}
7798
set blobdifffd($ids) $bdf
7793
- set currdiffsubmod ""
7799
+ initblobdiffvars
7800
filerun $bdf [list getblobdiffline $bdf $diffids]
7801
}
7802
@@ -7856,13 +7862,17 @@ proc makediffhdr {fname ids} {
7862
set diffline 0
7863
}
7864
7865
+proc blobdiffmaybeseehere {ateof} {
7866
+ global diffseehere
7867
+ if {$diffseehere >= 0} {
7868
+ mark_ctext_line [lindex [split $diffseehere .] 0]
7869
+ }
7870
+ maybe_scroll_ctext ateof
7871
+}
7872
+
7873
proc getblobdiffline {bdf ids} {
7860
- global diffids blobdifffd ctext curdiffstart
7861
- global diffnexthead diffnextnote difffilestart
7862
- global ctext_file_names ctext_file_lines
7863
- global diffinhdr treediffs mergemax diffnparents
7864
- global diffencoding jump_to_here targetline diffline currdiffsubmod
7865
- global worddiff
7874
+ global diffids blobdifffd
7875
+ global ctext
7876
7877
set nr 0
7878
$ctext conf -state normal
@@ -7871,212 +7881,220 @@ proc getblobdiffline {bdf ids} {
7881
catch {close $bdf}
7882
return 0
7883
}
7874
- if {![string compare -length 5 "diff " $line]} {
7875
- if {![regexp {^diff (--cc|--git) } $line m type]} {
7876
- set line [encoding convertfrom $line]
7877
- $ctext insert end "$line\n" hunksep
7878
- continue
7884
+ parseblobdiffline $ids $line
7885
+ }
7886
+ $ctext conf -state disabled
7887
+ blobdiffmaybeseehere [eof $bdf]
7888
+ if {[eof $bdf]} {
7889
+ catch {close $bdf}
7890
+ return 0
7891
+ }
7892
+ return [expr {$nr >= 1000? 2: 1}]
7893
+}
7894
+
7895
+proc parseblobdiffline {ids line} {
7896
+ global ctext curdiffstart
7897
+ global diffnexthead diffnextnote difffilestart
7898
+ global ctext_file_names ctext_file_lines
7899
+ global diffinhdr treediffs mergemax diffnparents
7900
+ global diffencoding jump_to_here targetline diffline currdiffsubmod
7901
+ global worddiff diffseehere
7902
+
7903
+ if {![string compare -length 5 "diff " $line]} {
7904
+ if {![regexp {^diff (--cc|--git) } $line m type]} {
7905
+ set line [encoding convertfrom $line]
7906
+ $ctext insert end "$line\n" hunksep
7907
+ continue
7908
+ }
7909
+ # start of a new file
7910
+ set diffinhdr 1
7911
+ $ctext insert end "\n"
7912
+ set curdiffstart [$ctext index "end - 1c"]
7913
+ lappend ctext_file_names ""
7914
+ lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
7915
+ $ctext insert end "\n" filesep
7916
+
7917
+ if {$type eq "--cc"} {
7918
+ # start of a new file in a merge diff
7919
+ set fname [string range $line 10 end]
7920
+ if {[lsearch -exact $treediffs($ids) $fname] < 0} {
7921
+ lappend treediffs($ids) $fname
7922
+ add_flist [list $fname]
7923
}
7880
- # start of a new file
7881
- set diffinhdr 1
7882
- $ctext insert end "\n"
7883
- set curdiffstart [$ctext index "end - 1c"]
7884
- lappend ctext_file_names ""
7885
- lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
7886
- $ctext insert end "\n" filesep
7887
-
7888
- if {$type eq "--cc"} {
7889
- # start of a new file in a merge diff
7890
- set fname [string range $line 10 end]
7891
- if {[lsearch -exact $treediffs($ids) $fname] < 0} {
7892
- lappend treediffs($ids) $fname
7893
- add_flist [list $fname]
7894
- }
7924
7925
+ } else {
7926
+ set line [string range $line 11 end]
7927
+ # If the name hasn't changed the length will be odd,
7928
+ # the middle char will be a space, and the two bits either
7929
+ # side will be a/name and b/name, or "a/name" and "b/name".
7930
+ # If the name has changed we'll get "rename from" and
7931
+ # "rename to" or "copy from" and "copy to" lines following
7932
+ # this, and we'll use them to get the filenames.
7933
+ # This complexity is necessary because spaces in the
7934
+ # filename(s) don't get escaped.
7935
+ set l [string length $line]
7936
+ set i [expr {$l / 2}]
7937
+ if {!(($l & 1) && [string index $line $i] eq " " &&
7938
+ [string range $line 2 [expr {$i - 1}]] eq \
7939
+ [string range $line [expr {$i + 3}] end])} {
7940
+ return
7941
+ }
7942
+ # unescape if quoted and chop off the a/ from the front
7943
+ if {[string index $line 0] eq "\""} {
7944
+ set fname [string range [lindex $line 0] 2 end]
7945
} else {
7897
- set line [string range $line 11 end]
7898
- # If the name hasn't changed the length will be odd,
7899
- # the middle char will be a space, and the two bits either
7900
- # side will be a/name and b/name, or "a/name" and "b/name".
7901
- # If the name has changed we'll get "rename from" and
7902
- # "rename to" or "copy from" and "copy to" lines following
7903
- # this, and we'll use them to get the filenames.
7904
- # This complexity is necessary because spaces in the
7905
- # filename(s) don't get escaped.
7906
- set l [string length $line]
7907
- set i [expr {$l / 2}]
7908
- if {!(($l & 1) && [string index $line $i] eq " " &&
7909
- [string range $line 2 [expr {$i - 1}]] eq \
7910
- [string range $line [expr {$i + 3}] end])} {
7911
- continue
7912
- }
7913
- # unescape if quoted and chop off the a/ from the front
7914
- if {[string index $line 0] eq "\""} {
7915
- set fname [string range [lindex $line 0] 2 end]
7916
- } else {
7917
- set fname [string range $line 2 [expr {$i - 1}]]
7918
- }
7946
+ set fname [string range $line 2 [expr {$i - 1}]]
7947
}
7920
- makediffhdr $fname $ids
7948
+ }
7949
+ makediffhdr $fname $ids
7950
7922
- } elseif {![string compare -length 16 "* Unmerged path " $line]} {
7923
- set fname [encoding convertfrom [string range $line 16 end]]
7924
- $ctext insert end "\n"
7925
- set curdiffstart [$ctext index "end - 1c"]
7926
- lappend ctext_file_names $fname
7927
- lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
7951
+ } elseif {![string compare -length 16 "* Unmerged path " $line]} {
7952
+ set fname [encoding convertfrom [string range $line 16 end]]
7953
+ $ctext insert end "\n"
7954
+ set curdiffstart [$ctext index "end - 1c"]
7955
+ lappend ctext_file_names $fname
7956
+ lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
7957
+ $ctext insert end "$line\n" filesep
7958
+ set i [lsearch -exact $treediffs($ids) $fname]
7959
+ if {$i >= 0} {
7960
+ setinlist difffilestart $i $curdiffstart
7961
+ }
7962
+
7963
+ } elseif {![string compare -length 2 "@@" $line]} {
7964
+ regexp {^@@+} $line ats
7965
+ set line [encoding convertfrom $diffencoding $line]
7966
+ $ctext insert end "$line\n" hunksep
7967
+ if {[regexp { \+(\d+),\d+ @@} $line m nl]} {
7968
+ set diffline $nl
7969
+ }
7970
+ set diffnparents [expr {[string length $ats] - 1}]
7971
+ set diffinhdr 0
7972
+
7973
+ } elseif {![string compare -length 10 "Submodule " $line]} {
7974
+ # start of a new submodule
7975
+ if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
7976
+ set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
7977
+ } else {
7978
+ set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
7979
+ }
7980
+ if {$currdiffsubmod != $fname} {
7981
+ $ctext insert end "\n"; # Add newline after commit message
7982
+ }
7983
+ set curdiffstart [$ctext index "end - 1c"]
7984
+ lappend ctext_file_names ""
7985
+ if {$currdiffsubmod != $fname} {
7986
+ lappend ctext_file_lines $fname
7987
+ makediffhdr $fname $ids
7988
+ set currdiffsubmod $fname
7989
+ $ctext insert end "\n$line\n" filesep
7990
+ } else {
7991
$ctext insert end "$line\n" filesep
7992
+ }
7993
+ } elseif {![string compare -length 3 " >" $line]} {
7994
+ set $currdiffsubmod ""
7995
+ set line [encoding convertfrom $diffencoding $line]
7996
+ $ctext insert end "$line\n" dresult
7997
+ } elseif {![string compare -length 3 " <" $line]} {
7998
+ set $currdiffsubmod ""
7999
+ set line [encoding convertfrom $diffencoding $line]
8000
+ $ctext insert end "$line\n" d0
8001
+ } elseif {$diffinhdr} {
8002
+ if {![string compare -length 12 "rename from " $line]} {
8003
+ set fname [string range $line [expr 6 + [string first " from " $line] ] end]
8004
+ if {[string index $fname 0] eq "\""} {
8005
+ set fname [lindex $fname 0]
8006
+ }
8007
+ set fname [encoding convertfrom $fname]
8008
set i [lsearch -exact $treediffs($ids) $fname]
8009
if {$i >= 0} {
8010
setinlist difffilestart $i $curdiffstart
8011
}
7933
-
7934
- } elseif {![string compare -length 2 "@@" $line]} {
7935
- regexp {^@@+} $line ats
7936
- set line [encoding convertfrom $diffencoding $line]
7937
- $ctext insert end "$line\n" hunksep
7938
- if {[regexp { \+(\d+),\d+ @@} $line m nl]} {
7939
- set diffline $nl
8012
+ } elseif {![string compare -length 10 $line "rename to "] ||
8013
+ ![string compare -length 8 $line "copy to "]} {
8014
+ set fname [string range $line [expr 4 + [string first " to " $line] ] end]
8015
+ if {[string index $fname 0] eq "\""} {
8016
+ set fname [lindex $fname 0]
8017
}
7941
- set diffnparents [expr {[string length $ats] - 1}]
8018
+ makediffhdr $fname $ids
8019
+ } elseif {[string compare -length 3 $line "---"] == 0} {
8020
+ # do nothing
8021
+ return
8022
+ } elseif {[string compare -length 3 $line "+++"] == 0} {
8023
set diffinhdr 0
8024
+ return
8025
+ }
8026
+ $ctext insert end "$line\n" filesep
8027
7944
- } elseif {![string compare -length 10 "Submodule " $line]} {
7945
- # start of a new submodule
7946
- if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
7947
- set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
7948
- } else {
7949
- set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
7950
- }
7951
- if {$currdiffsubmod != $fname} {
7952
- $ctext insert end "\n"; # Add newline after commit message
7953
- }
7954
- set curdiffstart [$ctext index "end - 1c"]
7955
- lappend ctext_file_names ""
7956
- if {$currdiffsubmod != $fname} {
7957
- lappend ctext_file_lines $fname
7958
- makediffhdr $fname $ids
7959
- set currdiffsubmod $fname
7960
- $ctext insert end "\n$line\n" filesep
7961
- } else {
7962
- $ctext insert end "$line\n" filesep
7963
- }
7964
- } elseif {![string compare -length 3 " >" $line]} {
7965
- set $currdiffsubmod ""
7966
- set line [encoding convertfrom $diffencoding $line]
7967
- $ctext insert end "$line\n" dresult
7968
- } elseif {![string compare -length 3 " <" $line]} {
7969
- set $currdiffsubmod ""
7970
- set line [encoding convertfrom $diffencoding $line]
7971
- $ctext insert end "$line\n" d0
7972
- } elseif {$diffinhdr} {
7973
- if {![string compare -length 12 "rename from " $line]} {
7974
- set fname [string range $line [expr 6 + [string first " from " $line] ] end]
7975
- if {[string index $fname 0] eq "\""} {
7976
- set fname [lindex $fname 0]
7977
- }
7978
- set fname [encoding convertfrom $fname]
7979
- set i [lsearch -exact $treediffs($ids) $fname]
7980
- if {$i >= 0} {
7981
- setinlist difffilestart $i $curdiffstart
8028
+ } else {
8029
+ set line [string map {\x1A ^Z} \
8030
+ [encoding convertfrom $diffencoding $line]]
8031
+ # parse the prefix - one ' ', '-' or '+' for each parent
8032
+ set prefix [string range $line 0 [expr {$diffnparents - 1}]]
8033
+ set tag [expr {$diffnparents > 1? "m": "d"}]
8034
+ set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
8035
+ set words_pre_markup ""
8036
+ set words_post_markup ""
8037
+ if {[string trim $prefix " -+"] eq {}} {
8038
+ # prefix only has " ", "-" and "+" in it: normal diff line
8039
+ set num [string first "-" $prefix]
8040
+ if {$dowords} {
8041
+ set line [string range $line 1 end]
8042
+ }
8043
+ if {$num >= 0} {
8044
+ # removed line, first parent with line is $num
8045
+ if {$num >= $mergemax} {
8046
+ set num "max"
8047
}
7983
- } elseif {![string compare -length 10 $line "rename to "] ||
7984
- ![string compare -length 8 $line "copy to "]} {
7985
- set fname [string range $line [expr 4 + [string first " to " $line] ] end]
7986
- if {[string index $fname 0] eq "\""} {
7987
- set fname [lindex $fname 0]
8048
+ if {$dowords && $worddiff eq [mc "Markup words"]} {
8049
+ $ctext insert end "\[-$line-\]" $tag$num
8050
+ } else {
8051
+ $ctext insert end "$line" $tag$num
8052
}
7989
- makediffhdr $fname $ids
7990
- } elseif {[string compare -length 3 $line "---"] == 0} {
7991
- # do nothing
7992
- continue
7993
- } elseif {[string compare -length 3 $line "+++"] == 0} {
7994
- set diffinhdr 0
7995
- continue
7996
- }
7997
- $ctext insert end "$line\n" filesep
7998
-
7999
- } else {
8000
- set line [string map {\x1A ^Z} \
8001
- [encoding convertfrom $diffencoding $line]]
8002
- # parse the prefix - one ' ', '-' or '+' for each parent
8003
- set prefix [string range $line 0 [expr {$diffnparents - 1}]]
8004
- set tag [expr {$diffnparents > 1? "m": "d"}]
8005
- set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
8006
- set words_pre_markup ""
8007
- set words_post_markup ""
8008
- if {[string trim $prefix " -+"] eq {}} {
8009
- # prefix only has " ", "-" and "+" in it: normal diff line
8010
- set num [string first "-" $prefix]
8011
- if {$dowords} {
8012
- set line [string range $line 1 end]
8053
+ if {!$dowords} {
8054
+ $ctext insert end "\n" $tag$num
8055
}
8014
- if {$num >= 0} {
8015
- # removed line, first parent with line is $num
8016
- if {$num >= $mergemax} {
8017
- set num "max"
8018
- }
8019
- if {$dowords && $worddiff eq [mc "Markup words"]} {
8020
- $ctext insert end "\[-$line-\]" $tag$num
8021
- } else {
8022
- $ctext insert end "$line" $tag$num
8023
- }
8024
- if {!$dowords} {
8025
- $ctext insert end "\n" $tag$num
8026
- }
8027
- } else {
8028
- set tags {}
8029
- if {[string first "+" $prefix] >= 0} {
8030
- # added line
8031
- lappend tags ${tag}result
8032
- if {$diffnparents > 1} {
8033
- set num [string first " " $prefix]
8034
- if {$num >= 0} {
8035
- if {$num >= $mergemax} {
8036
- set num "max"
8037
- }
8038
- lappend tags m$num
8056
+ } else {
8057
+ set tags {}
8058
+ if {[string first "+" $prefix] >= 0} {
8059
+ # added line
8060
+ lappend tags ${tag}result
8061
+ if {$diffnparents > 1} {
8062
+ set num [string first " " $prefix]
8063
+ if {$num >= 0} {
8064
+ if {$num >= $mergemax} {
8065
+ set num "max"
8066
}
8067
+ lappend tags m$num
8068
}
8041
- set words_pre_markup "{+"
8042
- set words_post_markup "+}"
8069
}
8044
- if {$targetline ne {}} {
8045
- if {$diffline == $targetline} {
8046
- set seehere [$ctext index "end - 1 chars"]
8047
- set targetline {}
8048
- } else {
8049
- incr diffline
8050
- }
8051
- }
8052
- if {$dowords && $worddiff eq [mc "Markup words"]} {
8053
- $ctext insert end "$words_pre_markup$line$words_post_markup" $tags
8070
+ set words_pre_markup "{+"
8071
+ set words_post_markup "+}"
8072
+ }
8073
+ if {$targetline ne {}} {
8074
+ if {$diffline == $targetline} {
8075
+ set diffseehere [$ctext index "end - 1 chars"]
8076
+ set targetline {}
8077
} else {
8055
- $ctext insert end "$line" $tags
8056
- }
8057
- if {!$dowords} {
8058
- $ctext insert end "\n" $tags
8078
+ incr diffline
8079
}
8080
}
8061
- } elseif {$dowords && $prefix eq "~"} {
8062
- $ctext insert end "\n" {}
8063
- } else {
8064
- # "\ No newline at end of file",
8065
- # or something else we don't recognize
8066
- $ctext insert end "$line\n" hunksep
8081
+ if {$dowords && $worddiff eq [mc "Markup words"]} {
8082
+ $ctext insert end "$words_pre_markup$line$words_post_markup" $tags
8083
+ } else {
8084
+ $ctext insert end "$line" $tags
8085
+ }
8086
+ if {!$dowords} {
8087
+ $ctext insert end "\n" $tags
8088
+ }
8089
}
8090
+ } elseif {$dowords && $prefix eq "~"} {
8091
+ $ctext insert end "\n" {}
8092
+ } else {
8093
+ # "\ No newline at end of file",
8094
+ # or something else we don't recognize
8095
+ $ctext insert end "$line\n" hunksep
8096
}
8097
}
8070
- if {[info exists seehere]} {
8071
- mark_ctext_line [lindex [split $seehere .] 0]
8072
- }
8073
- maybe_scroll_ctext [eof $bdf]
8074
- $ctext conf -state disabled
8075
- if {[eof $bdf]} {
8076
- catch {close $bdf}
8077
- return 0
8078
- }
8079
- return [expr {$nr >= 1000? 2: 1}]
8098
}
8099
8100
proc changediffdisp {} {