Patch 7.4.803
Problem:    C indent does not support C11 raw strings. (Mark Lodato)
Solution:   Do not change indent inside the raw string.
Files:      src/search.c, src/misc1.c, src/edit.c, src/ops.c,
            src/testdir/test3.in, src/testdir/test3.ok


*** ../vim-7.4.802/src/search.c 2015-07-21 17:53:11.585527913 +0200
--- src/search.c        2015-07-28 21:14:08.968071627 +0200
***************
*** 1725,1744 ****
      return (col >= 0 && linep[col] == ch) ? TRUE : FALSE;
  }
  
  /*
   * findmatchlimit -- find the matching paren or brace, if it exists within
!  * maxtravel lines of here.  A maxtravel of 0 means search until falling off
!  * the edge of the file.
   *
   * "initc" is the character to find a match for.  NUL means to find the
!  * character at or after the cursor.
   *
   * flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#')
   *      FM_FORWARD    search forwards (when initc is '/', '*' or '#')
   *      FM_BLOCKSTOP  stop at start/end of block ({ or } in column 0)
   *      FM_SKIPCOMM   skip comments (not implemented yet!)
   *
!  * "oap" is only used to set oap->motion_type for a linewise motion, it be
   * NULL
   */
  
--- 1725,1795 ----
      return (col >= 0 && linep[col] == ch) ? TRUE : FALSE;
  }
  
+ static int find_rawstring_end __ARGS((char_u *linep, pos_T *startpos, pos_T 
*endpos));
+ 
+ /*
+  * Raw string start is found at linep[startpos.col - 1].
+  * Return TRUE if the matching end can be found between startpos and endpos.
+  */
+     static int
+ find_rawstring_end(linep, startpos, endpos)
+     char_u  *linep;
+     pos_T   *startpos;
+     pos_T   *endpos;
+ {
+     char_u    *p;
+     char_u    *delim_copy;
+     size_t    delim_len;
+     linenr_T  lnum;
+     int               found = FALSE;
+ 
+     for (p = linep + startpos->col + 1; *p && *p != '('; ++p)
+       ;
+     delim_len = (p - linep) - startpos->col - 1;
+     delim_copy = vim_strnsave(linep + startpos->col + 1, delim_len);
+     if (delim_copy == NULL)
+       return FALSE;
+     for (lnum = startpos->lnum; lnum <= endpos->lnum; ++lnum)
+     {
+       char_u *line = ml_get(lnum);
+ 
+       for (p = line + (lnum == startpos->lnum
+                                           ? startpos->col + 1 : 0); *p; ++p)
+       {
+           if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col)
+               break;
+           if (*p == ')' && p[delim_len + 1] == '"'
+                         && STRNCMP(delim_copy, p + 1, delim_len) == 0)
+           {
+               found = TRUE;
+               break;
+           }
+       }
+       if (found)
+           break;
+     }
+     vim_free(delim_copy);
+     return found;
+ }
+ 
  /*
   * findmatchlimit -- find the matching paren or brace, if it exists within
!  * maxtravel lines of the cursor.  A maxtravel of 0 means search until falling
!  * off the edge of the file.
   *
   * "initc" is the character to find a match for.  NUL means to find the
!  * character at or after the cursor. Special values:
!  * '*'  look for C-style comment / *
!  * '/'  look for C-style comment / *, ignoring comment-end
!  * '#'  look for preprocessor directives
!  * 'R'  look for raw string start: R"delim(text)delim" (only backwards)
   *
   * flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#')
   *      FM_FORWARD    search forwards (when initc is '/', '*' or '#')
   *      FM_BLOCKSTOP  stop at start/end of block ({ or } in column 0)
   *      FM_SKIPCOMM   skip comments (not implemented yet!)
   *
!  * "oap" is only used to set oap->motion_type for a linewise motion, it can be
   * NULL
   */
  
***************
*** 1754,1759 ****
--- 1805,1811 ----
      int               c;
      int               count = 0;              /* cumulative number of braces 
*/
      int               backwards = FALSE;      /* init for gcc */
+     int               raw_string = FALSE;     /* search for raw string */
      int               inquote = FALSE;        /* TRUE when inside quotes */
      char_u    *linep;                 /* pointer to current line */
      char_u    *ptr;
***************
*** 1798,1809 ****
       * When '/' is used, we ignore running backwards into an star-slash, for
       * "[*" command, we just want to find any comment.
       */
!     if (initc == '/' || initc == '*')
      {
        comment_dir = dir;
        if (initc == '/')
            ignore_cend = TRUE;
        backwards = (dir == FORWARD) ? FALSE : TRUE;
        initc = NUL;
      }
      else if (initc != '#' && initc != NUL)
--- 1850,1862 ----
       * When '/' is used, we ignore running backwards into an star-slash, for
       * "[*" command, we just want to find any comment.
       */
!     if (initc == '/' || initc == '*' || initc == 'R')
      {
        comment_dir = dir;
        if (initc == '/')
            ignore_cend = TRUE;
        backwards = (dir == FORWARD) ? FALSE : TRUE;
+       raw_string = (initc == 'R');
        initc = NUL;
      }
      else if (initc != '#' && initc != NUL)
***************
*** 1812,1823 ****
        if (findc == NUL)
            return NULL;
      }
