[vim/vim] Collation (#6229)

76 views
Skip to first unread message

Christian Brabandt

unread,
Jun 9, 2020, 5:05:54 PM6/9/20
to vim/vim, Subscribed

allow to use collation based sorting of strings.

Currently, we use strcmp, which does a case sensitive comparison (almost) everywhere (we also use strcasecmp). For collation based sorting, we need to switch using strcoll(). I don't know whether this is available everywhere, so add a configure check and in case it is not available, fall back to strcmp. Apparently, on windows, we at least use strcoll() for generating the prototypes, so it should work there already.

For now, only apply the collation based sorting only for the readdirex() vimscript function, as asked for in #6214. I guess if this is useful and works well, we can move to strcoll() function for other functions as well.

Also, since it is now possible to use strcoll(), make it possible to query and set the collation based locale, using :lang collate as well as :echo v:collate.

Add a couple of tests to verify the behaviour.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/6229

Commit Summary

  • Use strcoll for sorting string according to the locale
  • Make collation order available in Vim
  • Expand :lang command correctly
  • Tests for readdirex
  • Add some more completions for :lang command

File Changes

Patch Links:


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

Christian Brabandt

unread,
Jun 10, 2020, 2:05:59 AM6/10/20
to vim/vim, Push

@chrisbra pushed 1 commit.

  • 3633d86 Fix failing readdirex test


You are receiving this because you are subscribed to this thread.

View it on GitHub or unsubscribe.

Bram Moolenaar

unread,
Jun 10, 2020, 7:07:25 AM6/10/20
to vim/vim, Subscribed

I can see that collation-ordered sorting can be useful, but for the readdir() function I thought the question was for case-ignored sorting. So README, Readme and readme sort together. And I would expect at least some users wanting byte-order sorting (like we do nearly everywhere currently).

Christian Brabandt

unread,
Jun 10, 2020, 7:23:01 AM6/10/20
to vim/vim, Subscribed

So README, Readme and readme sort together.

Yes, that's what I believe :lang collate de_DE would cause. If you do not want this, use :lang collate C

Christian Brabandt

unread,
Jun 10, 2020, 8:59:31 AM6/10/20
to vim/vim, Push

@chrisbra pushed 1 commit.


You are receiving this because you are subscribed to this thread.

Bram Moolenaar

unread,
Jun 10, 2020, 9:35:05 AM6/10/20
to vim/vim, Subscribed


Christian wrote:

> > So README, Readme and readme sort together.
>
> Yes, that's what I believe `:lang collate de_DE` would cause. If you
> do not want this, use `:lang collate C`

It's generally not a good idea to have the result of a function depend
on a global variable. It tends to break plugins.

A generic, but possibly complicated solution, is to add an argument to
specify the sorting:
none - byte order
icase - current case-folding comparison
collate - using language from environment
collate:{lang} - collattion using specific language

If we introduce collation here, then no doubt will it be requested where
we currently have a choice between ignore-case and byte order.

--
** Hello and Welcome to the Psychiatric Hotline **
If you are obsessive-compulsive, please press 1 repeatedly.
If you are co-dependent, please ask someone to press 2.
If you have multiple personalities, please press 3, 4, 5 and 6.
If you are paranoid-delusional, we know who you are and what you want
- just stay on the line so we can trace the call.
If you are schizophrenic, listen carefully and a little voice will
tell you which number to press next.
If you are manic-depressive, it doesn't matter which number you press
- no one will answer.
If you suffer from panic attacks, push every button you can find.
If you are sane, please hold on - we have the rest of humanity on the
other line and they desparately want to ask you a few questions.

/// 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 ///

Christian Brabandt

unread,
Jun 10, 2020, 10:02:14 AM6/10/20
to vim/vim, Subscribed

Okay, will rework.

K.Takata

unread,
Jun 10, 2020, 10:34:32 AM6/10/20
to vim/vim, Subscribed

A generic, but possibly complicated solution, is to add an argument to specify the sorting:
none - byte order
icase - current case-folding comparison
collate - using language from environment
collate:{lang} - collattion using specific language

How about:

none - unsorted
case - byte order (default)
icase - current case-folding comparison
...

Returning the result without sorting may have speed advantage.

chdiza

unread,
Jun 10, 2020, 11:27:37 AM6/10/20
to vim/vim, Subscribed

A generic, but possibly complicated solution, is to add an argument to specify the sorting

Yes, this corresponds with my original request and seems like the least likely to cause problems.

I was about to alter my feature request after realizing that I was asking for a set of conditions that are jointly unsatisfiable. I wanted the results of readdirex() to (i) match those of Vimscript glob(), and (ii) match what one would get by sorting using Vimscript '>?'

I also realized that the latter is probably what I really want for my plugin.

Thus an optional flag to sort in that fashion is most welcome! (I don't know whether that is what is meant by "icase - current case-folding comparison").

Gary Johnson

unread,
Jun 10, 2020, 12:44:00 PM6/10/20
to reply+ACY5DGELMUXW6ZRJ2Z...@reply.github.com, vim...@googlegroups.com
On 2020-06-10, K.Takata wrote:
> A generic, but possibly complicated solution, is to add an argument to
> specify the sorting:
> none - byte order
> icase - current case-folding comparison
> collate - using language from environment
> collate:{lang} - collattion using specific language
>
> How about:
>
> none - unsorted
> case - byte order (default)
> icase - current case-folding comparison

As I understand it, Vim's current case-folding comparison does
a stationary sort. So, if locale shows LC_COLLATE="en_US.UTF-8",
and the OS happened to put README, Readme and readme in the
directory in this order, for example,

Readme
readme
README

Vim's "sort i" would leave them in that order, but Vim's glob("*")
would sort them as

README
Readme
readme

and both ":!sort" and ":!echo *" would sort them as

readme
Readme
README

I still don't think that a purely case-insensitive sort is what
should be used for readdirex() or readdir() because the results will
be in an order dependent upon the order in which the OS happened to
put them in the directory. Two directories containing the same
files could case-insensitively sort differently.

Making a case-insensitive file name comparison can be useful, but
for sorting a directory, we should pick a set of collations or
unsorted. Call one dictionary order or case-folded, but not
case-insensitive.

Regards,
Gary

vim-dev ML

unread,
Jun 10, 2020, 12:44:22 PM6/10/20
to vim/vim, vim-dev ML, Your activity

chdiza

unread,
Jun 10, 2020, 2:34:29 PM6/10/20
to vim/vim, vim-dev ML, Comment

Whatever the sorting order for readdirex() is, it should be possible to use Vimscript to return to that sorting order after first sorting by (e.g., filesize or time). That's why I have landed on "the same as >?".

So unless the category expr5 has comparison operators that will follow "collation", I do not want "collation order" as the only alternative to the current "case sensitive" ordering.

Sketch of example: let foo be the result of calling readdirex(). It's a list of dicts. It has some sorting order to it, where what's sorted "on" are the filename entries in each dict. I might want to use Vimscript to sort foo by the "time" entry. And then having inspected that, I might want to use Vimscript return to sorting foo by filename. This last step ought to put foo back in the order it was in when it was first created by readdirex(). Or rather, the optional arg for readdirex() that I'm requesting should be able to take a value that allows for this putting-back.

IIUC collation order will not allow this, because IIUC >? and friends don't follow collation order.

Now one might say "well, just sort foo by >? right after it's created but before you display any of its contents." But that puts me right back where I was when I opened the GH issue: the time needed to perform that initial sorting cancels out the time saved by using readdirex() instead of glob() in the first place.

I used to think that Vimscript's glob() put things in my desired order (on macOS at least), but I now think I was wrong about that.


You are receiving this because you commented.

Gary Johnson

unread,
Jun 10, 2020, 3:46:30 PM6/10/20
to reply+ACY5DGELHJPYASKEM4...@reply.github.com, vim...@googlegroups.com
On 2020-06-10, chdiza wrote:
> Whatever the sorting order for readdirex() is, it should be possible to use
> Vimscript to return to that sorting order after first sorting by (e.g.,
> filesize or time). That's why I have landed on "the same as >?".
>
> So unless the category expr5 has comparison operators that will follow
> "collation", I do not want "collation order" as the only alternative to the
> current "case sensitive" ordering.
>
> Sketch of example: let foo be the result of calling readdirex(). It's a list of
> dicts. It has some sorting order to it, where what's sorted "on" are the
> filename entries in each dict. I might want to use Vimscript to sort foo by the
> "time" entry. And then having inspected that, I might want to use Vimscript
> return to sorting foo by filename. This last step ought to put foo back in the
> order it was in when it was first created by readdirex(). Or rather, the
> optional arg for readdirex() that I'm requesting should be able to take a value
> that allows for this putting-back.

Exactly! You want a sorting method that sorts a randomly-ordered
list with repeatable, predictable results.

Here's an example. I have a directory that contains three files.
If I read the directory unsorted at all, using either "ls -U" or
"find", I get this list in this order.

readme
README
Readme

If I apply Vim's case-insensitive sort, ":sort i", to that list,
I get the same list, because Vim's :sort is stationary.

readme
README
Readme

Now let me get the files sorted by time by reading the directory
using "ls -t".

README
readme
Readme

If I apply Vim's case-insensitive sort to that list I get the
following.

README
readme
Readme

Note that the list order is unchanged, as expected. Note also that
this order is different from what it was the first time I applied
Vim's case-insensitive sort to the "raw" file list. There is no
way to get back to Vim's case-insensitive sort of the original "raw"
list order using any sorting method other than one specifically
crafted to do that.

If you want all the same letters to sort together, and have
repeatable results so that you can put a list back in that order,
you need to choose a collating order, putting either each of the
lower-case letters before its upper-case equivalent or vice versa.
That is, either

aAbBcC...qQrRsS...

or

AaBbCc...QqRrSs...

> IIUC collation order will not allow this, because IIUC >? and friends don't
> follow collation order.

See above.

> Now one might say "well, just sort foo by >? right after it's created but
> before you display any of its contents." But that puts me right back where I
> was when I opened the GH issue: the time needed to perform that initial sorting
> cancels out the time saved by using readdirex() instead of glob() in the first
> place.

I agree that it would be much better to put the sorting in the
C code of the readdirex() function.

> I used to think that Vimscript's glob() put things in my desired order (on
> macOS at least), but I now think I was wrong about that.

I looked briefly at the glob() function but haven't figured it out
yet. I thought it used the shell, but it doesn't.

Regards,
Gary

vim-dev ML

unread,
Jun 10, 2020, 3:46:53 PM6/10/20
to vim/vim, vim-dev ML, Your activity

Christian Brabandt

unread,
Jun 11, 2020, 4:19:01 PM6/11/20
to vim/vim, vim-dev ML, Comment

reworked.


You are receiving this because you commented.

chdiza

unread,
Jun 11, 2020, 5:04:57 PM6/11/20
to vim/vim, vim-dev ML, Comment

@chdiza commented on this pull request.


In runtime/doc/eval.txt:

> @@ -7989,6 +7989,24 @@ readdirex({directory} [, {expr}])			*readdirex()*
 		When {expr} is a function the entry is passed as the argument.
 		For example, to get a list of files ending in ".txt": >
 		  readdirex(dirname, {e -> e.name =~ '.txt$'})
+<
+		The optional {dict} argument allows for further custom
+		values. Currently this is used to specify if and how sorting
+		should be performed. The dict can have the following members:
+
+		    sort    How to sort the result returned from the system.
+			    Valid values are:
+				none	do not sort (fastest method)
+				case	sort case senstive
+				icase	sort case insensitive
+				collate sort using collation order of your
+					|locale|
+			    Other values are silently ignored.
+
+		For example, to get a list of alle files in the current

Typo: "all", not "alle". Also, one line below: "entries", not "entires".


You are receiving this because you commented.

Christian Brabandt

unread,
Jun 11, 2020, 5:56:30 PM6/11/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 4 commits.


You are receiving this because you are subscribed to this thread.

Christian Brabandt

unread,
Jun 11, 2020, 5:58:05 PM6/11/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In runtime/doc/eval.txt:

> @@ -7989,6 +7989,24 @@ readdirex({directory} [, {expr}])			*readdirex()*
 		When {expr} is a function the entry is passed as the argument.
 		For example, to get a list of files ending in ".txt": >
 		  readdirex(dirname, {e -> e.name =~ '.txt$'})
+<
+		The optional {dict} argument allows for further custom
+		values. Currently this is used to specify if and how sorting
+		should be performed. The dict can have the following members:
+
+		    sort    How to sort the result returned from the system.
+			    Valid values are:
+				none	do not sort (fastest method)
+				case	sort case senstive
+				icase	sort case insensitive
+				collate sort using collation order of your
+					|locale|
+			    Other values are silently ignored.
+
+		For example, to get a list of alle files in the current

thanks fixed.


You are receiving this because you commented.

Christian Brabandt

unread,
Jun 11, 2020, 5:58:51 PM6/11/20
to vim/vim, vim-dev ML, Comment

Hm, looks like there are some sorting failures on some CI builds. Not sure how to fix those. I especially find the S390 results strange.


You are receiving this because you commented.

Gary Johnson

unread,
Jun 11, 2020, 6:20:27 PM6/11/20
to reply+ACY5DGGZ7Z3KLHP5MT...@reply.github.com, vim...@googlegroups.com
On 2020-06-11, Christian Brabandt wrote:
> reworked.

Looks good. That should keep everybody happy.

I noticed a couple of typos.

runtime/doc/mlang.txt:49:

collation order is pringed. Technical: LC_COLLATE.
^^^^^^^

"pringed" should be "printed".

src/testdir/test_functions.vim:1946:

" Skipt tests on Mac OS X (does not allow several files with different caseing)
^^^^^ ^^^^^^^

"Skipt" should be "Skip".
"caseing" should be "casing".

Also, in the new :help entry for readdirex(), it is not clear what
is meant by "case sensitive" here (which is also misspelled
"senstive"):

sort How to sort the result returned from the system.
Valid values are:
none do not sort (fastest method)
case sort case senstive
icase sort case insensitive
collate sort using collation order of your
|locale|
Other values are silently ignored.

It would be more clear if it said something like "according to the
byte value of each character", or 'using the collation order of the
"POSIX" or "C" locales'. (See the strcoll(3) man page.)

Regards,
Gary

vim-dev ML

unread,
Jun 11, 2020, 6:20:44 PM6/11/20
to vim/vim, vim-dev ML, Your activity

K.Takata

unread,
Jun 11, 2020, 9:08:21 PM6/11/20
to vim/vim, vim-dev ML, Comment

@k-takata commented on this pull request.


In runtime/doc/eval.txt:

> @@ -7931,7 +7939,7 @@ readdir({directory} [, {expr}])				*readdir()*

 		Can also be used as a |method|: >

 			GetDirName()->readdir()

 <

-readdirex({directory} [, {expr}])			*readdirex()*

+readdirex({directory} [, {expr} [, {dict}]])			*readdirex()*

The same change is needed at the line 2691 (in |functions|).


In src/fileio.c:

> @@ -4638,10 +4642,16 @@ create_readdirex_item(char_u *path, char_u *name)

 compare_readdirex_item(const void *p1, const void *p2)

 {

     char_u  *name1, *name2;

+    

Is this empty line needed?


In src/fileio.c:

>  	if (withattr)

 	    qsort((void*)gap->ga_data, (size_t)gap->ga_len, sizeof(dict_T*),

 		    compare_readdirex_item);

 	else

 # endif

 	    sort_strings((char_u **)gap->ga_data, gap->ga_len);

+

Is this empty line needed?


In runtime/doc/eval.txt:

> @@ -7980,6 +7989,24 @@ readdirex({directory} [, {expr}])			*readdirex()*

 		When {expr} is a function the entry is passed as the argument.

 		For example, to get a list of files ending in ".txt": >

 		  readdirex(dirname, {e -> e.name =~ '.txt$'})

+<

+		The optional {dict} argument allows for further custom

+		values. Currently this is used to specify if and how sorting

+		should be performed. The dict can have the following members:

+

+		    sort    How to sort the result returned from the system.

+			    Valid values are:

+				none	do not sort (fastest method)

+				case	sort case senstive

⬇️ Suggested change
-				case	sort case senstive

+				case	sort case sensitive (default)


In src/fileio.c:

> @@ -4872,7 +4887,7 @@ delete_recursive(char_u *name)

 	exp = vim_strsave(name);

 	if (exp == NULL)

 	    return -1;

-	if (readdir_core(&ga, exp, FALSE, NULL, NULL) == OK)

+	if (readdir_core(&ga, exp, FALSE, NULL, NULL, 0) == OK)

⬇️ Suggested change
-	if (readdir_core(&ga, exp, FALSE, NULL, NULL, 0) == OK)

+	if (readdir_core(&ga, exp, FALSE, NULL, NULL, READDIR_SORT_NONE) == OK)

Actually, this changes the current behavior, but that may not be an issue.


In src/filepath.c:

> @@ -1424,7 +1424,7 @@ f_readdir(typval_T *argvars, typval_T *rettv)

     expr = &argvars[1];

 

     ret = readdir_core(&ga, path, FALSE, (void *)expr,

-	    (expr->v_type == VAR_UNKNOWN) ? NULL : readdir_checkitem);

+	    (expr->v_type == VAR_UNKNOWN) ? NULL : readdir_checkitem, 0);

This changes the current behavior. Should be:

⬇️ Suggested change
-	    (expr->v_type == VAR_UNKNOWN) ? NULL : readdir_checkitem, 0);

