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

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: [rfc] tog horizontal scroll (diff & blame view)
To:
Mark Jamsek <mark@jamsek.com>, gameoftrees@openbsd.org
Date:
Thu, 16 Jun 2022 10:47:05 +0200

Download raw body.

Thread
On Thu, Jun 16, 2022 at 10:29:20AM +0200, Stefan Sperling wrote:
> Such issues also exists elsewhere. Try the attached repo which contains
> some text from today's index page of ja.wikipedia.org. There are some
> rendering issues to be observed, probably because substracting view->x
> doesn't do the right thing in Japanese.
> 
> I'll try to come up with some fixes, but don't hesitate to take a look
> if you have time :)

This fixes horizontal scrolling of japanese text in the log view.

I noticed that wcswidth() can be used instead of my hand-rolled
loop I added for the blame fix, so a change to reduce this loop
to wcswidth() is included as well.

diff 67461ab571e3ce9157e4a0cc09e2d632cd6f3263 8a5113cff911108d74d44f7fcb49d82920b128ed
blob - 8a28476cd4abc2585e93d816ed8368b82925038b
blob + 6949c6919a312d1d0e9ca87dc38ed6cf1d766d5a
--- tog/tog.c
+++ tog/tog.c
@@ -1514,11 +1514,12 @@ draw_commit(struct tog_view *view, struct got_commit_o
 	err = format_line(&wlogmsg, &logmsg_width, logmsg, limit, col, 1);
 	if (err)
 		goto done;
-	if (view->x < logmsg_width - 1)
+	if (view->x < logmsg_width - 1) {
 		waddwstr(view->window, wlogmsg + view->x);
-	else
+		logmsg_width -= wcswidth(wlogmsg, view->x);
+	} else
 		logmsg_width = 0;
-	col += MAX(logmsg_width - view->x, 0);
+	col += MAX(logmsg_width, 0);
 	while (col < avail) {
 		waddch(view->window, ' ');
 		col++;
@@ -1786,8 +1787,8 @@ draw_commits(struct tog_view *view)
 	ncommits = 0;
 	view->maxx = 0;
 	while (entry) {
-		char *author, *eol, *msg, *msg0;
-		wchar_t *wauthor;
+		char *author, *msg;
+		wchar_t *wauthor, *wmsg, *eol;
 		int width;
 		if (ncommits >= limit - 1)
 			break;
@@ -1802,17 +1803,22 @@ draw_commits(struct tog_view *view)
 			author_cols = width;
 		free(wauthor);
 		free(author);
-		err = got_object_commit_get_logmsg(&msg0, entry->commit);
+		err = got_object_commit_get_logmsg(&msg, entry->commit);
 		if (err)
 			goto done;
-		msg = msg0;
-		while (*msg == '\n')
-			++msg;
-		if ((eol = strchr(msg, '\n')))
-			view->maxx = MAX(view->maxx, eol - msg);
-		else
-			view->maxx = MAX(view->maxx, strlen(msg));
-		free(msg0);
+		err = format_line(&wmsg, &width, msg, COLS,
+		    date_display_cols + author_cols, 0);
+		if (err)
+			goto done;
+		while (*wmsg == L'\n')
+			++wmsg;
+		if ((eol = wcschr(wmsg, L'\n'))) {
+			*eol = L'\0';
+			width = wcswidth(wmsg, width);
+		}
+		view->maxx = MAX(view->maxx, wcswidth(wmsg, wcslen(wmsg)));
+		free(msg);
+		free(wmsg);
 		ncommits++;
 		entry = TAILQ_NEXT(entry, entry);
 	}
@@ -4190,7 +4196,7 @@ draw_blame(struct tog_view *view)
 	struct tog_blame *blame = &s->blame;
 	regmatch_t *regmatch = &view->regmatch;
 	const struct got_error *err;
-	int lineno = 0, nprinted = 0, i;
+	int lineno = 0, nprinted = 0;
 	char *line = NULL;
 	size_t linesize = 0;
 	ssize_t linelen;
@@ -4338,8 +4344,7 @@ draw_blame(struct tog_view *view)
 			}
 			if (view->x < width) {
 				waddwstr(view->window, wline + view->x);
-				for (i = 0; i < view->x; i++)
-					width -= wcwidth(wline[i]);
+				width -= wcswidth(wline, view->x);
 			}
 			width += 9;
 			free(wline);