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)