mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 8.2.1255: cannot use a lambda with quickfix functions
Problem: Cannot use a lambda with quickfix functions. Solution: Add support for lambda. (Yegappan Lakshmanan, closes #6499)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
*eval.txt* For Vim version 8.2. Last change: 2020 Jul 09
|
*eval.txt* For Vim version 8.2. Last change: 2020 Jul 19
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -94,8 +94,9 @@ the Number. Examples:
|
|||||||
Number 0 --> String "0" ~
|
Number 0 --> String "0" ~
|
||||||
Number -1 --> String "-1" ~
|
Number -1 --> String "-1" ~
|
||||||
*octal*
|
*octal*
|
||||||
Conversion from a String to a Number is done by converting the first digits to
|
Conversion from a String to a Number only happens in legacy Vim script, not in
|
||||||
a number. Hexadecimal "0xf9", Octal "017" or "0o17", and Binary "0b10"
|
Vim9 script. It is done by converting the first digits to a number.
|
||||||
|
Hexadecimal "0xf9", Octal "017" or "0o17", and Binary "0b10"
|
||||||
numbers are recognized (NOTE: when using |scriptversion-4| octal with a
|
numbers are recognized (NOTE: when using |scriptversion-4| octal with a
|
||||||
leading "0" is not recognized). If the String doesn't start with digits, the
|
leading "0" is not recognized). If the String doesn't start with digits, the
|
||||||
result is zero.
|
result is zero.
|
||||||
@@ -2831,7 +2832,7 @@ stridx({haystack}, {needle} [, {start}])
|
|||||||
string({expr}) String String representation of {expr} value
|
string({expr}) String String representation of {expr} value
|
||||||
strlen({expr}) Number length of the String {expr}
|
strlen({expr}) Number length of the String {expr}
|
||||||
strpart({str}, {start} [, {len}])
|
strpart({str}, {start} [, {len}])
|
||||||
String {len} characters of {str} at {start}
|
String {len} bytes of {str} at byte {start}
|
||||||
strptime({format}, {timestring})
|
strptime({format}, {timestring})
|
||||||
Number Convert {timestring} to unix timestamp
|
Number Convert {timestring} to unix timestamp
|
||||||
strridx({haystack}, {needle} [, {start}])
|
strridx({haystack}, {needle} [, {start}])
|
||||||
@@ -9183,7 +9184,8 @@ setqflist({list} [, {action} [, {what}]]) *setqflist()*
|
|||||||
the last quickfix list.
|
the last quickfix list.
|
||||||
quickfixtextfunc
|
quickfixtextfunc
|
||||||
function to get the text to display in the
|
function to get the text to display in the
|
||||||
quickfix window. Refer to
|
quickfix window. The value can be the name of
|
||||||
|
a function or a funcref or a lambda. Refer to
|
||||||
|quickfix-window-function| for an explanation
|
|quickfix-window-function| for an explanation
|
||||||
of how to write the function and an example.
|
of how to write the function and an example.
|
||||||
title quickfix list title text. See |quickfix-title|
|
title quickfix list title text. See |quickfix-title|
|
||||||
|
@@ -5913,7 +5913,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
customize the information displayed in the quickfix or location window
|
customize the information displayed in the quickfix or location window
|
||||||
for each entry in the corresponding quickfix or location list. See
|
for each entry in the corresponding quickfix or location list. See
|
||||||
|quickfix-window-function| for an explanation of how to write the
|
|quickfix-window-function| for an explanation of how to write the
|
||||||
function and an example.
|
function and an example. The value can be the name of a function or a
|
||||||
|
lambda.
|
||||||
|
|
||||||
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.
|
||||||
|
@@ -1964,7 +1964,10 @@ The function should return a single line of text to display in the quickfix
|
|||||||
window for each entry from start_idx to end_idx. The function can obtain
|
window for each entry from start_idx to end_idx. The function can obtain
|
||||||
information about the entries using the |getqflist()| function and specifying
|
information about the entries using the |getqflist()| function and specifying
|
||||||
the quickfix list identifier "id". For a location list, getloclist() function
|
the quickfix list identifier "id". For a location list, getloclist() function
|
||||||
can be used with the 'winid' argument.
|
can be used with the 'winid' argument. If an empty list is returned, then the
|
||||||
|
default format is used to display all the entries. If an item in the returned
|
||||||
|
list is an empty string, then the default format is used to display the
|
||||||
|
corresponding entry.
|
||||||
|
|
||||||
If a quickfix or location list specific customization is needed, then the
|
If a quickfix or location list specific customization is needed, then the
|
||||||
'quickfixtextfunc' attribute of the list can be set using the |setqflist()| or
|
'quickfixtextfunc' attribute of the list can be set using the |setqflist()| or
|
||||||
|
@@ -1101,27 +1101,6 @@ channel_open(
|
|||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy callback from "src" to "dest", incrementing the refcounts.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
copy_callback(callback_T *dest, callback_T *src)
|
|
||||||
{
|
|
||||||
dest->cb_partial = src->cb_partial;
|
|
||||||
if (dest->cb_partial != NULL)
|
|
||||||
{
|
|
||||||
dest->cb_name = src->cb_name;
|
|
||||||
dest->cb_free_name = FALSE;
|
|
||||||
++dest->cb_partial->pt_refcount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dest->cb_name = vim_strsave(src->cb_name);
|
|
||||||
dest->cb_free_name = TRUE;
|
|
||||||
func_ref(src->cb_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_set_callback(callback_T *cbp, callback_T *callback)
|
free_set_callback(callback_T *cbp, callback_T *callback)
|
||||||
{
|
{
|
||||||
|
@@ -3848,6 +3848,27 @@ set_callback(callback_T *dest, callback_T *src)
|
|||||||
dest->cb_partial = src->cb_partial;
|
dest->cb_partial = src->cb_partial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy callback from "src" to "dest", incrementing the refcounts.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
copy_callback(callback_T *dest, callback_T *src)
|
||||||
|
{
|
||||||
|
dest->cb_partial = src->cb_partial;
|
||||||
|
if (dest->cb_partial != NULL)
|
||||||
|
{
|
||||||
|
dest->cb_name = src->cb_name;
|
||||||
|
dest->cb_free_name = FALSE;
|
||||||
|
++dest->cb_partial->pt_refcount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest->cb_name = vim_strsave(src->cb_name);
|
||||||
|
dest->cb_free_name = TRUE;
|
||||||
|
func_ref(src->cb_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unref/free "callback" returned by get_callback() or set_callback().
|
* Unref/free "callback" returned by get_callback() or set_callback().
|
||||||
*/
|
*/
|
||||||
|
@@ -2255,6 +2255,14 @@ did_set_string_option(
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_QUICKFIX
|
||||||
|
else if (varp == &p_qftf)
|
||||||
|
{
|
||||||
|
if (qf_process_qftf_option() == FALSE)
|
||||||
|
errmsg = e_invarg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Options that are a list of flags.
|
// Options that are a list of flags.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -88,5 +88,6 @@ void f_setbufvar(typval_T *argvars, typval_T *rettv);
|
|||||||
callback_T get_callback(typval_T *arg);
|
callback_T get_callback(typval_T *arg);
|
||||||
void put_callback(callback_T *cb, typval_T *tv);
|
void put_callback(callback_T *cb, typval_T *tv);
|
||||||
void set_callback(callback_T *dest, callback_T *src);
|
void set_callback(callback_T *dest, callback_T *src);
|
||||||
|
void copy_callback(callback_T *dest, callback_T *src);
|
||||||
void free_callback(callback_T *callback);
|
void free_callback(callback_T *callback);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -15,6 +15,7 @@ void ex_cclose(exarg_T *eap);
|
|||||||
void ex_copen(exarg_T *eap);
|
void ex_copen(exarg_T *eap);
|
||||||
void ex_cbottom(exarg_T *eap);
|
void ex_cbottom(exarg_T *eap);
|
||||||
linenr_T qf_current_entry(win_T *wp);
|
linenr_T qf_current_entry(win_T *wp);
|
||||||
|
int qf_process_qftf_option(void);
|
||||||
int grep_internal(cmdidx_T cmdidx);
|
int grep_internal(cmdidx_T cmdidx);
|
||||||
void ex_make(exarg_T *eap);
|
void ex_make(exarg_T *eap);
|
||||||
int qf_get_size(exarg_T *eap);
|
int qf_get_size(exarg_T *eap);
|
||||||
|
139
src/quickfix.c
139
src/quickfix.c
@@ -82,7 +82,7 @@ typedef struct qf_list_S
|
|||||||
char_u *qf_title; // title derived from the command that created
|
char_u *qf_title; // title derived from the command that created
|
||||||
// the error list or set by setqflist
|
// the error list or set by setqflist
|
||||||
typval_T *qf_ctx; // context set by setqflist/setloclist
|
typval_T *qf_ctx; // context set by setqflist/setloclist
|
||||||
char_u *qf_qftf; // 'quickfixtextfunc' setting for this list
|
callback_T qftf_cb; // 'quickfixtextfunc' callback function
|
||||||
|
|
||||||
struct dir_stack_T *qf_dir_stack;
|
struct dir_stack_T *qf_dir_stack;
|
||||||
char_u *qf_directory;
|
char_u *qf_directory;
|
||||||
@@ -161,6 +161,9 @@ static int quickfix_busy = 0;
|
|||||||
|
|
||||||
static efm_T *fmt_start = NULL; // cached across qf_parse_line() calls
|
static efm_T *fmt_start = NULL; // cached across qf_parse_line() calls
|
||||||
|
|
||||||
|
// callback function for 'quickfixtextfunc'
|
||||||
|
static callback_T qftf_cb;
|
||||||
|
|
||||||
static void qf_new_list(qf_info_T *qi, char_u *qf_title);
|
static void qf_new_list(qf_info_T *qi, char_u *qf_title);
|
||||||
static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *module, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid);
|
static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *module, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid);
|
||||||
static void qf_free(qf_list_T *qfl);
|
static void qf_free(qf_list_T *qfl);
|
||||||
@@ -2279,10 +2282,10 @@ copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
to_qfl->qf_ctx = NULL;
|
to_qfl->qf_ctx = NULL;
|
||||||
if (from_qfl->qf_qftf != NULL)
|
if (from_qfl->qftf_cb.cb_name != NULL)
|
||||||
to_qfl->qf_qftf = vim_strsave(from_qfl->qf_qftf);
|
copy_callback(&to_qfl->qftf_cb, &from_qfl->qftf_cb);
|
||||||
else
|
else
|
||||||
to_qfl->qf_qftf = NULL;
|
to_qfl->qftf_cb.cb_name = NULL;
|
||||||
|
|
||||||
if (from_qfl->qf_count)
|
if (from_qfl->qf_count)
|
||||||
if (copy_loclist_entries(from_qfl, to_qfl) == FAIL)
|
if (copy_loclist_entries(from_qfl, to_qfl) == FAIL)
|
||||||
@@ -3818,7 +3821,7 @@ qf_free(qf_list_T *qfl)
|
|||||||
VIM_CLEAR(qfl->qf_title);
|
VIM_CLEAR(qfl->qf_title);
|
||||||
free_tv(qfl->qf_ctx);
|
free_tv(qfl->qf_ctx);
|
||||||
qfl->qf_ctx = NULL;
|
qfl->qf_ctx = NULL;
|
||||||
VIM_CLEAR(qfl->qf_qftf);
|
free_callback(&qfl->qftf_cb);
|
||||||
qfl->qf_id = 0;
|
qfl->qf_id = 0;
|
||||||
qfl->qf_changedtick = 0L;
|
qfl->qf_changedtick = 0L;
|
||||||
}
|
}
|
||||||
@@ -4348,6 +4351,49 @@ qf_find_buf(qf_info_T *qi)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process the 'quickfixtextfunc' option value.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qf_process_qftf_option(void)
|
||||||
|
{
|
||||||
|
typval_T *tv;
|
||||||
|
callback_T cb;
|
||||||
|
|
||||||
|
if (p_qftf == NULL || *p_qftf == NUL)
|
||||||
|
{
|
||||||
|
free_callback(&qftf_cb);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p_qftf == '{')
|
||||||
|
{
|
||||||
|
// Lambda expression
|
||||||
|
tv = eval_expr(p_qftf, NULL);
|
||||||
|
if (tv == NULL)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// treat everything else as a function name string
|
||||||
|
tv = alloc_string_tv(vim_strsave(p_qftf));
|
||||||
|
if (tv == NULL)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb = get_callback(tv);
|
||||||
|
if (cb.cb_name == NULL)
|
||||||
|
{
|
||||||
|
free_tv(tv);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free_callback(&qftf_cb);
|
||||||
|
set_callback(&qftf_cb, &cb);
|
||||||
|
free_tv(tv);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the w:quickfix_title variable in the quickfix/location list window
|
* Update the w:quickfix_title variable in the quickfix/location list window
|
||||||
*/
|
*/
|
||||||
@@ -4424,7 +4470,9 @@ qf_buf_add_line(
|
|||||||
int len;
|
int len;
|
||||||
buf_T *errbuf;
|
buf_T *errbuf;
|
||||||
|
|
||||||
if (qftf_str != NULL)
|
// If the 'quickfixtextfunc' function returned an non-empty custom string
|
||||||
|
// for this entry, then use it.
|
||||||
|
if (qftf_str != NULL && *qftf_str != NUL)
|
||||||
vim_strncpy(IObuff, qftf_str, IOSIZE - 1);
|
vim_strncpy(IObuff, qftf_str, IOSIZE - 1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -4501,21 +4549,26 @@ qf_buf_add_line(
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the 'quickfixtextfunc' function to get the list of lines to display in
|
||||||
|
* the quickfix window for the entries 'start_idx' to 'end_idx'.
|
||||||
|
*/
|
||||||
static list_T *
|
static list_T *
|
||||||
call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx)
|
call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx)
|
||||||
{
|
{
|
||||||
char_u *qftf = p_qftf;
|
callback_T *cb = &qftf_cb;
|
||||||
list_T *qftf_list = NULL;
|
list_T *qftf_list = NULL;
|
||||||
|
|
||||||
// If 'quickfixtextfunc' is set, then use the user-supplied function to get
|
// If 'quickfixtextfunc' is set, then use the user-supplied function to get
|
||||||
// the text to display. Use the local value of 'quickfixtextfunc' if it is
|
// the text to display. Use the local value of 'quickfixtextfunc' if it is
|
||||||
// set.
|
// set.
|
||||||
if (qfl->qf_qftf != NULL)
|
if (qfl->qftf_cb.cb_name != NULL)
|
||||||
qftf = qfl->qf_qftf;
|
cb = &qfl->qftf_cb;
|
||||||
if (qftf != NULL && *qftf != NUL)
|
if (cb != NULL && cb->cb_name != NULL)
|
||||||
{
|
{
|
||||||
typval_T args[1];
|
typval_T args[1];
|
||||||
dict_T *d;
|
dict_T *d;
|
||||||
|
typval_T rettv;
|
||||||
|
|
||||||
// create the dict argument
|
// create the dict argument
|
||||||
if ((d = dict_alloc_lock(VAR_FIXED)) == NULL)
|
if ((d = dict_alloc_lock(VAR_FIXED)) == NULL)
|
||||||
@@ -4529,8 +4582,17 @@ call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx)
|
|||||||
args[0].v_type = VAR_DICT;
|
args[0].v_type = VAR_DICT;
|
||||||
args[0].vval.v_dict = d;
|
args[0].vval.v_dict = d;
|
||||||
|
|
||||||
qftf_list = call_func_retlist(qftf, 1, args);
|
qftf_list = NULL;
|
||||||
--d->dv_refcount;
|
if (call_callback(cb, 0, &rettv, 1, args) != FAIL)
|
||||||
|
{
|
||||||
|
if (rettv.v_type == VAR_LIST)
|
||||||
|
{
|
||||||
|
qftf_list = rettv.vval.v_list;
|
||||||
|
qftf_list->lv_refcount++;
|
||||||
|
}
|
||||||
|
clear_tv(&rettv);
|
||||||
|
}
|
||||||
|
dict_unref(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
return qftf_list;
|
return qftf_list;
|
||||||
@@ -4569,6 +4631,7 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
|
|||||||
if (qfl != NULL)
|
if (qfl != NULL)
|
||||||
{
|
{
|
||||||
char_u dirname[MAXPATHL];
|
char_u dirname[MAXPATHL];
|
||||||
|
int invalid_val = FALSE;
|
||||||
|
|
||||||
*dirname = NUL;
|
*dirname = NUL;
|
||||||
|
|
||||||
@@ -4593,9 +4656,15 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
|
|||||||
{
|
{
|
||||||
char_u *qftf_str = NULL;
|
char_u *qftf_str = NULL;
|
||||||
|
|
||||||
if (qftf_li != NULL)
|
// Use the text supplied by the user defined function (if any).
|
||||||
// Use the text supplied by the user defined function
|
// If the returned value is not string, then ignore the rest
|
||||||
|
// of the returned values and use the default.
|
||||||
|
if (qftf_li != NULL && !invalid_val)
|
||||||
|
{
|
||||||
qftf_str = tv_get_string_chk(&qftf_li->li_tv);
|
qftf_str = tv_get_string_chk(&qftf_li->li_tv);
|
||||||
|
if (qftf_str == NULL)
|
||||||
|
invalid_val = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (qf_buf_add_line(buf, lnum, qfp, dirname, qftf_str) == FAIL)
|
if (qf_buf_add_line(buf, lnum, qfp, dirname, qftf_str) == FAIL)
|
||||||
break;
|
break;
|
||||||
@@ -6515,7 +6584,8 @@ enum {
|
|||||||
QF_GETLIST_TICK = 0x100,
|
QF_GETLIST_TICK = 0x100,
|
||||||
QF_GETLIST_FILEWINID = 0x200,
|
QF_GETLIST_FILEWINID = 0x200,
|
||||||
QF_GETLIST_QFBUFNR = 0x400,
|
QF_GETLIST_QFBUFNR = 0x400,
|
||||||
QF_GETLIST_ALL = 0x7FF,
|
QF_GETLIST_QFTF = 0x800,
|
||||||
|
QF_GETLIST_ALL = 0xFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6644,6 +6714,9 @@ qf_getprop_keys2flags(dict_T *what, int loclist)
|
|||||||
if (dict_find(what, (char_u *)"qfbufnr", -1) != NULL)
|
if (dict_find(what, (char_u *)"qfbufnr", -1) != NULL)
|
||||||
flags |= QF_GETLIST_QFBUFNR;
|
flags |= QF_GETLIST_QFBUFNR;
|
||||||
|
|
||||||
|
if (dict_find(what, (char_u *)"quickfixtextfunc", -1) != NULL)
|
||||||
|
flags |= QF_GETLIST_QFTF;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6738,6 +6811,8 @@ qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict)
|
|||||||
status = dict_add_number(retdict, "filewinid", 0);
|
status = dict_add_number(retdict, "filewinid", 0);
|
||||||
if ((status == OK) && (flags & QF_GETLIST_QFBUFNR))
|
if ((status == OK) && (flags & QF_GETLIST_QFBUFNR))
|
||||||
status = qf_getprop_qfbufnr(qi, retdict);
|
status = qf_getprop_qfbufnr(qi, retdict);
|
||||||
|
if ((status == OK) && (flags & QF_GETLIST_QFTF))
|
||||||
|
status = dict_add_string(retdict, "quickfixtextfunc", (char_u *)"");
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -6836,6 +6911,28 @@ qf_getprop_idx(qf_list_T *qfl, int eidx, dict_T *retdict)
|
|||||||
return dict_add_number(retdict, "idx", eidx);
|
return dict_add_number(retdict, "idx", eidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the 'quickfixtextfunc' function of a quickfix/location list
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qf_getprop_qftf(qf_list_T *qfl, dict_T *retdict)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (qfl->qftf_cb.cb_name != NULL)
|
||||||
|
{
|
||||||
|
typval_T tv;
|
||||||
|
|
||||||
|
put_callback(&qfl->qftf_cb, &tv);
|
||||||
|
status = dict_add_tv(retdict, "quickfixtextfunc", &tv);
|
||||||
|
clear_tv(&tv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
status = dict_add_string(retdict, "quickfixtextfunc", (char_u *)"");
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return quickfix/location list details (title) as a
|
* Return quickfix/location list details (title) as a
|
||||||
* dictionary. 'what' contains the details to return. If 'list_idx' is -1,
|
* dictionary. 'what' contains the details to return. If 'list_idx' is -1,
|
||||||
@@ -6899,6 +6996,8 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
|||||||
status = qf_getprop_filewinid(wp, qi, retdict);
|
status = qf_getprop_filewinid(wp, qi, retdict);
|
||||||
if ((status == OK) && (flags & QF_GETLIST_QFBUFNR))
|
if ((status == OK) && (flags & QF_GETLIST_QFBUFNR))
|
||||||
status = qf_getprop_qfbufnr(qi, retdict);
|
status = qf_getprop_qfbufnr(qi, retdict);
|
||||||
|
if ((status == OK) && (flags & QF_GETLIST_QFTF))
|
||||||
|
status = qf_getprop_qftf(qfl, retdict);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -7260,10 +7359,12 @@ qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, dictitem_T *di)
|
|||||||
static int
|
static int
|
||||||
qf_setprop_qftf(qf_info_T *qi UNUSED, qf_list_T *qfl, dictitem_T *di)
|
qf_setprop_qftf(qf_info_T *qi UNUSED, qf_list_T *qfl, dictitem_T *di)
|
||||||
{
|
{
|
||||||
VIM_CLEAR(qfl->qf_qftf);
|
callback_T cb;
|
||||||
if (di->di_tv.v_type == VAR_STRING
|
|
||||||
&& di->di_tv.vval.v_string != NULL)
|
free_callback(&qfl->qftf_cb);
|
||||||
qfl->qf_qftf = vim_strsave(di->di_tv.vval.v_string);
|
cb = get_callback(&di->di_tv);
|
||||||
|
if (cb.cb_name != NULL && *cb.cb_name != NUL)
|
||||||
|
set_callback(&qfl->qftf_cb, &cb);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@@ -3490,13 +3490,13 @@ func Xgetlist_empty_tests(cchar)
|
|||||||
if a:cchar == 'c'
|
if a:cchar == 'c'
|
||||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
|
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
|
||||||
\ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
|
\ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
|
||||||
\ 'title' : '', 'winid' : 0, 'changedtick': 0},
|
\ 'title' : '', 'winid' : 0, 'changedtick': 0,
|
||||||
\ g:Xgetlist({'all' : 0}))
|
\ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
|
||||||
else
|
else
|
||||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
|
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
|
||||||
\ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
|
\ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
|
||||||
\ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
|
\ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
|
||||||
\ 'qfbufnr' : 0},
|
\ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
|
||||||
\ g:Xgetlist({'all' : 0}))
|
\ g:Xgetlist({'all' : 0}))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -3535,12 +3535,13 @@ func Xgetlist_empty_tests(cchar)
|
|||||||
if a:cchar == 'c'
|
if a:cchar == 'c'
|
||||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
||||||
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
||||||
\ 'qfbufnr' : qfbufnr,
|
\ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
|
||||||
\ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
|
\ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
|
||||||
else
|
else
|
||||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
||||||
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
||||||
\ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
|
\ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
|
||||||
|
\ 'quickfixtextfunc' : ''},
|
||||||
\ g:Xgetlist({'id' : qfid, 'all' : 0}))
|
\ g:Xgetlist({'id' : qfid, 'all' : 0}))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -3557,13 +3558,13 @@ func Xgetlist_empty_tests(cchar)
|
|||||||
if a:cchar == 'c'
|
if a:cchar == 'c'
|
||||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
||||||
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
||||||
\ 'changedtick' : 0, 'qfbufnr' : qfbufnr},
|
\ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
|
||||||
\ g:Xgetlist({'nr' : 5, 'all' : 0}))
|
\ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
|
||||||
else
|
else
|
||||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
|
||||||
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
|
||||||
\ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0},
|
\ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
|
||||||
\ g:Xgetlist({'nr' : 5, 'all' : 0}))
|
\ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
|
||||||
endif
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
@@ -4865,6 +4866,9 @@ func Xtest_qftextfunc(cchar)
|
|||||||
|
|
||||||
set efm=%f:%l:%c:%m
|
set efm=%f:%l:%c:%m
|
||||||
set quickfixtextfunc=Tqfexpr
|
set quickfixtextfunc=Tqfexpr
|
||||||
|
call assert_equal('Tqfexpr', &quickfixtextfunc)
|
||||||
|
call assert_equal('',
|
||||||
|
\ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
|
||||||
Xexpr ['F1:10:2:green', 'F1:20:4:blue']
|
Xexpr ['F1:10:2:green', 'F1:20:4:blue']
|
||||||
Xwindow
|
Xwindow
|
||||||
call assert_equal('F1-L10C2-green', getline(1))
|
call assert_equal('F1-L10C2-green', getline(1))
|
||||||
@@ -4901,12 +4905,15 @@ func Xtest_qftextfunc(cchar)
|
|||||||
call assert_equal('Line 10, Col 2', getline(1))
|
call assert_equal('Line 10, Col 2', getline(1))
|
||||||
call assert_equal('Line 20, Col 4', getline(2))
|
call assert_equal('Line 20, Col 4', getline(2))
|
||||||
Xclose
|
Xclose
|
||||||
|
call assert_equal(function('PerQfText'),
|
||||||
|
\ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
|
||||||
" Add entries to the list when the quickfix buffer is hidden
|
" Add entries to the list when the quickfix buffer is hidden
|
||||||
Xaddexpr ['F1:30:6:red']
|
Xaddexpr ['F1:30:6:red']
|
||||||
Xwindow
|
Xwindow
|
||||||
call assert_equal('Line 30, Col 6', getline(3))
|
call assert_equal('Line 30, Col 6', getline(3))
|
||||||
Xclose
|
Xclose
|
||||||
call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
|
call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
|
||||||
|
call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
|
||||||
set quickfixtextfunc&
|
set quickfixtextfunc&
|
||||||
delfunc PerQfText
|
delfunc PerQfText
|
||||||
|
|
||||||
@@ -4941,12 +4948,53 @@ func Xtest_qftextfunc(cchar)
|
|||||||
call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
|
call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
|
||||||
\ 'E730:')
|
\ 'E730:')
|
||||||
call assert_fails('Xwindow', 'E730:')
|
call assert_fails('Xwindow', 'E730:')
|
||||||
call assert_equal(['one', 'F1|20 col 4| blue', 'two'], getline(1, '$'))
|
call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
|
||||||
|
\ getline(1, '$'))
|
||||||
Xclose
|
Xclose
|
||||||
|
|
||||||
set quickfixtextfunc&
|
set quickfixtextfunc&
|
||||||
delfunc Xqftext
|
delfunc Xqftext
|
||||||
delfunc Xqftext2
|
delfunc Xqftext2
|
||||||
|
|
||||||
|
" set the global option to a lambda function
|
||||||
|
set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
|
||||||
|
Xexpr ['F1:10:2:green', 'F1:20:4:blue']
|
||||||
|
Xwindow
|
||||||
|
call assert_equal(['green', 'blue'], getline(1, '$'))
|
||||||
|
Xclose
|
||||||
|
call assert_equal("{d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1], 'v:val.text')}", &quickfixtextfunc)
|
||||||
|
set quickfixtextfunc&
|
||||||
|
|
||||||
|
" use a lambda function that returns an empty list
|
||||||
|
set quickfixtextfunc={d\ ->\ []}
|
||||||
|
Xexpr ['F1:10:2:green', 'F1:20:4:blue']
|
||||||
|
Xwindow
|
||||||
|
call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
|
||||||
|
\ getline(1, '$'))
|
||||||
|
Xclose
|
||||||
|
set quickfixtextfunc&
|
||||||
|
|
||||||
|
" use a lambda function that returns a list with empty strings
|
||||||
|
set quickfixtextfunc={d\ ->\ ['',\ '']}
|
||||||
|
Xexpr ['F1:10:2:green', 'F1:20:4:blue']
|
||||||
|
Xwindow
|
||||||
|
call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
|
||||||
|
\ getline(1, '$'))
|
||||||
|
Xclose
|
||||||
|
set quickfixtextfunc&
|
||||||
|
|
||||||
|
" set the per-quickfix list text function to a lambda function
|
||||||
|
call g:Xsetlist([], ' ',
|
||||||
|
\ {'quickfixtextfunc' :
|
||||||
|
\ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
|
||||||
|
\ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
|
||||||
|
Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
|
||||||
|
Xwindow
|
||||||
|
call assert_equal('Line 10, Col 2', getline(1))
|
||||||
|
call assert_equal('Line 20, Col 4', getline(2))
|
||||||
|
Xclose
|
||||||
|
call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
|
||||||
|
call g:Xsetlist([], 'f')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_qftextfunc()
|
func Test_qftextfunc()
|
||||||
|
@@ -754,6 +754,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1255,
|
||||||
/**/
|
/**/
|
||||||
1254,
|
1254,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user