+	    (expr->v_type == VAR_UNKNOWN) ? NULL : readdir_checkitem, READDIR_SORT_BYTE);


In src/filepath.c:

> @@ -1469,6 +1469,32 @@ readdirex_checkitem(void *context, void *item)

     return retval;

 }

 

+    static int

+readdirex_dict_arg(typval_T *tv, int *cmp)

+{

+    char_u     *compare;

+

+    if (tv->v_type != VAR_DICT)

+    {

+	emsg(_(e_dictreq));

+	return FAIL;

+    }

+

+    if (dict_find(tv->vval.v_dict, (char_u *)"sort", -1) != NULL)

+	compare  = dict_get_string(tv->vval.v_dict, (char_u *)"sort", FALSE);

If the key "sort" is not found, the result is unpredictable.

⬇️ Suggested change
-	compare  = dict_get_string(tv->vval.v_dict, (char_u *)"sort", FALSE);

+	compare = dict_get_string(tv->vval.v_dict, (char_u *)"sort", FALSE);

+    else

+    {

+	*cmp = READDIR_SORT_BYTE;

+	return OK;

+    }

Or, should be an error?


In src/vim.h:

> @@ -2668,4 +2674,12 @@ long elapsed(DWORD start_tick);

 #define FSK_IN_STRING	0x04	// TRUE in string, double quote is escaped

 #define FSK_SIMPLIFY	0x08	// simplify <C-H> and <A-x>

 

+#ifdef FEAT_EVAL

+// Flags for the readdirex function, how to sort the result

+# define READDIR_SORT_NONE		0  // do not sort

+# define READDIR_SORT_BYTE		1  // sort by byte order (strcmp), default

+# define READDIR_SORT_IC		2  // sort ignoreing case (strcasecmp)

⬇️ Suggested change
-# define READDIR_SORT_IC		2  // sort ignoreing case (strcasecmp)

+# define READDIR_SORT_IC		2  // sort ignoring case (strcasecmp)


In runtime/doc/eval.txt:

> +		The list will be sorted by name according to the current

+		locale, using the collation order.

Looks incorrect.


In runtime/doc/eval.txt:

> @@ -7980,6 +7989,24 @@ readdirex({directory} [, {expr}])			*readdirex()*

 		When {expr} is a function the entry is passed as the argument.

 		For example, to get a list of files ending in ".txt": >

 		  readdirex(dirname, {e -> e.name =~ '.txt$'})

+<

+		The optional {dict} argument allows for further custom

+		values. Currently this is used to specify if and how sorting

+		should be performed. The dict can have the following members:

+

+		    sort    How to sort the result returned from the system.

+			    Valid values are:

+				none	do not sort (fastest method)

⬇️ Suggested change
-				none	do not sort (fastest method)

+				"none"	do not sort (fastest method)

might be better (to make sure that this is a string)? (Same for the others.)


You are receiving this because you commented.

James McCoy

unread,
Jun 11, 2020, 10:21:19 PM6/11/20
to vim/vim, vim-dev ML, Comment

I especially find the S390 results strange.

The tests assume that the order in which the files are created are the order in which readdir() will return them. There are no guarantees about ordering. It's up to the individual filesystem implementation.


You are receiving this because you commented.

Christian Brabandt

unread,
Jun 12, 2020, 2:36:42 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/fileio.c:

> @@ -4872,7 +4887,7 @@ delete_recursive(char_u *name)
 	exp = vim_strsave(name);
 	if (exp == NULL)
 	    return -1;
-	if (readdir_core(&ga, exp, FALSE, NULL, NULL) == OK)
+	if (readdir_core(&ga, exp, FALSE, NULL, NULL, 0) == OK)

Indeed it actually changes behaviour, but then I thought, why should we actually sort the result, if we are going to delete it? And in addition it will be a small performance gain.


You are receiving this because you commented.

Christian Brabandt

unread,
Jun 12, 2020, 2:36:57 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/filepath.c:

> @@ -1424,7 +1424,7 @@ f_readdir(typval_T *argvars, typval_T *rettv)
     expr = &argvars[1];
 
     ret = readdir_core(&ga, path, FALSE, (void *)expr,
-	    (expr->v_type == VAR_UNKNOWN) ? NULL : readdir_checkitem);
+	    (expr->v_type == VAR_UNKNOWN) ? NULL : readdir_checkitem, 0);

