Download raw body.
[rfc] tog horizontal scroll (diff & blame view)
Stefan Sperling <stsp@stsp.name> wrote: > On Thu, Jun 16, 2022 at 01:38:16PM +0200, Stefan Sperling wrote: > > On Thu, Jun 16, 2022 at 09:16:05PM +1000, Mark Jamsek wrote: > > > On 22-06-16 12:33pm, Stefan Sperling wrote: > > > > This new helper could be part of format_line(), but for now I wanted > > > > to keep it seperate. Otherwise I would need to update all existing > > > > callers of format_line() in the same patch. > > > > > > > > > > I think that's a good idea too; it makes sense doing this in > > > format_line(). > > > > Yes, I'll try to this later once things have settled a bit. > > Well, why not do it now. > > Having this functionality built into format_line() should make it > easier to fix the other views for unicode. > > ok? sure, makes sense to do that; it's a rather mechanical change too for the most part. ok op@ (nit: double empty line between scroll_wline and format_line) > diff c05b27d80ffca42064176ccd557158bf67877943 0a40cff8c4fcef71b9eaf004224753b94cd426b0 > blob - 61e731b74f838cf2b8072f3655e745a29b6c673f > blob + 8f9d4366f97c12983f70c237ca107a52f835a2d9 > --- tog/tog.c > +++ tog/tog.c > @@ -1257,17 +1257,69 @@ expand_tab(char **ptr, const char *src) > return NULL; > } > > -/* Format a line for display, ensuring that it won't overflow a width limit. */ > +/* > + * 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 * > -format_line(wchar_t **wlinep, int *widthp, const char *line, int wlimit, > - int col_tab_align, int expand) > +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; > @@ -1283,6 +1335,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--; > @@ -1292,7 +1348,7 @@ format_line(wchar_t **wlinep, int *widthp, const char > wlen--; > } > > - i = 0; > + i = scrollx; > while (i < wlen) { > int width = wcwidth(wline[i]); > > @@ -1326,6 +1382,8 @@ 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); > @@ -1334,51 +1392,6 @@ done: > 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* > build_refs_str(char **refs_str, struct got_reflist_head *refs, > struct got_object_id *id, struct got_repository *repo) > @@ -1457,8 +1470,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 * > @@ -1471,10 +1484,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; > @@ -1555,15 +1568,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); > + limit = avail - col; > + err = format_line(&wlogmsg, &logmsg_width, &scrollx, logmsg, view->x, > + limit, col, 1); > if (err) > goto done; > - err = scroll_wline(&scrolled_wline, wlogmsg, view->x, col); > - 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, ' '); > @@ -1801,7 +1811,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; > > @@ -1856,7 +1866,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; > @@ -3117,7 +3127,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; > @@ -3187,7 +3197,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; > @@ -3236,7 +3247,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); > @@ -3269,8 +3280,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; > } > @@ -4269,7 +4280,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) > @@ -4298,7 +4309,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) > @@ -4385,7 +4396,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); > @@ -5263,7 +5274,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)) > @@ -5284,7 +5296,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); > @@ -5364,7 +5377,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; > @@ -6475,7 +6489,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; > @@ -6562,7 +6576,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;
[rfc] tog horizontal scroll (diff & blame view)