mirror of
https://github.com/neovim/neovim.git
synced 2025-09-13 14:58:18 +00:00
vim-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 vim/vim#4722)
52410575be
This commit is contained in:
@@ -4164,6 +4164,9 @@ getbufinfo([{dict}])
|
|||||||
changed TRUE if the buffer is modified.
|
changed TRUE if the buffer is modified.
|
||||||
changedtick number of changes made to the buffer.
|
changedtick number of changes made to the buffer.
|
||||||
hidden TRUE if the buffer is hidden.
|
hidden TRUE if the buffer is hidden.
|
||||||
|
lastused timestamp in seconds, like
|
||||||
|
|localtime()|, when the buffer was
|
||||||
|
last used.
|
||||||
listed TRUE if the buffer is listed.
|
listed TRUE if the buffer is listed.
|
||||||
lnum current line number in buffer.
|
lnum current line number in buffer.
|
||||||
linecount number of lines in the buffer (only
|
linecount number of lines in the buffer (only
|
||||||
|
@@ -6742,6 +6742,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
complete first match.
|
complete first match.
|
||||||
"list:longest" When more than one match, list all matches and
|
"list:longest" When more than one match, list all matches and
|
||||||
complete till longest common string.
|
complete till longest common string.
|
||||||
|
"list:lastused" When more than one buffer matches, sort buffers
|
||||||
|
by time last used (other than the current buffer).
|
||||||
When there is only a single match, it is fully completed in all cases.
|
When there is only a single match, it is fully completed in all cases.
|
||||||
|
|
||||||
Examples: >
|
Examples: >
|
||||||
|
@@ -1023,6 +1023,7 @@ list of buffers. |unlisted-buffer|
|
|||||||
# alternate buffer
|
# alternate buffer
|
||||||
R terminal buffers with a running job
|
R terminal buffers with a running job
|
||||||
F terminal buffers with a finished job
|
F terminal buffers with a finished job
|
||||||
|
t show time last used and sort buffers
|
||||||
Combining flags means they are "and"ed together, e.g.:
|
Combining flags means they are "and"ed together, e.g.:
|
||||||
h+ hidden buffers which are modified
|
h+ hidden buffers which are modified
|
||||||
a+ active buffers which are modified
|
a+ active buffers which are modified
|
||||||
|
@@ -2251,6 +2251,23 @@ int buflist_findpat(
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
buf_T *buf;
|
||||||
|
char_u *match;
|
||||||
|
} bufmatch_T;
|
||||||
|
|
||||||
|
/// Compare functions for qsort() below, that compares b_last_used.
|
||||||
|
static int
|
||||||
|
buf_time_compare(const void *s1, const void *s2)
|
||||||
|
{
|
||||||
|
buf_T *buf1 = *(buf_T **)s1;
|
||||||
|
buf_T *buf2 = *(buf_T **)s2;
|
||||||
|
|
||||||
|
if (buf1->b_last_used == buf2->b_last_used) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return buf1->b_last_used > buf2->b_last_used ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find all buffer names that match.
|
* Find all buffer names that match.
|
||||||
@@ -2264,6 +2281,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
|
|||||||
char_u *p;
|
char_u *p;
|
||||||
int attempt;
|
int attempt;
|
||||||
char_u *patc;
|
char_u *patc;
|
||||||
|
bufmatch_T *matches = NULL;
|
||||||
|
|
||||||
*num_file = 0; // return values in case of FAIL
|
*num_file = 0; // return values in case of FAIL
|
||||||
*file = NULL;
|
*file = NULL;
|
||||||
@@ -2314,15 +2332,25 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
|
|||||||
} else {
|
} else {
|
||||||
p = vim_strsave(p);
|
p = vim_strsave(p);
|
||||||
}
|
}
|
||||||
|
if (matches != NULL) {
|
||||||
|
matches[count].buf = buf;
|
||||||
|
matches[count].match = p;
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
(*file)[count++] = p;
|
(*file)[count++] = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (count == 0) { // no match found, break here
|
if (count == 0) { // no match found, break here
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (round == 1) {
|
if (round == 1) {
|
||||||
*file = xmalloc((size_t)count * sizeof(**file));
|
*file = xmalloc((size_t)count * sizeof(**file));
|
||||||
|
|
||||||
|
if (options & WILD_BUFLASTUSED) {
|
||||||
|
matches = xmalloc((size_t)count * sizeof(*matches));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vim_regfree(regmatch.regprog);
|
vim_regfree(regmatch.regprog);
|
||||||
@@ -2335,6 +2363,25 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
|
|||||||
xfree(patc);
|
xfree(patc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (matches != NULL) {
|
||||||
|
if (count > 1) {
|
||||||
|
qsort(matches, (size_t)count, sizeof(bufmatch_T), buf_time_compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the current buffer is first in the list, place it at the end
|
||||||
|
if (matches[0].buf == curbuf) {
|
||||||
|
for (int i = 1; i < count; i++) {
|
||||||
|
(*file)[i-1] = matches[i].match;
|
||||||
|
}
|
||||||
|
(*file)[count-1] = matches[0].match;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
(*file)[i] = matches[i].match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xfree(matches);
|
||||||
|
}
|
||||||
|
|
||||||
*num_file = count;
|
*num_file = count;
|
||||||
return count == 0 ? FAIL : OK;
|
return count == 0 ? FAIL : OK;
|
||||||
}
|
}
|
||||||
@@ -2595,11 +2642,32 @@ linenr_T buflist_findlnum(buf_T *buf)
|
|||||||
// List all known file names (for :files and :buffers command).
|
// List all known file names (for :files and :buffers command).
|
||||||
void buflist_list(exarg_T *eap)
|
void buflist_list(exarg_T *eap)
|
||||||
{
|
{
|
||||||
buf_T *buf;
|
buf_T *buf = firstbuf;
|
||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (buf = firstbuf; buf != NULL && !got_int; buf = buf->b_next) {
|
garray_T buflist;
|
||||||
|
buf_T **buflist_data = NULL, **p;
|
||||||
|
|
||||||
|
if (vim_strchr(eap->arg, 't')) {
|
||||||
|
ga_init(&buflist, sizeof(buf_T *), 50);
|
||||||
|
for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
|
||||||
|
ga_grow(&buflist, 1);
|
||||||
|
((buf_T **)buflist.ga_data)[buflist.ga_len++] = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(buflist.ga_data, (size_t)buflist.ga_len,
|
||||||
|
sizeof(buf_T *), buf_time_compare);
|
||||||
|
|
||||||
|
p = buflist_data = (buf_T **)buflist.ga_data;
|
||||||
|
buf = *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;
|
||||||
|
buf != NULL && !got_int;
|
||||||
|
buf = buflist_data
|
||||||
|
? (++p < buflist_data + buflist.ga_len ? *p : NULL)
|
||||||
|
: buf->b_next) {
|
||||||
const bool is_terminal = buf->terminal;
|
const bool is_terminal = buf->terminal;
|
||||||
const bool job_running = buf->terminal && terminal_running(buf->terminal);
|
const bool job_running = buf->terminal && terminal_running(buf->terminal);
|
||||||
|
|
||||||
@@ -2660,13 +2728,22 @@ void buflist_list(exarg_T *eap)
|
|||||||
do {
|
do {
|
||||||
IObuff[len++] = ' ';
|
IObuff[len++] = ' ';
|
||||||
} while (--i > 0 && len < IOSIZE - 18);
|
} while (--i > 0 && len < IOSIZE - 18);
|
||||||
|
if (vim_strchr(eap->arg, 't') && buf->b_last_used) {
|
||||||
|
add_time(IObuff + len, (size_t)(IOSIZE - len), buf->b_last_used);
|
||||||
|
} else {
|
||||||
vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len),
|
vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len),
|
||||||
_("line %" PRId64),
|
_("line %" PRId64),
|
||||||
buf == curbuf ? (int64_t)curwin->w_cursor.lnum
|
buf == curbuf ? (int64_t)curwin->w_cursor.lnum
|
||||||
: (int64_t)buflist_findlnum(buf));
|
: (int64_t)buflist_findlnum(buf));
|
||||||
|
}
|
||||||
|
|
||||||
msg_outtrans(IObuff);
|
msg_outtrans(IObuff);
|
||||||
line_breakcheck();
|
line_breakcheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buflist_data) {
|
||||||
|
ga_clear(&buflist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -7241,6 +7241,8 @@ dict_T *get_buffer_info(buf_T *buf)
|
|||||||
tv_dict_add_list(dict, S_LEN("signs"), get_buffer_signs(buf));
|
tv_dict_add_list(dict, S_LEN("signs"), get_buffer_signs(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tv_dict_add_nr(dict, S_LEN("lastused"), buf->b_last_used);
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -947,6 +947,10 @@ static int command_line_execute(VimState *state, int key)
|
|||||||
// - wildcard expansion is only done when the 'wildchar' key is really
|
// - wildcard expansion is only done when the 'wildchar' key is really
|
||||||
// typed, not when it comes from a macro
|
// typed, not when it comes from a macro
|
||||||
if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm) {
|
if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm) {
|
||||||
|
int options = WILD_NO_BEEP;
|
||||||
|
if (wim_flags[s->wim_index] & WIM_BUFLASTUSED) {
|
||||||
|
options |= WILD_BUFLASTUSED;
|
||||||
|
}
|
||||||
if (s->xpc.xp_numfiles > 0) { // typed p_wc at least twice
|
if (s->xpc.xp_numfiles > 0) { // typed p_wc at least twice
|
||||||
// if 'wildmode' contains "list" may still need to list
|
// if 'wildmode' contains "list" may still need to list
|
||||||
if (s->xpc.xp_numfiles > 1
|
if (s->xpc.xp_numfiles > 1
|
||||||
@@ -960,10 +964,10 @@ static int command_line_execute(VimState *state, int key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wim_flags[s->wim_index] & WIM_LONGEST) {
|
if (wim_flags[s->wim_index] & WIM_LONGEST) {
|
||||||
s->res = nextwild(&s->xpc, WILD_LONGEST, WILD_NO_BEEP,
|
s->res = nextwild(&s->xpc, WILD_LONGEST, options,
|
||||||
s->firstc != '@');
|
s->firstc != '@');
|
||||||
} else if (wim_flags[s->wim_index] & WIM_FULL) {
|
} else if (wim_flags[s->wim_index] & WIM_FULL) {
|
||||||
s->res = nextwild(&s->xpc, WILD_NEXT, WILD_NO_BEEP,
|
s->res = nextwild(&s->xpc, WILD_NEXT, options,
|
||||||
s->firstc != '@');
|
s->firstc != '@');
|
||||||
} else {
|
} else {
|
||||||
s->res = OK; // don't insert 'wildchar' now
|
s->res = OK; // don't insert 'wildchar' now
|
||||||
@@ -975,10 +979,10 @@ static int command_line_execute(VimState *state, int key)
|
|||||||
// if 'wildmode' first contains "longest", get longest
|
// if 'wildmode' first contains "longest", get longest
|
||||||
// common part
|
// common part
|
||||||
if (wim_flags[0] & WIM_LONGEST) {
|
if (wim_flags[0] & WIM_LONGEST) {
|
||||||
s->res = nextwild(&s->xpc, WILD_LONGEST, WILD_NO_BEEP,
|
s->res = nextwild(&s->xpc, WILD_LONGEST, options,
|
||||||
s->firstc != '@');
|
s->firstc != '@');
|
||||||
} else {
|
} else {
|
||||||
s->res = nextwild(&s->xpc, WILD_EXPAND_KEEP, WILD_NO_BEEP,
|
s->res = nextwild(&s->xpc, WILD_EXPAND_KEEP, options,
|
||||||
s->firstc != '@');
|
s->firstc != '@');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1016,10 +1020,10 @@ static int command_line_execute(VimState *state, int key)
|
|||||||
s->did_wild_list = true;
|
s->did_wild_list = true;
|
||||||
|
|
||||||
if (wim_flags[s->wim_index] & WIM_LONGEST) {
|
if (wim_flags[s->wim_index] & WIM_LONGEST) {
|
||||||
nextwild(&s->xpc, WILD_LONGEST, WILD_NO_BEEP,
|
nextwild(&s->xpc, WILD_LONGEST, options,
|
||||||
s->firstc != '@');
|
s->firstc != '@');
|
||||||
} else if (wim_flags[s->wim_index] & WIM_FULL) {
|
} else if (wim_flags[s->wim_index] & WIM_FULL) {
|
||||||
nextwild(&s->xpc, WILD_NEXT, WILD_NO_BEEP,
|
nextwild(&s->xpc, WILD_NEXT, options,
|
||||||
s->firstc != '@');
|
s->firstc != '@');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#define WILD_ALLLINKS 0x200
|
#define WILD_ALLLINKS 0x200
|
||||||
#define WILD_IGNORE_COMPLETESLASH 0x400
|
#define WILD_IGNORE_COMPLETESLASH 0x400
|
||||||
#define WILD_NOERROR 0x800 // sets EW_NOERROR
|
#define WILD_NOERROR 0x800 // sets EW_NOERROR
|
||||||
|
#define WILD_BUFLASTUSED 0x1000
|
||||||
|
|
||||||
/// Present history tables
|
/// Present history tables
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@@ -1162,3 +1162,26 @@ int goto_im(void)
|
|||||||
{
|
{
|
||||||
return p_im && stuff_empty() && typebuf_typed();
|
return p_im && stuff_empty() && typebuf_typed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Put the timestamp of an undo header in "buf[buflen]" in a nice format.
|
||||||
|
void add_time(char_u *buf, size_t buflen, time_t tt)
|
||||||
|
{
|
||||||
|
struct tm curtime;
|
||||||
|
|
||||||
|
if (time(NULL) - tt >= 100) {
|
||||||
|
os_localtime_r(&tt, &curtime);
|
||||||
|
if (time(NULL) - tt < (60L * 60L * 12L)) {
|
||||||
|
// within 12 hours
|
||||||
|
(void)strftime((char *)buf, buflen, "%H:%M:%S", &curtime);
|
||||||
|
} else {
|
||||||
|
// longer ago
|
||||||
|
(void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", &curtime);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int64_t seconds = time(NULL) - tt;
|
||||||
|
vim_snprintf((char *)buf, buflen,
|
||||||
|
NGETTEXT("%" PRId64 " second ago",
|
||||||
|
"%" PRId64 " seconds ago", (uint32_t)seconds),
|
||||||
|
seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -7083,6 +7083,8 @@ static int check_opt_wim(void)
|
|||||||
new_wim_flags[idx] |= WIM_FULL;
|
new_wim_flags[idx] |= WIM_FULL;
|
||||||
} else if (i == 4 && STRNCMP(p, "list", 4) == 0) {
|
} else if (i == 4 && STRNCMP(p, "list", 4) == 0) {
|
||||||
new_wim_flags[idx] |= WIM_LIST;
|
new_wim_flags[idx] |= WIM_LIST;
|
||||||
|
} else if (i == 8 && STRNCMP(p, "lastused", 8) == 0) {
|
||||||
|
new_wim_flags[idx] |= WIM_BUFLASTUSED;
|
||||||
} else {
|
} else {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
@@ -277,6 +277,7 @@ enum {
|
|||||||
#define WIM_FULL 1
|
#define WIM_FULL 1
|
||||||
#define WIM_LONGEST 2
|
#define WIM_LONGEST 2
|
||||||
#define WIM_LIST 4
|
#define WIM_LIST 4
|
||||||
|
#define WIM_BUFLASTUSED 8
|
||||||
|
|
||||||
// arguments for can_bs()
|
// arguments for can_bs()
|
||||||
#define BS_INDENT 'i' // "Indent"
|
#define BS_INDENT 'i' // "Indent"
|
||||||
|
@@ -149,3 +149,10 @@ func Test_getbufinfo_lines()
|
|||||||
edit Xfoo
|
edit Xfoo
|
||||||
bw!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
function Test_getbufinfo_lastused()
|
||||||
|
new Xfoo
|
||||||
|
let info = getbufinfo('Xfoo')[0]
|
||||||
|
call assert_equal(has_key(info, 'lastused'), 1)
|
||||||
|
call assert_equal(type(info.lastused), type(0))
|
||||||
|
endfunc
|
||||||
|
@@ -755,3 +755,49 @@ func Test_cmdwin_feedkeys()
|
|||||||
" This should not generate E488
|
" This should not generate E488
|
||||||
call feedkeys("q:\<CR>", 'x')
|
call feedkeys("q:\<CR>", 'x')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_buffers_lastused()
|
||||||
|
" check that buffers are sorted by time when wildmode has lastused
|
||||||
|
edit bufc " oldest
|
||||||
|
|
||||||
|
sleep 1200m
|
||||||
|
enew
|
||||||
|
edit bufa " middle
|
||||||
|
|
||||||
|
sleep 1200m
|
||||||
|
enew
|
||||||
|
edit bufb " newest
|
||||||
|
|
||||||
|
enew
|
||||||
|
|
||||||
|
call assert_equal(['bufc', 'bufa', 'bufb'],
|
||||||
|
\ getcompletion('', 'buffer'))
|
||||||
|
|
||||||
|
let save_wildmode = &wildmode
|
||||||
|
set wildmode=full:lastused
|
||||||
|
|
||||||
|
let cap = "\<c-r>=execute('let X=getcmdline()')\<cr>"
|
||||||
|
call feedkeys(":b \<tab>" .. cap .. "\<esc>", 'xt')
|
||||||
|
call assert_equal('b bufb', X)
|
||||||
|
call feedkeys(":b \<tab>\<tab>" .. cap .. "\<esc>", 'xt')
|
||||||
|
call assert_equal('b bufa', X)
|
||||||
|
call feedkeys(":b \<tab>\<tab>\<tab>" .. cap .. "\<esc>", 'xt')
|
||||||
|
call assert_equal('b bufc', X)
|
||||||
|
enew
|
||||||
|
|
||||||
|
sleep 1200m
|
||||||
|
edit other
|
||||||
|
call feedkeys(":b \<tab>" .. cap .. "\<esc>", 'xt')
|
||||||
|
call assert_equal('b bufb', X)
|
||||||
|
call feedkeys(":b \<tab>\<tab>" .. cap .. "\<esc>", 'xt')
|
||||||
|
call assert_equal('b bufa', X)
|
||||||
|
call feedkeys(":b \<tab>\<tab>\<tab>" .. cap .. "\<esc>", 'xt')
|
||||||
|
call assert_equal('b bufc', X)
|
||||||
|
enew
|
||||||
|
|
||||||
|
let &wildmode = save_wildmode
|
||||||
|
|
||||||
|
bwipeout bufa
|
||||||
|
bwipeout bufb
|
||||||
|
bwipeout bufc
|
||||||
|
endfunc
|
||||||
|
@@ -8,3 +8,35 @@ func Test_ex_delete()
|
|||||||
.dl
|
.dl
|
||||||
call assert_equal(['a', 'c'], getline(1, 2))
|
call assert_equal(['a', 'c'], getline(1, 2))
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_buffers_lastused()
|
||||||
|
edit bufc " oldest
|
||||||
|
|
||||||
|
sleep 1200m
|
||||||
|
edit bufa " middle
|
||||||
|
|
||||||
|
sleep 1200m
|
||||||
|
edit bufb " newest
|
||||||
|
|
||||||
|
enew
|
||||||
|
|
||||||
|
let ls = split(execute('buffers t', 'silent!'), '\n')
|
||||||
|
let bufs = []
|
||||||
|
for line in ls
|
||||||
|
let bufs += [split(line, '"\s*')[1:2]]
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let names = []
|
||||||
|
for buf in bufs
|
||||||
|
if buf[0] !=# '[No Name]'
|
||||||
|
let names += [buf[0]]
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call assert_equal(['bufb', 'bufa', 'bufc'], names)
|
||||||
|
call assert_match('[0-2] seconds ago', bufs[1][1])
|
||||||
|
|
||||||
|
bwipeout bufa
|
||||||
|
bwipeout bufb
|
||||||
|
bwipeout bufc
|
||||||
|
endfunc
|
||||||
|
@@ -2441,10 +2441,11 @@ static void u_undo_end(
|
|||||||
uhp = curbuf->b_u_newhead;
|
uhp = curbuf->b_u_newhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uhp == NULL)
|
if (uhp == NULL) {
|
||||||
*msgbuf = NUL;
|
*msgbuf = NUL;
|
||||||
else
|
} else {
|
||||||
u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
|
add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
@@ -2509,7 +2510,7 @@ void ex_undolist(exarg_T *eap)
|
|||||||
&& uhp->uh_walk != mark) {
|
&& uhp->uh_walk != mark) {
|
||||||
vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ",
|
vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ",
|
||||||
uhp->uh_seq, changes);
|
uhp->uh_seq, changes);
|
||||||
u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
|
add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
|
||||||
uhp->uh_time);
|
uhp->uh_time);
|
||||||
if (uhp->uh_save_nr > 0) {
|
if (uhp->uh_save_nr > 0) {
|
||||||
while (STRLEN(IObuff) < 33)
|
while (STRLEN(IObuff) < 33)
|
||||||
@@ -2574,30 +2575,6 @@ void ex_undolist(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Put the timestamp of an undo header in "buf[buflen]" in a nice format.
|
|
||||||
*/
|
|
||||||
static void u_add_time(char_u *buf, size_t buflen, time_t tt)
|
|
||||||
{
|
|
||||||
struct tm curtime;
|
|
||||||
|
|
||||||
if (time(NULL) - tt >= 100) {
|
|
||||||
os_localtime_r(&tt, &curtime);
|
|
||||||
if (time(NULL) - tt < (60L * 60L * 12L))
|
|
||||||
/* within 12 hours */
|
|
||||||
(void)strftime((char *)buf, buflen, "%H:%M:%S", &curtime);
|
|
||||||
else
|
|
||||||
/* longer ago */
|
|
||||||
(void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", &curtime);
|
|
||||||
} else {
|
|
||||||
int64_t seconds = time(NULL) - tt;
|
|
||||||
vim_snprintf((char *)buf, buflen,
|
|
||||||
NGETTEXT("%" PRId64 " second ago",
|
|
||||||
"%" PRId64 " seconds ago", (uint32_t)seconds),
|
|
||||||
seconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ":undojoin": continue adding to the last entry list
|
* ":undojoin": continue adding to the last entry list
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user