Skip to content

Commit 5241057

Browse files
committed
patch 8.1.2225: the "last used" info of a buffer is under used
Problem: The "last used" info of a buffer is under used. Solution: Add "lastused" to getbufinfo(). List buffers sorted by last-used field. (Andi Massimino, closes #4722)
1 parent dfded98 commit 5241057

18 files changed

Lines changed: 228 additions & 45 deletions

runtime/doc/eval.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4778,6 +4778,10 @@ getbufinfo([{dict}])
47784778
changed TRUE if the buffer is modified.
47794779
changedtick number of changes made to the buffer.
47804780
hidden TRUE if the buffer is hidden.
4781+
lastused timestamp in seconds, like
4782+
|localtime()|, when the buffer was
4783+
last used.
4784+
{only with the |+viminfo| feature}
47814785
listed TRUE if the buffer is listed.
47824786
lnum current line number in buffer.
47834787
loaded TRUE if the buffer is loaded.

runtime/doc/options.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8689,6 +8689,8 @@ A jump table for the options with a short description can be found at |Q_op|.
86898689
complete first match.
86908690
"list:longest" When more than one match, list all matches and
86918691
complete till longest common string.
8692+
"list:lastused" When more than one buffer matches, sort buffers
8693+
by time last used (other than the current buffer).
86928694
When there is only a single match, it is fully completed in all cases.
86938695

86948696
Examples: >

runtime/doc/windows.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,7 @@ list of buffers. |unlisted-buffer|
10901090
R terminal buffers with a running job
10911091
F terminal buffers with a finished job
10921092
? terminal buffers without a job: `:terminal NONE`
1093+
t show time last used and sort buffers
10931094
Combining flags means they are "and"ed together, e.g.:
10941095
h+ hidden buffers which are modified
10951096
a+ active buffers which are modified

src/buffer.c

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,13 @@ buflist_findpat(
26012601
return match;
26022602
}
26032603

2604+
#ifdef FEAT_VIMINFO
2605+
typedef struct {
2606+
buf_T *buf;
2607+
char_u *match;
2608+
} bufmatch_T;
2609+
#endif
2610+
26042611
/*
26052612
* Find all buffer names that match.
26062613
* For command line expansion of ":buf" and ":sbuf".
@@ -2619,6 +2626,9 @@ ExpandBufnames(
26192626
char_u *p;
26202627
int attempt;
26212628
char_u *patc;
2629+
#ifdef FEAT_VIMINFO
2630+
bufmatch_T *matches = NULL;
2631+
#endif
26222632

26232633
*num_file = 0; /* return values in case of FAIL */
26242634
*file = NULL;
@@ -2675,7 +2685,16 @@ ExpandBufnames(
26752685
p = home_replace_save(buf, p);
26762686
else
26772687
p = vim_strsave(p);
2678-
(*file)[count++] = p;
2688+
#ifdef FEAT_VIMINFO
2689+
if (matches != NULL)
2690+
{
2691+
matches[count].buf = buf;
2692+
matches[count].match = p;
2693+
count++;
2694+
}
2695+
else
2696+
#endif
2697+
(*file)[count++] = p;
26792698
}
26802699
}
26812700
}
@@ -2691,6 +2710,10 @@ ExpandBufnames(
26912710
vim_free(patc);
26922711
return FAIL;
26932712
}
2713+
#ifdef FEAT_VIMINFO
2714+
if (options & WILD_BUFLASTUSED)
2715+
matches = ALLOC_MULT(bufmatch_T, count);
2716+
#endif
26942717
}
26952718
}
26962719
vim_regfree(regmatch.regprog);
@@ -2701,6 +2724,28 @@ ExpandBufnames(
27012724
if (patc != pat)
27022725
vim_free(patc);
27032726

2727+
#ifdef FEAT_VIMINFO
2728+
if (matches != NULL)
2729+
{
2730+
int i;
2731+
if (count > 1)
2732+
qsort(matches, count, sizeof(bufmatch_T), buf_compare);
2733+
// if the current buffer is first in the list, place it at the end
2734+
if (matches[0].buf == curbuf)
2735+
{
2736+
for (i = 1; i < count; i++)
2737+
(*file)[i-1] = matches[i].match;
2738+
(*file)[count-1] = matches[0].match;
2739+
}
2740+
else
2741+
{
2742+
for (i = 0; i < count; i++)
2743+
(*file)[i] = matches[i].match;
2744+
}
2745+
vim_free(matches);
2746+
}
2747+
#endif
2748+
27042749
*num_file = count;
27052750
return (count == 0 ? FAIL : OK);
27062751
}
@@ -3016,7 +3061,7 @@ buflist_findlnum(buf_T *buf)
30163061
void
30173062
buflist_list(exarg_T *eap)
30183063
{
3019-
buf_T *buf;
3064+
buf_T *buf = firstbuf;
30203065
int len;
30213066
int i;
30223067
int ro_char;
@@ -3026,7 +3071,32 @@ buflist_list(exarg_T *eap)
30263071
int job_none_open;
30273072
#endif
30283073

3074+
#ifdef FEAT_VIMINFO
3075+
garray_T buflist;
3076+
buf_T **buflist_data = NULL, **p;
3077+
3078+
if (vim_strchr(eap->arg, 't'))
3079+
{
3080+
ga_init2(&buflist, sizeof(buf_T *), 50);
3081+
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
3082+
{
3083+
if (ga_grow(&buflist, 1) == OK)
3084+
((buf_T **)buflist.ga_data)[buflist.ga_len++] = buf;
3085+
}
3086+
3087+
qsort(buflist.ga_data, (size_t)buflist.ga_len,
3088+
sizeof(buf_T *), buf_compare);
3089+
3090+
p = buflist_data = (buf_T **)buflist.ga_data;
3091+
buf = *p;
3092+
}
3093+
3094+
for (; buf != NULL && !got_int; buf = buflist_data
3095+
? (++p < buflist_data + buflist.ga_len ? *p : NULL)
3096+
: buf->b_next)
3097+
#else
30293098
for (buf = firstbuf; buf != NULL && !got_int; buf = buf->b_next)
3099+
#endif
30303100
{
30313101
#ifdef FEAT_TERMINAL
30323102
job_running = term_job_running(buf->b_term);
@@ -3100,13 +3170,23 @@ buflist_list(exarg_T *eap)
31003170
do
31013171
IObuff[len++] = ' ';
31023172
while (--i > 0 && len < IOSIZE - 18);
3103-
vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len),
3104-
_("line %ld"), buf == curbuf ? curwin->w_cursor.lnum
3173+
#ifdef FEAT_VIMINFO
3174+
if (vim_strchr(eap->arg, 't') && buf->b_last_used)
3175+
add_time(IObuff + len, (size_t)(IOSIZE - len), buf->b_last_used);
3176+
else
3177+
#endif
3178+
vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len),
3179+
_("line %ld"), buf == curbuf ? curwin->w_cursor.lnum
31053180
: (long)buflist_findlnum(buf));
31063181
msg_outtrans(IObuff);
31073182
out_flush(); /* output one line at a time */
31083183
ui_breakcheck();
31093184
}
3185+
3186+
#ifdef FEAT_VIMINFO
3187+
if (buflist_data)
3188+
ga_clear(&buflist);
3189+
#endif
31103190
}
31113191

