mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.1.0313: information about a swap file is unavailable
Problem: Information about a swap file is unavailable. Solution: Add swapinfo(). (Enzo Ferber)
This commit is contained in:
parent
8e82c057ff
commit
00f123a565
@ -2409,6 +2409,7 @@ submatch({nr} [, {list}]) String or List
|
|||||||
specific match in ":s" or substitute()
|
specific match in ":s" or substitute()
|
||||||
substitute({expr}, {pat}, {sub}, {flags})
|
substitute({expr}, {pat}, {sub}, {flags})
|
||||||
String all {pat} in {expr} replaced with {sub}
|
String all {pat} in {expr} replaced with {sub}
|
||||||
|
swapinfo({fname}) Dict information about swap file {fname}
|
||||||
synID({lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
|
synID({lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
|
||||||
synIDattr({synID}, {what} [, {mode}])
|
synIDattr({synID}, {what} [, {mode}])
|
||||||
String attribute {what} of syntax ID {synID}
|
String attribute {what} of syntax ID {synID}
|
||||||
@ -8001,6 +8002,22 @@ substitute({expr}, {pat}, {sub}, {flags}) *substitute()*
|
|||||||
|submatch()| returns. Example: >
|
|submatch()| returns. Example: >
|
||||||
:echo substitute(s, '%\(\x\x\)', {m -> '0x' . m[1]}, 'g')
|
:echo substitute(s, '%\(\x\x\)', {m -> '0x' . m[1]}, 'g')
|
||||||
|
|
||||||
|
swapinfo({fname}) swapinfo()
|
||||||
|
The result is a dictionary, which holds information about the
|
||||||
|
swapfile {fname}. The available fields are:
|
||||||
|
version VIM version
|
||||||
|
user user name
|
||||||
|
host host name
|
||||||
|
fname original file name
|
||||||
|
pid PID of the VIM process that created the swap
|
||||||
|
file
|
||||||
|
mtime last modification time in seconds
|
||||||
|
inode Optional: INODE number of the file
|
||||||
|
In case of failure an "error" item is added with the reason:
|
||||||
|
Cannot open file: file not found or in accessible
|
||||||
|
Cannot read file: cannot read first block
|
||||||
|
magic number mismatch: info in first block is invalid
|
||||||
|
|
||||||
synID({lnum}, {col}, {trans}) *synID()*
|
synID({lnum}, {col}, {trans}) *synID()*
|
||||||
The result is a Number, which is the syntax ID at the position
|
The result is a Number, which is the syntax ID at the position
|
||||||
{lnum} and {col} in the current window.
|
{lnum} and {col} in the current window.
|
||||||
|
@ -398,6 +398,7 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_strwidth(typval_T *argvars, typval_T *rettv);
|
static void f_strwidth(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_submatch(typval_T *argvars, typval_T *rettv);
|
static void f_submatch(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_substitute(typval_T *argvars, typval_T *rettv);
|
static void f_substitute(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_swapinfo(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_synID(typval_T *argvars, typval_T *rettv);
|
static void f_synID(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_synIDattr(typval_T *argvars, typval_T *rettv);
|
static void f_synIDattr(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_synIDtrans(typval_T *argvars, typval_T *rettv);
|
static void f_synIDtrans(typval_T *argvars, typval_T *rettv);
|
||||||
@ -859,6 +860,7 @@ static struct fst
|
|||||||
{"strwidth", 1, 1, f_strwidth},
|
{"strwidth", 1, 1, f_strwidth},
|
||||||
{"submatch", 1, 2, f_submatch},
|
{"submatch", 1, 2, f_submatch},
|
||||||
{"substitute", 4, 4, f_substitute},
|
{"substitute", 4, 4, f_substitute},
|
||||||
|
{"swapinfo", 1, 1, f_swapinfo},
|
||||||
{"synID", 3, 3, f_synID},
|
{"synID", 3, 3, f_synID},
|
||||||
{"synIDattr", 2, 3, f_synIDattr},
|
{"synIDattr", 2, 3, f_synIDattr},
|
||||||
{"synIDtrans", 1, 1, f_synIDtrans},
|
{"synIDtrans", 1, 1, f_synIDtrans},
|
||||||
@ -12313,6 +12315,16 @@ f_substitute(typval_T *argvars, typval_T *rettv)
|
|||||||
rettv->vval.v_string = do_string_sub(str, pat, sub, expr, flg);
|
rettv->vval.v_string = do_string_sub(str, pat, sub, expr, flg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "swapinfo(swap_filename)" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_swapinfo(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
if (rettv_dict_alloc(rettv) == OK)
|
||||||
|
get_b0_dict(get_tv_string(argvars), rettv->vval.v_dict);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "synID(lnum, col, trans)" function
|
* "synID(lnum, col, trans)" function
|
||||||
*/
|
*/
|
||||||
|
@ -2041,6 +2041,49 @@ make_percent_swname(char_u *dir, char_u *name)
|
|||||||
static int process_still_running;
|
static int process_still_running;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return information found in swapfile "fname" in dictionary "d".
|
||||||
|
* This is used by the swapinfo() function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
get_b0_dict(char_u *fname, dict_T *d)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct block0 b0;
|
||||||
|
|
||||||
|
if ((fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0)
|
||||||
|
{
|
||||||
|
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
|
||||||
|
{
|
||||||
|
if (b0_magic_wrong(&b0))
|
||||||
|
{
|
||||||
|
dict_add_string(d, "error",
|
||||||
|
vim_strsave((char_u *)"magic number mismatch"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* we have swap information */
|
||||||
|
dict_add_string(d, "version", vim_strsave(b0.b0_version));
|
||||||
|
dict_add_string(d, "user", vim_strsave(b0.b0_uname));
|
||||||
|
dict_add_string(d, "host", vim_strsave(b0.b0_hname));
|
||||||
|
dict_add_string(d, "fname", vim_strsave(b0.b0_fname));
|
||||||
|
|
||||||
|
dict_add_number(d, "pid", char_to_long(b0.b0_pid));
|
||||||
|
dict_add_number(d, "mtime", char_to_long(b0.b0_mtime));
|
||||||
|
#ifdef CHECK_INODE
|
||||||
|
dict_add_number(d, "inode", char_to_long(b0.b0_ino));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dict_add_string(d, "error",
|
||||||
|
vim_strsave((char_u *)"Cannot read file"));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dict_add_string(d, "error", vim_strsave((char_u *)"Cannot open file"));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give information about an existing swap file.
|
* Give information about an existing swap file.
|
||||||
* Returns timestamp (0 when unknown).
|
* Returns timestamp (0 when unknown).
|
||||||
|
@ -11,6 +11,8 @@ void ml_close_notmod(void);
|
|||||||
void ml_timestamp(buf_T *buf);
|
void ml_timestamp(buf_T *buf);
|
||||||
void ml_recover(void);
|
void ml_recover(void);
|
||||||
int recover_names(char_u *fname, int list, int nr, char_u **fname_out);
|
int recover_names(char_u *fname, int list, int nr, char_u **fname_out);
|
||||||
|
char_u *make_percent_swname(char_u *dir, char_u *name);
|
||||||
|
void get_b0_dict(char_u *fname, dict_T *d);
|
||||||
void ml_sync_all(int check_file, int check_char);
|
void ml_sync_all(int check_file, int check_char);
|
||||||
void ml_preserve(buf_T *buf, int message);
|
void ml_preserve(buf_T *buf, int message);
|
||||||
char_u *ml_get(linenr_T lnum);
|
char_u *ml_get(linenr_T lnum);
|
||||||
@ -34,5 +36,4 @@ char_u *ml_encrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned siz
|
|||||||
void ml_decrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size);
|
void ml_decrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size);
|
||||||
long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp);
|
long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp);
|
||||||
void goto_byte(long cnt);
|
void goto_byte(long cnt);
|
||||||
char_u *make_percent_swname (char_u *dir, char_u *name);
|
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@ -97,3 +97,37 @@ func Test_missing_dir()
|
|||||||
set directory&
|
set directory&
|
||||||
call delete('Xswapdir', 'rf')
|
call delete('Xswapdir', 'rf')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_swapinfo()
|
||||||
|
new Xswapinfo
|
||||||
|
call setline(1, ['one', 'two', 'three'])
|
||||||
|
w
|
||||||
|
let fname = trim(execute('swapname'))
|
||||||
|
call assert_match('Xswapinfo', fname)
|
||||||
|
let info = swapinfo(fname)
|
||||||
|
call assert_match('8\.', info.version)
|
||||||
|
call assert_match('\w', info.user)
|
||||||
|
call assert_equal(hostname(), info.host)
|
||||||
|
call assert_match('Xswapinfo', info.fname)
|
||||||
|
call assert_equal(getpid(), info.pid)
|
||||||
|
call assert_match('^\d*$', info.mtime)
|
||||||
|
if has_key(info, 'inode')
|
||||||
|
call assert_match('\d', info.inode)
|
||||||
|
endif
|
||||||
|
bwipe!
|
||||||
|
call delete(fname)
|
||||||
|
call delete('Xswapinfo')
|
||||||
|
|
||||||
|
let info = swapinfo('doesnotexist')
|
||||||
|
call assert_equal('Cannot open file', info.error)
|
||||||
|
|
||||||
|
call writefile(['burp'], 'Xnotaswapfile')
|
||||||
|
let info = swapinfo('Xnotaswapfile')
|
||||||
|
call assert_equal('Cannot read file', info.error)
|
||||||
|
call delete('Xnotaswapfile')
|
||||||
|
|
||||||
|
call writefile([repeat('x', 10000)], 'Xnotaswapfile')
|
||||||
|
let info = swapinfo('Xnotaswapfile')
|
||||||
|
call assert_equal('magic number mismatch', info.error)
|
||||||
|
call delete('Xnotaswapfile')
|
||||||
|
endfunc
|
||||||
|
@ -794,6 +794,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 */
|
||||||
|
/**/
|
||||||
|
313,
|
||||||
/**/
|
/**/
|
||||||
312,
|
312,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user