commit f91a2b483b4be113fca62a06cd1c43795052af81 from: Stefan Sperling via: Thomas Adam date: Thu Jun 23 14:09:34 2022 UTC move horizontal line scrolling logic into format_line() for easier reuse ok op@ commit - 4122562d732f642d4fe4f5926b534508f2336155 commit + f91a2b483b4be113fca62a06cd1c43795052af81 blob - ef11f62ccd355dfd3ed47b46417d6dbebb0c8a6a blob + 8fe2c6de3560c3d5226e2d23a8e6dd5b3abb381f --- tog/tog.c +++ tog/tog.c @@ -1264,17 +1264,68 @@ expand_tab(char **ptr, const char *src) return NULL; } -/* Format a line for display, ensuring that it won't overflow a width limit. */ -static const struct got_error * -format_line(wchar_t **wlinep, int *widthp, const char *line, int wlimit, - int col_tab_align, int expand) +/* + * Skip leading nscroll columns of a wide character string. + * Returns the index to the first character of the scrolled string. + */ +static const struct got_error * +scroll_wline(int *scrollx , wchar_t *wline, int nscroll, + int col_tab_align) { + int cols = 0; + size_t wlen = wcslen(wline); + int i = 0; + + *scrollx = 0; + + while (i < wlen && cols < nscroll) { + int width = wcwidth(wline[i]); + + if (width == 0) { + i++; + continue; + } + + if (width == 1 || width == 2) { + if (cols + width > nscroll) + break; + cols += width; + i++; + } else if (width == -1) { + if (wline[i] == L'\t') { + width = TABSIZE - + ((cols + col_tab_align) % TABSIZE); + } else { + width = 1; + wline[i] = L'.'; + } + if (cols + width > nscroll) + break; + cols += width; + i++; + } else + return got_error_from_errno("wcwidth"); + } + + *scrollx = i; + return NULL; +} + +/* + * Format a line for display, ensuring that it won't overflow a width limit. + * With scrolling, the width returned refers to the scrolled version of the + * line, which starts at (*wlinep)[*scrollxp]. The caller must free *wlinep. + */ +static const struct got_error * +format_line(wchar_t **wlinep, int *widthp, int *scrollxp, + const char *line, int nscroll, int wlimit, int col_tab_align, int expand) +{ const struct got_error *err = NULL; int cols = 0; wchar_t *wline = NULL; char *exstr = NULL; size_t wlen; - int i; + int i, scrollx = 0; *wlinep = NULL; *widthp = 0; @@ -1290,6 +1341,10 @@ format_line(wchar_t **wlinep, int *widthp, const char if (err) return err; + err = scroll_wline(&scrollx, wline, nscroll, col_tab_align); + if (err) + goto done; + if (wlen > 0 && wline[wlen - 1] == L'\n') { wline[wlen - 1] = L'\0'; wlen--; @@ -1299,7 +1354,7 @@ format_line(wchar_t **wlinep, int *widthp, const char wlen--; } - i = 0; + i = scrollx; while (i < wlen) { int width = wcwidth(wline[i]); @@ -1333,57 +1388,14 @@ format_line(wchar_t **wlinep, int *widthp, const char wline[i] = L'\0'; if (widthp) *widthp = cols; + if (scrollxp) + *scrollxp = scrollx; done: if (err) free(wline); else *wlinep = wline; return err; -} - -/* Skip the leading nscroll columns of a wide character string. */ -const struct got_error * -scroll_wline(wchar_t **wlinep, wchar_t *wline, int nscroll, - int col_tab_align) -{ - int cols = 0; - size_t wlen = wcslen(wline); - int i = 0, j = 0; - - *wlinep = wline; - - while (i < wlen && cols < nscroll) { - int width = wcwidth(wline[i]); - - if (width == 0) { - i++; - continue; - } - - if (width == 1 || width == 2) { - if (cols + width > nscroll) - break; - cols += width; - i++; - } else if (width == -1) { - if (wline[i] == L'\t') { - width = TABSIZE - - ((cols + col_tab_align) % TABSIZE); - } else { - width = 1; - wline[i] = L'.'; - } - if (cols + width > nscroll) - break; - cols += width; - i++; - } else - return got_error_from_errno("wcwidth"); - j++; - } - - *wlinep = &wline[j]; - return NULL; } static const struct got_error* @@ -1464,8 +1476,8 @@ format_author(wchar_t **wauthor, int *author_width, ch if (smallerthan && smallerthan[1] != '\0') author = smallerthan + 1; author[strcspn(author, "@>")] = '\0'; - return format_line(wauthor, author_width, author, limit, col_tab_align, - 0); + return format_line(wauthor, author_width, NULL, author, 0, limit, + col_tab_align, 0); } static const struct got_error * @@ -1478,10 +1490,10 @@ draw_commit(struct tog_view *view, struct got_commit_o char datebuf[12]; /* YYYY-MM-DD + SPACE + NUL */ char *logmsg0 = NULL, *logmsg = NULL; char *author = NULL; - wchar_t *wlogmsg = NULL, *wauthor = NULL, *scrolled_wline; + wchar_t *wlogmsg = NULL, *wauthor = NULL; int author_width, logmsg_width; char *newline, *line = NULL; - int col, limit; + int col, limit, scrollx; const int avail = view->ncols; struct tm tm; time_t committer_time; @@ -1562,15 +1574,12 @@ draw_commit(struct tog_view *view, struct got_commit_o newline = strchr(logmsg, '\n'); if (newline) *newline = '\0'; - limit = view->x + avail - col; - err = format_line(&wlogmsg, &logmsg_width, logmsg, limit, col, 1); - if (err) - goto done; - err = scroll_wline(&scrolled_wline, wlogmsg, view->x, col); + limit = avail - col; + err = format_line(&wlogmsg, &logmsg_width, &scrollx, logmsg, view->x, + limit, col, 1); if (err) goto done; - waddwstr(view->window, scrolled_wline); - logmsg_width = wcswidth(scrolled_wline, wcslen(scrolled_wline)); + waddwstr(view->window, &wlogmsg[scrollx]); col += MAX(logmsg_width, 0); while (col < avail) { waddch(view->window, ' '); @@ -1808,7 +1817,7 @@ draw_commits(struct tog_view *view) header = NULL; goto done; } - err = format_line(&wline, &width, header, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, header, 0, view->ncols, 0, 0); if (err) goto done; @@ -1863,7 +1872,7 @@ draw_commits(struct tog_view *view) ++msg; if ((eol = strchr(msg, '\n'))) *eol = '\0'; - err = format_line(&wmsg, &width, msg, INT_MAX, + err = format_line(&wmsg, &width, NULL, msg, 0, INT_MAX, date_display_cols + author_cols, 0); if (err) goto done; @@ -3126,7 +3135,7 @@ add_matched_line(int *wtotal, const char *line, int wl rms = regmatch->rm_so; rme = regmatch->rm_eo; - err = format_line(&wline, &width, line, wlimit + skip, + err = format_line(&wline, &width, NULL, line, 0, wlimit + skip, col_tab_align, 1); if (err) return err; @@ -3196,7 +3205,8 @@ draw_file(struct tog_view *view, const char *header) s->first_displayed_line - 1 + s->selected_line, nlines, header) == -1) return got_error_from_errno("asprintf"); - err = format_line(&wline, &width, line, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, line, 0, view->ncols, + 0, 0); free(line); if (err) return err; @@ -3245,7 +3255,7 @@ draw_file(struct tog_view *view, const char *header) return err; } } else { - err = format_line(&wline, &width, line, + err = format_line(&wline, &width, NULL, line, 0, view->x + view->ncols, 0, view->x ? 1 : 0); if (err) { free(line); @@ -3278,8 +3288,8 @@ draw_file(struct tog_view *view, const char *header) nprinted++; } - err = format_line(&wline, &width, TOG_EOF_STRING, view->ncols, - 0, 0); + err = format_line(&wline, &width, NULL, TOG_EOF_STRING, 0, + view->ncols, 0, 0); if (err) { return err; } @@ -4278,7 +4288,7 @@ draw_blame(struct tog_view *view) return err; } - err = format_line(&wline, &width, line, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0); free(line); line = NULL; if (err) @@ -4307,7 +4317,7 @@ draw_blame(struct tog_view *view) return got_error_from_errno("asprintf"); } free(id_str); - err = format_line(&wline, &width, line, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0); free(line); line = NULL; if (err) @@ -4394,7 +4404,7 @@ draw_blame(struct tog_view *view) } width += 9; } else { - err = format_line(&wline, &width, line, + err = format_line(&wline, &width, NULL, line, 0, view->x + view->ncols - 9, 9, 1); if (err) { free(line); @@ -5272,7 +5282,8 @@ draw_tree_entries(struct tog_view *view, const char *p if (limit == 0) return NULL; - err = format_line(&wline, &width, s->tree_label, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, s->tree_label, 0, view->ncols, + 0, 0); if (err) return err; if (view_needs_focus_indication(view)) @@ -5293,7 +5304,8 @@ draw_tree_entries(struct tog_view *view, const char *p waddch(view->window, '\n'); if (--limit <= 0) return NULL; - err = format_line(&wline, &width, parent_path, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, parent_path, 0, view->ncols, + 0, 0); if (err) return err; waddwstr(view->window, wline); @@ -5373,7 +5385,8 @@ draw_tree_entries(struct tog_view *view, const char *p } free(id_str); free(link_target); - err = format_line(&wline, &width, line, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, line, 0, view->ncols, + 0, 0); if (err) { free(line); break; @@ -6484,7 +6497,7 @@ show_ref_view(struct tog_view *view) s->nrefs) == -1) return got_error_from_errno("asprintf"); - err = format_line(&wline, &width, line, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0); if (err) { free(line); return err; @@ -6571,7 +6584,8 @@ show_ref_view(struct tog_view *view) got_ref_get_name(re->ref)) == -1) return got_error_from_errno("asprintf"); - err = format_line(&wline, &width, line, view->ncols, 0, 0); + err = format_line(&wline, &width, NULL, line, 0, view->ncols, + 0, 0); if (err) { free(line); return err;