-     /*
-      * Either initc is '#', or no initc was given and we need to look under 
the
-      * cursor.
-      */
      else
      {
        if (initc == '#')
        {
            hash_dir = dir;
--- 1865,1876 ----
        if (findc == NUL)
            return NULL;
      }
      else
      {
+       /*
+        * Either initc is '#', or no initc was given and we need to look
+        * under the cursor.
+        */
        if (initc == '#')
        {
            hash_dir = dir;
***************
*** 2135,2140 ****
--- 2188,2213 ----
                 */
                if (pos.col == 0)
                    continue;
+               else if (raw_string)
+               {
+                   if (linep[pos.col - 1] == 'R'
+                       && linep[pos.col] == '"'
+                       && vim_strchr(linep + pos.col + 1, '(') != NULL)
+                   {
+                       /* Possible start of raw string. Now that we have the
+                        * delimiter we can check if it ends before where we
+                        * started searching, or before the previously found
+                        * raw string start. */
+                       if (!find_rawstring_end(linep, &pos,
+                                 count > 0 ? &match_pos : &curwin->w_cursor))
+                       {
+                           count++;
+                           match_pos = pos;
+                           match_pos.col--;
+                       }
+                       linep = ml_get(pos.lnum); /* may have been released */
+                   }
+               }
                else if (  linep[pos.col - 1] == '/'
                        && linep[pos.col] == '*'
                        && (int)pos.col < comment_col)
*** ../vim-7.4.802/src/misc1.c  2015-07-21 17:53:11.581527951 +0200
--- src/misc1.c 2015-07-28 21:06:38.908518760 +0200
***************
*** 5267,5276 ****
--- 5267,5279 ----
  
  static char_u *skip_string __ARGS((char_u *p));
  static pos_T *ind_find_start_comment __ARGS((void));
+ static pos_T *ind_find_start_CORS __ARGS((void));
+ static pos_T *find_start_rawstring __ARGS((int ind_maxcomment));
  
  /*
   * 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.
   */
      static pos_T *
  ind_find_start_comment()          /* XXX */
***************
*** 5313,5318 ****
--- 5316,5380 ----
  }
  
  /*
+  * Find the start of a comment or raw string, not knowing if we are in a
+  * comment or raw string right now.
+  * Search starts at w_cursor.lnum and goes backwards.
+  * Return NULL when not inside a comment or raw string.
+  * "CORS" -> Comment Or Raw String
+  */
+     static pos_T *
+ ind_find_start_CORS()     /* XXX */
+ {
+     pos_T     *comment_pos = find_start_comment(curbuf->b_ind_maxcomment);
+     pos_T     *rs_pos = find_start_rawstring(curbuf->b_ind_maxcomment);
+ 
+     /* If comment_pos is before rs_pos the raw string is inside the comment.
+      * If rs_pos is before comment_pos the comment is inside the raw string. 
*/
+     if (comment_pos == NULL || (rs_pos != NULL && lt(*rs_pos, *comment_pos)))
+       return rs_pos;
+     return comment_pos;
+ }
+ 
+ /*
+  * Find the start of a raw string, not knowing if we are in one right now.
+  * Search starts at w_cursor.lnum and goes backwards.
+  * Return NULL when not inside a raw string.
+  */
+     static pos_T *
+ find_start_rawstring(ind_maxcomment)      /* XXX */
+     int               ind_maxcomment;
+ {
+     pos_T     *pos;
+     char_u    *line;
+     char_u    *p;
+     int               cur_maxcomment = ind_maxcomment;
+ 
+     for (;;)
+     {
+       pos = findmatchlimit(NULL, 'R', FM_BACKWARD, cur_maxcomment);
+       if (pos == NULL)
+           break;
+ 
+       /*
+        * 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)
+       {
+           pos = NULL;
+           break;
+       }
+     }
+     return pos;
+ }
+ 
+ /*
   * Skip to the end of a "string" and a 'c' character.
   * If there is no string or character, return argument unmodified.
   */
***************
*** 5354,5360 ****
                    break;
            }
            if (p[0] == '"')
!               continue;
        }
        break;                              /* no string found */
      }
--- 5416,5443 ----
                    break;
            }
            if (p[0] == '"')
!               continue; /* continue for another string */
!       }
!       else if (p[0] == 'R' && p[1] == '"')
!       {
!           /* Raw string: R"[delim](...)[delim]" */
!           char_u *delim = p + 2;
!           char_u *paren = vim_strchr(delim, '(');
! 
!           if (paren != NULL)
!           {
!               size_t delim_len = paren - delim;
! 
!               for (p += 3; *p; ++p)
!                   if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0
!                           && p[delim_len + 1] == '"')
!                   {
!                       p += delim_len + 1;
!                       break;
!                   }
!               if (p[0] == '"')
!                   continue; /* continue for another string */
!           }
        }
        break;                              /* no string found */
      }
***************
*** 5596,5605 ****
            --curwin->w_cursor.lnum;
  
            /*
!            * If we're in a comment now, skip to the start of the comment.
             */
            curwin->w_cursor.col = 0;
!           if ((trypos = ind_find_start_comment()) != NULL) /* XXX */
                curwin->w_cursor = *trypos;
  
            line = ml_get_curline();
--- 5679,5689 ----
            --curwin->w_cursor.lnum;
  
            /*
!            * If we're in a comment or raw string now, skip to the start of
!            * it.
             */
            curwin->w_cursor.col = 0;
!           if ((trypos = ind_find_start_CORS()) != NULL) /* XXX */
                curwin->w_cursor = *trypos;
  
            line = ml_get_curline();
***************
*** 6454,6460 ****
                continue;
        }
  
!       if (s[0] == '"')
            s = skip_string(s) + 1;
        else if (s[0] == ':')
        {
--- 6538,6544 ----
                continue;
        }
  
