0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.1741: pathshorten() only supports using one character

Problem:    pathshorten() only supports using one character.
Solution:   Add an argument to control the length. (closes #7006)
This commit is contained in:
Bram Moolenaar
2020-09-25 22:42:48 +02:00
parent 58dbef330c
commit 6a33ef0deb
6 changed files with 103 additions and 48 deletions

View File

@@ -1351,6 +1351,69 @@ f_mkdir(typval_T *argvars, typval_T *rettv)
rettv->vval.v_number = vim_mkdir_emsg(dir, prot);
}
/*
* 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.
*/
static void
shorten_dir_len(char_u *str, int trim_len)
{
char_u *tail, *s, *d;
int skip = FALSE;
int dirchunk_len = 0;
tail = gettail(str);
d = str;
for (s = str; ; ++s)
{
if (s >= tail) // copy the whole tail
{
*d++ = *s;
if (*s == NUL)
break;
}
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 "."
{
++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;
}
if (has_mbyte)
{
int l = mb_ptr2len(s);
while (--l > 0)
*d++ = *++s;
}
}
}
}
/*
* 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);
}
/*
* "pathshorten()" function
*/
@@ -1358,9 +1421,18 @@ f_mkdir(typval_T *argvars, typval_T *rettv)
f_pathshorten(typval_T *argvars, typval_T *rettv)
{
char_u *p;
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;
p = tv_get_string_chk(&argvars[0]);
if (p == NULL)
rettv->vval.v_string = NULL;
else
@@ -1368,7 +1440,7 @@ f_pathshorten(typval_T *argvars, typval_T *rettv)
p = vim_strsave(p);
rettv->vval.v_string = p;
if (p != NULL)
shorten_dir(p);
shorten_dir_len(p, trim_len);
}
}
@@ -2706,47 +2778,6 @@ vim_ispathsep_nocolon(int c)
;
}
/*
* 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)
{
char_u *tail, *s, *d;
int skip = FALSE;
tail = gettail(str);
d = str;
for (s = str; ; ++s)
{
if (s >= tail) // copy the whole tail
{
*d++ = *s;
if (*s == NUL)
break;
}
else if (vim_ispathsep(*s)) // copy '/' and next char
{
*d++ = *s;
skip = FALSE;
}
else if (!skip)
{
*d++ = *s; // copy next char
if (*s != '~' && *s != '.') // and leading "~" and "."
skip = TRUE;
if (has_mbyte)
{
int l = mb_ptr2len(s);
while (--l > 0)
*d++ = *++s;
}
}
}
}
/*
* Return TRUE if the directory of "fname" exists, FALSE otherwise.
* Also returns TRUE if there is no directory name.