diff -r 486fb50528f0 -r 7d5e9d30c0ce runtime/doc/indent.txt
--- a/runtime/doc/indent.txt	Sun Jul 11 18:03:15 2010 +0200
+++ b/runtime/doc/indent.txt	Sun Jul 11 22:49:16 2010 +0530
@@ -431,10 +431,11 @@
 		    }
 		});
 <
-				*javascript-cinoptions* *javascript-indenting*
+					*javascript-cinoptions* *javascript-indenting*
 	JN    Indent JavaScript object declarations correctly by not confusing
-	      them with labels.  The value 'N' is currently unused but must be 
-	      non-zero (e.g. 'J1'). >
+	      them with labels. The value 'N' is currently unused but must be 
+	      non-zero (e.g. 'J1').
+
 
 		var bar = {
 		    foo: {
@@ -448,7 +449,7 @@
 			"y": 5
 		    }
 		}
-<
+
 	)N    Vim searches for unclosed parentheses at most N lines away.
 	      This limits the time needed to search for parentheses.  (default
 	      20 lines).
diff -r 486fb50528f0 -r 7d5e9d30c0ce runtime/indent/javascript.vim
--- a/runtime/indent/javascript.vim	Sun Jul 11 18:03:15 2010 +0200
+++ b/runtime/indent/javascript.vim	Sun Jul 11 22:49:16 2010 +0530
@@ -9,8 +9,7 @@
 endif
 let b:did_indent = 1
 
-" C indenting is not too bad.
-setlocal cindent
-setlocal cinoptions+=j1,J1
+" Indent JavaScript code correctly using cindent only.
+setlocal cindent cinoptions& cinoptions+=J1
 