!       if (s[0] == '"' || (s[0] == 'R' && s[1] == '"'))
            s = skip_string(s) + 1;
        else if (s[0] == ':')
        {
***************
*** 6660,6666 ****
        pos = NULL;
        /* ignore the { if it's in a // or / *  * / comment */
        if ((colnr_T)cin_skip2pos(trypos) == trypos->col
!                      && (pos = ind_find_start_comment()) == NULL) /* XXX */
            break;
        if (pos != NULL)
            curwin->w_cursor.lnum = pos->lnum;
--- 6744,6750 ----
        pos = NULL;
        /* ignore the { if it's in a // or / *  * / comment */
        if ((colnr_T)cin_skip2pos(trypos) == trypos->col
!                      && (pos = ind_find_start_CORS()) == NULL) /* XXX */
            break;
        if (pos != NULL)
            curwin->w_cursor.lnum = pos->lnum;
***************
*** 6714,6720 ****
            pos_copy = *trypos;     /* copy trypos, findmatch will change it */
            trypos = &pos_copy;
            curwin->w_cursor = *trypos;
!           if ((trypos_wk = ind_find_start_comment()) != NULL) /* XXX */
            {
                ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum
                        - trypos_wk->lnum);
--- 6798,6804 ----
            pos_copy = *trypos;     /* copy trypos, findmatch will change it */
            trypos = &pos_copy;
            curwin->w_cursor = *trypos;
!           if ((trypos_wk = ind_find_start_CORS()) != NULL) /* XXX */
            {
                ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum
                        - trypos_wk->lnum);
***************
*** 7029,7034 ****
--- 7113,7122 ----
      }
  }
  
+ /*
+  * Return the desired indent for C code.
+  * Return -1 if the indent should be left alone (inside a raw string).
+  */
      int
  get_c_indent()
  {
***************
*** 7040,7047 ****
      char_u    *theline;
      char_u    *linecopy;
      pos_T     *trypos;
      pos_T     *tryposBrace = NULL;
!     pos_T     tryposBraceCopy;
      pos_T     our_paren_pos;
      char_u    *start;
      int               start_brace;
--- 7128,7136 ----
      char_u    *theline;
      char_u    *linecopy;
      pos_T     *trypos;
+     pos_T     *comment_pos;
      pos_T     *tryposBrace = NULL;
!     pos_T     tryposCopy;
      pos_T     our_paren_pos;
      char_u    *start;
      int               start_brace;
***************
*** 7085,7091 ****
      /* remember where the cursor was when we started */
      cur_curpos = curwin->w_cursor;
  
!     /* if we are at line 1 0 is fine, right? */
      if (cur_curpos.lnum == 1)
        return 0;
  
--- 7174,7180 ----
      /* remember where the cursor was when we started */
      cur_curpos = curwin->w_cursor;
  
!     /* if we are at line 1 zero indent is fine, right? */
      if (cur_curpos.lnum == 1)
        return 0;
  
***************
*** 7117,7157 ****
      original_line_islabel = cin_islabel();  /* XXX */
  
      /*
       * #defines and so on always go at the left when included in 'cinkeys'.
       */
      if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE)))
        amount = curbuf->b_ind_hash_comment;
  
      /*
       * Is it a non-case label?        Then that goes at the left margin too 
unless:
       *  - JS flag is set.
       *  - 'L' item has a positive value.
       */
!     else if (original_line_islabel && !curbuf->b_ind_js
                                              && curbuf->b_ind_jump_label < 0)
      {
        amount = 0;
      }
  
      /*
       * If we're inside a "//" comment and there is a "//" comment in a
       * previous line, lineup with that one.
       */
!     else 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;
      }
  
      /*
       * If we're inside a comment and not looking at the start of the
       * comment, try using the 'comments' option.
       */
!     else if (!cin_iscomment(theline)
!                              && (trypos = ind_find_start_comment()) != NULL)
!       /* XXX */
      {
        int     lead_start_len = 2;
        int     lead_middle_len = 1;
--- 7206,7267 ----
      original_line_islabel = cin_islabel();  /* XXX */
  
      /*
+      * If we are inside a raw string don't change the indent.
+      * Ignore a raw string inside a comment.
+      */
+     comment_pos = ind_find_start_comment();
+     if (comment_pos != NULL)
+     {
+       /* findmatchlimit() static pos is overwritten, make a copy */
+       tryposCopy = *comment_pos;
+       comment_pos = &tryposCopy;
+     }
+     trypos = find_start_rawstring(curbuf->b_ind_maxcomment);
+     if (trypos != NULL && (comment_pos == NULL || lt(*trypos, *comment_pos)))
+     {
+       amount = -1;
+       goto laterend;
+     }
+ 
+     /*
       * #defines and so on always go at the left when included in 'cinkeys'.
       */
      if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE)))
+     {
        amount = curbuf->b_ind_hash_comment;
+       goto theend;
+     }
  
      /*
       * Is it a non-case label?        Then that goes at the left margin too 
unless:
       *  - JS flag is set.
       *  - 'L' item has a positive value.
       */
!     if (original_line_islabel && !curbuf->b_ind_js
                                              && curbuf->b_ind_jump_label < 0)
      {
        amount = 0;
+       goto theend;
      }
  
      /*
       * 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
       * comment, try using the 'comments' option.
       */