yes makes sense, was an overview.


You are receiving this because you commented.

Christian Brabandt

unread,
Jun 12, 2020, 2:59:11 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/filepath.c:

> @@ -1469,6 +1469,32 @@ readdirex_checkitem(void *context, void *item)
     return retval;
 }
 
+    static int
+readdirex_dict_arg(typval_T *tv, int *cmp)
+{
+    char_u     *compare;
+
+    if (tv->v_type != VAR_DICT)
+    {
+	emsg(_(e_dictreq));
+	return FAIL;
+    }
+
+    if (dict_find(tv->vval.v_dict, (char_u *)"sort", -1) != NULL)
+	compare  = dict_get_string(tv->vval.v_dict, (char_u *)"sort", FALSE);

Yes, I change it.


You are receiving this because you commented.

Christian Brabandt

unread,
Jun 12, 2020, 2:59:26 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/filepath.c:

> @@ -1469,6 +1469,32 @@ readdirex_checkitem(void *context, void *item)
     return retval;
 }
 
+    static int
+readdirex_dict_arg(typval_T *tv, int *cmp)
+{
+    char_u     *compare;
+
+    if (tv->v_type != VAR_DICT)
+    {
+	emsg(_(e_dictreq));
+	return FAIL;
+    }
+
+    if (dict_find(tv->vval.v_dict, (char_u *)"sort", -1) != NULL)
+	compare  = dict_get_string(tv->vval.v_dict, (char_u *)"sort", FALSE);

and make missing 'sort' key an error

Christian Brabandt

unread,
Jun 12, 2020, 3:00:34 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/vim.h:

> @@ -2668,4 +2674,12 @@ long elapsed(DWORD start_tick);
 #define FSK_IN_STRING	0x04	// TRUE in string, double quote is escaped
 #define FSK_SIMPLIFY	0x08	// simplify <C-H> and <A-x>
 
+#ifdef FEAT_EVAL
+// Flags for the readdirex function, how to sort the result
+# define READDIR_SORT_NONE		0  // do not sort
+# define READDIR_SORT_BYTE		1  // sort by byte order (strcmp), default
+# define READDIR_SORT_IC		2  // sort ignoreing case (strcasecmp)

thanks, will change

Christian Brabandt

unread,
Jun 12, 2020, 3:00:47 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In runtime/doc/eval.txt:

> @@ -7980,6 +7989,24 @@ readdirex({directory} [, {expr}])			*readdirex()*
 		When {expr} is a function the entry is passed as the argument.
 		For example, to get a list of files ending in ".txt": >
 		  readdirex(dirname, {e -> e.name =~ '.txt$'})
+<
+		The optional {dict} argument allows for further custom
+		values. Currently this is used to specify if and how sorting
+		should be performed. The dict can have the following members:
+
+		    sort    How to sort the result returned from the system.
+			    Valid values are:
+				none	do not sort (fastest method)

yes, done

Christian Brabandt

unread,
Jun 12, 2020, 3:05:16 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In runtime/doc/eval.txt:

> +		The list will be sorted by name according to the current
+		locale, using the collation order.

indeed, changed it.

Christian Brabandt

unread,
Jun 12, 2020, 3:06:31 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In runtime/doc/eval.txt:

> @@ -7931,7 +7939,7 @@ readdir({directory} [, {expr}])				*readdir()*
 		Can also be used as a |method|: >
 			GetDirName()->readdir()
 <
-readdirex({directory} [, {expr}])			*readdirex()*
+readdirex({directory} [, {expr} [, {dict}]])			*readdirex()*

fixed

Christian Brabandt

unread,
Jun 12, 2020, 3:06:38 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/fileio.c:

> @@ -4638,10 +4642,16 @@ create_readdirex_item(char_u *path, char_u *name)
 compare_readdirex_item(const void *p1, const void *p2)
 {
     char_u  *name1, *name2;
+    

Christian Brabandt

unread,
Jun 12, 2020, 3:06:45 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/fileio.c:

>  	if (withattr)
 	    qsort((void*)gap->ga_data, (size_t)gap->ga_len, sizeof(dict_T*),
 		    compare_readdirex_item);
 	else
 # endif
 	    sort_strings((char_u **)gap->ga_data, gap->ga_len);
+

Christian Brabandt

unread,
Jun 12, 2020, 3:06:54 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In runtime/doc/eval.txt:

> @@ -7980,6 +7989,24 @@ readdirex({directory} [, {expr}])			*readdirex()*
 		When {expr} is a function the entry is passed as the argument.
 		For example, to get a list of files ending in ".txt": >
 		  readdirex(dirname, {e -> e.name
 =~ '.txt$'})
+<
+		The optional {dict} argument allows for further custom
+		values. Currently this is used to specify if and how sorting
+		should be performed. The dict can have the following members:
+
+		    sort    How to sort the result returned from the system.
+			    Valid values are:
+				none	do not sort (fastest method)
+				case	sort case senstive

Christian Brabandt

unread,
Jun 12, 2020, 3:07:57 AM6/12/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/fileio.c:

> @@ -4872,7 +4887,7 @@ delete_recursive(char_u *name)
 	exp = vim_strsave(name);
 	if (exp == NULL)
 	    return -1;
-	if (readdir_core(&ga, exp, FALSE, NULL, NULL) == OK)
+	if (readdir_core(&ga, exp, FALSE, NULL, NULL, 0) == OK)

I used the 0, because READDIR_SORT_NONE is undefined for tiny builts. I now define only READDIR_SORT_NONE in all cases, the other ifdefs only for EVAL feature. Not pretty.

Christian Brabandt

unread,
Jun 12, 2020, 3:11:19 AM6/12/20
to vim/vim, vim-dev ML, Comment

Thanks @k-takata and Gary for the reviews, I have adjusted it.

The tests assume that the order in which the files are created are the order in which readdir() will return them. There are no guarantees about ordering. It's up to the individual filesystem implementation.

@jamessan indeed the test assumes this. Any suggestions on how to improve the test? Or should we skip test for s390? BTW: What feature does need to be checked for that architecture? It is not completely obvious to me if we want to adjust tests specifically for that architecture.

Christian Brabandt

unread,
Jun 12, 2020, 3:12:20 AM6/12/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 1 commit.

  • 2260f00 Several fixes according to review suggestions


You are receiving this because you are subscribed to this thread.

K.Takata

unread,
Jun 12, 2020, 3:14:51 AM6/12/20
to vim/vim, vim-dev ML, Comment

@k-takata commented on this pull request.


In src/filepath.c:

> @@ -1469,6 +1469,32 @@ readdirex_checkitem(void *context, void *item)
     return retval;
 }
 
+    static int
+readdirex_dict_arg(typval_T *tv, int *cmp)
+{
+    char_u     *compare;
+
+    if (tv->v_type != VAR_DICT)
+    {
+	emsg(_(e_dictreq));
+	return FAIL;
+    }
+
+    if (dict_find(tv->vval.v_dict, (char_u *)"sort", -1) != NULL)
+	compare  = dict_get_string(tv->vval.v_dict, (char_u *)"sort", FALSE);

Currently, the optional dict only has the 'sort' key, making it mandatory may make sense.
But if another keys are added later, making it mandatory may not make sense.

K.Takata

unread,
Jun 12, 2020, 3:25:08 AM6/12/20
to vim/vim, vim-dev ML, Comment

@jamessan indeed the test assumes this. Any suggestions on how to improve the test?

Isn't the issue fixed by my suggested change?

Christian Brabandt

unread,
Jun 12, 2020, 3:29:34 AM6/12/20
to vim/vim, vim-dev ML, Comment

The CI tests aren't complete yet, but I assume some will still fail, because the newly added test depends on the order in which the files are written. And it looks like this can't be guaranteed everywhere.

K.Takata

unread,
Jun 12, 2020, 3:33:10 AM6/12/20
to vim/vim, vim-dev ML, Comment

@k-takata commented on this pull request.


In src/fileio.c:

> @@ -4872,7 +4887,7 @@ delete_recursive(char_u *name)
 	exp = vim_strsave(name);
 	if (exp == NULL)
 	    return -1;
-	if (readdir_core(&ga, exp, FALSE, NULL, NULL) == OK)
+	if (readdir_core(&ga, exp, FALSE, NULL, NULL, 0) == OK)

Ah, understood.
Then, how about always defining all of them?

Christian Brabandt

unread,
Jun 12, 2020, 3:42:43 AM6/12/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 2 commits.

  • 9297eb9 Always define READDIR_SORT flags
  • 604920b remove readme from tests. Should make all pass except for s390

James McCoy

unread,
Jun 12, 2020, 7:23:32 AM6/12/20
to vim/vim, vim-dev ML, Comment

@jamessan indeed the test assumes this. Any suggestions on how to improve the test? Or should we skip test for s390?

It has nothing to do with the architecture. You're just getting lucky on the other systems. The order of the items returned by readdir() is unspecified, so there shouldn't be any assertion on a specific ordering.

It's completely valid for XFS, btrfs, and ext4 to return the files in different orders than each other even if the same steps were taken to create the files.

Christian Brabandt

unread,
Jun 12, 2020, 8:13:23 AM6/12/20
to vim/vim, vim-dev ML, Comment

@jamessan Understood and I did not mean to hint that the sorting order is dependent on the architecture. Sorry for that. I did realize that the sorting order depends on the underlying filesystem. I guess what I actually did want to say where 2 questions:

  1. So we are lucky, that the sorting in all builds except for s390 built works, I'd like to keep the test and I'd like to have at least some test that makes sure this feature works. So even so the test works by coincidence only, what would be a better and reliable way to test? I suppose your answer to this question is: There is no way, so don't bother?
  2. How can I detect from within Vim that we are running on s390? So even if would like to disable this test for the S390 built, I have no idea how to test that from Vimscript. It's not ebcdic, so I was just curious how to determine that we are running on S390? I did not see anything obvious at :h feature-list.

James McCoy

unread,
Jun 12, 2020, 9:27:59 AM6/12/20
to vim/vim, vim-dev ML, Comment

  1. So even so the test works by coincidence only, what would be a better and reliable way to test? I suppose your answer to this question is: There is no way, so don't bother?

I would say that the #{sort: 'none'} case can't be tested. This is exactly what's unspecified.

However, you can probably use that data to determine how the rest of the test assertions should look. Although it's still not guaranteed, I think it's far less likely that the ordering will change among different readdir() calls when there are no intervening changes to the filesystem.

  1. How can I detect from within Vim that we are running on s390?

There shouldn't be any reason to do that. There's nothing unique about an s390 system that's relevant to this test. The particulars of the Travis setup for CI might be relevant, but that has no bearing on any other s390 system.

If my above suggestion doesn't work, then maybe it would be worthwhile to change .travis.yml so it skips this test on s390. However, I would argue that's just hiding a flaky test that's going to cause problems downstream and cause people to waste time investigating false-negative test failures.

It's not ebcdic, so I was just curious how to determine that we are running on S390?

Right, because there's nothing different about how Vim is built. It's just a different architecture. There's nothing in Vim that let's you distinguish between i386, amd64, mips, m68k, etc.

K.Takata

unread,
Jun 12, 2020, 10:21:24 AM6/12/20
to vim/vim, vim-dev ML, Comment

I would say that the #{sort: 'none'} case can't be tested.

Agree. It depends on its underlying filesystem, not on OS.

Gary Johnson

unread,
Jun 12, 2020, 12:12:10 PM6/12/20
to vim/vim, vim-dev ML, Comment

@ghgary commented on this pull request.


In src/testdir/test_functions.vim:

> @@ -1903,6 +1903,54 @@ func Test_readdirex()
   eval 'Xdir'->delete('rf')
 endfunc
 
+func Test_readdirex_sort()
+  CheckUnix
+  CheckNotBSD
+  if !(has("osxdarwin") || has("osx") || has("macunix"))
+    let _collate = v:collate
+    call mkdir('Xdir2')
+    call writefile(['1'], 'Xdir2/README.txt')
+    call writefile(['2'], 'Xdir2/Readme.txt')
+    call writefile(['3'], 'Xdir2/readme.txt')
+
+    " Skip tests on Mac OS X (does not allow several files with different caseing)

Spelling: caseing -> casing

Christian Brabandt

unread,
Jun 14, 2020, 12:45:06 PM6/14/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 1 commit.

Christian Brabandt

unread,
Jun 14, 2020, 12:59:05 PM6/14/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 1 commit.

  • 1c4fefe Use ifdef constant instead of number

Bram Moolenaar

unread,
Jun 14, 2020, 1:50:26 PM6/14/20
to vim/vim, vim-dev ML, Comment

The Implementation looks OK now, thanks.
We should have a test that also works on Mac, using different file names. Also, the test still fails on s390.

Tony Mechelynck

unread,
Jun 14, 2020, 1:59:40 PM6/14/20
to vim/vim, vim-dev ML, Comment

The Implementation looks OK now, thanks.
We should have a test that also works on Mac, using different file names. Also, the test still fails on s390.

Maybe do the test differently if has('ebcdic')? (zArchitecture, but not Linux on Z, usually uses EBCDIC encoding IIUC.)

K.Takata

unread,
Jun 14, 2020, 9:27:12 PM6/14/20
to vim/vim, vim-dev ML, Comment

@k-takata commented on this pull request.


In src/testdir/test_functions.vim:

> +  if !(has("osxdarwin") || has("osx") || has("macunix"))

+    let _collate = v:collate

+    call mkdir('Xdir2')

+    call writefile(['1'], 'Xdir2/README.txt')

+    call writefile(['2'], 'Xdir2/Readme.txt')

+    call writefile(['3'], 'Xdir2/readme.txt')

+

+    " 1) default

+    let files = readdirex('Xdir2')->map({-> v:val.name})

+    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort using default')

+

+    " 2) no sorting

+    let files = readdirex('Xdir2', 1, #{sort: 'none'})->map({-> v:val.name})

+    " not possible to assert the order in which the files appear, so just make

+    " sure it matches in any order.

+    call assert_match('^\c\(readme\C\.txt\)\{3\}$', join(files, ''), 'unsorted')

How about comparing after sorting?

⬇️ Suggested change
-    call assert_match('^\c\(readme\C\.txt\)\{3\}$', join(files, ''), 'unsorted')

+    call assert_match(['README.txt', 'Readme.txt', 'readme.txt'], sort(files), 'unsorted')


In src/testdir/test_functions.vim:

> +    let files = readdirex('Xdir2')->map({-> v:val.name})

+    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort using default')

+

+    " 2) no sorting

+    let files = readdirex('Xdir2', 1, #{sort: 'none'})->map({-> v:val.name})

+    " not possible to assert the order in which the files appear, so just make

+    " sure it matches in any order.

+    call assert_match('^\c\(readme\C\.txt\)\{3\}$', join(files, ''), 'unsorted')

+

+    " 3) sort by case (same as default)

+    let files = readdirex('Xdir2', 1, #{sort: 'case'})->map({-> v:val.name})

+    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort by case')

+

+    " 4) sort by ignoring case

+    let files = readdirex('Xdir2', 1, #{sort: 'icase'})->map({-> v:val.name})

+    call assert_equal(['README.txt', 'readme.txt', 'Readme.txt'], files, 'sort by icase')

I don't think the order of the files can be determined here.
'README.txt', 'readme.txt' and 'Readme.txt' have the same priority, then they can be sorted in any order.

Maybe, a good additional test is e.g. using 'a.txt', 'b.txt' and 'Z.txt':
case -> 'Z.txt', 'a.txt', 'b.txt'
icase -> 'a.txt', 'b.txt', 'Z.txt'
This test can be also executed on Windows and macOS.


In src/testdir/test_functions.vim:

> +    call assert_equal(['README.txt', 'readme.txt', 'Readme.txt'], files, 'sort by icase')

+

+    " 5) Default Collation

+    let collate = v:collate

+    lang collate C

+    let files = readdirex('Xdir2', 1, #{sort: 'collate'})->map({-> v:val.name})

+    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort by C collation')

+

+    " 6) Collation de_DE

+    " Switch locale, this may not work on the CI system, if the locale isn't

+    " available

+    try

+      lang collate de_DE

+      let files = readdirex('Xdir2', 1, #{sort: 'collate'})->map({-> v:val.name})

+      call assert_equal(['readme.txt', 'Readme.txt', 'README.txt'], files, 'sort by de_DE collation')

+    catch

How about adding a skip message?

⬇️ Suggested change
-    catch

+    catch

+      throw 'Skipped: de_DE collation is not available'


In src/vim.h:

> +#ifdef HAVE_STRCOLL

+ # define STRCOLL(d, s)     strcoll((char *)(d), (char *)(s))

+# else

+ # define STRCOLL(d, s)     strcmp((char *)(d), (char *)(s))

+# endif

⬇️ Suggested change
-#ifdef HAVE_STRCOLL

- # define STRCOLL(d, s)     strcoll((char *)(d), (char *)(s))

-# else

- # define STRCOLL(d, s)     strcmp((char *)(d), (char *)(s))

-# endif

+#ifdef HAVE_STRCOLL

+# define STRCOLL(d, s)     strcoll((char *)(d), (char *)(s))

+#else

+# define STRCOLL(d, s)     strcmp((char *)(d), (char *)(s))

+#endif


In src/testdir/test_functions.vim:

> +  " Skip tests on Mac OS X (does not allow several files with different casing)

+  if !(has("osxdarwin") || has("osx") || has("macunix"))

Same for Cygwin.

⬇️ Suggested change
-  " Skip tests on Mac OS X (does not allow several files with different casing)

-  if !(has("osxdarwin") || has("osx") || has("macunix"))

+  " Skip tests on Mac OS X and Cygwin (does not allow several files with different casing)

+  if !(has("osxdarwin") || has("osx") || has("macunix") || has("win32unix"))

Maybe it's better to add a skip message?


In src/filepath.c:

> +	semsg(_(e_no_dict_key), "sort");

+	return FAIL;

I'm still wondering if this error is really needed. #6229 (comment)


In src/vim.h:

> +# define READDIR_SORT_NONE		0  // do not sort

+# define READDIR_SORT_BYTE		1  // sort by byte order (strcmp), default

+# define READDIR_SORT_IC		2  // sort ignoring case (strcasecmp)

+# define READDIR_SORT_COLLATE		3  // sort according to collation (strcoll)

⬇️ Suggested change
-# define READDIR_SORT_NONE		0  // do not sort

-# define READDIR_SORT_BYTE		1  // sort by byte order (strcmp), default

-# define READDIR_SORT_IC		2  // sort ignoring case (strcasecmp)

-# define READDIR_SORT_COLLATE		3  // sort according to collation (strcoll)

+#define READDIR_SORT_NONE		0  // do not sort

+#define READDIR_SORT_BYTE		1  // sort by byte order (strcmp), default

+#define READDIR_SORT_IC		2  // sort ignoring case (strcasecmp)

+#define READDIR_SORT_COLLATE		3  // sort according to collation (strcoll)

Tony Mechelynck

unread,
Jun 14, 2020, 10:11:19 PM6/14/20
to vim/vim, vim-dev ML, Comment

@tonymec commented on this pull request.


In src/testdir/test_functions.vim:

> +    let files = readdirex('Xdir2')->map({-> v:val.name})
+    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort using default')
+
+    " 2) no sorting
+    let files = readdirex('Xdir2', 1, #{sort: 'none'})->map({-> v:val.name})
+    " not possible to assert the order in which the files appear, so just make
+    " sure it matches in any order.
+    call assert_match('^\c\(readme\C\.txt\)\{3\}$', join(files, ''), 'unsorted')
+
+    " 3) sort by case (same as default)
+    let files = readdirex('Xdir2', 1, #{sort: 'case'})->map({-> v:val.name})
+    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort by case')
+
+    " 4) sort by ignoring case
+    let files = readdirex('Xdir2', 1, #{sort: 'icase'})->map({-> v:val.name})
+    call assert_equal(['README.txt', 'readme.txt', 'Readme.txt'], files, 'sort by icase')

Yeah, but on EBCDIC systems, in byte-value sorting, lowercase comes before uppercase and digits come last, (a-i 0x81-0x89, j-r 0x91-0x99, s-z 0xA2-0xA9, A-I 0xC1-0xC9, J-R 0xD1-0xD9, S-Z 0xE2-0xE9, digits 0xF0-0xF9, with punctuation characters in-between), so you may need to test for has('ebcdic') and if true compare A.txt, B.txt and z.txt (and if sorted on non-case-folded byte values, z will come before A).

Best regards,
Tony.

James McCoy

unread,
Jun 15, 2020, 2:06:29 AM6/15/20
to vim/vim, vim-dev ML, Comment

Also, the test still fails on s390.

Maybe do the test differently if has('ebcdic')?

has('ebcdic') is irrelevant for the Linux s390 build.

James McCoy

unread,
Jun 15, 2020, 8:47:07 AM6/15/20
to vim/vim, vim-dev ML, Comment

I would say that the #{sort: 'none'} case can't be tested. This is exactly what's unspecified.

However, you can probably use that data to determine how the rest of the test assertions should look.

I was thinking of something like below. This does pass on Travis.

diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 2316ac01d13..2463e3e5f67 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -1942,21 +1942,23 @@ func Test_readdirex_sort()
 
     " 1) default
     let files = readdirex('Xdir2')->map({-> v:val.name})
+    let default = copy(files)
     call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort using default')
 
     " 2) no sorting
     let files = readdirex('Xdir2', 1, #{sort: 'none'})->map({-> v:val.name})
+    let unsorted = copy(files)
     " not possible to assert the order in which the files appear, so just make
     " sure it matches in any order.
     call assert_match('^\c\(readme\C\.txt\)\{3\}$', join(files, ''), 'unsorted')
 
     " 3) sort by case (same as default)
     let files = readdirex('Xdir2', 1, #{sort: 'case'})->map({-> v:val.name})
-    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort by case')
+    call assert_equal(default, files, 'sort by case')
 
     " 4) sort by ignoring case
     let files = readdirex('Xdir2', 1, #{sort: 'icase'})->map({-> v:val.name})
-    call assert_equal(['README.txt', 'readme.txt', 'Readme.txt'], files, 'sort by icase')
+    call assert_equal(unsorted->sort('i'), files, 'sort by icase')
 
     " 5) Default Collation
     let collate = v:collate

Christian Brabandt

unread,
Jun 15, 2020, 8:51:02 AM6/15/20
to vim/vim, vim-dev ML, Comment

thanks everybody, will rework and apply the suggestions later today.

Christian Brabandt

unread,
Jun 15, 2020, 2:05:27 PM6/15/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/testdir/test_functions.vim:

> +  if !(has("osxdarwin") || has("osx") || has("macunix"))

+    let _collate = v:collate

+    call mkdir('Xdir2')

+    call writefile(['1'], 'Xdir2/README.txt')

+    call writefile(['2'], 'Xdir2/Readme.txt')

+    call writefile(['3'], 'Xdir2/readme.txt')

+

+    " 1) default

+    let files = readdirex('Xdir2')->map({-> v:val.name})

+    call assert_equal(['README.txt', 'Readme.txt', 'readme.txt'], files, 'sort using default')

+

+    " 2) no sorting

+    let files = readdirex('Xdir2', 1, #{sort: 'none'})->map({-> v:val.name})

+    " not possible to assert the order in which the files appear, so just make

+    " sure it matches in any order.

+    call assert_match('^\c\(readme\C\.txt\)\{3\}$', join(files, ''), 'unsorted')

And here I am, thinking I was overly clever using assert_match() :/

Thanks, good suggestion 👍

Christian Brabandt

unread,
Jun 15, 2020, 2:18:18 PM6/15/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/filepath.c:

> +	semsg(_(e_no_dict_key), "sort");
+	return FAIL;

I don't mind either way. I leave it to @brammool, the error message also needs a proper number. I am on the fence, but I slightly prefer, if Vim would error if I had a typo like readdirex(..., 1, #{sorta: 'case'}.

Christian Brabandt

unread,
Jun 15, 2020, 2:19:23 PM6/15/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/vim.h:

> +# define READDIR_SORT_NONE		0  // do not sort
+# define READDIR_SORT_BYTE		1  // sort by byte order (strcmp), default
+# define READDIR_SORT_IC		2  // sort ignoring case (strcasecmp)
+# define READDIR_SORT_COLLATE		3  // sort according to collation (strcoll)

Opps, where did the space come from...

Christian Brabandt

unread,
Jun 15, 2020, 3:33:55 PM6/15/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 1 commit.

Christian Brabandt

unread,
Jun 15, 2020, 3:35:36 PM6/15/20
to vim/vim, vim-dev ML, Comment

okay reworked.

Dominique Pellé

unread,
Jun 15, 2020, 3:55:05 PM6/15/20
to vim/vim, vim-dev ML, Comment

@dpelle commented on this pull request.


In runtime/doc/mlang.txt:

>  			Print the current language (aka locale).
 			With the "messages" argument the language used for
 			messages is printed.  Technical: LC_MESSAGES.
 			With the "ctype" argument the language used for
 			character encoding is printed.  Technical: LC_CTYPE.
 			With the "time" argument the language used for
 			strftime() is printed.  Technical: LC_TIME.
+			With the "collate" argument the language used for
+                        collation order is printed.  Technical: LC_COLLATE.

This line uses spaces for indentation whereas nearby line use tabs (inconsistent).

K.Takata

unread,
Jun 15, 2020, 7:27:28 PM6/15/20
to vim/vim, vim-dev ML, Comment

@k-takata commented on this pull request.


In src/testdir/test_functions.vim:

> @@ -1929,6 +1929,86 @@ func Test_readdirex()
   eval 'Xdir'->delete('rf')
 endfunc
 
+func Test_readdirex_sort()
+  CheckUnix
+  CheckNotBSD

Is this check still needed? Doesn't this test work on BSDs?

Christian Brabandt

unread,
Jun 16, 2020, 1:21:37 AM6/16/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 2 commits.

  • 1480cad Review: use tab instead of spaces for indent
  • 6d79eed Review: Remove CheckUnix Test

K.Takata

unread,
Jun 16, 2020, 1:31:44 AM6/16/20
to vim/vim, vim-dev ML, Comment

@k-takata commented on this pull request.


In src/testdir/test_functions.vim:

> -  CheckUnix
-  CheckNotBSD

Sorry, I meant removing only CheckNotBSD. I think CheckUnix is still needed.

Christian Brabandt

unread,
Jun 16, 2020, 2:01:55 AM6/16/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 5 commits.

  • 4c6202a Review: Use tabs instead of spaces for indent
  • db5278a Review: Remove CheckUnix and CheckUnixBSD test
  • c881dcb test: Clean up correctly in skipped case
  • a914b48 allow to determine sort order for readdir() as well
  • 7ba2814 Test: test readdir() with sort argument

Christian Brabandt

unread,
Jun 16, 2020, 2:02:26 AM6/16/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/testdir/test_functions.vim:

> @@ -1929,6 +1929,86 @@ func Test_readdirex()
   eval 'Xdir'->delete('rf')
 endfunc
 
+func Test_readdirex_sort()
+  CheckUnix
+  CheckNotBSD

I removed.

Christian Brabandt

unread,
Jun 16, 2020, 2:04:08 AM6/16/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 4 commits.

  • 59682d9 Review: Remove CheckUnix and CheckUnixBSD test
  • 9c1c42f test: Clean up correctly in skipped case
  • faa9897 allow to determine sort order for readdir() as well
  • 3c741f5 Test: test readdir() with sort argument

Christian Brabandt

unread,
Jun 16, 2020, 2:04:24 AM6/16/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In runtime/doc/mlang.txt:

>  			Print the current language (aka locale).
 			With the "messages" argument the language used for
 			messages is printed.  Technical: LC_MESSAGES.
 			With the "ctype" argument the language used for
 			character encoding is printed.  Technical: LC_CTYPE.
 			With the "time" argument the language used for
 			strftime() is printed.  Technical: LC_TIME.
+			With the "collate" argument the language used for
+                        collation order is printed.  Technical: LC_COLLATE.

thanks, fixed it as well.

Christian Brabandt

unread,
Jun 16, 2020, 2:04:50 AM6/16/20
to vim/vim, vim-dev ML, Comment

@chrisbra commented on this pull request.


In src/testdir/test_functions.vim:

> -  CheckUnix
-  CheckNotBSD

Hm, I thought we do not need this anymore. Anyhow, I re-added it back

K.Takata

unread,
Jun 16, 2020, 2:28:57 AM6/16/20
to vim/vim, vim-dev ML, Comment

Christian Brabandt

unread,
Jun 16, 2020, 2:57:34 AM6/16/20
to vim/vim, vim-dev ML, Comment

Which one? It's not clear from that link.

K.Takata

unread,
Jun 16, 2020, 3:17:43 AM6/16/20
to vim/vim, vim-dev ML, Comment

Oh, sorry. The description of readdir():
https://github.com/vim/vim/blob/3c741f50c6132fac1dd0992b56839117f281e1ce/runtime/doc/eval.txt#L7921

It should be

 The list will by default be sorted by name (case sensitive), 
 see below for changing the sorting. 

like readdirex().

And readdirex() should be also updated?
https://github.com/vim/vim/blob/3c741f50c6132fac1dd0992b56839117f281e1ce/runtime/doc/eval.txt#L7978-L7979
Not "below" now, I think.

Christian Brabandt

unread,
Jun 16, 2020, 3:31:44 AM6/16/20
to vim/vim, vim-dev ML, Push

@chrisbra pushed 1 commit.

  • 51bdd1c Review: mention sorting capabilities for readdir() and readdirex()

codecov[bot]

unread,
Jun 16, 2020, 4:37:36 AM6/16/20
to vim/vim, vim-dev ML, Comment

Codecov Report

Merging #6229 into master will decrease coverage by 0.00%.
The diff coverage is 87.27%.

Impacted file tree graph

@@            Coverage Diff             @@

##           master    #6229      +/-   ##

==========================================

- Coverage   87.48%   87.47%   -0.01%     

==========================================

  Files         143      143              

  Lines      158424   158475      +51     

==========================================

+ Hits       138590   138626      +36     

- Misses      19834    19849      +15     
Impacted Files Coverage Δ
src/evalfunc.c 96.37% <ø> (ø)
src/evalvars.c 95.98% <ø> (ø)
src/filepath.c 86.23% <77.77%> (-0.19%) ⬇️
src/fileio.c 84.85% <93.75%> (+0.04%) ⬆️
src/cmdexpand.c 92.96% <100.00%> (+<0.01%) ⬆️
src/ex_cmds2.c 90.85% <100.00%> (+0.14%) ⬆️
src/gui.c 63.37% <0.00%> (-0.51%) ⬇️
src/mbyte.c 79.62% <0.00%> (-0.25%) ⬇️
src/sign.c 94.77% <0.00%> (-0.18%) ⬇️
src/window.c 89.55% <0.00%> (-0.11%) ⬇️
... and 10 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b340bae...51bdd1c. Read the comment docs.

Christian Brabandt

unread,
Jun 16, 2020, 4:57:17 AM6/16/20
to vim/vim, vim-dev ML, Comment

all CI pass now

Christian Brabandt

unread,
Jun 16, 2020, 4:57:50 AM6/16/20
to vim/vim, vim-dev ML, Comment

I can squash into a single commit and force-push, if this is helpful.

Bram Moolenaar

unread,
Jun 16, 2020, 1:40:41 PM6/16/20
to vim/vim, vim-dev ML, Comment

I suppose it's OK to include now. Thanks for fine-tuning it.

Bram Moolenaar

unread,
Jun 16, 2020, 2:04:15 PM6/16/20
to vim/vim, vim-dev ML, Comment

Closed #6229 via 84cf6bd.

Yegappan Lakshmanan

unread,
Jun 16, 2020, 3:21:39 PM6/16/20
to vim_dev, reply+ACY5DGE3JCGI3HFVKE...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi Christian,

On Tue, Jun 16, 2020 at 1:57 AM Christian Brabandt <vim-dev...@256bit.org> wrote:

I can squash into a single commit and force-push, if this is helpful.



It will be good to add some more tests for the error cases in the new functions.
These show up as missing in the code coverage report:


For example, when the argument is not a dict or the "sort" key is not present.

Regards,
Yegappan 

vim-dev ML

unread,
Jun 16, 2020, 3:21:58 PM6/16/20
to vim/vim, vim-dev ML, Your activity


You are receiving this because you are subscribed to this thread.

Christian Brabandt

unread,
Jun 16, 2020, 4:08:07 PM6/16/20
to vim/vim, vim-dev ML, Comment

Thanks, done: #6278


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Jun 16, 2020, 5:29:30 PM6/16/20
to vim_dev, reply+ACY5DGHVTONW24SJTL...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi Christian,

On Tue, Jun 16, 2020 at 1:08 PM Christian Brabandt <vim-dev...@256bit.org> wrote:

Thanks, done: #6278



Thanks for adding the tests.

After adding a lot of tests we have reached 87.5% code coverage recently.
The goal is to reach 90%. To maintain this, we need to make sure that the
newly introduced code doesn't reduce the code coverage.

Regards,
Yegappan
 

vim-dev ML

unread,
Jun 16, 2020, 5:29:49 PM6/16/20
to vim/vim, vim-dev ML, Your activity

Hi Christian,

On Tue, Jun 16, 2020 at 1:08 PM Christian Brabandt <
vim-dev...@256bit.org> wrote:

> Thanks, done: #6278 <https://github.com/vim/vim/pull/6278>

>
>
>
Thanks for adding the tests.

After adding a lot of tests we have reached 87.5% code coverage recently.
The goal is to reach 90%. To maintain this, we need to make sure that the
newly introduced code doesn't reduce the code coverage.

Regards,
Yegappan


You are receiving this because you are subscribed to this thread.

lacygoill

unread,
Oct 26, 2020, 7:06:56 PM10/26/20
to vim/vim, vim-dev ML, Comment

I think this todo item is no longer needed:
https://github.com/vim/vim/blob/caf73dcfade0a435ea3f989285b43f07c40c9948/runtime/doc/todo.txt#L282


You are receiving this because you commented.

Bram Moolenaar

unread,
Oct 27, 2020, 2:45:49 PM10/27/20
to vim/vim, vim-dev ML, Comment

I'll update the todo list

Reply all
Reply to author
Forward
0 new messages