Hi all,
I am attaching a patch to get and set the quickfix list items using the
getqflist() and setqflist() functions. After this patch, it will be easier
to save and restore any quickfix list in the quickfix stack.
This will also make it consistent to get or set any attributes (title,
context, items) of the quickfix list using the getqflist() and setqflist()
functions.
- Yegappan
--
--
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].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 701fd3985..0ddde0bd1 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4586,6 +4586,7 @@ getqflist([{what}])
*getqflist()*
returns only the items listed in {what} as a dictionary. The
following string items are supported in {what}:
context get the context stored with |setqflist()|
+ items quickfix list entries
nr get information for this quickfix list; zero
means the current quickfix list and '$' means
the last quickfix list
@@ -4602,6 +4603,7 @@ getqflist([{what}])
*getqflist()*
The returned dictionary contains the following entries:
context context information stored with |setqflist()|
+ items quickfix list entries
nr quickfix list number
title quickfix list title text
winid quickfix |window-ID| (if opened)
@@ -6995,6 +6997,8 @@ setqflist({list} [, {action}[, {what}]])
*setqflist()*
argument is ignored. The following items can be specified in
{what}:
context any Vim type can be stored as a context
+ items list of quickfix entries. Same as the {list}
+ argument.
nr list number in the quickfix stack; zero
means the current quickfix list and '$' means
the last quickfix list
diff --git a/src/quickfix.c b/src/quickfix.c
index 8b61e10bc..f4d6cfb9c 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1347,6 +1347,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);
@@ -2738,7 +2741,7 @@ qf_history(exarg_T *eap)
* Free all the entries in the error list "idx".
*/
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 +2766,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 +2783,20 @@ qf_free(qf_info_T *qi, int idx)
}
/*
+ * Free error list "idx".
+ */
+ 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 +4712,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 +4736,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 +4758,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 +4826,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 +4939,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 +4980,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)
{
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 16187be76..c23e597e3 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -1835,6 +1835,73 @@ func Xproperty_tests(cchar)
call test_garbagecollect_now()
let m = g:Xgetlist({'context' : 1})
call assert_equal(["red", "blue", "green"], m.context)
+
+ " Test for setting/getting items
+ Xexpr ""
+ let qfprev = g:Xgetlist({'nr':0})
+ call g:Xsetlist([], ' ', {'title':'Green',
+ \ 'items' : [{'filename':'F1', 'lnum':10}]})
+ let qfcur = g:Xgetlist({'nr':0})
+ call assert_true(qfcur.nr == qfprev.nr + 1)
+ let l = g:Xgetlist({'items':1})
+ call assert_equal('F1', bufname(l.items[0].bufnr))
+ call assert_equal(10, l.items[0].lnum)
+ call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
+ \ {'filename':'F2', 'lnum':30}]})
+ let l = g:Xgetlist({'items':1})
+ call assert_equal('F2', bufname(l.items[2].bufnr))
+ call assert_equal(30, l.items[2].lnum)
+ call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
+ let l = g:Xgetlist({'items':1})
+ call assert_equal('F3', bufname(l.items[0].bufnr))
+ call assert_equal(40, l.items[0].lnum)
+ call g:Xsetlist([], 'r', {'items' : []})
+ let l = g:Xgetlist({'items':1})
+ call assert_equal(0, len(l.items))
+
+ " Save and restore the quickfix stack
+ call g:Xsetlist([], 'f')
+ call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
+ Xexpr "File1:10:Line1"
+ Xexpr "File2:20:Line2"
+ Xexpr "File3:30:Line3"
+ let last_qf = g:Xgetlist({'nr':'$'}).nr
+ call assert_equal(3, last_qf)
+ let qstack = []
+ for i in range(1, last_qf)
+ let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
+ endfor
+ call g:Xsetlist([], 'f')
+ for i in range(len(qstack))
+ call g:Xsetlist([], ' ', qstack[i])
+ endfor
+ call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
+ call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
+ call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
+ call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
+ call g:Xsetlist([], 'f')
+
+ " Swap two quickfix lists
+ Xexpr "File1:10:Line10"
+ Xexpr "File2:20:Line20"
+ Xexpr "File3:30:Line30"
+ call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
+ call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
+ let l1=g:Xgetlist({'nr':1,'all':1})
+ let l2=g:Xgetlist({'nr':2,'all':1})
+ let l1.nr=2
+ let l2.nr=1
+ call g:Xsetlist([], 'r', l1)
+ call g:Xsetlist([], 'r', l2)
+ let newl1=g:Xgetlist({'nr':1,'all':1})
+ let newl2=g:Xgetlist({'nr':2,'all':1})
+ call assert_equal(':Fruits', newl1.title)
+ call assert_equal(['Fruits'], newl1.context)
+ call assert_equal('Line20', newl1.items[0].text)
+ call assert_equal(':Colors', newl2.title)
+ call assert_equal(['Colors'], newl2.context)
+ call assert_equal('Line10', newl2.items[0].text)
+ call g:Xsetlist([], 'f')
endfunc
func Test_qf_property()