summaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
authorRon Yorston2021-04-17 09:25:47 +0100
committerDenys Vlasenko2021-04-20 11:21:43 +0200
commitf277c9eebb91a46cbd795c34aa64ee8b6a2e448c (patch)
tree184512a390ddbe64607d2bd60fbcd26b5aa1b083 /editors/vi.c
parent310ef232809b34a75c120629b7b2c0d4af0dd50f (diff)
downloadbusybox-f277c9eebb91a46cbd795c34aa64ee8b6a2e448c.zip
busybox-f277c9eebb91a46cbd795c34aa64ee8b6a2e448c.tar.gz
vi: make de-indentation with ctrl-D more like vim
Commit ac6495f6f (vi: allow ctrl-D to reduce indentation) treated ctrl-D during autoindent as a backspace. This was adequate for indentation using tabs but doesn't work well with the expandtab option. In the latter case it's necessary to backspace over all the spaces. Make ctrl-D work correctly when spaces are present in the indent. Also, make it behave more like vim: - ctrl-D is independent of autoindent; - indentation is reduced even when the cursor isn't positioned at the end of the indent. function old new delta char_insert 679 717 +38 get_column - 37 +37 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/0 up/down: 75/0) Total: 75 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors/vi.c')
-rw-r--r--editors/vi.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/editors/vi.c b/editors/vi.c
index de7a433..caf01ac 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -763,6 +763,11 @@ static int next_tabstop(int col)
return col + ((tabstop - 1) - (col % tabstop));
}
+static int prev_tabstop(int col)
+{
+ return col - ((col % tabstop) ?: tabstop);
+}
+
static int next_column(char c, int co)
{
if (c == '\t')
@@ -772,7 +777,6 @@ static int next_column(char c, int co)
return co + 1;
}
-#if ENABLE_FEATURE_VI_SETOPTS
static int get_column(char *p)
{
const char *r;
@@ -782,7 +786,6 @@ static int get_column(char *p)
co = next_column(*r, co);
return co;
}
-#endif
//----- Erase the Screen[] memory ------------------------------
static void screen_erase(void)
@@ -2113,14 +2116,23 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
if ((p[-1] != '\n') && (dot > text)) {
p--;
}
-#if ENABLE_FEATURE_VI_SETOPTS
- } else if (c == 4 && autoindent) { // ctrl-D reduces indentation
- q = begin_line(p);
- len = strspn(q, " \t");
- if (len && q + len == p) {
- p--;
- p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED);
+ } else if (c == 4) { // ctrl-D reduces indentation
+ int prev;
+ char *r, *bol;
+ bol = begin_line(p);
+ for (r = bol; r < end_line(p); ++r) {
+ if (!isblank(*r))
+ break;
}
+
+ prev = prev_tabstop(get_column(r));
+ while (r > bol && get_column(r) > prev) {
+ if (p > bol)
+ p--;
+ r--;
+ r = text_hole_delete(r, r, ALLOW_UNDO_QUEUED);
+ }
+#if ENABLE_FEATURE_VI_SETOPTS
} else if (c == '\t' && expandtab) { // expand tab
int col = get_column(p);
col = next_tabstop(col) - col + 1;