To: vim_dev@googlegroups.com Subject: Patch 8.2.3787 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@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 ///