!     if (!cin_iscomment(theline) && comment_pos != NULL) /* XXX */
      {
        int     lead_start_len = 2;
        int     lead_middle_len = 1;
***************
*** 7164,7170 ****
        int     done = FALSE;
  
        /* find how indented the line beginning the comment is */
!       getvcol(curwin, trypos, &col, NULL, NULL);
        amount = col;
        *lead_start = NUL;
        *lead_middle = NUL;
--- 7274,7280 ----
        int     done = FALSE;
  
        /* find how indented the line beginning the comment is */
!       getvcol(curwin, comment_pos, &col, NULL, NULL);
        amount = col;
        *lead_start = NUL;
        *lead_middle = NUL;
***************
*** 7228,7234 ****
                        }
                        /* If the start comment string doesn't match with the
                         * start of the comment, skip this entry. XXX */
!                       else if (STRNCMP(ml_get(trypos->lnum) + trypos->col,
                                             lead_start, lead_start_len) != 0)
                            continue;
                    }
--- 7338,7344 ----
                        }
                        /* If the start comment string doesn't match with the
                         * start of the comment, skip this entry. XXX */
!                       else if (STRNCMP(ml_get(comment_pos->lnum) + 
comment_pos->col,
                                             lead_start, lead_start_len) != 0)
                            continue;
                    }
***************
*** 7276,7282 ****
             * otherwise, add the amount specified by "c" in 'cino'
             */
            amount = -1;
!           for (lnum = cur_curpos.lnum - 1; lnum > trypos->lnum; --lnum)
            {
                if (linewhite(lnum))                /* skip blank lines */
                    continue;
--- 7386,7392 ----
             * otherwise, add the amount specified by "c" in 'cino'
             */
            amount = -1;
!           for (lnum = cur_curpos.lnum - 1; lnum > comment_pos->lnum; --lnum)
            {
                if (linewhite(lnum))                /* skip blank lines */
                    continue;
***************
*** 7287,7319 ****
            {
                if (!curbuf->b_ind_in_comment2)
                {
!                   start = ml_get(trypos->lnum);
!                   look = start + trypos->col + 2; /* skip / and * */
                    if (*look != NUL)               /* if something after it */
!                       trypos->col = (colnr_T)(skipwhite(look) - start);
                }
!               getvcol(curwin, trypos, &col, NULL, NULL);
                amount = col;
                if (curbuf->b_ind_in_comment2 || *look == NUL)
                    amount += curbuf->b_ind_in_comment;
            }
        }
      }
  
      /*
       * Are we looking at a ']' that has a match?
       */
!     else if (*skipwhite(theline) == ']'
            && (trypos = find_match_char('[', curbuf->b_ind_maxparen)) != NULL)
      {
        /* align with the line containing the '['. */
        amount = get_indent_lnum(trypos->lnum);
      }
  
      /*
       * Are we inside parentheses or braces?
       */                                                   /* XXX */
!     else if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL
                && curbuf->b_ind_java == 0)
            || (tryposBrace = find_start_brace()) != NULL
            || trypos != NULL)
--- 7397,7431 ----
            {
                if (!curbuf->b_ind_in_comment2)
                {
!                   start = ml_get(comment_pos->lnum);
!                   look = start + comment_pos->col + 2; /* skip / and * */
                    if (*look != NUL)               /* if something after it */
!                       comment_pos->col = (colnr_T)(skipwhite(look) - start);
                }
!               getvcol(curwin, comment_pos, &col, NULL, NULL);
                amount = col;
                if (curbuf->b_ind_in_comment2 || *look == NUL)
                    amount += curbuf->b_ind_in_comment;
            }
        }
+       goto theend;
      }
  
      /*
       * Are we looking at a ']' that has a match?
       */
!     if (*skipwhite(theline) == ']'
            && (trypos = find_match_char('[', curbuf->b_ind_maxparen)) != NULL)
      {
        /* align with the line containing the '['. */
        amount = get_indent_lnum(trypos->lnum);
+       goto theend;
      }
  
      /*
       * Are we inside parentheses or braces?
       */                                                   /* XXX */
!     if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL
                && curbuf->b_ind_java == 0)
            || (tryposBrace = find_start_brace()) != NULL
            || trypos != NULL)
***************
*** 7354,7361 ****
                    continue;                   /* ignore #define, #if, etc. */
                curwin->w_cursor.lnum = lnum;
  
