From 24f7c64b21bb26aab5b8525c0bac8452e7a7a4c8 Mon Sep 17 00:00:00 2001 From: Steffen Prohaska Date: Mon, 8 Oct 2007 08:25:47 +0200 Subject: [PATCH] git-gui: offer a list of recent repositories on startup If git-gui is started outside a work tree the repository chooser will offer a list of recently opened repositories. Clicking on any list entry directly opens the repository. The list of recently opened repositories is stored in the config as the multi-valued option gui.recentrepo. If the list grows beyond 10 entries it will be truncated by removing one of the older entries. Only repositories that are opened through the repository chooser will get added to the recent list. Repositories opened from the shell will not yet be added to the recent list, as users are likely to have a way to easily return to the same directory via their shell. [sp: This is actually a combined work from both Steffen and myself. Most of the ideas are Steffen's, as is the basic outline of the code, but any outstanding bugs are entirely my fault.] Signed-off-by: Steffen Prohaska Signed-off-by: Shawn O. Pearce --- git-gui.sh | 1 + lib/choose_repository.tcl | 82 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/git-gui.sh b/git-gui.sh index a6e2d57a2..dd320fb07 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -205,6 +205,7 @@ proc disable_option {option} { proc is_many_config {name} { switch -glob -- $name { + gui.recentrepo - remote.*.fetch - remote.*.push {return 1} diff --git a/lib/choose_repository.tcl b/lib/choose_repository.tcl index 5d5bc81ad..8dc850654 100644 --- a/lib/choose_repository.tcl +++ b/lib/choose_repository.tcl @@ -9,6 +9,7 @@ field w_body ; # Widget holding the center content field w_next ; # Next button field o_cons ; # Console object (if active) field w_types ; # List of type buttons in clone +field w_recentlist ; # Listbox containing recent repositories field action new ; # What action are we going to perform? field done 0 ; # Finished picking the repository? @@ -17,6 +18,7 @@ field origin_url {} ; # Where we are cloning from field origin_name origin ; # What we shall call 'origin' field clone_type hardlink ; # Type of clone to construct field readtree_err ; # Error output from read-tree (if any) +field sorted_recent ; # recent repositories (sorted) constructor pick {} { global M1T M1B @@ -82,6 +84,40 @@ constructor pick {} { pack $w_body.new -anchor w -fill x pack $w_body.clone -anchor w -fill x pack $w_body.open -anchor w -fill x + + set sorted_recent [_get_recentrepos] + if {[llength $sorted_recent] > 0} { + label $w_body.space + label $w_body.recentlabel \ + -anchor w \ + -text [mc "Open Recent Repository:"] + set w_recentlist $w_body.recentlist + text $w_recentlist \ + -cursor $::cursor_ptr \ + -relief flat \ + -background [$w_body.recentlabel cget -background] \ + -wrap none \ + -width 50 \ + -height 10 + $w_recentlist tag conf link \ + -foreground blue \ + -underline 1 + set home "[file normalize $::env(HOME)][file separator]" + set hlen [string length $home] + foreach p $sorted_recent { + if {[string equal -length $hlen $home $p]} { + set p "~[file separator][string range $p $hlen end]" + } + regsub -all "\n" $p "\\n" p + $w_recentlist insert end $p link + $w_recentlist insert end "\n" + } + $w_recentlist conf -state disabled + $w_recentlist tag bind link <1> [cb _open_recent %x,%y] + pack $w_body.space -anchor w -fill x + pack $w_body.recentlabel -anchor w -fill x + pack $w_recentlist -anchor w -fill x + } pack $w_body -fill x -padx 10 -pady 10 frame $w.buttons @@ -134,6 +170,50 @@ method _invoke_next {} { } } +proc _get_recentrepos {} { + set recent [list] + foreach p [get_config gui.recentrepo] { + if {[_is_git [file join $p .git]]} { + lappend recent $p + } + } + return [lsort $recent] +} + +proc _unset_recentrepo {p} { + regsub -all -- {([()\[\]{}\.^$+*?\\])} $p {\\\1} p + git config --global --unset gui.recentrepo "^$p\$" +} + +proc _append_recentrepos {path} { + set path [file normalize $path] + set recent [get_config gui.recentrepo] + + if {[lindex $recent end] eq $path} { + return + } + + set i [lsearch $recent $path] + if {$i >= 0} { + _unset_recentrepo $path + set recent [lreplace $recent $i $i] + } + + lappend recent $path + git config --global --add gui.recentrepo $path + + while {[llength $recent] > 10} { + _unset_recentrepo [lindex $recent 0] + set recent [lrange $recent 1 end] + } +} + +method _open_recent {xy} { + set id [lindex [split [$w_recentlist index @$xy] .] 0] + set local_path [lindex $sorted_recent [expr {$id - 1}]] + _do_open2 $this +} + method _next {} { destroy $w_body _do_$action $this @@ -174,6 +254,7 @@ method _git_init {} { return 0 } + _append_recentrepos [pwd] set ::_gitdir .git set ::_prefix {} return 1 @@ -856,6 +937,7 @@ method _do_open2 {} { return } + _append_recentrepos [pwd] set ::_gitdir .git set ::_prefix {} set done 1 -- 2.30.2