diff options
Diffstat (limited to 'third_party/git/git-gui/git-gui.sh')
-rwxr-xr-x | third_party/git/git-gui/git-gui.sh | 344 |
1 files changed, 240 insertions, 104 deletions
diff --git a/third_party/git/git-gui/git-gui.sh b/third_party/git/git-gui/git-gui.sh index 6de74ce639ce..867b8cea4618 100755 --- a/third_party/git/git-gui/git-gui.sh +++ b/third_party/git/git-gui/git-gui.sh @@ -30,8 +30,8 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.}] ## ## Tcl/Tk sanity check -if {[catch {package require Tcl 8.4} err] - || [catch {package require Tk 8.4} err] +if {[catch {package require Tcl 8.5} err] + || [catch {package require Tk 8.5} err] } { catch {wm withdraw .} tk_messageBox \ @@ -684,6 +684,7 @@ proc load_current_branch {} { global current_branch is_detached set fd [open [gitdir HEAD] r] + fconfigure $fd -translation binary -encoding utf-8 if {[gets $fd ref] < 1} { set ref {} } @@ -719,7 +720,9 @@ proc rmsel_tag {text} { -background [$text cget -background] \ -foreground [$text cget -foreground] \ -borderwidth 0 - $text tag conf in_sel -background lightgray + $text tag conf in_sel\ + -background $color::select_bg \ + -foreground $color::select_fg bind $text <Motion> break return $text } @@ -862,6 +865,7 @@ proc apply_config {} { set NS ttk bind [winfo class .] <<ThemeChanged>> [list InitTheme] pave_toplevel . + color::sync_with_theme } } } @@ -946,15 +950,15 @@ if {![regsub {^git version } $_git_version {} _git_version]} { } proc get_trimmed_version {s} { - set r {} - foreach x [split $s -._] { - if {[string is integer -strict $x]} { - lappend r $x - } else { - break - } - } - return [join $r .] + set r {} + foreach x [split $s -._] { + if {[string is integer -strict $x]} { + lappend r $x + } else { + break + } + } + return [join $r .] } set _real_git_version $_git_version set _git_version [get_trimmed_version $_git_version] @@ -966,7 +970,7 @@ if {![regexp {^[1-9]+(\.[0-9]+)+$} $_git_version]} { -type yesno \ -default no \ -title "[appname]: warning" \ - -message [mc "Git version cannot be determined. + -message [mc "Git version cannot be determined. %s claims it is version '%s'. @@ -1340,6 +1344,7 @@ set HEAD {} set PARENT {} set MERGE_HEAD [list] set commit_type {} +set commit_type_is_amend 0 set empty_tree {} set current_branch {} set is_detached 0 @@ -1347,8 +1352,9 @@ set current_diff_path {} set is_3way_diff 0 set is_submodule_diff 0 set is_conflict_diff 0 -set selected_commit_type new set diff_empty_count 0 +set last_revert {} +set last_revert_enc {} set nullid "0000000000000000000000000000000000000000" set nullid2 "0000000000000000000000000000000000000001" @@ -1434,7 +1440,7 @@ proc PARENT {} { } proc force_amend {} { - global selected_commit_type + global commit_type_is_amend global HEAD PARENT MERGE_HEAD commit_type repository_state newType newHEAD newMERGE_HEAD @@ -1443,7 +1449,7 @@ proc force_amend {} { set MERGE_HEAD $newMERGE_HEAD set commit_type $newType - set selected_commit_type amend + set commit_type_is_amend 1 do_select_commit_type } @@ -1650,7 +1656,7 @@ proc prepare_commit_msg_hook_wait {fd_ph} { set pch_error {} catch {file delete [gitdir PREPARE_COMMIT_MSG]} return - } + } fconfigure $fd_ph -blocking 0 catch {file delete [gitdir PREPARE_COMMIT_MSG]} } @@ -1795,10 +1801,10 @@ proc ui_status {msg} { } } -proc ui_ready {{test {}}} { +proc ui_ready {} { global main_status if {[info exists main_status]} { - $main_status show [mc "Ready."] $test + $main_status show [mc "Ready."] } } @@ -1998,72 +2004,72 @@ set filemask { #define mask_width 14 #define mask_height 15 static unsigned char mask_bits[] = { - 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, - 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, - 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f}; + 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, + 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, + 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f}; } image create bitmap file_plain -background white -foreground black -data { #define plain_width 14 #define plain_height 15 static unsigned char plain_bits[] = { - 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10, - 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, - 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f}; + 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10, + 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, + 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask image create bitmap file_mod -background white -foreground blue -data { #define mod_width 14 #define mod_height 15 static unsigned char mod_bits[] = { - 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10, - 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, - 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f}; + 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10, + 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, + 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask image create bitmap file_fulltick -background white -foreground "#007000" -data { #define file_fulltick_width 14 #define file_fulltick_height 15 static unsigned char file_fulltick_bits[] = { - 0xfe, 0x01, 0x02, 0x1a, 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x16, 0x02, 0x16, - 0x02, 0x13, 0x00, 0x13, 0x86, 0x11, 0x8c, 0x11, 0xd8, 0x10, 0xf2, 0x10, - 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f}; + 0xfe, 0x01, 0x02, 0x1a, 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x16, 0x02, 0x16, + 0x02, 0x13, 0x00, 0x13, 0x86, 0x11, 0x8c, 0x11, 0xd8, 0x10, 0xf2, 0x10, + 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask image create bitmap file_question -background white -foreground black -data { #define file_question_width 14 #define file_question_height 15 static unsigned char file_question_bits[] = { - 0xfe, 0x01, 0x02, 0x02, 0xe2, 0x04, 0xf2, 0x09, 0x1a, 0x1b, 0x0a, 0x13, - 0x82, 0x11, 0xc2, 0x10, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, 0x62, 0x10, - 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f}; + 0xfe, 0x01, 0x02, 0x02, 0xe2, 0x04, 0xf2, 0x09, 0x1a, 0x1b, 0x0a, 0x13, + 0x82, 0x11, 0xc2, 0x10, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, 0x62, 0x10, + 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask image create bitmap file_removed -background white -foreground red -data { #define file_removed_width 14 #define file_removed_height 15 static unsigned char file_removed_bits[] = { - 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10, - 0x1a, 0x16, 0x32, 0x13, 0xe2, 0x11, 0xc2, 0x10, 0xe2, 0x11, 0x32, 0x13, - 0x1a, 0x16, 0x02, 0x10, 0xfe, 0x1f}; + 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10, + 0x1a, 0x16, 0x32, 0x13, 0xe2, 0x11, 0xc2, 0x10, 0xe2, 0x11, 0x32, 0x13, + 0x1a, 0x16, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask image create bitmap file_merge -background white -foreground blue -data { #define file_merge_width 14 #define file_merge_height 15 static unsigned char file_merge_bits[] = { - 0xfe, 0x01, 0x02, 0x03, 0x62, 0x05, 0x62, 0x09, 0x62, 0x1f, 0x62, 0x10, - 0xfa, 0x11, 0xf2, 0x10, 0x62, 0x10, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, - 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f}; + 0xfe, 0x01, 0x02, 0x03, 0x62, 0x05, 0x62, 0x09, 0x62, 0x1f, 0x62, 0x10, + 0xfa, 0x11, 0xf2, 0x10, 0x62, 0x10, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, + 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask image create bitmap file_statechange -background white -foreground green -data { #define file_statechange_width 14 #define file_statechange_height 15 static unsigned char file_statechange_bits[] = { - 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x62, 0x10, - 0x62, 0x10, 0xba, 0x11, 0xba, 0x11, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, - 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f}; + 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x62, 0x10, + 0x62, 0x10, 0xba, 0x11, 0xba, 0x11, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, + 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask set ui_index .vpane.files.index.list @@ -2148,8 +2154,6 @@ proc incr_font_size {font {amt 1}} { ## ## ui commands -set starting_gitk_msg [mc "Starting gitk... please wait..."] - proc do_gitk {revs {is_submodule false}} { global current_diff_path file_states current_diff_side ui_index global _gitdir _gitworktree @@ -2204,9 +2208,12 @@ proc do_gitk {revs {is_submodule false}} { set env(GIT_WORK_TREE) $_gitworktree cd $pwd - ui_status $::starting_gitk_msg - after 10000 { - ui_ready $starting_gitk_msg + if {[info exists main_status]} { + set status_operation [$::main_status \ + start \ + [mc "Starting %s... please wait..." "gitk"]] + + after 3500 [list $status_operation stop] } } } @@ -2238,16 +2245,16 @@ proc do_git_gui {} { set env(GIT_WORK_TREE) $_gitworktree cd $pwd - ui_status $::starting_gitk_msg - after 10000 { - ui_ready $starting_gitk_msg - } + set status_operation [$::main_status \ + start \ + [mc "Starting %s... please wait..." "git-gui"]] + + after 3500 [list $status_operation stop] } } -proc do_explore {} { - global _gitworktree - set explorer {} +# Get the system-specific explorer app/command. +proc get_explorer {} { if {[is_Cygwin] || [is_Windows]} { set explorer "explorer.exe" } elseif {[is_MacOSX]} { @@ -2256,9 +2263,23 @@ proc do_explore {} { # freedesktop.org-conforming system is our best shot set explorer "xdg-open" } + return $explorer +} + +proc do_explore {} { + global _gitworktree + set explorer [get_explorer] eval exec $explorer [list [file nativename $_gitworktree]] & } +# Open file relative to the working tree by the default associated app. +proc do_file_open {file} { + global _gitworktree + set explorer [get_explorer] + set full_file_path [file join $_gitworktree $file] + exec $explorer [file nativename $full_file_path] & +} + set is_quitting 0 set ret_code 1 @@ -2494,7 +2515,7 @@ proc force_first_diff {after} { proc toggle_or_diff {mode w args} { global file_states file_lists current_diff_path ui_index ui_workdir - global last_clicked selected_paths + global last_clicked selected_paths file_lists_last_clicked if {$mode eq "click"} { foreach {x y} $args break @@ -2551,6 +2572,8 @@ proc toggle_or_diff {mode w args} { $ui_index tag remove in_sel 0.0 end $ui_workdir tag remove in_sel 0.0 end + set file_lists_last_clicked($w) $path + # Determine the state of the file if {[info exists file_states($path)]} { set state [lindex $file_states($path) 0] @@ -2580,12 +2603,12 @@ proc toggle_or_diff {mode w args} { update_indexinfo \ "Unstaging [short_path $path] from commit" \ [list $path] \ - [concat $after [list ui_ready]] + [concat $after {ui_ready;}] } elseif {$w eq $ui_workdir} { update_index \ "Adding [short_path $path]" \ [list $path] \ - [concat $after [list ui_ready]] + [concat $after {ui_ready;}] } } else { set selected_paths($path) 1 @@ -2664,6 +2687,32 @@ proc show_less_context {} { } } +proc focus_widget {widget} { + global file_lists last_clicked selected_paths + global file_lists_last_clicked + + if {[llength $file_lists($widget)] > 0} { + set path $file_lists_last_clicked($widget) + set index [lsearch -sorted -exact $file_lists($widget) $path] + if {$index < 0} { + set index 0 + set path [lindex $file_lists($widget) $index] + } + + focus $widget + set last_clicked [list $widget [expr $index + 1]] + array unset selected_paths + set selected_paths($path) 1 + show_diff $path $widget + } +} + +proc toggle_commit_type {} { + global commit_type_is_amend + set commit_type_is_amend [expr !$commit_type_is_amend] + do_select_commit_type +} + ###################################################################### ## ## ui construction @@ -2706,10 +2755,18 @@ if {![is_bare]} { } if {[is_Windows]} { + # Use /git-bash.exe if available + set normalized [file normalize $::argv0] + regsub "/mingw../libexec/git-core/git-gui$" \ + $normalized "/git-bash.exe" cmdLine + if {$cmdLine != $normalized && [file exists $cmdLine]} { + set cmdLine [list "Git Bash" $cmdLine &] + } else { + set cmdLine [list "Git Bash" bash --login -l &] + } .mbar.repository add command \ -label [mc "Git Bash"] \ - -command {eval exec [auto_execok start] \ - [list "Git Bash" bash --login -l &]} + -command {eval exec [auto_execok start] $cmdLine} } if {[is_Windows] || ![is_bare]} { @@ -2852,19 +2909,11 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} { menu .mbar.commit if {![is_enabled nocommit]} { - .mbar.commit add radiobutton \ - -label [mc "New Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value new - lappend disable_on_lock \ - [list .mbar.commit entryconf [.mbar.commit index last] -state] - - .mbar.commit add radiobutton \ + .mbar.commit add checkbutton \ -label [mc "Amend Last Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value amend + -accelerator $M1T-E \ + -variable commit_type_is_amend \ + -command do_select_commit_type lappend disable_on_lock \ [list .mbar.commit entryconf [.mbar.commit index last] -state] @@ -3030,8 +3079,23 @@ unset doc_path doc_url wm protocol . WM_DELETE_WINDOW do_quit bind all <$M1B-Key-q> do_quit bind all <$M1B-Key-Q> do_quit -bind all <$M1B-Key-w> {destroy [winfo toplevel %W]} -bind all <$M1B-Key-W> {destroy [winfo toplevel %W]} + +set m1b_w_script { + set toplvl_win [winfo toplevel %W] + + # If we are destroying the main window, we should call do_quit to take + # care of cleanup before exiting the program. + if {$toplvl_win eq "."} { + do_quit + } else { + destroy $toplvl_win + } +} + +bind all <$M1B-Key-w> $m1b_w_script +bind all <$M1B-Key-W> $m1b_w_script + +unset m1b_w_script set subcommand_args {} proc usage {} { @@ -3211,7 +3275,7 @@ pack .vpane -anchor n -side top -fill both -expand 1 textframe .vpane.files.workdir -height 100 -width 200 tlabel .vpane.files.workdir.title -text [mc "Unstaged Changes"] \ -background lightsalmon -foreground black -ttext $ui_workdir -background white -foreground black \ +ttext $ui_workdir \ -borderwidth 0 \ -width 20 -height 10 \ -wrap none \ @@ -3233,7 +3297,7 @@ textframe .vpane.files.index -height 100 -width 200 tlabel .vpane.files.index.title \ -text [mc "Staged Changes (Will Commit)"] \ -background lightgreen -foreground black -ttext $ui_index -background white -foreground black \ +ttext $ui_index \ -borderwidth 0 \ -width 20 -height 10 \ -wrap none \ @@ -3260,7 +3324,9 @@ if {!$use_ttk} { foreach i [list $ui_index $ui_workdir] { rmsel_tag $i - $i tag conf in_diff -background [$i tag cget in_sel -background] + $i tag conf in_diff \ + -background $color::select_bg \ + -foreground $color::select_fg } unset i @@ -3337,18 +3403,10 @@ set ui_comm .vpane.lower.commarea.buffer.frame.t set ui_coml .vpane.lower.commarea.buffer.header.l if {![is_enabled nocommit]} { - ${NS}::radiobutton .vpane.lower.commarea.buffer.header.new \ - -text [mc "New Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value new - lappend disable_on_lock \ - [list .vpane.lower.commarea.buffer.header.new conf -state] - ${NS}::radiobutton .vpane.lower.commarea.buffer.header.amend \ + ${NS}::checkbutton .vpane.lower.commarea.buffer.header.amend \ -text [mc "Amend Last Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value amend + -variable commit_type_is_amend \ + -command do_select_commit_type lappend disable_on_lock \ [list .vpane.lower.commarea.buffer.header.amend conf -state] } @@ -3373,11 +3431,10 @@ pack $ui_coml -side left -fill x if {![is_enabled nocommit]} { pack .vpane.lower.commarea.buffer.header.amend -side right - pack .vpane.lower.commarea.buffer.header.new -side right } textframe .vpane.lower.commarea.buffer.frame -ttext $ui_comm -background white -foreground black \ +ttext $ui_comm \ -borderwidth 1 \ -undo true \ -maxundo 20 \ @@ -3387,10 +3444,16 @@ ttext $ui_comm -background white -foreground black \ -relief sunken \ -width $repo_config(gui.commitmsgwidth) -height 9 -wrap none \ -font font_diff \ + -xscrollcommand {.vpane.lower.commarea.buffer.frame.sbx set} \ -yscrollcommand {.vpane.lower.commarea.buffer.frame.sby set} +${NS}::scrollbar .vpane.lower.commarea.buffer.frame.sbx \ + -orient horizontal \ + -command [list $ui_comm xview] ${NS}::scrollbar .vpane.lower.commarea.buffer.frame.sby \ + -orient vertical \ -command [list $ui_comm yview] +pack .vpane.lower.commarea.buffer.frame.sbx -side bottom -fill x pack .vpane.lower.commarea.buffer.frame.sby -side right -fill y pack $ui_comm -side left -fill y pack .vpane.lower.commarea.buffer.header -side top -fill x @@ -3470,9 +3533,11 @@ tlabel .vpane.lower.diff.header.file \ -justify left tlabel .vpane.lower.diff.header.path \ -background gold \ - -foreground black \ + -foreground blue \ -anchor w \ - -justify left + -justify left \ + -font [eval font create [font configure font_ui] -underline 1] \ + -cursor hand2 pack .vpane.lower.diff.header.status -side left pack .vpane.lower.diff.header.file -side left pack .vpane.lower.diff.header.path -fill x @@ -3487,14 +3552,18 @@ $ctxm add command \ -type STRING \ -- $current_diff_path } +$ctxm add command \ + -label [mc Open] \ + -command {do_file_open $current_diff_path} lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] bind_button3 .vpane.lower.diff.header.path "tk_popup $ctxm %X %Y" +bind .vpane.lower.diff.header.path <Button-1> {do_file_open $current_diff_path} # -- Diff Body # textframe .vpane.lower.diff.body set ui_diff .vpane.lower.diff.body.t -ttext $ui_diff -background white -foreground black \ +ttext $ui_diff \ -borderwidth 0 \ -width 80 -height 5 -wrap none \ -font font_diff \ @@ -3547,6 +3616,9 @@ $ui_diff tag conf d_s- \ $ui_diff tag conf d< \ -foreground orange \ -font font_diffbold +$ui_diff tag conf d| \ + -foreground orange \ + -font font_diffbold $ui_diff tag conf d= \ -foreground orange \ -font font_diffbold @@ -3606,16 +3678,32 @@ set ctxm .vpane.lower.diff.body.ctxm menu $ctxm -tearoff 0 $ctxm add command \ -label [mc "Apply/Reverse Hunk"] \ - -command {apply_hunk $cursorX $cursorY} + -command {apply_or_revert_hunk $cursorX $cursorY 0} set ui_diff_applyhunk [$ctxm index last] lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state] $ctxm add command \ -label [mc "Apply/Reverse Line"] \ - -command {apply_range_or_line $cursorX $cursorY; do_rescan} + -command {apply_or_revert_range_or_line $cursorX $cursorY 0; do_rescan} set ui_diff_applyline [$ctxm index last] lappend diff_actions [list $ctxm entryconf $ui_diff_applyline -state] $ctxm add separator $ctxm add command \ + -label [mc "Revert Hunk"] \ + -command {apply_or_revert_hunk $cursorX $cursorY 1} +set ui_diff_reverthunk [$ctxm index last] +lappend diff_actions [list $ctxm entryconf $ui_diff_reverthunk -state] +$ctxm add command \ + -label [mc "Revert Line"] \ + -command {apply_or_revert_range_or_line $cursorX $cursorY 1; do_rescan} +set ui_diff_revertline [$ctxm index last] +lappend diff_actions [list $ctxm entryconf $ui_diff_revertline -state] +$ctxm add command \ + -label [mc "Undo Last Revert"] \ + -command {undo_last_revert; do_rescan} +set ui_diff_undorevert [$ctxm index last] +lappend diff_actions [list $ctxm entryconf $ui_diff_undorevert -state] +$ctxm add separator +$ctxm add command \ -label [mc "Show Less Context"] \ -command show_less_context lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] @@ -3693,7 +3781,7 @@ proc has_textconv {path} { } proc popup_diff_menu {ctxm ctxmmg ctxmsm x y X Y} { - global current_diff_path file_states + global current_diff_path file_states last_revert set ::cursorX $x set ::cursorY $y if {[info exists file_states($current_diff_path)]} { @@ -3707,19 +3795,28 @@ proc popup_diff_menu {ctxm ctxmmg ctxmsm x y X Y} { tk_popup $ctxmsm $X $Y } else { set has_range [expr {[$::ui_diff tag nextrange sel 0.0] != {}}] + set u [mc "Undo Last Revert"] if {$::ui_index eq $::current_diff_side} { set l [mc "Unstage Hunk From Commit"] + set h [mc "Revert Hunk"] + if {$has_range} { set t [mc "Unstage Lines From Commit"] + set r [mc "Revert Lines"] } else { set t [mc "Unstage Line From Commit"] + set r [mc "Revert Line"] } } else { set l [mc "Stage Hunk For Commit"] + set h [mc "Revert Hunk"] + if {$has_range} { set t [mc "Stage Lines For Commit"] + set r [mc "Revert Lines"] } else { set t [mc "Stage Line For Commit"] + set r [mc "Revert Line"] } } if {$::is_3way_diff @@ -3730,11 +3827,35 @@ proc popup_diff_menu {ctxm ctxmmg ctxmsm x y X Y} { || [string match {T?} $state] || [has_textconv $current_diff_path]} { set s disabled + set revert_state disabled } else { set s normal + + # Only allow reverting changes in the working tree. If + # the user wants to revert changes in the index, they + # need to unstage those first. + if {$::ui_workdir eq $::current_diff_side} { + set revert_state normal + } else { + set revert_state disabled + } } + + if {$last_revert eq {}} { + set undo_state disabled + } else { + set undo_state normal + } + $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l $ctxm entryconf $::ui_diff_applyline -state $s -label $t + $ctxm entryconf $::ui_diff_revertline -state $revert_state \ + -label $r + $ctxm entryconf $::ui_diff_reverthunk -state $revert_state \ + -label $h + $ctxm entryconf $::ui_diff_undorevert -state $undo_state \ + -label $u + tk_popup $ctxm $X $Y } } @@ -3762,18 +3883,18 @@ proc on_application_mapped {} { set gm $repo_config(gui.geometry) if {$use_ttk} { bind .vpane <Map> \ - [list on_ttk_pane_mapped %W 0 [lindex $gm 1]] + [list on_ttk_pane_mapped %W 0 [lindex $gm 1]] bind .vpane.files <Map> \ - [list on_ttk_pane_mapped %W 0 [lindex $gm 2]] + [list on_ttk_pane_mapped %W 0 [lindex $gm 2]] } else { bind .vpane <Map> \ - [list on_tk_pane_mapped %W 0 \ - [lindex $gm 1] \ - [lindex [.vpane sash coord 0] 1]] + [list on_tk_pane_mapped %W 0 \ + [lindex $gm 1] \ + [lindex [.vpane sash coord 0] 1]] bind .vpane.files <Map> \ - [list on_tk_pane_mapped %W 0 \ - [lindex [.vpane.files sash coord 0] 0] \ - [lindex $gm 2]] + [list on_tk_pane_mapped %W 0 \ + [lindex [.vpane.files sash coord 0] 0] \ + [lindex $gm 2]] } wm geometry . [lindex $gm 0] } @@ -3812,6 +3933,8 @@ bind $ui_comm <$M1B-Key-KP_Subtract> {show_less_context;break} bind $ui_comm <$M1B-Key-equal> {show_more_context;break} bind $ui_comm <$M1B-Key-plus> {show_more_context;break} bind $ui_comm <$M1B-Key-KP_Add> {show_more_context;break} +bind $ui_comm <$M1B-Key-BackSpace> {event generate %W <Meta-Delete>;break} +bind $ui_comm <$M1B-Key-Delete> {event generate %W <Meta-d>;break} bind $ui_diff <$M1B-Key-x> {tk_textCopy %W;break} bind $ui_diff <$M1B-Key-X> {tk_textCopy %W;break} @@ -3861,6 +3984,8 @@ bind . <$M1B-Key-j> do_revert_selection bind . <$M1B-Key-J> do_revert_selection bind . <$M1B-Key-i> do_add_all bind . <$M1B-Key-I> do_add_all +bind . <$M1B-Key-e> toggle_commit_type +bind . <$M1B-Key-E> toggle_commit_type bind . <$M1B-Key-minus> {show_less_context;break} bind . <$M1B-Key-KP_Subtract> {show_less_context;break} bind . <$M1B-Key-equal> {show_more_context;break} @@ -3877,6 +4002,14 @@ foreach i [list $ui_index $ui_workdir] { } unset i +bind . <Alt-Key-1> {focus_widget $::ui_workdir} +bind . <Alt-Key-2> {focus_widget $::ui_index} +bind . <Alt-Key-3> {focus $::ui_diff} +bind . <Alt-Key-4> {focus $::ui_comm} + +set file_lists_last_clicked($ui_index) {} +set file_lists_last_clicked($ui_workdir) {} + set file_lists($ui_index) [list] set file_lists($ui_workdir) [list] @@ -4055,6 +4188,9 @@ if {$picked && [is_config_true gui.autoexplore]} { do_explore } +# Clear "Initializing..." status +after 500 {$main_status show ""} + # Local variables: # mode: tcl # indent-tabs-mode: t |