changeset 20069:9a67d41708d2 v8.2.0590

patch 8.2.0590: no 'backspace' value allows ignoring the insertion point Commit: https://github.com/vim/vim/commit/aa0489e12d227d24752cf16e4e97058ac32edcc1 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Apr 17 19:41:21 2020 +0200 patch 8.2.0590: no 'backspace' value allows ignoring the insertion point Problem: No 'backspace' value allows ignoring the insertion point. Solution: Add the "nostop" and 3 values. (Christian Brabandt, closes https://github.com/vim/vim/issues/5940)
author Bram Moolenaar <Bram@vim.org>
date Fri, 17 Apr 2020 19:45:05 +0200
parents b644ea832304
children 325ea41ce2e1
files runtime/doc/options.txt src/edit.c src/option.c src/option.h src/optionstr.c src/testdir/gen_opt_test.vim src/testdir/test_backspace_opt.vim src/version.c
diffstat 8 files changed, 67 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -915,6 +915,8 @@ A jump table for the options with a shor
 	eol	allow backspacing over line breaks (join lines)
 	start	allow backspacing over the start of insert; CTRL-W and CTRL-U
 		stop once at the start of insert.
+	nostop	like start, except CTRL-W and CTRL-U do not stop at the start of
+		insert.
 
 	When the value is empty, Vi compatible backspacing is used.
 
@@ -923,6 +925,7 @@ A jump table for the options with a shor
 	  0	same as ":set backspace=" (Vi compatible)
 	  1	same as ":set backspace=indent,eol"
 	  2	same as ":set backspace=indent,eol,start"
+	  3	same as ":set backspace=indent,eol,nostop"
 
 	See |:fixdel| if your <BS> or <Del> key does not do what you want.
 	NOTE: This option is set to "" when 'compatible' is set.
--- a/src/edit.c
+++ b/src/edit.c
@@ -4884,8 +4884,10 @@ ins_bs(
 		    revins_on ||
 #endif
 		    (curwin->w_cursor.col > mincol
-		    && (curwin->w_cursor.lnum != Insstart_orig.lnum
-			|| curwin->w_cursor.col != Insstart_orig.col)));
+		    &&  (can_bs(BS_NOSTOP)
+			|| (curwin->w_cursor.lnum != Insstart_orig.lnum
+			|| curwin->w_cursor.col != Insstart_orig.col)
+		    )));
 	}
 	did_backspace = TRUE;
     }
--- a/src/option.c
+++ b/src/option.c
@@ -1685,6 +1685,10 @@ do_set(
 					*(char_u **)varp = vim_strsave(
 						(char_u *)"indent,eol,start");
 					break;
+				    case 3:
+					*(char_u **)varp = vim_strsave(
+						(char_u *)"indent,eol,nostop");
+					break;
 				}
 				vim_free(oldval);
 				if (origval == oldval)
