summaryrefslogtreecommitdiff
path: root/src/quickfix.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-06-22 21:33:20 +0200
committerBram Moolenaar <Bram@vim.org>2017-06-22 21:33:20 +0200
commit6a8958db259d4444da6e6956e54a6513c1af8860 (patch)
treed4d9541e7aa99dca7aa933c4dfca980bb142792e /src/quickfix.c
parent6f9a476b2f2f0bb5c50d703ec4fc535ffd5bfe8f (diff)
downloadvim-git-6a8958db259d4444da6e6956e54a6513c1af8860.tar.gz
patch 8.0.0657: cannot get and set quickfix list itemsv8.0.0657
Problem: Cannot get and set quickfix list items. Solution: Add the "items" argument to getqflist() and setqflist(). (Yegappan Lakshmanan)
Diffstat (limited to 'src/quickfix.c')
-rw-r--r--src/quickfix.c98
1 files changed, 80 insertions, 18 deletions
diff --git a/src/quickfix.c b/src/quickfix.c
index f4bc5974e..40b6fe93d 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -47,19 +47,32 @@ struct qfline_S
*/
#define LISTCOUNT 10
+/*
+ * Quickfix/Location list definition
+ * Contains a list of entries (qfline_T). qf_start points to the first entry
+ * and qf_last points to the last entry. qf_count contains the list size.
+ *
+ * Usually the list contains one or more entries. But an empty list can be
+ * created using setqflist()/setloclist() with a title and/or user context
+ * information and entries can be added later using setqflist()/setloclist().
+ */
typedef struct qf_list_S
{
qfline_T *qf_start; /* pointer to the first error */
qfline_T *qf_last; /* pointer to the last error */
qfline_T *qf_ptr; /* pointer to the current error */
- int qf_count; /* number of errors (0 means no error list) */
+ int qf_count; /* number of errors (0 means empty list) */
int qf_index; /* current index in the error list */
int qf_nonevalid; /* TRUE if not a single valid entry found */
char_u *qf_title; /* title derived from the command that created
- * the error list */
+ * the error list or set by setqflist */
typval_T *qf_ctx; /* context set by setqflist/setloclist */
} qf_list_T;
+/*
+ * Quickfix/Location list stack definition
+ * Contains a list of quickfix/location lists (qf_list_T)
+ */
struct qf_info_S
{
/*
@@ -1347,6 +1360,9 @@ qf_init_end:
static void
qf_store_title(qf_info_T *qi, int qf_idx, char_u *title)
{
+ vim_free(qi->qf_lists[qf_idx].qf_title);
+ qi->qf_lists[qf_idx].qf_title = NULL;
+
if (title != NULL)
{
char_u *p = alloc((int)STRLEN(title) + 2);
@@ -2735,10 +2751,11 @@ qf_history(exarg_T *eap)
}
/*
- * Free all the entries in the error list "idx".
+ * Free all the entries in the error list "idx". Note that other information
+ * associated with the list like context and title are not freed.
*/
static void
-qf_free(qf_info_T *qi, int idx)
+qf_free_items(qf_info_T *qi, int idx)
{
qfline_T *qfp;
qfline_T *qfpnext;
@@ -2763,10 +2780,7 @@ qf_free(qf_info_T *qi, int idx)
qi->qf_lists[idx].qf_start = qfpnext;
--qi->qf_lists[idx].qf_count;
}
- vim_free(qi->qf_lists[idx].qf_title);
- qi->qf_lists[idx].qf_title = NULL;
- free_tv(qi->qf_lists[idx].qf_ctx);
- qi->qf_lists[idx].qf_ctx = NULL;
+
qi->qf_lists[idx].qf_index = 0;
qi->qf_lists[idx].qf_start = NULL;
qi->qf_lists[idx].qf_last = NULL;
@@ -2783,6 +2797,21 @@ qf_free(qf_info_T *qi, int idx)
}
/*
+ * Free error list "idx". Frees all the entries in the quickfix list,
+ * associated context information and the title.
+ */
+ static void
+qf_free(qf_info_T *qi, int idx)
+{
+ qf_free_items(qi, idx);
+
+ vim_free(qi->qf_lists[idx].qf_title);
+ qi->qf_lists[idx].qf_title = NULL;
+ free_tv(qi->qf_lists[idx].qf_ctx);
+ qi->qf_lists[idx].qf_ctx = NULL;
+}
+
+/*
* qf_mark_adjust: adjust marks
*/
void
@@ -4698,13 +4727,11 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
} else if ((di->di_tv.v_type == VAR_STRING) &&
(STRCMP(di->di_tv.vval.v_string, "$") == 0))
{
- {
- /* Get the last quickfix list number */
- if (qi->qf_listcount > 0)
- qf_idx = qi->qf_listcount - 1;
- else
- qf_idx = -1; /* Quickfix stack is empty */
- }
+ /* Get the last quickfix list number */
+ if (qi->qf_listcount > 0)
+ qf_idx = qi->qf_listcount - 1;
+ else
+ qf_idx = -1; /* Quickfix stack is empty */
flags |= QF_GETLIST_NR;
}
else
@@ -4724,6 +4751,9 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (dict_find(what, (char_u *)"context", -1) != NULL)
flags |= QF_GETLIST_CONTEXT;
+
+ if (dict_find(what, (char_u *)"items", -1) != NULL)
+ flags |= QF_GETLIST_ITEMS;
}
if (flags & QF_GETLIST_TITLE)
@@ -4743,6 +4773,15 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (win != NULL)
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
}
+ if ((status == OK) && (flags & QF_GETLIST_ITEMS))
+ {
+ list_T *l = list_alloc();
+ if (l != NULL)
+ {
+ (void)get_errorlist(wp, qf_idx, l);
+ dict_add_list(retdict, "items", l);
+ }
+ }
if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
{
@@ -4802,7 +4841,7 @@ qf_add_entries(
#endif
else if (action == 'r')
{
- qf_free(qi, qf_idx);
+ qf_free_items(qi, qf_idx);
qf_store_title(qi, qf_idx, title);
}
@@ -4915,15 +4954,27 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action)
/* for zero use the current list */
if (di->di_tv.vval.v_number != 0)
qf_idx = di->di_tv.vval.v_number - 1;
- if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
+
+ if ((action == ' ' || action == 'a') &&
+ qf_idx == qi->qf_listcount)
+ /*
+ * When creating a new list, accept qf_idx pointing to the next
+ * non-available list
+ */
+ newlist = TRUE;
+ else if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
return FAIL;
+ else
+ newlist = FALSE; /* use the specified list */
} else if (di->di_tv.v_type == VAR_STRING &&
STRCMP(di->di_tv.vval.v_string, "$") == 0 &&
qi->qf_listcount > 0)
+ {
qf_idx = qi->qf_listcount - 1;
+ newlist = FALSE;
+ }
else
return FAIL;
- newlist = FALSE; /* use the specified list */
}
if (newlist)
@@ -4944,6 +4995,17 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action)
retval = OK;
}
}
+ if ((di = dict_find(what, (char_u *)"items", -1)) != NULL)
+ {
+ if (di->di_tv.v_type == VAR_LIST)
+ {
+ char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title);
+
+ retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list,
+ title_save, action == ' ' ? 'a' : action);
+ vim_free(title_save);
+ }
+ }
if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
{