Patch 8.2.3938
Problem:    Line comment start is also found in a string.
Solution:   Skip line comments in a string.
Files:      src/cindent.c, src/proto/cindent.pro, src/search.c,
            src/testdir/test_textformat.vim


*** ../vim-8.2.3937/src/cindent.c       2021-12-27 17:21:38.000449144 +0000
--- src/cindent.c       2021-12-29 18:00:43.171290685 +0000
***************
*** 66,73 ****
  }
  #endif
  
- #if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL)
- 
  /*
   * Skip to the end of a "string" and a 'c' character.
   * If there is no string or character, return argument unmodified.
--- 66,71 ----
***************
*** 138,143 ****
--- 136,156 ----
  }
  
  /*
+  * Return TRUE if "line[col]" is inside a C string.
+  */
+     int
+ is_pos_in_string(char_u *line, colnr_T col)
+ {
+     char_u *p;
+ 
+     for (p = line; *p && (colnr_T)(p - line) < col; ++p)
+       p = skip_string(p);
+     return !((colnr_T)(p - line) <= col);
+ }
+ 
+ #if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL)
+ 
+ /*
   * Find the start of a comment, not knowing if we are in a comment right now.
   * Search starts at w_cursor.lnum and goes backwards.
   * Return NULL when not inside a comment.
***************
*** 152,159 ****
  find_start_comment(int ind_maxcomment)        // XXX
  {
      pos_T     *pos;
-     char_u    *line;
-     char_u    *p;
      int               cur_maxcomment = ind_maxcomment;
  
      for (;;)
--- 165,170 ----
***************
*** 164,173 ****
  
        // Check if the comment start we found is inside a string.
        // If it is then restrict the search to below this line and try again.
!       line = ml_get(pos->lnum);
!       for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
!           p = skip_string(p);
!       if ((colnr_T)(p - line) <= pos->col)
            break;
        cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
        if (cur_maxcomment <= 0)
--- 175,181 ----
  
        // Check if the comment start we found is inside a string.
        // If it is then restrict the search to below this line and try again.
!       if (!is_pos_in_string(ml_get(pos->lnum), pos->col))
            break;
        cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
        if (cur_maxcomment <= 0)
***************
*** 188,195 ****
  find_start_rawstring(int ind_maxcomment)      // XXX
  {
      pos_T     *pos;
-     char_u    *line;
-     char_u    *p;
      int               cur_maxcomment = ind_maxcomment;
  
      for (;;)
--- 196,201 ----
***************
*** 200,209 ****
  
        // Check if the raw string start we found is inside a string.
        // If it is then restrict the search to below this line and try again.
!       line = ml_get(pos->lnum);
!       for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
!           p = skip_string(p);
!       if ((colnr_T)(p - line) <= pos->col)
            break;
        cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
        if (cur_maxcomment <= 0)
--- 206,212 ----
  
        // Check if the raw string start we found is inside a string.
        // If it is then restrict the search to below this line and try again.
!       if (!is_pos_in_string(ml_get(pos->lnum), pos->col))
            break;
        cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
        if (cur_maxcomment <= 0)
*** ../vim-8.2.3937/src/proto/cindent.pro       2019-12-12 11:55:15.000000000 
+0000
--- src/proto/cindent.pro       2021-12-29 18:02:24.999114508 +0000
***************
*** 1,5 ****
--- 1,6 ----
  /* cindent.c */
  int cin_is_cinword(char_u *line);
+ int is_pos_in_string(char_u *line, colnr_T col);
  pos_T *find_start_comment(int ind_maxcomment);
  int cindent_on(void);
  void parse_cino(buf_T *buf);
*** ../vim-8.2.3937/src/search.c        2021-12-12 14:16:34.989862195 +0000
--- src/search.c        2021-12-29 18:06:39.946692667 +0000
***************
*** 2714,2720 ****
  /*
   * Check if line[] contains a / / comment.
   * Return MAXCOL if not, otherwise return the column.
-  * TODO: skip strings.
   */
      int
  check_linecomment(char_u *line)
--- 2714,2719 ----
***************
*** 2746,2752 ****
                        in_str = TRUE;
                }
                else if (!in_str && ((p - line) < 2
!                                   || (*(p - 1) != '\\' && *(p - 2) != '#')))
                    break;      // found!
                ++p;
            }
--- 2745,2752 ----
                        in_str = TRUE;
                }
                else if (!in_str && ((p - line) < 2
!                                   || (*(p - 1) != '\\' && *(p - 2) != '#'))
!                              && !is_pos_in_string(line, (colnr_T)(p - line)))
                    break;      // found!
                ++p;
            }
***************
*** 2758,2766 ****
  #endif
      while ((p = vim_strchr(p, '/')) != NULL)
      {
!       // accept a double /, unless it's preceded with * and followed by *,
!       // because * / / * is an end and start of a C comment
!       if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*'))
            break;
        ++p;
      }
--- 2758,2768 ----
  #endif
      while ((p = vim_strchr(p, '/')) != NULL)
      {
!       // Accept a double /, unless it's preceded with * and followed by *,
!       // because * / / * is an end and start of a C comment.
!       // Only accept the position if it is not inside a string.
!       if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')
!                              && !is_pos_in_string(line, (colnr_T)(p - line)))
            break;
        ++p;
      }
*** ../vim-8.2.3937/src/testdir/test_textformat.vim     2021-12-29 
16:05:28.026222402 +0000
--- src/testdir/test_textformat.vim     2021-12-29 18:05:13.674832781 +0000
***************
*** 261,266 ****
--- 261,281 ----
    END
    call assert_equal(expected, getline(1, '$'))
  
+   " Using "o" does not repeat a comment in a string
+   %del
+   let text =<< trim END
+       nop;
+       val = " // This is not a comment";
+   END
+   call setline(1, text)
+   normal 2Gox
+   let expected =<< trim END
+       nop;
+       val = " // This is not a comment";
+       x
+   END
+   call assert_equal(expected, getline(1, '$'))
+ 
    " Using CTRL-U after "o" fixes the indent
    %del
    let text =<< trim END
*** ../vim-8.2.3937/src/version.c       2021-12-29 17:38:42.301517624 +0000
--- src/version.c       2021-12-29 17:57:11.799676795 +0000
***************
*** 751,752 ****
--- 751,754 ----
  {   /* Add new patch number below this line */
+ /**/
+     3938,
  /**/

-- 
Drink wet cement and get really stoned.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20211229181114.16A151C0641%40moolenaar.net.

Raspunde prin e-mail lui