From: Alexander Gavrilov Date: Mon, 13 Oct 2008 08:12:31 +0000 (+0400) Subject: gitk: Enhance file encoding support X-Git-Tag: v1.6.1-rc1~2^2~27 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=09c7029dfa58748268a6306bfe764456a65a22bf;p=git.git 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 Tested-by: Johannes Sixt Signed-off-by: Paul Mackerras --- diff --git a/gitk b/gitk index dce17e9f1..5f35f612c 100755 --- a/gitk +++ b/gitk @@ -6229,7 +6229,7 @@ proc gettree {id} { set treepending $id set treefilelist($id) {} set treeidlist($id) {} - fconfigure $gtf -blocking 0 + fconfigure $gtf -blocking 0 -encoding binary filerun $gtf [list gettreeline $gtf $id] } } else { @@ -6251,11 +6251,12 @@ proc gettreeline {gtf id} { set line [string range $line 0 [expr {$i-1}]] if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue set sha1 [lindex $line 2] - if {[string index $fname 0] eq "\""} { - set fname [lindex $fname 0] - } lappend treeidlist($id) $sha1 } + if {[string index $fname 0] eq "\""} { + set fname [lindex $fname 0] + } + set fname [encoding convertfrom $fname] lappend treefilelist($id) $fname } if {![eof $gtf]} { @@ -6296,7 +6297,7 @@ proc showfile {f} { return } } - fconfigure $bf -blocking 0 + fconfigure $bf -blocking 0 -encoding [get_path_encoding $f] filerun $bf [list getblobline $bf $diffids] $ctext config -state normal clear_ctext $commentend @@ -6334,6 +6335,7 @@ proc mergediff {id} { global diffids global parents global diffcontext + global diffencoding global limitdiffs vfilelimit curview set diffmergeid $id @@ -6347,9 +6349,10 @@ proc mergediff {id} { error_popup "[mc "Error getting merge diffs:"] $err" return } - fconfigure $mdf -blocking 0 + fconfigure $mdf -blocking 0 -encoding binary set mdifffd($id) $mdf set np [llength $parents($curview,$id)] + set diffencoding [get_path_encoding {}] settabs $np filerun $mdf [list getmergediffline $mdf $id $np] } @@ -6357,6 +6360,7 @@ proc mergediff {id} { proc getmergediffline {mdf id np} { global diffmergeid ctext cflist mergemax global difffilestart mdifffd + global diffencoding $ctext conf -state normal set nr 0 @@ -6368,18 +6372,22 @@ proc getmergediffline {mdf id np} { } if {[regexp {^diff --cc (.*)} $line match fname]} { # start of a new file + set fname [encoding convertfrom $fname] $ctext insert end "\n" set here [$ctext index "end - 1c"] lappend difffilestart $here add_flist [list $fname] + set diffencoding [get_path_encoding $fname] set l [expr {(78 - [string length $fname]) / 2}] set pad [string range "----------------------------------------" 1 $l] $ctext insert end "$pad $fname $pad\n" filesep } elseif {[regexp {^@@} $line]} { + set line [encoding convertfrom $diffencoding $line] $ctext insert end "$line\n" hunksep } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} { # do nothing } else { + set line [encoding convertfrom $diffencoding $line] # parse the prefix - one ' ', '-' or '+' for each parent set spaces {} set minuses {} @@ -6514,7 +6522,7 @@ proc gettreediffs {ids} { set treepending $ids set treediff {} - fconfigure $gdtf -blocking 0 + fconfigure $gdtf -blocking 0 -encoding binary filerun $gdtf [list gettreediffline $gdtf $ids] } @@ -6530,6 +6538,7 @@ proc gettreediffline {gdtf ids} { if {[string index $file 0] eq "\""} { set file [lindex $file 0] } + set file [encoding convertfrom $file] lappend treediff $file } } @@ -6587,6 +6596,7 @@ proc getblobdiffs {ids} { global diffcontext global ignorespace global limitdiffs vfilelimit curview + global diffencoding set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] if {$ignorespace} { @@ -6600,7 +6610,8 @@ proc getblobdiffs {ids} { return } set diffinhdr 0 - fconfigure $bdf -blocking 0 + set diffencoding [get_path_encoding {}] + fconfigure $bdf -blocking 0 -encoding binary set blobdifffd($ids) $bdf filerun $bdf [list getblobdiffline $bdf $diffids] } @@ -6634,6 +6645,7 @@ proc getblobdiffline {bdf ids} { global diffids blobdifffd ctext curdiffstart global diffnexthead diffnextnote difffilestart global diffinhdr treediffs + global diffencoding set nr 0 $ctext conf -state normal @@ -6671,10 +6683,13 @@ proc getblobdiffline {bdf ids} { } else { set fname [string range $line 2 [expr {$i - 1}]] } + set fname [encoding convertfrom $fname] + set diffencoding [get_path_encoding $fname] makediffhdr $fname $ids } elseif {[regexp {^@@ -([0-9]+)(,[0-9]+)? \+([0-9]+)(,[0-9]+)? @@(.*)} \ $line match f1l f1c f2l f2c rest]} { + set line [encoding convertfrom $diffencoding $line] $ctext insert end "$line\n" hunksep set diffinhdr 0 @@ -6684,6 +6699,7 @@ proc getblobdiffline {bdf ids} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } + set fname [encoding convertfrom $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { setinlist difffilestart $i $curdiffstart @@ -6694,6 +6710,8 @@ proc getblobdiffline {bdf ids} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } + set fname [encoding convertfrom $fname] + set diffencoding [get_path_encoding $fname] makediffhdr $fname $ids } elseif {[string compare -length 3 $line "---"] == 0} { # do nothing @@ -6705,6 +6723,7 @@ proc getblobdiffline {bdf ids} { $ctext insert end "$line\n" filesep } else { + set line [encoding convertfrom $diffencoding $line] set x [string range $line 0 0] if {$x == "-" || $x == "+"} { set tag [expr {$x == "+"}] @@ -9727,7 +9746,7 @@ set encoding_aliases { { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 } { GBK CP936 MS936 windows-936 } { JIS_Encoding csJISEncoding } - { Shift_JIS MS_Kanji csShiftJIS } + { Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS } { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese EUC-JP } { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese } @@ -9769,7 +9788,7 @@ proc tcl_encoding {enc} { set i [lsearch -exact $lcnames $enc] if {$i < 0} { # look for "isonnn" instead of "iso-nnn" or "iso_nnn" - if {[regsub {^iso[-_]} $enc iso encx]} { + if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} { set i [lsearch -exact $lcnames $encx] } } @@ -9781,7 +9800,7 @@ proc tcl_encoding {enc} { foreach e $ll { set i [lsearch -exact $lcnames $e] if {$i < 0} { - if {[regsub {^iso[-_]} $e iso ex]} { + if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\1} ex]} { set i [lsearch -exact $lcnames $ex] } } @@ -9796,6 +9815,34 @@ proc tcl_encoding {enc} { return {} } +proc gitattr {path attr default} { + if {[catch {set r [exec git check-attr $attr -- $path]}]} { + set r unspecified + } else { + set r [join [lrange [split $r :] 2 end] :] + regsub {^ } $r {} r + } + if {$r eq {unspecified}} { + return $default + } + return $r +} + +proc get_path_encoding {path} { + global gui_encoding + set tcl_enc [tcl_encoding $gui_encoding] + if {$tcl_enc eq {}} { + set tcl_enc [encoding system] + } + if {$path ne {}} { + set enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]] + if {$enc2 ne {}} { + set tcl_enc $enc2 + } + } + return $tcl_enc +} + # First check that Tcl/Tk is recent enough if {[catch {package require Tk 8.4} err]} { show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\ @@ -9818,6 +9865,11 @@ if {$tclencoding == {}} { puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk" } +set gui_encoding [encoding system] +catch { + set gui_encoding [exec git config --get gui.encoding] +} + set mainfont {Helvetica 9} set textfont {Courier 9} set uifont {Helvetica 9 bold}