updated for version 7.0187
diff --git a/src/Makefile b/src/Makefile
index da6137c..2da7860 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1699,10 +1699,10 @@
 #
 test check:
 	$(MAKE) -f Makefile $(VIMTARGET)
-	cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) $(GUI_TESTARG)
-	@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
+	-@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
 		cd $(PODIR); $(MAKE) -f Makefile check VIM=../$(VIMTARGET); \
 	fi
+	cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) $(GUI_TESTARG)
 
 testclean:
 	cd testdir; $(MAKE) -f Makefile clean
diff --git a/src/edit.c b/src/edit.c
index 8dc07fd..e331c4c 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -89,7 +89,7 @@
 
 /* When the first completion is done "compl_started" is set.  When it's
  * FALSE the word to be completed must be located. */
-static int		    compl_started = FALSE;
+static int	  compl_started = FALSE;
 
 static int	  compl_matches = 0;
 static char_u	  *compl_pattern = NULL;
@@ -123,6 +123,7 @@
 static void ins_compl_insert __ARGS((void));
 static int  ins_compl_next __ARGS((int allow_get_expansion, int count));
 static int  ins_compl_key2dir __ARGS((int c));
+static int  ins_compl_pum_key __ARGS((int c));
 static int  ins_compl_key2count __ARGS((int c));
 static int  ins_complete __ARGS((int c));
 static int  quote_meta __ARGS((char_u *dest, char_u *str, int len));
@@ -495,7 +496,7 @@
      * actually changing anything.  It's put after the mode, if any.
      */
     i = 0;
-    if (p_smd)
+    if (p_smd && msg_silent == 0)
 	i = showmode();
 
     if (!p_im && did_restart_edit == 0)
@@ -1116,7 +1117,10 @@
 	     * cursor. */
 	    if (bt_quickfix(curbuf) && c == CAR)
 	    {
-		do_cmdline_cmd((char_u *)".cc");
+		if (curwin->w_llist_ref == NULL)    /* quickfix window */
+		    do_cmdline_cmd((char_u *)".cc");
+		else				    /* location list window */
+		    do_cmdline_cmd((char_u *)".ll");
 		break;
 	    }
 #endif
@@ -1846,8 +1850,7 @@
 	return TRUE;
 
     /* Accept <PageUp> and <PageDown> if the popup menu is visible. */
-    if (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
-		     || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN))
+    if (ins_compl_pum_key(c))
 	return TRUE;
 
     switch (ctrl_x_mode)
@@ -2648,7 +2651,8 @@
 	 * 'Pattern not found') until another key is hit, then go back to
 	 * showing what mode we are in. */
 	showmode();
