git-gui: Always indicate the file in the diff viewer.

When we did a rescan to update the file lists we lost the tag which
indicated which file was currently in the diff viewer.  This occurs
because we delete every line from the two file list boxes (thus
removing the tag) and then redisplay the diff in the diff viewer
but then fail to restore the tag in the file list.

Now we restore that tag by searching for the file in the file lists
and adding the tag back when the diff viewer displays something.

We also no longer obtain the file path directly from the file list
text box.  Instead we now keep two Tcl lists, one for each file list,
holding the file names in sorted order.  These lists can be searched
with the native [lsearch -sorted] operation (which should be faster
than our crude bsearch) or can be quickly accessed by index to return
the file path.  This should help make things safer should we ever be
given a file name which contains an LF within it (as that would span
two lines in the file list, not one).

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
maint
Shawn O. Pearce 2006-11-11 17:52:16 -05:00
parent 7d9e1d5e8a
commit 03e4ec5364
1 changed files with 36 additions and 36 deletions

72
git-gui
View File

@ -150,7 +150,7 @@ proc repository_state {hdvar ctvar} {
proc update_status {{final Ready.}} { proc update_status {{final Ready.}} {
global HEAD PARENT commit_type global HEAD PARENT commit_type
global ui_index ui_other ui_status_value ui_comm global ui_index ui_other ui_status_value ui_comm
global status_active file_states global status_active file_states file_lists
global cfg_trust_mtime global cfg_trust_mtime


if {$status_active || ![lock_index read]} return if {$status_active || ![lock_index read]} return
@ -166,6 +166,7 @@ proc update_status {{final Ready.}} {
} }


array unset file_states array unset file_states
array unset file_lists
foreach w [list $ui_index $ui_other] { foreach w [list $ui_index $ui_other] {
$w conf -state normal $w conf -state normal
$w delete 0.0 end $w delete 0.0 end
@ -196,7 +197,7 @@ proc update_status {{final Ready.}} {
proc update_status_stage2 {fd final} { proc update_status_stage2 {fd final} {
global gitdir PARENT commit_type global gitdir PARENT commit_type
global ui_index ui_other ui_status_value ui_comm global ui_index ui_other ui_status_value ui_comm
global status_active file_states global status_active
global buf_rdi buf_rdf buf_rlo global buf_rdi buf_rdf buf_rlo


if {$fd != {}} { if {$fd != {}} {
@ -346,22 +347,40 @@ proc status_eof {fd buf final} {
## diff ## diff


proc clear_diff {} { proc clear_diff {} {
global ui_diff ui_fname_value ui_fstatus_value global ui_diff ui_fname_value ui_fstatus_value ui_index ui_other


$ui_diff conf -state normal $ui_diff conf -state normal
$ui_diff delete 0.0 end $ui_diff delete 0.0 end
$ui_diff conf -state disabled $ui_diff conf -state disabled

set ui_fname_value {} set ui_fname_value {}
set ui_fstatus_value {} set ui_fstatus_value {}

$ui_index tag remove in_diff 0.0 end
$ui_other tag remove in_diff 0.0 end
} }


proc show_diff {path} { proc show_diff {path {w {}} {lno {}}} {
global file_states PARENT diff_3way diff_active global file_states file_lists
global PARENT diff_3way diff_active
global ui_diff ui_fname_value ui_fstatus_value ui_status_value global ui_diff ui_fname_value ui_fstatus_value ui_status_value


if {$diff_active || ![lock_index read]} return if {$diff_active || ![lock_index read]} return


clear_diff clear_diff
if {$w == {} || $lno == {}} {
foreach w [array names file_lists] {
set lno [lsearch -sorted $file_lists($w) $path]
if {$lno >= 0} {
incr lno
break
}
}
}
if {$w != {} && $lno >= 1} {
$w tag add in_diff $lno.0 [expr $lno + 1].0
}

set s $file_states($path) set s $file_states($path)
set m [lindex $s 0] set m [lindex $s 0]
set diff_3way 0 set diff_3way 0
@ -823,27 +842,6 @@ proc mapdesc {state path} {
return $r return $r
} }


proc bsearch {w path} {
set hi [expr [lindex [split [$w index end] .] 0] - 2]
if {$hi == 0} {
return -1
}
set lo 0
while {$lo < $hi} {
set mi [expr [expr $lo + $hi] / 2]
set ti [expr $mi + 1]
set cmp [string compare [$w get $ti.1 $ti.end] $path]
if {$cmp < 0} {
set lo $ti
} elseif {$cmp == 0} {
return $mi
} else {
set hi $mi
}
}
return -[expr $lo + 1]
}

set next_icon_id 0 set next_icon_id 0


proc merge_state {path new_state} { proc merge_state {path new_state} {
@ -877,7 +875,8 @@ proc merge_state {path new_state} {
} }


proc display_file {path state} { proc display_file {path state} {
global ui_index ui_other file_states status_active global ui_index ui_other
global file_states file_lists status_active


set old_m [merge_state $path $state] set old_m [merge_state $path $state]
if {$status_active} return if {$status_active} return
@ -889,7 +888,7 @@ proc display_file {path state} {
set new_icon [mapicon $new_m $path] set new_icon [mapicon $new_m $path]


if {$new_w != $old_w} { if {$new_w != $old_w} {
set lno [bsearch $old_w $path] set lno [lsearch -sorted $file_lists($old_w) $path]
if {$lno >= 0} { if {$lno >= 0} {
incr lno incr lno
$old_w conf -state normal $old_w conf -state normal
@ -897,7 +896,10 @@ proc display_file {path state} {
$old_w conf -state disabled $old_w conf -state disabled
} }


set lno [expr abs([bsearch $new_w $path] + 1) + 1] lappend file_lists($new_w) $path
set file_lists($new_w) [lsort $file_lists($new_w)]
set lno [lsearch -sorted $file_lists($new_w) $path]
incr lno
$new_w conf -state normal $new_w conf -state normal
$new_w image create $lno.0 \ $new_w image create $lno.0 \
-align center -padx 5 -pady 1 \ -align center -padx 5 -pady 1 \
@ -913,7 +915,7 @@ proc display_file {path state} {
} }


proc display_all_files {} { proc display_all_files {} {
global ui_index ui_other file_states global ui_index ui_other file_states file_lists


$ui_index conf -state normal $ui_index conf -state normal
$ui_other conf -state normal $ui_other conf -state normal
@ -922,6 +924,7 @@ proc display_all_files {} {
set s $file_states($path) set s $file_states($path)
set m [lindex $s 0] set m [lindex $s 0]
set w [mapcol $m $path] set w [mapcol $m $path]
lappend file_lists($w) $path
$w image create end \ $w image create end \
-align center -padx 5 -pady 1 \ -align center -padx 5 -pady 1 \
-name [lindex $s 1] \ -name [lindex $s 1] \
@ -1484,19 +1487,16 @@ proc do_commit {} {
# shift == 1: left click # shift == 1: left click
# 3: right click # 3: right click
proc click {w x y shift wx wy} { proc click {w x y shift wx wy} {
global ui_index ui_other global ui_index ui_other file_lists


set pos [split [$w index @$x,$y] .] set pos [split [$w index @$x,$y] .]
set lno [lindex $pos 0] set lno [lindex $pos 0]
set col [lindex $pos 1] set col [lindex $pos 1]
set path [$w get $lno.1 $lno.end] set path [lindex $file_lists($w) [expr $lno - 1]]
if {$path == {}} return if {$path == {}} return


if {$col > 0 && $shift == 1} { if {$col > 0 && $shift == 1} {
$ui_index tag remove in_diff 0.0 end show_diff $path $w $lno
$ui_other tag remove in_diff 0.0 end
$w tag add in_diff $lno.0 [expr $lno + 1].0
show_diff $path
} }
} }