Patch 8.2.1741
Problem: pathshorten() only supports using one character.
Solution: Add an argument to control the length. (closes #7006)
Files: runtime/doc/eval.txt, src/evalfunc.c, src/filepath.c,
src/proto/
filepath.pro, src/testdir/test_functions.vim
*** ../vim-8.2.1740/runtime/doc/eval.txt 2020-09-22 21:55:16.210978678 +0200
--- runtime/doc/eval.txt 2020-09-25 22:41:50.968800452 +0200
***************
*** 2647,2653 ****
nextnonblank({lnum}) Number line nr of non-blank line >= {lnum}
nr2char({expr} [, {utf8}]) String single char with ASCII/UTF8 value {expr}
or({expr}, {expr}) Number bitwise OR
! pathshorten({expr}) String shorten directory names in a path
perleval({expr}) any evaluate |Perl| expression
popup_atcursor({what}, {options}) Number create popup window near the cursor
popup_beval({what}, {options}) Number create popup window for 'ballooneval'
--- 2661,2667 ----
nextnonblank({lnum}) Number line nr of non-blank line >= {lnum}
nr2char({expr} [, {utf8}]) String single char with ASCII/UTF8 value {expr}
or({expr}, {expr}) Number bitwise OR
! pathshorten({expr} [, {len}]) String shorten directory names in a path
perleval({expr}) any evaluate |Perl| expression
popup_atcursor({what}, {options}) Number create popup window near the cursor
popup_beval({what}, {options}) Number create popup window for 'ballooneval'
***************
*** 7607,7619 ****
:let bits = bits->or(0x80)
! pathshorten({expr}) *pathshorten()*
Shorten directory names in the path {expr} and return the
result. The tail, the file name, is kept as-is. The other
! components in the path are reduced to single letters. Leading
! '~' and '.' characters are kept. Example: >
:echo pathshorten('~/.vim/autoload/myfile.vim')
< ~/.v/a/myfile.vim ~
It doesn't matter if the path exists or not.
Can also be used as a |method|: >
--- 7656,7672 ----
:let bits = bits->or(0x80)
! pathshorten({expr} [, {len}]) *pathshorten()*
Shorten directory names in the path {expr} and return the
result. The tail, the file name, is kept as-is. The other
! components in the path are reduced to {len} letters in length.
! 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')
< ~/.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.
Can also be used as a |method|: >
*** ../vim-8.2.1740/src/evalfunc.c 2020-09-23 12:28:46.421898027 +0200
--- src/evalfunc.c 2020-09-25 22:28:04.710790114 +0200
***************
*** 779,785 ****
{"nextnonblank", 1, 1, FEARG_1, ret_number, f_nextnonblank},
{"nr2char", 1, 2, FEARG_1, ret_string, f_nr2char},
{"or", 2, 2, FEARG_1, ret_number, f_or},
! {"pathshorten", 1, 1, FEARG_1, ret_string, f_pathshorten},
{"perleval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_PERL
f_perleval
--- 779,785 ----
{"nextnonblank", 1, 1, FEARG_1, ret_number, f_nextnonblank},
{"nr2char", 1, 2, FEARG_1, ret_string, f_nr2char},
{"or", 2, 2, FEARG_1, ret_number, f_or},
! {"pathshorten", 1, 2, FEARG_1, ret_string, f_pathshorten},
{"perleval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_PERL
f_perleval
*** ../vim-8.2.1740/src/filepath.c 2020-09-02 21:57:04.022422373 +0200
--- src/filepath.c 2020-09-25 22:39:30.341148104 +0200
***************
*** 1352,1366 ****
--- 1352,1438 ----
}
/*
+ * 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
*/
void
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,1374 ****
p = vim_strsave(p);
rettv->vval.v_string = p;
if (p != NULL)
! shorten_dir(p);
}
}
--- 1440,1446 ----
p = vim_strsave(p);
rettv->vval.v_string = p;
if (p != NULL)
! shorten_dir_len(p, trim_len);
}
}
***************
*** 2707,2753 ****
}
/*
- * 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.
* "fname" must be writable!.
--- 2779,2784 ----
*** ../vim-8.2.1740/src/proto/
filepath.pro 2020-06-01 16:09:30.266292734 +0200
--- src/proto/
filepath.pro 2020-09-25 22:35:05.237796160 +0200
***************
*** 21,26 ****
--- 21,27 ----
void f_globpath(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 shorten_dir(char_u *str);
void f_pathshorten(typval_T *argvars, typval_T *rettv);
void f_readdir(typval_T *argvars, typval_T *rettv);
void f_readdirex(typval_T *argvars, typval_T *rettv);
***************
*** 40,46 ****
char_u *get_past_head(char_u *path);
int vim_ispathsep(int c);
int vim_ispathsep_nocolon(int c);
- void shorten_dir(char_u *str);
int dir_of_file_exists(char_u *fname);
int vim_fnamecmp(char_u *x, char_u *y);
int vim_fnamencmp(char_u *x, char_u *y, size_t len);
--- 41,46 ----
*** ../vim-8.2.1740/src/testdir/test_functions.vim 2020-09-23 22:38:01.503927513 +0200
--- src/testdir/test_functions.vim 2020-09-25 22:28:04.710790114 +0200
***************
*** 500,505 ****
--- 500,523 ----
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()
*** ../vim-8.2.1740/src/version.c 2020-09-25 22:13:02.340553653 +0200
--- src/version.c 2020-09-25 22:32:20.066193012 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 1741,
/**/
--
Female engineers become irresistible at the age of consent and remain that
way until about thirty minutes after their clinical death. Longer if it's a
warm day.
(Scott Adams - The Dilbert principle)
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///