mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	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:
		
				
					committed by
					
						
						Justin M. Keyes
					
				
			
			
				
	
			
			
			
						parent
						
							c42aebf23e
						
					
				
				
					commit
					71d4b81b4c
				
			@@ -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"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user