diff options
Diffstat (limited to 'data/vim/patches/8.1.1256')
-rw-r--r-- | data/vim/patches/8.1.1256 | 810 |
1 files changed, 810 insertions, 0 deletions
diff --git a/data/vim/patches/8.1.1256 b/data/vim/patches/8.1.1256 new file mode 100644 index 000000000..cee4de207 --- /dev/null +++ b/data/vim/patches/8.1.1256 @@ -0,0 +1,810 @@ +To: vim_dev@googlegroups.com +Subject: Patch 8.1.1256 +Fcc: outbox +From: Bram Moolenaar <Bram@moolenaar.net> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 8.1.1256 +Problem: Cannot navigate through errors relative to the cursor. +Solution: Add :cabove, :cbelow, :labove and :lbelow. (Yegappan Lakshmanan, + closes #4316) +Files: runtime/doc/index.txt, runtime/doc/quickfix.txt, src/ex_cmdidxs.h, + src/ex_cmds.h, src/ex_docmd.c, src/proto/quickfix.pro, + src/quickfix.c, src/testdir/test_quickfix.vim + + +*** ../vim-8.1.1255/runtime/doc/index.txt 2019-04-27 20:36:52.526303597 +0200 +--- runtime/doc/index.txt 2019-05-03 21:35:09.162087906 +0200 +*************** +*** 1140,1150 **** +--- 1192,1204 ---- + |:cNfile| :cNf[ile] go to last error in previous file + |:cabbrev| :ca[bbrev] like ":abbreviate" but for Command-line mode + |:cabclear| :cabc[lear] clear all abbreviations for Command-line mode ++ |:cabove| :cabo[ve] go to error above current line + |:caddbuffer| :cad[dbuffer] add errors from buffer + |:caddexpr| :cadde[xpr] add errors from expr + |:caddfile| :caddf[ile] add error message to current quickfix list + |:call| :cal[l] call a function + |:catch| :cat[ch] part of a :try command ++ |:cbelow| :cbe[low] got to error below current line + |:cbottom| :cbo[ttom] scroll to the bottom of the quickfix window + |:cbuffer| :cb[uffer] parse error messages and jump to first error + |:cc| :cc go to specific error +*************** +*** 1302,1313 **** +--- 1356,1369 ---- + |:lNext| :lN[ext] go to previous entry in location list + |:lNfile| :lNf[ile] go to last entry in previous file + |:list| :l[ist] print lines ++ |:labove| :lab[ove] go to location above current line + |:laddexpr| :lad[dexpr] add locations from expr + |:laddbuffer| :laddb[uffer] add locations from buffer + |:laddfile| :laddf[ile] add locations to current location list + |:last| :la[st] go to the last file in the argument list + |:language| :lan[guage] set the language (locale) + |:later| :lat[er] go to newer change, redo ++ |:lbelow| :lbe[low] go to location below current line + |:lbottom| :lbo[ttom] scroll to the bottom of the location window + |:lbuffer| :lb[uffer] parse locations and jump to first location + |:lcd| :lc[d] change directory locally +--- 1703,1708 ---- +*** ../vim-8.1.1255/runtime/doc/quickfix.txt 2019-03-17 16:39:01.566006172 +0100 +--- runtime/doc/quickfix.txt 2019-05-03 21:35:09.166087887 +0200 +*************** +*** 123,128 **** +--- 123,158 ---- + list for the current window is used instead of the + quickfix list. + ++ *:cabo* *:cabove* ++ :[count]cabo[ve] Go to the [count] error above the current line in the ++ current buffer. If [count] is omitted, then 1 is ++ used. If there are no errors, then an error message ++ is displayed. Assumes that the entries in a quickfix ++ list are sorted by their buffer number and line ++ number. If there are multiple errors on the same line, ++ then only the first entry is used. If [count] exceeds ++ the number of entries above the current line, then the ++ first error in the file is selected. ++ ++ *:lab* *:labove* ++ :[count]lab[ove] Same as ":cabove", except the location list for the ++ current window is used instead of the quickfix list. ++ ++ *:cbe* *:cbelow* ++ :[count]cbe[low] Go to the [count] error below the current line in the ++ current buffer. If [count] is omitted, then 1 is ++ used. If there are no errors, then an error message ++ is displayed. Assumes that the entries in a quickfix ++ list are sorted by their buffer number and line ++ number. If there are multiple errors on the same ++ line, then only the first entry is used. If [count] ++ exceeds the number of entries below the current line, ++ then the last error in the file is selected. ++ ++ *:lbe* *:lbelow* ++ :[count]lbe[low] Same as ":cbelow", except the location list for the ++ current window is used instead of the quickfix list. ++ + *:cnf* *:cnfile* + :[count]cnf[ile][!] Display the first error in the [count] next file in + the list that includes a file name. If there are no +*** ../vim-8.1.1255/src/ex_cmdidxs.h 2019-04-27 20:36:52.530303581 +0200 +--- src/ex_cmdidxs.h 2019-05-03 21:42:06.720008024 +0200 +*************** +*** 8,36 **** + /* a */ 0, + /* b */ 19, + /* c */ 42, +! /* d */ 103, +! /* e */ 125, +! /* f */ 145, +! /* g */ 161, +! /* h */ 167, +! /* i */ 176, +! /* j */ 194, +! /* k */ 196, +! /* l */ 201, +! /* m */ 259, +! /* n */ 277, +! /* o */ 297, +! /* p */ 309, +! /* q */ 348, +! /* r */ 351, +! /* s */ 371, +! /* t */ 439, +! /* u */ 484, +! /* v */ 495, +! /* w */ 513, +! /* x */ 527, +! /* y */ 536, +! /* z */ 537 + }; + + /* +--- 8,36 ---- + /* a */ 0, + /* b */ 19, + /* c */ 42, +! /* d */ 105, +! /* e */ 127, +! /* f */ 147, +! /* g */ 163, +! /* h */ 169, +! /* i */ 178, +! /* j */ 196, +! /* k */ 198, +! /* l */ 203, +! /* m */ 263, +! /* n */ 281, +! /* o */ 301, +! /* p */ 313, +! /* q */ 352, +! /* r */ 355, +! /* s */ 375, +! /* t */ 443, +! /* u */ 488, +! /* v */ 499, +! /* w */ 517, +! /* x */ 531, +! /* y */ 540, +! /* z */ 541 + }; + + /* +*************** +*** 43,49 **** + { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ + /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0 }, + /* b */ { 2, 0, 0, 4, 5, 7, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 13, 0, 0, 0, 0, 22, 0, 0, 0 }, +! /* c */ { 3, 10, 12, 14, 16, 18, 21, 0, 0, 0, 0, 29, 33, 36, 42, 51, 53, 54, 55, 0, 57, 0, 60, 0, 0, 0 }, + /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 15, 0, 16, 0, 0, 17, 0, 0, 19, 20, 0, 0, 0, 0, 0, 0, 0 }, + /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0 }, + /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0 }, +--- 43,49 ---- + { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ + /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0 }, + /* b */ { 2, 0, 0, 4, 5, 7, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 13, 0, 0, 0, 0, 22, 0, 0, 0 }, +! /* c */ { 3, 11, 14, 16, 18, 20, 23, 0, 0, 0, 0, 31, 35, 38, 44, 53, 55, 56, 57, 0, 59, 0, 62, 0, 0, 0 }, + /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 15, 0, 16, 0, 0, 17, 0, 0, 19, 20, 0, 0, 0, 0, 0, 0, 0 }, + /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0 }, + /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0 }, +*************** +*** 52,58 **** + /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 13, 0, 15, 0, 0, 0, 0, 0 }, + /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, + /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +! /* l */ { 3, 9, 11, 15, 16, 20, 23, 28, 0, 0, 0, 30, 33, 36, 40, 46, 0, 48, 57, 49, 50, 54, 56, 0, 0, 0 }, + /* m */ { 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }, + /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0 }, + /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0 }, +--- 52,58 ---- + /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 13, 0, 15, 0, 0, 0, 0, 0 }, + /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, + /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +! /* l */ { 3, 10, 13, 17, 18, 22, 25, 30, 0, 0, 0, 32, 35, 38, 42, 48, 0, 50, 59, 51, 52, 56, 58, 0, 0, 0 }, + /* m */ { 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }, + /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0 }, + /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0 }, +*************** +*** 69,72 **** + /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + +! static const int command_count = 550; +--- 69,72 ---- + /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + +! static const int command_count = 554; +*** ../vim-8.1.1255/src/ex_cmds.h 2019-05-01 18:08:38.263237252 +0200 +--- src/ex_cmds.h 2019-05-03 21:43:59.707432410 +0200 +*************** +*** 252,257 **** +--- 252,260 ---- + EX(CMD_cabclear, "cabclear", ex_abclear, + EXTRA|TRLBAR|CMDWIN, + ADDR_NONE), ++ EX(CMD_cabove, "cabove", ex_cbelow, ++ RANGE|TRLBAR, ++ ADDR_OTHER), + EX(CMD_caddbuffer, "caddbuffer", ex_cbuffer, + RANGE|WORD1|TRLBAR, + ADDR_OTHER), +*************** +*** 270,275 **** +--- 273,281 ---- + EX(CMD_cbuffer, "cbuffer", ex_cbuffer, + BANG|RANGE|WORD1|TRLBAR, + ADDR_OTHER), ++ EX(CMD_cbelow, "cbelow", ex_cbelow, ++ RANGE|TRLBAR, ++ ADDR_OTHER), + EX(CMD_cbottom, "cbottom", ex_cbottom, + TRLBAR, + ADDR_NONE), +*************** +*** 726,731 **** +--- 732,740 ---- + EX(CMD_last, "last", ex_last, + EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR, + ADDR_NONE), ++ EX(CMD_labove, "labove", ex_cbelow, ++ RANGE|TRLBAR, ++ ADDR_OTHER), + EX(CMD_language, "language", ex_language, + EXTRA|TRLBAR|CMDWIN, + ADDR_NONE), +*************** +*** 744,749 **** +--- 753,761 ---- + EX(CMD_lbuffer, "lbuffer", ex_cbuffer, + BANG|RANGE|WORD1|TRLBAR, + ADDR_OTHER), ++ EX(CMD_lbelow, "lbelow", ex_cbelow, ++ RANGE|TRLBAR, ++ ADDR_OTHER), + EX(CMD_lbottom, "lbottom", ex_cbottom, + TRLBAR, + ADDR_NONE), +*** ../vim-8.1.1255/src/ex_docmd.c 2019-05-01 21:43:39.076257243 +0200 +--- src/ex_docmd.c 2019-05-03 21:35:09.166087887 +0200 +*************** +*** 56,61 **** +--- 56,62 ---- + # define ex_cbuffer ex_ni + # define ex_cc ex_ni + # define ex_cnext ex_ni ++ # define ex_cbelow ex_ni + # define ex_cfile ex_ni + # define qf_list ex_ni + # define qf_age ex_ni +*** ../vim-8.1.1255/src/proto/quickfix.pro 2019-02-05 21:23:00.600559169 +0100 +--- src/proto/quickfix.pro 2019-05-03 21:35:09.166087887 +0200 +*************** +*** 23,28 **** +--- 23,29 ---- + int qf_get_cur_valid_idx(exarg_T *eap); + void ex_cc(exarg_T *eap); + void ex_cnext(exarg_T *eap); ++ void ex_cbelow(exarg_T *eap); + void ex_cfile(exarg_T *eap); + void ex_vimgrep(exarg_T *eap); + int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list); +*** ../vim-8.1.1255/src/quickfix.c 2019-05-02 20:17:29.318924421 +0200 +--- src/quickfix.c 2019-05-03 21:35:09.166087887 +0200 +*************** +*** 177,182 **** +--- 177,183 ---- + static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start); + static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start); + static qf_info_T *ll_get_or_alloc_list(win_T *); ++ static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); + + // Quickfix window check helper macro + #define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL) +*************** +*** 1494,1499 **** +--- 1495,1510 ---- + } + + /* ++ * Returns TRUE if the specified quickfix/location list is not empty and ++ * has valid entries. ++ */ ++ static int ++ qf_list_has_valid_entries(qf_list_T *qfl) ++ { ++ return !qf_list_empty(qfl) && !qfl->qf_nonevalid; ++ } ++ ++ /* + * Return a pointer to a list in the specified quickfix stack + */ + static qf_list_T * +*************** +*** 2700,2706 **** + int qf_idx = qfl->qf_index; + qfline_T *prev_qf_ptr; + int prev_index; +- static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); + char_u *err = e_no_more_items; + + while (errornr--) +--- 2711,2716 ---- +*************** +*** 4886,4892 **** + qfp = qfl->qf_start; + + // check if the list has valid errors +! if (qfl->qf_count <= 0 || qfl->qf_nonevalid) + return 1; + + for (i = 1; i <= qfl->qf_index && qfp!= NULL; i++, qfp = qfp->qf_next) +--- 4896,4902 ---- + qfp = qfl->qf_start; + + // check if the list has valid errors +! if (!qf_list_has_valid_entries(qfl)) + return 1; + + for (i = 1; i <= qfl->qf_index && qfp!= NULL; i++, qfp = qfp->qf_next) +*************** +*** 4924,4930 **** + int prev_fnum = 0; + + // check if the list has valid errors +! if (qfl->qf_count <= 0 || qfl->qf_nonevalid) + return 1; + + eidx = 0; +--- 4934,4940 ---- + int prev_fnum = 0; + + // check if the list has valid errors +! if (!qf_list_has_valid_entries(qfl)) + return 1; + + eidx = 0; +*************** +*** 5045,5050 **** +--- 5055,5355 ---- + } + + /* ++ * Find the first entry in the quickfix list 'qfl' from buffer 'bnr'. ++ * The index of the entry is stored in 'errornr'. ++ * Returns NULL if an entry is not found. ++ */ ++ static qfline_T * ++ qf_find_first_entry_in_buf(qf_list_T *qfl, int bnr, int *errornr) ++ { ++ qfline_T *qfp = NULL; ++ int idx = 0; ++ ++ // Find the first entry in this file ++ FOR_ALL_QFL_ITEMS(qfl, qfp, idx) ++ if (qfp->qf_fnum == bnr) ++ break; ++ ++ *errornr = idx; ++ return qfp; ++ } ++ ++ /* ++ * Find the first quickfix entry on the same line as 'entry'. Updates 'errornr' ++ * with the error number for the first entry. Assumes the entries are sorted in ++ * the quickfix list by line number. ++ */ ++ static qfline_T * ++ qf_find_first_entry_on_line(qfline_T *entry, int *errornr) ++ { ++ while (!got_int ++ && entry->qf_prev != NULL ++ && entry->qf_fnum == entry->qf_prev->qf_fnum ++ && entry->qf_lnum == entry->qf_prev->qf_lnum) ++ { ++ entry = entry->qf_prev; ++ --*errornr; ++ } ++ ++ return entry; ++ } ++ ++ /* ++ * Find the last quickfix entry on the same line as 'entry'. Updates 'errornr' ++ * with the error number for the last entry. Assumes the entries are sorted in ++ * the quickfix list by line number. ++ */ ++ static qfline_T * ++ qf_find_last_entry_on_line(qfline_T *entry, int *errornr) ++ { ++ while (!got_int && ++ entry->qf_next != NULL ++ && entry->qf_fnum == entry->qf_next->qf_fnum ++ && entry->qf_lnum == entry->qf_next->qf_lnum) ++ { ++ entry = entry->qf_next; ++ ++*errornr; ++ } ++ ++ return entry; ++ } ++ ++ /* ++ * Find the first quickfix entry below line 'lnum' in buffer 'bnr'. ++ * 'qfp' points to the very first entry in the buffer and 'errornr' is the ++ * index of the very first entry in the quickfix list. ++ * Returns NULL if an entry is not found after 'lnum'. ++ */ ++ static qfline_T * ++ qf_find_entry_on_next_line( ++ int bnr, ++ linenr_T lnum, ++ qfline_T *qfp, ++ int *errornr) ++ { ++ if (qfp->qf_lnum > lnum) ++ // First entry is after line 'lnum' ++ return qfp; ++ ++ // Find the entry just before or at the line 'lnum' ++ while (qfp->qf_next != NULL ++ && qfp->qf_next->qf_fnum == bnr ++ && qfp->qf_next->qf_lnum <= lnum) ++ { ++ qfp = qfp->qf_next; ++ ++*errornr; ++ } ++ ++ if (qfp->qf_next == NULL || qfp->qf_next->qf_fnum != bnr) ++ // No entries found after 'lnum' ++ return NULL; ++ ++ // Use the entry just after line 'lnum' ++ qfp = qfp->qf_next; ++ ++*errornr; ++ ++ return qfp; ++ } ++ ++ /* ++ * Find the first quickfix entry before line 'lnum' in buffer 'bnr'. ++ * 'qfp' points to the very first entry in the buffer and 'errornr' is the ++ * index of the very first entry in the quickfix list. ++ * Returns NULL if an entry is not found before 'lnum'. ++ */ ++ static qfline_T * ++ qf_find_entry_on_prev_line( ++ int bnr, ++ linenr_T lnum, ++ qfline_T *qfp, ++ int *errornr) ++ { ++ // Find the entry just before the line 'lnum' ++ while (qfp->qf_next != NULL ++ && qfp->qf_next->qf_fnum == bnr ++ && qfp->qf_next->qf_lnum < lnum) ++ { ++ qfp = qfp->qf_next; ++ ++*errornr; ++ } ++ ++ if (qfp->qf_lnum >= lnum) // entry is after 'lnum' ++ return NULL; ++ ++ // If multiple entries are on the same line, then use the first entry ++ qfp = qf_find_first_entry_on_line(qfp, errornr); ++ ++ return qfp; ++ } ++ ++ /* ++ * Find a quickfix entry in 'qfl' closest to line 'lnum' in buffer 'bnr' in ++ * the direction 'dir'. ++ */ ++ static qfline_T * ++ qf_find_closest_entry( ++ qf_list_T *qfl, ++ int bnr, ++ linenr_T lnum, ++ int dir, ++ int *errornr) ++ { ++ qfline_T *qfp; ++ ++ *errornr = 0; ++ ++ // Find the first entry in this file ++ qfp = qf_find_first_entry_in_buf(qfl, bnr, errornr); ++ if (qfp == NULL) ++ return NULL; // no entry in this file ++ ++ if (dir == FORWARD) ++ qfp = qf_find_entry_on_next_line(bnr, lnum, qfp, errornr); ++ else ++ qfp = qf_find_entry_on_prev_line(bnr, lnum, qfp, errornr); ++ ++ return qfp; ++ } ++ ++ /* ++ * Get the nth quickfix entry below the specified entry treating multiple ++ * entries on a single line as one. Searches forward in the list. ++ */ ++ static qfline_T * ++ qf_get_nth_below_entry(qfline_T *entry, int *errornr, int n) ++ { ++ while (n-- > 0 && !got_int) ++ { ++ qfline_T *first_entry = entry; ++ int first_errornr = *errornr; ++ ++ // Treat all the entries on the same line in this file as one ++ entry = qf_find_last_entry_on_line(entry, errornr); ++ ++ if (entry->qf_next == NULL ++ || entry->qf_next->qf_fnum != entry->qf_fnum) ++ { ++ // If multiple entries are on the same line, then use the first ++ // entry ++ entry = first_entry; ++ *errornr = first_errornr; ++ break; ++ } ++ ++ entry = entry->qf_next; ++ ++*errornr; ++ } ++ ++ return entry; ++ } ++ ++ /* ++ * Get the nth quickfix entry above the specified entry treating multiple ++ * entries on a single line as one. Searches backwards in the list. ++ */ ++ static qfline_T * ++ qf_get_nth_above_entry(qfline_T *entry, int *errornr, int n) ++ { ++ while (n-- > 0 && !got_int) ++ { ++ if (entry->qf_prev == NULL ++ || entry->qf_prev->qf_fnum != entry->qf_fnum) ++ break; ++ ++ entry = entry->qf_prev; ++ --*errornr; ++ ++ // If multiple entries are on the same line, then use the first entry ++ entry = qf_find_first_entry_on_line(entry, errornr); ++ } ++ ++ return entry; ++ } ++ ++ /* ++ * Find the n'th quickfix entry adjacent to line 'lnum' in buffer 'bnr' in the ++ * specified direction. ++ * Returns the error number in the quickfix list or 0 if an entry is not found. ++ */ ++ static int ++ qf_find_nth_adj_entry(qf_list_T *qfl, int bnr, linenr_T lnum, int n, int dir) ++ { ++ qfline_T *adj_entry; ++ int errornr; ++ ++ // Find an entry closest to the specified line ++ adj_entry = qf_find_closest_entry(qfl, bnr, lnum, dir, &errornr); ++ if (adj_entry == NULL) ++ return 0; ++ ++ if (--n > 0) ++ { ++ // Go to the n'th entry in the current buffer ++ if (dir == FORWARD) ++ adj_entry = qf_get_nth_below_entry(adj_entry, &errornr, n); ++ else ++ adj_entry = qf_get_nth_above_entry(adj_entry, &errornr, n); ++ } ++ ++ return errornr; ++ } ++ ++ /* ++ * Jump to a quickfix entry in the current file nearest to the current line. ++ * ":cabove", ":cbelow", ":labove" and ":lbelow" commands ++ */ ++ void ++ ex_cbelow(exarg_T *eap) ++ { ++ qf_info_T *qi; ++ qf_list_T *qfl; ++ int dir; ++ int buf_has_flag; ++ int errornr = 0; ++ ++ if (eap->addr_count > 0 && eap->line2 <= 0) ++ { ++ emsg(_(e_invrange)); ++ return; ++ } ++ ++ // Check whether the current buffer has any quickfix entries ++ if (eap->cmdidx == CMD_cabove || eap->cmdidx == CMD_cbelow) ++ buf_has_flag = BUF_HAS_QF_ENTRY; ++ else ++ buf_has_flag = BUF_HAS_LL_ENTRY; ++ if (!(curbuf->b_has_qf_entry & buf_has_flag)) ++ { ++ emsg(_(e_quickfix)); ++ return; ++ } ++ ++ if ((qi = qf_cmd_get_stack(eap, TRUE)) == NULL) ++ return; ++ ++ qfl = qf_get_curlist(qi); ++ // check if the list has valid errors ++ if (!qf_list_has_valid_entries(qfl)) ++ { ++ emsg(_(e_quickfix)); ++ return; ++ } ++ ++ if (eap->cmdidx == CMD_cbelow || eap->cmdidx == CMD_lbelow) ++ dir = FORWARD; ++ else ++ dir = BACKWARD; ++ ++ errornr = qf_find_nth_adj_entry(qfl, curbuf->b_fnum, curwin->w_cursor.lnum, ++ eap->addr_count > 0 ? eap->line2 : 0, dir); ++ ++ if (errornr > 0) ++ qf_jump(qi, 0, errornr, FALSE); ++ else ++ emsg(_(e_no_more_items)); ++ } ++ ++ /* + * Return the autocmd name for the :cfile Ex commands + */ + static char_u * +*** ../vim-8.1.1255/src/testdir/test_quickfix.vim 2019-05-02 20:17:29.322924398 +0200 +--- src/testdir/test_quickfix.vim 2019-05-03 21:48:52.249927300 +0200 +*************** +*** 37,42 **** +--- 37,44 ---- + command! -nargs=* Xgrepadd <mods> grepadd <args> + command! -nargs=* Xhelpgrep helpgrep <args> + command! -nargs=0 -count Xcc <count>cc ++ command! -count=1 -nargs=0 Xbelow <mods><count>cbelow ++ command! -count=1 -nargs=0 Xabove <mods><count>cabove + let g:Xgetlist = function('getqflist') + let g:Xsetlist = function('setqflist') + call setqflist([], 'f') +*************** +*** 70,75 **** +--- 72,79 ---- + command! -nargs=* Xgrepadd <mods> lgrepadd <args> + command! -nargs=* Xhelpgrep lhelpgrep <args> + command! -nargs=0 -count Xcc <count>ll ++ command! -count=1 -nargs=0 Xbelow <mods><count>lbelow ++ command! -count=1 -nargs=0 Xabove <mods><count>labove + let g:Xgetlist = function('getloclist', [0]) + let g:Xsetlist = function('setloclist', [0]) + call setloclist(0, [], 'f') +*************** +*** 4035,4037 **** +--- 4039,4147 ---- + enew + call delete('Xfile1') + endfunc ++ ++ " Test for the :cbelow, :cabove, :lbelow and :labove commands. ++ func Xtest_below(cchar) ++ call s:setup_commands(a:cchar) ++ ++ " No quickfix/location list ++ call assert_fails('Xbelow', 'E42:') ++ call assert_fails('Xabove', 'E42:') ++ ++ " Empty quickfix/location list ++ call g:Xsetlist([]) ++ call assert_fails('Xbelow', 'E42:') ++ call assert_fails('Xabove', 'E42:') ++ ++ call s:create_test_file('X1') ++ call s:create_test_file('X2') ++ call s:create_test_file('X3') ++ call s:create_test_file('X4') ++ ++ " Invalid entries ++ edit X1 ++ call g:Xsetlist(["E1", "E2"]) ++ call assert_fails('Xbelow', 'E42:') ++ call assert_fails('Xabove', 'E42:') ++ call assert_fails('3Xbelow', 'E42:') ++ call assert_fails('4Xabove', 'E42:') ++ ++ " Test the commands with various arguments ++ Xexpr ["X1:5:L5", "X2:5:L5", "X2:10:L10", "X2:15:L15", "X3:3:L3"] ++ edit +7 X2 ++ Xabove ++ call assert_equal(['X2', 5], [bufname(''), line('.')]) ++ call assert_fails('Xabove', 'E553:') ++ normal 2j ++ Xbelow ++ call assert_equal(['X2', 10], [bufname(''), line('.')]) ++ " Last error in this file ++ Xbelow 99 ++ call assert_equal(['X2', 15], [bufname(''), line('.')]) ++ call assert_fails('Xbelow', 'E553:') ++ " First error in this file ++ Xabove 99 ++ call assert_equal(['X2', 5], [bufname(''), line('.')]) ++ call assert_fails('Xabove', 'E553:') ++ normal gg ++ Xbelow 2 ++ call assert_equal(['X2', 10], [bufname(''), line('.')]) ++ normal G ++ Xabove 2 ++ call assert_equal(['X2', 10], [bufname(''), line('.')]) ++ edit X4 ++ call assert_fails('Xabove', 'E42:') ++ call assert_fails('Xbelow', 'E42:') ++ if a:cchar == 'l' ++ " If a buffer has location list entries from some other window but not ++ " from the current window, then the commands should fail. ++ edit X1 | split | call setloclist(0, [], 'f') ++ call assert_fails('Xabove', 'E776:') ++ call assert_fails('Xbelow', 'E776:') ++ close ++ endif ++ ++ " Test for lines with multiple quickfix entries ++ Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3", ++ \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3", ++ \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"] ++ edit +1 X2 ++ Xbelow 2 ++ call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')]) ++ normal gg ++ Xbelow 99 ++ call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')]) ++ normal G ++ Xabove 2 ++ call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')]) ++ normal G ++ Xabove 99 ++ call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')]) ++ normal 10G ++ Xabove ++ call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')]) ++ normal 10G ++ Xbelow ++ call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')]) ++ ++ " Invalid range ++ if a:cchar == 'c' ++ call assert_fails('-2cbelow', 'E553:') ++ " TODO: should go to first error in the current line? ++ 0cabove ++ else ++ call assert_fails('-2lbelow', 'E553:') ++ " TODO: should go to first error in the current line? ++ 0labove ++ endif ++ ++ call delete('X1') ++ call delete('X2') ++ call delete('X3') ++ call delete('X4') ++ endfunc ++ ++ func Test_cbelow() ++ call Xtest_below('c') ++ call Xtest_below('l') ++ endfunc +*** ../vim-8.1.1255/src/version.c 2019-05-03 21:19:58.926404208 +0200 +--- src/version.c 2019-05-03 21:35:46.089908080 +0200 +*************** +*** 769,770 **** +--- 769,772 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 1256, + /**/ + +-- +A hamburger walks into a bar, and the bartender says: "I'm sorry, +but we don't serve food here." + + /// 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 /// |