summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-01-25 22:10:52 +0000
committerBram Moolenaar <Bram@vim.org>2006-01-25 22:10:52 +0000
commitd12f5c17be85407b7beb8622828ba6bc5903369e (patch)
treecb86c7b532ba41cd2f914bd2e2636acc09c99fe1 /src
parent28c258fd24342fe52e85059d68ce69cf9ef5f8cd (diff)
updated for version 7.0187v7.0187
Diffstat (limited to 'src')
-rw-r--r--src/Makefile4
-rw-r--r--src/edit.c31
-rw-r--r--src/ex_cmds.h44
-rw-r--r--src/globals.h2
-rw-r--r--src/if_cscope.c4
-rw-r--r--src/main.c6
-rw-r--r--src/misc2.c6
-rw-r--r--src/option.c2
-rw-r--r--src/os_unix.c17
-rw-r--r--src/proto/quickfix.pro11
-rw-r--r--src/quickfix.c865
-rw-r--r--src/screen.c9
-rw-r--r--src/structs.h12
-rw-r--r--src/version.h4
14 files changed, 780 insertions, 237 deletions
diff --git a/src/Makefile b/src/Makefile
index da6137cbba..2da7860835 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1699,10 +1699,10 @@ types.vim: $(TAGS_SRC) $(TAGS_INCL)
#
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 8dc07fdf97..e331c4c5a9 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -89,7 +89,7 @@ static compl_T *compl_shown_match = NULL;
/* 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_delete __ARGS((void));
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 @@ edit(cmdchar, startln, count)
* 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 @@ doESCkey:
* 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 @@ vim_is_ctrl_x_key(c)
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 @@ ins_compl_prep(c)
* '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 @@ ins_compl_key2dir(c)
}
/*
+ * 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 @@ ins_compl_key2count(c)
{
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 a15ed464d8..8211a7f8f7 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -473,26 +473,58 @@ EX(CMD_keepalt, "keepalt", ex_wrongmodifier,
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 @@ EX(CMD_lockmarks, "lockmarks", ex_wrongmodifier,
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 9fd9b668cc..82c42b2b65 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -83,6 +83,7 @@ EXTERN int cmdline_row;
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 @@ EXTERN char_u e_prev_dir[] INIT(= N_("E459: Cannot go back to previous directory
#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 56fd12aa2b..7a44253151 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -1104,7 +1104,7 @@ cs_find_common(opt, pat, forceit, verbose)
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 @@ cs_find_common(opt, pat, forceit, verbose)
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 561d6ae4bb..2661c26bbb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -636,7 +636,7 @@ main
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 @@ main
*/
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 @@ exe_commands(parmp)
#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 fb873fb4a2..328bdf216b 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -952,6 +952,7 @@ free_all_mem()
{
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 @@ free_all_mem()
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 b7f1cf02bf..079e472db1 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6743,7 +6743,7 @@ set_bool_option(opt_idx, varp, value, opt_flags)
{
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 afc68ff841..374d85e762 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4852,7 +4852,7 @@ mch_expandpath(gap, path, flags)
# define SEEK_END 2
#endif
-#define SHELL_SPECIAL (char_u *)"\t \"&';<>\\|"
+#define SHELL_SPECIAL (char_u *)"\t \"&';<>()\\|"
/* ARGSUSED */
int
@@ -5128,7 +5128,12 @@ mch_expand_wildcards(num_pat, pat, num_file, file, flags)
}
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 @@ mch_expand_wildcards(num_pat, pat, num_file, file, flags)
*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 6712cf1517..4ea4f01d49 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 @@ int set_errorlist __ARGS((list_T *list, int action));
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 2cd0bd03b1..923c7fda0b 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -49,17 +49,30 @@ struct qfline_S
*/
#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 @@ struct eformat
/* '+' 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 char_u *qf_guess_filepath __ARGS((char_u *));
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 @@ qf_init(efile, errorformat, newlist)
* 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 @@ qf_init_ext(efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
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 @@ restofline:
}
}
- if (qf_add_entry(&qfprev,
+ if (qf_add_entry(qi, &qfprev,
directory,
(*namebuf || directory)
? namebuf
@@ -721,27 +753,31 @@ restofline:
}
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 @@ qf_init_end:
vim_free(fmtstr);
#ifdef FEAT_WINDOWS
- qf_update_buffer();
+ qf_update_buffer(qi);
#endif
return retval;
@@ -770,7 +806,8 @@ qf_init_end:
* 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 @@ qf_new_list()
* 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;
+}
+
+/*
+ * Free a location list
+ */
+ static void
+ll_free_all(pqi)
+ qf_info_T **pqi;
+{
+ int i;
+ qf_info_T *qi;
+
+ 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);
+ }
}
-#if defined(EXITFREE) || defined(PROTO)
void
-qf_free_all()
+qf_free_all(wp)
+ win_T *wp;
{
int i;
+ qf_info_T *qi = &ql_info;
- for (i = 0; i < qf_listcount; ++i)
- qf_free(i);
+ 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);
}
-#endif
/*
* 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 @@ qf_add_entry(prevp, dir, fname, mesg, lnum, col, vis_col, pattern, nr, type,
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 @@ qf_add_entry(prevp, dir, fname, mesg, lnum, col, vis_col, pattern, nr, type,
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 @@ qf_guess_filepath(filename)
* 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 @@ qf_jump(dir, errornr, forceit)
int old_KeyTyped = KeyTyped; /* getting file may reset it */
#endif
int ok = OK;
+ int usable_win;
+
+ if (winptr != NULL)
+ qi = GET_LOC_LIST(winptr);
- 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)
{
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 @@ qf_jump(dir, errornr, forceit)
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_jump(dir, errornr, forceit)
}
++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_jump(dir, errornr, forceit)
}
--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_jump(dir, errornr, forceit)
--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 @@ qf_jump(dir, errornr, forceit)
}
#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 @@ qf_jump(dir, errornr, forceit)
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;
+ }