[PATCH] vi: add expandtab option

Peter0x44 urmum69 at snopyta.org
Thu Apr 15 17:30:58 UTC 2021


This implements the vim option expandtab in vi.
It replaces tabs with spaces while in insert mode.
---

>From vim help.txt:

In Insert mode: Use the appropriate number of spaces to insert a
<Tab>.  Spaces are used in indents with the '>' and '<' commands and
when 'autoindent' is on.  To insert a real tab when 'expandtab' is
on, use CTRL-V<Tab>.

 editors/vi.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 6dd951421..632f29163 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -292,11 +292,13 @@ struct globals {
 #define VI_ERR_METHOD (1 << 1)
 #define VI_IGNORECASE (1 << 2)
 #define VI_SHOWMATCH  (1 << 3)
-#define VI_TABSTOP    (1 << 4)
+#define VI_EXPANDTAB  (1 << 4)
+#define VI_TABSTOP    (1 << 5)
 #define autoindent (vi_setops & VI_AUTOINDENT)
 #define err_method (vi_setops & VI_ERR_METHOD) // indicate error with beep or flash
 #define ignorecase (vi_setops & VI_IGNORECASE)
 #define showmatch  (vi_setops & VI_SHOWMATCH )
+#define expandtab  (vi_setops & VI_EXPANDTAB )
 #define openabove  (vi_setops & VI_TABSTOP   )
 // order of constants and strings must match
 #define OPTS_STR \
@@ -304,6 +306,7 @@ struct globals {
 		"fl\0""flash\0" \
 		"ic\0""ignorecase\0" \
 		"sm\0""showmatch\0" \
+		"et\0""expandtab\0" \
 		"ts\0""tabstop\0"
 #define set_openabove() (vi_setops |= VI_TABSTOP)
 #define clear_openabove() (vi_setops &= ~VI_TABSTOP)
@@ -3363,6 +3366,16 @@ static void do_cmd(int c)
 		}
 	}
 	if (cmd_mode == 1) {
+		if (c == '\t' && expandtab) {
+			// insert tabstop spaces instead
+			for (i = 0; i < tabstop; ++i) {
+				char_insert(dot, ' ', NO_UNDO);
+				//mode cursor right
+				dot_right();
+			}
+			// skip inserting c
+			goto dc1;
+		}
 		// hitting "Insert" twice means "R" replace mode
 		if (c == KEYCODE_INSERT) goto dc5;
 		// insert the char c at "dot"
@@ -3752,7 +3765,7 @@ static void do_cmd(int c)
 		i = count_lines(p, q);	// # of lines we are shifting
 		for ( ; i > 0; i--, p = next_line(p)) {
 			if (c == '<') {
-				// shift left- remove tab or 8 spaces
+				// shift left- remove tab or tabstop spaces
 				if (*p == '\t') {
 					// shrink buffer 1 char
 					text_hole_delete(p, p, allow_undo);
@@ -3766,8 +3779,17 @@ static void do_cmd(int c)
 					}
 				}
 			} else /* if (c == '>') */ {
-				// shift right -- add tab or 8 spaces
-				char_insert(p, '\t', allow_undo);
+				// shift right -- add tab or tabstop spaces
+				if (expandtab) {
+					for (j = 0; j < tabstop; ++j) {
+						char_insert(p, ' ', allow_undo);
+#if ENABLE_FEATURE_VI_UNDO
+						allow_undo = ALLOW_UNDO_CHAIN;
+#endif
+					}
+				} else {
+					char_insert(p, '\t', allow_undo);
+				}
 			}
 #if ENABLE_FEATURE_VI_UNDO
 			allow_undo = ALLOW_UNDO_CHAIN;
-- 
2.31.1



More information about the busybox mailing list