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

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

Download raw body.

Thread
On Thu, Jun 16, 2022 at 05:46:24PM +0200, Stefan Sperling wrote:
> As you noted, this patch breaks the '$' key in the diff view.
> 
> I will need some more time to investigate and find a proper fix.

Here is a much simpler version which seems to work better.

Instead of complicating format_line() even further, we can let
draw_file() run it twice, each time with different parameters.
This way draw_file() can get all the required information.

Neither this version nor the old version of this patch fixes
the search highlighting case yet. That will come later.

ok?

diff 37e2dd76febe5755b17ee08be3ca2547b4765c87 3714876751901b56caaa1a0f030bc190cb5addaf
blob - ce1b254e1f4ae519df700e3c27df76b82dc3d652
blob + 34234f43c9ed0ca69cafef58339f81769b9fcc06
--- tog/tog.c
+++ tog/tog.c
@@ -3237,8 +3237,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,
@@ -3251,22 +3249,38 @@ draw_file(struct tog_view *view, const char *header)
 				free(line);
 				return err;
 			}
+			view->maxx = MAX(view->maxx, width);
 		} else {
-			err = format_line(&wline, &width, NULL, line, 0,
-			    view->x + view->ncols, 0, view->x ? 1 : 0);
+			int skip;
+
+			/* Set view->maxx based on full line length. */
+			err = format_line(&wline, &width, NULL, line,
+			    0, INT_MAX, 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, width);
+
+			/*
+			 * Get a new version of the line for display.
+			 * This will be scrolled and/or trimmed in length.
+			 */
 			free(wline);
+			err = format_line(&wline, &width, &skip, line,
+			    view->x, view->ncols, 0, view->x ? 1 : 0);
+			if (err) {
+				free(line);
+				return err;
+			}
+			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++;
 	}