Patch 8.2.3787
Problem: No proper formatting of a C line comment after a statement.
Solution: Find the start of the line comment, insert the comment leader and
indent the comment properly.
Files: src/change.c, src/proto/
change.pro, src/search.c,
src/proto/
search.pro, src/cindent.c, src/edit.c, src/normal.c,
src/textformat.c, src/testdir/test_textformat.vim,
src/testdir/test_cindent.vim
*** ../vim-8.2.3786/src/change.c 2021-11-29 20:39:06.670101630 +0000
--- src/change.c 2021-12-12 13:34:12.193723824 +0000
***************
*** 1356,1361 ****
--- 1356,1363 ----
*
* "second_line_indent": indent for after ^^D in Insert mode or if flag
* OPENLINE_COM_LIST
+ * "did_do_comment" is set to TRUE when intentionally putting the comment
+ * leader in fromt of the new line.
*
* Return OK for success, FAIL for failure
*/
***************
*** 1363,1369 ****
open_line(
int dir, // FORWARD or BACKWARD
int flags,
! int second_line_indent)
{
char_u *saved_line; // copy of the original line
char_u *next_line = NULL; // copy of the next line
--- 1365,1372 ----
open_line(
int dir, // FORWARD or BACKWARD
int flags,
! int second_line_indent,
! int *did_do_comment UNUSED)
{
char_u *saved_line; // copy of the original line
char_u *next_line = NULL; // copy of the next line
***************
*** 1378,1383 ****
--- 1381,1387 ----
int retval = FAIL; // return value
int extra_len = 0; // length of p_extra string
int lead_len; // length of comment leader
+ int comment_start = 0; // start index of the comment leader
char_u *lead_flags; // position in 'comments' for comment leader
char_u *leader = NULL; // copy of comment leader
char_u *allocated = NULL; // allocated memory
***************
*** 1393,1398 ****
--- 1397,1405 ----
&& *curbuf->b_p_inde == NUL
# endif
);
+ #ifdef FEAT_CINDENT
+ int do_cindent;
+ #endif
int no_si = FALSE; // reset did_si afterwards
int first_char = NUL; // init for GCC
#endif
***************
*** 1632,1643 ****
--- 1639,1681 ----
did_ai = TRUE;
}
+ #ifdef FEAT_CINDENT
+ // May do indenting after opening a new line.
+ do_cindent = !p_paste && (curbuf->b_p_cin
+ # ifdef FEAT_EVAL
+ || *curbuf->b_p_inde != NUL
+ # endif
+ )
+ && in_cinkeys(dir == FORWARD
+ ? KEY_OPEN_FORW
+ : KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum));
+ #endif
+
// Find out if the current line starts with a comment leader.
// This may then be inserted in front of the new line.
end_comment_pending = NUL;
if (flags & OPENLINE_DO_COM)
+ {
lead_len = get_leader_len(saved_line, &lead_flags,
dir == BACKWARD, TRUE);
+ #ifdef FEAT_CINDENT
+ if (lead_len == 0 && do_cindent)
+ {
+ comment_start = check_linecomment(saved_line);
+ if (comment_start != MAXCOL)
+ {
+ lead_len = get_leader_len(saved_line + comment_start,
+ &lead_flags, dir == BACKWARD, TRUE);
+ if (lead_len != 0)
+ {
+ lead_len += comment_start;
+ if (did_do_comment != NULL)
+ *did_do_comment = TRUE;
+ }
+ }
+ }
+ #endif
+ }
else
lead_len = 0;
if (lead_len > 0)
***************
*** 1799,1806 ****
--- 1837,1851 ----
lead_len = 0;
else
{
+ int li;
+
vim_strncpy(leader, saved_line, lead_len);
+ // TODO: handle multi-byte and double width chars
+ for (li = 0; li < comment_start; ++li)
+ if (!VIM_ISWHITE(leader[li]))
+ leader[li] = ' ';
+
// Replace leader with lead_repl, right or left adjusted
if (lead_repl != NULL)
{
***************
*** 2247,2261 ****
#endif
#ifdef FEAT_CINDENT
// May do indenting after opening a new line.
! if (!p_paste
! && (curbuf->b_p_cin
! # ifdef FEAT_EVAL
! || *curbuf->b_p_inde != NUL
! # endif
! )
! && in_cinkeys(dir == FORWARD
! ? KEY_OPEN_FORW
! : KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum)))
{
do_c_expr_indent();
ai_col = (colnr_T)getwhitecols_curline();
--- 2292,2298 ----
#endif
#ifdef FEAT_CINDENT
// May do indenting after opening a new line.
! if (do_cindent)
{
do_c_expr_indent();
ai_col = (colnr_T)getwhitecols_curline();
*** ../vim-8.2.3786/src/proto/
change.pro 2021-05-16 19:18:51.025536634 +0100
--- src/proto/
change.pro 2021-12-11 22:17:55.570644043 +0000
***************
*** 27,33 ****
int del_char(int fixpos);
int del_chars(long count, int fixpos);
int del_bytes(long count, int fixpos_arg, int use_delcombine);
! int open_line(int dir, int flags, int second_line_indent);
int truncate_line(int fixpos);
void del_lines(long nlines, int undo);
/* vim: set ft=c : */
--- 27,33 ----
int del_char(int fixpos);
int del_chars(long count, int fixpos);
int del_bytes(long count, int fixpos_arg, int use_delcombine);
! int open_line(int dir, int flags, int second_line_indent, int *did_do_comment);
int truncate_line(int fixpos);
void del_lines(long nlines, int undo);
/* vim: set ft=c : */
*** ../vim-8.2.3786/src/search.c 2021-10-15 12:51:25.279073103 +0100
--- src/search.c 2021-12-11 21:37:25.708092932 +0000
***************
*** 16,22 ****
static void set_vv_searchforward(void);
static int first_submatch(regmmatch_T *rp);
#endif
- static int check_linecomment(char_u *line);
#ifdef FEAT_FIND_ID
static void show_pat_in_path(char_u *, int,
int, int, FILE *, linenr_T *, long);
--- 16,21 ----
***************
*** 2717,2723 ****
* Return MAXCOL if not, otherwise return the column.
* TODO: skip strings.
*/
! static int
check_linecomment(char_u *line)
{
char_u *p;
--- 2716,2722 ----
* Return MAXCOL if not, otherwise return the column.
* TODO: skip strings.
*/
! int
check_linecomment(char_u *line)
{
char_u *p;
*** ../vim-8.2.3786/src/proto/
search.pro 2021-04-26 20:14:12.709924759 +0100
--- src/proto/
search.pro 2021-12-11 21:37:13.312083128 +0000
***************
*** 29,34 ****
--- 29,35 ----
int searchc(cmdarg_T *cap, int t_cmd);
pos_T *findmatch(oparg_T *oap, int initc);
pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int maxtravel);
+ int check_linecomment(char_u *line);
void showmatch(int c);
int current_search(long count, int forward);
int linewhite(linenr_T lnum);
*** ../vim-8.2.3786/src/cindent.c 2021-11-19 19:41:10.107995978 +0000
--- src/cindent.c 2021-12-12 12:49:57.150453431 +0000
***************
*** 2144,2156 ****
// If we're inside a "//" comment and there is a "//" comment in a
// previous line, lineup with that one.
! if (cin_islinecomment(theline)
! && (trypos = find_line_comment()) != NULL) // XXX
{
! // find how indented the line beginning the comment is
! getvcol(curwin, trypos, &col, NULL, NULL);
! amount = col;
! goto theend;
}
// If we're inside a comment and not looking at the start of the
--- 2144,2173 ----
// If we're inside a "//" comment and there is a "//" comment in a
// previous line, lineup with that one.
! if (cin_islinecomment(theline))
{
! pos_T linecomment_pos;
!
! trypos = find_line_comment(); // XXX
! if (trypos == NULL && curwin->w_cursor.lnum > 1)
! {
! // There may be a statement before the comment, search from the end
! // of the line for a comment start.
! linecomment_pos.col =
! check_linecomment(ml_get(curwin->w_cursor.lnum - 1));
! if (linecomment_pos.col != MAXCOL)
! {
! trypos = &linecomment_pos;
! trypos->lnum = curwin->w_cursor.lnum - 1;
! }
! }
! if (trypos != NULL)
! {
! // find how indented the line beginning the comment is
! getvcol(curwin, trypos, &col, NULL, NULL);
! amount = col;
! goto theend;
! }
}
// If we're inside a comment and not looking at the start of the
*** ../vim-8.2.3786/src/edit.c 2021-12-09 11:57:19.159557375 +0000
--- src/edit.c 2021-12-11 22:14:51.514791357 +0000
***************
*** 5147,5153 ****
AppendToRedobuff(NL_STR);
i = open_line(FORWARD,
! has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0, old_indent);
old_indent = 0;
#ifdef FEAT_CINDENT
can_cindent = TRUE;
--- 5147,5154 ----
AppendToRedobuff(NL_STR);
i = open_line(FORWARD,
! has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0, old_indent,
! NULL);
old_indent = 0;
#ifdef FEAT_CINDENT
can_cindent = TRUE;
*** ../vim-8.2.3786/src/normal.c 2021-12-09 11:57:19.159557375 +0000
--- src/normal.c 2021-12-11 22:15:18.838770319 +0000
***************
*** 6511,6517 ****
) == OK
&& open_line(cap->cmdchar == 'O' ? BACKWARD : FORWARD,
has_format_option(FO_OPEN_COMS) ? OPENLINE_DO_COM : 0,
! 0) == OK)
{
#ifdef FEAT_CONCEAL
if (curwin->w_p_cole > 0 && oldline != curwin->w_cursor.lnum)
--- 6511,6517 ----
) == OK
&& open_line(cap->cmdchar == 'O' ? BACKWARD : FORWARD,
has_format_option(FO_OPEN_COMS) ? OPENLINE_DO_COM : 0,
! 0, NULL) == OK)
{
#ifdef FEAT_CONCEAL
if (curwin->w_p_cole > 0 && oldline != curwin->w_cursor.lnum)
*** ../vim-8.2.3786/src/textformat.c 2021-12-06 19:50:57.706620019 +0000
--- src/textformat.c 2021-12-11 22:17:16.318676494 +0000
***************
*** 89,94 ****
--- 89,95 ----
colnr_T col;
colnr_T end_col;
int wcc; // counter for whitespace chars
+ int did_do_comment = FALSE;
virtcol = get_nolist_virtcol()
+ char2cells(c != NUL ? c : gchar_cursor());
***************
*** 352,361 ****
+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+ (do_comments ? OPENLINE_DO_COM : 0)
+ ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
! , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
if (!(flags & INSCHAR_COM_LIST))
old_indent = 0;
replace_offset = 0;
if (first_line)
{
--- 353,368 ----
+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+ (do_comments ? OPENLINE_DO_COM : 0)
+ ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
! , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent),
! &did_do_comment);
if (!(flags & INSCHAR_COM_LIST))
old_indent = 0;
+ // If a comment leader was inserted, may also do this on a following
+ // line.
+ if (did_do_comment)
+ no_leader = FALSE;
+
replace_offset = 0;
if (first_line)
{
*** ../vim-8.2.3786/src/testdir/test_textformat.vim 2021-08-23 20:18:58.266761007 +0100
--- src/testdir/test_textformat.vim 2021-12-12 13:40:32.881060202 +0000
***************
*** 196,201 ****
--- 196,231 ----
enew!
endfunc
+ func Test_format_c_comment()
+ new
+ setl ai cindent tw=40 et fo=croql
+ let text =<< trim END
+ var = 2345; // asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
+ END
+ call setline(1, text)
+ normal gql
+ let expected =<< trim END
+ var = 2345; // asdf asdf asdf asdf asdf
+ // asdf asdf asdf asdf asdf
+ END
+ call assert_equal(expected, getline(1, '$'))
+
+ %del
+ let text =<< trim END
+ var = 2345; // asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf
+ END
+ call setline(1, text)
+ normal gql
+ let expected =<< trim END
+ var = 2345; // asdf asdf asdf asdf asdf
+ // asdf asdf asdf asdf asdf
+ // asdf asdf
+ END
+ call assert_equal(expected, getline(1, '$'))
+
+ bwipe!
+ endfunc
+
" Tests for :right, :center and :left on text with embedded TAB.
func Test_format_align()
enew!
*** ../vim-8.2.3786/src/testdir/test_cindent.vim 2021-11-19 19:41:10.107995978 +0000
--- src/testdir/test_cindent.vim 2021-12-12 13:00:09.909325988 +0000
***************
*** 1694,1702 ****
#endif
int y; // comment
! // comment
! // comment
{
Constructor(int a,
--- 1694,1702 ----
#endif
int y; // comment
! // comment
! // comment
{
Constructor(int a,
*** ../vim-8.2.3786/src/version.c 2021-12-11 18:46:26.303603871 +0000
--- src/version.c 2021-12-11 22:20:14.066525852 +0000
***************
*** 755,756 ****
--- 755,758 ----
{ /* Add new patch number below this line */
+ /**/
+ 3787,
/**/
--
How To Keep A Healthy Level Of Insanity:
15. Five days in advance, tell your friends you can't attend their
party because you're not in the mood.
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///