-/* $OpenBSD: basic.c,v 1.53 2023/04/17 09:49:04 op Exp $ */
+/* $OpenBSD: basic.c,v 1.54 2023/04/21 13:39:36 op Exp $ */
/* This file is in the public domain */
for (i = 0; i < llength(dlp); i++) {
c = lgetc(dlp, i);
if (c == '\t') {
- col |= 0x07;
- col++;
+ col = ntabstop(col, curbp->b_tabw);
} else if (ISCTRL(c) != FALSE) {
col += 2;
} else if (isprint(c))
-/* $OpenBSD: buffer.c,v 1.113 2023/03/08 04:43:11 guenther Exp $ */
+/* $OpenBSD: buffer.c,v 1.114 2023/04/21 13:39:36 op Exp $ */
/* This file is in the public domain. */
static int usebufname(const char *);
+/* Default tab width */
+int defb_tabw = 8;
+
/* Flag for global working dir */
extern int globalwd;
+/*
+ * Set the tab width for the current buffer, or the default for new
+ * buffers if called with a prefix argument.
+ */
+int
+settabw(int f, int n)
+{
+ char buf[8], *bufp;
+ const char *errstr;
+
+ if (f & FFARG) {
+ if (n <= 0 || n > 16)
+ return (FALSE);
+ defb_tabw = n;
+ return (TRUE);
+ }
+
+ if ((bufp = eread("Tab Width: ", buf, sizeof(buf),
+ EFNUL | EFNEW | EFCR)) == NULL)
+ return (ABORT);
+ if (bufp[0] == '\0')
+ return (ABORT);
+ n = strtonum(buf, 1, 16, &errstr);
+ if (errstr)
+ return (dobeep_msgs("Tab width", errstr));
+ curbp->b_tabw = n;
+ curwp->w_rflag |= WFFRAME;
+ return (TRUE);
+}
+
int
togglereadonlyall(int f, int n)
{
bp->b_lines = 1;
bp->b_nlseq = "\n"; /* use unix default */
bp->b_nlchr = bp->b_nlseq;
+ bp->b_tabw = defb_tabw;
if ((bp->b_bname = strdup(bname)) == NULL) {
dobeep();
ewprintf("Can't get %d bytes", strlen(bname) + 1);
-/* $OpenBSD: cmode.c,v 1.21 2023/04/17 09:49:04 op Exp $ */
+/* $OpenBSD: cmode.c,v 1.22 2023/04/21 13:39:37 op Exp $ */
/*
* This file is in the public domain.
*
for (lo = 0; lo < llength(lp); lo++) {
if (!isspace(c = lgetc(lp, lo)))
break;
- if (c == '\t') {
- nicol |= 0x07;
- }
- nicol++;
+ if (c == '\t')
+ nicol = ntabstop(nicol, curbp->b_tabw);
+ else
+ nicol++;
}
/* If last line was blank, choose 0 */
for (i = 0; i < lo; ++i) {
c = lgetc(lp, i);
if (c == '\t') {
- col |= 0x07;
- col++;
+ col = ntabstop(col, curbp->b_tabw);
} else if (ISCTRL(c) != FALSE)
col += 2;
else if (isprint(c)) {
-/* $OpenBSD: def.h,v 1.179 2023/04/17 09:49:04 op Exp $ */
+/* $OpenBSD: def.h,v 1.180 2023/04/21 13:39:37 op Exp $ */
/* This file is in the public domain. */
char b_cwd[NFILEN]; /* working directory */
char *b_nlseq; /* Newline sequence of chars */
char *b_nlchr; /* 1st newline character */
+ int b_tabw; /* Width of a tab character */
struct fileinfo b_fi; /* File attributes */
struct undoq b_undo; /* Undo actions list */
struct undo_rec *b_undoptr;
int delwind(int, int);
/* buffer.c */
+int settabw(int, int);
int togglereadonly(int, int);
int togglereadonlyall(int, int);
struct buffer *bfind(const char *, int);
int setlineno(int);
/* util.c X */
+int ntabstop(int, int);
int showcpos(int, int);
int getcolpos(struct mgwin *);
int twiddle(int, int);
-/* $OpenBSD: display.c,v 1.51 2023/04/17 09:49:04 op Exp $ */
+/* $OpenBSD: display.c,v 1.52 2023/04/21 13:39:37 op Exp $ */
/* This file is in the public domain. */
};
void vtmove(int, int);
-void vtputc(int);
-void vtpute(int);
-int vtputs(const char *);
+void vtputc(int, struct mgwin *);
+void vtpute(int, struct mgwin *);
+int vtputs(const char *, struct mgwin *);
void vteeol(void);
void updext(int, int);
void modeline(struct mgwin *, int);
* Three guesses how we found this.
*/
void
-vtputc(int c)
+vtputc(int c, struct mgwin *wp)
{
struct video *vp;
+ int target;
c &= 0xff;
if (vtcol >= ncol)
vp->v_text[ncol - 1] = '$';
else if (c == '\t') {
+ target = ntabstop(vtcol, wp->w_bufp->b_tabw);
do {
- vtputc(' ');
- } while (vtcol < ncol && (vtcol & 0x07) != 0);
+ vtputc(' ', wp);
+ } while (vtcol < ncol && vtcol < target);
} else if (ISCTRL(c)) {
- vtputc('^');
- vtputc(CCHR(c));
+ vtputc('^', wp);
+ vtputc(CCHR(c), wp);
} else if (isprint(c))
vp->v_text[vtcol++] = c;
else {
char bf[5];
snprintf(bf, sizeof(bf), "\\%o", c);
- vtputs(bf);
+ vtputs(bf, wp);
}
}
* margin.
*/
void
-vtpute(int c)
+vtpute(int c, struct mgwin *wp)
{
struct video *vp;
+ int target;
c &= 0xff;
if (vtcol >= ncol)
vp->v_text[ncol - 1] = '$';
else if (c == '\t') {
+ target = ntabstop(vtcol + lbound, wp->w_bufp->b_tabw);
do {
- vtpute(' ');
- } while (((vtcol + lbound) & 0x07) != 0 && vtcol < ncol);
+ vtpute(' ', wp);
+ } while (((vtcol + lbound) < target) && vtcol < ncol);
} else if (ISCTRL(c) != FALSE) {
- vtpute('^');
- vtpute(CCHR(c));
+ vtpute('^', wp);
+ vtpute(CCHR(c), wp);
} else if (isprint(c)) {
if (vtcol >= 0)
vp->v_text[vtcol] = c;
snprintf(bf, sizeof(bf), "\\%o", c);
for (cp = bf; *cp != '\0'; cp++)
- vtpute(*cp);
+ vtpute(*cp, wp);
}
}
vscreen[i]->v_flag |= (VFCHG | VFHBAD);
vtmove(i, 0);
for (j = 0; j < llength(lp); ++j)
- vtputc(lgetc(lp, j));
+ vtputc(lgetc(lp, j), wp);
vteeol();
} else if ((wp->w_rflag & (WFEDIT | WFFULL)) != 0) {
hflag = TRUE;
vtmove(i, 0);
if (lp != wp->w_bufp->b_headp) {
for (j = 0; j < llength(lp); ++j)
- vtputc(lgetc(lp, j));
+ vtputc(lgetc(lp, j), wp);
lp = lforw(lp);
}
vteeol();
while (i < curwp->w_doto) {
c = lgetc(lp, i++);
if (c == '\t') {
- curcol |= 0x07;
- curcol++;
+ curcol = ntabstop(curcol, curwp->w_bufp->b_tabw);
} else if (ISCTRL(c) != FALSE)
curcol += 2;
else if (isprint(c))
(curcol < ncol - 1)) {
vtmove(i, 0);
for (j = 0; j < llength(lp); ++j)
- vtputc(lgetc(lp, j));
+ vtputc(lgetc(lp, j), wp);
vteeol();
/* this line no longer is extended */
vscreen[i]->v_flag &= ~VFEXT;
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));
+ vtpute(lgetc(lp, j), curwp);
vteeol(); /* truncate the virtual line */
vscreen[currow]->v_text[0] = '$'; /* and put a '$' in column 1 */
}
vscreen[n]->v_flag |= (VFCHG | VFHBAD); /* Recompute, display. */
vtmove(n, 0); /* Seek to right line. */
bp = wp->w_bufp;
- vtputc('-');
- vtputc('-');
+ vtputc('-', wp);
+ vtputc('-', wp);
if ((bp->b_flag & BFREADONLY) != 0) {
- vtputc('%');
+ vtputc('%', wp);
if ((bp->b_flag & BFCHG) != 0)
- vtputc('*');
+ vtputc('*', wp);
else
- vtputc('%');
+ vtputc('%', wp);
} else if ((bp->b_flag & BFCHG) != 0) { /* "*" if changed. */
- vtputc('*');
- vtputc('*');
+ vtputc('*', wp);
+ vtputc('*', wp);
} else {
- vtputc('-');
- vtputc('-');
+ vtputc('-', wp);
+ vtputc('-', wp);
}
- vtputc('-');
+ vtputc('-', wp);
n = 5;
- n += vtputs("Mg: ");
+ n += vtputs("Mg: ", wp);
if (bp->b_bname[0] != '\0')
- n += vtputs(&(bp->b_bname[0]));
+ n += vtputs(&(bp->b_bname[0]), wp);
while (n < 42) { /* Pad out with blanks. */
- vtputc(' ');
+ vtputc(' ', wp);
++n;
}
- vtputc('(');
+ vtputc('(', wp);
++n;
for (md = 0; ; ) {
- n += vtputs(bp->b_modes[md]->p_name);
+ n += vtputs(bp->b_modes[md]->p_name, wp);
if (++md > bp->b_nmodes)
break;
- vtputc('-');
+ vtputc('-', wp);
++n;
}
/* XXX These should eventually move to a real mode */
if (macrodef == TRUE)
- n += vtputs("-def");
+ n += vtputs("-def", wp);
if (globalwd == TRUE)
- n += vtputs("-gwd");
- vtputc(')');
+ n += vtputs("-gwd", wp);
+ vtputc(')', wp);
++n;
if (linenos && colnos)
else if (colnos)
len = snprintf(sl, sizeof(sl), "--C%d", getcolpos(wp));
if ((linenos || colnos) && len < sizeof(sl) && len != -1)
- n += vtputs(sl);
+ n += vtputs(sl, wp);
while (n < ncol) { /* Pad out. */
- vtputc('-');
+ vtputc('-', wp);
++n;
}
}
* Output a string to the mode line, report how long it was.
*/
int
-vtputs(const char *s)
+vtputs(const char *s, struct mgwin *wp)
{
int n = 0;
while (*s != '\0') {
- vtputc(*s++);
+ vtputc(*s++, wp);
++n;
}
return (n);
-/* $OpenBSD: funmap.c,v 1.66 2023/04/17 09:49:04 op Exp $ */
+/* $OpenBSD: funmap.c,v 1.67 2023/04/21 13:39:37 op Exp $ */
/* This file is in the public domain */
{ask_selfinsert, "self-insert-char", 1},
{selfinsert, "self-insert-command", 1}, /* startup only */
{sentencespace, "sentence-end-double-space", 0},
+ {settabw, "set-tab-width", 1},
#ifdef REGEX
{setcasefold, "set-case-fold-search", 0},
#endif /* REGEX */
-/* $OpenBSD: match.c,v 1.24 2023/04/17 15:18:25 op Exp $ */
+/* $OpenBSD: match.c,v 1.25 2023/04/21 13:39:37 op Exp $ */
/* This file is in the public domain. */
int cp;
int bufo;
int c;
+ int col;
int inwindow;
char buf[NLINE];
} else
buf[bufo++] = c;
} else {
- do {
+ col = ntabstop(bufo, curbp->b_tabw);
+ while (bufo < col && bufo < sizeof(buf) - 1)
buf[bufo++] = ' ';
- } while ((bufo & 7) && bufo < sizeof(buf) - 1);
}
}
buf[bufo++] = '\0';
-.\" $OpenBSD: mg.1,v 1.129 2023/04/17 09:49:04 op Exp $
+.\" $OpenBSD: mg.1,v 1.130 2023/04/21 13:39:37 op Exp $
.\" This file is in the public domain.
.\"
-.Dd $Mdocdate: April 17 2023 $
+.Dd $Mdocdate: April 21 2023 $
.Dt MG 1
.Os
.Sh NAME
Sets the mark in the current window to the current dot location.
.It set-prefix-string
Sets the prefix string to be used by the 'prefix-region' command.
+.It set-tab-width
+Set the tab width for the current buffer, or the default for new buffers
+if called with a prefix argument or from the startup file.
.It shell-command
Execute external command from mini-buffer.
.It shell-command-on-region
-/* $OpenBSD: paragraph.c,v 1.48 2023/04/17 09:49:04 op Exp $ */
+/* $OpenBSD: paragraph.c,v 1.49 2023/04/21 13:39:37 op Exp $ */
/* This file is in the public domain. */
return selfinsert(f, n);
c = lgetc(curwp->w_dotp, i);
if (c == '\t')
- col |= 0x07;
+ col = ntabstop(col, curwp->w_bufp->b_tabw);
else if (ISCTRL(c) != FALSE)
++col;
}
-/* $OpenBSD: util.c,v 1.47 2023/04/17 09:53:08 op Exp $ */
+/* $OpenBSD: util.c,v 1.48 2023/04/21 13:39:37 op Exp $ */
/* This file is in the public domain. */
int doindent(int);
+/*
+ * Compute next tab stop, with `col' being the a column number and
+ * `tabw' the tab width.
+ */
+int
+ntabstop(int col, int tabw)
+{
+ return (((col + tabw) / tabw) * tabw);
+}
+
/*
* Display a bunch of useful information about the current location of dot.
* The character under the cursor (in octal), the current line, row, and
for (i = 0; i < wp->w_doto; ++i) {
c = lgetc(wp->w_dotp, i);
if (c == '\t') {
- col |= 0x07;
- col++;
+ col = ntabstop(col, wp->w_bufp->b_tabw);
} else if (ISCTRL(c) != FALSE)
col += 2;
else if (isprint(c)) {
if (c != ' ' && c != '\t')
break;
if (c == '\t')
- nicol |= 0x07;
- ++nicol;
+ nicol = ntabstop(nicol, curwp->w_bufp->b_tabw);
+ else
+ ++nicol;
}
(void)delwhite(FFRAND, 1);
int
space_to_tabstop(int f, int n)
{
+ int c;
+
if (n < 0)
return (FALSE);
if (n == 0)
return (TRUE);
- return (linsert((n << 3) - (curwp->w_doto & 7), ' '));
+
+ c = curwp->w_doto;
+ while (n-- > 0)
+ c = ntabstop(c, curbp->b_tabw);
+ return (linsert(c - curwp->w_doto, ' '));
}
/*