Skip to content

Commit 09c7029

Browse files
angavrilovpaulusmack
authored andcommitted
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 <[email protected]> Tested-by: Johannes Sixt <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent 3945d2c commit 09c7029

File tree

1 file changed

+63
-11
lines changed

1 file changed

+63
-11
lines changed

gitk

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6229,7 +6229,7 @@ proc gettree {id} {
62296229
set treepending $id
62306230
set treefilelist($id) {}
62316231
set treeidlist($id) {}
6232-
fconfigure $gtf -blocking 0
6232+
fconfigure $gtf -blocking 0 -encoding binary
62336233
filerun $gtf [list gettreeline $gtf $id]
62346234
}
62356235
} else {
@@ -6251,11 +6251,12 @@ proc gettreeline {gtf id} {
62516251
set line [string range $line 0 [expr {$i-1}]]
62526252
if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
62536253
set sha1 [lindex $line 2]
6254-
if {[string index $fname 0] eq "\""} {
6255-
set fname [lindex $fname 0]
6256-
}
62576254
lappend treeidlist($id) $sha1
62586255
}
6256+
if {[string index $fname 0] eq "\""} {
6257+
set fname [lindex $fname 0]
6258+
}
6259+
set fname [encoding convertfrom $fname]
62596260
lappend treefilelist($id) $fname
62606261
}
62616262
if {![eof $gtf]} {
@@ -6296,7 +6297,7 @@ proc showfile {f} {
62966297
return
62976298
}
62986299
}
6299-
fconfigure $bf -blocking 0
6300+
fconfigure $bf -blocking 0 -encoding [get_path_encoding $f]
63006301
filerun $bf [list getblobline $bf $diffids]
63016302
$ctext config -state normal
63026303
clear_ctext $commentend
@@ -6334,6 +6335,7 @@ proc mergediff {id} {
63346335
global diffids
63356336
global parents
63366337
global diffcontext
6338+
global diffencoding
63376339
global limitdiffs vfilelimit curview
63386340

63396341
set diffmergeid $id
@@ -6347,16 +6349,18 @@ proc mergediff {id} {
63476349
error_popup "[mc "Error getting merge diffs:"] $err"
63486350
return
63496351
}
6350-
fconfigure $mdf -blocking 0
6352+
fconfigure $mdf -blocking 0 -encoding binary
63516353
set mdifffd($id) $mdf
63526354
set np [llength $parents($curview,$id)]
6355+
set diffencoding [get_path_encoding {}]
63536356
settabs $np
63546357
filerun $mdf [list getmergediffline $mdf $id $np]
63556358
}
63566359

