aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/change.txt11
-rw-r--r--src/nvim/edit.c27
-rw-r--r--src/nvim/option_defs.h9
-rw-r--r--src/nvim/testdir/test_textformat.vim26
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