Merge pull request #17305 from zeertzjq/vim-8.2.1741

vim-patch:8.2.1741: pathshorten() only supports using one character
This commit is contained in:
zeertzjq
2022-02-07 05:21:39 +08:00
committed by GitHub
6 changed files with 66 additions and 19 deletions

View File

@@ -262,7 +262,7 @@ return {
nextnonblank={args=1, base=1},
nr2char={args={1, 2}, base=1},
['or']={args=2, base=1},
pathshorten={args=1, base=1},
pathshorten={args={1, 2}, base=1},
pow={args=2, base=1},
prevnonblank={args=1, base=1},
printf={args=varargs(1), base=2},

View File

@@ -6846,12 +6846,23 @@ static void f_or(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
const char *const s = tv_get_string_chk(&argvars[0]);
if (!s) {
return;
int trim_len = 1;
if (argvars[1].v_type != VAR_UNKNOWN) {
trim_len = (int)tv_get_number(&argvars[1]);
if (trim_len < 1) {
trim_len = 1;
}
}
rettv->v_type = VAR_STRING;
const char_u *p = (char_u *)tv_get_string_chk(&argvars[0]);
if (p == NULL) {
rettv->vval.v_string = NULL;
} else {
rettv->vval.v_string = vim_strsave(p);
shorten_dir_len(rettv->vval.v_string, trim_len);
}
rettv->vval.v_string = shorten_dir((char_u *)xstrdup(s));
}
/*

View File

@@ -269,16 +269,17 @@ int vim_ispathlistsep(int c)
#endif
}
/*
* Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname"
* It's done in-place.
*/
char_u *shorten_dir(char_u *str)
/// Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname"
/// "trim_len" specifies how many characters to keep for each directory.
/// Must be 1 or more.
/// It's done in-place.
void shorten_dir_len(char_u *str, int trim_len)
{
char_u *tail = path_tail(str);
char_u *d = str;
bool skip = false;
for (char_u *s = str;; ++s) {
int dirchunk_len = 0;
for (char_u *s = str;; s++) {
if (s >= tail) { // copy the whole tail
*d++ = *s;
if (*s == NUL) {
@@ -287,10 +288,16 @@ char_u *shorten_dir(char_u *str)
} else if (vim_ispathsep(*s)) { // copy '/' and next char
*d++ = *s;
skip = false;
dirchunk_len = 0;
} else if (!skip) {
*d++ = *s; // copy next char
if (*s != '~' && *s != '.') { // and leading "~" and "."
skip = true;
dirchunk_len++; // only count word chars for the size
// keep copying chars until we have our preferred length (or
// until the above if/else branches move us along)
if (dirchunk_len >= trim_len) {
skip = true;
}
}
int l = utfc_ptr2len(s);
while (--l > 0) {
@@ -298,7 +305,13 @@ char_u *shorten_dir(char_u *str)
}
}
}
return str;
}
/// Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname"
/// It's done in-place.
void shorten_dir(char_u *str)
{
shorten_dir_len(str, 1);
}
/*

View File

@@ -7350,7 +7350,7 @@ void draw_tabline(void)
if (room > 0) {
// Get buffer name in NameBuff[]
get_trans_bufname(cwp->w_buffer);
(void)shorten_dir(NameBuff);
shorten_dir(NameBuff);
len = vim_strsize(NameBuff);
p = NameBuff;
while (len > room) {

View File

@@ -376,6 +376,25 @@ func Test_pathshorten()
call assert_equal('~.f/bar', pathshorten('~.foo/bar'))
call assert_equal('.~f/bar', pathshorten('.~foo/bar'))
call assert_equal('~/f/bar', pathshorten('~/foo/bar'))
call assert_fails('call pathshorten([])', 'E730:')
" test pathshorten with optional variable to set preferred size of shortening
call assert_equal('', pathshorten('', 2))
call assert_equal('foo', pathshorten('foo', 2))
call assert_equal('/foo', pathshorten('/foo', 2))
call assert_equal('fo/', pathshorten('foo/', 2))
call assert_equal('fo/bar', pathshorten('foo/bar', 2))
call assert_equal('fo/ba/foobar', pathshorten('foo/bar/foobar', 2))
call assert_equal('/fo/ba/foobar', pathshorten('/foo/bar/foobar', 2))
call assert_equal('.fo/bar', pathshorten('.foo/bar', 2))
call assert_equal('~fo/bar', pathshorten('~foo/bar', 2))
call assert_equal('~.fo/bar', pathshorten('~.foo/bar', 2))
call assert_equal('.~fo/bar', pathshorten('.~foo/bar', 2))
call assert_equal('~/fo/bar', pathshorten('~/foo/bar', 2))
call assert_fails('call pathshorten([],2)', 'E730:')
call assert_notequal('~/fo/bar', pathshorten('~/foo/bar', 3))
call assert_equal('~/foo/bar', pathshorten('~/foo/bar', 3))
call assert_equal('~/f/bar', pathshorten('~/foo/bar', 0))
endfunc
func Test_strpart()