X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/d720de4bb6ef9a214be1a86dbdd5d23cb665a953..8c317212e3f75826f5c789c29d63d72faccc90f5:/tig.c diff --git a/tig.c b/tig.c index a6447bf..25c423c 100644 --- a/tig.c +++ b/tig.c @@ -661,6 +661,10 @@ init_colors(void) struct line { enum line_type type; + + /* State flags */ + unsigned int selected:1; + void *data; /* User data */ }; @@ -1213,7 +1217,7 @@ struct view_ops { /* What type of content being displayed. Used in the title bar. */ const char *type; /* Draw one line; @lineno must be < view->height. */ - bool (*draw)(struct view *view, struct line *line, unsigned int lineno); + bool (*draw)(struct view *view, struct line *line, unsigned int lineno, bool selected); /* Read one line; updates view->line. */ bool (*read)(struct view *view, char *data); /* Depending on view, change display based on current line. */ @@ -1258,6 +1262,7 @@ static bool draw_view_line(struct view *view, unsigned int lineno) { struct line *line; + bool selected = (view->offset + lineno == view->lineno); assert(view_is_displayed(view)); @@ -1266,10 +1271,16 @@ draw_view_line(struct view *view, unsigned int lineno) line = &view->line[view->offset + lineno]; - if (view->offset + lineno == view->lineno) + if (selected) { + line->selected = TRUE; view->ops->select(view, line); + } else if (line->selected) { + line->selected = FALSE; + wmove(view->win, lineno, 0); + wclrtoeol(view->win); + } - return view->ops->draw(view, line, lineno); + return view->ops->draw(view, line, lineno, selected); } static void @@ -1421,9 +1432,9 @@ update_display_cursor(void) /* Scrolling backend */ static void -do_scroll_view(struct view *view, int lines, bool redraw) +do_scroll_view(struct view *view, int lines) { - assert(view_is_displayed(view)); + bool redraw_current_line = FALSE; /* The rendering expects the new offset. */ view->offset += lines; @@ -1431,6 +1442,17 @@ do_scroll_view(struct view *view, int lines, bool redraw) assert(0 <= view->offset && view->offset < view->lines); assert(lines); + /* Move current line into the view. */ + if (view->lineno < view->offset) { + view->lineno = view->offset; + redraw_current_line = TRUE; + } else if (view->lineno >= view->offset + view->height) { + view->lineno = view->offset + view->height - 1; + redraw_current_line = TRUE; + } + + assert(view->offset <= view->lineno && view->lineno < view->lines); + /* Redraw the whole screen if scrolling is pointless. */ if (view->height < ABS(lines)) { redraw_view(view); @@ -1445,29 +1467,11 @@ do_scroll_view(struct view *view, int lines, bool redraw) if (!draw_view_line(view, line)) break; } - } - /* Move current line into the view. */ - if (view->lineno < view->offset) { - view->lineno = view->offset; - draw_view_line(view, 0); - - } else if (view->lineno >= view->offset + view->height) { - if (view->lineno == view->offset + view->height) { - /* Clear the hidden line so it doesn't show if the view - * is scrolled up. */ - wmove(view->win, view->height, 0); - wclrtoeol(view->win); - } - view->lineno = view->offset + view->height - 1; - draw_view_line(view, view->lineno - view->offset); + if (redraw_current_line) + draw_view_line(view, view->lineno - view->offset); } - assert(view->offset <= view->lineno && view->lineno < view->lines); - - if (!redraw) - return; - redrawwin(view->win); wrefresh(view->win); report(""); @@ -1479,6 +1483,8 @@ scroll_view(struct view *view, enum request request) { int lines = 1; + assert(view_is_displayed(view)); + switch (request) { case REQ_SCROLL_PAGE_DOWN: lines = view->height; @@ -1510,7 +1516,7 @@ scroll_view(struct view *view, enum request request) die("request %d not handled in switch", request); } - do_scroll_view(view, lines, TRUE); + do_scroll_view(view, lines); } /* Cursor moving */ @@ -1564,13 +1570,8 @@ move_view(struct view *view, enum request request, bool redraw) assert(0 <= view->lineno && view->lineno < view->lines); /* Repaint the old "current" line if we be scrolling */ - if (ABS(steps) < view->height) { - int prev_lineno = view->lineno - steps - view->offset; - - wmove(view->win, prev_lineno, 0); - wclrtoeol(view->win); - draw_view_line(view, prev_lineno); - } + if (ABS(steps) < view->height) + draw_view_line(view, view->lineno - steps - view->offset); /* Check whether the view needs to be scrolled */ if (view->lineno < view->offset || @@ -1587,7 +1588,7 @@ move_view(struct view *view, enum request request, bool redraw) } } - do_scroll_view(view, steps, redraw); + do_scroll_view(view, steps); return; } @@ -1607,7 +1608,7 @@ move_view(struct view *view, enum request request, bool redraw) * Searching */ -static void search_view(struct view *view, enum request request, const char *search); +static void search_view(struct view *view, enum request request); static bool find_next_line(struct view *view, unsigned long lineno, struct line *line) @@ -1626,9 +1627,6 @@ find_next_line(struct view *view, unsigned long lineno, struct line *line) unsigned long old_lineno = view->lineno - view->offset; view->lineno = lineno; - - wmove(view->win, old_lineno, 0); - wclrtoeol(view->win); draw_view_line(view, old_lineno); draw_view_line(view, view->lineno - view->offset); @@ -1650,7 +1648,7 @@ find_next(struct view *view, enum request request) if (!*opt_search) report("No previous search"); else - search_view(view, request, opt_search); + search_view(view, request); return; } @@ -1685,7 +1683,7 @@ find_next(struct view *view, enum request request) } static void -search_view(struct view *view, enum request request, const char *search) +search_view(struct view *view, enum request request) { int regex_err; @@ -1698,7 +1696,7 @@ search_view(struct view *view, enum request request, const char *search) return; } - regex_err = regcomp(view->regex, search, REG_EXTENDED); + regex_err = regcomp(view->regex, opt_search, REG_EXTENDED); if (regex_err != 0) { char buf[SIZEOF_STR] = "unknown error"; @@ -1707,7 +1705,7 @@ search_view(struct view *view, enum request request, const char *search) return; } - string_copy(view->grep, search); + string_copy(view->grep, opt_search); find_next(view, request); } @@ -2013,7 +2011,7 @@ open_view(struct view *prev, enum request request, enum open_flags flags) /* Scroll the view that was split if the current line is * outside the new limited view. */ - do_scroll_view(prev, lines, TRUE); + do_scroll_view(prev, lines); } if (prev && view != prev) { @@ -2143,7 +2141,7 @@ view_driver(struct view *view, enum request request) case REQ_SEARCH: case REQ_SEARCH_BACK: - search_view(view, request, opt_search); + search_view(view, request); break; case REQ_FIND_NEXT: @@ -2208,7 +2206,7 @@ view_driver(struct view *view, enum request request) */ static bool -pager_draw(struct view *view, struct line *line, unsigned int lineno) +pager_draw(struct view *view, struct line *line, unsigned int lineno, bool selected) { char *text = line->data; enum line_type type = line->type; @@ -2217,7 +2215,7 @@ pager_draw(struct view *view, struct line *line, unsigned int lineno) wmove(view->win, lineno, 0); - if (view->offset + lineno == view->lineno) { + if (selected) { type = LINE_CURSOR; wchgat(view->win, -1, 0, type, NULL); } @@ -2424,7 +2422,7 @@ 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(view->ref, text + STRING_SIZE("commit ")); string_copy(ref_commit, view->ref); } } @@ -2671,7 +2669,7 @@ struct commit { }; static bool -main_draw(struct view *view, struct line *line, unsigned int lineno) +main_draw(struct view *view, struct line *line, unsigned int lineno, bool selected) { char buf[DATE_COLS + 1]; struct commit *commit = line->data; @@ -2686,7 +2684,7 @@ main_draw(struct view *view, struct line *line, unsigned int lineno) wmove(view->win, lineno, col); - if (view->offset + lineno == view->lineno) { + if (selected) { type = LINE_CURSOR; wattrset(view->win, get_line_attr(type)); wchgat(view->win, -1, 0, type, NULL);