Skip to content

Commit 33f0aed

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents b044cf0 + 1b0c2fc commit 33f0aed

12 files changed

Lines changed: 175 additions & 134 deletions

File tree

src/edit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5318,7 +5318,7 @@ ins_complete(int c, int enable_pum)
53185318
if (compl_pattern == NULL)
53195319
return FAIL;
53205320
set_cmd_context(&compl_xp, compl_pattern,
5321-
(int)STRLEN(compl_pattern), curs_col);
5321+
(int)STRLEN(compl_pattern), curs_col, FALSE);
53225322
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
53235323
|| compl_xp.xp_context == EXPAND_NOTHING)
53245324
/* No completion possible, use an empty pattern to get a

src/evalfunc.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12425,12 +12425,14 @@ f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
1242512425
static void
1242612426
f_timer_start(typval_T *argvars, typval_T *rettv)
1242712427
{
12428-
long msec = (long)get_tv_number(&argvars[0]);
12429-
timer_T *timer;
12430-
int repeat = 0;
12431-
char_u *callback;
12432-
dict_T *dict;
12428+
long msec = (long)get_tv_number(&argvars[0]);
12429+
timer_T *timer;
12430+
int repeat = 0;
12431+
char_u *callback;
12432+
dict_T *dict;
12433+
partial_T *partial;
1243312434

12435+
rettv->vval.v_number = -1;
1243412436
if (check_secure())
1243512437
return;
1243612438
if (argvars[2].v_type != VAR_UNKNOWN)
@@ -12445,21 +12447,22 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
1244512447
repeat = get_dict_number(dict, (char_u *)"repeat");
1244612448
}
1244712449

12448-
timer = create_timer(msec, repeat);
12449-
callback = get_callback(&argvars[1], &timer->tr_partial);
12450+
callback = get_callback(&argvars[1], &partial);
1245012451
if (callback == NULL)
12451-
{
12452-
stop_timer(timer);
12453-
rettv->vval.v_number = -1;
12454-
}
12452+
return;
12453+
12454+
timer = create_timer(msec, repeat);
12455+
if (timer == NULL)
12456+
free_callback(callback, partial);
1245512457
else
1245612458
{
1245712459
if (timer->tr_partial == NULL)
1245812460
timer->tr_callback = vim_strsave(callback);
1245912461
else
1246012462
/* pointer into the partial */
1246112463
timer->tr_callback = callback;
12462-
rettv->vval.v_number = timer->tr_id;
12464+
timer->tr_partial = partial;
12465+
rettv->vval.v_number = (varnumber_T)timer->tr_id;
1246312466
}
1246412467
}
1246512468

src/ex_cmds2.c

Lines changed: 79 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,10 +1088,17 @@ profile_zero(proftime_T *tm)
10881088

10891089
# if defined(FEAT_TIMERS) || defined(PROTO)
10901090
static timer_T *first_timer = NULL;
1091-
static int last_timer_id = 0;
1091+
static long last_timer_id = 0;
10921092

1093-
static timer_T *current_timer = NULL;
1094-
static int free_current_timer = FALSE;
1093+
# ifdef WIN3264
1094+
# define GET_TIMEDIFF(timer, now) \
1095+
(long)(((double)(timer->tr_due.QuadPart - now.QuadPart) \
1096+
/ (double)fr.QuadPart) * 1000);
1097+
# else
1098+
# define GET_TIMEDIFF(timer, now) \
1099+
(timer->tr_due.tv_sec - now.tv_sec) * 1000 \
1100+
+ (timer->tr_due.tv_usec - now.tv_usec) / 1000;
1101+
# endif
10951102

