git-gui: open the staged content of a file in the editor
[git-gui/bertw.git] / lib / tools.tcl
blob4cbbc1a8b39bd7dc8ab556a5e3795d935d1ecbdd
1 # git-gui Tools menu implementation
3 proc tools_list {} {
4 global repo_config
6 set names {}
7 foreach item [array names repo_config guitool.*.cmd] {
8 lappend names [string range $item 8 end-4]
10 return [lsort $names]
13 proc tools_populate_all {tailcnt} {
14 global tools_menubar tools_menutbl
16 set mbar_end [$tools_menubar index end]
17 set mbar_base [expr {$mbar_end - $tailcnt}]
18 if {$mbar_base >= 0} {
19 $tools_menubar delete 0 $mbar_base
22 array unset tools_menutbl
24 foreach fullname [tools_list] {
25 tools_populate_one $tailcnt $fullname
29 proc tools_create_item {menu tailcnt parent args} {
30 if {$parent eq $menu} {
31 set pos [expr {[$parent index end]-$tailcnt+1}]
32 eval [list $parent insert $pos] $args
33 } else {
34 eval [list $parent add] $args
38 proc tools_populate_one {tailcnt fullname} {
39 global tools_menubar tools_menutbl tools_id
41 if {![info exists tools_id]} {
42 set tools_id 0
45 set names [split $fullname '/']
46 set parent $tools_menubar
47 for {set i 0} {$i < [llength $names]-1} {incr i} {
48 set subname [join [lrange $names 0 $i] '/']
49 if {[info exists tools_menutbl($subname)]} {
50 set parent $tools_menutbl($subname)
51 } else {
52 set subid $parent.t$tools_id
53 tools_create_item $tools_menubar $tailcnt \
54 $parent cascade \
55 -label [lindex $names $i] \
56 -menu $subid
57 menu $subid
58 set tools_menutbl($subname) $subid
59 set parent $subid
60 incr tools_id
64 tools_create_item $tools_menubar $tailcnt \
65 $parent command \
66 -label [lindex $names end] \
67 -command [list tools_exec $fullname]
70 proc files_tools_populate_all {tailcnt {path_var {}}} {
71 global files_ctxm files_ctxmtbl
73 set ctxm_end [$files_ctxm index end]
74 set ctxm_base [expr {$ctxm_end - $tailcnt}]
75 if {$ctxm_base >= 0} {
76 $files_ctxm delete 0 $ctxm_base
79 array unset files_ctxmtbl
81 foreach fullname [tools_list] {
82 if {[is_config_true "guitool.$fullname.needsfile"]} {
83 files_tools_populate_one $tailcnt $fullname $path_var
88 proc files_tools_populate_one {tailcnt fullname {path_var {}}} {
89 global files_ctxm files_ctxmtbl files_tools_id
91 if {![info exists files_tools_id]} {
92 set files_tools_id 0
95 set names [split $fullname '/']
96 set parent $files_ctxm
97 for {set i 0} {$i < [llength $names]-1} {incr i} {
98 set subname [join [lrange $names 0 $i] '/']
99 if {[info exists files_ctxmtbl($subname)]} {
100 set parent $files_ctxmtbl($subname)
101 } else {
102 set subid $parent.t$files_tools_id
103 tools_create_item $files_ctxm $tailcnt \
104 $parent cascade \
105 -label [lindex $names $i] \
106 -menu $subid
107 menu $subid -tearoff 0
108 set files_ctxmtbl($subname) $subid
109 set parent $subid
110 incr files_tools_id
114 tools_create_item $files_ctxm $tailcnt \
115 $parent command \
116 -label [lindex $names end] \
117 -command [list tools_exec $fullname $path_var]
120 proc tools_exec {fullname {path_var {}}} {
121 global repo_config env current_diff_path
122 global current_branch is_detached
124 if {$path_var ne {}} {
125 upvar #0 $path_var path
126 } else {
127 set path $current_diff_path
130 if {[is_config_true "guitool.$fullname.needsfile"]} {
131 if {$path eq {}} {
132 error_popup [mc "Running %s requires a selected file." $fullname]
133 return
137 catch { unset env(ARGS) }
138 catch { unset env(REVISION) }
140 if {[get_config "guitool.$fullname.revprompt"] ne {} ||
141 [get_config "guitool.$fullname.argprompt"] ne {}} {
142 set dlg [tools_askdlg::dialog $fullname]
143 if {![tools_askdlg::execute $dlg]} {
144 return
146 } elseif {[is_config_true "guitool.$fullname.confirm"]} {
147 if {[is_config_true "guitool.$fullname.needsfile"]} {
148 if {[ask_popup [mc "Are you sure you want to run %1\$s on file \"%2\$s\"?" $fullname $path]] ne {yes}} {
149 return
151 } else {
152 if {[ask_popup [mc "Are you sure you want to run %s?" $fullname]] ne {yes}} {
153 return
158 set env(GIT_GUITOOL) $fullname
159 set env(FILENAME) $path
160 if {$is_detached} {
161 set env(CUR_BRANCH) ""
162 } else {
163 set env(CUR_BRANCH) $current_branch
166 set cmdline $repo_config(guitool.$fullname.cmd)
167 if {[is_config_true "guitool.$fullname.noconsole"]} {
168 tools_run_silent [list sh -c $cmdline] \
169 [list tools_complete $fullname {}]
170 } else {
171 regsub {/} $fullname { / } title
172 set w [console::new \
173 [mc "Tool: %s" $title] \
174 [mc "Running: %s" $cmdline]]
175 console::exec $w [list sh -c $cmdline] \
176 [list tools_complete $fullname $w]
179 unset env(GIT_GUITOOL)
180 unset env(FILENAME)
181 unset env(CUR_BRANCH)
182 catch { unset env(ARGS) }
183 catch { unset env(REVISION) }
186 proc tools_run_silent {cmd after} {
187 lappend cmd 2>@1
188 set fd [_open_stdout_stderr $cmd]
190 fconfigure $fd -blocking 0 -translation binary
191 fileevent $fd readable [list tools_consume_input $fd $after]
194 proc tools_consume_input {fd after} {
195 read $fd
196 if {[eof $fd]} {
197 fconfigure $fd -blocking 1
198 if {[catch {close $fd}]} {
199 uplevel #0 $after 0
200 } else {
201 uplevel #0 $after 1
206 proc tools_complete {fullname w {ok 1}} {
207 if {$w ne {}} {
208 console::done $w $ok
211 if {$ok} {
212 set msg [mc "Tool completed successfully: %s" $fullname]
213 } else {
214 set msg [mc "Tool failed: %s" $fullname]
217 if {[is_config_true "guitool.$fullname.norescan"]} {
218 ui_status $msg
219 } else {
220 rescan [list ui_status $msg]