]> granicus.if.org Git - vim/commitdiff
patch 8.2.4329: no support for end line number and column in 'errorformat' v8.2.4329
authorhaya14busa <haya14busa@gmail.com>
Tue, 8 Feb 2022 18:09:29 +0000 (18:09 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 8 Feb 2022 18:09:29 +0000 (18:09 +0000)
Problem:    No support for end line number and column in 'errorformat'.
Solution:   Add %e and %k. (closes #9624)

runtime/doc/quickfix.txt
src/quickfix.c
src/testdir/test_quickfix.vim
src/version.c

index b7a01bdfd73c704f79f1a1852c7e12b132796f83..6bb259f723a93d0cdf7b210b956d4592f3e5a6bb 100644 (file)
@@ -1385,12 +1385,17 @@ Basic items
        %f              file name (finds a string)
        %o              module name (finds a string)
        %l              line number (finds a number)
+       %e              end line number (finds a number)
        %c              column number (finds a number representing character
                        column of the error, byte index, a <tab> is 1
                        character column)
        %v              virtual column number (finds a number representing
                        screen column of the error (1 <tab> == 8 screen
                        columns))
+       %k              end column number (finds a number representing
+                       the character column of the error, byte index, or a
+                       number representing screen end column of the error if
+                       it's used with %v)
        %t              error type (finds a single character):
                            e - error message
                            w - warning message
index 3643f2740392f1cdc9c4fc69bb843d188e8560a3..132d99216fe7c296d2016347c3c01df3cf976aa4 100644 (file)
@@ -118,7 +118,7 @@ struct qf_info_S
 static qf_info_T ql_info;      // global quickfix list
 static int_u last_qf_id = 0;   // Last used quickfix list id
 
-#define FMT_PATTERNS 11                // maximum number of % recognized
+#define FMT_PATTERNS 13                // maximum number of % recognized
 
 /*
  * Structure used to hold the info of one part of 'errorformat'
@@ -224,6 +224,9 @@ static bufref_T  qf_last_bufref = {NULL, 0, 0};
  */
 #define LINE_MAXLEN 4096
 
+/*
+ * Patterns used.  Keep in sync with qf_parse_fmt[].
+ */
 static struct fmtpattern
 {
     char_u     convchar;
@@ -231,16 +234,20 @@ static struct fmtpattern
 } fmt_pat[FMT_PATTERNS] =
     {
        {'f', ".\\+"},      // only used when at end
-       {'n', "\\d\\+"},
-       {'l', "\\d\\+"},
-       {'c', "\\d\\+"},
-       {'t', "."},
-       {'m', ".\\+"},
-       {'r', ".*"},
-       {'p', "[-       .]*"},
-       {'v', "\\d\\+"},
-       {'s', ".\\+"},
-       {'o', ".\\+"}
+       {'n', "\\d\\+"},        // 1
+       {'l', "\\d\\+"},        // 2
+       {'e', "\\d\\+"},        // 3
+       {'c', "\\d\\+"},        // 4
+       {'k', "\\d\\+"},        // 5
+       {'t', "."},             // 6
+#define FMT_PATTERN_M 7
+       {'m', ".\\+"},          // 7
+#define FMT_PATTERN_R 8
+       {'r', ".*"},            // 8
+       {'p', "[-       .]*"},  // 9
+       {'v', "\\d\\+"},        // 10
+       {'s', ".\\+"},          // 11
+       {'o', ".\\+"}           // 12
     };
 
 /*
@@ -265,9 +272,9 @@ efmpat_to_regpat(
        semsg(_(e_too_many_chr_in_format_string), *efmpat);
        return NULL;
     }
-    if ((idx && idx < 6
+    if ((idx && idx < FMT_PATTERN_R
                && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
-           || (idx == 6
+           || (idx == FMT_PATTERN_R
                && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL))
     {
        semsg(_(e_unexpected_chr_in_format_str), *efmpat);
@@ -948,7 +955,7 @@ qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields)
 }
 
 /*
- * Parse the match for line number (%l') pattern in regmatch.
+ * Parse the match for line number ('%l') pattern in regmatch.
  * Return the matched value in "fields->lnum".
  */
     static int
@@ -960,6 +967,19 @@ qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields)
     return QF_OK;
 }
 
+/*
+ * Parse the match for end line number ('%e') pattern in regmatch.
+ * Return the matched value in "fields->end_lnum".
+ */
+    static int
+qf_parse_fmt_e(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+    if (rmp->startp[midx] == NULL)
+       return QF_FAIL;
+    fields->end_lnum = atol((char *)rmp->startp[midx]);
+    return QF_OK;
+}
+
 /*
  * Parse the match for column number ('%c') pattern in regmatch.
  * Return the matched value in "fields->col".
@@ -973,6 +993,19 @@ qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields)
     return QF_OK;
 }
 
+/*
+ * Parse the match for end column number ('%k') pattern in regmatch.
+ * Return the matched value in "fields->end_col".
+ */
+    static int
+qf_parse_fmt_k(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+    if (rmp->startp[midx] == NULL)
+       return QF_FAIL;
+    fields->end_col = (int)atol((char *)rmp->startp[midx]);
+    return QF_OK;
+}
+
 /*
  * Parse the match for error type ('%t') pattern in regmatch.
  * Return the matched value in "fields->type".
@@ -1132,16 +1165,19 @@ qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
  * 'errorformat' format pattern parser functions.
  * The '%f' and '%r' formats are parsed differently from other formats.
  * See qf_parse_match() for details.
+ * Keep in sync with fmt_pat[].
  */
 static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) =
 {
-    NULL,
+    NULL, // %f
     qf_parse_fmt_n,
     qf_parse_fmt_l,
+    qf_parse_fmt_e,
     qf_parse_fmt_c,
+    qf_parse_fmt_k,
     qf_parse_fmt_t,
     qf_parse_fmt_m,
-    NULL,
+    NULL, // %r
     qf_parse_fmt_p,
     qf_parse_fmt_v,
     qf_parse_fmt_s,
@@ -1186,14 +1222,14 @@ qf_parse_match(
        midx = (int)fmt_ptr->addr[i];
        if (i == 0 && midx > 0)                         // %f
            status = qf_parse_fmt_f(regmatch, midx, fields, idx);
-       else if (i == 5)
+       else if (i == FMT_PATTERN_M)
        {
            if (fmt_ptr->flags == '+' && !qf_multiscan) // %+
                status = copy_nonerror_line(linebuf, linelen, fields);
            else if (midx > 0)                          // %m
                status = qf_parse_fmt_m(regmatch, midx, fields);
        }
-       else if (i == 6 && midx > 0)                    // %r
+       else if (i == FMT_PATTERN_R && midx > 0)        // %r
            status = qf_parse_fmt_r(regmatch, midx, tail);
        else if (midx > 0)                              // others
            status = (qf_parse_fmt[i])(regmatch, midx, fields);
@@ -1363,11 +1399,15 @@ qf_parse_multiline_pfx(
 
        if (!qfprev->qf_lnum)
            qfprev->qf_lnum = fields->lnum;
+       if (!qfprev->qf_end_lnum)
+           qfprev->qf_end_lnum = fields->end_lnum;
        if (!qfprev->qf_col)
        {
            qfprev->qf_col = fields->col;
            qfprev->qf_viscol = fields->use_viscol;
        }
+       if (!qfprev->qf_end_col)
+           qfprev->qf_end_col = fields->end_col;
        if (!qfprev->qf_fnum)
            qfprev->qf_fnum = qf_get_fnum(qfl,
                    qfl->qf_directory,
index adb0ea4fd5ce0801c36a0bd0f587ae6e8ef22d08..7d2373b828cf905688dc9dad3b7db17fb652909c 100644 (file)
@@ -1469,6 +1469,29 @@ func Test_efm_error_type()
   let &efm = save_efm
 endfunc
 
+" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
+func Test_efm_end_lnum_col()
+  let save_efm = &efm
+
+  " single line
+  set efm=%f:%l-%e:%c-%k:%t:%m
+  cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
+  let output = split(execute('clist'), "\n")
+  call assert_equal([
+        \ ' 1 Xfile1:10-20 col 1-2 error: msg1',
+        \ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
+
+  " multiple lines
+  set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
+  cexpr ["1)msg1", "Xfile1:14-24:1-2",
+        \ "2)msg2", "Xfile1:24-34:3-4"]
+  let output = split(execute('clist'), "\n")
+  call assert_equal([
+        \ ' 1 Xfile1:14-24 col 1-2 error   1: msg1',
+        \ ' 2 Xfile1:24-34 col 3-4 error   2: msg2'], output)
+  let &efm = save_efm
+endfunc
+
 func XquickfixChangedByAutocmd(cchar)
   call s:setup_commands(a:cchar)
   if a:cchar == 'c'
index 7e61af9edd44d05a6002967a1172ad24f9543040..2feed3cf37f0933fd1af64b7f565d4ef2d9df4ff 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4329,
 /**/
     4328,
 /**/