changeset 11502:46bbef0ee9a6 v8.0.0634

patch 8.0.0634: cannot easily get to the last quickfix list commit https://github.com/vim/vim/commit/875feea6ce223462d55543735143d747dcaf4287 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jun 11 16:07:51 2017 +0200 patch 8.0.0634: cannot easily get to the last quickfix list Problem: Cannot easily get to the last quickfix list. Solution: Add "$" as a value for the "nr" argument of getqflist() and setqflist(). (Yegappan Lakshmanan)
author Christian Brabandt <cb@256bit.org>
date Sun, 11 Jun 2017 16:15:04 +0200
parents 2ac2ec9f4160
children ce206a9d1faa
files runtime/doc/eval.txt src/quickfix.c src/testdir/test_quickfix.vim src/version.c
diffstat 4 files changed, 97 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*	For Vim version 8.0.  Last change: 2017 Jun 04
+*eval.txt*	For Vim version 8.0.  Last change: 2017 Jun 05
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -4587,12 +4587,16 @@ getqflist([{what}])					*getqflist()*
 		following string items are supported in {what}:
 			context	get the context stored with |setqflist()|
 			nr	get information for this quickfix list; zero
-				means the current quickfix list
+				means the current quickfix list and '$' means
+				the last quickfix list
 			title	get the list title
 			winid	get the |window-ID| (if opened)
 			all	all of the above quickfix properties
 		Non-string items in {what} are ignored.
 		If "nr" is not present then the current quickfix list is used.
+		To get the number of lists in the quickfix stack, set 'nr' to
+		'$' in {what}. The 'nr' value in the returned dictionary
+		contains the quickfix stack size.
 		In case of error processing {what}, an empty dictionary is
 		returned.
 
@@ -6991,7 +6995,9 @@ setqflist({list} [, {action}[, {what}]])
 		argument is ignored.  The following items can be specified in
 		{what}:
 		    context	any Vim type can be stored as a context
-		    nr		list number in the quickfix stack
+		    nr		list number in the quickfix stack; zero
+				means the current quickfix list and '$' means
+				the last quickfix list
 		    title	quickfix list title text
 		Unsupported keys in {what} are ignored.
 		If the "nr" item is not present, then the current quickfix list
@@ -7095,18 +7101,22 @@ shellescape({string} [, {special}])			*s
 		quotes within {string}.
 		Otherwise it will enclose {string} in single quotes and
 		replace all "'" with "'\''".
+
 		When the {special} argument is present and it's a non-zero
 		Number or a non-empty String (|non-zero-arg|), then special
 		items such as "!", "%", "#" and "<cword>" will be preceded by
 		a backslash.  This backslash will be removed again by the |:!|
 		command.
+
 		The "!" character will be escaped (again with a |non-zero-arg|
 		{special}) when 'shell' contains "csh" in the tail.  That is
 		because for csh and tcsh "!" is used for history replacement
 		even when inside single quotes.
-		The <NL> character is also escaped.  With a |non-zero-arg|
-		{special} and 'shell' containing "csh" in the tail it's
+
+		With a |non-zero-arg| {special} the <NL> character is also
+		escaped.  When 'shell' containing "csh" in the tail it's
 		escaped a second time.
+
 		Example of use with a |:!| command: >
 		    :exe '!dir ' . shellescape(expand('<cfile>'), 1)
 <		This results in a directory listing for the file under the
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -4670,7 +4670,14 @@ get_errorlist_properties(win_T *wp, dict
     {
 	qi = GET_LOC_LIST(wp);
 	if (qi == NULL)
+	{
+	    /* If querying for the size of the location list, return 0 */
+	    if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL) &&
+		    (di->di_tv.v_type == VAR_STRING) &&
+		    (STRCMP(di->di_tv.vval.v_string, "$") == 0))
+		    return dict_add_nr_str(retdict, "nr", 0, NULL);
 	    return FAIL;
+	}
     }
 
     qf_idx = qi->qf_curlist;		/* default is the current list */
