Patch 8.2.3787

9 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 12, 2021, 9:17:56 AM12/12/21
to vim...@googlegroups.com

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 ///

Gary Johnson

unread,
Dec 12, 2021, 1:38:12 PM12/12/21
to vim...@googlegroups.com
On 2021-12-12, Bram Moolenaar wrote:
> 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.

This is great! Thank you.

Regards,
Gary

John Marriott

unread,
Dec 12, 2021, 1:49:41 PM12/12/21
to vim...@googlegroups.com


On 13-Dec-2021 01:17, Bram Moolenaar wrote:
> 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
>
Hi All,

After this patch, mingw64 (gcc 11.2.0) spits out this compile error if
FEAT_SMARTINDENT is not defined:
<snip>
gcc -c -I. -Iproto -DWIN32 -DWINVER=0x0603 -D_WIN32_WINNT=0x0603
-DHAVE_PATHDEF -DFEAT_NORMAL -DHAVE_STDINT_H -D__USE_MINGW_ANSI_STDIO
-pipe -march=native -Wall -O3 -fomit-frame-pointer -freg-struct-return
-fpie -fPIE  change.c -o objnative/change.o
change.c: In function 'open_line':
change.c:1644:5: error: 'do_cindent' undeclared (first use in this
function); did you mean 'f_cindent'?
 1644 |     do_cindent = !p_paste && (curbuf->b_p_cin
      |     ^~~~~~~~~~
      |     f_cindent
change.c:1644:5: note: each undeclared identifier is reported only once
for each function it appears in
make: *** [Make_cyg_ming.mak:1159: objnative/change.o] Error 1
</snip>

The attached patch tries to fix it.

Cheers
change.c.8.2.3787.patch

Bram Moolenaar

unread,
Dec 12, 2021, 2:11:32 PM12/12/21
to vim...@googlegroups.com, John Marriott

John Marriott wrote:

> On 13-Dec-2021 01:17, Bram Moolenaar wrote:
> > 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
> >
> Hi All,
>
> After this patch, mingw64 (gcc 11.2.0) spits out this compile error if
> FEAT_SMARTINDENT is not defined:
> <snip>
> gcc -c -I. -Iproto -DWIN32 -DWINVER=0x0603 -D_WIN32_WINNT=0x0603
> -DHAVE_PATHDEF -DFEAT_NORMAL -DHAVE_STDINT_H -D__USE_MINGW_ANSI_STDIO
> -pipe -march=native -Wall -O3 -fomit-frame-pointer -freg-struct-return
> -fpie -fPIE  change.c -o objnative/change.o
> change.c: In function 'open_line':
> change.c:1644:5: error: 'do_cindent' undeclared (first use in this
> function); did you mean 'f_cindent'?
>  1644 |     do_cindent = !p_paste && (curbuf->b_p_cin
>       |     ^~~~~~~~~~
>       |     f_cindent
> change.c:1644:5: note: each undeclared identifier is reported only once
> for each function it appears in
> make: *** [Make_cyg_ming.mak:1159: objnative/change.o] Error 1
> </snip>
>
> The attached patch tries to fix it.

That looks good, I'll include it. Thanks!

--
In many of the more relaxed civilizations on the Outer Eastern Rim of the
Galaxy, "The Hitchhiker's Guide to the Galaxy" has already supplanted the
great "Encyclopedia Galactica" as the standard repository of all knowledge
and wisdom, for though it has many omissions and contains much that is
apocryphal, or at least wildly inaccurate, it scores over the older, more
pedestrian work in two important respects.
First, it is slightly cheaper; and second, it has the words "DON'T PANIC"
inscribed in large friendly letters on its cover.
-- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"
Reply all
Reply to author
Forward
0 new messages