To: vim_dev@googlegroups.com Subject: Patch 7.4.355 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.355 Problem: Several problems with Javascript indenting. Solution: Improve Javascript indenting. Files: src/misc1.c *** ../vim-7.4.354/src/misc1.c 2014-07-02 18:27:44.662290695 +0200 --- src/misc1.c 2014-07-03 22:42:20.315848662 +0200 *************** *** 5382,5387 **** --- 5382,5388 ---- 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,5415 **** --- 5411,5417 ---- 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)); *************** *** 5494,5500 **** --- 5496,5533 ---- } /* + * 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) *************** *** 6621,6632 **** find_match_paren(ind_maxparen) /* XXX */ 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) { /* check if the ( is in a // comment */ if ((colnr_T)cin_skip2pos(trypos) > trypos->col) --- 6654,6673 ---- 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, c, 0, ind_maxparen)) != NULL) { /* check if the ( is in a // comment */ if ((colnr_T)cin_skip2pos(trypos) > trypos->col) *************** *** 6976,6981 **** --- 7017,7024 ---- #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,6991 **** --- 7029,7035 ---- 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; *************** *** 7209,7214 **** --- 7253,7268 ---- } /* + * 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 *************** *** 7473,7486 **** if (cin_iscomment(theline)) amount += curbuf->b_ind_comment; } - - /* - * Are we at least inside braces, then? - */ else { trypos = tryposBrace; - ourscope = trypos->lnum; start = ml_get(ourscope); --- 7527,7539 ---- if (cin_iscomment(theline)) amount += curbuf->b_ind_comment; } 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,7525 **** } else { ! /* ! * 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. ! */ 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 * case 1: if (asdf && * ldfd) { * } --- 7555,7573 ---- } else { ! /* 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. */ 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 * case 1: if (asdf && * ldfd) { * } *************** *** 7535,7542 **** start_brace = BRACE_AT_END; } /* ! * 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. */ --- 7583,7594 ---- 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 * we want to be. otherwise, add the amount of room * that an indent is supposed to be. */ *************** *** 7643,7649 **** * Search backwards. If we find something we recognize, line up * with that. * ! * if we're looking at an open brace, indent * the usual amount relative to the conditional * that opens the block. */ --- 7695,7701 ---- * Search backwards. If we find something we recognize, line up * with that. * ! * If we're looking at an open brace, indent * the usual amount relative to the conditional * that opens the block. */ *************** *** 8051,8056 **** --- 8103,8143 ---- */ 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,8072 **** * bar ) */ /* ! * 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(&cur_curpos)); /* * If we are looking for ',', we also look for matching --- 8149,8164 ---- * bar ) */ /* ! * 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,8126 **** * 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 cur_amount = get_indent(); /* * If this is just above the line we are indenting, and it * starts with a '{', line it up with this line. --- 8209,8218 ---- * Get indent and pointer to text for current line, * ignoring any jump label. XXX */ ! 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,8148 **** if (*skipwhite(l) != '{') amount += curbuf->b_ind_open_extra; ! if (curbuf->b_ind_cpp_baseclass) { /* have to look back, whether it is a cpp base * class declaration or initialization */ --- 8234,8240 ---- if (*skipwhite(l) != '{') amount += curbuf->b_ind_open_extra; ! 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,8309 **** */ if (lookfor == LOOKFOR_INITIAL && terminated == ',') { ! lookfor = LOOKFOR_ENUM_OR_INIT; ! cont_amount = cin_first_id_amount(); } else { --- 8394,8434 ---- */ if (lookfor == LOOKFOR_INITIAL && terminated == ',') { ! 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,8319 **** /* XXX */ cont_amount = cin_get_equal_amount( curwin->w_cursor.lnum); ! if (lookfor != LOOKFOR_TERM) lookfor = LOOKFOR_UNTERM; } } --- 8438,8445 ---- /* XXX */ cont_amount = cin_get_equal_amount( curwin->w_cursor.lnum); ! if (lookfor != LOOKFOR_TERM ! && lookfor != LOOKFOR_JS_KEY) lookfor = LOOKFOR_UNTERM; } } *************** *** 8324,8331 **** * Check if we are after a while (cond); * If so: Ignore until the matching "do". */ ! /* XXX */ ! else if (cin_iswhileofdo_end(terminated)) { /* * Found an unterminated line after a while ();, line up --- 8450,8456 ---- * Check if we are after a while (cond); * If so: Ignore until the matching "do". */ ! else if (cin_iswhileofdo_end(terminated)) /* XXX */ { /* * Found an unterminated line after a while ();, line up *************** *** 8538,8555 **** 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 { /* * if our line starts with an open brace, forget about any * prevailing indent and make sure it looks like the start * of a function --- 8663,8678 ---- 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 *************** *** 8700,8705 **** --- 8823,8840 ---- 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. *** ../vim-7.4.354/src/testdir/test3.in 2014-07-02 18:27:44.662290695 +0200 --- src/testdir/test3.in 2014-07-03 22:41:38.743848025 +0200 *************** *** 1432,1438 **** STARTTEST :set cino=(0,ts ! 2kdd=][ ENDTEST void func(int a --- 1432,1438 ---- STARTTEST :set cino=(0,ts ! 2kdd2j=][ ENDTEST void func(int a *************** *** 1446,1452 **** STARTTEST :set cino=(0 ! 2kdd=][ ENDTEST void --- 1446,1452 ---- STARTTEST :set cino=(0 ! 2kdd2j=][ ENDTEST void *************** *** 1461,1467 **** STARTTEST :set cino& ! 2kdd=7][ ENDTEST void func(void) --- 1461,1467 ---- STARTTEST :set cino& ! 2kdd2j=7][ ENDTEST void func(void) *************** *** 1538,1544 **** STARTTEST :set cino& :set cino+=l1 ! 2kdd=][ ENDTEST void func(void) --- 1538,1544 ---- STARTTEST :set cino& :set cino+=l1 ! 2kdd2j=][ ENDTEST void func(void) *************** *** 1567,1573 **** STARTTEST :set cino& ! 2kdd=][ ENDTEST void func(void) --- 1567,1573 ---- STARTTEST :set cino& ! 2kdd2j=][ ENDTEST void func(void) *************** *** 1592,1598 **** STARTTEST :set cino& ! 2kdd=][ ENDTEST void func(void) --- 1592,1598 ---- STARTTEST :set cino& ! 2kdd2j=][ ENDTEST void func(void) *************** *** 1919,1928 **** JSSTART var foo = [ ! 1, // indent 8 more 2, 3 ! ]; // indent 8 less JSEND STARTTEST --- 1919,1928 ---- JSSTART var foo = [ ! 1, 2, 3 ! ]; JSEND STARTTEST *************** *** 1937,1943 **** 1, 2, 3 ! ]; // indent 16 less } JSEND --- 1937,1943 ---- 1, 2, 3 ! ]; } JSEND *************** *** 1954,1959 **** --- 1954,1961 ---- cond) { stmt; } + window.something.left = + (width - 50 + offset) + "px"; var class_name='myclass'; function private_method() { *************** *** 1969,1983 **** $(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 ], ! callback: function(){ // indent 8 more ! return true; // indent 8 more ! } // indent 8 more }, options||{})); } --- 1971,1985 ---- $(this).data(class_name+'_public',$.extend({},{ foo: 'bar', ! bar: 2, ! foobar: [ ! 1, ! 2, ! 3 ], ! callback: function(){ ! return true; ! } }, options||{})); } *************** *** 2018,2026 **** foo: 'bar', bar: 2, foobar: [ ! 1, // indent 8 more ! 2, // indent 8 more ! 3 // indent 8 more ], callback: function(){ return true; --- 2020,2028 ---- foo: 'bar', bar: 2, foobar: [ ! 1, ! 2, ! 3 ], callback: function(){ return true; *************** *** 2040,2054 **** 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 ], ! callback: function(){ // indent 8 more ! return true; // indent 8 more ! } // indent 8 more }, options||{})); } })(jQuery); --- 2042,2056 ---- function init(options) { $(this).data(class_name+'_public',$.extend({},{ foo: 'bar', ! bar: 2, ! foobar: [ ! 1, ! 2, ! 3 ], ! callback: function(){ ! return true; ! } }, options||{})); } })(jQuery); *** ../vim-7.4.354/src/testdir/test3.ok 2014-07-02 18:27:44.662290695 +0200 --- src/testdir/test3.ok 2014-07-03 22:18:58.167827177 +0200 *************** *** 1707,1716 **** JSSTART var foo = [ ! 1, // indent 8 more 2, 3 ! ]; // indent 8 less JSEND --- 1707,1716 ---- JSSTART var foo = [ ! 1, 2, 3 ! ]; JSEND *************** *** 1720,1726 **** 1, 2, 3 ! ]; // indent 16 less } JSEND --- 1720,1726 ---- 1, 2, 3 ! ]; } JSEND *************** *** 1732,1737 **** --- 1732,1739 ---- cond) { stmt; } + window.something.left = + (width - 50 + offset) + "px"; var class_name='myclass'; function private_method() { *************** *** 1747,1761 **** $(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 ], ! callback: function(){ // indent 8 more ! return true; // indent 8 more ! } // indent 8 more }, options||{})); } --- 1749,1763 ---- $(this).data(class_name+'_public',$.extend({},{ foo: 'bar', ! bar: 2, ! foobar: [ ! 1, ! 2, ! 3 ], ! callback: function(){ ! return true; ! } }, options||{})); } *************** *** 1791,1799 **** foo: 'bar', bar: 2, foobar: [ ! 1, // indent 8 more ! 2, // indent 8 more ! 3 // indent 8 more ], callback: function(){ return true; --- 1793,1801 ---- foo: 'bar', bar: 2, foobar: [ ! 1, ! 2, ! 3 ], callback: function(){ return true; *************** *** 1808,1822 **** 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 ], ! callback: function(){ // indent 8 more ! return true; // indent 8 more ! } // indent 8 more }, options||{})); } })(jQuery); --- 1810,1824 ---- function init(options) { $(this).data(class_name+'_public',$.extend({},{ foo: 'bar', ! bar: 2, ! foobar: [ ! 1, ! 2, ! 3 ], ! callback: function(){ ! return true; ! } }, options||{})); } })(jQuery); *** ../vim-7.4.354/src/version.c 2014-07-03 22:54:04.911859458 +0200 --- src/version.c 2014-07-03 22:54:40.971860011 +0200 *************** *** 736,737 **** --- 736,739 ---- { /* Add new patch number below this line */ + /**/ + 355, /**/ -- MESKIMEN'S LAW There's never time to do it right, but always time to do it over. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 ///