mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -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:
parent
58dbef330c
commit
6a33ef0deb
@ -2661,7 +2661,7 @@ mzeval({expr}) any evaluate |MzScheme| expression
|
|||||||
nextnonblank({lnum}) Number line nr of non-blank line >= {lnum}
|
nextnonblank({lnum}) Number line nr of non-blank line >= {lnum}
|
||||||
nr2char({expr} [, {utf8}]) String single char with ASCII/UTF8 value {expr}
|
nr2char({expr} [, {utf8}]) String single char with ASCII/UTF8 value {expr}
|
||||||
or({expr}, {expr}) Number bitwise OR
|
or({expr}, {expr}) Number bitwise OR
|
||||||
pathshorten({expr}) String shorten directory names in a path
|
pathshorten({expr} [, {len}]) String shorten directory names in a path
|
||||||
perleval({expr}) any evaluate |Perl| expression
|
perleval({expr}) any evaluate |Perl| expression
|
||||||
popup_atcursor({what}, {options}) Number create popup window near the cursor
|
popup_atcursor({what}, {options}) Number create popup window near the cursor
|
||||||
popup_beval({what}, {options}) Number create popup window for 'ballooneval'
|
popup_beval({what}, {options}) Number create popup window for 'ballooneval'
|
||||||
@ -7656,13 +7656,17 @@ or({expr}, {expr}) *or()*
|
|||||||
:let bits = bits->or(0x80)
|
:let bits = bits->or(0x80)
|
||||||
|
|
||||||
|
|
||||||
pathshorten({expr}) *pathshorten()*
|
pathshorten({expr} [, {len}]) *pathshorten()*
|
||||||
Shorten directory names in the path {expr} and return the
|
Shorten directory names in the path {expr} and return the
|
||||||
result. The tail, the file name, is kept as-is. The other
|
result. The tail, the file name, is kept as-is. The other
|
||||||
components in the path are reduced to single letters. Leading
|
components in the path are reduced to {len} letters in length.
|
||||||
'~' and '.' characters are kept. Example: >
|
If {len} is omitted or smaller than 1 then 1 is used (single
|
||||||
|
letters). Leading '~' and '.' characters are kept. Examples: >
|
||||||
:echo pathshorten('~/.vim/autoload/myfile.vim')
|
:echo pathshorten('~/.vim/autoload/myfile.vim')
|
||||||
< ~/.v/a/myfile.vim ~
|
< ~/.v/a/myfile.vim ~
|
||||||
|
>
|
||||||
|
:echo pathshorten('~/.vim/autoload/myfile.vim', 2)
|
||||||
|
< ~/.vi/au/myfile.vim ~
|
||||||
It doesn't matter if the path exists or not.
|
It doesn't matter if the path exists or not.
|
||||||
|
|
||||||
Can also be used as a |method|: >
|
Can also be used as a |method|: >
|
||||||
|
@ -779,7 +779,7 @@ static funcentry_T global_functions[] =
|
|||||||
{"nextnonblank", 1, 1, FEARG_1, ret_number, f_nextnonblank},
|
{"nextnonblank", 1, 1, FEARG_1, ret_number, f_nextnonblank},
|
||||||
{"nr2char", 1, 2, FEARG_1, ret_string, f_nr2char},
|
{"nr2char", 1, 2, FEARG_1, ret_string, f_nr2char},
|
||||||
{"or", 2, 2, FEARG_1, ret_number, f_or},
|
{"or", 2, 2, FEARG_1, ret_number, f_or},
|
||||||
{"pathshorten", 1, 1, FEARG_1, ret_string, f_pathshorten},
|
{"pathshorten", 1, 2, FEARG_1, ret_string, f_pathshorten},
|
||||||
{"perleval", 1, 1, FEARG_1, ret_any,
|
{"perleval", 1, 1, FEARG_1, ret_any,
|
||||||
#ifdef FEAT_PERL
|
#ifdef FEAT_PERL
|
||||||
f_perleval
|
f_perleval
|
||||||
|
115
src/filepath.c
115
src/filepath.c
@ -1351,6 +1351,69 @@ f_mkdir(typval_T *argvars, typval_T *rettv)
|
|||||||
rettv->vval.v_number = vim_mkdir_emsg(dir, prot);
|
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
|
* "pathshorten()" function
|
||||||
*/
|
*/
|
||||||
@ -1358,9 +1421,18 @@ f_mkdir(typval_T *argvars, typval_T *rettv)
|
|||||||
f_pathshorten(typval_T *argvars, typval_T *rettv)
|
f_pathshorten(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
char_u *p;
|
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;
|
rettv->v_type = VAR_STRING;
|
||||||
p = tv_get_string_chk(&argvars[0]);
|
p = tv_get_string_chk(&argvars[0]);
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
else
|
else
|
||||||
@ -1368,7 +1440,7 @@ f_pathshorten(typval_T *argvars, typval_T *rettv)
|
|||||||
p = vim_strsave(p);
|
p = vim_strsave(p);
|
||||||
rettv->vval.v_string = p;
|
rettv->vval.v_string = p;
|
||||||
if (p != NULL)
|
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.
|
* Return TRUE if the directory of "fname" exists, FALSE otherwise.
|
||||||
* Also returns TRUE if there is no directory name.
|
* Also returns TRUE if there is no directory name.
|
||||||
|
@ -21,6 +21,7 @@ void f_glob2regpat(typval_T *argvars, typval_T *rettv);
|
|||||||
void f_globpath(typval_T *argvars, typval_T *rettv);
|
void f_globpath(typval_T *argvars, typval_T *rettv);
|
||||||
void f_isdirectory(typval_T *argvars, typval_T *rettv);
|
void f_isdirectory(typval_T *argvars, typval_T *rettv);
|
||||||
void f_mkdir(typval_T *argvars, typval_T *rettv);
|
void f_mkdir(typval_T *argvars, typval_T *rettv);
|
||||||
|
void shorten_dir(char_u *str);
|
||||||
void f_pathshorten(typval_T *argvars, typval_T *rettv);
|
void f_pathshorten(typval_T *argvars, typval_T *rettv);
|
||||||
void f_readdir(typval_T *argvars, typval_T *rettv);
|
void f_readdir(typval_T *argvars, typval_T *rettv);
|
||||||
void f_readdirex(typval_T *argvars, typval_T *rettv);
|
void f_readdirex(typval_T *argvars, typval_T *rettv);
|
||||||
@ -40,7 +41,6 @@ char_u *getnextcomp(char_u *fname);
|
|||||||
char_u *get_past_head(char_u *path);
|
char_u *get_past_head(char_u *path);
|
||||||
int vim_ispathsep(int c);
|
int vim_ispathsep(int c);
|
||||||
int vim_ispathsep_nocolon(int c);
|
int vim_ispathsep_nocolon(int c);
|
||||||
void shorten_dir(char_u *str);
|
|
||||||
int dir_of_file_exists(char_u *fname);
|
int dir_of_file_exists(char_u *fname);
|
||||||
int vim_fnamecmp(char_u *x, char_u *y);
|
int vim_fnamecmp(char_u *x, char_u *y);
|
||||||
int vim_fnamencmp(char_u *x, char_u *y, size_t len);
|
int vim_fnamencmp(char_u *x, char_u *y, size_t len);
|
||||||
|
@ -500,6 +500,24 @@ 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_equal('~/f/bar', pathshorten('~/foo/bar'))
|
||||||
call assert_fails('call pathshorten([])', 'E730:')
|
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
|
endfunc
|
||||||
|
|
||||||
func Test_strpart()
|
func Test_strpart()
|
||||||
|
@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
1741,
|
||||||
/**/
|
/**/
|
||||||
1740,
|
1740,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user