10961103
/*
10971104
* Insert a timer in the list of timers.
@@ -1124,13 +1131,8 @@ remove_timer(timer_T *timer)
11241131
static void
11251132
free_timer(timer_T *timer)
11261133
{
1127-
if (timer == current_timer)
1128-
free_current_timer = TRUE;
1129-
else
1130-
{
1131-
free_callback(timer->tr_callback, timer->tr_partial);
1132-
vim_free(timer);
1133-
}
1134+
free_callback(timer->tr_callback, timer->tr_partial);
1135+
vim_free(timer);
11341136
}
11351137

11361138
/*
@@ -1144,7 +1146,10 @@ create_timer(long msec, int repeat)
11441146

11451147
if (timer == NULL)
11461148
return NULL;
1147-
timer->tr_id = ++last_timer_id;
1149+
if (++last_timer_id < 0)
1150+
/* Overflow! Might cause duplicates... */
1151+
last_timer_id = 0;
1152+
timer->tr_id = last_timer_id;
11481153
insert_timer(timer);
11491154
if (repeat != 0)
11501155
timer->tr_repeat = repeat - 1;
@@ -1165,7 +1170,7 @@ timer_callback(timer_T *timer)
11651170
typval_T argv[2];
11661171

11671172
argv[0].v_type = VAR_NUMBER;
1168-
argv[0].vval.v_number = timer->tr_id;
1173+
argv[0].vval.v_number = (varnumber_T)timer->tr_id;
11691174
argv[1].v_type = VAR_UNKNOWN;
11701175