@@ -4685,6 +4692,18 @@ get_errorlist_properties(win_T *wp, dict
 		qf_idx = di->di_tv.vval.v_number - 1;
 		if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
 		    return FAIL;
+	    } else if (qi->qf_listcount == 0)	    /* stack is empty */
+		return FAIL;
+	    flags |= QF_GETLIST_NR;
+	} 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 */
 	    }
 	    flags |= QF_GETLIST_NR;
 	}
@@ -4692,17 +4711,20 @@ get_errorlist_properties(win_T *wp, dict
 	    return FAIL;
     }
 
-    if (dict_find(what, (char_u *)"all", -1) != NULL)
-	flags |= QF_GETLIST_ALL;
-
-    if (dict_find(what, (char_u *)"title", -1) != NULL)
-	flags |= QF_GETLIST_TITLE;
-
-    if (dict_find(what, (char_u *)"winid", -1) != NULL)
-	flags |= QF_GETLIST_WINID;
-
-    if (dict_find(what, (char_u *)"context", -1) != NULL)
-	flags |= QF_GETLIST_CONTEXT;
+    if (qf_idx != -1)
+    {
+	if (dict_find(what, (char_u *)"all", -1) != NULL)
+	    flags |= QF_GETLIST_ALL;
+
+	if (dict_find(what, (char_u *)"title", -1) != NULL)
+	    flags |= QF_GETLIST_TITLE;
+
+	if (dict_find(what, (char_u *)"winid", -1) != NULL)
+	    flags |= QF_GETLIST_WINID;
+
+	if (dict_find(what, (char_u *)"context", -1) != NULL)
+	    flags |= QF_GETLIST_CONTEXT;
+    }
 
     if (flags & QF_GETLIST_TITLE)
     {
@@ -4895,7 +4917,10 @@ qf_set_properties(qf_info_T *qi, dict_T 
 		qf_idx = di->di_tv.vval.v_number - 1;
 	    if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
 		return FAIL;
-	}
+	} 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;
 	else
 	    return FAIL;
 	newlist = FALSE;	/* use the specified list */
@@ -4923,6 +4948,7 @@ qf_set_properties(qf_info_T *qi, dict_T 
     if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
     {
 	typval_T	*ctx;
+
 	free_tv(qi->qf_lists[qf_idx].qf_ctx);
 	ctx =  alloc_tv();
 	if (ctx != NULL)
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -1650,12 +1650,12 @@ func XbottomTests(cchar)
       call assert_fails('lbottom', 'E776:')
   endif
 
-  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) 
+  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
   Xopen
   let wid = win_getid()
   call assert_equal(1, line('.'))
   wincmd w
-  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a') 
+  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
   Xbottom
   call win_gotoid(wid)
   call assert_equal(2, line('.'))
@@ -2120,3 +2120,43 @@ func Test_bufoverflow()
   set efm&vim
 endfunc
 
+func Test_cclose_from_copen()
+    augroup QF_Test
+	au!
+	au FileType qf :cclose
+    augroup END
+    copen
+    augroup QF_Test
+	au!
+    augroup END
+    augroup! QF_Test
+endfunc
+
+" Tests for getting the quickfix stack size
+func XsizeTests(cchar)
+  call s:setup_commands(a:cchar)
+
+  call g:Xsetlist([], 'f')
+  call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
+  call assert_equal(1, len(g:Xgetlist({'nr':'$', 'all':1})))
+  call assert_equal(0, len(g:Xgetlist({'nr':0})))
+
+  Xexpr "File1:10:Line1"
+  Xexpr "File2:20:Line2"
+  Xexpr "File3:30:Line3"
+  Xolder | Xolder
+  call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
+  call g:Xsetlist([], 'f')
+
+  Xexpr "File1:10:Line1"
+  Xexpr "File2:20:Line2"
+  Xexpr "File3:30:Line3"
+  Xolder | Xolder
+  call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
+  call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
+endfunc
+
+func Test_Qf_Size()
+  call XsizeTests('c')
+  call XsizeTests('l')
+endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    634,
+/**/
     633,
 /**/
     632,