Download raw body.
tog: fix horizontal scrolling of unicode in the diff view
Stefan Sperling <stsp@stsp.name> wrote:
> Fix horizontal scrolling of unicode in the diff view. This makes
> the diff in my ja.git test repo scroll properly.
>
> Turns out we need another output parameter in format_line() for
> this case. draw_file() needs to know the width of the unscrolled
> version of each line in order to set view->maxx correctly.
>
> ok?
yep, it reads fine.
> diff 3a8eb03e7089a4869bb33afa6dc90d2b9d4c2c70 7c4eb5ef2ddd2fc6b8127a6b4746081efcb1411c
> blob - 285021accb225e5cc858097d09e1a68d4b32e1ca
> blob + 4b3a42b896e6f4177b004831b046fa812308b489
> --- tog/tog.c
> +++ tog/tog.c
> @@ -1262,7 +1262,7 @@ expand_tab(char **ptr, const char *src)
> * 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,
> +scroll_wline(int *scrollx, int *widthp, wchar_t *wline, int nscroll,
> int col_tab_align)
> {
> int cols = 0;
> @@ -1301,27 +1301,34 @@ scroll_wline(int *scrollx , wchar_t *wline, int nscrol
> }
>
> *scrollx = i;
> + *widthp = cols;
> 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.
> + * With scrolling, the width returned in *scrolled_widthp 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,
> +format_line(wchar_t **wlinep, int *widthp, int *scrollxp, int *scrolled_widthp,
> const char *line, int nscroll, int wlimit, int col_tab_align, int expand)
> {
> const struct got_error *err = NULL;
> - int cols = 0;
> + int cols = 0, skipped_cols = 0;
> wchar_t *wline = NULL;
> char *exstr = NULL;
> size_t wlen;
> int i, scrollx = 0;
>
> *wlinep = NULL;
> - *widthp = 0;
> + if (widthp)
> + *widthp = 0;
> + if (scrollxp)
> + *scrollxp = 0;
> + if (scrolled_widthp)
> + *scrolled_widthp = 0;
>
> if (expand) {
> err = expand_tab(&exstr, line);
> @@ -1334,7 +1341,8 @@ format_line(wchar_t **wlinep, int *widthp, int *scroll
> if (err)
> return err;
>
> - err = scroll_wline(&scrollx, wline, nscroll, col_tab_align);
> + err = scroll_wline(&scrollx, &skipped_cols, wline, nscroll,
> + col_tab_align);
> if (err)
> goto done;
>
> @@ -1380,9 +1388,11 @@ format_line(wchar_t **wlinep, int *widthp, int *scroll
> }
> wline[i] = L'\0';
> if (widthp)
> - *widthp = cols;
> + *widthp = skipped_cols + cols;
> if (scrollxp)
> *scrollxp = scrollx;
> + if (scrolled_widthp)
> + *scrolled_widthp = cols;
> done:
> if (err)
> free(wline);
> @@ -1469,7 +1479,7 @@ 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, NULL, author, 0, limit,
> + return format_line(wauthor, author_width, NULL, NULL, author, 0, limit,
> col_tab_align, 0);
> }
>
> @@ -1568,8 +1578,8 @@ draw_commit(struct tog_view *view, struct got_commit_o
> if (newline)
> *newline = '\0';
> limit = avail - col;
> - err = format_line(&wlogmsg, &logmsg_width, &scrollx, logmsg, view->x,
> - limit, col, 1);
> + err = format_line(&wlogmsg, NULL, &scrollx, &logmsg_width,
> + logmsg, view->x, limit, col, 1);
> if (err)
> goto done;
> waddwstr(view->window, &wlogmsg[scrollx]);
> @@ -1810,7 +1820,8 @@ draw_commits(struct tog_view *view)
> header = NULL;
> goto done;
> }
> - err = format_line(&wline, &width, NULL, header, 0, view->ncols, 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, header, 0, view->ncols,
> + 0, 0);
> if (err)
> goto done;
>
> @@ -1865,7 +1876,7 @@ draw_commits(struct tog_view *view)
> ++msg;
> if ((eol = strchr(msg, '\n')))
> *eol = '\0';
> - err = format_line(&wmsg, &width, NULL, msg, 0, INT_MAX,
> + err = format_line(&wmsg, &width, NULL, NULL, msg, 0, INT_MAX,
> date_display_cols + author_cols, 0);
> if (err)
> goto done;
> @@ -3126,7 +3137,7 @@ add_matched_line(int *wtotal, const char *line, int wl
> rms = regmatch->rm_so;
> rme = regmatch->rm_eo;
>
> - err = format_line(&wline, &width, NULL, line, 0, wlimit + skip,
> + err = format_line(&wline, &width, NULL, NULL, line, 0, wlimit + skip,
> col_tab_align, 1);
> if (err)
> return err;
> @@ -3196,8 +3207,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, NULL, line, 0, view->ncols,
> - 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, line, 0,
> + view->ncols, 0, 0);
> free(line);
> if (err)
> return err;
> @@ -3231,8 +3242,6 @@ draw_file(struct tog_view *view, const char *header)
> return got_ferror(s->f, GOT_ERR_IO);
> }
>
> - view->maxx = MAX(view->maxx, linelen);
> -
> tc = match_color(&s->colors, line);
> if (tc)
> wattr_on(view->window,
> @@ -3246,23 +3255,25 @@ draw_file(struct tog_view *view, const char *header)
> return err;
> }
> } else {
> - err = format_line(&wline, &width, NULL, line, 0,
> - view->x + view->ncols, 0, view->x ? 1 : 0);
> + int skip, fullwidth;
> + err = format_line(&wline, &fullwidth, &skip, &width,
> + line, view->x, view->ncols, 0, view->x ? 1 : 0);
> if (err) {
> free(line);
> return err;
> }
> - if (view->x < width)
> - waddwstr(view->window, wline + view->x);
> + view->maxx = MAX(view->maxx, fullwidth);
> + waddwstr(view->window, &wline[skip]);
> free(wline);
> wline = NULL;
> }
> if (tc)
> wattr_off(view->window,
> COLOR_PAIR(tc->colorpair), NULL);
> - if (width - view->x <= view->ncols - 1)
> + if (width <= view->ncols - 1)
> waddch(view->window, '\n');
> nprinted++;
> +
> }
> free(line);
> if (nprinted >= 1)
> @@ -3279,7 +3290,7 @@ draw_file(struct tog_view *view, const char *header)
> nprinted++;
> }
>
> - err = format_line(&wline, &width, NULL, TOG_EOF_STRING, 0,
> + err = format_line(&wline, &width, NULL, NULL, TOG_EOF_STRING, 0,
> view->ncols, 0, 0);
> if (err) {
> return err;
> @@ -4279,7 +4290,8 @@ draw_blame(struct tog_view *view)
> return err;
> }
>
> - err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, line, 0, view->ncols,
> + 0, 0);
> free(line);
> line = NULL;
> if (err)
> @@ -4308,7 +4320,8 @@ draw_blame(struct tog_view *view)
> return got_error_from_errno("asprintf");
> }
> free(id_str);
> - err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, line, 0, view->ncols,
> + 0, 0);
> free(line);
> line = NULL;
> if (err)
> @@ -4395,7 +4408,7 @@ draw_blame(struct tog_view *view)
> }
> width += 9;
> } else {
> - err = format_line(&wline, &width, NULL, line, 0,
> + err = format_line(&wline, &width, NULL, NULL, line, 0,
> view->x + view->ncols - 9, 9, 1);
> if (err) {
> free(line);
> @@ -5273,8 +5286,8 @@ draw_tree_entries(struct tog_view *view, const char *p
> if (limit == 0)
> return NULL;
>
> - err = format_line(&wline, &width, NULL, s->tree_label, 0, view->ncols,
> - 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, s->tree_label, 0,
> + view->ncols, 0, 0);
> if (err)
> return err;
> if (view_needs_focus_indication(view))
> @@ -5295,8 +5308,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, NULL, parent_path, 0, view->ncols,
> - 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, parent_path, 0,
> + view->ncols, 0, 0);
> if (err)
> return err;
> waddwstr(view->window, wline);
> @@ -5376,8 +5389,8 @@ draw_tree_entries(struct tog_view *view, const char *p
> }
> free(id_str);
> free(link_target);
> - err = format_line(&wline, &width, NULL, line, 0, view->ncols,
> - 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, line, 0,
> + view->ncols, 0, 0);
> if (err) {
> free(line);
> break;
> @@ -6488,7 +6501,8 @@ show_ref_view(struct tog_view *view)
> s->nrefs) == -1)
> return got_error_from_errno("asprintf");
>
> - err = format_line(&wline, &width, NULL, line, 0, view->ncols, 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, line, 0, view->ncols,
> + 0, 0);
> if (err) {
> free(line);
> return err;
> @@ -6575,8 +6589,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, NULL, line, 0, view->ncols,
> - 0, 0);
> + err = format_line(&wline, &width, NULL, NULL, line, 0,
> + view->ncols, 0, 0);
> if (err) {
> free(line);
> return err;
tog: fix horizontal scrolling of unicode in the diff view