If the terminal LOCALE is set to UTF-8, isprint() considers the first
UTF-8 sequence as printable which makes Mg to print one invisible
character and the rest of a UTF-8 sequence as \octal. Instead, we can
print isascii() bytes, and display everything else -- except control
characters -- as \octal. Moreover, counting each control character
(e.g ^@) or \octal (e.g. \342) as one column would improve the
navigation and/or editing of non-ASCII bytes.
The following diff also includes minor refactoring.
OK?
diff --git a/basic.c b/basic.c
index 251e7e8..9aa890f 100644
--- a/basic.c
+++ b/basic.c
@@ -288,7 +288,7 @@ getgoal(struct line *dlp)
&& !(curbp->b_flag & BFNOTAB)
#endif
) {
- col |= 0x07;
+ col |= TABMASK;
col++;
} else if (ISCTRL(c) != FALSE) {
col += 2;
diff --git a/cmode.c b/cmode.c
index 46bd602..1f12fa3 100644
--- a/cmode.c
+++ b/cmode.c
@@ -244,7 +244,7 @@ getindent(const struct line *lp, int *curi)
&& !(curbp->b_flag & BFNOTAB)
#endif /* NOTAB */
) {
- nicol |= 0x07;
+ nicol |= TABMASK;
}
nicol++;
}
@@ -413,7 +413,7 @@ findcolpos(const struct buffer *bp, const struct line *lp,
int lo)
&& !(bp->b_flag & BFNOTAB)
#endif /* NOTAB */
) {
- col |= 0x07;
+ col |= TABMASK;
col++;
} else if (ISCTRL(c) != FALSE)
col += 2;
diff --git a/def.h b/def.h
index a4b7bee..13b54af 100644
--- a/def.h
+++ b/def.h
@@ -40,6 +40,7 @@ typedef int (*PF)(int, int); /* generally useful
type */
#define REVERT 4 /* Revert the buffer */
#define KCLEAR 2 /* clear echo area */
+#define TABMASK 0x7 /* tab width mask */
/*
* These flag bits keep track of
diff --git a/display.c b/display.c
index 888f33f..41493dd 100644
--- a/display.c
+++ b/display.c
@@ -53,7 +53,7 @@ struct score {
void vtmove(int, int);
void vtputc(int);
-void vtpute(int);
+void vtputl(struct line *);
int vtputs(const char *);
void vteeol(void);
void updext(int, int);
@@ -326,13 +326,15 @@ vtputc(int c)
) {
do {
vtputc(' ');
- } while (vtcol < ncol && (vtcol & 0x07) != 0);
+ } while (vtcol < ncol && ((vtcol + lbound) & TABMASK) != 0);
} else if (ISCTRL(c)) {
vtputc('^');
vtputc(CCHR(c));
- } else if (isprint(c))
- vp->v_text[vtcol++] = c;
- else {
+ } else if (isascii(c)) {
+ if (vtcol >= 0)
+ vp->v_text[vtcol] = c;
+ vtcol++;
+ } else {
char bf[5];
snprintf(bf, sizeof(bf), "\\%o", c);
@@ -341,42 +343,28 @@ vtputc(int c)
}
/*
- * Put a character to the virtual screen in an extended line. If we are not
- * yet on left edge, don't print it yet. Check for overflow on the right
- * margin.
+ * Output the content of a line pointer.
*/
void
-vtpute(int c)
-{
- struct video *vp;
-
- c &= 0xff;
+vtputl(struct line *lp) {
+ int i;
+ for (i = 0; i < llength(lp); i++)
+ vtputc(lgetc(lp, i));
+}
- vp = vscreen[vtrow];
- if (vtcol >= ncol)
- vp->v_text[ncol - 1] = '$';
- else if (c == '\t'
-#ifdef NOTAB
- && !(curbp->b_flag & BFNOTAB)
-#endif
- ) {
- do {
- vtpute(' ');
- } while (((vtcol + lbound) & 0x07) != 0 && vtcol < ncol);
- } else if (ISCTRL(c) != FALSE) {
- vtpute('^');
- vtpute(CCHR(c));
- } else if (isprint(c)) {
- if (vtcol >= 0)
- vp->v_text[vtcol] = c;
- ++vtcol;
- } else {
- char bf[5], *cp;
+/*
+ * Output a string, and report how long it was.
+ */
+int
+vtputs(const char *s)
+{
+ int n = 0;
- snprintf(bf, sizeof(bf), "\\%o", c);
- for (cp = bf; *cp != '\0'; cp++)
- vtpute(*cp);
+ while (*s != '\0') {
+ vtputc(*s++);
+ ++n;
}
+ return (n);
}
/*
@@ -410,7 +398,7 @@ update(int modelinecolor)
struct mgwin *wp;
struct video *vp1;
struct video *vp2;
- int c, i, j;
+ int c, i;
int hflag;
int currow, curcol;
int offs, size;
@@ -485,8 +473,7 @@ update(int modelinecolor)
vscreen[i]->v_color = CTEXT;
vscreen[i]->v_flag |= (VFCHG | VFHBAD);
vtmove(i, 0);
- for (j = 0; j < llength(lp); ++j)
- vtputc(lgetc(lp, j));
+ vtputl(lp);
vteeol();
} else if ((wp->w_rflag & (WFEDIT | WFFULL)) != 0) {
hflag = TRUE;
@@ -495,8 +482,7 @@ update(int modelinecolor)
vscreen[i]->v_flag |= (VFCHG | VFHBAD);
vtmove(i, 0);
if (lp != wp->w_bufp->b_headp) {
- for (j = 0; j < llength(lp); ++j)
- vtputc(lgetc(lp, j));
+ vtputl(lp);
lp = lforw(lp);
}
vteeol();
@@ -523,11 +509,11 @@ update(int modelinecolor)
&& !(curbp->b_flag & BFNOTAB)
#endif
) {
- curcol |= 0x07;
+ curcol |= TABMASK;
curcol++;
- } else if (ISCTRL(c) != FALSE)
+ } else if (ISCTRL(c))
curcol += 2;
- else if (isprint(c))
+ else if (isascii(c))
curcol++;
else {
char bf[5];
@@ -558,8 +544,7 @@ update(int modelinecolor)
if ((wp != curwp) || (lp != wp->w_dotp) ||
(curcol < ncol - 1)) {
vtmove(i, 0);
- for (j = 0; j < llength(lp); ++j)
- vtputc(lgetc(lp, j));
+ vtputl(lp);
vteeol();
/* this line no longer is extended */
vscreen[i]->v_flag &= ~VFEXT;
@@ -673,7 +658,6 @@ void
updext(int currow, int curcol)
{
struct line *lp; /* pointer to current line */
- int j; /* index into line */
if (ncol < 2)
return;
@@ -690,8 +674,7 @@ updext(int currow, int curcol)
*/
vtmove(currow, -lbound); /* start scanning offscreen */
lp = curwp->w_dotp; /* line to output */
- for (j = 0; j < llength(lp); ++j) /* until the end-of-line */
- vtpute(lgetc(lp, j));
+ vtputl(lp); /* until the end-of-line */
vteeol(); /* truncate the virtual line */
vscreen[currow]->v_text[0] = '$'; /* and put a '$' in column 1 */
}
@@ -863,21 +846,6 @@ modeline(struct mgwin *wp, int modelinecolor)
}
}
-/*
- * Output a string to the mode line, report how long it was.
- */
-int
-vtputs(const char *s)
-{
- int n = 0;
-
- while (*s != '\0') {
- vtputc(*s++);
- ++n;
- }
- return (n);
-}
-
/*
* Compute the hash code for the line pointed to by the "vp".
* Recompute it if necessary. Also set the approximate redisplay
diff --git a/kbd.c b/kbd.c
index 2015a8b..0734658 100644
--- a/kbd.c
+++ b/kbd.c
@@ -19,7 +19,7 @@
#include "log.h"
#endif
-#define METABIT 0x80
+#define METABIT 0x800
#define PROMPTL 80
char prompt[PROMPTL] = "", *promptp = prompt;
diff --git a/match.c b/match.c
index 32a2fd0..aaa5199 100644
--- a/match.c
+++ b/match.c
@@ -181,7 +181,7 @@ displaymatch(struct line *clp, int cbo)
else
do {
buf[bufo++] = ' ';
- } while (bufo & 7);
+ } while (bufo & TABMASK);
}
buf[bufo++] = '\0';
ewprintf("Matches %s", buf);
diff --git a/paragraph.c b/paragraph.c
index 694fcc9..0efdea1 100644
--- a/paragraph.c
+++ b/paragraph.c
@@ -424,7 +424,7 @@ fillword(int f, int n)
&& !(curbp->b_flag & BFNOTAB)
#endif
)
- col |= 0x07;
+ col |= TABMASK;
else if (ISCTRL(c) != FALSE)
++col;
}
diff --git a/util.c b/util.c
index 4d38284..955750b 100644
--- a/util.c
+++ b/util.c
@@ -94,7 +94,6 @@ int
getcolpos(struct mgwin *wp)
{
int col, i, c;
- char tmp[5];
/* determine column */
col = 0;
@@ -105,16 +104,9 @@ getcolpos(struct mgwin *wp)
#ifdef NOTAB
&& !(wp->w_bufp->b_flag & BFNOTAB)
#endif /* NOTAB */
- ) {
- col |= 0x07;
- col++;
- } else if (ISCTRL(c) != FALSE)
- col += 2;
- else if (isprint(c)) {
- col++;
- } else {
- col += snprintf(tmp, sizeof(tmp), "\\%o", c);
- }
+ )
+ col |= TABMASK;
+ col++;
}
return (col);
@@ -370,7 +362,7 @@ lfindent(int f, int n)
if (c != ' ' && c != '\t')
break;
if (c == '\t')
- nicol |= 0x07;
+ nicol |= TABMASK;
++nicol;
}
if (lnewline() == FALSE || ((