updated for version 7.4.355 v7.4.355
authorBram Moolenaar <Bram@vim.org>
Thu, 3 Jul 2014 20:57:55 +0000 (22:57 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 3 Jul 2014 20:57:55 +0000 (22:57 +0200)
Problem:    Several problems with Javascript indenting.
Solution:   Improve Javascript indenting.

src/misc1.c
src/testdir/test3.in
src/testdir/test3.ok
src/version.c

index fbebd5aec08d19157a39c3b43dfa5a84fcdf37cb..3a834aa0cfeb50f90cc59963ed33234004bb2f8f 100644 (file)
@@ -5382,6 +5382,7 @@ do_c_expr_indent()
 static char_u  *cin_skipcomment __ARGS((char_u *));
 static int     cin_nocode __ARGS((char_u *));
 static pos_T   *find_line_comment __ARGS((void));
+static int     cin_has_js_key __ARGS((char_u *text));
 static int     cin_islabel_skip __ARGS((char_u **));
 static int     cin_isdefault __ARGS((char_u *));
 static char_u  *after_label __ARGS((char_u *l));
@@ -5410,6 +5411,7 @@ static int        cin_starts_with __ARGS((char_u *s, char *word));
 static int     cin_skip2pos __ARGS((pos_T *trypos));
 static pos_T   *find_start_brace __ARGS((void));
 static pos_T   *find_match_paren __ARGS((int));
+static pos_T   *find_match_char __ARGS((int c, int ind_maxparen));
 static int     corr_ind_maxparen __ARGS((pos_T *startpos));
 static int     find_last_paren __ARGS((char_u *l, int start, int end));
 static int     find_match __ARGS((int lookfor, linenr_T ourscope));
@@ -5493,8 +5495,39 @@ find_line_comment() /* XXX */
     return NULL;
 }
 
+/*
+ * Return TRUE if "text" starts with "key:".
+ */
+    static int
+cin_has_js_key(text)
+    char_u *text;
+{
+    char_u *s = skipwhite(text);
+    int            quote = 0;
+
+    if (*s == '\'' || *s == '"')
+    {
+       /* can be 'key': or "key": */
+       quote = *s;
+       ++s;
+    }
+    if (!vim_isIDc(*s))            /* need at least one ID character */
+       return FALSE;
+
+    while (vim_isIDc(*s))
+       ++s;
+    if (*s == quote)
+       ++s;
+
+    s = cin_skipcomment(s);
+
+    /* "::" is not a label, it's C++ */
+    return (*s == ':' && s[1] != ':');
+}
+
 /*
  * Check if string matches "label:"; move to character after ':' if true.
+ * "*s" must point to the start of the label, if there is one.
  */
     static int
 cin_islabel_skip(s)
@@ -6620,13 +6653,21 @@ find_start_brace()          /* XXX */
     static pos_T *
 find_match_paren(ind_maxparen)     /* XXX */
     int                ind_maxparen;
+{
+    return find_match_char('(', ind_maxparen);
+}
+
+    static pos_T *
+find_match_char(c, ind_maxparen)           /* XXX */
+    int                c;
+    int                ind_maxparen;
 {
     pos_T      cursor_save;
     pos_T      *trypos;
     static pos_T pos_copy;
 
     cursor_save = curwin->w_cursor;
-    if ((trypos = findmatchlimit(NULL, '(', 0, ind_maxparen)) != NULL)
+    if ((trypos = findmatchlimit(NULL, c, 0, ind_maxparen)) != NULL)
     {
        /* check if the ( is in a // comment */
        if ((colnr_T)cin_skip2pos(trypos) > trypos->col)
@@ -6976,6 +7017,8 @@ get_c_indent()
 #define LOOKFOR_NOBREAK                8
 #define LOOKFOR_CPP_BASECLASS  9
 #define LOOKFOR_ENUM_OR_INIT   10
+#define LOOKFOR_JS_KEY         11
+#define LOOKFOR_NO_COMMA       12
 
     int                whilelevel;
     linenr_T   lnum;
@@ -6986,6 +7029,7 @@ get_c_indent()
     int                cont_amount = 0;    /* amount for continuation line */
     int                original_line_islabel;
     int                added_to_amount = 0;
+    int                js_cur_has_key = 0;
 
     /* make a copy, value is changed below */
     int                ind_continuation = curbuf->b_ind_continuation;
@@ -7208,6 +7252,16 @@ get_c_indent()
        }
     }
 
+    /*
+     * 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 */
@@ -7473,14 +7527,13 @@ get_c_indent()
        if (cin_iscomment(theline))
            amount += curbuf->b_ind_comment;
       }
