mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.1.0313: information about a swap file is unavailable
Problem: Information about a swap file is unavailable.
Solution: Add swapinfo(). (Enzo Ferber)
00f123a565
This commit is contained in:
parent
a0d723db55
commit
24b7462b3c
@ -2321,6 +2321,7 @@ submatch({nr} [, {list}]) String or List
|
||||
specific match in ":s" or substitute()
|
||||
substitute({expr}, {pat}, {sub}, {flags})
|
||||
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}
|
||||
synIDattr({synID}, {what} [, {mode}])
|
||||
String attribute {what} of syntax ID {synID}
|
||||
@ -7758,6 +7759,22 @@ substitute({expr}, {pat}, {sub}, {flags}) *substitute()*
|
||||
|submatch()| returns. Example: >
|
||||
: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()*
|
||||
The result is a Number, which is the syntax ID at the position
|
||||
{lnum} and {col} in the current window.
|
||||
|
@ -16423,6 +16423,13 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
}
|
||||
}
|
||||
|
||||
/// "swapinfo(swap_filename)" function
|
||||
static void f_swapinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
tv_dict_alloc_ret(rettv);
|
||||
get_b0_dict(tv_get_string(argvars), rettv->vval.v_dict);
|
||||
}
|
||||
|
||||
/// "synID(lnum, col, trans)" function
|
||||
static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
|
@ -301,6 +301,7 @@ return {
|
||||
strwidth={args=1},
|
||||
submatch={args={1, 2}},
|
||||
substitute={args=4},
|
||||
swapinfo={args={1}},
|
||||
synID={args=3},
|
||||
synIDattr={args={2, 3}},
|
||||
synIDtrans={args=1},
|
||||
|
@ -1457,10 +1457,41 @@ static char *make_percent_swname(const char *dir, char *name)
|
||||
static bool process_still_running;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Give information about an existing swap file.
|
||||
* Returns timestamp (0 when unknown).
|
||||
*/
|
||||
/// Return information found in swapfile "fname" in dictionary "d".
|
||||
/// This is used by the swapinfo() function.
|
||||
void get_b0_dict(const char *fname, dict_T *d)
|
||||
{
|
||||
int fd;
|
||||
struct block0 b0;
|
||||
|
||||
if ((fd = os_open(fname, O_RDONLY, 0)) >= 0) {
|
||||
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
|
||||
if (b0_magic_wrong(&b0)) {
|
||||
tv_dict_add_str(d, S_LEN("error"), xstrdup("magic number mismatch"));
|
||||
} else {
|
||||
// We have swap information.
|
||||
tv_dict_add_str(d, S_LEN("version"), xstrdup((char *)b0.b0_version));
|
||||
tv_dict_add_str(d, S_LEN("user"), xstrdup((char *)b0.b0_uname));
|
||||
tv_dict_add_str(d, S_LEN("host"), xstrdup((char *)b0.b0_hname));
|
||||
tv_dict_add_str(d, S_LEN("fname"), xstrdup((char *)b0.b0_fname));
|
||||
|
||||
tv_dict_add_nr(d, S_LEN("pid"), char_to_long(b0.b0_pid));
|
||||
tv_dict_add_nr(d, S_LEN("mtime"), char_to_long(b0.b0_mtime));
|
||||
#ifdef CHECK_INODE
|
||||
tv_dict_add_nr(d, S_LEN("inode"), char_to_long(b0.b0_ino));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
tv_dict_add_str(d, S_LEN("error"), xstrdup("Cannot read file"));
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
tv_dict_add_str(d, S_LEN("error"), xstrdup("Cannot open file"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Give information about an existing swap file.
|
||||
/// Returns timestamp (0 when unknown).
|
||||
static time_t swapfile_info(char_u *fname)
|
||||
{
|
||||
assert(fname != NULL);
|
||||
|
@ -61,3 +61,37 @@ func Test_missing_dir()
|
||||
set directory&
|
||||
call delete('Xswapdir', 'rf')
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user