]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.0.1782: no simple way to label quickfix entries v8.0.1782
authorBram Moolenaar <Bram@vim.org>
Tue, 1 May 2018 13:02:04 +0000 (15:02 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 1 May 2018 13:02:04 +0000 (15:02 +0200)
Problem:    No simple way to label quickfix entries.
Solution:   Add the "module" item, to be used instead of the file name for
            display purposes. (Martin Szamotulski, closes #1757)

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

index 0e611f4f1e53deb91e021872079768d534e6ddd0..050b48960a586b2b8647b230621bd901e768d3bc 100644 (file)
@@ -4737,6 +4737,7 @@ getqflist([{what}])                                       *getqflist()*
                list item is a dictionary with these entries:
                        bufnr   number of buffer that has the file name, use
                                bufname() to get the name
+                       module  module name
                        lnum    line number in the buffer (first line is 1)
                        col     column number (first column is 1)
                        vcol    |TRUE|: "col" is visual column
@@ -7221,6 +7222,8 @@ setqflist({list} [, {action} [, {what}]])         *setqflist()*
                                buffer
                    filename    name of a file; only used when "bufnr" is not
                                present or it is invalid.
+                   module      name of a module; if given it will be used in
+                               quickfix error window instead of the filename.
                    lnum        line number in the file
                    pattern     search pattern used to locate the error
                    col         column number
index de80c68adf029857e1b844e318cdfa362c580708..96085d2e2c47c670563829f09b2c5d31689caf10 100644 (file)
@@ -1220,6 +1220,7 @@ you want to match case, add "\C" to the pattern |/\C|.
 Basic items
 
        %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))
@@ -1264,6 +1265,11 @@ conversion can be used to locate lines without a line number in the error
 output.  Like the output of the "grep" shell command.
 When the pattern is present the line number will not be used.
 
+The "%o" conversion specifies the module name in quickfix entry.  If present
+it will be used in quickfix error window instead of the filename.  The module
+name is used only for displaying purposes, the file name is used when jumping
+to the file.
+
 Changing directory
 
 The following uppercase conversion characters specify the type of special
index 715f5cc25c8d5c1cdc9471ad9fa62e57a1cae6ee..60fa4bd66e678c4fa9e1092401c05437b8cc219a 100644 (file)
@@ -15,6 +15,7 @@ typedef enum {
        aid_qf_dirname_start,
        aid_qf_dirname_now,
        aid_qf_namebuf,
+       aid_qf_module,
        aid_qf_errmsg,
        aid_qf_pattern,
        aid_last
index dde68419a2fba5d5f02c1545738ffeaa99fafbdc..385438b55fd34611ac5b647d4e7b604c4a65a732 100644 (file)
@@ -33,6 +33,7 @@ struct qfline_S
     int                qf_fnum;        /* file number for the line */
     int                qf_col;         /* column where the error occurred */
     int                qf_nr;          /* error number */
+    char_u     *qf_module;     /* module name for this error */
     char_u     *qf_pattern;    /* search pattern for the error */
     char_u     *qf_text;       /* description of the error */
     char_u     qf_viscol;      /* set to TRUE if qf_col is screen column */
@@ -101,7 +102,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 10                /* maximum number of % recognized */
+#define FMT_PATTERNS 11                /* maximum number of % recognized */
 
 /*
  * Structure used to hold the info of one part of 'errorformat'
@@ -135,7 +136,8 @@ static efm_T        *fmt_start = NULL; /* cached across qf_parse_line() calls */
 
 static int     qf_init_ext(qf_info_T *qi, int qf_idx, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title, char_u *enc);
 static void    qf_new_list(qf_info_T *qi, char_u *qf_title);
-static int     qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid);
+static int     qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname, char_u *module, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid);
+static qf_info_T *ll_new_list(void);
 static void    qf_free(qf_info_T *qi, int idx);
 static char_u  *qf_types(int, int);
 static int     qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *);
@@ -221,7 +223,8 @@ static struct fmtpattern
                    {'r', ".*"},
                    {'p', "[-   .]*"},
                    {'v', "\\d\\+"},
-                   {'s', ".\\+"}
+                   {'s', ".\\+"},
+                   {'o', ".\\+"}
                };
 
 /*
@@ -809,6 +812,7 @@ qf_get_nextline(qfstate_T *state)
 
 typedef struct {
     char_u     *namebuf;
+    char_u     *module;
     char_u     *errmsg;
     int                errmsglen;
     long       lnum;
@@ -868,6 +872,7 @@ restofline:
        if (qfl->qf_multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL)
            continue;
        fields->namebuf[0] = NUL;
+       fields->module[0] = NUL;
        fields->pattern[0] = NUL;
        if (!qfl->qf_multiscan)
            fields->errmsg[0] = NUL;
@@ -1008,6 +1013,15 @@ restofline:
                fields->pattern[len + 4] = '$';
                fields->pattern[len + 5] = NUL;
            }
+           if ((i = (int)fmt_ptr->addr[10]) > 0)               /* %o */
+           {
+               if (regmatch.startp[i] == NULL)
+                   continue;
+               len = (int)(regmatch.endp[i] - regmatch.startp[i]);
+               if (len > CMDBUFFSIZE)
+                   len = CMDBUFFSIZE;
+               STRNCAT(fields->module, regmatch.startp[i], len);
+           }
            break;
        }
     }