-
-      /*
-       * Are we at least inside braces, then?
-       */
       else
       {
+       /*
+        * We are inside braces, there is a { before this line at the position
+        * stored in tryposBrace.
+        */
        trypos = tryposBrace;
-
        ourscope = trypos->lnum;
        start = ml_get(ourscope);
 
@@ -7502,24 +7555,19 @@ get_c_indent()
        }
        else
        {
-           /*
-            * that opening brace might have been on a continuation
-            * line.  if so, find the start of the line.
-            */
+           /* That opening brace might have been on a continuation
+            * line.  if so, find the start of the line. */
            curwin->w_cursor.lnum = ourscope;
 
-           /*
-            * position the cursor over the rightmost paren, so that
-            * matching it will take us back to the start of the line.
-            */
+           /* Position the cursor over the rightmost paren, so that
+            * matching it will take us back to the start of the line. */
            lnum = ourscope;
            if (find_last_paren(start, '(', ')')
                        && (trypos = find_match_paren(curbuf->b_ind_maxparen))
                                                                      != NULL)
                lnum = trypos->lnum;
 
-           /*
-            * It could have been something like
+           /* It could have been something like
             *     case 1: if (asdf &&
             *                  ldfd) {
             *              }
@@ -7535,8 +7583,12 @@ get_c_indent()
            start_brace = BRACE_AT_END;
        }
 
+       /* For Javascript check if the line starts with "key:". */
+       if (curbuf->b_ind_js)
+           js_cur_has_key = cin_has_js_key(theline);
+
        /*
-        * if we're looking at a closing brace, that's where
+        * If we're looking at a closing brace, that's where
         * we want to be.  otherwise, add the amount of room
         * that an indent is supposed to be.
         */
@@ -7643,7 +7695,7 @@ get_c_indent()
             * Search backwards.  If we find something we recognize, line up
             * with that.
             *
-            * if we're looking at an open brace, indent
+            * If we're looking at an open brace, indent
             * the usual amount relative to the conditional
             * that opens the block.
             */
@@ -8051,6 +8103,41 @@ get_c_indent()
                 */
                terminated = cin_isterminated(l, FALSE, TRUE);
 
+               if (js_cur_has_key)
+               {
+                   js_cur_has_key = 0; /* only check the first line */
+                   if (curbuf->b_ind_js && terminated == ',')
+                   {
+                       /* For Javascript we might be inside an object:
+                        *   key: something,  <- align with this
+                        *   key: something
+                        * or:
+                        *   key: something +  <- align with this
+                        *       something,
+                        *   key: something
+                        */
+                       lookfor = LOOKFOR_JS_KEY;
+                   }
+               }
+               if (lookfor == LOOKFOR_JS_KEY && cin_has_js_key(l))
+               {
+                   amount = get_indent();
+                   break;
+               }
+               if (lookfor == LOOKFOR_NO_COMMA)
+               {
+                   if (terminated != ',')
+                       /* line below current line is the one that starts a
+                        * (possibly broken) line ending in a comma. */
+                       break;
+                   amount = get_indent();
+                   if (curwin->w_cursor.lnum - 1 == ourscope)
+                       /* line above is start of the scope, thus current line
+                        * is the one that stars a (possibly broken) line
+                        * ending in a comma. */
+                       break;
+               }
+
                if (terminated == 0 || (lookfor != LOOKFOR_UNTERM
                                                        && terminated == ','))
                {
@@ -8062,11 +8149,16 @@ get_c_indent()
                     *              bar )
                     */
                    /*
-                    * position the cursor over the rightmost paren, so that
+                    * Position the cursor over the rightmost paren, so that
                     * matching it will take us back to the start of the line.
+                    * Ignore a match before the start of the block.
                     */
                    (void)find_last_paren(l, '(', ')');
                    trypos = find_match_paren(corr_ind_maxparen(&cur_curpos));
+                   if (trypos != NULL && (trypos->lnum < tryposBrace->lnum
+                               || (trypos->lnum == tryposBrace->lnum
+                                   && trypos->col < tryposBrace->col)))
+                       trypos = NULL;
 
                    /*
                     * If we are looking for ',', we also look for matching
@@ -8117,10 +8209,10 @@ get_c_indent()
                     * Get indent and pointer to text for current line,
                     * ignoring any jump label.     XXX
                     */
-                   if (!curbuf->b_ind_js)
-                       cur_amount = skip_label(curwin->w_cursor.lnum, &l);
-                   else
+                   if (curbuf->b_ind_js)
                        cur_amount = get_indent();
+                   else
+                       cur_amount = skip_label(curwin->w_cursor.lnum, &l);
                    /*
                     * If this is just above the line we are indenting, and it
                     * starts with a '{', line it up with this line.
@@ -8142,7 +8234,7 @@ get_c_indent()
                        if (*skipwhite(l) != '{')
                            amount += curbuf->b_ind_open_extra;
 
-                       if (curbuf->b_ind_cpp_baseclass)
+                       if (curbuf->b_ind_cpp_baseclass && !curbuf->b_ind_js)
                        {
                            /* have to look back, whether it is a cpp base
                             * class declaration or initialization */
@@ -8302,8 +8394,41 @@ get_c_indent()
                             */
                            if (lookfor == LOOKFOR_INITIAL && terminated == ',')
                            {
-                               lookfor = LOOKFOR_ENUM_OR_INIT;
-                               cont_amount = cin_first_id_amount();
+                               if (curbuf->b_ind_js)
+                               {
+                                   /* Search for a line ending in a comma
+                                    * and line up with the line below it
+                                    * (could be the current line).
+                                    * some = [
+                                    *     1,     <- line up here
+                                    *     2,
+                                    * some = [
+                                    *     3 +    <- line up here
+                                    *       4 *
+                                    *        5,
+                                    *     6,
+                                    */
+                                   lookfor = LOOKFOR_NO_COMMA;
+                                   amount = get_indent();          /* XXX */
+                                   trypos = find_match_char('[',
+                                                     curbuf->b_ind_maxparen);
+                                   if (trypos != NULL)
+                                   {
+                                       if (trypos->lnum
+                                                == curwin->w_cursor.lnum - 1)
+                                       {
+                                           /* Current line is first inside
+                                            * [], line up with it. */
+                                           break;
+                                       }
+                                       ourscope = trypos->lnum;
+                                   }
+                               }
+                               else
+                               {
+                                   lookfor = LOOKFOR_ENUM_OR_INIT;
+                                   cont_amount = cin_first_id_amount();
+                               }
                            }
                            else
                            {
@@ -8313,7 +8438,8 @@ get_c_indent()
                                                                /* XXX */
                                    cont_amount = cin_get_equal_amount(
                                                       curwin->w_cursor.lnum);
-                               if (lookfor != LOOKFOR_TERM)
+                               if (lookfor != LOOKFOR_TERM
+                                                && lookfor != LOOKFOR_JS_KEY)
                                    lookfor = LOOKFOR_UNTERM;
                            }
                        }
