diff options
author | Bram Moolenaar <Bram@vim.org> | 2006-01-25 22:10:52 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2006-01-25 22:10:52 +0000 |
commit | d12f5c17be85407b7beb8622828ba6bc5903369e (patch) | |
tree | cb86c7b532ba41cd2f914bd2e2636acc09c99fe1 /src | |
parent | 28c258fd24342fe52e85059d68ce69cf9ef5f8cd (diff) |
updated for version 7.0187v7.0187
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/edit.c | 31 | ||||
-rw-r--r-- | src/ex_cmds.h | 44 | ||||
-rw-r--r-- | src/globals.h | 2 | ||||
-rw-r--r-- | src/if_cscope.c | 4 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/misc2.c | 6 | ||||
-rw-r--r-- | src/option.c | 2 | ||||
-rw-r--r-- | src/os_unix.c | 17 | ||||
-rw-r--r-- | src/proto/quickfix.pro | 11 | ||||
-rw-r--r-- | src/quickfix.c | 865 | ||||
-rw-r--r-- | src/screen.c | 9 | ||||
-rw-r--r-- | src/structs.h | 12 | ||||
-rw-r--r-- | src/version.h | 4 |
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; + } |