{"thread":{"id":"1622","subject":"gitk tree view","startedAt":"2005-08-23T04:24:32Z","lastAt":"2005-08-24T22:35:50Z","messageCount":2,"participants":["Ingo Bormuth"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"7647","messageId":"20050823042432.GA21140@kruemel","threadId":"1622","inReplyTo":null,"subject":"gitk tree view","fromName":"Ingo Bormuth","fromEmail":"ibormuth@efil.de","sentAt":"2005-08-23T04:24:32Z","receivedAt":"2005-08-23T04:24:32Z","isPatch":false,"sender":{"key":"ibormuth@efil.de","avatar":null},"body":"\nHi.\n\nThis is a quick hack which allows you to browser the entire tree using gitk.\n\nKeybindings:  n - toggle line numbers\n              v - toggle tree view\n\nI know, it should be cleaned up. It needs some locking. \nColored diffs in the tree would be nice.\n\nIs anybody interested in a propper version ???\n\nCheers Ingo\n\n\n-- \n   +--------------------------------------------------------+\n   | Ingo Bormuth,  voicebox & telefax: +49-12125-10226517  |\n   | GnuPG key 86326EC9 at http://ibormuth.efil.de/contact  |\n   +--------------------------------------------------------+\n\n\n\n\n\nAdded tree view.\nThis is a rather quick hack.\n\n---\ncommit 4f697f79d6e82d0d0269eeda5f746174c6ba047e\ntree c6f82a184da82ed417f170d1b7e2025a801c879b\nparent 792fe559d02e55c12d2d544fd6d6f202cbaab6f4\nauthor <ingo@kruemel.(none)> Tue, 23 Aug 2005 06:08:21 +0200\ncommitter <ingo@kruemel.(none)> Tue, 23 Aug 2005 06:08:21 +0200\n\n gitk |  189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 183 insertions(+), 6 deletions(-)\n\ndiff --git a/gitk b/gitk\n--- a/gitk\n+++ b/gitk\n@@ -329,12 +329,13 @@ proc makewindow {} {\n     global findtype findtypemenu findloc findstring fstring geometry\n     global entries sha1entry sha1string sha1but\n     global maincursor textcursor curtextcursor\n-    global rowctxmenu gaudydiff mergemax\n+    global rowctxmenu gaudydiff mergemax viewmodebutton\n \n     menu .bar\n     .bar add cascade -label \"File\" -menu .bar.file\n     menu .bar.file\n     .bar.file add command -label \"Reread references\" -command rereadrefs\n+    .bar.file add command -label \"Toggle line numbers\" -command togglelinenum\n     .bar.file add command -label \"Quit\" -command doquit\n     menu .bar.help\n     .bar add cascade -label \"Help\" -menu .bar.help\n@@ -381,6 +382,9 @@ proc makewindow {} {\n     .ctop.top.clist add $canv3\n     bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}\n \n+    set viewmodebutton Tree\n+    button .ctop.top.bar.viewmodebutton -textvariable viewmodebutton -command togglesetviewmode\n+    pack .ctop.top.bar.viewmodebutton -side left\n     set sha1entry .ctop.top.bar.sha1\n     set entries $sha1entry\n     set sha1but .ctop.top.bar.sha1label\n@@ -493,9 +497,11 @@ proc makewindow {} {\n     bindkey <Key-space> \"$ctext yview scroll 1 pages\"\n     bindkey p \"selnextline -1\"\n     bindkey n \"selnextline 1\"\n+    bindkey l \"togglelinenum\"\n     bindkey b \"$ctext yview scroll -1 pages\"\n     bindkey d \"$ctext yview scroll 18 units\"\n     bindkey u \"$ctext yview scroll -18 units\"\n+    bindkey v \"toggleviewmode\"\n     bindkey / {findnext 1}\n     bindkey <Key-Return> {findnext 0}\n     bindkey ? findprev\n@@ -2056,7 +2062,7 @@ proc selectline {l isnew} {\n     global lineid linehtag linentag linedtag\n     global canvy0 linespc parents nparents children\n     global cflist currentid sha1entry\n-    global commentend idtags idline linknum\n+    global commentend idtags idline linknum viewmodebutton\n \n     $canv delete hover\n     if {![info exists lineid($l)] || ![info exists linehtag($l)]} return\n@@ -2815,10 +2821,173 @@ proc gettreediffline {gdtf ids} {\n     lappend treediff $file\n }\n \n+proc toggleviewmode {} {\n+    global viewmodebutton selectedline\n+    if { $viewmodebutton == \"Commit\" } { \n+        set viewmodebutton Tree\n+    } else { \n+        set viewmodebutton Commit\n+    }\n+    if {![info exists selectedline]} return\n+    set l [expr $selectedline]\n+    selectline $l 1\n+}\n+\n+proc togglelinenum {} {\n+    global showlinenum selectedline\n+    if { $showlinenum } { set showlinenum false } else { set showlinenum true }\n+    if {![info exists selectedline]} return\n+    set l [expr $selectedline]\n+    selectline $l 1\n+}\n+\n+proc viewfull { path } {\n+    global ctext currentid viewpath\n+    $ctext conf -state normal\n+    $ctext delete 0.0 end\n+\n+    if { $viewpath == \"Comments\" || $path == \"/\" } {\n+        set path \"\"\n+        set viewpath \"\"\n+    }\n+    if { $path != \"\" } {\n+        set viewpath $path\n+    }\n+\n+    if [catch {set stream [open \"|git-ls-tree $currentid $viewpath\" r]}] {\n+        $ctext insert end \"ERROR: viewfull: git-ls-tree $currentid $viewpath\"\n+        return\n+    }\n+    gets $stream line\n+    close $stream\n+    \n+    set kind [lindex $line 1]\n+    set sha  [lindex $line 2]\n+\n+    if { $viewpath == \"\" } {\n+        set kind root\n+        set sha $currentid\n+    }\n+\n+    if { $line == \"\" } {\n+      set kind \"NOT FOUND !!!\"\n+    }\n+    \n+    viewheader $viewpath $kind\n+    \n+    if { $kind == \"blob\"} {\n+      viewblob $sha\n+    } elseif { $kind == \"tree\" || $kind == \"root\"} {\n+      viewtree $sha\n+    }\n+}\n+\n+proc viewheader { path kind } {\n+    global ctext\n+    $ctext insert end \"type: $kind\\n\"\n+    $ctext insert end \"path: \"\n+    \n+    set splitpath [ linsert [ split [ string trim $path \"/\" ] \"/\" ] 0 \"ROOT\" ]\n+    set name [ lindex $splitpath end ]\n+    set splitpath [ lrange $splitpath 0 end-1 ]\n+    set buildpath \"/\"\n+    foreach next $splitpath {\n+        if { $next != \"ROOT\" } { \n+            append buildpath \"$next/\"\n+        }\n+        viewprintlink \"$next\" $buildpath\n+        $ctext insert end \" / \"\n+    }\n+    $ctext insert end \"$name \\n\"\n+    set l [expr {(78 - [string length $name]) / 2}]\n+    set pad [string range \"----------------------------------------\" 1 $l]\n+    $ctext insert end \"$pad $name $pad\\n\" filesep\n+}\n+\n+proc viewprintlink { name path } {\n+    global ctext\n+    set linkbeg [$ctext index \"end - 1c\"]\n+    $ctext insert end \"$name\"\n+    set linkend [$ctext index \"end - 1c\"]\n+    $ctext tag add  linkfile$name \"$linkbeg + 0 c\" \"$linkend + 0 c\"\n+    $ctext tag conf linkfile$name -foreground blue -underline 1\n+    $ctext tag bind linkfile$name <Enter> { %W configure -cursor hand2 }\n+    $ctext tag bind linkfile$name <Leave> { %W configure -cursor $curtextcursor }\n+    $ctext tag bind linkfile$name <1> [ list viewfull \"$path\" ]\n+}\n+\n+\n+proc viewblob {sha} {\n+    global ctext linenum\n+    set linenum 0\n+    if [catch {set stream [open \"|git-cat-file blob $sha\" r]}] {\n+        $ctext insert end \"ERROR: viewblob\"\n+        return\n+    }\n+    fconfigure $stream -blocking 0\n+    fileevent $stream readable [list getviewblobline $stream $sha]\n+}\n+\n+proc getviewblobline {stream sha} {\n+    global ctext linenum showlinenum\n+    set n [gets $stream line]\n+    if {$n < 0} {\n+\tif {![eof $stream]} return\n+\tclose $stream\n+        return\n+    }\n+    incr linenum\n+    set num [format \"%5s\" \"$linenum\"]\n+    if { $showlinenum } { $ctext insert end \"$num \" hunksep }\n+    $ctext insert end \"$line\\n\"\n+}\n+\n+proc viewtree {sha} {\n+    global ctext lstree\n+    set lstree \"\"\n+    $ctext insert end \"\\n\\n\"\n+    if [catch {set stream [open \"|git-ls-tree $sha\" r]}] {\n+        $ctext insert end \"ERROR viewtree\"\n+        return\n+    }\n+    fconfigure $stream -blocking 0\n+    fileevent $stream readable [list getviewtreeline $stream]\n+}\n+\n+proc getviewtreeline {stream} {\n+    global ctext viewpath lstree\n+    set n [gets $stream line]\n+    if {$n < 0} {\n+\tif {![eof $stream]} return\n+\tclose $stream\n+        printviewtreefilter \"tree\"\n+        $ctext insert end \"\\n\"\n+        printviewtreefilter \"blob\"\n+        return\n+    }\n+    lappend lstree $line\n+}\n+    \n+proc printviewtreefilter {filter} {\n+    global ctext lstree viewpath\n+    foreach line $lstree  {\n+        set kind [ lindex $line 1 ]\n+        if { $kind != $filter} continue\n+        set name [ lindex $line 3 ]\n+        $ctext insert end \"    $kind  \"\n+        viewprintlink $name \"$viewpath/$name\"\n+        $ctext insert end \" \\n\"\n+    }\n+}\n+\n proc getblobdiffs {ids} {\n     global diffopts blobdifffd diffids env curdifftag curtagstart\n-    global difffilestart nextupdate diffinhdr treediffs\n-\n+    global difffilestart nextupdate diffinhdr treediffs viewmodebutton\n+    # If the button says COMMIT, we are in TREE mode)\n+    if { $viewmodebutton == \"Commit\" } { \n+      viewfull \"\" \n+      return \n+    }\n     set id [lindex $ids 0]\n     set p [lindex $ids 1]\n     set env(GIT_DIFF_OPTS) $diffopts\n@@ -2951,12 +3120,18 @@ proc nextfile {} {\n }\n \n proc listboxsel {} {\n-    global ctext cflist currentid\n+    global ctext cflist currentid viewmodebutton viewpath\n     if {![info exists currentid]} return\n     set sel [lsort [$cflist curselection]]\n     if {$sel eq {}} return\n     set first [lindex $sel 0]\n-    catch {$ctext yview fmark.$first}\n+    set viewpath [ $cflist get $first ]\n+    # If the button says COMMIT, we are in TREE mode\n+    if {$viewmodebutton == \"Commit\"} {\n+      viewfull [$cflist get $first]\n+    } else {\n+        catch {$ctext yview fmark.$first}\n+    }\n }\n \n proc setcoords {} {\n@@ -3576,6 +3751,8 @@ set stopped 0\n set redisplaying 0\n set stuffsaved 0\n set patchnum 0\n+set viewpath \"\"\n+set showlinenum false\n setcoords\n makewindow\n readrefs\n\n\n"},{"id":"7730","messageId":"20050824223550.GA23693@kruemel","threadId":"1622","inReplyTo":"20050823042432.GA21140@kruemel","subject":"[PATCH] Gitk tree view (correction)","fromName":"Ingo Bormuth","fromEmail":"ibormuth@efil.de","sentAt":"2005-08-24T22:35:50Z","receivedAt":"2005-08-24T22:35:50Z","isPatch":true,"sender":{"key":"ibormuth@efil.de","avatar":null},"body":"\nI'm sorry for sending a non-working patch. Apparently I got lost in /tmp.\n\nSo here is the patch for gitk that allows you to browse the entire tree for\nevery revision.\n\nThe patched gitk script and some screenshots can be found at:\n\n    http://public.efil.de/gitk/\n\nFor my personal use it's rather sufficient.\nIf anybody is interested in using it, I would clean it up.\n\n   - Ingo\n\n\n\n\n\n\n\nAdd tree view.\n\n   This allows you to browse the entire tree for every revision.\n   You may switch back an forward betweem the two modes at any time.\n\n   Keybindings:  v - toggle view mode (tree/commit)\n                 l - toggle line numbers\n\n---\ncommit dbbfcc0cabb8eaaff998dc95957d73867f0e2f35\ntree 53d7597f0f42ca1c3f7f01c7ca60d14541077a89\nparent ccf1ee327f9a7d51704578fa41ba255abfd3a730\nauthor <ingo@kruemel.(none)> Thu, 25 Aug 2005 00:13:22 +0200\ncommitter <ingo@kruemel.(none)> Thu, 25 Aug 2005 00:13:22 +0200\n\n gitk |  192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 187 insertions(+), 5 deletions(-)\n\ndiff --git a/gitk b/gitk\n--- a/gitk\n+++ b/gitk\n@@ -329,12 +329,13 @@ proc makewindow {} {\n     global findtype findtypemenu findloc findstring fstring geometry\n     global entries sha1entry sha1string sha1but\n     global maincursor textcursor curtextcursor\n-    global rowctxmenu gaudydiff mergemax\n+    global rowctxmenu gaudydiff mergemax viewmodebutton\n \n     menu .bar\n     .bar add cascade -label \"File\" -menu .bar.file\n     menu .bar.file\n     .bar.file add command -label \"Reread references\" -command rereadrefs\n+    .bar.file add command -label \"Toggle line numbers\" -command togglelinenum\n     .bar.file add command -label \"Quit\" -command doquit\n     menu .bar.help\n     .bar add cascade -label \"Help\" -menu .bar.help\n@@ -381,6 +382,9 @@ proc makewindow {} {\n     .ctop.top.clist add $canv3\n     bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}\n \n+    set viewmodebutton Tree\n+    button .ctop.top.bar.viewmodebutton -textvariable viewmodebutton -command toggleviewmode\n+    pack .ctop.top.bar.viewmodebutton -side left\n     set sha1entry .ctop.top.bar.sha1\n     set entries $sha1entry\n     set sha1but .ctop.top.bar.sha1label\n@@ -493,9 +497,11 @@ proc makewindow {} {\n     bindkey <Key-space> \"$ctext yview scroll 1 pages\"\n     bindkey p \"selnextline -1\"\n     bindkey n \"selnextline 1\"\n+    bindkey l \"togglelinenum\"\n     bindkey b \"$ctext yview scroll -1 pages\"\n     bindkey d \"$ctext yview scroll 18 units\"\n     bindkey u \"$ctext yview scroll -18 units\"\n+    bindkey v \"toggleviewmode\"\n     bindkey / {findnext 1}\n     bindkey <Key-Return> {findnext 0}\n     bindkey ? findprev\n@@ -2815,10 +2821,178 @@ proc gettreediffline {gdtf ids} {\n     lappend treediff $file\n }\n \n+proc toggleviewmode {} {\n+    global treemode viewmodebutton selectedline cflist viewpath ctext\n+    if { $treemode } {\n+        set viewmodebutton Tree\n+        set treemode false\n+    } else { \n+        set viewmodebutton Commit\n+        set treemode true\n+    }\n+    # redraw\n+    if {![info exists selectedline]} return\n+    set l [expr $selectedline]\n+    selectline $l 1\n+    # select current file \n+    if {! $treemode } {\n+        set commitfiles [ $cflist get 0 end ] \n+        set index [ lsearch $commitfiles $viewpath ]\n+        if { $index > 0 } {\n+            catch { after 500 $ctext yview fmark.$index }\n+        }\n+    }\n+}\n+\n+proc togglelinenum {} {\n+    global showlinenum selectedline\n+    if { $showlinenum } { set showlinenum false } else { set showlinenum true }\n+    if {![info exists selectedline]} return\n+    set l [expr $selectedline]\n+    selectline $l 1\n+}\n+\n+proc viewfull { path } {\n+    global ctext currentid viewpath\n+    $ctext conf -state normal\n+    $ctext delete 0.0 end\n+\n+    if { $path != \"\" } { set viewpath $path }\n+    if { $viewpath == \"Comments\" ||  $viewpath == \"/\" || $viewpath == \"\" } {\n+        set path \"\"\n+        set viewpath \"/\"\n+        set kind root\n+        set sha $currentid\n+    } else {\n+        if [catch {set stream [open \"|git-ls-tree $currentid $viewpath\" r]}] {\n+            $ctext insert end \"ERROR: viewfull: git-ls-tree $currentid $viewpath\"\n+            return\n+        }\n+        gets $stream line\n+        fconfigure $stream -blocking 0\n+        close $stream\n+        if { $line == \"\" } {\n+            set kind \"NOT FOUND !!!\"\n+        } else {\n+            set kind [lindex $line 1]\n+        }\n+        set sha  [lindex $line 2]\n+    }\n+   \n+    viewheader $viewpath $kind\n+    \n+    if { $kind == \"blob\"} {\n+      viewblob $sha\n+    } elseif { $kind == \"tree\" || $kind == \"root\"} {\n+      viewtree $sha\n+    }\n+}\n+\n+proc viewheader { path kind } {\n+    global ctext\n+    $ctext insert end \"type: $kind\\n\"\n+    $ctext insert end \"path: \"\n+    \n+    set splitpath [ linsert [ split [ string trim $path \"/\" ] \"/\" ] 0 \"ROOT\" ]\n+    set name [ lindex $splitpath end ]\n+    set splitpath [ lrange $splitpath 0 end-1 ]\n+    set buildpath \"/\"\n+    foreach next $splitpath {\n+        if { $next != \"ROOT\" } { \n+            append buildpath \"$next/\"\n+        }\n+        viewprintlink \"$next\" $buildpath\n+        $ctext insert end \" / \"\n+    }\n+    $ctext insert end \"$name \\n\"\n+    set l [expr {(78 - [string length $name]) / 2}]\n+    set pad [string range \"----------------------------------------\" 1 $l]\n+    $ctext insert end \"$pad $name $pad\\n\" filesep\n+}\n+\n+proc viewprintlink { name path } {\n+    global ctext\n+    set linkbeg [$ctext index \"end - 1c\"]\n+    $ctext insert end \"$name\"\n+    set linkend [$ctext index \"end - 1c\"]\n+    $ctext tag add  linkfile$name \"$linkbeg + 0 c\" \"$linkend + 0 c\"\n+    $ctext tag conf linkfile$name -foreground blue -underline 1\n+    $ctext tag bind linkfile$name <Enter> { %W configure -cursor hand2 }\n+    $ctext tag bind linkfile$name <Leave> { %W configure -cursor $curtextcursor }\n+    $ctext tag bind linkfile$name <1> [ list viewfull \"$path\" ]\n+}\n+\n+\n+proc viewblob {sha} {\n+    global ctext linenum\n+    set linenum 0\n+    if [catch {set stream [open \"|git-cat-file blob $sha\" r]}] {\n+        $ctext insert end \"ERROR: viewblob\"\n+        return\n+    }\n+    fconfigure $stream -blocking 0\n+    fileevent $stream readable [list getviewblobline $stream $sha]\n+}\n+\n+proc getviewblobline {stream sha} {\n+    global ctext linenum showlinenum\n+    set n [gets $stream line]\n+    if {$n < 0} {\n+\tif {![eof $stream]} return\n+\tclose $stream\n+        return\n+    }\n+    incr linenum\n+    set num [format \"%5s\" \"$linenum\"]\n+    if { $showlinenum } { $ctext insert end \"$num \" hunksep }\n+    $ctext insert end \"$line\\n\"\n+}\n+\n+proc viewtree {sha} {\n+    global ctext lstree\n+    set lstree \"\"\n+    $ctext insert end \"\\n\\n\"\n+    if [catch {set stream [open \"|git-ls-tree $sha\" r]}] {\n+        $ctext insert end \"ERROR viewtree\"\n+        return\n+    }\n+    fconfigure $stream -blocking 0\n+    fileevent $stream readable [list getviewtreeline $stream]\n+}\n+\n+proc getviewtreeline {stream} {\n+    global ctext viewpath lstree\n+    set n [gets $stream line]\n+    if {$n < 0} {\n+\tif {![eof $stream]} return\n+\tclose $stream\n+        printviewtreefilter \"tree\"\n+        $ctext insert end \"\\n\"\n+        printviewtreefilter \"blob\"\n+        return\n+    }\n+    lappend lstree $line\n+}\n+    \n+proc printviewtreefilter {filter} {\n+    global ctext lstree viewpath\n+    foreach line $lstree  {\n+        set kind [ lindex $line 1 ]\n+        if { $kind != $filter} continue\n+        $ctext insert end \"    $kind  \"\n+        set name [ lindex $line 3 ]\n+        viewprintlink $name \"$viewpath/$name\"\n+        $ctext insert end \"\\n\"\n+    }\n+}\n+\n proc getblobdiffs {ids} {\n     global diffopts blobdifffd diffids env curdifftag curtagstart\n-    global difffilestart nextupdate diffinhdr treediffs\n-\n+    global difffilestart nextupdate diffinhdr treediffs treemode\n+    if { $treemode } { \n+      viewfull \"\" \n+      return \n+    }\n     set id [lindex $ids 0]\n     set p [lindex $ids 1]\n     set env(GIT_DIFF_OPTS) $diffopts\n@@ -2951,12 +3125,17 @@ proc nextfile {} {\n }\n \n proc listboxsel {} {\n-    global ctext cflist currentid\n+    global ctext cflist currentid treemode viewpath\n     if {![info exists currentid]} return\n     set sel [lsort [$cflist curselection]]\n     if {$sel eq {}} return\n     set first [lindex $sel 0]\n-    catch {$ctext yview fmark.$first}\n+    set viewpath [ $cflist get $first ]\n+    if { $treemode } {\n+      viewfull [$cflist get $first]\n+    } else {\n+        catch {$ctext yview fmark.$first}\n+    }\n }\n \n proc setcoords {} {\n@@ -3576,6 +3755,9 @@ set stopped 0\n set redisplaying 0\n set stuffsaved 0\n set patchnum 0\n+set treemode false\n+set viewpath \"\"\n+set showlinenum true\n setcoords\n makewindow\n readrefs\n\n\n\n\n-- \n   +--------------------------------------------------------+\n   | Ingo Bormuth,  voicebox & telefax: +49-12125-10226517  |\n   | GnuPG key 86326EC9 at http://ibormuth.efil.de/contact  |\n   +--------------------------------------------------------+\n"}]}