aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2019-12-18 05:22:58 -0500
committerJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2019-12-18 05:38:59 -0500
commit04ebfeb8818b7f5b3d0b174c18257f1afa0bc8fd (patch)
treefe267efddf75b1ceeadf981daa2f0eb89a22e271
parent74a547d340cbdf9ec60c498a9d064283cabcfb6f (diff)
downloadrneovim-04ebfeb8818b7f5b3d0b174c18257f1afa0bc8fd.tar.gz
rneovim-04ebfeb8818b7f5b3d0b174c18257f1afa0bc8fd.tar.bz2
rneovim-04ebfeb8818b7f5b3d0b174c18257f1afa0bc8fd.zip
vim-patch:8.2.0018: :join does not add white space where it should
Problem: :join does not add white space where it should. (Zdenek Dohnal) Solution: Handle joining multiple lines propely. https://github.com/vim/vim/commit/91b65e49440e77222a65b6f868507453239f409b
-rw-r--r--src/nvim/ops.c2
-rw-r--r--src/nvim/testdir/test_join.vim385
2 files changed, 386 insertions, 1 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 294c65ca03..0ca16e2c25 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -3772,7 +3772,7 @@ int do_join(size_t count,
curr = skipwhite(curr);
if (*curr != NUL
&& *curr != ')'
- && currsize != 0
+ && sumsize != 0
&& endcurr1 != TAB
&& (!has_format_option(FO_MBYTE_JOIN)
|| (utf_ptr2char(curr) < 0x100 && endcurr1 < 0x100))
diff --git a/src/nvim/testdir/test_join.vim b/src/nvim/testdir/test_join.vim
index ecb55c9af6..ac6ef8f29f 100644
--- a/src/nvim/testdir/test_join.vim
+++ b/src/nvim/testdir/test_join.vim
@@ -54,3 +54,388 @@ func Test_join_marks()
call assert_equal([0, 4, 67, 0], getpos("']"))
enew!
endfunc
+
+" Test for joining lines and marks in them
+" in compatible and nocompatible modes
+" and with 'joinspaces' set or not
+" and with 'cpoptions' flag 'j' set or not
+func Test_join_spaces_marks()
+ new
+ " Text used for the test
+ insert
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+zx cvn.
+as dfg?
+hjkl iop!
+ert
+zx cvn.
+as dfg?
+hjkl iop!
+ert
+.
+ let text = getline(1, '$')
+ normal gg
+
+ set nojoinspaces
+ set cpoptions-=j
+ normal JjJjJjJjJjJjJjJjJjJjJjJjJjJ
+ normal j05lmx
+ normal 2j06lmy
+ normal 2k4Jy3l$p
+ normal `xyl$p
+ normal `yy2l$p
+
+ " set cpoptions+=j
+ normal j05lmx
+ normal 2j06lmy
+ normal 2k4Jy3l$p
+ normal `xyl$p
+ normal `yy2l$p
+
+ " Expected output
+ let expected =<< trim [DATA]
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ zx cvn. as dfg? hjkl iop! ert ernop
+ zx cvn. as dfg? hjkl iop! ert ernop
+ [DATA]
+
+ call assert_equal(expected, getline(1, '$'))
+ throw 'skipped: Nvim does not support "set compatible" or "set cpoptions+=j"'
+
+ enew!
+ call append(0, text)
+ normal gg
+
+ set cpoptions-=j
+ set joinspaces
+ normal JjJjJjJjJjJjJjJjJjJjJjJjJjJ
+ normal j05lmx
+ normal 2j06lmy
+ normal 2k4Jy3l$p
+ normal `xyl$p
+ normal `yy2l$p
+
+ set cpoptions+=j
+ normal j05lmx
+ normal 2j06lmy
+ normal 2k4Jy3l$p
+ normal `xyl$p
+ normal `yy2l$p
+
+ " Expected output
+ let expected =<< trim [DATA]
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ zx cvn. as dfg? hjkl iop! ert enop
+ zx cvn. as dfg? hjkl iop! ert ernop
+
+ [DATA]
+
+ call assert_equal(expected, getline(1, '$'))
+
+ enew!
+ call append(0, text)
+ normal gg
+
+ set cpoptions-=j
+ set nojoinspaces
+ set compatible
+
+ normal JjJjJjJjJjJjJjJjJjJjJjJjJjJ
+ normal j4Jy3l$pjdG
+
+ " Expected output
+ let expected =<< trim [DATA]
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf. asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ asdfasdf asdf
+ zx cvn. as dfg? hjkl iop! ert a
+ [DATA]
+
+ call assert_equal(expected, getline(1, '$'))
+
+ set nocompatible
+ set cpoptions&vim
+ set joinspaces&vim
+ close!
+endfunc
+
+" Test for joining lines with comments
+func Test_join_lines_with_comments()
+ new
+
+ " Text used by the test
+ insert
+{
+
+/*
+* Make sure the previous comment leader is not removed.
+*/
+
+/*
+* Make sure the previous comment leader is not removed.
+*/
+
+// Should the next comment leader be left alone?
+// Yes.
+
+// Should the next comment leader be left alone?
+// Yes.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+if (condition) // Remove the next comment leader!
+// OK, I will.
+action();
+
+if (condition) // Remove the next comment leader!
+// OK, I will.
+action();
+}
+.
+
+ call cursor(2, 1)
+ set comments=s1:/*,mb:*,ex:*/,://
+ set nojoinspaces fo=j
+ set backspace=eol,start
+
+ .,+3join
+ exe "normal j4J\<CR>"
+ .,+2join
+ exe "normal j3J\<CR>"
+ .,+2join
+ exe "normal j3J\<CR>"
+ .,+2join
+ exe "normal jj3J\<CR>"
+
+ " Expected output
+ let expected =<< trim [CODE]
+ {
+ /* Make sure the previous comment leader is not removed. */
+ /* Make sure the previous comment leader is not removed. */
+ // Should the next comment leader be left alone? Yes.
+ // Should the next comment leader be left alone? Yes.
+ /* Here the comment leader should be left intact. */ // And so should this one.
+ /* Here the comment leader should be left intact. */ // And so should this one.
+ if (condition) // Remove the next comment leader! OK, I will.
+ action();
+ if (condition) // Remove the next comment leader! OK, I will.
+ action();
+ }
+ [CODE]
+
+ call assert_equal(expected, getline(1, '$'))
+
+ set comments&vim
+ set joinspaces&vim
+ set fo&vim
+ set backspace&vim
+ close!
+endfunc
+
+" Test for joining lines with different comment leaders
+func Test_join_comments_2()
+ new
+
+ insert
+{
+
+/*
+ * Make sure the previous comment leader is not removed.
+ */
+
+/*
+ * Make sure the previous comment leader is not removed.
+ */
+
+/* List:
+ * - item1
+ * foo bar baz
+ * foo bar baz
+ * - item2
+ * foo bar baz
+ * foo bar baz
+ */
+
+/* List:
+ * - item1
+ * foo bar baz
+ * foo bar baz
+ * - item2
+ * foo bar baz
+ * foo bar baz
+ */
+
+// Should the next comment leader be left alone?
+// Yes.
+
+// Should the next comment leader be left alone?
+// Yes.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+if (condition) // Remove the next comment leader!
+ // OK, I will.
+ action();
+
+if (condition) // Remove the next comment leader!
+ // OK, I will.
+ action();
+
+int i = 7 /* foo *// 3
+ // comment
+ ;
+
+int i = 7 /* foo *// 3
+ // comment
+ ;
+
+># Note that the last character of the ending comment leader (left angle
+ # bracket) is a comment leader itself. Make sure that this comment leader is
+ # not removed from the next line #<
+< On this line a new comment is opened which spans 2 lines. This comment should
+< retain its comment leader.
+
+># Note that the last character of the ending comment leader (left angle
+ # bracket) is a comment leader itself. Make sure that this comment leader is
+ # not removed from the next line #<
+< On this line a new comment is opened which spans 2 lines. This comment should
+< retain its comment leader.
+
+}
+.
+
+ call cursor(2, 1)
+ set comments=sO:*\ -,mO:*\ \ ,exO:*/
+ set comments+=s1:/*,mb:*,ex:*/,://
+ set comments+=s1:>#,mb:#,ex:#<,:<
+ set cpoptions-=j joinspaces fo=j
+ set backspace=eol,start
+
+ .,+3join
+ exe "normal j4J\<CR>"
+ .,+8join
+ exe "normal j9J\<CR>"
+ .,+2join
+ exe "normal j3J\<CR>"
+ .,+2join
+ exe "normal j3J\<CR>"
+ .,+2join
+ exe "normal jj3J\<CR>j"
+ .,+2join
+ exe "normal jj3J\<CR>j"
+ .,+5join
+ exe "normal j6J\<CR>"
+ exe "normal oSome code!\<CR>// Make sure backspacing does not remove this comment leader.\<Esc>0i\<C-H>\<Esc>"
+
+ " Expected output
+ let expected =<< trim [CODE]
+ {
+ /* Make sure the previous comment leader is not removed. */
+ /* Make sure the previous comment leader is not removed. */
+ /* List: item1 foo bar baz foo bar baz item2 foo bar baz foo bar baz */
+ /* List: item1 foo bar baz foo bar baz item2 foo bar baz foo bar baz */
+ // Should the next comment leader be left alone? Yes.
+ // Should the next comment leader be left alone? Yes.
+ /* Here the comment leader should be left intact. */ // And so should this one.
+ /* Here the comment leader should be left intact. */ // And so should this one.
+ if (condition) // Remove the next comment leader! OK, I will.
+ action();
+ if (condition) // Remove the next comment leader! OK, I will.
+ action();
+ int i = 7 /* foo *// 3 // comment
+ ;
+ int i = 7 /* foo *// 3 // comment
+ ;
+ ># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader.
+ ># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader.
+
+ Some code!// Make sure backspacing does not remove this comment leader.
+ }
+ [CODE]
+
+ call assert_equal(expected, getline(1, '$'))
+ close!
+endfunc
+
+func Test_join_lines()
+ new
+ call setline(1, ['a', 'b', '', 'c', 'd'])
+ %join
+ call assert_equal('a b c d', getline(1))
+ call setline(1, ['a', 'b', '', 'c', 'd'])
+ normal 5J
+ call assert_equal('a b c d', getline(1))
+ bwipe!
+endfunc