@matheusbsbs / matheus-bagliano / commits / 09c7029dfa
Fork 0

gitk: Enhance file encoding support

This allows the encoding to be specified for file contents and used when displaying files and diffs in the bottom-left pane. When displaying diffs, the encoding for each diff hunk is that for the file that the diff hunk is from, so it can change through the course of the diff. The encoding for file contents is determined as follows: - File encoding defaults to the system encoding. - It can be overridden by setting the gui.encoding option. - Finally, the 'encoding' attribute is checked on per-file basis; it has the last word. Note: Since git-check-attr does not provide support for reading attributes from trees, attribute lookup is done using files from the working directory. This also extends the range of supported encoding names, adding ShiftJIS and Shift-JIS as aliases for Shift_JIS, and allowing cp-*, cp_*, ibm-*, ibm_*, jis-* and jis_* as aliases for cp*, ibm* and jis* respectively. This also fixes some bugs in handling of non-ASCII filenames. Core git apparently supports only locale-encoded filenames, so processing is done using the system encoding. Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> Tested-by: Johannes Sixt <johannes.sixt@telecom.at> Signed-off-by: Paul Mackerras <paulus@samba.org>

Alexander Gavrilov committed Oct 13, 2008 at 12:12 UTC 09c7029dfa58748268a6306bfe764456a65a22bf
1 file changed +63 -11
gitk
+63 -11
@@ -6229,7 +6229,7 @@ proc gettree {id} {
6229 set treepending $id
6230 set treefilelist($id) {}
6231 set treeidlist($id) {}
6232 - fconfigure $gtf -blocking 0
6232 + fconfigure $gtf -blocking 0 -encoding binary
6233 filerun $gtf [list gettreeline $gtf $id]
6234 }
6235 } else {
@@ -6251,11 +6251,12 @@ proc gettreeline {gtf id} {
6251 set line [string range $line 0 [expr {$i-1}]]
6252 if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
6253 set sha1 [lindex $line 2]
6254 - if {[string index $fname 0] eq "\""} {
6255 - set fname [lindex $fname 0]
6256 - }
6254 lappend treeidlist($id) $sha1
6255 }
6256 + if {[string index $fname 0] eq "\""} {
6257 + set fname [lindex $fname 0]
6258 + }
6259 + set fname [encoding convertfrom $fname]
6260 lappend treefilelist($id) $fname
6261 }
6262 if {![eof $gtf]} {
@@ -6296,7 +6297,7 @@ proc showfile {f} {
6297 return
6298 }
6299 }
6299 - fconfigure $bf -blocking 0
6300 + fconfigure $bf -blocking 0 -encoding [get_path_encoding $f]
6301 filerun $bf [list getblobline $bf $diffids]
6302 $ctext config -state normal
6303 clear_ctext $commentend
@@ -6334,6 +6335,7 @@ proc mergediff {id} {
6335 global diffids
6336 global parents
6337 global diffcontext
6338 + global diffencoding
6339 global limitdiffs vfilelimit curview
6340
6341 set diffmergeid $id
@@ -6347,9 +6349,10 @@ proc mergediff {id} {
6349 error_popup "[mc "Error getting merge diffs:"] $err"
6350 return
6351 }
6350 - fconfigure $mdf -blocking 0
6352 + fconfigure $mdf -blocking 0 -encoding binary
6353 set mdifffd($id) $mdf
6354 set np [llength $parents($curview,$id)]
6355 + set diffencoding [get_path_encoding {}]
6356 settabs $np
6357 filerun $mdf [list getmergediffline $mdf $id $np]
6358 }
@@ -6357,6 +6360,7 @@ proc mergediff {id} {
6360 proc getmergediffline {mdf id np} {
6361 global diffmergeid ctext cflist mergemax
6362 global difffilestart mdifffd
6363 + global diffencoding
6364
6365 $ctext conf -state normal
6366 set nr 0
@@ -6368,18 +6372,22 @@ proc getmergediffline {mdf id np} {
6372 }
6373 if {[regexp {^diff --cc (.*)} $line match fname]} {
6374 # start of a new file
6375 + set fname [encoding convertfrom $fname]
6376 $ctext insert end "\n"
6377 set here [$ctext index "end - 1c"]
6378 lappend difffilestart $here
6379 add_flist [list $fname]
6380 + set diffencoding [get_path_encoding $fname]
6381 set l [expr {(78 - [string length $fname]) / 2}]
6382 set pad [string range "----------------------------------------" 1 $l]
6383 $ctext insert end "$pad $fname $pad\n" filesep
6384 } elseif {[regexp {^@@} $line]} {
6385 + set line [encoding convertfrom $diffencoding $line]
6386 $ctext insert end "$line\n" hunksep
6387 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
6388 # do nothing
6389 } else {
6390 + set line [encoding convertfrom $diffencoding $line]
6391 # parse the prefix - one ' ', '-' or '+' for each parent
6392 set spaces {}
6393 set minuses {}
@@ -6514,7 +6522,7 @@ proc gettreediffs {ids} {
6522
6523 set treepending $ids
6524 set treediff {}
6517 - fconfigure $gdtf -blocking 0
6525 + fconfigure $gdtf -blocking 0 -encoding binary
6526 filerun $gdtf [list gettreediffline $gdtf $ids]
6527 }
6528
@@ -6530,6 +6538,7 @@ proc gettreediffline {gdtf ids} {
6538 if {[string index $file 0] eq "\""} {
6539 set file [lindex $file 0]
6540 }
6541 + set file [encoding convertfrom $file]
6542 lappend treediff $file
6543 }
6544 }
@@ -6587,6 +6596,7 @@ proc getblobdiffs {ids} {
6596 global diffcontext
6597 global ignorespace
6598 global limitdiffs vfilelimit curview
6599 + global diffencoding
6600
6601 set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"]
6602 if {$ignorespace} {
@@ -6600,7 +6610,8 @@ proc getblobdiffs {ids} {
6610 return
6611 }
6612 set diffinhdr 0
6603 - fconfigure $bdf -blocking 0
6613 + set diffencoding [get_path_encoding {}]
6614 + fconfigure $bdf -blocking 0 -encoding binary
6615 set blobdifffd($ids) $bdf
6616 filerun $bdf [list getblobdiffline $bdf $diffids]
6617 }
@@ -6634,6 +6645,7 @@ proc getblobdiffline {bdf ids} {
6645 global diffids blobdifffd ctext curdiffstart
6646 global diffnexthead diffnextnote difffilestart
6647 global diffinhdr treediffs
6648 + global diffencoding
6649
6650 set nr 0
6651 $ctext conf -state normal
@@ -6671,10 +6683,13 @@ proc getblobdiffline {bdf ids} {
6683 } else {
6684 set fname [string range $line 2 [expr {$i - 1}]]
6685 }
6686 + set fname [encoding convertfrom $fname]
6687 + set diffencoding [get_path_encoding $fname]
6688 makediffhdr $fname $ids
6689
6690 } elseif {[regexp {^@@ -([0-9]+)(,[0-9]+)? \+([0-9]+)(,[0-9]+)? @@(.*)} \
6691 $line match f1l f1c f2l f2c rest]} {
6692 + set line [encoding convertfrom $diffencoding $line]
6693 $ctext insert end "$line\n" hunksep
6694 set diffinhdr 0
6695
@@ -6684,6 +6699,7 @@ proc getblobdiffline {bdf ids} {
6699 if {[string index $fname 0] eq "\""} {
6700 set fname [lindex $fname 0]
6701 }
6702 + set fname [encoding convertfrom $fname]
6703 set i [lsearch -exact $treediffs($ids) $fname]
6704 if {$i >= 0} {
6705 setinlist difffilestart $i $curdiffstart
@@ -6694,6 +6710,8 @@ proc getblobdiffline {bdf ids} {
6710 if {[string index $fname 0] eq "\""} {
6711 set fname [lindex $fname 0]
6712 }
6713 + set fname [encoding convertfrom $fname]
6714 + set diffencoding [get_path_encoding $fname]
6715 makediffhdr $fname $ids
6716 } elseif {[string compare -length 3 $line "---"] == 0} {
6717 # do nothing
@@ -6705,6 +6723,7 @@ proc getblobdiffline {bdf ids} {
6723 $ctext insert end "$line\n" filesep
6724
6725 } else {
6726 + set line [encoding convertfrom $diffencoding $line]
6727 set x [string range $line 0 0]
6728 if {$x == "-" || $x == "+"} {
6729 set tag [expr {$x == "+"}]
@@ -9727,7 +9746,7 @@ set encoding_aliases {
9746 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
9747 { GBK CP936 MS936 windows-936 }
9748 { JIS_Encoding csJISEncoding }
9730 - { Shift_JIS MS_Kanji csShiftJIS }
9749 + { Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS }
9750 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
9751 EUC-JP }
9752 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
@@ -9769,7 +9788,7 @@ proc tcl_encoding {enc} {
9788 set i [lsearch -exact $lcnames $enc]
9789 if {$i < 0} {
9790 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
9772 - if {[regsub {^iso[-_]} $enc iso encx]} {
9791 + if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} {
9792 set i [lsearch -exact $lcnames $encx]
9793 }
9794 }
@@ -9781,7 +9800,7 @@ proc tcl_encoding {enc} {
9800 foreach e $ll {
9801 set i [lsearch -exact $lcnames $e]
9802 if {$i < 0} {
9784 - if {[regsub {^iso[-_]} $e iso ex]} {
9803 + if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\1} ex]} {
9804 set i [lsearch -exact $lcnames $ex]
9805 }
9806 }
@@ -9796,6 +9815,34 @@ proc tcl_encoding {enc} {
9815 return {}
9816 }
9817
9818 +proc gitattr {path attr default} {
9819 + if {[catch {set r [exec git check-attr $attr -- $path]}]} {
9820 + set r unspecified
9821 + } else {
9822 + set r [join [lrange [split $r :] 2 end] :]
9823 + regsub {^ } $r {} r
9824 + }
9825 + if {$r eq {unspecified}} {
9826 + return $default
9827 + }
9828 + return $r
9829 +}
9830 +
9831 +proc get_path_encoding {path} {
9832 + global gui_encoding
9833 + set tcl_enc [tcl_encoding $gui_encoding]
9834 + if {$tcl_enc eq {}} {
9835 + set tcl_enc [encoding system]
9836 + }
9837 + if {$path ne {}} {
9838 + set enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]
9839 + if {$enc2 ne {}} {
9840 + set tcl_enc $enc2
9841 + }
9842 + }
9843 + return $tcl_enc
9844 +}
9845 +
9846 # First check that Tcl/Tk is recent enough
9847 if {[catch {package require Tk 8.4} err]} {
9848 show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
@@ -9818,6 +9865,11 @@ if {$tclencoding == {}} {
9865 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
9866 }
9867
9868 +set gui_encoding [encoding system]
9869 +catch {
9870 + set gui_encoding [exec git config --get gui.encoding]
9871 +}
9872 +
9873 set mainfont {Helvetica 9}
9874 set textfont {Courier 9}
9875 set uifont {Helvetica 9 bold}