Patch 8.2.4329
Problem:    No support for end line number and column in 'errorformat'.
Solution:   Add %e and %k. (closes #9624)
Files:      runtime/doc/quickfix.txt, src/quickfix.c,
            src/testdir/test_quickfix.vim


*** ../vim-8.2.4328/runtime/doc/quickfix.txt    2021-04-26 20:14:12.709924759 
+0100
--- runtime/doc/quickfix.txt    2022-02-08 17:52:46.035090664 +0000
***************
*** 1382,1392 ****
        %f              file name (finds a string)
        %o              module name (finds a string)
        %l              line number (finds a number)
        %c              column number (finds a number representing character
!                       column of the error, (1 <tab> == 1 character column))
        %v              virtual column number (finds a number representing
                        screen column of the error (1 <tab> == 8 screen
                        columns))
        %t              error type (finds a single character):
                            e - error message
                            w - warning message
--- 1385,1401 ----
        %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
*** ../vim-8.2.4328/src/quickfix.c      2022-01-05 20:24:34.276005641 +0000
--- src/quickfix.c      2022-02-08 18:06:28.044675832 +0000
***************
*** 118,124 ****
  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
  
  /*
   * Structure used to hold the info of one part of 'errorformat'
--- 118,124 ----
  static qf_info_T ql_info;     // global quickfix list
  static int_u last_qf_id = 0;  // Last used quickfix list id
  
! #define FMT_PATTERNS 13               // maximum number of % recognized
  
  /*
   * Structure used to hold the info of one part of 'errorformat'
***************
*** 224,229 ****
--- 224,232 ----
   */
  #define LINE_MAXLEN 4096
  
+ /*
+  * Patterns used.  Keep in sync with qf_parse_fmt[].
+  */
  static struct fmtpattern
  {
      char_u    convchar;
***************
*** 231,246 ****
  } fmt_pat[FMT_PATTERNS] =
      {
        {'f', ".\\+"},      // only used when at end
!       {'n', "\\d\\+"},
!       {'l', "\\d\\+"},
!       {'c', "\\d\\+"},
!       {'t', "."},
!       {'m', ".\\+"},
!       {'r', ".*"},
!       {'p', "[-       .]*"},
!       {'v', "\\d\\+"},
!       {'s', ".\\+"},
!       {'o', ".\\+"}
      };
  
  /*
--- 234,253 ----
  } fmt_pat[FMT_PATTERNS] =
      {
        {'f', ".\\+"},      // only used when at end
!       {'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,273 ****
        semsg(_(e_too_many_chr_in_format_string), *efmpat);
        return NULL;
      }
!     if ((idx && idx < 6
                && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
!           || (idx == 6
                && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL))
      {
        semsg(_(e_unexpected_chr_in_format_str), *efmpat);
--- 272,280 ----
        semsg(_(e_too_many_chr_in_format_string), *efmpat);
        return NULL;
      }
!     if ((idx && idx < FMT_PATTERN_R
                && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
!           || (idx == FMT_PATTERN_R
                && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL))
      {
        semsg(_(e_unexpected_chr_in_format_str), *efmpat);
***************
*** 948,954 ****
  }
  
  /*
!  * Parse the match for line number (%l') pattern in regmatch.
   * Return the matched value in "fields->lnum".
   */
      static int
--- 955,961 ----
  }
  
  /*
!  * Parse the match for line number ('%l') pattern in regmatch.
   * Return the matched value in "fields->lnum".
   */
      static int
***************
*** 961,966 ****
--- 968,986 ----
  }
  
  /*
+  * 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".
   */
***************
*** 974,979 ****
--- 994,1012 ----
  }
  
  /*
+  * 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,1147 ****
   * 'errorformat' format pattern parser functions.
   * The '%f' and '%r' formats are parsed differently from other formats.
   * See qf_parse_match() for details.
   */
  static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) =
  {
!     NULL,
      qf_parse_fmt_n,
      qf_parse_fmt_l,
      qf_parse_fmt_c,
      qf_parse_fmt_t,
      qf_parse_fmt_m,
!     NULL,
      qf_parse_fmt_p,
      qf_parse_fmt_v,
      qf_parse_fmt_s,
--- 1165,1183 ----
   * '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, // %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, // %r
      qf_parse_fmt_p,
      qf_parse_fmt_v,
      qf_parse_fmt_s,
***************
*** 1186,1199 ****
        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)
        {
            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
            status = qf_parse_fmt_r(regmatch, midx, tail);
        else if (midx > 0)                              // others
            status = (qf_parse_fmt[i])(regmatch, midx, fields);
--- 1222,1235 ----
        midx = (int)fmt_ptr->addr[i];
        if (i == 0 && midx > 0)                         // %f
            status = qf_parse_fmt_f(regmatch, midx, fields, idx);
!       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 == 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,1373 ****
--- 1399,1413 ----
  
        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,
*** ../vim-8.2.4328/src/testdir/test_quickfix.vim       2022-02-08 
15:05:16.664625568 +0000
--- src/testdir/test_quickfix.vim       2022-02-08 17:48:35.780264014 +0000
***************
*** 1469,1474 ****
--- 1469,1497 ----
    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'
*** ../vim-8.2.4328/src/version.c       2022-02-08 17:40:13.649047302 +0000
--- src/version.c       2022-02-08 17:51:28.667417479 +0000
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     4329,
  /**/

-- 
I have a drinking problem -- I don't have a drink!

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220208181001.9EB171C1905%40moolenaar.net.

Raspunde prin e-mail lui