@@ -6818,7 +6822,7 @@ fill_breakat_flags(void)
  */
     int
 can_bs(
-    int		what)	    // BS_INDENT, BS_EOL or BS_START
+    int		what)	    // BS_INDENT, BS_EOL, BS_START or BS_NOSTOP
 {
 #ifdef FEAT_JOB_CHANNEL
     if (what == BS_START && bt_prompt(curbuf))
@@ -6826,7 +6830,8 @@ can_bs(
 #endif
     switch (*p_bs)
     {
-	case '2':	return TRUE;
+	case '3':       return TRUE;
+	case '2':	return (what != BS_NOSTOP);
 	case '1':	return (what != BS_START);
 	case '0':	return FALSE;
     }
--- a/src/option.h
+++ b/src/option.h
@@ -344,9 +344,14 @@
 #define WIM_BUFLASTUSED	0x08
 
 // arguments for can_bs()
+// each defined char should be unique over all values
+// except for BS_START, that intentionally also matches BS_NOSTOP
+// because BS_NOSTOP behaves exactly the same except it
+// does not stop at the start of the insert point
 #define BS_INDENT	'i'	// "Indent"
-#define BS_EOL		'o'	// "eOl"
+#define BS_EOL		'l'	// "eoL"
 #define BS_START	's'	// "Start"
+#define BS_NOSTOP	'p'	// "nostoP
 
 // flags for the 'culopt' option
 #define CULOPT_LINE	0x01	// Highlight complete line
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -68,7 +68,7 @@ static char *(p_debug_values[]) = {"msg"
 static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
 static char *(p_buftype_values[]) = {"nofile", "nowrite", "quickfix", "help", "terminal", "acwrite", "prompt", "popup", NULL};
 static char *(p_bufhidden_values[]) = {"hide", "unload", "delete", "wipe", NULL};
-static char *(p_bs_values[]) = {"indent", "eol", "start", NULL};
+static char *(p_bs_values[]) = {"indent", "eol", "start", "nostop", NULL};
 #ifdef FEAT_FOLDING
 static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
 # ifdef FEAT_DIFF
@@ -1910,7 +1910,7 @@ did_set_string_option(
     {
 	if (VIM_ISDIGIT(*p_bs))
 	{
-	    if (*p_bs > '2' || p_bs[1] != NUL)
+	    if (*p_bs > '3' || p_bs[1] != NUL)
 		errmsg = e_invarg;
 	}
 	else if (check_opt_strings(p_bs, p_bs_values, TRUE) != OK)
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -63,7 +63,7 @@ let test_values = {
       \
       \ 'ambiwidth': [['', 'single'], ['xxx']],
       \ 'background': [['', 'light', 'dark'], ['xxx']],
-      \ 'backspace': [[0, 2, '', 'eol', 'eol,start'], ['xxx']],
+      \ 'backspace': [[0, 2, 3, '', 'eol', 'eol,start', 'indent,eol,nostop'], ['4', 'xxx']],
       \ 'backupcopy': [['yes', 'auto'], ['', 'xxx', 'yes,no']],
       \ 'backupext': [['xxx'], ['']],
       \ 'belloff': [['', 'all', 'copy,error'], ['xxx']],
--- a/src/testdir/test_backspace_opt.vim
+++ b/src/testdir/test_backspace_opt.vim
@@ -19,6 +19,8 @@ func Test_backspace_option()
   call assert_equal('eol', &backspace)
   set backspace=start
   call assert_equal('start', &backspace)
+  set backspace=nostop
+  call assert_equal('nostop', &backspace)
   " Add the value
   set backspace=
   set backspace=indent
@@ -27,7 +29,11 @@ func Test_backspace_option()
   call assert_equal('indent,eol', &backspace)
   set backspace+=start
   call assert_equal('indent,eol,start', &backspace)
+  set backspace+=nostop
+  call assert_equal('indent,eol,start,nostop', &backspace)
   " Delete the value
+  set backspace-=nostop
+  call assert_equal('indent,eol,start', &backspace)
   set backspace-=indent
   call assert_equal('eol,start', &backspace)
   set backspace-=start
@@ -47,7 +53,9 @@ func Test_backspace_option()
   call assert_equal('1', &backspace)
   set backspace=2
   call assert_equal('2', &backspace)
-  call assert_false(match(Exec('set backspace=3'), '.*E474'))
+  set backspace=3
+  call assert_equal('3', &backspace)
+  call assert_false(match(Exec('set backspace=4'), '.*E474'))
   call assert_false(match(Exec('set backspace=10'), '.*E474'))
 
   " Cleared when 'compatible' is set
@@ -101,6 +109,39 @@ func Test_backspace_ctrl_u()
         \ "8 this shouldn't be deleted (not touched yet) vim7",
         \ ""], getline(1, '$'))
 
+  " Reset values
+  set compatible&vim
+  set visualbell&vim
+  set backspace&vim
+
+  " Test new nostop option
+  %d_
+  let expected = "foo bar foobar"
+  call setline(1, expected)
+  call cursor(1, 8)
+  exe ":norm! ianotherone\<c-u>"
+  call assert_equal(expected, getline(1))
+  call cursor(1, 8)
+  exe ":norm! ianothertwo\<c-w>"
+  call assert_equal(expected, getline(1))
+
+  let content = getline(1)
+  for value in ['indent,nostop', 'eol,nostop', 'indent,eol,nostop', 'indent,eol,start,nostop']
+    exe ":set bs=".. value
+    %d _
+    call setline(1, content)
+    let expected = " foobar"
+    call cursor(1, 8)
+    exe ":norm! ianotherone\<c-u>"
+    call assert_equal(expected, getline(1), 'CTRL-U backspace value: '.. &bs)
+    let expected = "foo  foobar"
+    call setline(1, content)
+    call cursor(1, 8)
+    exe ":norm! ianothertwo\<c-w>"
+    call assert_equal(expected, getline(1), 'CTRL-W backspace value: '.. &bs)
+  endfor
+
+  " Reset options
   set compatible&vim
   set visualbell&vim
   set backspace&vim
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    590,
+/**/
     589,
 /**/
     588,