X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/9a48919bfae4a744d0f852d834aa93e71293e8f0..d720de4bb6ef9a214be1a86dbdd5d23cb665a953:/tig.c diff --git a/tig.c b/tig.c index 44fcb1b..a6447bf 100644 --- a/tig.c +++ b/tig.c @@ -1192,7 +1192,7 @@ struct view { /* Searching */ char grep[SIZEOF_STR]; /* Search string */ - regex_t regex; /* Pre-compiled regex */ + regex_t *regex; /* Pre-compiled regex */ /* If non-NULL, points to the view that opened this view. If this view * is closed tig will switch back to the parent view. */ @@ -1220,6 +1220,8 @@ struct view_ops { bool (*enter)(struct view *view, struct line *line); /* Search for regex in a line. */ bool (*grep)(struct view *view, struct line *line); + /* Select line */ + void (*select)(struct view *view, struct line *line); }; static struct view_ops pager_ops; @@ -1255,12 +1257,19 @@ static struct view views[] = { static bool draw_view_line(struct view *view, unsigned int lineno) { + struct line *line; + assert(view_is_displayed(view)); if (view->offset + lineno >= view->lines) return FALSE; - return view->ops->draw(view, &view->line[view->offset + lineno], lineno); + line = &view->line[view->offset + lineno]; + + if (view->offset + lineno == view->lineno) + view->ops->select(view, line); + + return view->ops->draw(view, line, lineno); } static void @@ -1680,16 +1689,20 @@ search_view(struct view *view, enum request request, const char *search) { int regex_err; - if (*view->grep) { - regfree(&view->regex); + if (view->regex) { + regfree(view->regex); *view->grep = 0; + } else { + view->regex = calloc(1, sizeof(*view->regex)); + if (!view->regex) + return; } - regex_err = regcomp(&view->regex, search, REG_EXTENDED); + regex_err = regcomp(view->regex, search, REG_EXTENDED); if (regex_err != 0) { char buf[SIZEOF_STR] = "unknown error"; - regerror(regex_err, &view->regex, buf, sizeof(buf)); + regerror(regex_err, view->regex, buf, sizeof(buf)); report("Search failed: %s", buf); return; } @@ -2205,15 +2218,6 @@ pager_draw(struct view *view, struct line *line, unsigned int lineno) wmove(view->win, lineno, 0); if (view->offset + lineno == view->lineno) { - if (type == LINE_COMMIT) { - string_copy(view->ref, text + 7); - string_copy(ref_commit, view->ref); - - } else if (type == LINE_TREE_DIR || type == LINE_TREE_FILE) { - string_ncopy(view->ref, text + STRING_SIZE("100644 blob "), 40); - string_copy(ref_blob, view->ref); - } - type = LINE_CURSOR; wchgat(view->win, -1, 0, type, NULL); } @@ -2333,10 +2337,14 @@ add_pager_refs(struct view *view, struct line *line) if (!is_tag && view == VIEW(REQ_VIEW_DIFF)) { try_add_describe_ref: + /* Add -g "fake" reference. */ if (!add_describe_ref(buf, &bufpos, commit_id, sep)) return; } + if (bufpos == 0) + return; + if (!realloc_lines(view, view->line_size + 1)) return; @@ -2404,18 +2412,30 @@ pager_grep(struct view *view, struct line *line) if (!*text) return FALSE; - if (regexec(&view->regex, text, 1, &pmatch, 0) == REG_NOMATCH) + if (regexec(view->regex, text, 1, &pmatch, 0) == REG_NOMATCH) return FALSE; return TRUE; } +static void +pager_select(struct view *view, struct line *line) +{ + if (line->type == LINE_COMMIT) { + char *text = line->data; + + string_copy(view->ref, text + 7); + string_copy(ref_commit, view->ref); + } +} + static struct view_ops pager_ops = { "line", pager_draw, pager_read, pager_enter, pager_grep, + pager_select, }; @@ -2555,7 +2575,7 @@ tree_enter(struct view *view, struct line *line) size_t origlen = pathlen; char *basename = data + SIZEOF_TREE_ATTR; - if (string_format_from(opt_path, &pathlen, "%s/", basename)) { + if (!string_format_from(opt_path, &pathlen, "%s/", basename)) { opt_path[origlen] = 0; return TRUE; } @@ -2595,12 +2615,24 @@ tree_enter(struct view *view, struct line *line) return TRUE; } +static void +tree_select(struct view *view, struct line *line) +{ + if (line->type == LINE_TREE_DIR || line->type == LINE_TREE_FILE) { + char *text = line->data; + + string_ncopy(view->ref, text + STRING_SIZE("100644 blob "), 40); + string_copy(ref_blob, view->ref); + } +} + static struct view_ops tree_ops = { "file", pager_draw, tree_read, tree_enter, pager_grep, + tree_select, }; static bool @@ -2620,6 +2652,7 @@ static struct view_ops blob_ops = { blob_read, pager_enter, pager_grep, + pager_select, }; @@ -2654,8 +2687,6 @@ main_draw(struct view *view, struct line *line, unsigned int lineno) wmove(view->win, lineno, col); if (view->offset + lineno == view->lineno) { - string_copy(view->ref, commit->id); - string_copy(ref_commit, view->ref); type = LINE_CURSOR; wattrset(view->win, get_line_attr(type)); wchgat(view->win, -1, 0, type, NULL); @@ -2880,19 +2911,29 @@ main_grep(struct view *view, struct line *line) return FALSE; } - if (regexec(&view->regex, text, 1, &pmatch, 0) != REG_NOMATCH) + if (regexec(view->regex, text, 1, &pmatch, 0) != REG_NOMATCH) return TRUE; } return FALSE; } +static void +main_select(struct view *view, struct line *line) +{ + struct commit *commit = line->data; + + string_copy(view->ref, commit->id); + string_copy(ref_commit, view->ref); +} + static struct view_ops main_ops = { "commit", main_draw, main_read, main_enter, main_grep, + main_select, };