X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/efa092c4e4286943b2c4270624ee5c4331006312..9e21ce5c3b27e32aec6bbb9ecb41cb3a55e30838:/tig.c diff --git a/tig.c b/tig.c index 1ad1994..7b8fc7d 100644 --- a/tig.c +++ b/tig.c @@ -54,8 +54,8 @@ static size_t utf8_length(const char *string, size_t max_width, int *coloffset, #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define STRING_SIZE(x) (sizeof(x) - 1) +#define SIZEOF_STR 1024 /* Default string size. */ #define SIZEOF_REF 256 /* Size of symbolic or SHA1 ID. */ -#define SIZEOF_CMD 1024 /* Size of command buffer. */ #define SIZEOF_REVGRAPH 19 /* Size of revision ancestry graphics. */ /* This color name can be used to refer to the default term colors. */ @@ -224,11 +224,11 @@ string_enum_compare(const char *str1, const char *str2, int len) */ static size_t -sq_quote(char buf[SIZEOF_CMD], size_t bufsize, const char *src) +sq_quote(char buf[SIZEOF_STR], size_t bufsize, const char *src) { char c; -#define BUFPUT(x) do { if (bufsize < SIZEOF_CMD) buf[bufsize++] = (x); } while (0) +#define BUFPUT(x) do { if (bufsize < SIZEOF_STR) buf[bufsize++] = (x); } while (0) BUFPUT('\''); while ((c = *src++)) { @@ -366,7 +366,7 @@ static bool opt_rev_graph = TRUE; static int opt_num_interval = NUMBER_INTERVAL; static int opt_tab_size = TABSIZE; static enum request opt_request = REQ_VIEW_MAIN; -static char opt_cmd[SIZEOF_CMD] = ""; +static char opt_cmd[SIZEOF_STR] = ""; static FILE *opt_pipe = NULL; static char opt_encoding[20] = "UTF-8"; static bool opt_utf8 = TRUE; @@ -1089,7 +1089,7 @@ static int load_options(void) { char *home = getenv("HOME"); - char buf[1024]; + char buf[SIZEOF_STR]; FILE *file; config_lineno = 0; @@ -1141,7 +1141,7 @@ struct view { enum keymap keymap; /* What keymap does this view have */ - char cmd[SIZEOF_CMD]; /* Command buffer */ + char cmd[SIZEOF_STR]; /* Command buffer */ char ref[SIZEOF_REF]; /* Hovered commit reference */ char vid[SIZEOF_REF]; /* View ID. Set to id member when updating. */ @@ -2067,20 +2067,52 @@ pager_draw(struct view *view, struct line *line, unsigned int lineno) return TRUE; } +static bool +add_describe_ref(char *buf, int *bufpos, char *commit_id, const char *sep) +{ + char refbuf[SIZEOF_STR]; + char *ref = NULL; + FILE *pipe; + + if (!string_format(refbuf, "git describe %s", commit_id)) + return TRUE; + + pipe = popen(refbuf, "r"); + if (!pipe) + return TRUE; + + if ((ref = fgets(refbuf, sizeof(refbuf), pipe))) + ref = chomp_string(ref); + pclose(pipe); + + if (!ref || !*ref) + return TRUE; + + /* This is the only fatal call, since it can "corrupt" the buffer. */ + if (!string_nformat(buf, SIZEOF_STR, bufpos, "%s%s", sep, ref)) + return FALSE; + + return TRUE; +} + static void add_pager_refs(struct view *view, struct line *line) { - char buf[1024]; - char *data = line->data; + char buf[SIZEOF_STR]; + char *commit_id = line->data + STRING_SIZE("commit "); struct ref **refs; int bufpos = 0, refpos = 0; const char *sep = "Refs: "; + bool is_tag = FALSE; assert(line->type == LINE_COMMIT); - refs = get_refs(data + STRING_SIZE("commit ")); - if (!refs) + refs = get_refs(commit_id); + if (!refs) { + if (view == VIEW(REQ_VIEW_DIFF)) + goto try_add_describe_ref; return; + } do { struct ref *ref = refs[refpos]; @@ -2089,8 +2121,16 @@ add_pager_refs(struct view *view, struct line *line) if (!string_format_from(buf, &bufpos, fmt, sep, ref->name)) return; sep = ", "; + if (ref->tag) + is_tag = TRUE; } while (refs[refpos++]->next); + if (!is_tag && view == VIEW(REQ_VIEW_DIFF)) { +try_add_describe_ref: + if (!add_describe_ref(buf, &bufpos, commit_id, sep)) + return; + } + if (!realloc_lines(view, view->line_size + 1)) return; @@ -2646,11 +2686,11 @@ init_display(void) wbkgdset(status_win, get_line_attr(LINE_STATUS)); } -static int -read_prompt(void) +static char * +read_prompt(const char *prompt) { enum { READING, STOP, CANCEL } status = READING; - char buf[sizeof(opt_cmd) - STRING_SIZE("git \0")]; + static char buf[sizeof(opt_cmd) - STRING_SIZE("git \0")]; int pos = 0; while (status == READING) { @@ -2660,7 +2700,7 @@ read_prompt(void) foreach_view (view, i) update_view(view); - report(":%.*s", pos, buf); + report("%s%.*s", prompt, pos, buf); /* Refresh, accept single keystroke of input */ key = wgetch(status_win); switch (key) { @@ -2687,7 +2727,7 @@ read_prompt(void) default: if (pos >= sizeof(buf)) { report("Input string too long"); - return ERR; + return NULL; } if (isprint(key)) @@ -2698,18 +2738,12 @@ read_prompt(void) if (status == CANCEL) { /* Clear the status window */ report(""); - return ERR; + return NULL; } buf[pos++] = 0; - if (!string_format(opt_cmd, "git %s", buf)) - return ERR; - if (strncmp(buf, "show", 4) && isspace(buf[4])) - opt_request = REQ_VIEW_DIFF; - else - opt_request = REQ_VIEW_PAGER; - return OK; + return buf; } /* @@ -2970,10 +3004,21 @@ main(int argc, char *argv[]) * status_win restricted. */ switch (request) { case REQ_PROMPT: - if (read_prompt() == ERR) - request = REQ_SCREEN_UPDATE; - break; + { + char *cmd = read_prompt(":"); + if (cmd && string_format(opt_cmd, "git %s", cmd)) { + if (strncmp(cmd, "show", 4) && isspace(cmd[4])) { + opt_request = REQ_VIEW_DIFF; + } else { + opt_request = REQ_VIEW_PAGER; + } + break; + } + + request = REQ_SCREEN_UPDATE; + break; + } case REQ_SCREEN_RESIZE: { int height, width;