Index | Thread | Search

From:
YASUOKA Masahiko <yasuoka@openbsd.org>
Subject:
watch: tab + holizontal scroll
To:
tedu@openbsd.org, job@openbsd.org
Cc:
tech@openbsd.org
Date:
Fri, 27 Jun 2025 13:40:54 +0900

Download raw body.

Thread
Hi,

More care about TAB spaces seems to be needed for scrolling
horizontally.

ok?

Index: usr.bin/watch/watch.c
===================================================================
RCS file: /cvs/src/usr.bin/watch/watch.c,v
diff -u -p -r1.32 watch.c
--- usr.bin/watch/watch.c	26 Jun 2025 21:34:45 -0000	1.32
+++ usr.bin/watch/watch.c	27 Jun 2025 04:37:59 -0000
@@ -85,8 +85,16 @@ time_t lastupdate;
 int xflag = 0;
 struct timespec prev_start, start, prev_stop, stop;
 
-#define	addwch(_x)	addnwstr(&(_x), 1);
-#define	WCWIDTH(_x)	((wcwidth((_x)) > 0)? wcwidth((_x)) : 1)
+#define	WCWIDTH(_c)	(wcwidth((_c)) > 0)? wcwidth((_c)) : 1
+#define	WCWIDTHX(_x, _c)					\
+	(((_c) == '\t')? TABSPACE - ((_x) % TABSPACE) : WCWIDTH(_c))
+#define ADDWCHX0(_x0, _c)					\
+	do {							\
+		if ((_c) != '\t' || ((_x0) % TABSPACE) == 0)	\
+			addnwstr(&(_c), 1);			\
+		else						\
+			addnstr("        ", 8); /* untabify */	\
+	} while (0)
 
 static char	 *cmdstr;
 static size_t	  cmdlen;
@@ -305,18 +313,19 @@ display(BUFFER * cur, BUFFER * prev, hig
 	for (line = start_line, screen_y = 2;
 	    screen_y < LINES && line < MAXLINE && (*cur)[line][0];
 	    line++, screen_y++) {
-		wchar_t	*cur_line, *prev_line, *p, *pp;
+		wchar_t	*cur_line, *prev_line, *p, *p0, *pp;
 
 		rl = 0;	/* reversing line */
 		cur_line = (*cur)[line];
 		prev_line = (*prev)[line];
 
 		for (p = cur_line, cw = 0; cw < start_column; p++)
-			cw += WCWIDTH(*p);
+			cw += WCWIDTHX(cw, *p);
 		screen_x = cw - start_column;
 		for (pp = prev_line, cw = 0; cw < start_column; pp++)
-			cw += WCWIDTH(*pp);
+			cw += WCWIDTHX(cw, *pp);
 
+		p0 = p;
 		switch (hm) {
 		case HIGHLIGHT_LINE:
 			if (wcscmp(cur_line, prev_line)) {
@@ -333,10 +342,11 @@ display(BUFFER * cur, BUFFER * prev, hig
 			move(screen_y, screen_x);
 			while (screen_x < COLS) {
 				if (*p && *p != L'\n') {
-					cw = wcwidth(*p);
+					cw = WCWIDTHX(screen_x, *p);
 					if (screen_x + cw >= COLS)
 						break;
-					addwch(*p++);
+					ADDWCHX0(start_column, *p);
+					p++;
 					pp++;
 					screen_x += cw;
 				} else if (rl) {
@@ -352,14 +362,12 @@ display(BUFFER * cur, BUFFER * prev, hig
 		case HIGHLIGHT_CHAR:
 			move(screen_y, screen_x);
 			while (*p && screen_x < COLS) {
-				if (*p == '\t')
-					cw = TABSPACE - (screen_x % TABSPACE);
-				else
-					cw = wcwidth(*p);
+				cw = WCWIDTHX(screen_x, *p);
 				if (screen_x + cw >= COLS)
 					break;
 				if (*p == *pp) {
-					addwch(*p++);
+					ADDWCHX0(start_column, *p);
+					p++;
 					pp++;
 					screen_x += cw;
 					continue;
@@ -370,19 +378,19 @@ display(BUFFER * cur, BUFFER * prev, hig
 				 * back to the beginning of the word.
 				 */
 				if (hm == HIGHLIGHT_WORD && !iswspace(*p)) {
-					while (cur_line + start_column < p &&
-					    !iswspace(*(p - 1))) {
+					while (p0 < p && !iswspace(*(p - 1))) {
 						p--;
 						pp--;
-						screen_x -= wcwidth(*p);
+						screen_x -= WCWIDTH(*p);
 					}
 					move(screen_y, screen_x);
-					cw = wcwidth(*p);
+					cw = WCWIDTH(*p);
 				}
 				standout();
 
 				/* Print character itself.  */
-				addwch(*p++);
+				ADDWCHX0(start_column, *p);
+				p++;
 				pp++;
 				screen_x += cw;
 
@@ -395,8 +403,9 @@ display(BUFFER * cur, BUFFER * prev, hig
 				if (hm == HIGHLIGHT_WORD) {
 					while (*p && !iswspace(*p) &&
 					    screen_x < COLS) {
-						cw = wcwidth(*p);
-						addwch(*p++);
+						cw = WCWIDTH(*p);
+						ADDWCHX0(start_column, *p);
+						p++;
 						pp++;
 						screen_x += cw;
 					}