!               /* Skip a comment. XXX */
!               if ((trypos = ind_find_start_comment()) != NULL)
                {
                    lnum = trypos->lnum + 1;
                    continue;
--- 7466,7473 ----
                    continue;                   /* ignore #define, #if, etc. */
                curwin->w_cursor.lnum = lnum;
  
!               /* Skip a comment or raw string. XXX */
!               if ((trypos = ind_find_start_CORS()) != NULL)
                {
                    lnum = trypos->lnum + 1;
                    continue;
***************
*** 7583,7590 ****
         * Make a copy of tryposBrace, it may point to pos_copy inside
         * find_start_brace(), which may be changed somewhere.
         */
!       tryposBraceCopy = *tryposBrace;
!       tryposBrace = &tryposBraceCopy;
        trypos = tryposBrace;
        ourscope = trypos->lnum;
        start = ml_get(ourscope);
--- 7695,7702 ----
         * Make a copy of tryposBrace, it may point to pos_copy inside
         * find_start_brace(), which may be changed somewhere.
         */
!       tryposCopy = *tryposBrace;
!       tryposBrace = &tryposCopy;
        trypos = tryposBrace;
        ourscope = trypos->lnum;
        start = ml_get(ourscope);
***************
*** 7791,7800 ****
                        l = ml_get_curline();
  
                        /*
!                        * If we're in a comment now, skip to the start of the
!                        * comment.
                         */
!                       trypos = ind_find_start_comment();
                        if (trypos != NULL)
                        {
                            curwin->w_cursor.lnum = trypos->lnum + 1;
--- 7903,7912 ----
                        l = ml_get_curline();
  
                        /*
!                        * If we're in a comment or raw string now, skip to
!                        * the start of it.
                         */
!                       trypos = ind_find_start_CORS();
                        if (trypos != NULL)
                        {
                            curwin->w_cursor.lnum = trypos->lnum + 1;
***************
*** 7911,7919 ****
  
                            l = ml_get_curline();
  
!                           /* If we're in a comment now, skip to the start of
!                            * the comment. */
!                           trypos = ind_find_start_comment();
                            if (trypos != NULL)
                            {
                                curwin->w_cursor.lnum = trypos->lnum + 1;
--- 8023,8031 ----
  
                            l = ml_get_curline();
  
!                           /* If we're in a comment or raw string now, skip
!                            * to the start of it. */
!                           trypos = ind_find_start_CORS();
                            if (trypos != NULL)
                            {
                                curwin->w_cursor.lnum = trypos->lnum + 1;
***************
*** 7941,7949 ****
                }
  
                /*
!                * If we're in a comment now, skip to the start of the comment.
                 */                                         /* XXX */
!               if ((trypos = ind_find_start_comment()) != NULL)
                {
                    curwin->w_cursor.lnum = trypos->lnum + 1;
                    curwin->w_cursor.col = 0;
--- 8053,8062 ----
                }
  
                /*
!                * If we're in a comment or raw string now, skip to the start
!                * of it.
                 */                                         /* XXX */
!               if ((trypos = ind_find_start_CORS()) != NULL)
                {
                    curwin->w_cursor.lnum = trypos->lnum + 1;
                    curwin->w_cursor.col = 0;
***************
*** 8729,9004 ****
        /* subtract extra left-shift for jump labels */
        if (curbuf->b_ind_jump_label > 0 && original_line_islabel)
          amount -= curbuf->b_ind_jump_label;
      }
!     else
      {
!       /*
!        * ok -- we're not inside any sort of structure at all!
!        *
!        * This means we're at the top level, and everything should
!        * basically just match where the previous line is, except
!        * for the lines immediately following a function declaration,
!        * which are K&R-style parameters and need to be indented.
!        *
!        * if our line starts with an open brace, forget about any
!        * prevailing indent and make sure it looks like the start
!        * of a function
!        */
  
!       if (theline[0] == '{')
        {
!           amount = curbuf->b_ind_first_open;
        }
  
        /*
!        * If the NEXT line is a function declaration, the current
!        * line needs to be indented as a function type spec.
!        * Don't do this if the current line looks like a comment or if the
!        * current line is terminated, ie. ends in ';', or if the current line
!        * contains { or }: "void f() {\n if (1)"
!        */
!       else if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
!               && !cin_nocode(theline)
!               && vim_strchr(theline, '{') == NULL
!               && vim_strchr(theline, '}') == NULL
!               && !cin_ends_in(theline, (char_u *)":", NULL)
!               && !cin_ends_in(theline, (char_u *)",", NULL)
!               && cin_isfuncdecl(NULL, cur_curpos.lnum + 1,
!                                 cur_curpos.lnum + 1)
!               && !cin_isterminated(theline, FALSE, TRUE))
        {
!           amount = curbuf->b_ind_func_type;
        }
!       else
        {
!           amount = 0;
!           curwin->w_cursor = cur_curpos;
! 
!           /* search backwards until we find something we recognize */
  
!           while (curwin->w_cursor.lnum > 1)
!           {
!               curwin->w_cursor.lnum--;
!               curwin->w_cursor.col = 0;
  
!               l = ml_get_curline();
  
!               /*
!                * If we're in a comment now, skip to the start of the comment.
!                */                                             /* XXX */
!               if ((trypos = ind_find_start_comment()) != NULL)
!               {
!                   curwin->w_cursor.lnum = trypos->lnum + 1;
!                   curwin->w_cursor.col = 0;
!                   continue;
!               }
  
!               /*
!                * Are we at the start of a cpp base class declaration or
!                * constructor initialization?
!                */                                                 /* XXX */
!               n = FALSE;
!               if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{')
!               {
!                   n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
!                   l = ml_get_curline();
!               }
!               if (n)
!               {
!                                                                    /* XXX */
!                   amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col);
                    break;
!               }
! 
!               /*
!                * Skip preprocessor directives and blank lines.
!                */
!               if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
!                   continue;
! 
!               if (cin_nocode(l))
!                   continue;
  
!               /*
!                * If the previous line ends in ',', use one level of
!                * indentation:
!                * int foo,
!                *     bar;
!                * do this before checking for '}' in case of eg.
!                * enum foobar
!                * {
!                *   ...
!                * } foo,
!                *   bar;
!                */
!               n = 0;
!               if (cin_ends_in(l, (char_u *)",", NULL)
!                            || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\'))
!               {
!                   /* take us back to opening paren */
!                   if (find_last_paren(l, '(', ')')
!                           && (trypos = find_match_paren(
!                                            curbuf->b_ind_maxparen)) != NULL)
!                       curwin->w_cursor = *trypos;
  
!                   /* For a line ending in ',' that is a continuation line go
!                    * back to the first line with a backslash:
!                    * char *foo = "bla\
!                    *           bla",
!                    *      here;
!                    */
!                   while (n == 0 && curwin->w_cursor.lnum > 1)
!                   {
!                       l = ml_get(curwin->w_cursor.lnum - 1);
!                       if (*l == NUL || l[STRLEN(l) - 1] != '\\')
!                           break;
!                       --curwin->w_cursor.lnum;
!                       curwin->w_cursor.col = 0;
!                   }
  
!                   amount = get_indent();          /* XXX */
  
!                   if (amount == 0)
!                       amount = cin_first_id_amount();
!                   if (amount == 0)
!                       amount = ind_continuation;
!                   break;
!               }
  
!               /*
!                * If the line looks like a function declaration, and we're
!                * not in a comment, put it the left margin.
!                */
!               if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0))  /* XXX */
!                   break;
!               l = ml_get_curline();
  
!               /*
!                * Finding the closing '}' of a previous function.  Put
!                * current line at the left margin.  For when 'cino' has "fs".
!                */
!               if (*skipwhite(l) == '}')
!                   break;
  
!               /*                          (matching {)
!                * If the previous line ends on '};' (maybe followed by
!                * comments) align at column 0.  For example:
!                * char *string_array[] = { "foo",
!                *     / * x * / "b};ar" }; / * foobar * /
!                */
!               if (cin_ends_in(l, (char_u *)"};", NULL))
!                   break;
  
!               /*
!                * If the previous line ends on '[' we are probably in an
!                * array constant:
!                * something = [
!                *     234,  <- extra indent
!                */
!               if (cin_ends_in(l, (char_u *)"[", NULL))
!               {
!                   amount = get_indent() + ind_continuation;
                    break;
!               }
! 
!               /*
!                * Find a line only has a semicolon that belongs to a previous
!                * line ending in '}', e.g. before an #endif.  Don't increase
!                * indent then.
!                */
!               if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1))
!               {
!                   pos_T curpos_save = curwin->w_cursor;
! 
!                   while (curwin->w_cursor.lnum > 1)
!                   {
!                       look = ml_get(--curwin->w_cursor.lnum);
!                       if (!(cin_nocode(look) || cin_ispreproc_cont(
!                                             &look, &curwin->w_cursor.lnum)))
!                           break;
!                   }
!                   if (curwin->w_cursor.lnum > 0
!                                   && cin_ends_in(look, (char_u *)"}", NULL))
!                       break;
  
!                   curwin->w_cursor = curpos_save;
!               }
  
!               /*
!                * If the PREVIOUS line is a function declaration, the current
!                * line (and the ones that follow) needs to be indented as
!                * parameters.
!                */
!               if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0))
!               {
!                   amount = curbuf->b_ind_param;
!                   break;
!               }
  
!               /*
!                * If the previous line ends in ';' and the line before the
!                * previous line ends in ',' or '\', ident to column zero:
!                * int foo,
!                *     bar;
!                * indent_to_0 here;
!                */
!               if (cin_ends_in(l, (char_u *)";", NULL))
!               {
!                   l = ml_get(curwin->w_cursor.lnum - 1);
!                   if (cin_ends_in(l, (char_u *)",", NULL)
!                           || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
!                       break;
!                   l = ml_get_curline();
!               }
  
!               /*
!                * Doesn't look like anything interesting -- so just
!                * use the indent of this line.
!                *
!                * Position the cursor over the rightmost paren, so that
!                * matching it will take us back to the start of the line.
!                */
!               find_last_paren(l, '(', ')');
  
!               if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
!                   curwin->w_cursor = *trypos;
!               amount = get_indent();      /* XXX */
!               break;
!           }
  
!           /* add extra indent for a comment */
!           if (cin_iscomment(theline))
!               amount += curbuf->b_ind_comment;
! 
!           /* add extra indent if the previous line ended in a backslash:
!            *        "asdfasdf\
!            *            here";
!            *      char *foo = "asdf\
!            *                   here";
!            */
!           if (cur_curpos.lnum > 1)
!           {
!               l = ml_get(cur_curpos.lnum - 1);
!               if (*l != NUL && l[STRLEN(l) - 1] == '\\')
!               {
!                   cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
!                   if (cur_amount > 0)
!                       amount = cur_amount;
!                   else if (cur_amount == 0)
!                       amount += ind_continuation;
!               }
!           }
        }
      }
  
  theend:
      /* put the cursor back where it belongs */
      curwin->w_cursor = cur_curpos;
  
      vim_free(linecopy);
  
