commit - c9d2b2638181862042c8d712cf7bf4977fea15e2
commit + 41605754d020cd4be569b2dffdfac47451ea8925
blob - 7b48924a0835e067b5b49dc74d78a60a76d928d4
blob + 3895e44e1cc2bd3dcc96dbcbd7369ecad839c9b0
--- tog/tog.c
+++ tog/tog.c
#define TOG_SEARCH_NO_MORE 2
#define TOG_SEARCH_HAVE_NONE 3
regex_t regex;
+ regmatch_t regmatch;
};
static const struct got_error *open_diff_view(struct tog_view *,
view->searching = 0;
}
- if (regcomp(&view->regex, pattern,
- REG_EXTENDED | REG_NOSUB | REG_NEWLINE) == 0) {
+ if (regcomp(&view->regex, pattern, REG_EXTENDED | REG_NEWLINE) == 0) {
err = view->search_start(view);
if (err) {
regfree(&view->regex);
}
static int
-match_line(const char *line, regex_t *regex)
+match_line(const char *line, regex_t *regex, size_t nmatch,
+ regmatch_t *regmatch)
{
- regmatch_t regmatch;
-
- return regexec(regex, line, 1, ®match, 0) == 0;
+ return regexec(regex, line, nmatch, regmatch, 0) == 0;
}
struct tog_color *
struct tog_color *tc = NULL;
SIMPLEQ_FOREACH(tc, colors, entry) {
- if (match_line(line, &tc->regex))
+ if (match_line(line, &tc->regex, 0, NULL))
return tc;
}
}
static const struct got_error *
+add_matched_line(int *wtotal, const char *line, int wlimit, int col_tab_align,
+ WINDOW *window, regmatch_t *regmatch)
+{
+ const struct got_error *err = NULL;
+ wchar_t *wline;
+ int width;
+ char *s;
+
+ *wtotal = 0;
+
+ s = strndup(line, regmatch->rm_so);
+ if (s == NULL)
+ return got_error_from_errno("strndup");
+
+ err = format_line(&wline, &width, s, wlimit, col_tab_align);
+ if (err) {
+ free(s);
+ return err;
+ }
+ waddwstr(window, wline);
+ free(wline);
+ free(s);
+ wlimit -= width;
+ *wtotal += width;
+
+ if (wlimit > 0) {
+ s = strndup(line + regmatch->rm_so,
+ regmatch->rm_eo - regmatch->rm_so);
+ if (s == NULL) {
+ err = got_error_from_errno("strndup");
+ free(s);
+ return err;
+ }
+ err = format_line(&wline, &width, s, wlimit, col_tab_align);
+ if (err) {
+ free(s);
+ return err;
+ }
+ wattr_on(window, A_STANDOUT, NULL);
+ waddwstr(window, wline);
+ wattr_off(window, A_STANDOUT, NULL);
+ free(wline);
+ free(s);
+ wlimit -= width;
+ *wtotal += width;
+ }
+
+ if (wlimit > 0 && strlen(line) > regmatch->rm_eo) {
+ err = format_line(&wline, &width,
+ line + regmatch->rm_eo, wlimit, col_tab_align);
+ if (err)
+ return err;
+ waddwstr(window, wline);
+ free(wline);
+ *wtotal += width;
+ }
+
+ return NULL;
+}
+
+static const struct got_error *
draw_file(struct tog_view *view, FILE *f, int first_displayed_line, int nlines,
off_t *line_offsets, int selected_line, int max_lines,
- int *last_displayed_line, int *eof, char *header, struct tog_colors *colors)
+ int *last_displayed_line, int *eof, char *header,
+ struct tog_colors *colors, int matched_line, regmatch_t *regmatch)
{
const struct got_error *err;
int nprinted = 0;
if (line == NULL) {
*eof = 1;
break;
- }
- err = format_line(&wline, &width, line, view->ncols, 0);
- if (err) {
- free(line);
- return err;
}
tc = match_color(colors, line);
if (tc)
wattr_on(view->window,
COLOR_PAIR(tc->colorpair), NULL);
- waddwstr(view->window, wline);
+ if (first_displayed_line + nprinted == matched_line &&
+ regmatch->rm_so >= 0 && regmatch->rm_so < regmatch->rm_eo) {
+ err = add_matched_line(&width, line, view->ncols, 0,
+ view->window, regmatch);
+ if (err) {
+ free(line);
+ return err;
+ }
+ } else {
+ err = format_line(&wline, &width, line, view->ncols, 0);
+ if (err) {
+ free(line);
+ return err;
+ }
+ waddwstr(view->window, wline);
+ free(wline);
+ wline = NULL;
+ }
if (tc)
wattr_off(view->window,
COLOR_PAIR(tc->colorpair), NULL);
waddch(view->window, '\n');
nprinted++;
free(line);
- free(wline);
- wline = NULL;
}
if (nprinted >= 1)
*last_displayed_line = first_displayed_line + (nprinted - 1);
}
free(line);
line = parse_next_line(s->f, &len);
- if (line && match_line(line, &view->regex)) {
+ if (line &&
+ match_line(line, &view->regex, 1, &view->regmatch)) {
view->search_next_done = TOG_SEARCH_HAVE_MORE;
s->matched_line = lineno;
free(line);
return draw_file(view, s->f, s->first_displayed_line, s->nlines,
s->line_offsets, s->selected_line, view->nlines,
- &s->last_displayed_line, &s->eof, header, &s->colors);
+ &s->last_displayed_line, &s->eof, header, &s->colors,
+ s->matched_line, &view->regmatch);
}
static const struct got_error *
const char *path, struct tog_blame_line *lines, int nlines,
int blame_complete, int selected_line, int *first_displayed_line,
int *last_displayed_line, int *eof, int max_lines,
- struct tog_colors *colors)
+ struct tog_colors *colors, int matched_line, regmatch_t *regmatch)
{
const struct got_error *err;
int lineno = 0, nprinted = 0;
if (++lineno < *first_displayed_line) {
free(line);
continue;
- }
-
- if (view->ncols <= 9) {
- width = 9;
- wline = wcsdup(L"");
- if (wline == NULL)
- err = got_error_from_errno("wcsdup");
- } else {
- err = format_line(&wline, &width, line,
- view->ncols - 9, 9);
- width += 9;
- }
- if (err) {
- free(line);
- return err;
}
if (view->focussed && nprinted == selected_line - 1)
err = got_object_id_str(&id_str, blame_line->id);
if (err) {
free(line);
- free(wline);
return err;
}
tc = get_color(colors, TOG_COLOR_COMMIT);
wstandend(view->window);
waddstr(view->window, " ");
- waddwstr(view->window, wline);
+ if (view->ncols <= 9) {
+ width = 9;
+ wline = wcsdup(L"");
+ if (wline == NULL) {
+ err = got_error_from_errno("wcsdup");
+ free(line);
+ return err;
+ }
+ } else if (*first_displayed_line + nprinted == matched_line &&
+ regmatch->rm_so >= 0 && regmatch->rm_so < regmatch->rm_eo) {
+ err = add_matched_line(&width, line, view->ncols - 9, 9,
+ view->window, regmatch);
+ if (err) {
+ free(line);
+ return err;
+ }
+ width += 9;
+ } else {
+ err = format_line(&wline, &width, line,
+ view->ncols - 9, 9);
+ waddwstr(view->window, wline);
+ free(wline);
+ wline = NULL;
+ width += 9;
+ }
+
if (width <= view->ncols - 1)
waddch(view->window, '\n');
if (++nprinted == 1)
*first_displayed_line = lineno;
free(line);
- free(wline);
- wline = NULL;
}
*last_displayed_line = lineno;
}
free(line);
line = parse_next_line(s->blame.f, &len);
- if (line && match_line(line, &view->regex)) {
+ if (line &&
+ match_line(line, &view->regex, 1, &view->regmatch)) {
view->search_next_done = TOG_SEARCH_HAVE_MORE;
s->matched_line = lineno;
free(line);
err = draw_blame(view, s->blamed_commit->id, s->blame.f,
s->path, s->blame.lines, s->blame.nlines, s->blame_complete,
s->selected_line, &s->first_displayed_line,
- &s->last_displayed_line, &s->eof, view->nlines, &s->colors);
+ &s->last_displayed_line, &s->eof, view->nlines, &s->colors,
+ s->matched_line, &view->regmatch);
view_vborder(view);
return err;