@@ -8324,8 +8450,7 @@ get_c_indent()
                 * Check if we are after a while (cond);
                 * If so: Ignore until the matching "do".
                 */
-                                                       /* XXX */
-               else if (cin_iswhileofdo_end(terminated))
+               else if (cin_iswhileofdo_end(terminated)) /* XXX */
                {
                    /*
                     * Found an unterminated line after a while ();, line up
@@ -8538,18 +8663,16 @@ term_again:
       if (curbuf->b_ind_jump_label > 0 && original_line_islabel)
          amount -= curbuf->b_ind_jump_label;
     }
-
-    /*
-     * 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.
-     */
     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
@@ -8699,6 +8822,18 @@ term_again:
                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
index a33a4cba60562dbcc3c913ac1c9e95ab6a53a022..de86700380f0e3de2f089fccb860ed11550547dd 100644 (file)
@@ -1432,7 +1432,7 @@ int main ()
 
 STARTTEST
 :set cino=(0,ts
-2kdd=][
+2kdd2j=][
 ENDTEST
 
 void func(int a
@@ -1446,7 +1446,7 @@ void func(int a
 
 STARTTEST
 :set cino=(0
-2kdd=][
+2kdd2j=][
 ENDTEST
 
 void
@@ -1461,7 +1461,7 @@ func(int a
 
 STARTTEST
 :set cino&
-2kdd=7][
+2kdd2j=7][
 ENDTEST
 
 void func(void)
@@ -1538,7 +1538,7 @@ func6(
 STARTTEST
 :set cino&
 :set cino+=l1
-2kdd=][
+2kdd2j=][
 ENDTEST
 
 void func(void)
@@ -1567,7 +1567,7 @@ break;
 
 STARTTEST
 :set cino&
-2kdd=][
+2kdd2j=][
 ENDTEST
 
 void func(void)
@@ -1592,7 +1592,7 @@ void func(void)
 
 STARTTEST
 :set cino&
-2kdd=][
+2kdd2j=][
 ENDTEST
 
 void func(void)
@@ -1919,10 +1919,10 @@ ENDTEST
 
 JSSTART
 var foo = [
-1,  // indent 8 more
+1,
 2,
 3
-];  // indent 8 less
+];
 JSEND
 
 STARTTEST
@@ -1937,7 +1937,7 @@ var foo = [
 1,
 2,
 3
-];  // indent 16 less
+];
 }
 JSEND
 
@@ -1954,6 +1954,8 @@ if (cond &&
 cond) {
 stmt;
 }
+window.something.left =
+(width - 50 + offset) + "px";
 var class_name='myclass';
 
 function private_method() {
@@ -1969,15 +1971,15 @@ function init(options) {
 
 $(this).data(class_name+'_public',$.extend({},{
 foo: 'bar',
-bar: 2,  // indent 8 more
-foobar: [  // indent 8 more
-1,  // indent 8 more
-2,  // indent 16 more
-3   // indent 16 more
+bar: 2,
+foobar: [
+1,
+2,
+3
 ],
-callback: function(){  // indent 8 more
-return true;  // indent 8 more
-}  // indent 8 more
+callback: function(){
+return true;
+}
 }, options||{}));
 }
 
@@ -2018,9 +2020,9 @@ $(this).data(class_name+'_public',$.extend({},{
 foo: 'bar',
 bar: 2,
 foobar: [
-1,  // indent 8 more
-2,  // indent 8 more
-3   // indent 8 more
+1,
+2,
+3
 ],
 callback: function(){
 return true;
@@ -2040,15 +2042,15 @@ JSSTART
 function init(options) {
 $(this).data(class_name+'_public',$.extend({},{
 foo: 'bar',
-bar: 2,  // indent 8 more
-foobar: [  // indent 8 more
-1,  // indent 8 more
-2,  // indent 16 more
-3  // indent 16 more
+bar: 2,
+foobar: [
+1,
+2,
+3
 ],
-callback: function(){  // indent 8 more
-return true;  // indent 8 more
-}  // indent 8 more
+callback: function(){
+return true;
+}
 }, options||{}));
 }
 })(jQuery);
index edd9e236a621e2421f174c3cef90fbec80047f96..0d0e76fce46c850b3dacda2e6f04bd011a50b5ac 100644 (file)
@@ -1707,10 +1707,10 @@ JSEND
 
 JSSTART
 var foo = [
-1,  // indent 8 more
+       1,
        2,
        3
-       ];  // indent 8 less
+];
 JSEND
 
 
@@ -1720,7 +1720,7 @@ function bar() {
                1,
                2,
                3
-                       ];  // indent 16 less
+       ];
 }
 JSEND
 
@@ -1732,6 +1732,8 @@ JSSTART
                        cond) {
                stmt;
        }
+       window.something.left =
+               (width - 50 + offset) + "px";
        var class_name='myclass';
 
        function private_method() {
@@ -1747,15 +1749,15 @@ JSSTART
 
                $(this).data(class_name+'_public',$.extend({},{
                        foo: 'bar',
-               bar: 2,  // indent 8 more
-               foobar: [  // indent 8 more
-                       1,  // indent 8 more
-               2,  // indent 16 more
-               3   // indent 16 more
+                       bar: 2,
+                       foobar: [
+                               1,
+                               2,
+                               3
                        ],
-               callback: function(){  // indent 8 more
-                       return true;  // indent 8 more
-               }  // indent 8 more
+                       callback: function(){
+                               return true;
+                       }
                }, options||{}));
        }
 
@@ -1791,9 +1793,9 @@ function init(options) {
                foo: 'bar',
                bar: 2,
                foobar: [
-               1,  // indent 8 more
-               2,  // indent 8 more
-               3   // indent 8 more
+                       1,
+                       2,
+                       3
                ],
                callback: function(){
                        return true;
@@ -1808,15 +1810,15 @@ JSSTART
        function init(options) {
                $(this).data(class_name+'_public',$.extend({},{
                        foo: 'bar',
-               bar: 2,  // indent 8 more
-               foobar: [  // indent 8 more
-                       1,  // indent 8 more
-               2,  // indent 16 more
-               3  // indent 16 more
+                       bar: 2,
+                       foobar: [
+                               1,
+                               2,
+                               3
                        ],
-               callback: function(){  // indent 8 more
-                       return true;  // indent 8 more
-               }  // indent 8 more
+                       callback: function(){
+                               return true;
+                       }
                }, options||{}));
        }
 })(jQuery);
index 5be575a78153aa62e699f4d5a1774f89ad6ad777..0921f40d4a081756ad3a089b93ac987bf0815c5c 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    355,
 /**/
     354,
 /**/