63576360
proc getmergediffline {mdf id np} {
63586361
global diffmergeid ctext cflist mergemax
63596362
global difffilestart mdifffd
6363+
global diffencoding
63606364

63616365
$ctext conf -state normal
63626366
set nr 0
@@ -6368,18 +6372,22 @@ proc getmergediffline {mdf id np} {
63686372
}
63696373
if {[regexp {^diff --cc (.*)} $line match fname]} {
63706374
# start of a new file
6375+
set fname [encoding convertfrom $fname]
63716376
$ctext insert end "\n"
63726377
set here [$ctext index "end - 1c"]
63736378
lappend difffilestart $here
63746379
add_flist [list $fname]
6380+
set diffencoding [get_path_encoding $fname]
63756381
set l [expr {(78 - [string length $fname]) / 2}]
63766382
set pad [string range "----------------------------------------" 1 $l]
63776383
$ctext insert end "$pad $fname $pad\n" filesep
63786384
} elseif {[regexp {^@@} $line]} {
6385+
set line [encoding convertfrom $diffencoding $line]
63796386
$ctext insert end "$line\n" hunksep
63806387
} elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
63816388
# do nothing
63826389
} else {
6390+
set line [encoding convertfrom $diffencoding $line]
63836391
# parse the prefix - one ' ', '-' or '+' for each parent
63846392
set spaces {}
63856393
set minuses {}
@@ -6514,7 +6522,7 @@ proc gettreediffs {ids} {
65146522

65156523
set treepending $ids
65166524
set treediff {}
6517-
fconfigure $gdtf -blocking 0
6525+
fconfigure $gdtf -blocking 0 -encoding binary
65186526
filerun $gdtf [list gettreediffline $gdtf $ids]
65196527
}
65206528

@@ -6530,6 +6538,7 @@ proc gettreediffline {gdtf ids} {
65306538
if {[string index $file 0] eq "\""} {
65316539
set file [lindex $file 0]
65326540
}
6541+
set file [encoding convertfrom $file]
65336542
lappend treediff $file
65346543
}
65356544
}
@@ -6587,6 +6596,7 @@ proc getblobdiffs {ids} {
65876596
global diffcontext
65886597
global ignorespace
65896598
global limitdiffs vfilelimit curview
6599+
global diffencoding
65906600

65916601
set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"]
65926602
if {$ignorespace} {
@@ -6600,7 +6610,8 @@ proc getblobdiffs {ids} {
66006610
return
66016611
}
66026612
set diffinhdr 0
6603-
fconfigure $bdf -blocking 0
6613+
set diffencoding [get_path_encoding {}]
6614+
fconfigure $bdf -blocking 0 -encoding binary
66046615
set blobdifffd($ids) $bdf
66056616
filerun $bdf [list getblobdiffline $bdf $diffids]
66066617
}
@@ -6634,6 +6645,7 @@ proc getblobdiffline {bdf ids} {
66346645
global diffids blobdifffd ctext curdiffstart
66356646
global diffnexthead diffnextnote difffilestart
66366647
global diffinhdr treediffs
6648+
global diffencoding
66376649

66386650
set nr 0
66396651
$ctext conf -state normal
@@ -6671,10 +6683,13 @@ proc getblobdiffline {bdf ids} {
66716683
} else {
66726684
set fname [string range $line 2 [expr {$i - 1}]]
66736685
}
6686+
set fname [encoding convertfrom $fname]
6687+
set diffencoding [get_path_encoding $fname]
66746688
makediffhdr $fname $ids
66756689

66766690
} elseif {[regexp {^@@ -([0-9]+)(,[0-9]+)? \+([0-9]+)(,[0-9]+)? @@(.*)} \
66776691
$line match f1l f1c f2l f2c rest]} {
6692+
set line [encoding convertfrom $diffencoding $line]
66786693
$ctext insert end "$line\n" hunksep
66796694
set diffinhdr 0
66806695

@@ -6684,6 +6699,7 @@ proc getblobdiffline {bdf ids} {
66846699
if {[string index $fname 0] eq "\""} {
66856700
set fname [lindex $fname 0]
66866701
}
6702+
set fname [encoding convertfrom $fname]
66876703
set i [lsearch -exact $treediffs($ids) $fname]
66886704
if {$i >= 0} {
66896705
setinlist difffilestart $i $curdiffstart
@@ -6694,6 +6710,8 @@ proc getblobdiffline {bdf ids} {
66946710
if {[string index $fname 0] eq "\""} {
66956711
set fname [lindex $fname 0]
66966712
}
6713+
set fname [encoding convertfrom $fname]
6714+
set diffencoding [get_path_encoding $fname]
66976715
makediffhdr $fname $ids
66986716
} elseif {[string compare -length 3 $line "---"] == 0} {
66996717
# do nothing
@@ -6705,6 +6723,7 @@ proc getblobdiffline {bdf ids} {
67056723
$ctext insert end "$line\n" filesep
67066724

67076725
} else {
6726+
set line [encoding convertfrom $diffencoding $line]
67086727
set x [string range $line 0 0]
67096728
if {$x == "-" || $x == "+"} {
67106729
set tag [expr {$x == "+"}]
@@ -9727,7 +9746,7 @@ set encoding_aliases {
97279746
{ ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
97289747
{ GBK CP936 MS936 windows-936 }
97299748
{ JIS_Encoding csJISEncoding }
9730-
{ Shift_JIS MS_Kanji csShiftJIS }
9749+
{ Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS }
97319750
{ Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
97329751
EUC-JP }
97339752
{ Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
@@ -9769,7 +9788,7 @@ proc tcl_encoding {enc} {
97699788
set i [lsearch -exact $lcnames $enc]
97709789
if {$i < 0} {
97719790
# 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]} {
97739792
set i [lsearch -exact $lcnames $encx]
97749793
}
97759794
}
@@ -9781,7 +9800,7 @@ proc tcl_encoding {enc} {
97819800
foreach e $ll {
97829801
set i [lsearch -exact $lcnames $e]
97839802
if {$i < 0} {
9784-
if {[regsub {^iso[-_]} $e iso ex]} {
9803+
if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\1} ex]} {
97859804
set i [lsearch -exact $lcnames $ex]
97869805
}
97879806
}
@@ -9796,6 +9815,34 @@ proc tcl_encoding {enc} {
97969815
return {}
97979816
}
97989817

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+
97999846
# First check that Tcl/Tk is recent enough
98009847
if {[catch {package require Tk 8.4} err]} {
98019848
show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
@@ -9818,6 +9865,11 @@ if {$tclencoding == {}} {
98189865
puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
98199866
}
98209867

9868+
set gui_encoding [encoding system]
9869+
catch {
9870+
set gui_encoding [exec git config --get gui.encoding]
9871+
}
9872+
98219873
set mainfont {Helvetica 9}
98229874
set textfont {Courier 9}
98239875
set uifont {Helvetica 9 bold}

0 commit comments

Comments
 (0)