-     if (amount < 0)
-       return 0;
      return amount;
  }
  
--- 8842,9118 ----
        /* subtract extra left-shift for jump labels */
        if (curbuf->b_ind_jump_label > 0 && original_line_islabel)
          amount -= curbuf->b_ind_jump_label;
+ 
+       goto theend;
      }
! 
!     /*
!      * ok -- we're not inside any sort of structure at all!
!      *
!      * This means we're at the top level, and everything should
!      * basically just match where the previous line is, except
!      * for the lines immediately following a function declaration,
!      * which are K&R-style parameters and need to be indented.
!      *
!      * if our line starts with an open brace, forget about any
!      * prevailing indent and make sure it looks like the start
!      * of a function
!      */
! 
!     if (theline[0] == '{')
      {
!       amount = curbuf->b_ind_first_open;
!       goto theend;
!     }
  
!     /*
!      * If the NEXT line is a function declaration, the current
!      * line needs to be indented as a function type spec.
!      * Don't do this if the current line looks like a comment or if the
!      * current line is terminated, ie. ends in ';', or if the current line
!      * contains { or }: "void f() {\n if (1)"
!      */
!     if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
!           && !cin_nocode(theline)
!           && vim_strchr(theline, '{') == NULL
!           && vim_strchr(theline, '}') == NULL
!           && !cin_ends_in(theline, (char_u *)":", NULL)
!           && !cin_ends_in(theline, (char_u *)",", NULL)
!           && cin_isfuncdecl(NULL, cur_curpos.lnum + 1,
!                             cur_curpos.lnum + 1)
!           && !cin_isterminated(theline, FALSE, TRUE))
!     {
!       amount = curbuf->b_ind_func_type;
!       goto theend;
!     }
! 
!     /* search backwards until we find something we recognize */
!     amount = 0;
!     curwin->w_cursor = cur_curpos;
!     while (curwin->w_cursor.lnum > 1)
!     {
!       curwin->w_cursor.lnum--;
!       curwin->w_cursor.col = 0;
! 
!       l = ml_get_curline();
! 
!       /*
!        * If we're in a comment or raw string now, skip to the start
!        * of it.
!        */                                             /* XXX */
!       if ((trypos = ind_find_start_CORS()) != NULL)
        {
!           curwin->w_cursor.lnum = trypos->lnum + 1;
!           curwin->w_cursor.col = 0;
!           continue;
        }
  
        /*
!        * Are we at the start of a cpp base class declaration or
!        * constructor initialization?
!        */                                                 /* XXX */
!       n = FALSE;
!       if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{')
        {
!           n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
!           l = ml_get_curline();
        }
!       if (n)
        {
!                                                            /* XXX */
!           amount = get_baseclass_amount(cache_cpp_baseclass.lpos.col);
!           break;
!       }
  
!       /*
!        * Skip preprocessor directives and blank lines.
!        */
!       if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
!           continue;
  
!       if (cin_nocode(l))
!           continue;
  
!       /*
!        * If the previous line ends in ',', use one level of
!        * indentation:
!        * int foo,
!        *     bar;
!        * do this before checking for '}' in case of eg.
!        * enum foobar
!        * {
!        *   ...
!        * } foo,
!        *   bar;
!        */
!       n = 0;
!       if (cin_ends_in(l, (char_u *)",", NULL)
!                    || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\'))
!       {
!           /* take us back to opening paren */
!           if (find_last_paren(l, '(', ')')
!                   && (trypos = find_match_paren(
!                                    curbuf->b_ind_maxparen)) != NULL)
!               curwin->w_cursor = *trypos;
  
!           /* For a line ending in ',' that is a continuation line go
!            * back to the first line with a backslash:
!            * char *foo = "bla\
!            *           bla",
!            *      here;
!            */
!           while (n == 0 && curwin->w_cursor.lnum > 1)
!           {
!               l = ml_get(curwin->w_cursor.lnum - 1);
!               if (*l == NUL || l[STRLEN(l) - 1] != '\\')
                    break;
!               --curwin->w_cursor.lnum;
!               curwin->w_cursor.col = 0;
!           }
  
!           amount = get_indent();          /* XXX */
  
!           if (amount == 0)
!               amount = cin_first_id_amount();
!           if (amount == 0)
!               amount = ind_continuation;
!           break;
!       }
  
!       /*
!        * If the line looks like a function declaration, and we're
!        * not in a comment, put it the left margin.
!        */
!       if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0))  /* XXX */
!           break;
!       l = ml_get_curline();
  
!       /*
!        * Finding the closing '}' of a previous function.  Put
!        * current line at the left margin.  For when 'cino' has "fs".
!        */
!       if (*skipwhite(l) == '}')
!           break;
  
!       /*                          (matching {)
!        * If the previous line ends on '};' (maybe followed by
!        * comments) align at column 0.  For example:
!        * char *string_array[] = { "foo",
!        *     / * x * / "b};ar" }; / * foobar * /
!        */
!       if (cin_ends_in(l, (char_u *)"};", NULL))
!           break;
  
!       /*
!        * If the previous line ends on '[' we are probably in an
!        * array constant:
!        * something = [
!        *     234,  <- extra indent
!        */
!       if (cin_ends_in(l, (char_u *)"[", NULL))
!       {
!           amount = get_indent() + ind_continuation;
!           break;
!       }
  
!       /*
!        * Find a line only has a semicolon that belongs to a previous
!        * line ending in '}', e.g. before an #endif.  Don't increase
!        * indent then.
!        */
!       if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1))
!       {
!           pos_T curpos_save = curwin->w_cursor;
  
!           while (curwin->w_cursor.lnum > 1)
!           {
!               look = ml_get(--curwin->w_cursor.lnum);
!               if (!(cin_nocode(look) || cin_ispreproc_cont(
!                                     &look, &curwin->w_cursor.lnum)))
                    break;
!           }
!           if (curwin->w_cursor.lnum > 0
!                           && cin_ends_in(look, (char_u *)"}", NULL))
!               break;
  
!           curwin->w_cursor = curpos_save;
!       }
  
