Use lf translation rather than binary when reading commit data.
[git.git] / gitk
diff --git a/gitk b/gitk
index 2ee8a83..e21d7a2 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -48,13 +48,13 @@ proc getcommits {rargs} {
        exit 1
     }
     set leftover {}
-    fconfigure $commfd -blocking 0 -translation binary
+    fconfigure $commfd -blocking 0 -translation lf
     fileevent $commfd readable "getcommitlines $commfd"
     $canv delete all
     $canv create text 3 3 -anchor nw -text "Reading commits..." \
        -font $mainfont -tags textitems
     . config -cursor watch
-    $ctext config -cursor watch
+    settextcursor watch
 }
 
 proc getcommitlines {commfd}  {
@@ -277,7 +277,7 @@ proc makewindow {} {
     global canv canv2 canv3 linespc charspc ctext cflist textfont
     global findtype findtypemenu findloc findstring fstring geometry
     global entries sha1entry sha1string sha1but
-    global maincursor textcursor
+    global maincursor textcursor curtextcursor
     global rowctxmenu gaudydiff mergemax
 
     menu .bar
@@ -339,6 +339,30 @@ proc makewindow {} {
     entry $sha1entry -width 40 -font $textfont -textvariable sha1string
     trace add variable sha1string write sha1change
     pack $sha1entry -side left -pady 2
+
+    image create bitmap bm-left -data {
+       #define left_width 16
+       #define left_height 16
+       static unsigned char left_bits[] = {
+       0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
+       0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
+       0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
+    }
+    image create bitmap bm-right -data {
+       #define right_width 16
+       #define right_height 16
+       static unsigned char right_bits[] = {
+       0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
+       0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
+       0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
+    }
+    button .ctop.top.bar.leftbut -image bm-left -command goback \
+       -state disabled -width 26
+    pack .ctop.top.bar.leftbut -side left -fill y
+    button .ctop.top.bar.rightbut -image bm-right -command goforw \
+       -state disabled -width 26
+    pack .ctop.top.bar.rightbut -side left -fill y
+
     button .ctop.top.bar.findbut -text "Find" -command dofind
     pack .ctop.top.bar.findbut -side left
     set findstring {}
@@ -441,6 +465,7 @@ proc makewindow {} {
 
     set maincursor [. cget -cursor]
     set textcursor [$ctext cget -cursor]
+    set curtextcursor $textcursor
 
     set rowctxmenu .rowctxmenu
     menu $rowctxmenu -tearoff 0
@@ -1118,7 +1143,18 @@ proc finishcommits {} {
        drawrest $level [llength $startcommits]
     }
     . config -cursor $maincursor
-    $ctext config -cursor $textcursor
+    settextcursor $textcursor
+}
+
+# Don't change the text pane cursor if it is currently the hand cursor,
+# showing that we are over a sha1 ID link.
+proc settextcursor {c} {
+    global ctext curtextcursor
+
+    if {[$ctext cget -cursor] == $curtextcursor} {
+       $ctext config -cursor $c
+    }
+    set curtextcursor $c
 }
 
 proc drawgraph {} {
@@ -1175,7 +1211,7 @@ proc drawrest {level startix} {
     #puts "overall $drawmsecs ms for $numcommits commits"
     if {$redisplaying} {
        if {$stopped == 0 && [info exists selectedline]} {
-           selectline $selectedline
+           selectline $selectedline 0
        }
        if {$stopped == 1} {
            set stopped 0
@@ -1274,7 +1310,7 @@ proc dofind {} {
 
 proc findselectline {l} {
     global findloc commentend ctext
-    selectline $l
+    selectline $l 1
     if {$findloc == "All fields" || $findloc == "Comments"} {
        # highlight the matches in the comments
        set f [$ctext get 1.0 $commentend]
@@ -1353,7 +1389,7 @@ proc stopfindproc {{done 0}} {
        unset findinprogress
        if {$phase != "incrdraw"} {
            . config -cursor $maincursor
-           $ctext config -cursor $textcursor
+           settextcursor $textcursor
        }
     }
 }
@@ -1396,7 +1432,7 @@ proc findpatches {} {
     fileevent $f readable readfindproc
     set finddidsel 0
     . config -cursor watch
-    $ctext config -cursor watch
+    settextcursor watch
     set findinprogress 1
 }
 
@@ -1501,7 +1537,7 @@ proc findfiles {} {
     set id $lineid($l)
     set p [lindex $parents($id) 0]
     . config -cursor watch
-    $ctext config -cursor watch
+    settextcursor watch
     set findinprogress 1
     findcont [list $id $p]
     update
@@ -1665,15 +1701,17 @@ proc selcanvline {w x y} {
        if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return
     }
     unmarkmatches
-    selectline $l
+    selectline $l 1
 }
 
-proc selectline {l} {
+proc selectline {l isnew} {
     global canv canv2 canv3 ctext commitinfo selectedline
     global lineid linehtag linentag linedtag
     global canvy0 linespc parents nparents
     global cflist currentid sha1entry
-    global commentend idtags
+    global commentend idtags idline
+    global history historyindex
+
     $canv delete hover
     if {![info exists lineid($l)] || ![info exists linehtag($l)]} return
     $canv delete secsel
@@ -1722,6 +1760,22 @@ proc selectline {l} {
        }
        allcanvs yview moveto [expr $newtop * 1.0 / $ymax]
     }
+
+    if {$isnew && (![info exists selectedline] || $selectedline != $l)} {
+       if {$historyindex < [llength $history]} {
+           set history [lreplace $history $historyindex end $l]
+       } else {
+           lappend history $l
+       }
+       incr historyindex
+       if {$historyindex > 1} {
+           .ctop.top.bar.leftbut conf -state normal
+       } else {
+           .ctop.top.bar.leftbut conf -state disabled
+       }
+       .ctop.top.bar.rightbut conf -state disabled
+    }
+
     set selectedline $l
 
     set id $lineid($l)
@@ -1746,8 +1800,29 @@ proc selectline {l} {
        $ctext insert end "\n"
     }
     $ctext insert end "\n"
-    $ctext insert end [lindex $info 5]
+    set commentstart [$ctext index "end - 1c"]
+    set comment [lindex $info 5]
+    $ctext insert end $comment
     $ctext insert end "\n"
+
+    # make anything that looks like a SHA1 ID be a clickable link
+    set links [regexp -indices -all -inline {[0-9a-f]{40}} $comment]
+    set i 0
+    foreach l $links {
+       set s [lindex $l 0]
+       set e [lindex $l 1]
+       set linkid [string range $comment $s $e]
+       if {![info exists idline($linkid)]} continue
+       incr e
+       $ctext tag add link "$commentstart + $s c" "$commentstart + $e c"
+       $ctext tag add link$i "$commentstart + $s c" "$commentstart + $e c"
+       $ctext tag bind link$i <1> [list selectline $idline($linkid) 1]
+       incr i
+    }
+    $ctext tag conf link -foreground blue -underline 1
+    $ctext tag bind link <Enter> { %W configure -cursor hand2 }
+    $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+
     $ctext tag delete Comments
     $ctext tag remove found 1.0 end
     $ctext conf -state disabled
@@ -1767,7 +1842,34 @@ proc selnextline {dir} {
     if {![info exists selectedline]} return
     set l [expr $selectedline + $dir]
     unmarkmatches
-    selectline $l
+    selectline $l 1
+}
+
+proc goback {} {
+    global history historyindex
+
+    if {$historyindex > 1} {
+       incr historyindex -1
+       selectline [lindex $history [expr {$historyindex - 1}]] 0
+       .ctop.top.bar.rightbut conf -state normal
+    }
+    if {$historyindex <= 1} {
+       .ctop.top.bar.leftbut conf -state disabled
+    }
+}
+
+proc goforw {} {
+    global history historyindex
+
+    if {$historyindex < [llength $history]} {
+       set l [lindex $history $historyindex]
+       incr historyindex
+       selectline $l 0
+       .ctop.top.bar.leftbut conf -state normal
+    }
+    if {$historyindex >= [llength $history]} {
+       .ctop.top.bar.rightbut conf -state disabled
+    }
 }
 
 proc mergediff {id} {
@@ -2590,7 +2692,7 @@ proc gotocommit {} {
        }
     }
     if {[info exists idline($id)]} {
-       selectline $idline($id)
+       selectline $idline($id) 1
        return
     }
     if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
@@ -2702,7 +2804,7 @@ proc lineclick {x y id} {
 proc selbyid {id} {
     global idline
     if {[info exists idline($id)]} {
-       selectline $idline($id)
+       selectline $idline($id) 1
     }
 }
 
@@ -2906,7 +3008,7 @@ proc domktag {} {
     set xt [eval drawtags $id $idpos($id)]
     $canv coords $linehtag($idline($id)) $xt [lindex $idpos($id) 2]
     if {[info exists selectedline] && $selectedline == $idline($id)} {
-       selectline $selectedline
+       selectline $selectedline 0
     }
 }
 
@@ -3016,6 +3118,9 @@ foreach arg $argv {
     }
 }
 
+set history {}
+set historyindex 0
+
 set stopped 0
 set redisplaying 0
 set stuffsaved 0