@@ -85,6 +85,7 @@ typedef struct qf_list_S {
85
85
int qf_nonevalid ; // TRUE if not a single valid entry found
86
86
char_u * qf_title ; // title derived from the command that created
87
87
// the error list
88
+ typval_T * qf_ctx ; // context set by setqflist/setloclist
88
89
} qf_list_T ;
89
90
90
91
struct qf_info_S {
@@ -800,7 +801,7 @@ static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen,
800
801
fields -> type = * regmatch .startp [i ];
801
802
}
802
803
if (fmt_ptr -> flags == '+' && !qi -> qf_multiscan ) { // %+
803
- if (linelen > fields -> errmsglen ) {
804
+ if (linelen >= fields -> errmsglen ) {
804
805
// linelen + null terminator
805
806
fields -> errmsg = xrealloc (fields -> errmsg , linelen + 1 );
806
807
fields -> errmsglen = linelen + 1 ;
@@ -811,7 +812,7 @@ static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen,
811
812
continue ;
812
813
}
813
814
len = (size_t )(regmatch .endp [i ] - regmatch .startp [i ]);
814
- if (len > fields -> errmsglen ) {
815
+ if (len >= fields -> errmsglen ) {
815
816
// len + null terminator
816
817
fields -> errmsg = xrealloc (fields -> errmsg , len + 1 );
817
818
fields -> errmsglen = len + 1 ;
@@ -888,7 +889,7 @@ static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen,
888
889
fields -> namebuf [0 ] = NUL ; // no match found, remove file name
889
890
fields -> lnum = 0 ; // don't jump to this line
890
891
fields -> valid = false;
891
- if (linelen > fields -> errmsglen ) {
892
+ if (linelen >= fields -> errmsglen ) {
892
893
// linelen + null terminator
893
894
fields -> errmsg = xrealloc (fields -> errmsg , linelen + 1 );
894
895
fields -> errmsglen = linelen + 1 ;
@@ -1409,6 +1410,13 @@ void copy_loclist(win_T *from, win_T *to)
1409
1410
else
1410
1411
to_qfl -> qf_title = NULL ;
1411
1412
1413
+ if (from_qfl -> qf_ctx != NULL ) {
1414
+ to_qfl -> qf_ctx = xcalloc (1 , sizeof (typval_T ));
1415
+ tv_copy (from_qfl -> qf_ctx , to_qfl -> qf_ctx );
1416
+ } else {
1417
+ to_qfl -> qf_ctx = NULL ;
1418
+ }
1419
+
1412
1420
if (from_qfl -> qf_count ) {
1413
1421
qfline_T * from_qfp ;
1414
1422
qfline_T * prevp ;
@@ -2410,6 +2418,8 @@ static void qf_free(qf_info_T *qi, int idx)
2410
2418
qi -> qf_lists [idx ].qf_start = NULL ;
2411
2419
qi -> qf_lists [idx ].qf_ptr = NULL ;
2412
2420
qi -> qf_lists [idx ].qf_title = NULL ;
2421
+ tv_free (qi -> qf_lists [idx ].qf_ctx );
2422
+ qi -> qf_lists [idx ].qf_ctx = NULL ;
2413
2423
qi -> qf_lists [idx ].qf_index = 0 ;
2414
2424
qi -> qf_lists [idx ].qf_start = NULL ;
2415
2425
qi -> qf_lists [idx ].qf_last = NULL ;
@@ -4060,6 +4070,7 @@ enum {
4060
4070
QF_GETLIST_ITEMS = 0x2 ,
4061
4071
QF_GETLIST_NR = 0x4 ,
4062
4072
QF_GETLIST_WINID = 0x8 ,
4073
+ QF_GETLIST_CONTEXT = 0x10 ,
4063
4074
QF_GETLIST_ALL = 0xFF
4064
4075
};
4065
4076
@@ -4110,6 +4121,10 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
4110
4121
flags |= QF_GETLIST_WINID ;
4111
4122
}
4112
4123
4124
+ if (tv_dict_find (what , S_LEN ("context" )) != NULL ) {
4125
+ flags |= QF_GETLIST_CONTEXT ;
4126
+ }
4127
+
4113
4128
if (flags & QF_GETLIST_TITLE ) {
4114
4129
char_u * t = qi -> qf_lists [qf_idx ].qf_title ;
4115
4130
if (t == NULL ) {
@@ -4127,6 +4142,20 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
4127
4142
}
4128
4143
}
4129
4144
4145
+ if ((status == OK ) && (flags & QF_GETLIST_CONTEXT )) {
4146
+ if (qi -> qf_lists [qf_idx ].qf_ctx != NULL ) {
4147
+ di = tv_dict_item_alloc_len (S_LEN ("context" ));
4148
+ if (di != NULL ) {
4149
+ tv_copy (qi -> qf_lists [qf_idx ].qf_ctx , & di -> di_tv );
4150
+ if (tv_dict_add (retdict , di ) == FAIL ) {
4151
+ tv_dict_item_free (di );
4152
+ }
4153
+ }
4154
+ } else {
4155
+ status = tv_dict_add_str (retdict , S_LEN ("context" ), "" );
4156
+ }
4157
+ }
4158
+
4130
4159
return status ;
4131
4160
}
4132
4161
@@ -4249,7 +4278,10 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action)
4249
4278
if ((di = tv_dict_find (what , S_LEN ("nr" ))) != NULL ) {
4250
4279
// Use the specified quickfix/location list
4251
4280
if (di -> di_tv .v_type == VAR_NUMBER ) {
4252
- qf_idx = (int )di -> di_tv .vval .v_number - 1 ;
4281
+ // for zero use the current list
4282
+ if (di -> di_tv .vval .v_number != 0 ) {
4283
+ qf_idx = (int )di -> di_tv .vval .v_number - 1 ;
4284
+ }
4253
4285
if (qf_idx < 0 || qf_idx >= qi -> qf_listcount ) {
4254
4286
return FAIL ;
4255
4287
}
@@ -4276,6 +4308,14 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action)
4276
4308
}
4277
4309
}
4278
4310
4311
+ if ((di = tv_dict_find (what , S_LEN ("context" ))) != NULL ) {
4312
+ tv_free (qi -> qf_lists [qf_idx ].qf_ctx );
4313
+
4314
+ typval_T * ctx = xcalloc (1 , sizeof (typval_T ));
4315
+ tv_copy (& di -> di_tv , ctx );
4316
+ qi -> qf_lists [qf_idx ].qf_ctx = ctx ;
4317
+ }
4318
+
4279
4319
return retval ;
4280
4320
}
4281
4321
@@ -4362,6 +4402,42 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
4362
4402
return retval ;
4363
4403
}
4364
4404
4405
+ static bool mark_quickfix_ctx (qf_info_T * qi , int copyID )
4406
+ {
4407
+ bool abort = false;
4408
+
4409
+ for (int i = 0 ; i < LISTCOUNT && !abort ; i ++ ) {
4410
+ typval_T * ctx = qi -> qf_lists [i ].qf_ctx ;
4411
+ if (ctx != NULL && ctx -> v_type != VAR_NUMBER
4412
+ && ctx -> v_type != VAR_STRING && ctx -> v_type != VAR_FLOAT ) {
4413
+ abort = set_ref_in_item (ctx , copyID , NULL , NULL );
4414
+ }
4415
+ }
4416
+
4417
+ return abort ;
4418
+ }
4419
+
4420
+ /// Mark the context of the quickfix list and the location lists (if present) as
4421
+ /// "in use". So that garabage collection doesn't free the context.
4422
+ bool set_ref_in_quickfix (int copyID )
4423
+ {
4424
+ bool abort = mark_quickfix_ctx (& ql_info , copyID );
4425
+ if (abort ) {
4426
+ return abort ;
4427
+ }
4428
+
4429
+ FOR_ALL_TAB_WINDOWS (tp , win ) {
4430
+ if (win -> w_llist != NULL ) {
4431
+ abort = mark_quickfix_ctx (win -> w_llist , copyID );
4432
+ if (abort ) {
4433
+ return abort ;
4434
+ }
4435
+ }
4436
+ }
4437
+
4438
+ return abort ;
4439
+ }
4440
+
4365
4441
/*
4366
4442
* ":[range]cbuffer [bufnr]" command.
4367
4443
* ":[range]caddbuffer [bufnr]" command.
0 commit comments