vim-patch:8.0.0453 (#6266)

Problem:    Adding fold marker creates new comment.
Solution:   Use an existing comment if possible. (LemonBoy, closes vim/vim#1549)

025a6b708a
This commit is contained in:
Matthieu Coudron 2017-03-13 01:54:35 +01:00 committed by Justin M. Keyes
parent c42aebf23e
commit 71d4b81b4c
4 changed files with 58 additions and 33 deletions

View File

@ -29,6 +29,7 @@
#include "nvim/strings.h" #include "nvim/strings.h"
#include "nvim/syntax.h" #include "nvim/syntax.h"
#include "nvim/undo.h" #include "nvim/undo.h"
#include "nvim/ops.h"
/* local declarations. {{{1 */ /* local declarations. {{{1 */
/* typedef fold_T {{{2 */ /* typedef fold_T {{{2 */
@ -1593,29 +1594,32 @@ static void foldCreateMarkers(linenr_T start, linenr_T end)
/* /*
* Add "marker[markerlen]" in 'commentstring' to line "lnum". * Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/ */
static void foldAddMarker(linenr_T lnum, char_u *marker, size_t markerlen) static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
{ {
char_u *cms = curbuf->b_p_cms; char_u *cms = curbuf->b_p_cms;
char_u *line; char_u *line;
char_u *newline; char_u *newline;
char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s"); char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
bool line_is_comment = false;
/* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */ // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
line = ml_get(lnum); line = ml_get(lnum);
size_t line_len = STRLEN(line); size_t line_len = STRLEN(line);
if (u_save(lnum - 1, lnum + 1) == OK) { if (u_save(lnum - 1, lnum + 1) == OK) {
// Check if the line ends with an unclosed comment
skip_comment(line, false, false, &line_is_comment);
newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1); newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1);
STRCPY(newline, line); STRCPY(newline, line);
if (p == NULL) // Append the marker to the end of the line
if (p == NULL || line_is_comment) {
STRLCPY(newline + line_len, marker, markerlen + 1); STRLCPY(newline + line_len, marker, markerlen + 1);
else { } else {
STRCPY(newline + line_len, cms); STRCPY(newline + line_len, cms);
memcpy(newline + line_len + (p - cms), marker, markerlen); memcpy(newline + line_len + (p - cms), marker, markerlen);
STRCPY(newline + line_len + (p - cms) + markerlen, p + 2); STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
} }
ml_replace(lnum, newline, false);
ml_replace(lnum, newline, FALSE);
} }
} }
@ -2535,10 +2539,10 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
* 1 2 3 * 1 2 3
* 1 2 3 * 1 2 3
* top 2 3 4 5 * top 2 3 4 5
* 2 3 4 5 * 2 3 4 5
* bot 2 3 4 5 * bot 2 3 4 5
* 3 5 6 * 3 5 6
* 3 5 6 * 3 5 6
* *
* 1: not changed * 1: not changed
* 2: truncate to stop above "top" * 2: truncate to stop above "top"

View File

@ -2318,7 +2318,7 @@ ml_append_int (
* *
* return FAIL for failure, OK otherwise * return FAIL for failure, OK otherwise
*/ */
int ml_replace(linenr_T lnum, char_u *line, int copy) int ml_replace(linenr_T lnum, char_u *line, bool copy)
{ {
if (line == NULL) /* just checking... */ if (line == NULL) /* just checking... */
return FAIL; return FAIL;

View File

@ -3438,43 +3438,47 @@ dis_msg (
os_breakcheck(); os_breakcheck();
} }
/* /// If \p "process" is true and the line begins with a comment leader (possibly
* If "process" is TRUE and the line begins with a comment leader (possibly /// after some white space), return a pointer to the text after it.
* after some white space), return a pointer to the text after it. Put a boolean /// Put a boolean value indicating whether the line ends with an unclosed
* value indicating whether the line ends with an unclosed comment in /// comment in "is_comment".
* "is_comment". ///
* line - line to be processed, /// @param line - line to be processed
* process - if FALSE, will only check whether the line ends with an unclosed /// @param process - if false, will only check whether the line ends
* comment, /// with an unclosed comment,
* include_space - whether to also skip space following the comment leader, /// @param include_space - whether to skip space following the comment leader
* is_comment - will indicate whether the current line ends with an unclosed /// @param[out] is_comment - whether the current line ends with an unclosed
* comment. /// comment.
*/ char_u *skip_comment(
static char_u *skip_comment(char_u *line, int process, int include_space, int *is_comment) char_u *line, bool process, bool include_space, bool *is_comment
)
{ {
char_u *comment_flags = NULL; char_u *comment_flags = NULL;
int lead_len; int lead_len;
int leader_offset = get_last_leader_offset(line, &comment_flags); int leader_offset = get_last_leader_offset(line, &comment_flags);
*is_comment = FALSE; *is_comment = false;
if (leader_offset != -1) { if (leader_offset != -1) {
/* Let's check whether the line ends with an unclosed comment. /* Let's check whether the line ends with an unclosed comment.
* If the last comment leader has COM_END in flags, there's no comment. * If the last comment leader has COM_END in flags, there's no comment.
*/ */
while (*comment_flags) { while (*comment_flags) {
if (*comment_flags == COM_END if (*comment_flags == COM_END
|| *comment_flags == ':') || *comment_flags == ':') {
break; break;
++comment_flags; }
comment_flags++;
}
if (*comment_flags != COM_END) {
*is_comment = true;
} }
if (*comment_flags != COM_END)
*is_comment = TRUE;
} }
if (process == FALSE) if (process == false) {
return line; return line;
}
lead_len = get_leader_len(line, &comment_flags, FALSE, include_space); lead_len = get_leader_len(line, &comment_flags, false, include_space);
if (lead_len == 0) if (lead_len == 0)
return line; return line;
@ -3496,8 +3500,9 @@ static char_u *skip_comment(char_u *line, int process, int include_space, int *i
* starting with a closing part of a three-part comment. That's good, * starting with a closing part of a three-part comment. That's good,
* because we don't want to remove those as this would be annoying. * because we don't want to remove those as this would be annoying.
*/ */
if (*comment_flags == ':' || *comment_flags == NUL) if (*comment_flags == ':' || *comment_flags == NUL) {
line += lead_len; line += lead_len;
}
return line; return line;
} }
@ -3531,7 +3536,7 @@ int do_join(size_t count,
int *comments = NULL; int *comments = NULL;
int remove_comments = (use_formatoptions == TRUE) int remove_comments = (use_formatoptions == TRUE)
&& has_format_option(FO_REMOVE_COMS); && has_format_option(FO_REMOVE_COMS);
int prev_was_comment; bool prev_was_comment;
if (save_undo && u_save(curwin->w_cursor.lnum - 1, if (save_undo && u_save(curwin->w_cursor.lnum - 1,
curwin->w_cursor.lnum + (linenr_T)count) == FAIL) { curwin->w_cursor.lnum + (linenr_T)count) == FAIL) {

View File

@ -96,6 +96,22 @@ func! Test_indent_fold2()
bw! bw!
endfunc endfunc
func Test_folds_marker_in_comment()
new
call setline(1, ['" foo', 'bar', 'baz'])
setl fen fdm=marker
setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
norm! zf2j
setl nofen
:1y
call assert_equal(['" foo{{{'], getreg(0,1,1))
:+2y
call assert_equal(['baz"}}}'], getreg(0,1,1))
set foldmethod&
bwipe!
endfunc
func Test_manual_fold_with_filter() func Test_manual_fold_with_filter()
if !executable('cat') if !executable('cat')
return return