diff options
-rw-r--r-- | runtime/doc/change.txt | 11 | ||||
-rw-r--r-- | src/nvim/edit.c | 27 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 9 | ||||
-rw-r--r-- | src/nvim/testdir/test_textformat.vim | 26 |
4 files changed, 64 insertions, 9 deletions
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index c73b460767..1761616651 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -1635,6 +1635,17 @@ j Where it makes sense, remove a comment leader when joining lines. For // in the list ~ Becomes: int i; // the index in the list ~ +p Don't break lines at single spaces that follow periods. This is + intended to complement 'joinspaces' and |cpo-J|, for prose with + sentences separated by two spaces. For example, with 'textwidth' set + to 28: > + Surely you're joking, Mr. Feynman! +< Becomes: > + Surely you're joking, + Mr. Feynman! +< Instead of: > + Surely you're joking, Mr. + Feynman! With 't' and 'c' you can specify when Vim performs auto-wrapping: diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 667bc54e2e..aae63c0490 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -5486,16 +5486,33 @@ internal_format ( /* remember position of blank just before text */ end_col = curwin->w_cursor.col; - /* find start of sequence of blanks */ + // find start of sequence of blanks + int wcc = 0; // counter for whitespace chars while (curwin->w_cursor.col > 0 && WHITECHAR(cc)) { dec_cursor(); cc = gchar_cursor(); + + // Increment count of how many whitespace chars in this + // group; we only need to know if it's more than one. + if (wcc < 2) { + wcc++; + } } - if (curwin->w_cursor.col == 0 && WHITECHAR(cc)) - break; /* only spaces in front of text */ - /* Don't break until after the comment leader */ - if (curwin->w_cursor.col < leader_len) + if (curwin->w_cursor.col == 0 && WHITECHAR(cc)) { + break; // only spaces in front of text + } + + // Don't break after a period when 'formatoptions' has 'p' and + // there are less than two spaces. + if (has_format_option(FO_PERIOD_ABBR) && cc == '.' && wcc < 2) { + continue; + } + + // Don't break until after the comment leader + if (curwin->w_cursor.col < leader_len) { break; + } + if (has_format_option(FO_ONE_LETTER)) { /* do not break after one-letter words */ if (curwin->w_cursor.col == 0) diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 6dc5e418fc..74047e7cef 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -74,13 +74,14 @@ #define FO_MBYTE_JOIN 'M' /* no space before/after multi-byte char */ #define FO_MBYTE_JOIN2 'B' /* no space between multi-byte chars */ #define FO_ONE_LETTER '1' -#define FO_WHITE_PAR 'w' /* trailing white space continues paragr. */ -#define FO_AUTO 'a' /* automatic formatting */ -#define FO_REMOVE_COMS 'j' /* remove comment leaders when joining lines */ +#define FO_WHITE_PAR 'w' // trailing white space continues paragr. +#define FO_AUTO 'a' // automatic formatting +#define FO_REMOVE_COMS 'j' // remove comment leaders when joining lines +#define FO_PERIOD_ABBR 'p' // don't break a single space after a period #define DFLT_FO_VI "vt" #define DFLT_FO_VIM "tcqj" -#define FO_ALL "tcroq2vlb1mMBn,awj" /* for do_set() */ +#define FO_ALL "tcroq2vlb1mMBn,awjp" // for do_set() // characters for the p_cpo option: #define CPO_ALTREAD 'a' // ":read" sets alternate file name diff --git a/src/nvim/testdir/test_textformat.vim b/src/nvim/testdir/test_textformat.vim index 0f8e09532b..13fb50b985 100644 --- a/src/nvim/testdir/test_textformat.vim +++ b/src/nvim/testdir/test_textformat.vim @@ -163,6 +163,32 @@ func Test_text_format() \ '# 1 xxxxx', \ '# foobar'], getline(1, 2)) + " Test the 'p' flag for 'formatoptions' + " First test without the flag: that it will break "Mr. Feynman" at the space + normal ggdG + setl tw=28 fo=tcq + call setline('.', 'Surely you''re joking, Mr. Feynman!') + normal gqq + call assert_equal([ + \ 'Surely you''re joking, Mr.', + \ 'Feynman!'], getline(1, 2)) + " Now test with the flag: that it will push the name with the title onto the + " next line + normal ggdG + setl fo+=p + call setline('.', 'Surely you''re joking, Mr. Feynman!') + normal gqq + call assert_equal([ + \ 'Surely you''re joking,', + \ 'Mr. Feynman!'], getline(1, 2)) + " Ensure that it will still break if two spaces are entered + normal ggdG + call setline('.', 'Surely you''re joking, Mr. Feynman!') + normal gqq + call assert_equal([ + \ 'Surely you''re joking, Mr.', + \ 'Feynman!'], getline(1, 2)) + setl ai& tw& fo& si& comments& enew! endfunc |