!       /*
!        * If the PREVIOUS line is a function declaration, the current
!        * line (and the ones that follow) needs to be indented as
!        * parameters.
!        */
!       if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0))
!       {
!           amount = curbuf->b_ind_param;
!           break;
!       }
  
!       /*
!        * If the previous line ends in ';' and the line before the
!        * previous line ends in ',' or '\', ident to column zero:
!        * int foo,
!        *     bar;
!        * indent_to_0 here;
!        */
!       if (cin_ends_in(l, (char_u *)";", NULL))
!       {
!           l = ml_get(curwin->w_cursor.lnum - 1);
!           if (cin_ends_in(l, (char_u *)",", NULL)
!                   || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
!               break;
!           l = ml_get_curline();
!       }
  
!       /*
!        * Doesn't look like anything interesting -- so just
!        * use the indent of this line.
!        *
!        * Position the cursor over the rightmost paren, so that
!        * matching it will take us back to the start of the line.
!        */
!       find_last_paren(l, '(', ')');
  
!       if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
!           curwin->w_cursor = *trypos;
!       amount = get_indent();      /* XXX */
!       break;
!     }
  
!     /* add extra indent for a comment */
!     if (cin_iscomment(theline))
!       amount += curbuf->b_ind_comment;
! 
!     /* add extra indent if the previous line ended in a backslash:
!      *              "asdfasdf\
!      *                  here";
!      *            char *foo = "asdf\
!      *                         here";
!      */
!     if (cur_curpos.lnum > 1)
!     {
!       l = ml_get(cur_curpos.lnum - 1);
!       if (*l != NUL && l[STRLEN(l) - 1] == '\\')
!       {
!           cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
!           if (cur_amount > 0)
!               amount = cur_amount;
!           else if (cur_amount == 0)
!               amount += ind_continuation;
        }
      }
  
  theend:
