mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
vim-patch:9.1.1283: quickfix stack is limited to 10 items
Problem: quickfix and location-list stack is limited to 10 items
Solution: add the 'chistory' and 'lhistory' options to configure a
larger quickfix/location list stack
(64-bitman)
closes: vim/vim#16920
88d41ab270
Co-authored-by: 64-bitman <60551350+64-bitman@users.noreply.github.com>
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
This commit is contained in:
@@ -78,6 +78,7 @@ LUA
|
|||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
|
|
||||||
|
• 'chistory' and 'lhistory' set size of the |quickfix-stack|.
|
||||||
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
|
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
|
||||||
• 'pummaxwidth' sets maximum width for the completion popup menu.
|
• 'pummaxwidth' sets maximum width for the completion popup menu.
|
||||||
|
|
||||||
|
@@ -1326,6 +1326,17 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
This option cannot be set from a |modeline| or in the |sandbox|, for
|
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||||
security reasons.
|
security reasons.
|
||||||
|
|
||||||
|
*'chistory'* *'chi'*
|
||||||
|
'chistory' 'chi' number (default 10)
|
||||||
|
global
|
||||||
|
Number of quickfix lists that should be remembered for the quickfix
|
||||||
|
stack. Must be between 1 and 100. If the option is set to a value
|
||||||
|
that is lower than the amount of entries in the quickfix list stack,
|
||||||
|
entries will be removed starting from the oldest one. If the current
|
||||||
|
quickfix list was removed, then the quickfix list at top of the stack
|
||||||
|
(the most recently created) will be used in its place. For additional
|
||||||
|
info, see |quickfix-stack|.
|
||||||
|
|
||||||
*'cindent'* *'cin'* *'nocindent'* *'nocin'*
|
*'cindent'* *'cin'* *'nocindent'* *'nocin'*
|
||||||
'cindent' 'cin' boolean (default off)
|
'cindent' 'cin' boolean (default off)
|
||||||
local to buffer
|
local to buffer
|
||||||
@@ -3780,6 +3791,17 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
temporarily when performing an operation where redrawing may cause
|
temporarily when performing an operation where redrawing may cause
|
||||||
flickering or cause a slowdown.
|
flickering or cause a slowdown.
|
||||||
|
|
||||||
|
*'lhistory'* *'lhi'*
|
||||||
|
'lhistory' 'lhi' number (default 10)
|
||||||
|
local to window
|
||||||
|
Like 'chistory', but for the location list stack associated with the
|
||||||
|
current window. If the option is changed in either the location list
|
||||||
|
window itself or the the window that is associated with the location
|
||||||
|
list stack, the new value will also be applied to the other one. This
|
||||||
|
means this value will always be the same for a given location list
|
||||||
|
window and its corresponding window. See |quickfix-stack| for
|
||||||
|
additional info.
|
||||||
|
|
||||||
*'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'*
|
*'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'*
|
||||||
'linebreak' 'lbr' boolean (default off)
|
'linebreak' 'lbr' boolean (default off)
|
||||||
local to window
|
local to window
|
||||||
|
@@ -31,12 +31,12 @@ From inside Vim an easy way to run a command and handle the output is with the
|
|||||||
The 'errorformat' option should be set to match the error messages from your
|
The 'errorformat' option should be set to match the error messages from your
|
||||||
compiler (see |errorformat| below).
|
compiler (see |errorformat| below).
|
||||||
|
|
||||||
*quickfix-ID*
|
*quickfix-stack* *quickfix-ID*
|
||||||
Each quickfix list has a unique identifier called the quickfix ID and this
|
Each quickfix list has a unique identifier called the quickfix ID and this
|
||||||
number will not change within a Vim session. The |getqflist()| function can be
|
number will not change within a Vim session. The |getqflist()| function can be
|
||||||
used to get the identifier assigned to a list. There is also a quickfix list
|
used to get the identifier assigned to a list. There is also a quickfix list
|
||||||
number which may change whenever more than ten lists are added to a quickfix
|
number which may change whenever more than 'chistory' lists are added to a
|
||||||
stack.
|
quickfix stack.
|
||||||
|
|
||||||
*location-list* *E776*
|
*location-list* *E776*
|
||||||
A location list is a window-local quickfix list. You get one after commands
|
A location list is a window-local quickfix list. You get one after commands
|
||||||
@@ -848,10 +848,12 @@ using these functions are below:
|
|||||||
=============================================================================
|
=============================================================================
|
||||||
3. Using more than one list of errors *quickfix-error-lists*
|
3. Using more than one list of errors *quickfix-error-lists*
|
||||||
|
|
||||||
So far has been assumed that there is only one list of errors. Actually the
|
So far it has been assumed that there is only one list of errors. Actually
|
||||||
ten last used lists are remembered. When starting a new list, the previous
|
there can be multiple used lists that are remembered; see 'chistory' and
|
||||||
ones are automatically kept. Two commands can be used to access older error
|
'lhistory'.
|
||||||
lists. They set one of the existing error lists as the current one.
|
When starting a new list, the previous ones are automatically kept. Two
|
||||||
|
commands can be used to access older error lists. They set one of the
|
||||||
|
existing error lists as the current one.
|
||||||
|
|
||||||
*:colder* *:col* *E380*
|
*:colder* *:col* *E380*
|
||||||
:col[der] [count] Go to older error list. When [count] is given, do
|
:col[der] [count] Go to older error list. When [count] is given, do
|
||||||
|
@@ -651,6 +651,7 @@ Short explanation of each option: *option-list*
|
|||||||
'cdpath' 'cd' list of directories searched with ":cd"
|
'cdpath' 'cd' list of directories searched with ":cd"
|
||||||
'cedit' key used to open the command-line window
|
'cedit' key used to open the command-line window
|
||||||
'charconvert' 'ccv' expression for character encoding conversion
|
'charconvert' 'ccv' expression for character encoding conversion
|
||||||
|
'chistory' 'chi' maximum number of quickfix lists in history
|
||||||
'cindent' 'cin' do C program indenting
|
'cindent' 'cin' do C program indenting
|
||||||
'cinkeys' 'cink' keys that trigger indent when 'cindent' is set
|
'cinkeys' 'cink' keys that trigger indent when 'cindent' is set
|
||||||
'cinoptions' 'cino' how to do indenting when 'cindent' is set
|
'cinoptions' 'cino' how to do indenting when 'cindent' is set
|
||||||
@@ -768,6 +769,7 @@ Short explanation of each option: *option-list*
|
|||||||
'langremap' 'lrm' do apply 'langmap' to mapped characters
|
'langremap' 'lrm' do apply 'langmap' to mapped characters
|
||||||
'laststatus' 'ls' tells when last window has status lines
|
'laststatus' 'ls' tells when last window has status lines
|
||||||
'lazyredraw' 'lz' don't redraw while executing macros
|
'lazyredraw' 'lz' don't redraw while executing macros
|
||||||
|
'lhistory' 'lhi' maximum number of location lists in history
|
||||||
'linebreak' 'lbr' wrap long lines at a blank
|
'linebreak' 'lbr' wrap long lines at a blank
|
||||||
'lines' number of lines in the display
|
'lines' number of lines in the display
|
||||||
'linespace' 'lsp' number of pixel lines to use between characters
|
'linespace' 'lsp' number of pixel lines to use between characters
|
||||||
|
28
runtime/lua/vim/_meta/options.lua
generated
28
runtime/lua/vim/_meta/options.lua
generated
@@ -799,6 +799,20 @@ vim.o.ccv = vim.o.charconvert
|
|||||||
vim.go.charconvert = vim.o.charconvert
|
vim.go.charconvert = vim.o.charconvert
|
||||||
vim.go.ccv = vim.go.charconvert
|
vim.go.ccv = vim.go.charconvert
|
||||||
|
|
||||||
|
--- Number of quickfix lists that should be remembered for the quickfix
|
||||||
|
--- stack. Must be between 1 and 100. If the option is set to a value
|
||||||
|
--- that is lower than the amount of entries in the quickfix list stack,
|
||||||
|
--- entries will be removed starting from the oldest one. If the current
|
||||||
|
--- quickfix list was removed, then the quickfix list at top of the stack
|
||||||
|
--- (the most recently created) will be used in its place. For additional
|
||||||
|
--- info, see `quickfix-stack`.
|
||||||
|
---
|
||||||
|
--- @type integer
|
||||||
|
vim.o.chistory = 10
|
||||||
|
vim.o.chi = vim.o.chistory
|
||||||
|
vim.go.chistory = vim.o.chistory
|
||||||
|
vim.go.chi = vim.go.chistory
|
||||||
|
|
||||||
--- Enables automatic C program indenting. See 'cinkeys' to set the keys
|
--- Enables automatic C program indenting. See 'cinkeys' to set the keys
|
||||||
--- that trigger reindenting in insert mode and 'cinoptions' to set your
|
--- that trigger reindenting in insert mode and 'cinoptions' to set your
|
||||||
--- preferred indent style.
|
--- preferred indent style.
|
||||||
@@ -3730,6 +3744,20 @@ vim.o.lz = vim.o.lazyredraw
|
|||||||
vim.go.lazyredraw = vim.o.lazyredraw
|
vim.go.lazyredraw = vim.o.lazyredraw
|
||||||
vim.go.lz = vim.go.lazyredraw
|
vim.go.lz = vim.go.lazyredraw
|
||||||
|
|
||||||
|
--- Like 'chistory', but for the location list stack associated with the
|
||||||
|
--- current window. If the option is changed in either the location list
|
||||||
|
--- window itself or the the window that is associated with the location
|
||||||
|
--- list stack, the new value will also be applied to the other one. This
|
||||||
|
--- means this value will always be the same for a given location list
|
||||||
|
--- window and its corresponding window. See `quickfix-stack` for
|
||||||
|
--- additional info.
|
||||||
|
---
|
||||||
|
--- @type integer
|
||||||
|
vim.o.lhistory = 10
|
||||||
|
vim.o.lhi = vim.o.lhistory
|
||||||
|
vim.wo.lhistory = vim.o.lhistory
|
||||||
|
vim.wo.lhi = vim.wo.lhistory
|
||||||
|
|
||||||
--- If on, Vim will wrap long lines at a character in 'breakat' rather
|
--- If on, Vim will wrap long lines at a character in 'breakat' rather
|
||||||
--- than at the last character that fits on the screen. Unlike
|
--- than at the last character that fits on the screen. Unlike
|
||||||
--- 'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file,
|
--- 'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file,
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
" These commands create the option window.
|
" These commands create the option window.
|
||||||
"
|
"
|
||||||
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||||
" Last Change: 2025 Mar 28
|
" Last Change: 2025 Apr 06
|
||||||
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||||
|
|
||||||
" If there already is an option window, jump to that one.
|
" If there already is an option window, jump to that one.
|
||||||
@@ -367,6 +367,13 @@ if has("linebreak")
|
|||||||
call append("$", "\t" .. s:local_to_window)
|
call append("$", "\t" .. s:local_to_window)
|
||||||
call <SID>OptionL("nuw")
|
call <SID>OptionL("nuw")
|
||||||
endif
|
endif
|
||||||
|
if has("quickfix")
|
||||||
|
call <SID>AddOption("chistory", gettext("maximum number of quickfix lists that can be stored in history"))
|
||||||
|
call <SID>OptionL("chi")
|
||||||
|
call <SID>AddOption("lhistory", gettext("maximum number of location lists that can be stored in history"))
|
||||||
|
call append("$", "\t" .. s:local_to_window)
|
||||||
|
call <SID>OptionL("lhi")
|
||||||
|
endif
|
||||||
if has("conceal")
|
if has("conceal")
|
||||||
call <SID>AddOption("conceallevel", gettext("controls whether concealable text is hidden"))
|
call <SID>AddOption("conceallevel", gettext("controls whether concealable text is hidden"))
|
||||||
call append("$", "\t" .. s:local_to_window)
|
call append("$", "\t" .. s:local_to_window)
|
||||||
|
@@ -149,6 +149,8 @@ typedef struct {
|
|||||||
#define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth'
|
#define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth'
|
||||||
int wo_pvw;
|
int wo_pvw;
|
||||||
#define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow'
|
#define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow'
|
||||||
|
OptInt wo_lhi;
|
||||||
|
#define w_p_lhi w_onebuf_opt.wo_lhi // 'lhistory'
|
||||||
int wo_rl;
|
int wo_rl;
|
||||||
#define w_p_rl w_onebuf_opt.wo_rl // 'rightleft'
|
#define w_p_rl w_onebuf_opt.wo_rl // 'rightleft'
|
||||||
char *wo_rlc;
|
char *wo_rlc;
|
||||||
|
@@ -238,6 +238,9 @@ void early_init(mparm_T *paramp)
|
|||||||
TIME_MSG("inits 1");
|
TIME_MSG("inits 1");
|
||||||
|
|
||||||
set_lang_var(); // set v:lang and v:ctype
|
set_lang_var(); // set v:lang and v:ctype
|
||||||
|
|
||||||
|
// initialize global quickfix list
|
||||||
|
qf_init_quickfix_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAKE_LIB
|
#ifdef MAKE_LIB
|
||||||
|
@@ -126,6 +126,10 @@ static const char e_number_required_after_equal[]
|
|||||||
= N_("E521: Number required after =");
|
= N_("E521: Number required after =");
|
||||||
static const char e_preview_window_already_exists[]
|
static const char e_preview_window_already_exists[]
|
||||||
= N_("E590: A preview window already exists");
|
= N_("E590: A preview window already exists");
|
||||||
|
static const char e_cannot_have_negative_or_zero_number_of_quickfix[]
|
||||||
|
= N_("E1542: Cannot have a negative or zero number of quickfix/location lists");
|
||||||
|
static const char e_cannot_have_more_than_hundred_quickfix[]
|
||||||
|
= N_("E1543: Cannot have more than a hundred quickfix/location lists");
|
||||||
|
|
||||||
static char *p_term = NULL;
|
static char *p_term = NULL;
|
||||||
static char *p_ttytype = NULL;
|
static char *p_ttytype = NULL;
|
||||||
@@ -2701,6 +2705,23 @@ static const char *did_set_wrap(optset_T *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Process the new 'chistory' or 'lhistory' option value. 'chistory' will
|
||||||
|
/// be used if args->os_varp is the same as p_chi, else 'lhistory'.
|
||||||
|
static const char *did_set_xhistory(optset_T *args)
|
||||||
|
{
|
||||||
|
win_T *win = (win_T *)args->os_win;
|
||||||
|
bool is_p_chi = (OptInt *)args->os_varp == &p_chi;
|
||||||
|
OptInt *arg = is_p_chi ? &p_chi : (OptInt *)args->os_varp;
|
||||||
|
|
||||||
|
if (is_p_chi) {
|
||||||
|
qf_resize_quickfix_stack((int)(*arg));
|
||||||
|
} else {
|
||||||
|
ll_resize_stack(win, (int)(*arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// When 'syntax' is set, load the syntax of that name
|
// When 'syntax' is set, load the syntax of that name
|
||||||
static void do_syntax_autocmd(buf_T *buf, bool value_changed)
|
static void do_syntax_autocmd(buf_T *buf, bool value_changed)
|
||||||
{
|
{
|
||||||
@@ -2942,6 +2963,14 @@ static const char *validate_num_option(OptIndex opt_idx, OptInt *newval, char *e
|
|||||||
return e_invarg;
|
return e_invarg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kOptChistory:
|
||||||
|
case kOptLhistory:
|
||||||
|
if (value < 1) {
|
||||||
|
return e_cannot_have_negative_or_zero_number_of_quickfix;
|
||||||
|
} else if (value > 100) {
|
||||||
|
return e_cannot_have_more_than_hundred_quickfix;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4604,6 +4633,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win)
|
|||||||
return &(win->w_p_wfw);
|
return &(win->w_p_wfw);
|
||||||
case kOptPreviewwindow:
|
case kOptPreviewwindow:
|
||||||
return &(win->w_p_pvw);
|
return &(win->w_p_pvw);
|
||||||
|
case kOptLhistory:
|
||||||
|
return &(win->w_p_lhi);
|
||||||
case kOptRightleft:
|
case kOptRightleft:
|
||||||
return &(win->w_p_rl);
|
return &(win->w_p_rl);
|
||||||
case kOptRightleftcmd:
|
case kOptRightleftcmd:
|
||||||
@@ -4883,6 +4914,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
|
|||||||
to->wo_fdt = copy_option_val(from->wo_fdt);
|
to->wo_fdt = copy_option_val(from->wo_fdt);
|
||||||
to->wo_fmr = copy_option_val(from->wo_fmr);
|
to->wo_fmr = copy_option_val(from->wo_fmr);
|
||||||
to->wo_scl = copy_option_val(from->wo_scl);
|
to->wo_scl = copy_option_val(from->wo_scl);
|
||||||
|
to->wo_lhi = from->wo_lhi;
|
||||||
to->wo_winhl = copy_option_val(from->wo_winhl);
|
to->wo_winhl = copy_option_val(from->wo_winhl);
|
||||||
to->wo_winbl = from->wo_winbl;
|
to->wo_winbl = from->wo_winbl;
|
||||||
to->wo_stc = copy_option_val(from->wo_stc);
|
to->wo_stc = copy_option_val(from->wo_stc);
|
||||||
|
@@ -444,6 +444,7 @@ EXTERN OptInt p_rdt; ///< 'redrawtime'
|
|||||||
EXTERN OptInt p_re; ///< 'regexpengine'
|
EXTERN OptInt p_re; ///< 'regexpengine'
|
||||||
EXTERN OptInt p_report; ///< 'report'
|
EXTERN OptInt p_report; ///< 'report'
|
||||||
EXTERN OptInt p_pvh; ///< 'previewheight'
|
EXTERN OptInt p_pvh; ///< 'previewheight'
|
||||||
|
EXTERN OptInt p_chi; ///< 'chistory'
|
||||||
EXTERN int p_ari; ///< 'allowrevins'
|
EXTERN int p_ari; ///< 'allowrevins'
|
||||||
EXTERN int p_ri; ///< 'revins'
|
EXTERN int p_ri; ///< 'revins'
|
||||||
EXTERN int p_ru; ///< 'ruler'
|
EXTERN int p_ru; ///< 'ruler'
|
||||||
|
@@ -1122,6 +1122,25 @@ local options = {
|
|||||||
tags = { 'E202', 'E214', 'E513' },
|
tags = { 'E202', 'E214', 'E513' },
|
||||||
varname = 'p_ccv',
|
varname = 'p_ccv',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
abbreviation = 'chi',
|
||||||
|
cb = 'did_set_xhistory',
|
||||||
|
defaults = 10,
|
||||||
|
desc = [=[
|
||||||
|
Number of quickfix lists that should be remembered for the quickfix
|
||||||
|
stack. Must be between 1 and 100. If the option is set to a value
|
||||||
|
that is lower than the amount of entries in the quickfix list stack,
|
||||||
|
entries will be removed starting from the oldest one. If the current
|
||||||
|
quickfix list was removed, then the quickfix list at top of the stack
|
||||||
|
(the most recently created) will be used in its place. For additional
|
||||||
|
info, see |quickfix-stack|.
|
||||||
|
]=],
|
||||||
|
full_name = 'chistory',
|
||||||
|
scope = { 'global' },
|
||||||
|
short_desc = N_('number of quickfix lists stored in history'),
|
||||||
|
type = 'number',
|
||||||
|
varname = 'p_chi',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
abbreviation = 'cin',
|
abbreviation = 'cin',
|
||||||
defaults = false,
|
defaults = false,
|
||||||
@@ -5022,6 +5041,24 @@ local options = {
|
|||||||
type = 'boolean',
|
type = 'boolean',
|
||||||
varname = 'p_lz',
|
varname = 'p_lz',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
abbreviation = 'lhi',
|
||||||
|
cb = 'did_set_xhistory',
|
||||||
|
defaults = 10,
|
||||||
|
desc = [=[
|
||||||
|
Like 'chistory', but for the location list stack associated with the
|
||||||
|
current window. If the option is changed in either the location list
|
||||||
|
window itself or the the window that is associated with the location
|
||||||
|
list stack, the new value will also be applied to the other one. This
|
||||||
|
means this value will always be the same for a given location list
|
||||||
|
window and its corresponding window. See |quickfix-stack| for
|
||||||
|
additional info.
|
||||||
|
]=],
|
||||||
|
full_name = 'lhistory',
|
||||||
|
scope = { 'win' },
|
||||||
|
short_desc = N_('number of location lists stored in history'),
|
||||||
|
type = 'number',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
abbreviation = 'lbr',
|
abbreviation = 'lbr',
|
||||||
defaults = false,
|
defaults = false,
|
||||||
|
@@ -101,7 +101,6 @@ struct qfline_S {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// There is a stack of error lists.
|
// There is a stack of error lists.
|
||||||
#define LISTCOUNT 10
|
|
||||||
#define INVALID_QFIDX (-1)
|
#define INVALID_QFIDX (-1)
|
||||||
#define INVALID_QFBUFNR (0)
|
#define INVALID_QFBUFNR (0)
|
||||||
|
|
||||||
@@ -153,12 +152,14 @@ struct qf_info_S {
|
|||||||
int qf_refcount;
|
int qf_refcount;
|
||||||
int qf_listcount; // current number of lists
|
int qf_listcount; // current number of lists
|
||||||
int qf_curlist; // current error list
|
int qf_curlist; // current error list
|
||||||
qf_list_T qf_lists[LISTCOUNT];
|
int qf_maxcount; // maximum number of lists
|
||||||
|
qf_list_T *qf_lists;
|
||||||
qfltype_T qfl_type; // type of list
|
qfltype_T qfl_type; // type of list
|
||||||
int qf_bufnr; // quickfix window buffer number
|
int qf_bufnr; // quickfix window buffer number
|
||||||
};
|
};
|
||||||
|
|
||||||
static qf_info_T ql_info; // global quickfix list
|
static qf_info_T ql_info_actual; // global quickfix list
|
||||||
|
static qf_info_T *ql_info; // points to ql_info_actual after allocation
|
||||||
static unsigned last_qf_id = 0; // Last Used quickfix list id
|
static unsigned last_qf_id = 0; // Last Used quickfix list id
|
||||||
|
|
||||||
#define FMT_PATTERNS 14 // maximum number of % recognized
|
#define FMT_PATTERNS 14 // maximum number of % recognized
|
||||||
@@ -382,7 +383,8 @@ static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T
|
|||||||
int qf_init(win_T *wp, const char *restrict efile, char *restrict errorformat, int newlist,
|
int qf_init(win_T *wp, const char *restrict efile, char *restrict errorformat, int newlist,
|
||||||
const char *restrict qf_title, char *restrict enc)
|
const char *restrict qf_title, char *restrict enc)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = wp == NULL ? &ql_info : ll_get_or_alloc_list(wp);
|
qf_info_T *qi = wp == NULL ? ql_info : ll_get_or_alloc_list(wp);
|
||||||
|
assert(qi != NULL);
|
||||||
|
|
||||||
return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat,
|
return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat,
|
||||||
newlist, 0, 0, qf_title, enc);
|
newlist, 0, 0, qf_title, enc);
|
||||||
@@ -1260,6 +1262,31 @@ static qf_list_T *qf_get_curlist(qf_info_T *qi)
|
|||||||
return qf_get_list(qi, qi->qf_curlist);
|
return qf_get_list(qi, qi->qf_curlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pop a quickfix list from the quickfix/location list stack
|
||||||
|
/// Automatically adjust qf_curlist so that it stays pointed
|
||||||
|
/// to the same list, unless it is deleted, if so then use the
|
||||||
|
/// newest created list instead. qf_listcount will be set correctly.
|
||||||
|
/// The above will only happen if <adjust> is true.
|
||||||
|
static void qf_pop_stack(qf_info_T *qi, bool adjust)
|
||||||
|
{
|
||||||
|
qf_free(&qi->qf_lists[0]);
|
||||||
|
for (int i = 1; i < qi->qf_listcount; i++) {
|
||||||
|
qi->qf_lists[i - 1] = qi->qf_lists[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill with zeroes now unused list at the top
|
||||||
|
memset(qi->qf_lists + qi->qf_listcount - 1, 0, sizeof(*qi->qf_lists));
|
||||||
|
|
||||||
|
if (adjust) {
|
||||||
|
qi->qf_listcount--;
|
||||||
|
if (qi->qf_curlist == 0) {
|
||||||
|
qi->qf_curlist = qi->qf_listcount - 1;
|
||||||
|
} else {
|
||||||
|
qi->qf_curlist--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Prepare for adding a new quickfix list. If the current list is in the
|
/// Prepare for adding a new quickfix list. If the current list is in the
|
||||||
/// middle of the stack, then all the following lists are freed and then
|
/// middle of the stack, then all the following lists are freed and then
|
||||||
/// the new list is added.
|
/// the new list is added.
|
||||||
@@ -1274,15 +1301,13 @@ static void qf_new_list(qf_info_T *qi, const char *qf_title)
|
|||||||
|
|
||||||
// When the stack is full, remove to oldest entry
|
// When the stack is full, remove to oldest entry
|
||||||
// Otherwise, add a new entry.
|
// Otherwise, add a new entry.
|
||||||
if (qi->qf_listcount == LISTCOUNT) {
|
if (qi->qf_listcount == qi->qf_maxcount) {
|
||||||
qf_free(&qi->qf_lists[0]);
|
qf_pop_stack(qi, false);
|
||||||
for (int i = 1; i < LISTCOUNT; i++) {
|
qi->qf_curlist = qi->qf_listcount - 1; // point to new empty list
|
||||||
qi->qf_lists[i - 1] = qi->qf_lists[i];
|
|
||||||
}
|
|
||||||
qi->qf_curlist = LISTCOUNT - 1;
|
|
||||||
} else {
|
} else {
|
||||||
qi->qf_curlist = qi->qf_listcount++;
|
qi->qf_curlist = qi->qf_listcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
qf_list_T *qfl = qf_get_curlist(qi);
|
qf_list_T *qfl = qf_get_curlist(qi);
|
||||||
CLEAR_POINTER(qfl);
|
CLEAR_POINTER(qfl);
|
||||||
qf_store_title(qfl, qf_title);
|
qf_store_title(qfl, qf_title);
|
||||||
@@ -1731,7 +1756,8 @@ static void locstack_queue_delreq(qf_info_T *qi)
|
|||||||
/// Return the global quickfix stack window buffer number.
|
/// Return the global quickfix stack window buffer number.
|
||||||
int qf_stack_get_bufnr(void)
|
int qf_stack_get_bufnr(void)
|
||||||
{
|
{
|
||||||
return ql_info.qf_bufnr;
|
assert(ql_info != NULL);
|
||||||
|
return ql_info->qf_bufnr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wipe the quickfix window buffer (if present) for the specified
|
/// Wipe the quickfix window buffer (if present) for the specified
|
||||||
@@ -1766,6 +1792,23 @@ static void wipe_qf_buffer(qf_info_T *qi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Free all lists in the stack (not including the stack)
|
||||||
|
static void qf_free_list_stack_items(qf_info_T *qi)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < qi->qf_listcount; i++) {
|
||||||
|
qf_free(qf_get_list(qi, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free a qf_info_T struct completely
|
||||||
|
static void qf_free_lists(qf_info_T *qi)
|
||||||
|
{
|
||||||
|
qf_free_list_stack_items(qi);
|
||||||
|
|
||||||
|
xfree(qi->qf_lists);
|
||||||
|
xfree(qi);
|
||||||
|
}
|
||||||
|
|
||||||
/// Free a location list stack
|
/// Free a location list stack
|
||||||
static void ll_free_all(qf_info_T **pqi)
|
static void ll_free_all(qf_info_T **pqi)
|
||||||
{
|
{
|
||||||
@@ -1788,26 +1831,21 @@ static void ll_free_all(qf_info_T **pqi)
|
|||||||
// If the quickfix window buffer is loaded, then wipe it
|
// If the quickfix window buffer is loaded, then wipe it
|
||||||
wipe_qf_buffer(qi);
|
wipe_qf_buffer(qi);
|
||||||
|
|
||||||
for (int i = 0; i < qi->qf_listcount; i++) {
|
qf_free_lists(qi);
|
||||||
qf_free(qf_get_list(qi, i));
|
|
||||||
}
|
|
||||||
xfree(qi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free all the quickfix/location lists in the stack.
|
/// Free all the quickfix/location lists in the stack.
|
||||||
void qf_free_all(win_T *wp)
|
void qf_free_all(win_T *wp)
|
||||||
{
|
{
|
||||||
|
qf_info_T *qi = ql_info;
|
||||||
|
|
||||||
if (wp != NULL) {
|
if (wp != NULL) {
|
||||||
// location list
|
// location list
|
||||||
ll_free_all(&wp->w_llist);
|
ll_free_all(&wp->w_llist);
|
||||||
ll_free_all(&wp->w_llist_ref);
|
ll_free_all(&wp->w_llist_ref);
|
||||||
} else {
|
} else if (qi != NULL) {
|
||||||
// quickfix list
|
qf_free_list_stack_items(qi); // quickfix list
|
||||||
qf_info_T *qi = &ql_info;
|
|
||||||
for (int i = 0; i < qi->qf_listcount; i++) {
|
|
||||||
qf_free(qf_get_list(qi, i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1963,18 +2001,116 @@ static int qf_add_entry(qf_list_T *qfl, char *dir, char *fname, char *module, in
|
|||||||
return QF_OK;
|
return QF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a new quickfix/location list stack
|
/// Resize global quickfix stack to be able to hold n amount of lists.
|
||||||
static qf_info_T *qf_alloc_stack(qfltype_T qfltype)
|
void qf_resize_quickfix_stack(int n)
|
||||||
|
{
|
||||||
|
assert(ql_info != NULL);
|
||||||
|
qf_resize_stack(ql_info, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resize location list stack for window 'wp' to be able to hold n amount of lists.
|
||||||
|
void ll_resize_stack(win_T *wp, int n)
|
||||||
|
{
|
||||||
|
// check if current window is a location list window;
|
||||||
|
// if so then sync its 'lhistory' to the parent window or vice versa
|
||||||
|
if (IS_LL_WINDOW(curwin)) {
|
||||||
|
qf_sync_llw_to_win(wp);
|
||||||
|
} else {
|
||||||
|
qf_sync_win_to_llw(wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
qf_info_T *qi = ll_get_or_alloc_list(wp);
|
||||||
|
qf_resize_stack(qi, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resize quickfix stack to be able to hold n amount of quickfix lists.
|
||||||
|
static void qf_resize_stack(qf_info_T *qi, int n)
|
||||||
|
{
|
||||||
|
int amount_to_rm = 0;
|
||||||
|
size_t lsz = sizeof(*qi->qf_lists);
|
||||||
|
|
||||||
|
if (n == qi->qf_maxcount) {
|
||||||
|
return;
|
||||||
|
} else if (n < qi->qf_maxcount && n < qi->qf_listcount) {
|
||||||
|
// We have too many lists to store them all in the new stack,
|
||||||
|
// pop lists until we can fit them all in the newly resized stack
|
||||||
|
amount_to_rm = qi->qf_listcount - n;
|
||||||
|
|
||||||
|
for (int i = 0; i < amount_to_rm; i++) {
|
||||||
|
qf_pop_stack(qi, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qf_list_T *new = xrealloc(qi->qf_lists, lsz * (size_t)n);
|
||||||
|
|
||||||
|
// fill with zeroes any newly allocated memory
|
||||||
|
if (n > qi->qf_maxcount) {
|
||||||
|
memset(new + qi->qf_maxcount, 0, lsz * (size_t)(n - qi->qf_maxcount));
|
||||||
|
}
|
||||||
|
|
||||||
|
qi->qf_lists = new;
|
||||||
|
qi->qf_maxcount = n;
|
||||||
|
|
||||||
|
qf_update_buffer(qi, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize global quickfix list, should only be called once.
|
||||||
|
void qf_init_quickfix_stack(void)
|
||||||
|
{
|
||||||
|
ql_info_actual.qf_lists = qf_alloc_list_stack((int)p_chi);
|
||||||
|
ql_info = &ql_info_actual;
|
||||||
|
ql_info->qfl_type = QFLT_QUICKFIX;
|
||||||
|
ql_info->qf_maxcount = (int)p_chi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sync a location list window's 'lhistory' value to the parent window
|
||||||
|
static void qf_sync_llw_to_win(win_T *llw)
|
||||||
|
{
|
||||||
|
win_T *wp = qf_find_win_with_loclist(llw->w_llist_ref);
|
||||||
|
|
||||||
|
if (wp != NULL) {
|
||||||
|
wp->w_p_lhi = llw->w_p_lhi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sync a window's 'lhistory' value to its location list window, if any
|
||||||
|
static void qf_sync_win_to_llw(win_T *pwp)
|
||||||
|
{
|
||||||
|
qf_info_T *llw = pwp->w_llist;
|
||||||
|
|
||||||
|
if (llw != NULL) {
|
||||||
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
|
if (wp->w_llist_ref == llw && bt_quickfix(wp->w_buffer)) {
|
||||||
|
wp->w_p_lhi = pwp->w_p_lhi;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Allocate a new quickfix/location list stack that is able to hold
|
||||||
|
/// up to n amount of lists
|
||||||
|
static qf_info_T *qf_alloc_stack(qfltype_T qfltype, int n)
|
||||||
FUNC_ATTR_NONNULL_RET
|
FUNC_ATTR_NONNULL_RET
|
||||||
{
|
{
|
||||||
qf_info_T *qi = xcalloc(1, sizeof(qf_info_T));
|
qf_info_T *qi = xcalloc(1, sizeof(qf_info_T));
|
||||||
qi->qf_refcount++;
|
qi->qf_refcount++;
|
||||||
qi->qfl_type = qfltype;
|
qi->qfl_type = qfltype;
|
||||||
qi->qf_bufnr = INVALID_QFBUFNR;
|
qi->qf_bufnr = INVALID_QFBUFNR;
|
||||||
|
qi->qf_lists = qf_alloc_list_stack(n);
|
||||||
|
qi->qf_maxcount = n;
|
||||||
|
|
||||||
return qi;
|
return qi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate memory for qf_lists member of qf_info_T struct.
|
||||||
|
/// 'actual' is the actual amount of lists that have been allocated for
|
||||||
|
static qf_list_T *qf_alloc_list_stack(int n)
|
||||||
|
FUNC_ATTR_NONNULL_RET
|
||||||
|
{
|
||||||
|
return xcalloc((size_t)n, sizeof(qf_list_T));
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the location list stack for window 'wp'.
|
/// Return the location list stack for window 'wp'.
|
||||||
/// If not present, allocate a location list stack
|
/// If not present, allocate a location list stack
|
||||||
static qf_info_T *ll_get_or_alloc_list(win_T *wp)
|
static qf_info_T *ll_get_or_alloc_list(win_T *wp)
|
||||||
@@ -1990,8 +2126,10 @@ static qf_info_T *ll_get_or_alloc_list(win_T *wp)
|
|||||||
ll_free_all(&wp->w_llist_ref);
|
ll_free_all(&wp->w_llist_ref);
|
||||||
|
|
||||||
if (wp->w_llist == NULL) {
|
if (wp->w_llist == NULL) {
|
||||||
wp->w_llist = qf_alloc_stack(QFLT_LOCATION); // new location list
|
// new location list
|
||||||
|
wp->w_llist = qf_alloc_stack(QFLT_LOCATION, (int)wp->w_p_lhi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wp->w_llist;
|
return wp->w_llist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2001,7 +2139,8 @@ static qf_info_T *ll_get_or_alloc_list(win_T *wp)
|
|||||||
/// message if 'print_emsg' is true.
|
/// message if 'print_emsg' is true.
|
||||||
static qf_info_T *qf_cmd_get_stack(exarg_T *eap, bool print_emsg)
|
static qf_info_T *qf_cmd_get_stack(exarg_T *eap, bool print_emsg)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
|
|
||||||
if (is_loclist_cmd(eap->cmdidx)) {
|
if (is_loclist_cmd(eap->cmdidx)) {
|
||||||
qi = GET_LOC_LIST(curwin);
|
qi = GET_LOC_LIST(curwin);
|
||||||
@@ -2023,7 +2162,7 @@ static qf_info_T *qf_cmd_get_stack(exarg_T *eap, bool print_emsg)
|
|||||||
static qf_info_T *qf_cmd_get_or_alloc_stack(const exarg_T *eap, win_T **pwinp)
|
static qf_info_T *qf_cmd_get_or_alloc_stack(const exarg_T *eap, win_T **pwinp)
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
|
||||||
if (is_loclist_cmd(eap->cmdidx)) {
|
if (is_loclist_cmd(eap->cmdidx)) {
|
||||||
qi = ll_get_or_alloc_list(curwin);
|
qi = ll_get_or_alloc_list(curwin);
|
||||||
@@ -2136,8 +2275,10 @@ void copy_loclist_stack(win_T *from, win_T *to)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate a new location list
|
// allocate a new location list, set size of stack to 'from' window value
|
||||||
to->w_llist = qf_alloc_stack(QFLT_LOCATION);
|
to->w_llist = qf_alloc_stack(QFLT_LOCATION, (int)from->w_p_lhi);
|
||||||
|
// set 'to' lhi to reflect new value
|
||||||
|
to->w_p_lhi = to->w_llist->qf_maxcount;
|
||||||
|
|
||||||
to->w_llist->qf_listcount = qi->qf_listcount;
|
to->w_llist->qf_listcount = qi->qf_listcount;
|
||||||
|
|
||||||
@@ -2354,17 +2495,17 @@ static char *qf_guess_filepath(qf_list_T *qfl, char *filename)
|
|||||||
/// Returns true, if a quickfix/location list with the given identifier exists.
|
/// Returns true, if a quickfix/location list with the given identifier exists.
|
||||||
static bool qflist_valid(win_T *wp, unsigned qf_id)
|
static bool qflist_valid(win_T *wp, unsigned qf_id)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
|
||||||
if (wp) {
|
if (wp) {
|
||||||
if (!win_valid(wp)) {
|
if (!win_valid(wp)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qi = GET_LOC_LIST(wp); // Location list
|
qi = GET_LOC_LIST(wp); // Location list
|
||||||
|
}
|
||||||
if (!qi) {
|
if (!qi) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < qi->qf_listcount; i++) {
|
for (int i = 0; i < qi->qf_listcount; i++) {
|
||||||
if (qi->qf_lists[i].qf_id == qf_id) {
|
if (qi->qf_lists[i].qf_id == qf_id) {
|
||||||
@@ -3077,7 +3218,8 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
|
|||||||
const bool old_KeyTyped = KeyTyped; // getting file may reset it
|
const bool old_KeyTyped = KeyTyped; // getting file may reset it
|
||||||
|
|
||||||
if (qi == NULL) {
|
if (qi == NULL) {
|
||||||
qi = &ql_info;
|
assert(ql_info != NULL);
|
||||||
|
qi = ql_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) {
|
if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) {
|
||||||
@@ -3518,7 +3660,8 @@ static void qf_free(qf_list_T *qfl)
|
|||||||
bool qf_mark_adjust(buf_T *buf, win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount,
|
bool qf_mark_adjust(buf_T *buf, win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount,
|
||||||
linenr_T amount_after)
|
linenr_T amount_after)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
|
int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
|
||||||
|
|
||||||
if (!(buf->b_has_qf_entry & buf_has_flag)) {
|
if (!(buf->b_has_qf_entry & buf_has_flag)) {
|
||||||
@@ -3607,7 +3750,8 @@ static char *qf_types(int c, int nr)
|
|||||||
// When "split" is true: Open the entry/result under the cursor in a new window.
|
// When "split" is true: Open the entry/result under the cursor in a new window.
|
||||||
void qf_view_result(bool split)
|
void qf_view_result(bool split)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
|
|
||||||
if (IS_LL_WINDOW(curwin)) {
|
if (IS_LL_WINDOW(curwin)) {
|
||||||
qi = GET_LOC_LIST(curwin);
|
qi = GET_LOC_LIST(curwin);
|
||||||
@@ -3883,7 +4027,8 @@ void ex_cbottom(exarg_T *eap)
|
|||||||
// window).
|
// window).
|
||||||
linenr_T qf_current_entry(win_T *wp)
|
linenr_T qf_current_entry(win_T *wp)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
|
|
||||||
if (IS_LL_WINDOW(wp)) {
|
if (IS_LL_WINDOW(wp)) {
|
||||||
// In the location list window, use the referenced location list
|
// In the location list window, use the referenced location list
|
||||||
@@ -4459,7 +4604,8 @@ void ex_make(exarg_T *eap)
|
|||||||
|
|
||||||
int res = qf_init(wp, fname, errorformat, newlist, qf_cmdtitle(*eap->cmdlinep), enc);
|
int res = qf_init(wp, fname, errorformat, newlist, qf_cmdtitle(*eap->cmdlinep), enc);
|
||||||
|
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
if (wp != NULL) {
|
if (wp != NULL) {
|
||||||
qi = GET_LOC_LIST(wp);
|
qi = GET_LOC_LIST(wp);
|
||||||
if (qi == NULL) {
|
if (qi == NULL) {
|
||||||
@@ -5146,7 +5292,8 @@ static char *cfile_get_auname(cmdidx_T cmdidx)
|
|||||||
void ex_cfile(exarg_T *eap)
|
void ex_cfile(exarg_T *eap)
|
||||||
{
|
{
|
||||||
win_T *wp = NULL;
|
win_T *wp = NULL;
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
char *au_name = NULL;
|
char *au_name = NULL;
|
||||||
|
|
||||||
au_name = cfile_get_auname(eap->cmdidx);
|
au_name = cfile_get_auname(eap->cmdidx);
|
||||||
@@ -5935,14 +6082,14 @@ static int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, int eidx, lis
|
|||||||
qf_info_T *qi = qi_arg;
|
qf_info_T *qi = qi_arg;
|
||||||
|
|
||||||
if (qi == NULL) {
|
if (qi == NULL) {
|
||||||
qi = &ql_info;
|
qi = ql_info;
|
||||||
if (wp != NULL) {
|
if (wp != NULL) {
|
||||||
qi = GET_LOC_LIST(wp);
|
qi = GET_LOC_LIST(wp);
|
||||||
|
}
|
||||||
if (qi == NULL) {
|
if (qi == NULL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (eidx < 0) {
|
if (eidx < 0) {
|
||||||
return OK;
|
return OK;
|
||||||
@@ -6018,14 +6165,15 @@ static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_T *l = tv_list_alloc(kListLenMayKnow);
|
list_T *l = tv_list_alloc(kListLenMayKnow);
|
||||||
qf_info_T *const qi = qf_alloc_stack(QFLT_INTERNAL);
|
qf_info_T *const qi = qf_alloc_stack(QFLT_INTERNAL, 1);
|
||||||
|
|
||||||
if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
|
if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
|
||||||
true, 0, 0, NULL, NULL) > 0) {
|
true, 0, 0, NULL, NULL) > 0) {
|
||||||
get_errorlist(qi, NULL, 0, 0, l);
|
get_errorlist(qi, NULL, 0, 0, l);
|
||||||
qf_free(&qi->qf_lists[0]);
|
qf_free(&qi->qf_lists[0]);
|
||||||
}
|
}
|
||||||
xfree(qi);
|
|
||||||
|
qf_free_lists(qi);
|
||||||
|
|
||||||
tv_dict_add_list(retdict, S_LEN("items"), l);
|
tv_dict_add_list(retdict, S_LEN("items"), l);
|
||||||
status = OK;
|
status = OK;
|
||||||
@@ -6302,7 +6450,8 @@ static int qf_getprop_qftf(qf_list_T *qfl, dict_T *retdict)
|
|||||||
/// then current list is used. Otherwise the specified list is used.
|
/// then current list is used. Otherwise the specified list is used.
|
||||||
static int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
static int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
dictitem_T *di = NULL;
|
dictitem_T *di = NULL;
|
||||||
int status = OK;
|
int status = OK;
|
||||||
int qf_idx = INVALID_QFIDX;
|
int qf_idx = INVALID_QFIDX;
|
||||||
@@ -6880,7 +7029,7 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi)
|
|||||||
} else if (qfwin != NULL) {
|
} else if (qfwin != NULL) {
|
||||||
// If the location list window is open, then create a new empty location
|
// If the location list window is open, then create a new empty location
|
||||||
// list
|
// list
|
||||||
qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION);
|
qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION, (int)wp->w_p_lhi);
|
||||||
new_ll->qf_bufnr = qfwin->w_buffer->b_fnum;
|
new_ll->qf_bufnr = qfwin->w_buffer->b_fnum;
|
||||||
|
|
||||||
// first free the list reference in the location list window
|
// first free the list reference in the location list window
|
||||||
@@ -6900,7 +7049,8 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi)
|
|||||||
/// When "what" is not NULL then only set some properties.
|
/// When "what" is not NULL then only set some properties.
|
||||||
int set_errorlist(win_T *wp, list_T *list, int action, char *title, dict_T *what)
|
int set_errorlist(win_T *wp, list_T *list, int action, char *title, dict_T *what)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
|
|
||||||
if (wp != NULL) {
|
if (wp != NULL) {
|
||||||
qi = ll_get_or_alloc_list(wp);
|
qi = ll_get_or_alloc_list(wp);
|
||||||
@@ -6938,7 +7088,7 @@ int set_errorlist(win_T *wp, list_T *list, int action, char *title, dict_T *what
|
|||||||
static bool mark_quickfix_user_data(qf_info_T *qi, int copyID)
|
static bool mark_quickfix_user_data(qf_info_T *qi, int copyID)
|
||||||
{
|
{
|
||||||
bool abort = false;
|
bool abort = false;
|
||||||
for (int i = 0; i < LISTCOUNT && !abort; i++) {
|
for (int i = 0; i < qi->qf_maxcount && !abort; i++) {
|
||||||
qf_list_T *qfl = &qi->qf_lists[i];
|
qf_list_T *qfl = &qi->qf_lists[i];
|
||||||
if (!qfl->qf_has_user_data) {
|
if (!qfl->qf_has_user_data) {
|
||||||
continue;
|
continue;
|
||||||
@@ -6962,7 +7112,7 @@ static bool mark_quickfix_ctx(qf_info_T *qi, int copyID)
|
|||||||
{
|
{
|
||||||
bool abort = false;
|
bool abort = false;
|
||||||
|
|
||||||
for (int i = 0; i < LISTCOUNT && !abort; i++) {
|
for (int i = 0; i < qi->qf_maxcount && !abort; i++) {
|
||||||
typval_T *ctx = qi->qf_lists[i].qf_ctx;
|
typval_T *ctx = qi->qf_lists[i].qf_ctx;
|
||||||
if (ctx != NULL && ctx->v_type != VAR_NUMBER
|
if (ctx != NULL && ctx->v_type != VAR_NUMBER
|
||||||
&& ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT) {
|
&& ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT) {
|
||||||
@@ -6980,8 +7130,9 @@ static bool mark_quickfix_ctx(qf_info_T *qi, int copyID)
|
|||||||
/// "in use". So that garbage collection doesn't free the context.
|
/// "in use". So that garbage collection doesn't free the context.
|
||||||
bool set_ref_in_quickfix(int copyID)
|
bool set_ref_in_quickfix(int copyID)
|
||||||
{
|
{
|
||||||
if (mark_quickfix_ctx(&ql_info, copyID)
|
assert(ql_info != NULL);
|
||||||
|| mark_quickfix_user_data(&ql_info, copyID)
|
if (mark_quickfix_ctx(ql_info, copyID)
|
||||||
|
|| mark_quickfix_user_data(ql_info, copyID)
|
||||||
|| set_ref_in_callback(&qftf_cb, copyID, NULL, NULL)) {
|
|| set_ref_in_callback(&qftf_cb, copyID, NULL, NULL)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -7229,7 +7380,7 @@ static qf_info_T *hgr_get_ll(bool *new_ll)
|
|||||||
qf_info_T *qi = wp == NULL ? NULL : wp->w_llist;
|
qf_info_T *qi = wp == NULL ? NULL : wp->w_llist;
|
||||||
if (qi == NULL) {
|
if (qi == NULL) {
|
||||||
// Allocate a new location list for help text matches
|
// Allocate a new location list for help text matches
|
||||||
qi = qf_alloc_stack(QFLT_LOCATION);
|
qi = qf_alloc_stack(QFLT_LOCATION, 1);
|
||||||
*new_ll = true;
|
*new_ll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7340,7 +7491,8 @@ static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char
|
|||||||
// ":helpgrep {pattern}"
|
// ":helpgrep {pattern}"
|
||||||
void ex_helpgrep(exarg_T *eap)
|
void ex_helpgrep(exarg_T *eap)
|
||||||
{
|
{
|
||||||
qf_info_T *qi = &ql_info;
|
qf_info_T *qi = ql_info;
|
||||||
|
assert(qi != NULL);
|
||||||
char *au_name = NULL;
|
char *au_name = NULL;
|
||||||
|
|
||||||
switch (eap->cmdidx) {
|
switch (eap->cmdidx) {
|
||||||
|
@@ -106,6 +106,7 @@ let test_values = {
|
|||||||
\ []],
|
\ []],
|
||||||
\
|
\
|
||||||
"\ number options
|
"\ number options
|
||||||
|
\ 'chistory': [[1, 2, 10, 50], [1000, -1]],
|
||||||
\ 'cmdheight': [[0, 1, 2, 10], [-1]],
|
\ 'cmdheight': [[0, 1, 2, 10], [-1]],
|
||||||
\ 'cmdwinheight': [[1, 2, 10], [-1, 0]],
|
\ 'cmdwinheight': [[1, 2, 10], [-1, 0]],
|
||||||
\ 'columns': [[12, 80, 10000], [-1, 0, 10]],
|
\ 'columns': [[12, 80, 10000], [-1, 0, 10]],
|
||||||
@@ -116,6 +117,7 @@ let test_values = {
|
|||||||
"\ 'iminsert': [[0, 1, 2], [-1, 3, 999]],
|
"\ 'iminsert': [[0, 1, 2], [-1, 3, 999]],
|
||||||
"\ 'imsearch': [[-1, 0, 1, 2], [-2, 3, 999]],
|
"\ 'imsearch': [[-1, 0, 1, 2], [-2, 3, 999]],
|
||||||
"\ 'imstyle': [[0, 1], [-1, 2, 999]],
|
"\ 'imstyle': [[0, 1], [-1, 2, 999]],
|
||||||
|
\ 'lhistory': [[1, 2, 10, 50], [1000, -1]],
|
||||||
\ 'lines': [[2, 24, 1000], [-1, 0, 1]],
|
\ 'lines': [[2, 24, 1000], [-1, 0, 1]],
|
||||||
\ 'linespace': [[-1, 0, 2, 4, 999], ['']],
|
\ 'linespace': [[-1, 0, 2, 4, 999], ['']],
|
||||||
\ 'numberwidth': [[1, 4, 8, 10, 11, 20], [-1, 0, 21]],
|
\ 'numberwidth': [[1, 4, 8, 10, 11, 20], [-1, 0, 21]],
|
||||||
|
@@ -43,6 +43,8 @@ func s:setup_commands(cchar)
|
|||||||
command! -count=1 -nargs=0 Xabove <mods><count>cabove
|
command! -count=1 -nargs=0 Xabove <mods><count>cabove
|
||||||
command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
|
command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
|
||||||
command! -count=1 -nargs=0 Xafter <mods><count>cafter
|
command! -count=1 -nargs=0 Xafter <mods><count>cafter
|
||||||
|
command! -nargs=1 Xsethist <mods>set chistory=<args>
|
||||||
|
command! -nargs=0 Xsethistdefault <mods>set chistory&
|
||||||
let g:Xgetlist = function('getqflist')
|
let g:Xgetlist = function('getqflist')
|
||||||
let g:Xsetlist = function('setqflist')
|
let g:Xsetlist = function('setqflist')
|
||||||
call setqflist([], 'f')
|
call setqflist([], 'f')
|
||||||
@@ -80,6 +82,9 @@ func s:setup_commands(cchar)
|
|||||||
command! -count=1 -nargs=0 Xabove <mods><count>labove
|
command! -count=1 -nargs=0 Xabove <mods><count>labove
|
||||||
command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
|
command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
|
||||||
command! -count=1 -nargs=0 Xafter <mods><count>lafter
|
command! -count=1 -nargs=0 Xafter <mods><count>lafter
|
||||||
|
command! -nargs=1 Xsethist <mods>set lhistory=<args>
|
||||||
|
command! -nargs=1 Xsetlocalhist <mods>setlocal lhistory=<args>
|
||||||
|
command! -nargs=0 Xsethistdefault <mods>set lhistory&
|
||||||
let g:Xgetlist = function('getloclist', [0])
|
let g:Xgetlist = function('getloclist', [0])
|
||||||
let g:Xsetlist = function('setloclist', [0])
|
let g:Xsetlist = function('setloclist', [0])
|
||||||
call setloclist(0, [], 'f')
|
call setloclist(0, [], 'f')
|
||||||
@@ -6596,6 +6601,174 @@ func Test_hardlink_fname()
|
|||||||
call Xtest_hardlink_fname('l')
|
call Xtest_hardlink_fname('l')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for checking if correct number of tests are deleted
|
||||||
|
" and current list stays the same after setting Xhistory
|
||||||
|
" to a smaller number. Do roughly the same for growing the stack.
|
||||||
|
func Xtest_resize_list_stack(cchar)
|
||||||
|
call s:setup_commands(a:cchar)
|
||||||
|
Xsethist 100
|
||||||
|
|
||||||
|
for i in range(1, 100)
|
||||||
|
Xexpr string(i)
|
||||||
|
endfor
|
||||||
|
Xopen
|
||||||
|
call assert_equal(g:Xgetlist({'nr': '$'}).nr, 100)
|
||||||
|
call assert_equal("|| 100", getline(1))
|
||||||
|
Xsethist 8
|
||||||
|
call assert_equal("|| 100", getline(1))
|
||||||
|
Xolder 5
|
||||||
|
call assert_equal("|| 95", getline(1))
|
||||||
|
Xsethist 6
|
||||||
|
call assert_equal("|| 95", getline(1))
|
||||||
|
Xsethist 1
|
||||||
|
call assert_equal("|| 100", getline(1))
|
||||||
|
|
||||||
|
" grow array again
|
||||||
|
Xsethist 100
|
||||||
|
for i in range(1, 99)
|
||||||
|
Xexpr string(i)
|
||||||
|
endfor
|
||||||
|
call assert_equal("|| 99", getline(1))
|
||||||
|
Xolder 99
|
||||||
|
call assert_equal("|| 100", getline(1))
|
||||||
|
|
||||||
|
Xsethistdefault
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_resize_list_stack()
|
||||||
|
call Xtest_resize_list_stack('c')
|
||||||
|
call Xtest_resize_list_stack('l')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Test to check if order of lists is from
|
||||||
|
" oldest at the bottom to newest at the top
|
||||||
|
func Xtest_Xhistory_check_order(cchar)
|
||||||
|
|
||||||
|
Xsethist 100
|
||||||
|
|
||||||
|
for i in range(1, 100)
|
||||||
|
Xexpr string(i)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
Xopen
|
||||||
|
for i in range(100, 1, -1)
|
||||||
|
let l:ret = assert_equal("|| " .. i, getline(1))
|
||||||
|
|
||||||
|
if ret == 1 || i == 1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
Xolder
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for i in range(1, 50)
|
||||||
|
Xexpr string(i)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for i in range(50, 1, -1)
|
||||||
|
let l:ret = assert_equal("|| " .. i, getline(1))
|
||||||
|
|
||||||
|
if ret == 1 || i == 50
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
Xolder
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for i in range(50, 1, -1)
|
||||||
|
let l:ret = assert_equal("|| " .. i, getline(1))
|
||||||
|
|
||||||
|
if ret == 1 || i == 50
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
Xolder
|
||||||
|
endfor
|
||||||
|
|
||||||
|
Xsethistdefault
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_set_history_to_check_order()
|
||||||
|
call Xtest_Xhistory_check_order('c')
|
||||||
|
call Xtest_Xhistory_check_order('l')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Check if 'lhistory' is the same between the location list window
|
||||||
|
" and associated normal window
|
||||||
|
func Test_win_and_loc_synced()
|
||||||
|
new
|
||||||
|
set lhistory=2
|
||||||
|
lexpr "Text"
|
||||||
|
lopen
|
||||||
|
|
||||||
|
" check if lhistory is synced when modified inside the
|
||||||
|
" location list window
|
||||||
|
setlocal lhistory=1
|
||||||
|
wincmd k
|
||||||
|
call assert_equal(&lhistory, 1)
|
||||||
|
|
||||||
|
" check if lhistory is synced when modified inside the
|
||||||
|
" normal window
|
||||||
|
setlocal lhistory=10
|
||||||
|
lopen
|
||||||
|
call assert_equal(&lhistory, 10)
|
||||||
|
|
||||||
|
wincmd k
|
||||||
|
lclose
|
||||||
|
wincmd q
|
||||||
|
|
||||||
|
set lhistory&
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Test if setting the lhistory of one window doesn't affect the other
|
||||||
|
func Test_two_win_are_independent_of_history()
|
||||||
|
setlocal lhistory=10
|
||||||
|
new
|
||||||
|
setlocal lhistory=20
|
||||||
|
wincmd w
|
||||||
|
call assert_equal(&lhistory, 10)
|
||||||
|
wincmd w
|
||||||
|
wincmd q
|
||||||
|
|
||||||
|
set lhistory&
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Test if lhistory is copied over to a new window
|
||||||
|
func Test_lhistory_copied_over()
|
||||||
|
setlocal lhistory=3
|
||||||
|
split
|
||||||
|
call assert_equal(&lhistory, 3)
|
||||||
|
wincmd q
|
||||||
|
|
||||||
|
set lhistory&
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Test if error occurs when given invalid history number
|
||||||
|
func Xtest_invalid_history_num(cchar)
|
||||||
|
call s:setup_commands(a:cchar)
|
||||||
|
|
||||||
|
call assert_fails('Xsethist -10000', "E1542:")
|
||||||
|
call assert_fails('Xsethist 10000', "E1543:")
|
||||||
|
Xsethistdefault
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_invalid_history_num()
|
||||||
|
call Xtest_invalid_history_num('c')
|
||||||
|
call Xtest_invalid_history_num('l')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Test if chistory and lhistory don't affect each other
|
||||||
|
func Test_chi_and_lhi_are_independent()
|
||||||
|
set chistory=100
|
||||||
|
set lhistory=100
|
||||||
|
|
||||||
|
set chistory=10
|
||||||
|
call assert_equal(&lhistory, 100)
|
||||||
|
|
||||||
|
set lhistory=1
|
||||||
|
call assert_equal(&chistory, 10)
|
||||||
|
|
||||||
|
set chistory&
|
||||||
|
set lhistory&
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_quickfix_close_buffer_crash()
|
func Test_quickfix_close_buffer_crash()
|
||||||
new
|
new
|
||||||
lexpr 'test' | lopen
|
lexpr 'test' | lopen
|
||||||
|
Reference in New Issue
Block a user