Add context-sensitive Git History item
[git-cheetah/kirill.git] / cheetahmenu.c
blob9f07be2b60c0e2ea56ad70d4d4439cdc0e8d38a3
2 #include "cache.h"
3 #include "exec.h"
4 #include "menuengine.h"
5 #include "cheetahmenu.h"
7 char *wd_from_path(const char *path, BOOL *is_path_dir)
9 BOOL is_directory = TRUE;
10 char *cheetah_wd = strdup(path);
11 if (!(FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(cheetah_wd))) {
12 char *c = strrchr(cheetah_wd, '\\');
13 if (c) /* sanity check in case it's a weird directory */
14 *c = 0;
16 is_directory = FALSE;
19 if (is_path_dir)
20 *is_path_dir = is_directory;
22 return cheetah_wd;
26 * Cheetah-specific menu
29 static void menu_gui(struct git_data *this_, UINT id)
31 char *wd = wd_from_path(this_->name, NULL);
32 exec_program(wd, NULL, NULL, HIDDENMODE, "git", "gui", NULL);
33 free(wd);
36 static void menu_history(struct git_data *this_, unsigned int id)
38 BOOL is_directory;
39 char *wd = wd_from_path(this_->name, &is_directory);
40 char *name = "";
42 if (!is_directory)
43 name = this_->name + strlen(wd) + 1;
45 exec_program(wd, NULL, NULL, HIDDENMODE, "sh", "--login", "-i",
46 "/bin/gitk", "HEAD", "--", name, NULL);
47 free(wd);
50 UINT cheetah_menu_mask(struct git_data *this_)
52 BOOL is_directory;
53 char *wd = wd_from_path(this_->name, &is_directory);
54 UINT selection = is_directory ? MENU_ITEM_DIR : MENU_ITEM_FILE;
55 int status;
57 struct strbuf output;
58 char *eol;
59 strbuf_init(&output, 0);
61 status = exec_program(wd, &output, NULL, WAITMODE,
62 "git", "rev-parse", "--show-prefix", NULL);
63 eol = strchr(output.buf, '\n');
64 if (eol)
65 *eol = 0;
67 if (status < 0) /* something went terribly wrong */
68 selection = MENU_ITEM_LAST;
69 else if (status)
70 selection |= MENU_ITEM_NOREPO;
71 else {
72 char head_path[MAX_PATH] = "HEAD";
73 if (!is_directory)
74 sprintf(head_path, "HEAD:%s%s",
75 output.buf,
76 this_->name + strlen(wd) + 1);
78 status = exec_program(wd, NULL, NULL, WAITMODE,
79 "git", "rev-parse", "--verify", head_path, NULL);
80 if (status < 0) /* something went terribly wrong */
81 selection = MENU_ITEM_LAST;
82 else
83 selection |= MENU_ITEM_REPO |
84 (status ?
85 MENU_ITEM_NOTRACK : MENU_ITEM_TRACK);
88 strbuf_release(&output);
89 free(wd);
90 return selection;
93 const struct menu_item cheetah_menu[] = {
94 { MENU_ITEM_ALWAYS, NULL, NULL, build_separator, NULL },
96 { MENU_ITEM_TRACK, "Git &History",
97 "Show GIT history of the chosen file or directory.",
98 build_item,
99 menu_history },
101 { MENU_ITEM_REPO, "&Git",
102 "Launch the GIT Gui in the local or chosen directory.",
103 build_item, menu_gui },
105 { MENU_ITEM_NOREPO | MENU_ITEM_FILE, "&Git Init Here",
106 "Initialize GIT repo in the local directory.",
107 build_item, menu_gui },
108 { MENU_ITEM_NOREPO | MENU_ITEM_DIR, "&Git Clone Here",
109 "Clone GIT repo into the local or chosen directory.",
110 build_item, menu_gui },
113 void build_cheetah_menu(struct git_data *data, void *platform_data)
115 reset_platform(platform_data);
116 build_menu_items(data, cheetah_menu_mask,
117 cheetah_menu,
118 sizeof(cheetah_menu) / sizeof(cheetah_menu[0]),
119 platform_data);