4 #include "menuengine.h"
5 #include "cheetahmenu.h"
7 #include "systeminfo.h"
9 char *wd_from_path(const char *path
, BOOL
*is_path_dir
)
11 BOOL directory
= TRUE
;
12 char *cheetah_wd
= strdup(path
);
13 if (!is_directory(cheetah_wd
)) {
14 char *c
= strrchr(cheetah_wd
, PATH_SEPERATOR
);
15 if (c
) /* sanity check in case it's a weird directory */
22 *is_path_dir
= directory
;
27 static char *get_git_prefix(const char *wd
, int *out_status
)
29 char *prefix
= NULL
, *eol
;
31 struct strbuf output
= STRBUF_INIT
;
33 status
= exec_program(wd
, &output
, NULL
, WAITMODE
,
34 "git", "rev-parse", "--show-prefix", NULL
);
38 eol
= strchr(output
.buf
, '\n');
42 if (!status
) /* we're in the repo */
43 prefix
= strdup(output
.buf
);
45 strbuf_release(&output
);
50 * Cheetah-specific menu
53 static int menu_gui(struct git_data
*this_
, UINT id
)
55 char *wd
= wd_from_path(this_
->name
, NULL
);
58 free_func_t argv_free
;
61 const char *generic_argv
[] = { "git", "gui", NULL
};
63 argv
= menu_get_platform_argv(MENU_GUI
, NULL
,
64 &argv_free
, &argv_data
);
69 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
78 static int menu_init(struct git_data
*this_
, UINT id
)
80 char *wd
= wd_from_path(this_
->name
, NULL
);
83 free_func_t argv_free
;
86 const char *generic_argv
[] = { "git", "init", NULL
};
88 argv
= menu_get_platform_argv(MENU_INIT
, NULL
,
89 &argv_free
, &argv_data
);
93 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
| WAITMODE
, argv
);
102 static int menu_history(struct git_data
*this_
, unsigned int id
)
105 char *wd
= wd_from_path(this_
->name
, &is_directory
);
109 free_func_t argv_free
;
112 const char *generic_argv
[] = { "gitk", "HEAD", "--",
116 name
= this_
->name
+ strlen(wd
) + 1;
117 generic_argv
[3] = name
;
119 argv
= menu_get_platform_argv(MENU_HISTORY
, name
,
120 &argv_free
, &argv_data
);
124 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
127 argv_free(argv_data
);
133 static int menu_bash(struct git_data
*this_
, UINT id
)
135 char *wd
= wd_from_path(this_
->name
, NULL
);
138 free_func_t argv_free
;
141 argv
= menu_get_platform_argv(MENU_BASH
, wd
,
142 &argv_free
, &argv_data
);
143 /* There is no generic implementation for this item */
145 debug_git("Error: Got no platform terminal for bash");
149 exec_program_v(wd
, NULL
, NULL
, NORMALMODE
, argv
);
152 argv_free(argv_data
);
158 static int menu_blame(struct git_data
*this_
, UINT id
)
161 char *wd
= wd_from_path(this_
->name
, &is_directory
);
165 free_func_t argv_free
= NULL
;
168 const char *generic_argv
[] = { "git", "gui", "blame",
172 name
= this_
->name
+ strlen(wd
) + 1;
173 generic_argv
[3] = name
;
175 argv
= menu_get_platform_argv(MENU_BLAME
, name
,
176 &argv_free
, &argv_data
);
180 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
184 argv_free(argv_data
);
190 static int menu_citool(struct git_data
*this_
, UINT id
)
192 char *wd
= wd_from_path(this_
->name
, NULL
);
195 free_func_t argv_free
;
198 const char *generic_argv
[] = { "git", "citool", NULL
};
200 argv
= menu_get_platform_argv(MENU_CITOOL
, NULL
,
201 &argv_free
, &argv_data
);
205 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
208 argv_free(argv_data
);
214 static int menu_addall(struct git_data
*this_
, UINT id
)
216 char *wd
= wd_from_path(this_
->name
, NULL
);
219 free_func_t argv_free
;
222 const char *generic_argv
[] = { "git", "add", "--all", NULL
};
224 argv
= menu_get_platform_argv(MENU_ADDALL
, NULL
,
225 &argv_free
, &argv_data
);
229 exec_program_v(wd
, NULL
, NULL
, HIDDENMODE
, argv
);
232 argv_free(argv_data
);
238 static int menu_branch(struct git_data
*this_
, UINT id
)
241 char *wd
= wd_from_path(this_
->name
, NULL
);
243 const char *menu_item_text
;
246 free_func_t argv_free
;
249 const char *generic_argv
[] = { "git", "checkout", NULL
, NULL
};
251 menu_item_text
= get_menu_item_text(id
);
252 generic_argv
[2] = menu_item_text
;
254 argv
= menu_get_platform_argv(MENU_BRANCH
, menu_item_text
,
255 &argv_free
, &argv_data
);
259 strbuf_init(&err
, 0);
261 status
= exec_program_v(wd
, NULL
, &err
, HIDDENMODE
| WAITMODE
, argv
);
263 /* if nothing, terribly wrong happened, show the confirmation */
265 /* strangely enough even success message is on stderr */
266 debug_git_mbox(err
.buf
);
269 argv_free(argv_data
);
275 static BOOL
build_branch_menu(struct git_data
*data
,
276 const struct menu_item
*item
,
282 char *wd
= wd_from_path(data
->name
, NULL
);
284 struct strbuf output
;
285 struct strbuf
**lines
, **it
;
286 strbuf_init(&output
, 0);
288 status
= exec_program(wd
, &output
, NULL
, WAITMODE
,
289 "git", "branch", NULL
);
294 submenu
= start_submenu(data
, item
, platform
);
296 lines
= strbuf_split(&output
, '\n');
297 for (it
= lines
; *it
; it
++) {
298 struct menu_item item
= {
299 MENU_ITEM_CLEANUP
, 0,
305 item
.string
= strdup((*it
)->buf
+ 2);
306 item
.helptext
= strdup((*it
)->buf
+ 2);
307 item
.flags
= '*' == (*it
)->buf
[0] ?
308 MI_CHECKED
| MI_DISABLED
: 0;
309 if (build_item(data
, &item
, submenu
))
310 append_active_menu(&item
);
313 * if the platform failed to create an item
314 * there is no point to try other items
319 end_submenu(platform
, submenu
);
321 /* technically, there is nothing to track for the menu engine */
325 UINT
cheetah_menu_mask(struct git_data
*this_
)
328 char *wd
= wd_from_path(this_
->name
, &is_directory
);
329 UINT selection
= is_directory
? MENU_ITEM_DIR
: MENU_ITEM_FILE
;
331 char *prefix
= get_git_prefix(wd
, &status
);
333 if (status
< 0) /* something went terribly wrong */
334 selection
= MENU_ITEM_LAST
;
336 selection
|= MENU_ITEM_NOREPO
;
338 char head_path
[MAX_PATH
] = "HEAD";
340 sprintf(head_path
, "HEAD:%s%s",
342 this_
->name
+ strlen(wd
) + 1);
344 status
= exec_program(wd
, NULL
, NULL
, WAITMODE
,
345 "git", "rev-parse", "--verify", head_path
, NULL
);
346 if (status
< 0) /* something went terribly wrong */
347 selection
= MENU_ITEM_LAST
;
349 selection
|= MENU_ITEM_REPO
|
351 MENU_ITEM_NOTRACK
: MENU_ITEM_TRACK
);
359 const struct menu_item cheetah_menu
[] = {
360 { MENU_ITEM_ALWAYS
, 0, NULL
, NULL
, build_separator
, NULL
},
362 { MENU_ITEM_REPO
, 0, "Git &Add all files now",
363 "Add all files from this folder now",
364 build_item
, menu_addall
},
365 { MENU_ITEM_REPO
, 0, "Git &Commit Tool",
366 "Launch the GIT commit tool in the local or chosen directory.",
367 build_item
, menu_citool
},
368 { MENU_ITEM_TRACK
, 0, "Git &History",
369 "Show GIT history of the chosen file or directory.",
372 { MENU_ITEM_TRACK
| MENU_ITEM_FILE
, 0, "Git &Blame",
373 "Start a blame viewer on the specified file.",
374 build_item
, menu_blame
},
376 { MENU_ITEM_REPO
, 0, "Git &Gui",
377 "Launch the GIT Gui in the local or chosen directory.",
378 build_item
, menu_gui
},
380 { MENU_ITEM_REPO
, 0, "Git Bra&nch",
382 build_branch_menu
, NULL
},
384 { MENU_ITEM_NOREPO
, 0, "Git I&nit Here",
385 "Initialize GIT repo in the local directory.",
386 build_item
, menu_init
},
387 { MENU_ITEM_NOREPO
| MENU_ITEM_DIR
, 0, "Git &Gui",
388 "Launch the GIT Gui in the local or chosen directory.",
389 build_item
, menu_gui
},
391 { MENU_ITEM_ALWAYS
, 0, "Git Ba&sh",
392 "Start GIT shell in the local or chosen directory",
393 build_item
, menu_bash
},
394 { MENU_ITEM_ALWAYS
, 0, NULL
, NULL
, build_separator
, NULL
},
397 void build_cheetah_menu(struct git_data
*data
, void *platform_data
)
399 reset_platform(platform_data
);
400 build_menu_items(data
, cheetah_menu_mask
,
402 sizeof(cheetah_menu
) / sizeof(cheetah_menu
[0]),