31123192
/*

src/evalbuffer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,10 @@ get_buffer_info(buf_T *buf)
595595
}
596596
#endif
597597

598+
#ifdef FEAT_VIMINFO
599+
dict_add_number(dict, "lastused", buf->b_last_used);
600+
#endif
601+
598602
return dict;
599603
}
600604

src/ex_getln.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,9 @@ getcmdline_int(
14071407
*/
14081408
if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm)
14091409
{
1410+
int options = WILD_NO_BEEP;
1411+
if (wim_flags[wim_index] & WIM_BUFLASTUSED)
1412+
options |= WILD_BUFLASTUSED;
14101413
if (xpc.xp_numfiles > 0) /* typed p_wc at least twice */
14111414
{
14121415
/* if 'wildmode' contains "list" may still need to list */
@@ -1419,10 +1422,10 @@ getcmdline_int(
14191422
did_wild_list = TRUE;
14201423
}
14211424
if (wim_flags[wim_index] & WIM_LONGEST)
1422-
res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
1425+
res = nextwild(&xpc, WILD_LONGEST, options,
14231426
firstc != '@');
14241427
else if (wim_flags[wim_index] & WIM_FULL)
1425-
res = nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP,
1428+
res = nextwild(&xpc, WILD_NEXT, options,
14261429
firstc != '@');
14271430
else
14281431
res = OK; /* don't insert 'wildchar' now */
@@ -1434,10 +1437,10 @@ getcmdline_int(
14341437
/* if 'wildmode' first contains "longest", get longest
14351438
* common part */
14361439
if (wim_flags[0] & WIM_LONGEST)
1437-
res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
1440+
res = nextwild(&xpc, WILD_LONGEST, options,
14381441
firstc != '@');
14391442
else
1440-
res = nextwild(&xpc, WILD_EXPAND_KEEP, WILD_NO_BEEP,
1443+
res = nextwild(&xpc, WILD_EXPAND_KEEP, options,
14411444
firstc != '@');
14421445

14431446
/* if interrupted while completing, behave like it failed */
@@ -1488,10 +1491,10 @@ getcmdline_int(
14881491
redrawcmd();
14891492
did_wild_list = TRUE;
14901493
if (wim_flags[wim_index] & WIM_LONGEST)
1491-
nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
1494+
nextwild(&xpc, WILD_LONGEST, options,
14921495
firstc != '@');
14931496
else if (wim_flags[wim_index] & WIM_FULL)
1494-
nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP,
1497+
nextwild(&xpc, WILD_NEXT, options,
14951498
firstc != '@');
14961499
}
14971500
else

src/misc1.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2576,3 +2576,34 @@ path_with_url(char_u *fname)
25762576
;
25772577
return path_is_url(p);
25782578
}
2579+
2580+
/*
2581+
* Put timestamp "tt" in "buf[buflen]" in a nice format.
2582+
*/
2583+
void
2584+
add_time(char_u *buf, size_t buflen, time_t tt)
2585+
{
2586+
#ifdef HAVE_STRFTIME
2587+
struct tm tmval;
2588+
struct tm *curtime;
2589+
2590+
if (vim_time() - tt >= 100)
2591+
{
2592+
curtime = vim_localtime(&tt, &tmval);
2593+
if (vim_time() - tt < (60L * 60L * 12L))
2594+
/* within 12 hours */
2595+
(void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
2596+
else
2597+
/* longer ago */
2598+
(void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime);
2599+
}
2600+
else
2601+
#endif
2602+
{
2603+
long seconds = (long)(vim_time() - tt);
2604+
2605+
vim_snprintf((char *)buf, buflen,
2606+
NGETTEXT("%ld second ago", "%ld seconds ago", seconds),
2607+
seconds);
2608+
}
2609+
}

src/option.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6987,6 +6987,8 @@ check_opt_wim(void)
69876987
new_wim_flags[idx] |= WIM_FULL;
69886988
else if (i == 4 && STRNCMP(p, "list", 4) == 0)
69896989
new_wim_flags[idx] |= WIM_LIST;
6990+
else if (i == 8 && STRNCMP(p, "lastused", 8) == 0)
6991+
new_wim_flags[idx] |= WIM_BUFLASTUSED;
69906992
else
69916993
return FAIL;
69926994
p += i;

src/option.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@
338338
#define WIM_FULL 0x01
339339
#define WIM_LONGEST 0x02
340340
#define WIM_LIST 0x04
341+
#define WIM_BUFLASTUSED 0x08
341342

342343
// arguments for can_bs()
343344
#define BS_INDENT 'i' // "Indent"

src/proto/misc1.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ int goto_im(void);
4646
char_u *get_isolated_shell_name(void);
4747
int path_is_url(char_u *p);
4848
int path_with_url(char_u *fname);
49+
void add_time(char_u *buf, size_t buflen, time_t tt);
4950
/* vim: set ft=c : */

0 commit comments

Comments
 (0)