"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Omar Polo <op@omarpolo.com>
Subject:
Re: tog: fix horizontal scrolling of unicode in the diff view
To:
Stefan Sperling <stsp@stsp.name>
Cc:
gameoftrees@openbsd.org
Date:
Thu, 16 Jun 2022 16:49:03 +0200

Download raw body.

Thread
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;