gitk: Synchronize highlighting in file view when scrolling diff

Whenever the diff pane scrolls, highlight the corresponding file in the file list on the right. For a large commit with many files and long per-file diffs, this makes it easier to keep track of what you're looking at. This allows simplifying the prevfile and nextfile functions, because all they have to do is scroll the diff pane. In some situations we want to suppress this mechanism, for example when clicking on a file in the file list to select it, or when searching in the diff, in which case we want to highlight based on the current search hit and not the top line visible. In these cases it's not sufficient to set a "suppress" flag before scrolling and reset it afterwards, because the scrolltext notification is sent deferred from a timer or some such; so we need to remember the scroll position for which we want to suppress the auto-highlighting until the next call to scrolltext; a bit ugly, but does the job. Signed-off-by: Stefan Haller <stefan@haller-berlin.de> Signed-off-by: Paul Mackerras <paulus@samba.org>

Stefan Haller committed Sep 19, 2012 at 20:17 UTC b967135d89e8d8461d0590b2d5181781caeac741
1 file changed +43 -11
gitk
+43 -11
@@ -3309,6 +3309,7 @@ proc sel_flist {w x y} {
3309 } else {
3310 catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
3311 }
3312 + suppress_highlighting_file_for_current_scrollpos
3313 }
3314
3315 proc pop_flist_menu {w X Y x y} {
@@ -7947,32 +7948,42 @@ proc changediffdisp {} {
7948 $ctext tag conf dresult -elide [lindex $diffelide 1]
7949 }
7950
7950 -proc highlightfile {loc cline} {
7951 - global ctext cflist cflist_top
7951 +proc highlightfile {cline} {
7952 + global cflist cflist_top
7953
7953 - $ctext yview $loc
7954 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
7955 $cflist tag add highlight $cline.0 "$cline.0 lineend"
7956 $cflist see $cline.0
7957 set cflist_top $cline
7958 }
7959
7960 +proc highlightfile_for_scrollpos {topidx} {
7961 + global difffilestart
7962 +
7963 + if {![info exists difffilestart]} return
7964 +
7965 + set top [lindex [split $topidx .] 0]
7966 + if {$difffilestart eq {} || $top < [lindex $difffilestart 0]} {
7967 + highlightfile 0
7968 + } else {
7969 + highlightfile [expr {[bsearch $difffilestart $top] + 2}]
7970 + }
7971 +}
7972 +
7973 proc prevfile {} {
7974 global difffilestart ctext cmitmode
7975
7976 if {$cmitmode eq "tree"} return
7977 set prev 0.0
7965 - set prevline 1
7978 set here [$ctext index @0,0]
7979 foreach loc $difffilestart {
7980 if {[$ctext compare $loc >= $here]} {
7969 - highlightfile $prev $prevline
7981 + $ctext yview $prev
7982 return
7983 }
7984 set prev $loc
7973 - incr prevline
7985 }
7975 - highlightfile $prev $prevline
7986 + $ctext yview $prev
7987 }
7988
7989 proc nextfile {} {
@@ -7980,11 +7991,9 @@ proc nextfile {} {
7991
7992 if {$cmitmode eq "tree"} return
7993 set here [$ctext index @0,0]
7983 - set line 1
7994 foreach loc $difffilestart {
7985 - incr line
7995 if {[$ctext compare $loc > $here]} {
7987 - highlightfile $loc $line
7996 + $ctext yview $loc
7997 return
7998 }
7999 }
@@ -8046,6 +8055,8 @@ proc incrsearch {name ix op} {
8055 set here [$ctext search $searchdirn -- $searchstring anchor]
8056 if {$here ne {}} {
8057 $ctext see $here
8058 + suppress_highlighting_file_for_current_scrollpos
8059 + highlightfile_for_scrollpos $here
8060 }
8061 searchmarkvisible 1
8062 }
@@ -8071,6 +8082,8 @@ proc dosearch {} {
8082 return
8083 }
8084 $ctext see $match
8085 + suppress_highlighting_file_for_current_scrollpos
8086 + highlightfile_for_scrollpos $match
8087 set mend "$match + $mlen c"
8088 $ctext tag add sel $match $mend
8089 $ctext mark unset anchor
@@ -8097,6 +8110,8 @@ proc dosearchback {} {
8110 return
8111 }
8112 $ctext see $match
8113 + suppress_highlighting_file_for_current_scrollpos
8114 + highlightfile_for_scrollpos $match
8115 set mend "$match + $ml c"
8116 $ctext tag add sel $match $mend
8117 $ctext mark unset anchor
@@ -8137,8 +8152,25 @@ proc searchmarkvisible {doall} {
8152 }
8153 }
8154
8155 +proc suppress_highlighting_file_for_current_scrollpos {} {
8156 + global ctext suppress_highlighting_file_for_this_scrollpos
8157 +
8158 + set suppress_highlighting_file_for_this_scrollpos [$ctext index @0,0]
8159 +}
8160 +
8161 proc scrolltext {f0 f1} {
8141 - global searchstring
8162 + global searchstring cmitmode ctext
8163 + global suppress_highlighting_file_for_this_scrollpos
8164 +
8165 + if {$cmitmode ne "tree"} {
8166 + set topidx [$ctext index @0,0]
8167 + if {![info exists suppress_highlighting_file_for_this_scrollpos]
8168 + || $topidx ne $suppress_highlighting_file_for_this_scrollpos} {
8169 + highlightfile_for_scrollpos $topidx
8170 + }
8171 + }
8172 +
8173 + catch {unset suppress_highlighting_file_for_this_scrollpos}
8174
8175 .bleft.bottom.sb set $f0 $f1
8176 if {$searchstring ne {}} {