$NetBSD: patch-az,v 1.2 2013/01/23 17:26:08 wiz Exp $ --- vi/v_txt.c.orig 2007-11-19 03:41:42.000000000 +1100 +++ vi/v_txt.c @@ -948,7 +948,7 @@ k_escape: LINE_RESOLVE; switch (carat) { case C_CARATSET: /* ^^D */ - if (tp->ai == 0 || tp->cno > tp->ai + tp->offset + 1) + if (tp->ai == 0 || tp->cno != tp->ai + tp->offset + 1) goto ins_ch; /* Save the ai string for later. */ @@ -961,17 +961,18 @@ k_escape: LINE_RESOLVE; carat = C_NOCHANGE; goto leftmargin; case C_ZEROSET: /* 0^D */ - if (tp->ai == 0 || tp->cno > tp->ai + tp->offset + 1) + if (tp->ai == 0 || tp->cno != tp->ai + tp->offset + 1) goto ins_ch; carat = C_NOTSET; leftmargin: tp->lb[tp->cno - 1] = ' '; tp->owrite += tp->cno - tp->offset; - tp->ai = 0; tp->cno = tp->offset; break; + case C_NOCHANGE: /* ^D after reset with ^^D */ + /* FALLTHROUGH */ case C_NOTSET: /* ^D */ - if (tp->ai == 0 || tp->cno > tp->ai + tp->offset) + if (tp->ai == 0 || tp->cno != tp->ai + tp->offset) goto ins_ch; (void)txt_dent(sp, tp, 0); @@ -1719,13 +1720,19 @@ txt_ai_resolve(SCR *sp, TEXT *tp, int *c /* * 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; /* @@ -1889,7 +1896,6 @@ txt_dent(SCR *sp, TEXT *tp, int isindent CHAR_T ch; u_long sw, ts; size_t cno, current, spaces, target, tabs, off; - int ai_reset; ts = O_VAL(sp, O_TABSTOP); sw = O_VAL(sp, O_SHIFTWIDTH); @@ -1921,16 +1927,6 @@ txt_dent(SCR *sp, TEXT *tp, int isindent target -= --target % sw; /* - * The AI characters will be turned into overwrite characters if the - * cursor immediately follows them. We test both the cursor position - * and the indent flag because there's no single test. (^T can only - * be detected by the cursor position, and while we know that the test - * is always true for ^D, the cursor can be in more than one place, as - * "0^D" and "^D" are different.) - */ - ai_reset = !isindent || tp->cno == tp->ai + tp->offset; - - /* * Back up over any previous characters, changing them into * overwrite characters (including any ai characters). Then figure * out the current screen column. @@ -1957,15 +1953,16 @@ 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; } - /* If we overwrote ai characters, reset the ai count. */ - if (ai_reset) - tp->ai = tabs + spaces; + tp->ai = tabs + spaces; /* * Call txt_insch() to insert each character, so that we get the