]> asedeno.scripts.mit.edu Git - git.git/blobdiff - git-gui.sh
git-gui: Work around random missing scrollbar in revision list
[git.git] / git-gui.sh
index be506b908c0aba7d54d3230b36599ac1db4e7352..f42e461fd42ad37075d433f3509d6bd415a0b97a 100755 (executable)
@@ -10,7 +10,7 @@
  exec wish "$argv0" -- "$@"
 
 set appvers {@@GITGUI_VERSION@@}
-set copyright {
+set copyright [encoding convertfrom utf-8 {
 Copyright © 2006, 2007 Shawn Pearce, et. al.
 
 This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA}
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA}]
 
 ######################################################################
 ##
@@ -88,13 +88,20 @@ if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} {
 
 package require msgcat
 
-proc mc {fmt args} {
-       set fmt [::msgcat::mc $fmt]
+proc _mc_trim {fmt} {
        set cmk [string first @@ $fmt]
        if {$cmk > 0} {
-               set fmt [string range $fmt 0 [expr {$cmk - 1}]]
+               return [string range $fmt 0 [expr {$cmk - 1}]]
        }
-       return [eval [list format $fmt] $args]
+       return $fmt
+}
+
+proc mc {en_fmt args} {
+       set fmt [_mc_trim [::msgcat::mc $en_fmt]]
+       if {[catch {set msg [eval [list format $fmt] $args]} err]} {
+               set msg [eval [list format [_mc_trim $en_fmt]] $args]
+       }
+       return $msg
 }
 
 proc strcat {args} {
@@ -205,6 +212,7 @@ proc disable_option {option} {
 
 proc is_many_config {name} {
        switch -glob -- $name {
+       gui.recentrepo -
        remote.*.fetch -
        remote.*.push
                {return 1}
@@ -233,51 +241,6 @@ proc get_config {name} {
        }
 }
 
-proc load_config {include_global} {
-       global repo_config global_config default_config
-
-       array unset global_config
-       if {$include_global} {
-               catch {
-                       set fd_rc [git_read config --global --list]
-                       while {[gets $fd_rc line] >= 0} {
-                               if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
-                                       if {[is_many_config $name]} {
-                                               lappend global_config($name) $value
-                                       } else {
-                                               set global_config($name) $value
-                                       }
-                               }
-                       }
-                       close $fd_rc
-               }
-       }
-
-       array unset repo_config
-       catch {
-               set fd_rc [git_read config --list]
-               while {[gets $fd_rc line] >= 0} {
-                       if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
-                               if {[is_many_config $name]} {
-                                       lappend repo_config($name) $value
-                               } else {
-                                       set repo_config($name) $value
-                               }
-                       }
-               }
-               close $fd_rc
-       }
-
-       foreach name [array names default_config] {
-               if {[catch {set v $global_config($name)}]} {
-                       set global_config($name) $default_config($name)
-               }
-               if {[catch {set v $repo_config($name)}]} {
-                       set repo_config($name) $default_config($name)
-               }
-       }
-}
-
 ######################################################################
 ##
 ## handy utils
@@ -343,6 +306,9 @@ proc _which {what} {
                                $env(PATH)] {;}]
                        set _search_exe .exe
                } elseif {[is_Windows]} {
+                       set gitguidir [file dirname [info script]]
+                       regsub -all ";" $gitguidir "\\;" gitguidir
+                       set env(PATH) "$gitguidir;$env(PATH)"
                        set _search_path [split $env(PATH) {;}]
                        set _search_exe .exe
                } else {
@@ -472,6 +438,34 @@ proc git_write {args} {
        return [open [concat $opt $cmdp $args] w]
 }
 
+proc githook_read {hook_name args} {
+       set pchook [gitdir hooks $hook_name]
+       lappend args 2>@1
+
+       # On Cygwin [file executable] might lie so we need to ask
+       # the shell if the hook is executable.  Yes that's annoying.
+       #
+       if {[is_Cygwin]} {
+               upvar #0 _sh interp
+               if {![info exists interp]} {
+                       set interp [_which sh]
+               }
+               if {$interp eq {}} {
+                       error "hook execution requires sh (not in PATH)"
+               }
+
+               set scr {if test -x "$1";then exec "$@";fi}
+               set sh_c [list | $interp -c $scr $interp $pchook]
+               return [_open_stdout_stderr [concat $sh_c $args]]
+       }
+
+       if {[file executable $pchook]} {
+               return [_open_stdout_stderr [concat [list | $pchook] $args]]
+       }
+
+       return {}
+}
+
 proc sq {value} {
        regsub -all ' $value "'\\''" value
        return "'$value'"
@@ -585,8 +579,15 @@ proc apply_config {} {
                set name [lindex $option 0]
                set font [lindex $option 1]
                if {[catch {
+                       set need_weight 1
                        foreach {cn cv} $repo_config(gui.$name) {
-                               font configure $font $cn $cv -weight normal
+                               if {$cn eq {-weight}} {
+                                       set need_weight 0
+                               }
+                               font configure $font $cn $cv
+                       }
+                       if {$need_weight} {
+                               font configure $font -weight normal
                        }
                        } err]} {
                        error_popup [strcat [mc "Invalid font specified in %s:" "gui.$name"] "\n\n$err"]
@@ -786,6 +787,71 @@ if {$idx ne {}} {
 }
 unset -nocomplain idx fd
 
+######################################################################
+##
+## config file parsing
+
+git-version proc _parse_config {arr_name args} {
+       >= 1.5.3 {
+               upvar $arr_name arr
+               array unset arr
+               set buf {}
+               catch {
+                       set fd_rc [eval \
+                               [list git_read config] \
+                               $args \
+                               [list --null --list]]
+                       fconfigure $fd_rc -translation binary
+                       set buf [read $fd_rc]
+                       close $fd_rc
+               }
+               foreach line [split $buf "\0"] {
+                       if {[regexp {^([^\n]+)\n(.*)$} $line line name value]} {
+                               if {[is_many_config $name]} {
+                                       lappend arr($name) $value
+                               } else {
+                                       set arr($name) $value
+                               }
+                       }
+               }
+       }
+       default {
+               upvar $arr_name arr
+               array unset arr
+               catch {
+                       set fd_rc [eval [list git_read config --list] $args]
+                       while {[gets $fd_rc line] >= 0} {
+                               if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
+                                       if {[is_many_config $name]} {
+                                               lappend arr($name) $value
+                                       } else {
+                                               set arr($name) $value
+                                       }
+                               }
+                       }
+                       close $fd_rc
+               }
+       }
+}
+
+proc load_config {include_global} {
+       global repo_config global_config default_config
+
+       if {$include_global} {
+               _parse_config global_config --global
+       }
+       _parse_config repo_config
+
+       foreach name [array names default_config] {
+               if {[catch {set v $global_config($name)}]} {
+                       set global_config($name) $default_config($name)
+               }
+               if {[catch {set v $repo_config($name)}]} {
+                       set repo_config($name) $default_config($name)
+               }
+       }
+}
+
 ######################################################################
 ##
 ## feature option selection
@@ -1655,8 +1721,8 @@ proc do_quit {} {
                #
                set cfg_geometry [list]
                lappend cfg_geometry [wm geometry .]
-               lappend cfg_geometry [lindex [.vpane sash coord 0] 1]
-               lappend cfg_geometry [lindex [.vpane.files sash coord 0] 0]
+               lappend cfg_geometry [lindex [.vpane sash coord 0] 0]
+               lappend cfg_geometry [lindex [.vpane.files sash coord 0] 1]
                if {[catch {set rc_geometry $repo_config(gui.geometry)}]} {
                        set rc_geometry {}
                }
@@ -1948,7 +2014,8 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
        .mbar.commit add command -label [mc "Stage To Commit"] \
-               -command do_add_selection
+               -command do_add_selection \
+               -accelerator $M1T-T
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
@@ -2205,15 +2272,15 @@ pack .branch -side top -fill x
 
 # -- Main Window Layout
 #
-panedwindow .vpane -orient vertical
-panedwindow .vpane.files -orient horizontal
+panedwindow .vpane -orient horizontal
+panedwindow .vpane.files -orient vertical
 .vpane add .vpane.files -sticky nsew -height 100 -width 200
 pack .vpane -anchor n -side top -fill both -expand 1
 
 # -- Index File List
 #
 frame .vpane.files.index -height 100 -width 200
-label .vpane.files.index.title -text [mc "Staged Changes (Will Be Committed)"] \
+label .vpane.files.index.title -text [mc "Staged Changes (Will Commit)"] \
        -background lightgreen
 text $ui_index -background white -borderwidth 0 \
        -width 20 -height 10 \
@@ -2228,12 +2295,11 @@ pack .vpane.files.index.title -side top -fill x
 pack .vpane.files.index.sx -side bottom -fill x
 pack .vpane.files.index.sy -side right -fill y
 pack $ui_index -side left -fill both -expand 1
-.vpane.files add .vpane.files.index -sticky nsew
 
 # -- Working Directory File List
 #
 frame .vpane.files.workdir -height 100 -width 200
-label .vpane.files.workdir.title -text [mc "Unstaged Changes (Will Not Be Committed)"] \
+label .vpane.files.workdir.title -text [mc "Unstaged Changes"] \
        -background lightsalmon
 text $ui_workdir -background white -borderwidth 0 \
        -width 20 -height 10 \
@@ -2248,7 +2314,9 @@ pack .vpane.files.workdir.title -side top -fill x
 pack .vpane.files.workdir.sx -side bottom -fill x
 pack .vpane.files.workdir.sy -side right -fill y
 pack $ui_workdir -side left -fill both -expand 1
+
 .vpane.files add .vpane.files.workdir -sticky nsew
+.vpane.files add .vpane.files.index -sticky nsew
 
 foreach i [list $ui_index $ui_workdir] {
        rmsel_tag $i
@@ -2261,8 +2329,8 @@ unset i
 frame .vpane.lower -height 300 -width 400
 frame .vpane.lower.commarea
 frame .vpane.lower.diff -relief sunken -borderwidth 1
-pack .vpane.lower.commarea -side top -fill x
-pack .vpane.lower.diff -side bottom -fill both -expand 1
+pack .vpane.lower.diff -fill both -expand 1
+pack .vpane.lower.commarea -side bottom -fill x
 .vpane add .vpane.lower -sticky nsew
 
 # -- Commit Area Buttons
@@ -2501,6 +2569,27 @@ $ui_diff tag raise sel
 #
 set ctxm .vpane.lower.diff.body.ctxm
 menu $ctxm -tearoff 0
+$ctxm add command \
+       -label [mc "Apply/Reverse Hunk"] \
+       -command {apply_hunk $cursorX $cursorY}
+set ui_diff_applyhunk [$ctxm index last]
+lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state]
+$ctxm add separator
+$ctxm add command \
+       -label [mc "Show Less Context"] \
+       -command {if {$repo_config(gui.diffcontext) >= 1} {
+               incr repo_config(gui.diffcontext) -1
+               reshow_diff
+       }}
+lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+$ctxm add command \
+       -label [mc "Show More Context"] \
+       -command {if {$repo_config(gui.diffcontext) < 99} {
+               incr repo_config(gui.diffcontext)
+               reshow_diff
+       }}
+lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+$ctxm add separator
 $ctxm add command \
        -label [mc Refresh] \
        -command reshow_diff
@@ -2522,12 +2611,6 @@ $ctxm add command \
        }
 lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
 $ctxm add separator
-$ctxm add command \
-       -label [mc "Apply/Reverse Hunk"] \
-       -command {apply_hunk $cursorX $cursorY}
-set ui_diff_applyhunk [$ctxm index last]
-lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state]
-$ctxm add separator
 $ctxm add command \
        -label [mc "Decrease Font Size"] \
        -command {incr_font_size font_diff -1}
@@ -2537,21 +2620,6 @@ $ctxm add command \
        -command {incr_font_size font_diff 1}
 lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
 $ctxm add separator
-$ctxm add command \
-       -label [mc "Show Less Context"] \
-       -command {if {$repo_config(gui.diffcontext) >= 1} {
-               incr repo_config(gui.diffcontext) -1
-               reshow_diff
-       }}
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add command \
-       -label [mc "Show More Context"] \
-       -command {if {$repo_config(gui.diffcontext) < 99} {
-               incr repo_config(gui.diffcontext)
-               reshow_diff
-       }}
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add separator
 $ctxm add command -label [mc "Options..."] \
        -command do_options
 proc popup_diff_menu {ctxm x y X Y} {
@@ -2588,17 +2656,19 @@ catch {
 set gm $repo_config(gui.geometry)
 wm geometry . [lindex $gm 0]
 .vpane sash place 0 \
-       [lindex [.vpane sash coord 0] 0] \
-       [lindex $gm 1]
+       [lindex $gm 1] \
+       [lindex [.vpane sash coord 0] 1]
 .vpane.files sash place 0 \
-       [lindex $gm 2] \
-       [lindex [.vpane.files sash coord 0] 1]
+       [lindex [.vpane.files sash coord 0] 0] \
+       [lindex $gm 2]
 unset gm
 }
 
 # -- Key Bindings
 #
 bind $ui_comm <$M1B-Key-Return> {do_commit;break}
+bind $ui_comm <$M1B-Key-t> {do_add_selection;break}
+bind $ui_comm <$M1B-Key-T> {do_add_selection;break}
 bind $ui_comm <$M1B-Key-i> {do_add_all;break}
 bind $ui_comm <$M1B-Key-I> {do_add_all;break}
 bind $ui_comm <$M1B-Key-x> {tk_textCut %W;break}
@@ -2648,6 +2718,8 @@ bind .   <$M1B-Key-r> do_rescan
 bind .   <$M1B-Key-R> do_rescan
 bind .   <$M1B-Key-s> do_signoff
 bind .   <$M1B-Key-S> do_signoff
+bind .   <$M1B-Key-t> do_add_selection
+bind .   <$M1B-Key-T> do_add_selection
 bind .   <$M1B-Key-i> do_add_all
 bind .   <$M1B-Key-I> do_add_all
 bind .   <$M1B-Key-Return> do_commit