summaryrefslogtreecommitdiff
path: root/usr.bin/vi
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2020-04-30 10:40:22 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2020-04-30 10:40:22 +0000
commit5bbfc7d35ac70959c754f905b9d56b094ce484e9 (patch)
treec424e6ec2b977b310a98b379589f30cae23d7d7d /usr.bin/vi
parent34ab4e3ca489a87b316f509a06f041cfe1f47f7a (diff)
Add an expandtab option, similar to what vim supports.
If set, expands tabs to spaces in insert mode as well as when shifting and indenting/outdenting. If quoted with ^V, a literal tab is inserted. Adapted from NetBSD, but this implementation more closely matches vim's behavior. OK dlg@
Diffstat (limited to 'usr.bin/vi')
-rw-r--r--usr.bin/vi/common/options.c5
-rw-r--r--usr.bin/vi/docs/USD.doc/vi.man/vi.119
-rw-r--r--usr.bin/vi/docs/USD.doc/vi.ref/set.opt.roff17
-rw-r--r--usr.bin/vi/ex/ex_shift.c13
-rw-r--r--usr.bin/vi/ex/ex_txt.c10
-rw-r--r--usr.bin/vi/vi/v_txt.c40
6 files changed, 79 insertions, 25 deletions
diff --git a/usr.bin/vi/common/options.c b/usr.bin/vi/common/options.c
index 6e11150b62c..d921afef311 100644
--- a/usr.bin/vi/common/options.c
+++ b/usr.bin/vi/common/options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options.c,v 1.27 2019/05/21 09:24:58 martijn Exp $ */
+/* $OpenBSD: options.c,v 1.28 2020/04/30 10:40:21 millert Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -69,6 +69,8 @@ OPTLIST const optlist[] = {
{"escapetime", NULL, OPT_NUM, 0},
/* O_ERRORBELLS 4BSD */
{"errorbells", NULL, OPT_0BOOL, 0},
+/* O_EXPANDTAB NetBSD 5.0 */
+ {"expandtab", NULL, OPT_0BOOL, 0},
/* O_EXRC System V (undocumented) */
{"exrc", NULL, OPT_0BOOL, 0},
/* O_EXTENDED 4.4BSD */
@@ -207,6 +209,7 @@ static OABBREV const abbrev[] = {
{"co", O_COLUMNS}, /* 4.4BSD */
{"eb", O_ERRORBELLS}, /* 4BSD */
{"ed", O_EDCOMPATIBLE}, /* 4BSD */
+ {"et", O_EXPANDTAB}, /* NetBSD 5.0 */
{"ex", O_EXRC}, /* System V (undocumented) */
{"ht", O_HARDTABS}, /* 4BSD */
{"ic", O_IGNORECASE}, /* 4BSD */
diff --git a/usr.bin/vi/docs/USD.doc/vi.man/vi.1 b/usr.bin/vi/docs/USD.doc/vi.man/vi.1
index c852b45b6dd..0dd08bc5dee 100644
--- a/usr.bin/vi/docs/USD.doc/vi.man/vi.1
+++ b/usr.bin/vi/docs/USD.doc/vi.man/vi.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: vi.1,v 1.77 2019/10/04 20:12:01 jmc Exp $
+.\" $OpenBSD: vi.1,v 1.78 2020/04/30 10:40:21 millert Exp $
.\"
.\" Copyright (c) 1994
.\" The Regents of the University of California. All rights reserved.
@@ -14,7 +14,7 @@
.\"
.\" @(#)vi.1 8.51 (Berkeley) 10/10/96
.\"
-.Dd $Mdocdate: October 4 2019 $
+.Dd $Mdocdate: April 30 2020 $
.Dt VI 1
.Os
.Sh NAME
@@ -1606,6 +1606,11 @@ and
characters to move forward to the next
.Ar shiftwidth
column boundary.
+If the
+.Cm expandtab
+option is set, only insert
+.Aq space
+characters.
.Pp
.It Aq Cm erase
.It Aq Cm control-H
@@ -2343,6 +2348,16 @@ key mapping.
.Nm ex
only.
Announce error messages with a bell.
+.It Cm expandtab , et Bq off
+Expand
+.Aq tab
+characters to
+.Aq space
+when inserting, replacing or shifting text, autoindenting,
+indenting with
+.Aq Ic control-T ,
+or outdenting with
+.Aq Ic control-D .
.It Cm exrc , ex Bq off
Read the startup files in the local directory.
.It Cm extended Bq off
diff --git a/usr.bin/vi/docs/USD.doc/vi.ref/set.opt.roff b/usr.bin/vi/docs/USD.doc/vi.ref/set.opt.roff
index 6c51da59b77..28f291d0cff 100644
--- a/usr.bin/vi/docs/USD.doc/vi.ref/set.opt.roff
+++ b/usr.bin/vi/docs/USD.doc/vi.ref/set.opt.roff
@@ -1,4 +1,4 @@
-.\" $OpenBSD: set.opt.roff,v 1.12 2016/08/08 15:09:33 sobrado Exp $
+.\" $OpenBSD: set.opt.roff,v 1.13 2020/04/30 10:40:21 millert Exp $
.\"
.\" Copyright (c) 1994
.\" The Regents of the University of California. All rights reserved.
@@ -96,7 +96,9 @@ the first nonblank character of the line from which you created it.
Lines are indented using tab characters to the extent possible (based on
the value of the
.OP tabstop
-option) and then using space characters as necessary.
+option, and if
+.OP expandtab
+is not set) and then using space characters as necessary.
For commands inserting text into the middle of a line, any blank characters
to the right of the cursor are discarded, and the first nonblank character
to the right of the cursor is aligned as described above.
@@ -400,6 +402,17 @@ only.
error messages are normally presented in inverse video.
If that is not possible for the terminal, setting this option causes
error messages to be announced by ringing the terminal bell.
+.KY expandtab
+.IP "expandtab, et [off]"
+Expand
+.LI <tab>
+characters to
+.LI <space>
+when inserting, replacing or shifting text, autoindenting,
+indenting with
+.CO <control-T>,
+or outdenting with
+.CO <control-D>.
.KY exrc
.IP "exrc, ex [off]"
If this option is turned on in the EXINIT environment variables,
diff --git a/usr.bin/vi/ex/ex_shift.c b/usr.bin/vi/ex/ex_shift.c
index e202c48e2fb..b9ab249c1fb 100644
--- a/usr.bin/vi/ex/ex_shift.c
+++ b/usr.bin/vi/ex/ex_shift.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ex_shift.c,v 1.8 2016/01/06 22:28:52 millert Exp $ */
+/* $OpenBSD: ex_shift.c,v 1.9 2020/04/30 10:40:21 millert Exp $ */
/*-
* Copyright (c) 1992, 1993, 1994
@@ -127,10 +127,13 @@ shift(SCR *sp, EXCMD *cmdp, enum which rl)
* Build a new indent string and count the number of
* characters it uses.
*/
- for (tbp = bp, newidx = 0;
- newcol >= O_VAL(sp, O_TABSTOP); ++newidx) {
- *tbp++ = '\t';
- newcol -= O_VAL(sp, O_TABSTOP);
+ tbp = bp;
+ newidx = 0;
+ if (!O_ISSET(sp, O_EXPANDTAB)) {
+ for (; newcol >= O_VAL(sp, O_TABSTOP); ++newidx) {
+ *tbp++ = '\t';
+ newcol -= O_VAL(sp, O_TABSTOP);
+ }
}
for (; newcol > 0; --newcol, ++newidx)
*tbp++ = ' ';
diff --git a/usr.bin/vi/ex/ex_txt.c b/usr.bin/vi/ex/ex_txt.c
index 10b3a0cc21c..0dcfcf3c492 100644
--- a/usr.bin/vi/ex/ex_txt.c
+++ b/usr.bin/vi/ex/ex_txt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ex_txt.c,v 1.16 2016/05/27 09:18:12 martijn Exp $ */
+/* $OpenBSD: ex_txt.c,v 1.17 2020/04/30 10:40:21 millert Exp $ */
/*-
* Copyright (c) 1992, 1993, 1994
@@ -400,8 +400,12 @@ txt_dent(SCR *sp, TEXT *tp)
*
* Count up spaces/tabs needed to get to the target.
*/
- for (cno = 0, tabs = 0; cno + COL_OFF(cno, ts) <= scno; ++tabs)
- cno += COL_OFF(cno, ts);
+ cno = 0;
+ tabs = 0;
+ if (!O_ISSET(sp, O_EXPANDTAB)) {
+ for (; cno + COL_OFF(cno, ts) <= scno; ++tabs)
+ cno += COL_OFF(cno, ts);
+ }
spaces = scno - cno;
/* Make sure there's enough room. */
diff --git a/usr.bin/vi/vi/v_txt.c b/usr.bin/vi/vi/v_txt.c
index ad47953c9a8..31ea4cba57c 100644
--- a/usr.bin/vi/vi/v_txt.c
+++ b/usr.bin/vi/vi/v_txt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: v_txt.c,v 1.33 2016/05/27 09:18:12 martijn Exp $ */
+/* $OpenBSD: v_txt.c,v 1.34 2020/04/30 10:40:21 millert Exp $ */
/*-
* Copyright (c) 1993, 1994
@@ -32,7 +32,7 @@
static int txt_abbrev(SCR *, TEXT *, CHAR_T *, int, int *, int *);
static void txt_ai_resolve(SCR *, TEXT *, int *);
static TEXT *txt_backup(SCR *, TEXTH *, TEXT *, u_int32_t *);
-static int txt_dent(SCR *, TEXT *, int);
+static int txt_dent(SCR *, TEXT *, int, int);
static int txt_emark(SCR *, TEXT *, size_t);
static void txt_err(SCR *, TEXTH *);
static int txt_fc(SCR *, TEXT *, int *);
@@ -968,7 +968,7 @@ leftmargin: tp->lb[tp->cno - 1] = ' ';
if (tp->ai == 0 || tp->cno > tp->ai + tp->offset)
goto ins_ch;
- (void)txt_dent(sp, tp, 0);
+ (void)txt_dent(sp, tp, O_SHIFTWIDTH, 0);
break;
default:
abort();
@@ -1184,7 +1184,7 @@ leftmargin: tp->lb[tp->cno - 1] = ' ';
case K_CNTRLT: /* Add autoindent characters. */
if (!LF_ISSET(TXT_CNTRLT))
goto ins_ch;
- if (txt_dent(sp, tp, 1))
+ if (txt_dent(sp, tp, O_SHIFTWIDTH, 1))
goto err;
goto ebuf_chk;
case K_RIGHTBRACE:
@@ -1213,6 +1213,13 @@ leftmargin: tp->lb[tp->cno - 1] = ' ';
case K_HEXCHAR:
hexcnt = 1;
goto insq_ch;
+ case K_TAB:
+ if (quote != Q_VTHIS && O_ISSET(sp, O_EXPANDTAB)) {
+ if (txt_dent(sp, tp, O_TABSTOP, 1))
+ goto err;
+ goto ebuf_chk;
+ }
+ goto insq_ch;
default: /* Insert the character. */
ins_ch: /*
* Historically, vi eliminated nul's out of hand. If the
@@ -1683,13 +1690,19 @@ txt_ai_resolve(SCR *sp, TEXT *tp, int *changedp)
/*
* If there are no spaces, or no tabs after spaces and less than
* ts spaces, it's already minimal.
+ * Keep analysing if expandtab is set.
*/
- if (!spaces || (!tab_after_sp && spaces < ts))
+ if ((!spaces || (!tab_after_sp && spaces < ts)) &&
+ !O_ISSET(sp, O_EXPANDTAB))
return;
/* Count up spaces/tabs needed to get to the target. */
- for (cno = 0, tabs = 0; cno + COL_OFF(cno, ts) <= scno; ++tabs)
- cno += COL_OFF(cno, ts);
+ cno = 0;
+ tabs = 0;
+ if (!O_ISSET(sp, O_EXPANDTAB)) {
+ for (; cno + COL_OFF(cno, ts) <= scno; ++tabs)
+ cno += COL_OFF(cno, ts);
+ }
spaces = scno - cno;
/*
@@ -1846,7 +1859,7 @@ txt_backup(SCR *sp, TEXTH *tiqh, TEXT *tp, u_int32_t *flagsp)
* changes.
*/
static int
-txt_dent(SCR *sp, TEXT *tp, int isindent)
+txt_dent(SCR *sp, TEXT *tp, int swopt, int isindent)
{
CHAR_T ch;
u_long sw, ts;
@@ -1854,7 +1867,7 @@ txt_dent(SCR *sp, TEXT *tp, int isindent)
int ai_reset;
ts = O_VAL(sp, O_TABSTOP);
- sw = O_VAL(sp, O_SHIFTWIDTH);
+ sw = O_VAL(sp, swopt);
/*
* Since we don't know what precedes the character(s) being inserted
@@ -1921,9 +1934,12 @@ txt_dent(SCR *sp, TEXT *tp, int isindent)
if (current >= target)
spaces = tabs = 0;
else {
- for (cno = current,
- tabs = 0; cno + COL_OFF(cno, ts) <= target; ++tabs)
- cno += COL_OFF(cno, ts);
+ cno = current;
+ tabs = 0;
+ if (!O_ISSET(sp, O_EXPANDTAB)) {
+ for (; cno + COL_OFF(cno, ts) <= target; ++tabs)
+ cno += COL_OFF(cno, ts);
+ }
spaces = target - cno;
}