-let b:undo_indent = "setl cin<"
+let b:undo_indent = "set cin< cino<"
diff -r 486fb50528f0 -r 7d5e9d30c0ce src/edit.c
--- a/src/edit.c	Sun Jul 11 18:03:15 2010 +0200
+++ b/src/edit.c	Sun Jul 11 22:49:16 2010 +0530
@@ -7545,7 +7545,7 @@
 	    if (try_match && keytyped == ':')
 	    {
 		p = ml_get_curline();
-		if (cin_iscase(p, FALSE) || cin_isscopedecl(p)
+		if (cin_iscase(p) || cin_isscopedecl(p)
 							   || cin_islabel(30))
 		    return TRUE;
 		/* Need to get the line again after cin_islabel(). */
@@ -7555,7 +7555,7 @@
 			&& p[curwin->w_cursor.col - 2] == ':')
 		{
 		    p[curwin->w_cursor.col - 1] = ' ';
-		    i = (cin_iscase(p, FALSE) || cin_isscopedecl(p)
+		    i = (cin_iscase(p) || cin_isscopedecl(p)
 							  || cin_islabel(30));
 		    p = ml_get_curline();
 		    p[curwin->w_cursor.col - 1] = ':';
diff -r 486fb50528f0 -r 7d5e9d30c0ce src/misc1.c
--- a/src/misc1.c	Sun Jul 11 18:03:15 2010 +0200
+++ b/src/misc1.c	Sun Jul 11 22:49:16 2010 +0530
@@ -5050,7 +5050,7 @@
 	    curwin->w_cursor = cursor_save;
 	    if (cin_isterminated(line, TRUE, FALSE)
 		    || cin_isscopedecl(line)
-		    || cin_iscase(line, TRUE)
+		    || cin_iscase(line)
 		    || (cin_islabel_skip(&line) && cin_nocode(line)))
 		return TRUE;
 	    return FALSE;
@@ -5089,9 +5089,8 @@
  * Recognize a switch label: "case .*:" or "default:".
  */
      int
-cin_iscase(s, strict)
+cin_iscase(s)
     char_u *s;
-    int strict; /* Allow relaxed check of case statement for JS */
 {
     s = cin_skipcomment(s);
     if (STRNCMP(s, "case", 4) == 0 && !vim_isIDc(s[4]))
@@ -5107,13 +5106,13 @@
 		    return TRUE;
 	    }
 	    if (*s == '\'' && s[1] && s[2] == '\'')
-		s += 2;			/* skip over ':' */
+		s += 2;			/* skip over '.' */
 	    else if (*s == '/' && (s[1] == '*' || s[1] == '/'))
 		return FALSE;		/* stop at comment */
 	    else if (*s == '"')
 	    {
-		/* JS etc. */
-		if (strict)
+		/* If cindentoptions has 'J' flag. Used by JavaScript files */
+		if (vim_strchr(curbuf->b_p_cino, 'J') != NULL)
 		    return FALSE;		/* stop at string */
 		else
 		    return TRUE;
@@ -5176,7 +5175,7 @@
 	{
 	    if (l[1] == ':')	    /* skip over "::" for C++ */
 		++l;
-	    else if (!cin_iscase(l + 1, FALSE))
+	    else if (!cin_iscase(l + 1))
 		break;
 	}
 	else if (*l == '\'' && l[1] && l[2] == '\'')
@@ -5234,8 +5233,7 @@
     curwin->w_cursor.lnum = lnum;
     l = ml_get_curline();
 				    /* XXX */
-    if (cin_iscase(l, FALSE) || cin_isscopedecl(l)
-					       || cin_islabel(ind_maxcomment))
+    if (cin_iscase(l) || cin_isscopedecl(l) || cin_islabel(ind_maxcomment))
     {
 	amount = get_indent_nolabel(lnum);
 	l = after_label(ml_get_curline());
@@ -5474,6 +5472,9 @@
 	s = ml_get(lnum);
     else
 	s = *sp;
+   /* while (foo() = some + bar()) */ 
+    if (cin_is_cinword(s))
+	return FALSE;
 
     while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"')
     {
@@ -5914,7 +5915,12 @@
     static pos_T	pos_copy;
 
     cursor_save = curwin->w_cursor;
-    while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL)
+/* removing this: FM_BLOCKSTOP
+* while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL)
+ * could have a perf hit
+ * the loop would run till a match is found or file edge hit
+ */
+    while ((trypos = findmatchlimit(NULL, '{', 0, 0)) != NULL)
     {
 	pos_copy = *trypos;	/* copy pos_T, next findmatch will change it */
 	trypos = &pos_copy;
@@ -5984,6 +5990,7 @@
 /*
  * Set w_cursor.col to the column number of the last unmatched ')' or '{' in
  * line "l".
+ * - you could abuse start and end to any char you want
  */
     static int
 find_last_paren(l, start, end)
@@ -5998,8 +6005,8 @@
 
     for (i = 0; l[i]; i++)
     {
-	i = (int)(cin_skipcomment(l + i) - l); /* ignore parens in comments */
-	i = (int)(skip_string(l + i) - l);    /* ignore parens in quotes */
+	i = (int)(cin_skipcomment(l + i) - l); /* ignore  comments */
+	i = (int)(skip_string(l + i) - l);    /* ignore  quoted content */
 	if (l[i] == start)
 	    ++open_count;
 	else if (l[i] == end)
@@ -6169,7 +6176,7 @@
     /*
      * max lines to search for an open paren
      */
-    int ind_maxparen = 20;
+    int ind_maxparen = 70;
 
     /*
      * max lines to search for an open comment
@@ -6182,7 +6189,17 @@
     int	ind_java = 0;
 
     /*
-     * not to confuse JS object properties with labels
+     * Handle JavaScript code:
+     * - not to confuse JS object properties with labels
+     * indenting braces inside parenthesized structures 
+     * f.e. 
+     * window.Foo(1, long_argument,
+     *     2,3, 
+     *     fun ()
+     *     {
+     *         some statements
+     *     },
+     *     some, more, args);
      */
     int ind_js = 0;
 
@@ -6192,13 +6209,14 @@
     int ind_keep_case_label = 0;
 
     pos_T	cur_curpos;
-    int		amount;
-    int		scope_amount;
+    int		amount = 0;
+    int		scope_amount = 0;
+    int		paren_scope_amount = 0;
     int		cur_amount = MAXCOL;
     colnr_T	col;
     char_u	*theline;
     char_u	*linecopy;
-    pos_T	*trypos;
+    pos_T	*trypos = NULL;
     pos_T	*tryposBrace = NULL;
     pos_T	our_paren_pos;
     char_u	*start;
@@ -6311,7 +6329,7 @@
     cur_curpos = curwin->w_cursor;
 
     /* if we are at line 1 0 is fine, right? */
-    if (cur_curpos.lnum == 1)
+    if (cur_curpos.lnum == 1) 
 	return 0;
 
     /* Get a copy of the current contents of the line.
@@ -6522,12 +6540,11 @@
     /*
      * Are we inside parentheses or braces?
      */						    /* XXX */
-    else if (((trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL
-		&& ind_java == 0)
-	    || (tryposBrace = find_start_brace(ind_maxcomment)) != NULL
-	    || trypos != NULL)
-    {
-      if (trypos != NULL && tryposBrace != NULL)
+    else if (((trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL && ind_java ==0)
+	    || (tryposBrace = find_start_brace(ind_maxcomment)) != NULL)
+    {
+	/* keep both of these */
+      if (!ind_js && trypos != NULL && tryposBrace != NULL)
       {
 	  /* Both an unmatched '(' and '{' is found.  Use the one which is
 	   * closer to the current cursor position, set the other to NULL. */
@@ -6570,6 +6587,7 @@
 		    continue;
 		}
 
+		/* The line with the paren and current line are same */
 		/* XXX */
 		if ((trypos = find_match_paren(
 				corr_ind_maxparen(ind_maxparen, &cur_curpos),
@@ -6581,7 +6599,7 @@
 
 			if (theline[0] == ')')
 			{
-			    if (our_paren_pos.lnum != lnum
+			    if (!ind_js && our_paren_pos.lnum != lnum
 						       && cur_amount > amount)
 				cur_amount = amount;
 			    amount = -1;
@@ -6599,7 +6617,7 @@
 	if (amount == -1)
 	{
 	    int	    ignore_paren_col = 0;
-
+	    /* get the indent avoiding any labels */
 	    amount = skip_label(our_paren_pos.lnum, &look, ind_maxcomment);
 	    look = skipwhite(look);
 	    if (*look == '(')
@@ -6744,17 +6762,20 @@
 		if (cur_amount < amount)
 		    amount = cur_amount;
 	    }
+	    paren_scope_amount = amount;
 	}
 
 	/* add extra indent for a comment */
 	if (cin_iscomment(theline))
 	    amount += ind_comment;
       }
+      curwin->w_cursor  = cur_curpos;
+      tryposBrace = find_start_brace(ind_maxcomment);
 
       /*
        * Are we at least inside braces, then?
        */
-      else
+      if (tryposBrace != NULL)
       {
 	trypos = tryposBrace;
 
@@ -6801,10 +6822,9 @@
 	     *			ldfd) {
 	     *		    }
 	     */
-	    if ((ind_keep_case_label
-			   && cin_iscase(skipwhite(ml_get_curline()), FALSE)))
+	    if (ind_keep_case_label && cin_iscase(skipwhite(ml_get_curline())))
 		amount = get_indent();
-	    else
+	    else 
 		amount = skip_label(lnum, &l, ind_maxcomment);
 
 	    start_brace = BRACE_AT_END;
@@ -6880,7 +6900,7 @@
 
 	    lookfor_break = FALSE;
 
-	    if (cin_iscase(theline, FALSE))	/* it's a switch() label */
+	    if (cin_iscase(theline))	/* it's a switch() label */
 	    {
 		lookfor = LOOKFOR_CASE;	/* find a previous switch() label */
 		amount += ind_case;
@@ -6941,7 +6961,7 @@
 			     * initialization) */
 			    if (cont_amount > 0)
 				amount = cont_amount;
-			    else if (!ind_js)
+			    else
 				amount += ind_continuation;
 			    break;
 			}
@@ -7065,7 +7085,7 @@
 		 * If this is a switch() label, may line up relative to that.
 		 * If this is a C++ scope declaration, do the same.
 		 */
-		iscase = cin_iscase(l, FALSE);
+		iscase = cin_iscase(l);
 		if (iscase || cin_isscopedecl(l))
 		{
 		    /* we are only looking for cpp base class
@@ -7098,7 +7118,7 @@
 		     *	    x = 333;
 		     *	case yy:
 		     */
-		    if (       (iscase && lookfor == LOOKFOR_CASE)
+		    if ((iscase && lookfor == LOOKFOR_CASE)
 			    || (iscase && lookfor_break)
 			    || (!iscase && lookfor == LOOKFOR_SCOPEDECL))
 		    {
@@ -7277,16 +7297,18 @@
 		     * position the cursor over the rightmost paren, so that
 		     * matching it will take us back to the start of the line.
 		     */
-		    (void)find_last_paren(l, '(', ')');
-		    trypos = find_match_paren(
-				 corr_ind_maxparen(ind_maxparen, &cur_curpos),
-							      ind_maxcomment);
-
+		    if (!ind_js)
+		    {
+			(void)find_last_paren(l, '(', ')');
+			trypos = find_match_paren(
+				corr_ind_maxparen(ind_maxparen, &cur_curpos),
+				ind_maxcomment);
+		    }
 		    /*
 		     * If we are looking for ',', we also look for matching
 		     * braces.
 		     */
-		    if (trypos == NULL && terminated == ','
+		    if (!ind_js && trypos == NULL && terminated == ','
 					      && find_last_paren(l, '{', '}'))
 			trypos = find_start_brace(ind_maxcomment);
 
@@ -7300,7 +7322,7 @@
 			 */
 			curwin->w_cursor = *trypos;
 			l = ml_get_curline();
-			if (cin_iscase(l, FALSE) || cin_isscopedecl(l))
+			if (cin_iscase(l) || cin_isscopedecl(l))
 			{
 			    ++curwin->w_cursor.lnum;
 			    curwin->w_cursor.col = 0;
@@ -7333,7 +7355,7 @@
 		     */
 		    if (!ind_js)
 			cur_amount = skip_label(curwin->w_cursor.lnum,
-							  &l, ind_maxcomment);
+				&l, ind_maxcomment);
 		    else
 			cur_amount = get_indent();
 		    /*
@@ -7637,7 +7659,7 @@
 		     * To know what needs to be done look further backward for
 		     * a terminated line.
 		     */
-		    else
+		    else if (!paren_scope_amount)
 		    {
 			/*
 			 * position the cursor over the rightmost paren, so
@@ -7661,7 +7683,7 @@
 			     */
 			    curwin->w_cursor = *trypos;
 			    l = ml_get_curline();
-			    if (cin_iscase(l, FALSE) || cin_isscopedecl(l))
+			    if (cin_iscase(l) || cin_isscopedecl(l))
 			    {
 				++curwin->w_cursor.lnum;
 				curwin->w_cursor.col = 0;
@@ -7678,7 +7700,7 @@
 			 *	stat;
 			 * }
 			 */
-			iscase = (ind_keep_case_label && cin_iscase(l, FALSE));
+			iscase = (ind_keep_case_label && cin_iscase(l));
 
 			/*
 			 * Get indent and pointer to text for current line,
@@ -7739,7 +7761,8 @@
 	    }
 	}
       }
-
+      if (amount < paren_scope_amount)
+	  amount += paren_scope_amount;
       /* add extra indent for a comment */
       if (cin_iscomment(theline))
 	  amount += ind_comment;
@@ -7760,10 +7783,23 @@
 	 * prevailing indent and make sure it looks like the start
 	 * of a function
 	 */
-
+	/* what if we are deep inside multiple open braces?
+	 * ans: this is supposed to be handled before by tryposBrace
+	 */
+   
 	if (theline[0] == '{')
 	{
 	    amount = ind_first_open;
+	    //TODO: JS code -
+	    //look back how nested this is
+	    //if (1)
+	    //   oneliner();
+	    //   else
+	    //   (function ()
+	    //   {
+	    //   // manyliner;
+	    //   })();
+	    //
 	}
 
 	/*
@@ -7779,7 +7815,7 @@
 		&& 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)
+		&& (!ind_js && cin_isfuncdecl(NULL, cur_curpos.lnum + 1))
 		&& !cin_isterminated(theline, FALSE, TRUE))
 	{
 	    amount = ind_func_type;
@@ -7789,6 +7825,37 @@
 	    amount = 0;
 	    curwin->w_cursor = cur_curpos;
 
+	    l = skipwhite(ml_get_curline());
+	    /*
+	     * TODO: Handle JS code like:
+	     *	     if (a)
+	     *	        b();
+	     *	     else
+	     *	        (function ()
+	     *	         {
+	     *	             something();
+	     *	             if (2)
+	     *	                more_nastiness();
+	     *	             else
+	     *	                ugly();
+	     *	         })();
+	     *	    
+	     *	    if (ind_js)
+	     *	    {
+	     *		if (cin_iselse(l) || cin_isif(l))
+	     *		{
+	     *		    /* FIXME: need to match this up with any if's or else' up above
+	     *		     * if (typeof foo == bar)
+	     *		     *    (function () 
+	     *		     *       {
+	     *		     *          // something
+	     *		     *       })();
+	     *		     *  else
+	     *		     *     something more nasty;
+	     *		    goto theend;
+	     *		}
+	     *	    }
+	     */
 	    /* search backwards until we find something we recognize */
 
 	    while (curwin->w_cursor.lnum > 1)
@@ -7796,10 +7863,21 @@
 		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.
+		l = skipwhite(ml_get_curline());
+		/* TODO: statements which are not inside a brace (in JS)
+		 * 		if (ind_js)
+		 * 		{
+		 * 		    if (curwin->w_cursor.lnum == (cur_curpos.lnum - 1))
+		 * 		    {
+		 * 			if (cin_iselse(l) || cin_isif(l))
+		 * 			{
+		 * 			    amount = ind_level;
+		 * 			    break;
+		 * 			}
+		 * 		    }
+		 * 		}
+		 */
+		 /* If we're in a comment now, skip to the start of the comment.
 		 */						/* XXX */
 		if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
 		{
@@ -7834,7 +7912,6 @@
 
 		if (cin_nocode(l))
 		    continue;
-
 		/*
 		 * If the previous line ends in ',', use one level of
 		 * indentation:
@@ -7871,9 +7948,13 @@
 			--curwin->w_cursor.lnum;
 			curwin->w_cursor.col = 0;
 		    }
-
+/* The following means get the indent of the line where we are
+ * now
+ * i..e get_indent_lnum(curwin->w_cursor.lnum);
+ */
 		    amount = get_indent();	    /* XXX */
 
+		    /* -> static struct foo   b,  -> indent of "b" */
 		    if (amount == 0)
 			amount = cin_first_id_amount();
 		    if (amount == 0)
@@ -7972,7 +8053,6 @@
 	    }
 	}
     }
-
 theend:
     /* put the cursor back where it belongs */
     curwin->w_cursor = cur_curpos;
diff -r 486fb50528f0 -r 7d5e9d30c0ce src/proto/misc1.pro
--- a/src/proto/misc1.pro	Sun Jul 11 18:03:15 2010 +0200
+++ b/src/proto/misc1.pro	Sun Jul 11 22:49:16 2010 +0530
@@ -76,7 +76,7 @@
 pos_T *find_start_comment __ARGS((int ind_maxcomment));
 void do_c_expr_indent __ARGS((void));
 int cin_islabel __ARGS((int ind_maxcomment));
-int cin_iscase __ARGS((char_u *s, int strict));
+int cin_iscase __ARGS((char_u *s));
 int cin_isscopedecl __ARGS((char_u *s));
 int get_c_indent __ARGS((void));
 int get_expr_indent __ARGS((void));