11711176
call_func(timer->tr_callback, (int)STRLEN(timer->tr_callback),
@@ -1182,77 +1187,76 @@ timer_callback(timer_T *timer)
11821187
check_due_timer(void)
11831188
{
11841189
timer_T *timer;
1190+
timer_T *timer_next;
11851191
long this_due;
11861192
long next_due = -1;
11871193
proftime_T now;
11881194
int did_one = FALSE;
1195+
long current_id = last_timer_id;
11891196
# ifdef WIN3264
11901197
LARGE_INTEGER fr;
11911198

11921199
QueryPerformanceFrequency(&fr);
11931200
# endif
1194-
while (!got_int)
1201+
profile_start(&now);
1202+
for (timer = first_timer; timer != NULL && !got_int; timer = timer_next)
11951203
{
1196-
profile_start(&now);
1197-
next_due = -1;
1198-
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
1204+
timer_next = timer->tr_next;
1205+
1206+
if (timer->tr_id == -1 || timer->tr_firing || timer->tr_paused)
1207+
continue;
1208+
this_due = GET_TIMEDIFF(timer, now);
1209+
if (this_due <= 1)
11991210
{
1200-
if (timer->tr_paused)
1201-
continue;
1202-
# ifdef WIN3264
1203-
this_due = (long)(((double)(timer->tr_due.QuadPart - now.QuadPart)
1204-
/ (double)fr.QuadPart) * 1000);
1205-
# else
1206-
this_due = (timer->tr_due.tv_sec - now.tv_sec) * 1000
1207-
+ (timer->tr_due.tv_usec - now.tv_usec) / 1000;
1208-
# endif
1209-
if (this_due <= 1)
1211+
timer->tr_firing = TRUE;
1212+
timer_callback(timer);
1213+
timer->tr_firing = FALSE;
1214+
timer_next = timer->tr_next;
1215+
did_one = TRUE;
1216+
1217+
/* Only fire the timer again if it repeats and stop_timer() wasn't
1218+
* called while inside the callback (tr_id == -1). */
1219+
if (timer->tr_repeat != 0 && timer->tr_id != -1)
12101220
{
1211-
current_timer = timer;
1212-
free_current_timer = FALSE;
1213-
timer_callback(timer);
1214-
current_timer = NULL;
1215-
1216-
did_one = TRUE;
1217-
if (timer->tr_repeat != 0 && !free_current_timer)
1218-
{
1219-
profile_setlimit(timer->tr_interval, &timer->tr_due);
1220-
if (timer->tr_repeat > 0)
1221-
--timer->tr_repeat;
1222-
}
1223-
else
1224-
{
1225-
remove_timer(timer);
1226-
free_timer(timer);
1227-
}
1228-
/* the callback may do anything, start all over */
1229-
break;
1221+
profile_setlimit(timer->tr_interval, &timer->tr_due);
1222+
this_due = GET_TIMEDIFF(timer, now);
1223+
if (this_due < 1)
1224+
this_due = 1;
1225+
if (timer->tr_repeat > 0)
1226+
--timer->tr_repeat;
1227+
}
1228+
else
1229+
{
1230+
this_due = -1;
1231+
remove_timer(timer);
1232+
free_timer(timer);
12301233
}
1231-
if (next_due == -1 || next_due > this_due)
1232-
next_due = this_due;
12331234
}
1234-
if (timer == NULL)
1235-
break;
1235+
if (this_due > 0 && (next_due == -1 || next_due > this_due))
1236+
next_due = this_due;
12361237
}
12371238

12381239
if (did_one)
12391240
redraw_after_callback();
12401241

1241-
return next_due;
1242+
return current_id != last_timer_id ? 1 : next_due;
12421243
}
12431244

12441245
/*
12451246
* Find a timer by ID. Returns NULL if not found;
12461247
*/
12471248
timer_T *
1248-
find_timer(int id)
1249+
find_timer(long id)
12491250
{
12501251
timer_T *timer;
12511252

1252-
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
1253-
if (timer->tr_id == id)
1254-
break;
1255-
return timer;
1253+
if (id >= 0)
1254+
{
1255+
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
1256+
if (timer->tr_id == id)
1257+
return timer;
1258+
}
1259+
return NULL;
12561260
}
12571261

12581262

@@ -1262,15 +1266,27 @@ find_timer(int id)
12621266
void
12631267
stop_timer(timer_T *timer)
12641268
{
1265-
remove_timer(timer);
1266-
free_timer(timer);
1269+
if (timer->tr_firing)
1270+
/* Free the timer after the callback returns. */
1271+
timer->tr_id = -1;
1272+
else
1273+
{
1274+
remove_timer(timer);
1275+
free_timer(timer);
1276+
}
12671277
}
12681278

12691279
void
12701280
stop_all_timers(void)
12711281
{
1272-
while (first_timer != NULL)
1273-
stop_timer(first_timer);
1282+
timer_T *timer;
1283+
timer_T *timer_next;
1284+
1285+
for (timer = first_timer; timer != NULL; timer = timer_next)
1286+
{
1287+
timer_next = timer->tr_next;
1288+
stop_timer(timer);
1289+
}
12741290
}
12751291

12761292
void
@@ -1289,18 +1305,14 @@ add_timer_info(typval_T *rettv, timer_T *timer)
12891305
return;
12901306
list_append_dict(list, dict);
12911307

1292-
dict_add_nr_str(dict, "id", (long)timer->tr_id, NULL);
1308+
dict_add_nr_str(dict, "id", timer->tr_id, NULL);
12931309
dict_add_nr_str(dict, "time", (long)timer->tr_interval, NULL);
12941310

12951311
profile_start(&now);
12961312
# ifdef WIN3264
12971313
QueryPerformanceFrequency(&fr);
1298-
remaining = (long)(((double)(timer->tr_due.QuadPart - now.QuadPart)
1299-
/ (double)fr.QuadPart) * 1000);
1300-
# else
1301-
remaining = (timer->tr_due.tv_sec - now.tv_sec) * 1000
1302-
+ (timer->tr_due.tv_usec - now.tv_usec) / 1000;
13031314
# endif
1315+
remaining = GET_TIMEDIFF(timer, now);
13041316
dict_add_nr_str(dict, "remaining", (long)remaining, NULL);
13051317

13061318
dict_add_nr_str(dict, "repeat",
@@ -1333,7 +1345,8 @@ add_timer_info_all(typval_T *rettv)
13331345
timer_T *timer;
13341346

13351347
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
1336-
add_timer_info(rettv, timer);
1348+
if (timer->tr_id != -1)
1349+
add_timer_info(rettv, timer);
13371350
}
13381351

13391352
/*

src/ex_getln.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,15 +4520,16 @@ set_expand_context(expand_T *xp)
45204520
xp->xp_context = EXPAND_NOTHING;
45214521
return;
45224522
}
4523-
set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos);
4523+
set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos, TRUE);
45244524
}
45254525

45264526
void
45274527
set_cmd_context(
45284528
expand_T *xp,
45294529
char_u *str, /* start of command line */
45304530
int len, /* length of command line (excl. NUL) */
4531-
int col) /* position of cursor */
4531+
int col, /* position of cursor */
4532+
int use_ccline UNUSED) /* use ccline for info */
45324533
{
45334534
int old_char = NUL;
45344535
char_u *nextcomm;
@@ -4543,14 +4544,14 @@ set_cmd_context(
45434544
nextcomm = str;
45444545

45454546
#ifdef FEAT_EVAL
4546-
if (ccline.cmdfirstc == '=')
4547+
if (use_ccline && ccline.cmdfirstc == '=')
45474548
{
45484549
# ifdef FEAT_CMDL_COMPL
45494550
/* pass CMD_SIZE because there is no real command */
45504551
set_context_for_expression(xp, str, CMD_SIZE);
45514552
# endif
45524553
}
4553-
else if (ccline.input_fn)
4554+
else if (use_ccline && ccline.input_fn)
45544555
{
45554556
xp->xp_context = ccline.xp_context;
45564557
xp->xp_pattern = ccline.cmdbuff;

src/proto/ex_cmds2.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ int profile_passed_limit(proftime_T *tm);
2020
void profile_zero(proftime_T *tm);
2121
timer_T *create_timer(long msec, int repeat);
2222
long check_due_timer(void);
23-
timer_T *find_timer(int id);
23+
timer_T *find_timer(long id);
2424
void stop_timer(timer_T *timer);
2525
void stop_all_timers(void);
2626
void add_timer_info(typval_T *rettv, timer_T *timer);

src/proto/ex_getln.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ char_u *vim_strsave_fnameescape(char_u *fname, int shell);
3030
void tilde_replace(char_u *orig_pat, int num_files, char_u **files);
3131
char_u *sm_gettail(char_u *s);
3232
char_u *addstar(char_u *fname, int len, int context);
33-
void set_cmd_context(expand_T *xp, char_u *str, int len, int col);
33+
void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline);
3434
int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches);
3535
int ExpandGeneric(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int)), int escaped);
3636
void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options);

src/structs.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,12 +3185,13 @@ typedef struct js_reader js_read_T;
31853185
typedef struct timer_S timer_T;
31863186
struct timer_S
31873187
{
3188-
int tr_id;
3188+
long tr_id;
31893189
#ifdef FEAT_TIMERS
31903190
timer_T *tr_next;
31913191
timer_T *tr_prev;
31923192
proftime_T tr_due; /* when the callback is to be invoked */
3193-
int tr_paused; /* when TRUE callback is not invoked */
3193+
char tr_firing; /* when TRUE callback is being called */
3194+
char tr_paused; /* when TRUE callback is not invoked */
31943195
int tr_repeat; /* number of times to repeat, -1 forever */
31953196
long tr_interval; /* msec */
31963197
char_u *tr_callback; /* allocated */

src/testdir/test_getcwd.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ STARTTEST
99
:set visualbell
1010
:set nocp viminfo+=nviminfo
1111
:"
12+
:" On windows a swapfile in Xtopdir prevents it from being cleaned up.
13+
:set noswapfile
14+
:"
1215
:function! GetCwdInfo(win, tab)
1316
: let tab_changed = 0
1417
: let mod = ":t"

0 commit comments

Comments
 (0)