@@ -1181,11 +1195,12 @@ qf_init_ext(
        convert_setup(&state.vc, enc, p_enc);
 #endif
     fields.namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf);
+    fields.module = alloc_id(CMDBUFFSIZE + 1, aid_qf_module);
     fields.errmsglen = CMDBUFFSIZE + 1;
     fields.errmsg = alloc_id(fields.errmsglen, aid_qf_errmsg);
     fields.pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern);
     if (fields.namebuf == NULL || fields.errmsg == NULL
-               || fields.pattern == NULL)
+               || fields.pattern == NULL || fields.module == NULL)
        goto qf_init_end;
 
     if (efile != NULL && (state.fd = mch_fopen((char *)efile, "r")) == NULL)
@@ -1282,6 +1297,7 @@ qf_init_ext(
                            ? fields.namebuf
                            : ((qfl->qf_currfile != NULL && fields.valid)
                                ? qfl->qf_currfile : (char_u *)NULL),
+                       fields.module,
                        0,
                        fields.errmsg,
                        fields.lnum,
@@ -1327,6 +1343,7 @@ qf_init_end:
     if (state.fd != NULL)
        fclose(state.fd);
     vim_free(fields.namebuf);
+    vim_free(fields.module);
     vim_free(fields.errmsg);
     vim_free(fields.pattern);
     vim_free(state.growbuf);
@@ -1444,6 +1461,7 @@ qf_add_entry(
     int                qf_idx,         /* list index */
     char_u     *dir,           /* optional directory name */
     char_u     *fname,         /* file name or NULL */
+    char_u     *module,        /* module name or NULL */
     int                bufnum,         /* buffer number or zero */
     char_u     *mesg,          /* message */
     long       lnum,           /* line number */
@@ -1486,6 +1504,15 @@ qf_add_entry(
        vim_free(qfp);
        return FAIL;
     }
+    if (module == NULL || *module == NUL)
+       qfp->qf_module = NULL;
+    else if ((qfp->qf_module = vim_strsave(module)) == NULL)
+    {
+       vim_free(qfp->qf_text);
+       vim_free(qfp->qf_pattern);
+       vim_free(qfp);
+       return FAIL;
+    }
     qfp->qf_nr = nr;
     if (type != 1 && !vim_isprintc(type)) /* only printable chars allowed */
        type = 0;
@@ -1635,6 +1662,7 @@ copy_loclist(win_T *from, win_T *to)
                                 to->w_llist->qf_curlist,
                                 NULL,
                                 NULL,
+                                from_qfp->qf_module,
                                 0,
                                 from_qfp->qf_text,
                                 from_qfp->qf_lnum,
@@ -2765,18 +2793,22 @@ qf_list(exarg_T *eap)
                break;
 
            fname = NULL;
-           if (qfp->qf_fnum != 0
-                             && (buf = buflist_findnr(qfp->qf_fnum)) != NULL)
-           {
-               fname = buf->b_fname;
-               if (qfp->qf_type == 1)  /* :helpgrep */
-                   fname = gettail(fname);
+           if (qfp->qf_module != NULL && *qfp->qf_module != NUL)
+               vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", i, (char *)qfp->qf_module);
+           else {
+               if (qfp->qf_fnum != 0
+                               && (buf = buflist_findnr(qfp->qf_fnum)) != NULL)
+               {
+                   fname = buf->b_fname;
+                   if (qfp->qf_type == 1)      /* :helpgrep */
+                       fname = gettail(fname);
+               }
+               if (fname == NULL)
+                   sprintf((char *)IObuff, "%2d", i);
+               else
+                   vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
+                                                               i, (char *)fname);
            }
-           if (fname == NULL)
-               sprintf((char *)IObuff, "%2d", i);
-           else
-               vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
-                                                           i, (char *)fname);
            msg_outtrans_attr(IObuff, i == qi->qf_lists[qi->qf_curlist].qf_index
                                           ? HL_ATTR(HLF_QFL) : qfFileAttr);
 
@@ -2957,9 +2989,10 @@ qf_free_items(qf_info_T *qi, int idx)
        qfpnext = qfp->qf_next;
        if (!stop)
        {
+           vim_free(qfp->qf_module);
            vim_free(qfp->qf_text);
-           stop = (qfp == qfpnext);
            vim_free(qfp->qf_pattern);
+           stop = (qfp == qfpnext);
            vim_free(qfp);
            if (stop)
                /* Somehow qf_count may have an incorrect value, set it to 1
@@ -3562,7 +3595,12 @@ qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last)
        }
        while (lnum < qi->qf_lists[qi->qf_curlist].qf_count)
        {
-           if (qfp->qf_fnum != 0
+           if (qfp->qf_module != NULL)
+           {
+               STRCPY(IObuff, qfp->qf_module);
+               len = (int)STRLEN(IObuff);
+           }
+           else if (qfp->qf_fnum != 0
                    && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL
                    && errbuf->b_fname != NULL)
            {
@@ -4367,6 +4405,7 @@ vgr_match_buflines(
                        qi->qf_curlist,
                        NULL,       /* dir */
                        fname,
+                       NULL,
                        duplicate_name ? 0 : buf->b_fnum,
                        ml_get_buf(buf,
                            regmatch->startpos[0].lnum + lnum, FALSE),
@@ -4934,6 +4973,8 @@ get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list)
          || dict_add_nr_str(dict, "col",   (long)qfp->qf_col, NULL) == FAIL
          || dict_add_nr_str(dict, "vcol",  (long)qfp->qf_viscol, NULL) == FAIL
          || dict_add_nr_str(dict, "nr",    (long)qfp->qf_nr, NULL) == FAIL
+         || dict_add_nr_str(dict, "module",  0L,
+                  qfp->qf_module == NULL ? (char_u *)"" : qfp->qf_module) == FAIL
          || dict_add_nr_str(dict, "pattern",  0L,
             qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL
          || dict_add_nr_str(dict, "text",  0L,
@@ -5312,7 +5353,7 @@ qf_add_entries(
 {
     listitem_T *li;
     dict_T     *d;
-    char_u     *filename, *pattern, *text, *type;
+    char_u     *filename, *module, *pattern, *text, *type;
     int                bufnum;
     long       lnum;
     int                col, nr;
@@ -5347,6 +5388,7 @@ qf_add_entries(
            continue;
 
        filename = get_dict_string(d, (char_u *)"filename", TRUE);
+       module = get_dict_string(d, (char_u *)"module", TRUE);
        bufnum = (int)get_dict_number(d, (char_u *)"bufnr");
        lnum = (int)get_dict_number(d, (char_u *)"lnum");
        col = (int)get_dict_number(d, (char_u *)"col");
@@ -5383,6 +5425,7 @@ qf_add_entries(
                               qf_idx,
                               NULL,        /* dir */
                               filename,
+                              module,
                               bufnum,
                               text,
                               lnum,
@@ -5394,6 +5437,7 @@ qf_add_entries(
                               valid);
 
        vim_free(filename);
+       vim_free(module);
        vim_free(pattern);
        vim_free(text);
        vim_free(type);
@@ -6040,6 +6084,7 @@ hgr_search_file(
                        qi->qf_curlist,
                        NULL,   /* dir */
                        fname,
+                       NULL,
                        0,
                        line,
                        lnum,
@@ -6104,7 +6149,7 @@ hgr_search_files_in_dir(
            /* Skip files for a different language. */
            if (lang != NULL
                    && STRNICMP(lang, fnames[fi]
-                       + STRLEN(fnames[fi]) - 3, 2) != 0
+                                   + STRLEN(fnames[fi]) - 3, 2) != 0
                    && !(STRNICMP(lang, "en", 2) == 0
                        && STRNICMP("txt", fnames[fi]
                            + STRLEN(fnames[fi]) - 3, 3) == 0))
index 1e781de11efb87709538d03447dfd682fc3705e5..559958b7e10efa05315af5b3db2775f3e22ebcad 100644 (file)
@@ -138,6 +138,16 @@ func XlistTests(cchar)
              \ ' 4:40 col 20 x  44: Other',
              \ ' 5:50 col 25  55: one'], l)
 
+  " Test for module names, one needs to explicitly set `'valid':v:true` so
+  call g:Xsetlist([
+       \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
+       \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
+       \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
+  let l = split(execute('Xlist', ""), "\n")
+  call assert_equal([' 1 Data.Text:10 col 5 warning  11: ModuleWarning',
+       \ ' 2 Data.Text:20 col 10 warning  22: ModuleWarning',
+       \ ' 3 Data/Text.hs:30 col 15 warning  33: FileWarning'], l)
+
   " Error cases
   call assert_fails('Xlist abc', 'E488:')
 endfunc
@@ -1142,6 +1152,21 @@ func Test_efm2()
   call assert_equal(1, l[4].valid)
   call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
 
+  " Test for %o
+  set efm=%f(%o):%l\ %m
+  cgetexpr ['Xtestfile(Language.PureScript.Types):20 Error']
+  call writefile(['Line1'], 'Xtestfile')
+  let l = getqflist()
+  call assert_equal(1, len(l), string(l))
+  call assert_equal('Language.PureScript.Types', l[0].module)
+  copen
+  call assert_equal('Language.PureScript.Types|20| Error', getline(1))
+  call feedkeys("\<CR>", 'xn')
+  call assert_equal('Xtestfile', expand('%:t'))
+  cclose
+  bd
+  call delete("Xtestfile")
+
   " The following sequence of commands used to crash Vim
   set efm=%W%m
   cgetexpr ['msg1']
index ae231be515be4362dd03649a9d9417df97eb2733..a02360ff7a6928916ef7607a74f4b46222b3517d 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1782,
 /**/
     1781,
 /**/