-	if ((ctrl_x_mode == 0 && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R)
+	if ((ctrl_x_mode == 0 && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R
+						     && !ins_compl_pum_key(c))
 		|| ctrl_x_mode == CTRL_X_FINISHED)
 	{
 	    /* Get here when we have finished typing a sequence of ^N and
@@ -3452,6 +3456,18 @@
 }
 
 /*
+ * Return TRUE for keys that are used for completion only when the popup menu
+ * is visible.
+ */
+    static int
+ins_compl_pum_key(c)
+    int		c;
+{
+    return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
+		     || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN);
+}
+
+/*
  * Decide the number of completions to move forward.
  * Returns 1 for most keys, height of the popup menu for page-up/down keys.
  */
@@ -3461,8 +3477,7 @@
 {
     int		h;
 
-    if (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
-	    || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN))
+    if (ins_compl_pum_key(c))
     {
 	h = pum_get_height();
 	if (h > 3)
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index a15ed46..8211a7f 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -473,26 +473,58 @@
 			NEEDARG|EXTRA|NOTRLCOM),
 EX(CMD_list,		"list",		ex_print,
 			RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+EX(CMD_lNext,		"lNext",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lNfile,		"lNfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
 EX(CMD_last,		"last",		ex_last,
 			EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
 EX(CMD_language,	"language",	ex_language,
 			EXTRA|TRLBAR|CMDWIN),
+EX(CMD_laddexpr,	"laddexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_laddfile,	"laddfile",	ex_cfile,
+			TRLBAR|FILE1),
+EX(CMD_lbuffer,		"lbuffer",	ex_cbuffer,
+			RANGE|NOTADR|WORD1|TRLBAR),
 EX(CMD_lcd,		"lcd",		ex_cd,
 			BANG|FILE1|TRLBAR|CMDWIN),
 EX(CMD_lchdir,		"lchdir",	ex_cd,
 			BANG|FILE1|TRLBAR|CMDWIN),
+EX(CMD_lclose,		"lclose",	ex_cclose,
+			RANGE|NOTADR|COUNT|TRLBAR),
 EX(CMD_left,		"left",		ex_align,
 			TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
 EX(CMD_leftabove,	"leftabove",	ex_wrongmodifier,
 			NEEDARG|EXTRA|NOTRLCOM),
 EX(CMD_let,		"let",		ex_let,
 			EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+EX(CMD_lexpr,		"lexpr",	ex_cexpr,
+			NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+EX(CMD_lfile,		"lfile",	ex_cfile,
+			TRLBAR|FILE1|BANG),
+EX(CMD_lfirst,		"lfirst",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lgetfile,	"lgetfile",	ex_cfile,
+			TRLBAR|FILE1|BANG),
+EX(CMD_ll,		"ll",		ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_llast,		"llast",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_llist,		"llist",	qf_list,
+			BANG|EXTRA|TRLBAR|CMDWIN),
 EX(CMD_lmap,		"lmap",		ex_map,
 			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
 EX(CMD_lmapclear,	"lmapclear",	ex_mapclear,
 			EXTRA|TRLBAR|CMDWIN),
 EX(CMD_lnoremap,	"lnoremap",	ex_map,
 			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_lnext,		"lnext",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lnewer,		"lnewer",	qf_age,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_lnfile,		"lnfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
 EX(CMD_loadview,	"loadview",	ex_loadview,
 			FILE1|TRLBAR),
 EX(CMD_loadkeymap,	"loadkeymap",	ex_loadkeymap,
@@ -501,8 +533,20 @@
 			NEEDARG|EXTRA|NOTRLCOM),
 EX(CMD_lockvar,		"lockvar",	ex_lockvar,
 			BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+EX(CMD_lolder,		"lolder",	qf_age,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_lopen,		"lopen",	ex_copen,
+			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_lprevious,	"lprevious",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lpfile,		"lpfile",	ex_cnext,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
+EX(CMD_lrewind,		"lrewind",	ex_cc,
+			RANGE|NOTADR|COUNT|TRLBAR|BANG),
 EX(CMD_lunmap,		"lunmap",	ex_unmap,
 			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_lwindow,		"lwindow",	ex_cwindow,
+			RANGE|NOTADR|COUNT|TRLBAR),
 EX(CMD_ls,		"ls",		buflist_list,
 			BANG|TRLBAR|CMDWIN),
 EX(CMD_move,		"move",		ex_copymove,
diff --git a/src/globals.h b/src/globals.h
index 9fd9b66..82c42b2 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -83,6 +83,7 @@
 
 EXTERN int	redraw_cmdline INIT(= FALSE);	/* cmdline must be redrawn */
 EXTERN int	clear_cmdline INIT(= FALSE);	/* cmdline must be cleared */
+EXTERN int	mode_displayed INIT(= FALSE);	/* mode is being displayed */
 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
 EXTERN int	cmdline_star INIT(= FALSE);	/* cmdline is crypted */
 #endif
@@ -1366,6 +1367,7 @@
 
 #ifdef FEAT_QUICKFIX
 EXTERN char_u e_quickfix[]	INIT(= N_("E42: No Errors"));
+EXTERN char_u e_loclist[]	INIT(= N_("E776: No location list"));
 #endif
 EXTERN char_u e_re_damg[]	INIT(= N_("E43: Damaged match string"));
 EXTERN char_u e_re_corr[]	INIT(= N_("E44: Corrupted regexp program"));
diff --git a/src/if_cscope.c b/src/if_cscope.c
index 56fd12a..7a44253 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -1104,7 +1104,7 @@
 	cs_file_results(f, nummatches);
 	fclose(f);
 	/* '-' starts a new error list */
-	if (qf_init(tmp, (char_u *)"%f%*\\t%l%*\\t%m", *qfpos == '-') > 0)
+	if (qf_init(NULL, tmp, (char_u *)"%f%*\\t%l%*\\t%m", *qfpos == '-') > 0)
 	{
 # ifdef FEAT_WINDOWS
 	    if (postponed_split != 0)
@@ -1117,7 +1117,7 @@
 		postponed_split = 0;
 	    }
 # endif
-	    qf_jump(0, 0, forceit);
+	    qf_jump(NULL, 0, 0, forceit);
 	}
 	mch_remove(tmp);
 	vim_free(tmp);
diff --git a/src/main.c b/src/main.c
index 561d6ae..2661c26 100644
--- a/src/main.c
+++ b/src/main.c
@@ -636,7 +636,7 @@
 	if (params.use_ef != NULL)
 	    set_string_option_direct((char_u *)"ef", -1,
 						     params.use_ef, OPT_FREE);
-	if (qf_init(p_ef, p_efm, TRUE) < 0)
+	if (qf_init(NULL, p_ef, p_efm, TRUE) < 0)
 	{
 	    out_char('\n');
 	    mch_exit(3);
@@ -785,7 +785,7 @@
      */
     if (params.edit_type == EDIT_QF)
     {
-	qf_jump(0, 0, FALSE);
+	qf_jump(NULL, 0, 0, FALSE);
 	TIME_MSG("jump to first error");
     }
 #endif
@@ -2442,7 +2442,7 @@
 #ifdef FEAT_QUICKFIX
     /* When started with "-q errorfile" jump to first error again. */
     if (parmp->edit_type == EDIT_QF)
-	qf_jump(0, 0, FALSE);
+	qf_jump(NULL, 0, 0, FALSE);
 #endif
     TIME_MSG("executing command arguments");
 }
diff --git a/src/misc2.c b/src/misc2.c
index fb873fb..328bdf2 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -952,6 +952,7 @@
 {
     buf_T	*buf, *nextbuf;
     static int	entered = FALSE;
+    win_T	*win;
 
     /* When we cause a crash here it is caught and Vim tries to exit cleanly.
      * Don't try freeing everything again. */
@@ -1027,7 +1028,10 @@
     init_history();
 
 #ifdef FEAT_QUICKFIX
-    qf_free_all();
+    qf_free_all(NULL);
+    /* Free all location lists */
+    FOR_ALL_WINDOWS(win)
+	qf_free_all(win);
 #endif
 
     /* Close all script inputs. */
diff --git a/src/option.c b/src/option.c
index b7f1cf0..079e472 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6743,7 +6743,7 @@
 	{
 	    need_start_insertmode = FALSE;
 	    stop_insert_mode = TRUE;
-	    if (p_smd && msg_silent == 0 && restart_edit != 0)
+	    if (restart_edit != 0 && mode_displayed)
 		clear_cmdline = TRUE;	/* remove "(insert)" */
 	    restart_edit = 0;
 	}
diff --git a/src/os_unix.c b/src/os_unix.c
index afc68ff..374d85e 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4852,7 +4852,7 @@
 # define SEEK_END 2
 #endif
 
-#define SHELL_SPECIAL (char_u *)"\t \"&';<>\\|"
+#define SHELL_SPECIAL (char_u *)"\t \"&';<>()\\|"
 
 /* ARGSUSED */
     int
@@ -5128,7 +5128,12 @@
 		}
 		else if (pat[i][j] == '\\' && pat[i][j + 1] != NUL)
 		{
-		    /* Remove a backslash, take char literally. */
+		    /* Remove a backslash, take char literally.  But keep
+		     * backslash before special character and inside
+		     * backticks. */
+		    if (intick
+			  || vim_strchr(SHELL_SPECIAL, pat[i][j + 1]) != NULL)
+			*p++ = '\\';
 		    *p++ = pat[i][++j];
 		}
 		else if (!intick && vim_strchr(SHELL_SPECIAL,
@@ -5140,12 +5145,8 @@
 		    *p++ = pat[i][j];
 		}
 		else
-		{
-		    /* For a backslash also copy the next character, don't
-		     * want to put quotes around it. */
-		    if ((*p++ = pat[i][j]) == '\\' && pat[i][j + 1] != NUL)
-			*p++ = pat[i][++j];
-		}
+		    /* Simply copy the character. */
+		    *p++ = pat[i][++j];
 	    }
 	    *p = NUL;
 #endif
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
index 6712cf1..4ea4f01 100644
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -1,14 +1,14 @@
 /* quickfix.c */
-int qf_init __ARGS((char_u *efile, char_u *errorformat, int newlist));
-void qf_free_all __ARGS((void));
-void qf_jump __ARGS((int dir, int errornr, int forceit));
+int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist));
+void qf_free_all __ARGS((win_T *wp));
+void qf_jump __ARGS((win_T *wp, int dir, int errornr, int forceit));
 void qf_list __ARGS((exarg_T *eap));
 void qf_age __ARGS((exarg_T *eap));
-void qf_mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount, long amount_after));
+void qf_mark_adjust __ARGS((win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after));
 void ex_cwindow __ARGS((exarg_T *eap));
 void ex_cclose __ARGS((exarg_T *eap));
 void ex_copen __ARGS((exarg_T *eap));
-linenr_T qf_current_entry __ARGS((void));
+linenr_T qf_current_entry __ARGS((win_T *wp));
 int bt_quickfix __ARGS((buf_T *buf));
 int bt_nofile __ARGS((buf_T *buf));
 int bt_dontwrite __ARGS((buf_T *buf));
@@ -26,4 +26,5 @@
 void ex_cbuffer __ARGS((exarg_T *eap));
 void ex_cexpr __ARGS((exarg_T *eap));
 void ex_helpgrep __ARGS((exarg_T *eap));
+void copy_loclist __ARGS((win_T *from, win_T *to));
 /* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
index 2cd0bd0..923c7fd 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -49,17 +49,30 @@
  */
 #define LISTCOUNT   10
 
-static struct qf_list
+typedef struct qf_list_S
 {
     qfline_T	*qf_start;	/* pointer to the first error */
     qfline_T	*qf_ptr;	/* pointer to the current error */
     int		qf_count;	/* number of errors (0 means no error list) */
     int		qf_index;	/* current index in the error list */
     int		qf_nonevalid;	/* TRUE if not a single valid entry found */
-} qf_lists[LISTCOUNT];
+} qf_list_T;
 
-static int	qf_curlist = 0;	/* current error list */
-static int	qf_listcount = 0;   /* current number of lists */
+struct qf_info_S
+{
+    /*
+     * Count of references to this list. Used only for location lists.
+     * When a location list window reference this list, qf_refcount
+     * will be 2. Otherwise, qf_refcount will be 1. When qf_refcount
+     * reaches 0, the list is freed.
+     */
+    int		qf_refcount;
+    int		qf_listcount;	    /* current number of lists */
+    int		qf_curlist;	    /* current error list */
+    qf_list_T	qf_lists[LISTCOUNT];
+};
+
+static qf_info_T ql_info;	/* global quickfix list */
 
 #define FMT_PATTERNS 10		/* maximum number of % recognized */
 
@@ -89,11 +102,11 @@
 				/*   '+' include whole line in message */
 };
 
-static int	qf_init_ext __ARGS((char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
-static void	qf_new_list __ARGS((void));
-static int	qf_add_entry __ARGS((qfline_T **prevp, char_u *dir, char_u *fname, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
-static void	qf_msg __ARGS((void));
-static void	qf_free __ARGS((int idx));
+static int	qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
+static void	qf_new_list __ARGS((qf_info_T *qi));
+static int	qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
+static void	qf_msg __ARGS((qf_info_T *qi));
+static void	qf_free __ARGS((qf_info_T *qi, int idx));
 static char_u	*qf_types __ARGS((int, int));
 static int	qf_get_fnum __ARGS((char_u *, char_u *));
 static char_u	*qf_push_dir __ARGS((char_u *, struct dir_stack_T **));
@@ -102,30 +115,48 @@
 static void	qf_fmt_text __ARGS((char_u *text, char_u *buf, int bufsize));
 static void	qf_clean_dir_stack __ARGS((struct dir_stack_T **));
 #ifdef FEAT_WINDOWS
-static int	qf_win_pos_update __ARGS((int old_qf_index));
-static buf_T	*qf_find_buf __ARGS((void));
-static void	qf_update_buffer __ARGS((void));
-static void	qf_fill_buffer __ARGS((void));
+static int	qf_win_pos_update __ARGS((qf_info_T *qi, int old_qf_index));
+static win_T	*qf_find_win __ARGS((qf_info_T *qi));
+static buf_T	*qf_find_buf __ARGS((qf_info_T *qi));
+static void	qf_update_buffer __ARGS((qf_info_T *qi));
+static void	qf_fill_buffer __ARGS((qf_info_T *qi));
 #endif
 static char_u	*get_mef_name __ARGS((void));
 static buf_T	*load_dummy_buffer __ARGS((char_u *fname));
 static void	wipe_dummy_buffer __ARGS((buf_T *buf));
 static void	unload_dummy_buffer __ARGS((buf_T *buf));
 
+/* Quickfix window check helper macro */
+#define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL)
+/* Location list window check helper macro */
+#define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
+/*
+ * Return location list for window 'wp'
+ * For location list window, return the referenced location list
+ */
+#define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist)
+
 /*
  * Read the errorfile "efile" into memory, line by line, building the error
  * list.
  * Return -1 for error, number of errors for success.
  */
     int
-qf_init(efile, errorformat, newlist)
+qf_init(wp, efile, errorformat, newlist)
+    win_T	    *wp;
     char_u	    *efile;
     char_u	    *errorformat;
     int		    newlist;		/* TRUE: start a new error list */
 {
+    qf_info_T	    *qi = &ql_info;
+
     if (efile == NULL)
 	return FAIL;
-    return qf_init_ext(efile, curbuf, NULL, errorformat, newlist,
+
+    if (wp != NULL)
+	qi = GET_LOC_LIST(wp);
+
+    return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
 						    (linenr_T)0, (linenr_T)0);
 }
 
@@ -138,7 +169,8 @@
  * Return -1 for error, number of errors for success.
  */
     static int
-qf_init_ext(efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
+qf_init_ext(qi, efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
+    qf_info_T	    *qi;
     char_u	    *efile;
     buf_T	    *buf;
     typval_T	    *tv;
@@ -212,12 +244,12 @@
 	goto qf_init_end;
     }
 
-    if (newlist || qf_curlist == qf_listcount)
+    if (newlist || qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
-	qf_new_list();
-    else if (qf_lists[qf_curlist].qf_count > 0)
+	qf_new_list(qi);
+    else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
 	/* Adding to existing list, find last entry. */
-	for (qfprev = qf_lists[qf_curlist].qf_start;
+	for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
 			    qfprev->qf_next != qfprev; qfprev = qfprev->qf_next)
 	    ;
 
@@ -703,7 +735,7 @@
 	    }
 	}
 
-	if (qf_add_entry(&qfprev,
+	if (qf_add_entry(qi, &qfprev,
 			directory,
 			(*namebuf || directory)
 			    ? namebuf
@@ -721,27 +753,31 @@
     }
     if (fd == NULL || !ferror(fd))
     {
-	if (qf_lists[qf_curlist].qf_index == 0)	/* no valid entry found */
+	if (qi->qf_lists[qi->qf_curlist].qf_index == 0)
 	{
-	    qf_lists[qf_curlist].qf_ptr = qf_lists[qf_curlist].qf_start;
-	    qf_lists[qf_curlist].qf_index = 1;
-	    qf_lists[qf_curlist].qf_nonevalid = TRUE;
+	    /* no valid entry found */
+	    qi->qf_lists[qi->qf_curlist].qf_ptr =
+		qi->qf_lists[qi->qf_curlist].qf_start;
+	    qi->qf_lists[qi->qf_curlist].qf_index = 1;
+	    qi->qf_lists[qi->qf_curlist].qf_nonevalid = TRUE;
 	}
 	else
 	{
-	    qf_lists[qf_curlist].qf_nonevalid = FALSE;
-	    if (qf_lists[qf_curlist].qf_ptr == NULL)
-		qf_lists[qf_curlist].qf_ptr = qf_lists[qf_curlist].qf_start;
+	    qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+	    if (qi->qf_lists[qi->qf_curlist].qf_ptr == NULL)
+		qi->qf_lists[qi->qf_curlist].qf_ptr =
+		    qi->qf_lists[qi->qf_curlist].qf_start;
 	}
-	retval = qf_lists[qf_curlist].qf_count;	/* return number of matches */
+	/* return number of matches */
+	retval = qi->qf_lists[qi->qf_curlist].qf_count;
 	goto qf_init_ok;
     }
     EMSG(_(e_readerrf));
 error2:
-    qf_free(qf_curlist);
-    qf_listcount--;
-    if (qf_curlist > 0)
-	--qf_curlist;
+    qf_free(qi, qi->qf_curlist);
+    qi->qf_listcount--;
+    if (qi->qf_curlist > 0)
+	--qi->qf_curlist;
 qf_init_ok:
     if (fd != NULL)
 	fclose(fd);
@@ -760,7 +796,7 @@
     vim_free(fmtstr);
 
 #ifdef FEAT_WINDOWS
-    qf_update_buffer();
+    qf_update_buffer(qi);
 #endif
 
     return retval;
@@ -770,7 +806,8 @@
  * Prepare for adding a new quickfix list.
  */
     static void
-qf_new_list()
+qf_new_list(qi)
+    qf_info_T	*qi;
 {
     int		i;
 
@@ -779,44 +816,78 @@
      * the current entry.  This makes it possible to browse in a tree-like
      * way with ":grep'.
      */
-    while (qf_listcount > qf_curlist + 1)
-	qf_free(--qf_listcount);
+    while (qi->qf_listcount > qi->qf_curlist + 1)
+	qf_free(qi, --qi->qf_listcount);
 
     /*
      * When the stack is full, remove to oldest entry
      * Otherwise, add a new entry.
      */
-    if (qf_listcount == LISTCOUNT)
+    if (qi->qf_listcount == LISTCOUNT)
     {
-	qf_free(0);
+	qf_free(qi, 0);
 	for (i = 1; i < LISTCOUNT; ++i)
-	    qf_lists[i - 1] = qf_lists[i];
-	qf_curlist = LISTCOUNT - 1;
+	    qi->qf_lists[i - 1] = qi->qf_lists[i];
+	qi->qf_curlist = LISTCOUNT - 1;
     }
     else
-	qf_curlist = qf_listcount++;
-    qf_lists[qf_curlist].qf_index = 0;
-    qf_lists[qf_curlist].qf_count = 0;
+	qi->qf_curlist = qi->qf_listcount++;
+    qi->qf_lists[qi->qf_curlist].qf_index = 0;
+    qi->qf_lists[qi->qf_curlist].qf_count = 0;
 }
 
-#if defined(EXITFREE) || defined(PROTO)
-    void
-qf_free_all()
+/*
+ * Free a location list
+ */
+    static void
+ll_free_all(pqi)
+    qf_info_T	**pqi;
 {
     int		i;
+    qf_info_T	*qi;
 
-    for (i = 0; i < qf_listcount; ++i)
-	qf_free(i);
+    qi = *pqi;
+    if (qi == NULL)
+	return;
+    *pqi = NULL;	/* Remove reference to this list */
+
+    qi->qf_refcount--;
+    if (qi->qf_refcount < 1)
+    {
+	/* No references to this location list */
+	for (i = 0; i < qi->qf_listcount; ++i)
+	    qf_free(qi, i);
+	vim_free(qi);
+    }
 }
-#endif
+
+    void
+qf_free_all(wp)
+    win_T	*wp;
+{
+    int		i;
+    qf_info_T	*qi = &ql_info;
+
+    if (wp != NULL)
+    {
+	/* location list */
+	ll_free_all(&wp->w_llist);
+	ll_free_all(&wp->w_llist_ref);
+    }
+    else
+	/* quickfix list */
+	for (i = 0; i < qi->qf_listcount; ++i)
+	    qf_free(qi, i);
+}
 
 /*
  * Add an entry to the end of the list of errors.
  * Returns OK or FAIL.
  */
     static int
-qf_add_entry(prevp, dir, fname, mesg, lnum, col, vis_col, pattern, nr, type,
+qf_add_entry(qi, prevp, dir, fname, mesg, lnum, col, vis_col, pattern, nr, type,
 	     valid)
+    qf_info_T	*qi;		/* quickfix list */
     qfline_T	**prevp;	/* pointer to previously added entry or NULL */
     char_u	*dir;		/* optional directory name */
     char_u	*fname;		/* file name or NULL */
@@ -856,9 +927,10 @@
     qfp->qf_type = type;
     qfp->qf_valid = valid;
 
-    if (qf_lists[qf_curlist].qf_count == 0)	/* first element in the list */
+    if (qi->qf_lists[qi->qf_curlist].qf_count == 0)
+				/* first element in the list */
     {
-	qf_lists[qf_curlist].qf_start = qfp;
+	qi->qf_lists[qi->qf_curlist].qf_start = qfp;
 	qfp->qf_prev = qfp;	/* first element points to itself */
     }
     else
@@ -869,18 +941,154 @@
     qfp->qf_next = qfp;	/* last element points to itself */
     qfp->qf_cleared = FALSE;
     *prevp = qfp;
-    ++qf_lists[qf_curlist].qf_count;
-    if (qf_lists[qf_curlist].qf_index == 0 && qfp->qf_valid)
-					    /* first valid entry */
+    ++qi->qf_lists[qi->qf_curlist].qf_count;
+    if (qi->qf_lists[qi->qf_curlist].qf_index == 0 && qfp->qf_valid)
+				/* first valid entry */
     {
-	qf_lists[qf_curlist].qf_index = qf_lists[qf_curlist].qf_count;
-	qf_lists[qf_curlist].qf_ptr = qfp;
+	qi->qf_lists[qi->qf_curlist].qf_index =
+	    qi->qf_lists[qi->qf_curlist].qf_count;
+	qi->qf_lists[qi->qf_curlist].qf_ptr = qfp;
     }
 
     return OK;
 }
 
 /*
+ * Allocate a new location list for window 'wp'
+ */
+    static int
+ll_new_list(wp)
+    win_T   *wp;
+{
+    if ((wp->w_llist = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T))) == NULL)
+	return FAIL;
+
+    vim_memset(wp->w_llist, 0, (size_t)(sizeof(qf_info_T)));
+    wp->w_llist->qf_refcount++;
+
+    return OK;
+}
+
+/*
+ * Return the location list for window 'wp'.
+ * If not present, allocate a location list
+ */
+    static qf_info_T *
+ll_get_or_alloc_list(wp)
+    win_T   *wp;
+{
+    if (IS_LL_WINDOW(wp))
+	/* For a location list window, use the referenced location list */
+	return wp->w_llist_ref;
+
+    /*
+     * For a non-location list window, w_llist_ref should not point to a
+     * location list.
+     */
+    ll_free_all(&wp->w_llist_ref);
+
+    if (wp->w_llist == NULL)
+	if (ll_new_list(wp) == FAIL)	/* new location list */
+	    return NULL;
+    return wp->w_llist;
+}
+
+/*
+ * Copy the location list from window "from" to window "to".
+ */
+    void
+copy_loclist(from, to)
+    win_T	*from;
+    win_T	*to;
+{
+    qf_info_T	*qi;
+    int		idx;
+    int		i;
+
+    /*
+     * When copying from a location list window, copy the referenced
+     * location list. For other windows, copy the location list for
+     * that window.
+     */
+    if (IS_LL_WINDOW(from))
+	qi = from->w_llist_ref;
+    else
+	qi = from->w_llist;
+
+    if (qi == NULL)		    /* no location list to copy */
+	return;
+
+    if (ll_new_list(to) == FAIL)    /* allocate a new location list */
+	return;
+
+    to->w_llist->qf_listcount = qi->qf_listcount;
+
+    /* Copy the location lists one at a time */
+    for (idx = 0; idx < qi->qf_listcount; idx++)
+    {
+	qf_list_T   *from_qfl;
+	qf_list_T   *to_qfl;
+
+	to->w_llist->qf_curlist = idx;
+
+	from_qfl = &qi->qf_lists[idx];
+	to_qfl = &to->w_llist->qf_lists[idx];
+
+	/* Some of the fields are populated by qf_add_entry() */
+	to_qfl->qf_nonevalid = from_qfl->qf_nonevalid;
+	to_qfl->qf_count = 0;
+	to_qfl->qf_index = 0;
+	to_qfl->qf_start = NULL;
+	to_qfl->qf_ptr = NULL;
+
+	if (from_qfl->qf_count)
+	{
+	    qfline_T    *from_qfp;
+	    qfline_T    *prevp = NULL;
+
+	    /* copy all the location entries in this list */
+	    for (i = 0, from_qfp = from_qfl->qf_start; i < from_qfl->qf_count;
+		 ++i, from_qfp = from_qfp->qf_next)
+	    {
+		if (qf_add_entry(to->w_llist, &prevp,
+				 NULL,
+				 NULL,
+				 from_qfp->qf_text,
+				 from_qfp->qf_lnum,
+				 from_qfp->qf_col,
+				 from_qfp->qf_viscol,
+				 from_qfp->qf_pattern,
+				 from_qfp->qf_nr,
+				 0,
+				 from_qfp->qf_valid) == FAIL)
+		{
+		    qf_free_all(to);
+		    return;
+		}
+		/*
+		 * qf_add_entry() will not set the qf_num field, as the
+		 * directory and file names are not supplied. So the qf_fnum
+		 * field is copied here.
+		 */
+		prevp->qf_fnum = from_qfp->qf_fnum; /* file number */
+		prevp->qf_type = from_qfp->qf_type; /* error type */
+		if (from_qfl->qf_ptr == from_qfp)
+		    to_qfl->qf_ptr = prevp;	    /* current location */
+	    }
+	}
+
+	to_qfl->qf_index = from_qfl->qf_index;	/* current index in the list */
+
+	/* When no valid entries are present in the list, qf_ptr points to
+	 * the first item in the list */
+	if (to_qfl->qf_nonevalid == TRUE)
+	    to_qfl->qf_ptr = to_qfl->qf_start;
+    }
+
+    to->w_llist->qf_curlist = qi->qf_curlist;	/* current list */
+}
+
+/*
  * get buffer number for file "dir.name"
  */
     static int
@@ -1123,11 +1331,14 @@
  * else go to entry "errornr"
  */
     void
-qf_jump(dir, errornr, forceit)
+qf_jump(winptr, dir, errornr, forceit)
+    win_T	*winptr;
     int		dir;
     int		errornr;
     int		forceit;
 {
+    qf_info_T		*qi = &ql_info;
+    qf_info_T		*ll_ref;
     qfline_T		*qf_ptr;
     qfline_T		*old_qf_ptr;
     int			qf_index;
@@ -1154,16 +1365,21 @@
     int			old_KeyTyped = KeyTyped; /* getting file may reset it */
 #endif
     int			ok = OK;
+    int			usable_win;
 
-    if (qf_curlist >= qf_listcount || qf_lists[qf_curlist].qf_count == 0)
+    if (winptr != NULL)
+	qi = GET_LOC_LIST(winptr);
+
+    if (qi->qf_curlist >= qi->qf_listcount
+	|| qi->qf_lists[qi->qf_curlist].qf_count == 0)
     {
 	EMSG(_(e_quickfix));
 	return;
     }
 
-    qf_ptr = qf_lists[qf_curlist].qf_ptr;
+    qf_ptr = qi->qf_lists[qi->qf_curlist].qf_ptr;
     old_qf_ptr = qf_ptr;
-    qf_index = qf_lists[qf_curlist].qf_index;
+    qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
     old_qf_index = qf_index;
     if (dir == FORWARD || dir == FORWARD_FILE)	    /* next valid entry */
     {
@@ -1174,7 +1390,7 @@
 	    old_qf_fnum = qf_ptr->qf_fnum;
 	    do
 	    {
-		if (qf_index == qf_lists[qf_curlist].qf_count
+		if (qf_index == qi->qf_lists[qi->qf_curlist].qf_count
 						   || qf_ptr->qf_next == NULL)
 		{
 		    qf_ptr = old_qf_ptr;
@@ -1189,7 +1405,8 @@
 		}
 		++qf_index;
 		qf_ptr = qf_ptr->qf_next;
-	    } while ((!qf_lists[qf_curlist].qf_nonevalid && !qf_ptr->qf_valid)
+	    } while ((!qi->qf_lists[qi->qf_curlist].qf_nonevalid
+		      && !qf_ptr->qf_valid)
 		  || (dir == FORWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum));
 	    err = NULL;
 	}
@@ -1217,7 +1434,8 @@
 		}
 		--qf_index;
 		qf_ptr = qf_ptr->qf_prev;
-	    } while ((!qf_lists[qf_curlist].qf_nonevalid && !qf_ptr->qf_valid)
+	    } while ((!qi->qf_lists[qi->qf_curlist].qf_nonevalid
+		      && !qf_ptr->qf_valid)
 		  || (dir == BACKWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum));
 	    err = NULL;
 	}
@@ -1229,7 +1447,8 @@
 	    --qf_index;
 	    qf_ptr = qf_ptr->qf_prev;
 	}
-	while (errornr > qf_index && qf_index < qf_lists[qf_curlist].qf_count
+	while (errornr > qf_index && qf_index <
+				    qi->qf_lists[qi->qf_curlist].qf_count
 						   && qf_ptr->qf_next != NULL)
 	{
 	    ++qf_index;
@@ -1238,8 +1457,8 @@
     }
 
 #ifdef FEAT_WINDOWS
-    qf_lists[qf_curlist].qf_index = qf_index;
-    if (qf_win_pos_update(old_qf_index))
+    qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
+    if (qf_win_pos_update(qi, old_qf_index))
 	/* No need to print the error message if it's visible in the error
 	 * window */
 	print_message = FALSE;
@@ -1294,12 +1513,23 @@
 	if (qf_ptr->qf_fnum == 0)
 	    goto theend;
 
+	/* Locate a window showing a normal buffer */
+	usable_win = 0;
+	FOR_ALL_WINDOWS(win)
+	    if (win->w_buffer->b_p_bt[0] == NUL)
+	    {
+		usable_win = 1;
+		break;
+	    }
+
 	/*
 	 * If there is only one window, create a new one above the quickfix
 	 * window.
 	 */
-	if (firstwin == lastwin)
+	if (firstwin == lastwin || !usable_win)
 	{
+	    ll_ref = curwin->w_llist_ref;
+
 	    if (win_split(0, WSP_ABOVE) == FAIL)
 		goto failed;		/* not enough room for window */
 	    opened_window = TRUE;	/* close it when fail */
@@ -1307,9 +1537,60 @@
 # ifdef FEAT_SCROLLBIND
 	    curwin->w_p_scb = FALSE;
 # endif
+	    if (ll_ref != NULL)
+	    {
+		/* The new window should use the location list from the
+		 * location list window */
+		qf_free_all(curwin);
+		curwin->w_llist = ll_ref;
+		ll_ref->qf_refcount++;
+	    }
 	}
 	else
 	{
+	    if (curwin->w_llist_ref != NULL)
+	    {
+		/* In a location window */
+		ll_ref = curwin->w_llist_ref;
+
+		/* Find the window with the same location list */
+		FOR_ALL_WINDOWS(win)
+		    if (win->w_llist == ll_ref)
+			break;
+		if (win == NULL)
+		{
+		    /* Find the window showing the selected file */
+		    FOR_ALL_WINDOWS(win)
+			if (win->w_buffer->b_fnum == qf_ptr->qf_fnum)
+			    break;
+		    if (win == NULL)
+		    {
+			/* Find a previous usable window */
+			win = curwin;
+			do
+			{
+			    if (win->w_buffer->b_p_bt[0] == NUL)
+				break;
+			    if (win->w_prev == NULL)
+				win = lastwin;	/* wrap around the top */
+			    else
+				win = win->w_prev; /* go to previous window */
+			} while (win != curwin);
+		    }
+		}
+		win_goto(win);
+
+		/* If the location list for the window is not set, then set it
+		 * to the location list from the location window */
+		if (win->w_llist == NULL)
+		{
+		    win->w_llist = ll_ref;
+		    ll_ref->qf_refcount++;
+		}
+	    }
+	    else
+	    {
+
 	    /*
 	     * Try to find a window that shows the right buffer.
 	     * Default to the window just above the quickfix buffer.
@@ -1325,7 +1606,7 @@
 		else
 		    win = win->w_prev;	/* go to previous window */
 
-		if (bt_quickfix(win->w_buffer))
+		if (IS_QF_WINDOW(win))
 		{
 		    /* Didn't find it, go to the window before the quickfix
 		     * window. */
@@ -1345,6 +1626,7 @@
 	    }
 
 	    win_goto(win);
+	    }
 	}
     }
 #endif
@@ -1445,7 +1727,7 @@
 	    /* Update the screen before showing the message */
 	    update_topline_redraw();
 	    sprintf((char *)IObuff, _("(%d of %d)%s%s: "), qf_index,
-		    qf_lists[qf_curlist].qf_count,
+		    qi->qf_lists[qi->qf_curlist].qf_count,
 		    qf_ptr->qf_cleared ? _(" (line deleted)") : "",
 		    (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
 	    /* Add the message, skipping leading whitespace and newlines. */
@@ -1484,8 +1766,8 @@
 	}
     }
 theend:
-    qf_lists[qf_curlist].qf_ptr = qf_ptr;
-    qf_lists[qf_curlist].qf_index = qf_index;
+    qi->qf_lists[qi->qf_curlist].qf_ptr = qf_ptr;
+    qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
 #ifdef FEAT_WINDOWS
     if (p_swb != old_swb && opened_window)
     {
@@ -1501,6 +1783,7 @@
 
 /*
  * ":clist": list all errors
+ * ":llist": list all locations
  */
     void
 qf_list(eap)
@@ -1516,8 +1799,20 @@
     char_u	*arg = eap->arg;
     int		all = eap->forceit;	/* if not :cl!, only show
 						   recognised errors */
+    qf_info_T	*qi = &ql_info;
 
-    if (qf_curlist >= qf_listcount || qf_lists[qf_curlist].qf_count == 0)
+    if (eap->cmdidx == CMD_llist)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
+    if (qi->qf_curlist >= qi->qf_listcount
+	|| qi->qf_lists[qi->qf_curlist].qf_count == 0)
     {
 	EMSG(_(e_quickfix));
 	return;
@@ -1527,16 +1822,16 @@
 	EMSG(_(e_trailing));
 	return;
     }
-    i = qf_lists[qf_curlist].qf_count;
+    i = qi->qf_lists[qi->qf_curlist].qf_count;
     if (idx1 < 0)
 	idx1 = (-idx1 > i) ? 0 : idx1 + i + 1;
     if (idx2 < 0)
 	idx2 = (-idx2 > i) ? 0 : idx2 + i + 1;
 
-    if (qf_lists[qf_curlist].qf_nonevalid)
+    if (qi->qf_lists[qi->qf_curlist].qf_nonevalid)
 	all = TRUE;
-    qfp = qf_lists[qf_curlist].qf_start;
-    for (i = 1; !got_int && i <= qf_lists[qf_curlist].qf_count; )
+    qfp = qi->qf_lists[qi->qf_curlist].qf_start;
+    for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; )
     {
 	if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2)
 	{
@@ -1561,7 +1856,7 @@
 	    else
 		vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
 							    i, (char *)fname);
-	    msg_outtrans_attr(IObuff, i == qf_lists[qf_curlist].qf_index
+	    msg_outtrans_attr(IObuff, i == qi->qf_lists[qi->qf_curlist].qf_index
 					   ? hl_attr(HLF_L) : hl_attr(HLF_D));
 	    if (qfp->qf_lnum == 0)
 		IObuff[0] = NUL;
@@ -1629,48 +1924,64 @@
 /*
  * ":colder [count]": Up in the quickfix stack.
  * ":cnewer [count]": Down in the quickfix stack.
+ * ":lolder [count]": Up in the location list stack.
+ * ":lnewer [count]": Down in the location list stack.
  */
     void
 qf_age(eap)
     exarg_T	*eap;
 {
+    qf_info_T	*qi = &ql_info;
     int		count;
 
+    if (eap->cmdidx == CMD_lolder || eap->cmdidx == CMD_lnewer)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
     if (eap->addr_count != 0)
 	count = eap->line2;
     else
 	count = 1;
     while (count--)
     {
-	if (eap->cmdidx == CMD_colder)
+	if (eap->cmdidx == CMD_colder || eap->cmdidx == CMD_lolder)
 	{
-	    if (qf_curlist == 0)
+	    if (qi->qf_curlist == 0)
 	    {
 		EMSG(_("E380: At bottom of quickfix stack"));
 		return;
 	    }
-	    --qf_curlist;
+	    --qi->qf_curlist;
 	}
 	else
 	{
-	    if (qf_curlist >= qf_listcount - 1)
+	    if (qi->qf_curlist >= qi->qf_listcount - 1)
 	    {
 		EMSG(_("E381: At top of quickfix stack"));
 		return;
 	    }
-	    ++qf_curlist;
+	    ++qi->qf_curlist;
 	}
     }
-    qf_msg();
+    qf_msg(qi);
+
 }
 
     static void
-qf_msg()
+qf_msg(qi)
+    qf_info_T	*qi;
 {
     smsg((char_u *)_("error list %d of %d; %d errors"),
-	    qf_curlist + 1, qf_listcount, qf_lists[qf_curlist].qf_count);
+	    qi->qf_curlist + 1, qi->qf_listcount,
+	    qi->qf_lists[qi->qf_curlist].qf_count);
 #ifdef FEAT_WINDOWS
-    qf_update_buffer();
+    qf_update_buffer(qi);
 #endif
 }
 
@@ -1678,19 +1989,20 @@
  * Free error list "idx".
  */
     static void
-qf_free(idx)
+qf_free(qi, idx)
+    qf_info_T	*qi;
     int		idx;
 {
     qfline_T	*qfp;
 
-    while (qf_lists[idx].qf_count)
+    while (qi->qf_lists[idx].qf_count)
     {
-	qfp = qf_lists[idx].qf_start->qf_next;
-	vim_free(qf_lists[idx].qf_start->qf_text);
-	vim_free(qf_lists[idx].qf_start->qf_pattern);
-	vim_free(qf_lists[idx].qf_start);
-	qf_lists[idx].qf_start = qfp;
-	--qf_lists[idx].qf_count;
+	qfp = qi->qf_lists[idx].qf_start->qf_next;
+	vim_free(qi->qf_lists[idx].qf_start->qf_text);
+	vim_free(qi->qf_lists[idx].qf_start->qf_pattern);
+	vim_free(qi->qf_lists[idx].qf_start);
+	qi->qf_lists[idx].qf_start = qfp;
+	--qi->qf_lists[idx].qf_count;
     }
 }
 
@@ -1698,7 +2010,8 @@
  * qf_mark_adjust: adjust marks
  */
    void
-qf_mark_adjust(line1, line2, amount, amount_after)
+qf_mark_adjust(wp, line1, line2, amount, amount_after)
+    win_T	*wp;
     linenr_T	line1;
     linenr_T	line2;
     long	amount;
@@ -1707,11 +2020,19 @@
     int		i;
     qfline_T	*qfp;
     int		idx;
+    qf_info_T	*qi = &ql_info;
 
-    for (idx = 0; idx < qf_listcount; ++idx)
-	if (qf_lists[idx].qf_count)
-	    for (i = 0, qfp = qf_lists[idx].qf_start;
-		       i < qf_lists[idx].qf_count; ++i, qfp = qfp->qf_next)
+    if (wp != NULL)
+    {
+	if (wp->w_llist == NULL)
+	    return;
+	qi = wp->w_llist;
+    }
+
+    for (idx = 0; idx < qi->qf_listcount; ++idx)
+	if (qi->qf_lists[idx].qf_count)
+	    for (i = 0, qfp = qi->qf_lists[idx].qf_start;
+		       i < qi->qf_lists[idx].qf_count; ++i, qfp = qfp->qf_next)
 		if (qfp->qf_fnum == curbuf->b_fnum)
 		{
 		    if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2)
@@ -1776,26 +2097,33 @@
 /*
  * ":cwindow": open the quickfix window if we have errors to display,
  *	       close it if not.
+ * ":lwindow": open the location list window if we have locations to display,
+ *	       close it if not.
  */
     void
 ex_cwindow(eap)
     exarg_T	*eap;
 {
+    qf_info_T	*qi = &ql_info;
     win_T	*win;
 
-    /*
-     * Look for an existing quickfix window.
-     */
-    for (win = firstwin; win != NULL; win = win->w_next)
-	if (bt_quickfix(win->w_buffer))
-	    break;
+    if (eap->cmdidx == CMD_lwindow)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	    return;
+    }
+
+    /* Look for an existing quickfix window.  */
+    win = qf_find_win(qi);
 
     /*
      * If a quickfix window is open but we have no errors to display,
      * close the window.  If a quickfix window is not open, then open
      * it if we have errors; otherwise, leave it closed.
      */
-    if (qf_lists[qf_curlist].qf_nonevalid || qf_curlist >= qf_listcount)
+    if (qi->qf_lists[qi->qf_curlist].qf_nonevalid
+	|| qi->qf_curlist >= qi->qf_listcount)
     {
 	if (win != NULL)
 	    ex_cclose(eap);
@@ -1806,36 +2134,51 @@
 
 /*
  * ":cclose": close the window showing the list of errors.
+ * ":lclose": close the window showing the location list
  */
 /*ARGSUSED*/
     void
 ex_cclose(eap)
     exarg_T	*eap;
 {
-    win_T	*win;
+    win_T	*win = NULL;
+    qf_info_T	*qi = &ql_info;
 
-    /*
-     * Find existing quickfix window and close it.
-     */
-    for (win = firstwin; win != NULL; win = win->w_next)
-	if (bt_quickfix(win->w_buffer))
-	    break;
+    if (eap->cmdidx == CMD_lclose || eap->cmdidx == CMD_lwindow)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	    return;
+    }
 
+    /* Find existing quickfix window and close it. */
+    win = qf_find_win(qi);
     if (win != NULL)
 	win_close(win, FALSE);
 }
 
 /*
  * ":copen": open a window that shows the list of errors.
+ * ":lopen": open a window that shows the location list.
  */
     void
 ex_copen(eap)
     exarg_T	*eap;
 {
+    qf_info_T	*qi = &ql_info;
     int		height;
-    buf_T	*buf;
     win_T	*win;
 
+    if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+    }
+
     if (eap->addr_count != 0)
 	height = eap->line2;
     else
@@ -1851,9 +2194,8 @@
     /*
      * Find existing quickfix window, or open a new one.
      */
-    for (win = firstwin; win != NULL; win = win->w_next)
-	if (bt_quickfix(win->w_buffer))
-	    break;
+    win = qf_find_win(qi);
+
     if (win != NULL)
 	win_goto(win);
     else
@@ -1861,30 +2203,35 @@
 	/* The current window becomes the previous window afterwards. */
 	win = curwin;
 
-	/* Create the new window at the very bottom. */
-	win_goto(lastwin);
+	if (eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow)
+	    /* Create the new window at the very bottom. */
+	    win_goto(lastwin);
 	if (win_split(height, WSP_BELOW) == FAIL)
 	    return;		/* not enough room for window */
 #ifdef FEAT_SCROLLBIND
 	curwin->w_p_scb = FALSE;
 #endif
 
-	/*
-	 * Find existing quickfix buffer, or create a new one.
-	 */
-	buf = qf_find_buf();
-	if (buf == NULL)
+	/* Remove the location list for the quickfix window */
+	qf_free_all(curwin);
+
+	if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
 	{
-	    (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE);
-	    /* switch off 'swapfile' */
-	    set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
-	    set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
-								   OPT_LOCAL);
-	    set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
-	    set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
+	    /*
+	     * For the location list window, create a reference to the
+	     * location list from the window 'win'.
+	     */
+	    curwin->w_llist_ref = win->w_llist;
+	    win->w_llist->qf_refcount++;
 	}
-	else if (buf != curbuf)
-	    set_curbuf(buf, DOBUF_GOTO);
+
+	(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE);
+	/* switch off 'swapfile' */
+	set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
+	set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
+			 OPT_LOCAL);
+	set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
+	set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
 
 #ifdef FEAT_VERTSPLIT
 	/* Only set the height when there is no window to the side. */
@@ -1899,9 +2246,9 @@
     /*
      * Fill the buffer with the quickfix list.
      */
-    qf_fill_buffer();
+    qf_fill_buffer(qi);
 
-    curwin->w_cursor.lnum = qf_lists[qf_curlist].qf_index;
+    curwin->w_cursor.lnum = qi->qf_lists[qi->qf_curlist].qf_index;
     curwin->w_cursor.col = 0;
     check_cursor();
     update_topline();		/* scroll to show the line */
@@ -1912,9 +2259,16 @@
  * window).
  */
      linenr_T
-qf_current_entry()
+qf_current_entry(wp)
+    win_T	*wp;
 {
-    return qf_lists[qf_curlist].qf_index;
+    qf_info_T	*qi = &ql_info;
+
+    if (IS_LL_WINDOW(wp))
+	/* In the location list window, use the referenced location list */
+	qi = wp->w_llist_ref;
+
+    return qi->qf_lists[qi->qf_curlist].qf_index;
 }
 
 /*
@@ -1922,19 +2276,18 @@
  * Return TRUE if there is a quickfix window.
  */
     static int
-qf_win_pos_update(old_qf_index)
+qf_win_pos_update(qi, old_qf_index)
+    qf_info_T	*qi;
     int		old_qf_index;	/* previous qf_index or zero */
 {
     win_T	*win;
-    int		qf_index = qf_lists[qf_curlist].qf_index;
+    int		qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
 
     /*
      * Put the cursor on the current error in the quickfix window, so that
      * it's viewable.
      */
-    for (win = firstwin; win != NULL; win = win->w_next)
-	if (bt_quickfix(win->w_buffer))
-	    break;
+    win = qf_find_win(qi);
     if (win != NULL
 	    && qf_index <= win->w_buffer->b_ml.ml_line_count
 	    && old_qf_index != qf_index)
@@ -1965,24 +2318,49 @@
 }
 
 /*
+ * Find a window displaying the quickfix/location list 'qi'
+ */
+    static win_T *
+qf_find_win(qi)
+    qf_info_T	*qi;
+{
+    win_T	*win;
+
+    /*
+     * When searching for the quickfix buffer, find a window
+     * with w_llist_ref set to NULL.
+     * When searching for the location list buffer, find a window
+     * with w_llist_ref pointing to the supplied location list.
+     */
+    FOR_ALL_WINDOWS(win)
+	if (bt_quickfix(win->w_buffer))
+	    if ((qi == &ql_info && win->w_llist_ref == NULL)
+		|| (qi != &ql_info && win->w_llist_ref == qi))
+		break;
+
+    return win;
+}
+
+/*
  * Find quickfix buffer.
  */
     static buf_T *
-qf_find_buf()
+qf_find_buf(qi)
+    qf_info_T	*qi;
 {
-    buf_T	*buf;
+    win_T	*win;
 
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
-	if (bt_quickfix(buf))
-	    break;
-    return buf;
+    win = qf_find_win(qi);
+
+    return (win != NULL) ? win->w_buffer: NULL;
 }
 
 /*
  * Find the quickfix buffer.  If it exists, update the contents.
  */
     static void
-qf_update_buffer()
+qf_update_buffer(qi)
+    qf_info_T	*qi;
 {
     buf_T	*buf;
 #ifdef FEAT_AUTOCMD
@@ -1992,7 +2370,7 @@
 #endif
 
     /* Check if a buffer for the quickfix list exists.  Update it. */
-    buf = qf_find_buf();
+    buf = qf_find_buf(qi);
     if (buf != NULL)
     {
 #ifdef FEAT_AUTOCMD
@@ -2003,7 +2381,7 @@
 	curbuf = buf;
 #endif
 
-	qf_fill_buffer();
+	qf_fill_buffer(qi);
 
 #ifdef FEAT_AUTOCMD
 	/* restore curwin/curbuf and a few other things */
@@ -2012,7 +2390,7 @@
 	curbuf = save_curbuf;
 #endif
 
-	(void)qf_win_pos_update(0);
+	(void)qf_win_pos_update(qi, 0);
     }
 }
 
@@ -2021,7 +2399,8 @@
  * curbuf must be the quickfix buffer!
  */
     static void
-qf_fill_buffer()
+qf_fill_buffer(qi)
+    qf_info_T	*qi;
 {
     linenr_T	lnum;
     qfline_T	*qfp;
@@ -2034,11 +2413,11 @@
 	(void)ml_delete((linenr_T)1, FALSE);
 
     /* Check if there is anything to display */
-    if (qf_curlist < qf_listcount)
+    if (qi->qf_curlist < qi->qf_listcount)
     {
 	/* Add one line for each error */
-	qfp = qf_lists[qf_curlist].qf_start;
-	for (lnum = 0; lnum < qf_lists[qf_curlist].qf_count; ++lnum)
+	qfp = qi->qf_lists[qi->qf_curlist].qf_start;
+	for (lnum = 0; lnum < qi->qf_lists[qi->qf_curlist].qf_count; ++lnum)
 	{
 	    if (qfp->qf_fnum != 0
 		    && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL
@@ -2268,10 +2647,10 @@
     (void)char_avail();
 #endif
 
-    if (qf_init(fname, eap->cmdidx != CMD_make ? p_gefm : p_efm,
+    if (qf_init(NULL, fname, eap->cmdidx != CMD_make ? p_gefm : p_efm,
 					       eap->cmdidx != CMD_grepadd) > 0
 	    && !eap->forceit)
-	qf_jump(0, 0, FALSE);		/* display first error */
+	qf_jump(NULL, 0, 0, FALSE);		/* display first error */
 
     mch_remove(fname);
     vim_free(fname);
@@ -2343,17 +2722,34 @@
 
 /*
  * ":cc", ":crewind", ":cfirst" and ":clast".
+ * ":ll", ":lrewind", ":lfirst" and ":llast".
  */
     void
 ex_cc(eap)
     exarg_T	*eap;
 {
-    qf_jump(0,
+    win_T	*wp = NULL;
+    qf_info_T	*qi;
+
+    if (eap->cmdidx == CMD_ll || eap->cmdidx == CMD_lrewind
+	|| eap->cmdidx == CMD_lfirst || eap->cmdidx == CMD_llast)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+	wp = curwin;
+    }
+
+    qf_jump(wp, 0,
 	    eap->addr_count > 0
 	    ? (int)eap->line2
-	    : eap->cmdidx == CMD_cc
+	    : (eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll)
 		? 0
-		: (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_cfirst)
+		: (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_lrewind
+		   || eap->cmdidx == CMD_cfirst || eap->cmdidx == CMD_lfirst)
 		    ? 1
 		    : 32767,
 	    eap->forceit);
@@ -2361,16 +2757,34 @@
 
 /*
  * ":cnext", ":cnfile", ":cNext" and ":cprevious".
+ * ":lnext", ":lNext", ":lprevious", ":lnfile", ":lNfile" and ":lpfile".
  */
     void
 ex_cnext(eap)
     exarg_T	*eap;
 {
-    qf_jump(eap->cmdidx == CMD_cnext
+    win_T	*wp = NULL;
+    qf_info_T	*qi;
+
+    if (eap->cmdidx == CMD_lnext || eap->cmdidx == CMD_lNext
+	|| eap->cmdidx == CMD_lprevious || eap->cmdidx == CMD_lnfile
+	|| eap->cmdidx == CMD_lNfile || eap->cmdidx == CMD_lpfile)
+    {
+	qi = GET_LOC_LIST(curwin);
+	if (qi == NULL)
+	{
+	    EMSG(_(e_loclist));
+	    return;
+	}
+	wp = curwin;
+    }
+
+    qf_jump(wp, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext)
 	    ? FORWARD
-	    : eap->cmdidx == CMD_cnfile
+	    : (eap->cmdidx == CMD_cnfile || eap->cmdidx == CMD_lnfile)
 		? FORWARD_FILE
-		: (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_cNfile)
+		: (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_lpfile
+		   || eap->cmdidx == CMD_cNfile || eap->cmdidx == CMD_lNfile)
 		    ? BACKWARD_FILE
 		    : BACKWARD,
 	    eap->addr_count > 0 ? (int)eap->line2 : 1, eap->forceit);
@@ -2378,11 +2792,24 @@
 
 /*
  * ":cfile"/":cgetfile"/":caddfile" commands.
+ * ":lfile"/":lgetfile"/":laddfile" commands.
  */
     void
 ex_cfile(eap)
     exarg_T	*eap;
 {
+    win_T	*wp = NULL;
+    qf_info_T	*qi;
+
+    if (eap->cmdidx == CMD_lfile || eap->cmdidx == CMD_lgetfile
+	|| eap->cmdidx == CMD_laddfile)
+    {
+	qi = ll_get_or_alloc_list(curwin);
+	if (qi == NULL)
+	    return;
+	wp = curwin;
+    }
+
     if (*eap->arg != NUL)
 	set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE);
 
@@ -2396,9 +2823,11 @@
      * :caddfile adds to an existing quickfix list. If there is no
      * quickfix list then a new list is created.
      */
-    if (qf_init(p_ef, p_efm, eap->cmdidx != CMD_caddfile) > 0
-						  && eap->cmdidx == CMD_cfile)
-	qf_jump(0, 0, eap->forceit);		/* display first error */
+    if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
+				  && eap->cmdidx != CMD_laddfile)) > 0
+				  && (eap->cmdidx == CMD_cfile
+					     || eap->cmdidx == CMD_lfile))
+	qf_jump(wp, 0, 0, eap->forceit);	/* display first error */
 }
 
 /*
@@ -2430,6 +2859,7 @@
     char_u	*au_name =  NULL;
     int		flags = 0;
     colnr_T	col;
+    qf_info_T	*qi = &ql_info;
 
     switch (eap->cmdidx)
     {
@@ -2468,12 +2898,12 @@
     }
 
     if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_vimgrepadd)
-						|| qf_curlist == qf_listcount)
+					|| qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
-	qf_new_list();
-    else if (qf_lists[qf_curlist].qf_count > 0)
+	qf_new_list(qi);
+    else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
 	/* Adding to existing list, find last entry. */
-	for (prevp = qf_lists[qf_curlist].qf_start;
+	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
 			    prevp->qf_next != prevp; prevp = prevp->qf_next)
 	    ;
 
@@ -2550,7 +2980,7 @@
 		while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
 								     col) > 0)
 		{
-		    if (qf_add_entry(&prevp,
+		    if (qf_add_entry(qi, &prevp,
 				NULL,       /* dir */
 				fnames[fi],
 				ml_get_buf(buf,
@@ -2630,19 +3060,19 @@
 
     FreeWild(fcount, fnames);
 
-    qf_lists[qf_curlist].qf_nonevalid = FALSE;
-    qf_lists[qf_curlist].qf_ptr = qf_lists[qf_curlist].qf_start;
-    qf_lists[qf_curlist].qf_index = 1;
+    qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+    qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
+    qi->qf_lists[qi->qf_curlist].qf_index = 1;
 
 #ifdef FEAT_WINDOWS
-    qf_update_buffer();
+    qf_update_buffer(qi);
 #endif
 
     /* Jump to first match. */
-    if (qf_lists[qf_curlist].qf_count > 0)
+    if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
     {
 	if ((flags & VGR_NOJUMP) == 0)
-	    qf_jump(0, 0, eap->forceit);
+	    qf_jump(NULL, 0, 0, eap->forceit);
     }
     else
 	EMSG2(_(e_nomatch2), s);
@@ -2821,16 +3251,18 @@
 get_errorlist(list)
     list_T	*list;
 {
+    qf_info_T	*qi = &ql_info;
     dict_T	*dict;
     char_u	buf[2];
     qfline_T	*qfp;
     int		i;
 
-    if (qf_curlist >= qf_listcount || qf_lists[qf_curlist].qf_count == 0)
+    if (qi->qf_curlist >= qi->qf_listcount
+	|| qi->qf_lists[qi->qf_curlist].qf_count == 0)
 	return FAIL;
 
-    qfp = qf_lists[qf_curlist].qf_start;
-    for (i = 1; !got_int && i <= qf_lists[qf_curlist].qf_count; ++i)
+    qfp = qi->qf_lists[qi->qf_curlist].qf_start;
+    for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ++i)
     {
 	if ((dict = dict_alloc()) == NULL)
 	    return FAIL;
@@ -2873,17 +3305,18 @@
     qfline_T	*prevp = NULL;
     int		valid, status;
     int		retval = OK;
+    qf_info_T	*qi = &ql_info;
 
-    if (action == ' ' || qf_curlist == qf_listcount)
+    if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
 	/* make place for a new list */
-	qf_new_list();
-    else if (action == 'a' && qf_lists[qf_curlist].qf_count > 0)
+	qf_new_list(qi);
+    else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
 	/* Adding to existing list, find last entry. */
-	for (prevp = qf_lists[qf_curlist].qf_start;
+	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
 	     prevp->qf_next != prevp; prevp = prevp->qf_next)
 	    ;
     else if (action == 'r')
-	qf_free(qf_curlist);
+	qf_free(qi, qi->qf_curlist);
 
     for (li = list->lv_first; li != NULL; li = li->li_next)
     {
@@ -2909,7 +3342,7 @@
 	if (filename == NULL || (lnum == 0 && pattern == NULL))
 	    valid = FALSE;
 
-	status =  qf_add_entry(&prevp,
+	status =  qf_add_entry(qi, &prevp,
 			       NULL,	    /* dir */
 			       filename,
 			       text,
@@ -2933,12 +3366,12 @@
 	}
     }
 
-    qf_lists[qf_curlist].qf_nonevalid = FALSE;
-    qf_lists[qf_curlist].qf_ptr = qf_lists[qf_curlist].qf_start;
-    qf_lists[qf_curlist].qf_index = 1;
+    qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+    qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
+    qi->qf_lists[qi->qf_curlist].qf_index = 1;
 
 #ifdef FEAT_WINDOWS
-    qf_update_buffer();
+    qf_update_buffer(qi);
 #endif
 
     return retval;
@@ -2947,12 +3380,21 @@
 
 /*
  * ":[range]cbuffer [bufnr]" command.
+ * ":[range]lbuffer [bufnr]" command.
  */
     void
 ex_cbuffer(eap)
     exarg_T   *eap;
 {
     buf_T	*buf = NULL;
+    qf_info_T	*qi = &ql_info;
+
+    if (eap->cmdidx == CMD_lbuffer)
+    {
+	qi = ll_get_or_alloc_list(curwin);
+	if (qi == NULL)
+	    return;
+    }
 
     if (*eap->arg == NUL)
 	buf = curbuf;
@@ -2973,19 +3415,30 @@
 		|| eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count)
 	    EMSG(_(e_invrange));
 	else
-	    qf_init_ext(NULL, buf, NULL, p_efm, TRUE, eap->line1, eap->line2);
+	    qf_init_ext(qi, NULL, buf, NULL, p_efm, TRUE, eap->line1, eap->line2);
     }
 }
 
 #if defined(FEAT_EVAL) || defined(PROTO)
 /*
  * ":cexpr {expr}" and ":caddexpr {expr}" command.
+ * ":lexpr {expr}" and ":laddexpr {expr}" command.
  */
     void
 ex_cexpr(eap)
     exarg_T	*eap;
 {
     typval_T	*tv;
+    qf_info_T	*qi = &ql_info;
+    win_T	*wp = NULL;
+
+    if (eap->cmdidx == CMD_lexpr || eap->cmdidx == CMD_laddexpr)
+    {
+	qi = ll_get_or_alloc_list(curwin);
+	if (qi == NULL)
+	    return;
+	wp = curwin;
+    }
 
     /* Evaluate the expression.  When the result is a string or a list we can
      * use it to fill the errorlist. */
@@ -2995,10 +3448,12 @@
 	if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
 		|| (tv->v_type == VAR_LIST && tv->vval.v_list != NULL))
 	{
-	    if (qf_init_ext(NULL, NULL, tv, p_efm, eap->cmdidx == CMD_cexpr,
+	    if (qf_init_ext(qi, NULL, NULL, tv, p_efm,
+			    (eap->cmdidx == CMD_cexpr
+			     || eap->cmdidx == CMD_lexpr),
 						 (linenr_T)0, (linenr_T)0) > 0
-		    && eap->cmdidx == CMD_cexpr)
-		qf_jump(0, 0, eap->forceit);	/* display first error */
+		    && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr))
+		qf_jump(wp, 0, 0, eap->forceit);  /* display first error */
 	}
 	else
 	    EMSG(_("E777: String or List expected"));
@@ -3026,6 +3481,7 @@
 #ifdef FEAT_MULTI_LANG
     char_u	*lang;
 #endif
+    qf_info_T	*qi = &ql_info;
 
     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
     save_cpo = p_cpo;
@@ -3041,7 +3497,7 @@
     if (regmatch.regprog != NULL)
     {
 	/* create a new quickfix list */
-	qf_new_list();
+	qf_new_list(qi);
 
 	/* Go through all directories in 'runtimepath' */
 	p = p_rtp;
@@ -3082,7 +3538,7 @@
 				while (l > 0 && IObuff[l - 1] <= ' ')
 				     IObuff[--l] = NUL;
 
-				if (qf_add_entry(&prevp,
+				if (qf_add_entry(qi, &prevp,
 					    NULL,	/* dir */
 					    fnames[fi],
 					    IObuff,
@@ -3111,20 +3567,21 @@
 	}
 	vim_free(regmatch.regprog);
 
-	qf_lists[qf_curlist].qf_nonevalid = FALSE;
-	qf_lists[qf_curlist].qf_ptr = qf_lists[qf_curlist].qf_start;
-	qf_lists[qf_curlist].qf_index = 1;
+	qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
+	qi->qf_lists[qi->qf_curlist].qf_ptr =
+	    qi->qf_lists[qi->qf_curlist].qf_start;
+	qi->qf_lists[qi->qf_curlist].qf_index = 1;
     }
 
     p_cpo = save_cpo;
 
 #ifdef FEAT_WINDOWS
-    qf_update_buffer();
+    qf_update_buffer(qi);
 #endif
 
     /* Jump to first match. */
-    if (qf_lists[qf_curlist].qf_count > 0)
-	qf_jump(0, 0, FALSE);
+    if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+	qf_jump(NULL, 0, 0, FALSE);
     else
 	EMSG2(_(e_nomatch2), eap->arg);
 }
diff --git a/src/screen.c b/src/screen.c
index 4657566..e2f10db 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2806,7 +2806,7 @@
 # endif
 # if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)
     /* Highlight the current line in the quickfix window. */
-    if (bt_quickfix(wp->w_buffer) && qf_current_entry() == lnum)
+    if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum)
 	line_attr = hl_attr(HLF_L);
 # endif
     if (line_attr != 0)
@@ -6651,6 +6651,8 @@
 	    redraw_cmdline = TRUE;
 	    if (c1 == ' ' && c2 == ' ')
 		clear_cmdline = FALSE;	/* command line has been cleared */
+	    if (start_col == 0)
+		mode_displayed = FALSE; /* mode cleared or overwritten */
 	}
     }
 }
@@ -7027,6 +7029,7 @@
     {
 	out_str(T_CL);		/* clear the display */
 	clear_cmdline = FALSE;
+	mode_displayed = FALSE;
     }
     else
     {
@@ -8326,6 +8329,7 @@
 #endif
 		MSG_PUTS_ATTR(" --", attr);
 	    }
+
 	    need_clear = TRUE;
 	}
 	if (Recording
@@ -8337,6 +8341,8 @@
 	    MSG_PUTS_ATTR(_("recording"), attr);
 	    need_clear = TRUE;
 	}
+
+	mode_displayed = TRUE;
 	if (need_clear || clear_cmdline)
 	    msg_clr_eos();
 	msg_didout = FALSE;		/* overwrite this message */
@@ -8383,6 +8389,7 @@
 /*
  * Delete mode message.  Used when ESC is typed which is expected to end
  * Insert mode (but Insert mode didn't end yet!).
+ * Caller should check "mode_displayed".
  */
     void
 unshowmode(force)
diff --git a/src/structs.h b/src/structs.h
index b71f592..e8d5b72 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1085,6 +1085,9 @@
 # define B_SPELL(buf)  (0)
 #endif
 
+#ifdef FEAT_QUICKFIX
+typedef struct qf_info_S qf_info_T;
+#endif
 
 /*
  * buffer: structure that holds information about one file
@@ -1835,6 +1838,15 @@
     int		w_nrwidth_width;	/* nr of chars to print line count. */
 #endif
 
+#ifdef FEAT_QUICKFIX
+    qf_info_T	*w_llist;		/* Location list for this window */
+    /*
+     * Location list reference used in the location list window.
+     * In a non-location list window, w_llist_ref is NULL.
+     */
+    qf_info_T	*w_llist_ref;
+#endif
+
 
 #ifdef FEAT_MZSCHEME
     void	*w_mzscheme_ref;	/* The MzScheme value for this window */
diff --git a/src/version.h b/src/version.h
index 3d42437..569cb6e 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 23)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 23, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 25)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Jan 25, compiled "