+     if (amount < 0)
+       amount = 0;
+ 
+ laterend:
      /* put the cursor back where it belongs */
      curwin->w_cursor = cur_curpos;
  
      vim_free(linecopy);
  
      return amount;
  }
  
*** ../vim-7.4.802/src/edit.c   2015-07-21 17:53:11.577527989 +0200
--- src/edit.c  2015-07-28 19:40:27.771945786 +0200
***************
*** 7813,7821 ****
  fixthisline(get_the_indent)
      int (*get_the_indent) __ARGS((void));
  {
!     change_indent(INDENT_SET, get_the_indent(), FALSE, 0, TRUE);
!     if (linewhite(curwin->w_cursor.lnum))
!       did_ai = TRUE;      /* delete the indent if the line stays empty */
  }
  
      void
--- 7813,7826 ----
  fixthisline(get_the_indent)
      int (*get_the_indent) __ARGS((void));
  {
!     int amount = get_the_indent();
! 
!     if (amount >= 0)
!     {
!       change_indent(INDENT_SET, amount, FALSE, 0, TRUE);
!       if (linewhite(curwin->w_cursor.lnum))
!           did_ai = TRUE;      /* delete the indent if the line stays empty */
!     }
  }
  
      void
*** ../vim-7.4.802/src/ops.c    2015-07-22 22:46:08.127010101 +0200
--- src/ops.c   2015-07-28 19:45:37.060848436 +0200
***************
*** 686,692 ****
  {
      long      i;
      char_u    *l;
!     int               count;
      linenr_T  first_changed = 0;
      linenr_T  last_changed = 0;
      linenr_T  start_lnum = curwin->w_cursor.lnum;
--- 686,692 ----
  {
      long      i;
      char_u    *l;
!     int               amount;
      linenr_T  first_changed = 0;
      linenr_T  last_changed = 0;
      linenr_T  start_lnum = curwin->w_cursor.lnum;
***************
*** 719,729 ****
        {
            l = skipwhite(ml_get_curline());
            if (*l == NUL)                  /* empty or blank line */
!               count = 0;
            else
!               count = how();              /* get the indent for this line */
  
!           if (set_indent(count, SIN_UNDO))
            {
                /* did change the indent, call changed_lines() later */
                if (first_changed == 0)
--- 719,729 ----
        {
            l = skipwhite(ml_get_curline());
            if (*l == NUL)                  /* empty or blank line */
!               amount = 0;
            else
!               amount = how();             /* get the indent for this line */
  
!           if (amount >= 0 && set_indent(amount, SIN_UNDO))
            {
                /* did change the indent, call changed_lines() later */
                if (first_changed == 0)
*** ../vim-7.4.802/src/testdir/test3.in 2015-03-20 19:06:01.982429823 +0100
--- src/testdir/test3.in        2015-07-28 20:03:32.290099553 +0200
***************
*** 891,896 ****
--- 891,915 ----
    111111111111111111;
  }
  
+ void getstring() {
+ /* Raw strings */
+ const char* s = R"(
+   test {
+     # comment
+     field: 123
+   }
+  )";
+      }
+ 
+ void getstring() {
+ const char* s = R"foo(
+   test {
+     # comment
+     field: 123
+   }
+     )foo";
+      }
+ 
  /* end of AUTO */
  
  STARTTEST
*** ../vim-7.4.802/src/testdir/test3.ok 2015-03-20 19:06:01.986429778 +0100
--- src/testdir/test3.ok        2015-07-28 20:03:59.985823030 +0200
***************
*** 879,884 ****
--- 879,903 ----
        111111111111111111;
  }
  
+ void getstring() {
+       /* Raw strings */
+       const char* s = R"(
+   test {
+     # comment
+     field: 123
+   }
+  )";
+ }
+ 
+ void getstring() {
+       const char* s = R"foo(
+   test {
+     # comment
+     field: 123
+   }
+     )foo";
+ }
+ 
  /* end of AUTO */
  
  
*** ../vim-7.4.802/src/version.c        2015-07-28 17:16:28.302488118 +0200
--- src/version.c       2015-07-28 21:07:42.219893314 +0200
***************
*** 743,744 ****
--- 743,746 ----
  {   /* Add new patch number below this line */
+ /**/
+     803,
  /**/

-- 
Facepalm statement #4: "3000 year old graves?  That's not possible, it's only
2014!"

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui