sort: Use a stable sort

This allows e.g. sorting first by dirname and then by basename.
This commit is contained in:
Fabian Homborg 2022-04-07 16:09:28 +02:00
parent 640bd7b183
commit 4fec045073
2 changed files with 26 additions and 4 deletions

View file

@ -736,16 +736,24 @@ static int path_sort(parser_t &parser, io_streams_t &streams, int argc, const wc
funced[arg] = func(arg);
}
std::sort(list.begin(), list.end(),
// We use a stable sort here, and also explicit < and >,
// to avoid changing the order so you can chain calls.
std::stable_sort(list.begin(), list.end(),
[&](const wcstring &a, const wcstring &b) {
return (wcsfilecmp_glob(funced[a].c_str(), funced[b].c_str()) < 0) != opts.invert;
if (!opts.invert)
return (wcsfilecmp_glob(funced[a].c_str(), funced[b].c_str()) < 0);
else
return (wcsfilecmp_glob(funced[a].c_str(), funced[b].c_str()) > 0);
});
} else {
// Without --what, we just sort by the entire path,
// so we have no need to transform and such.
std::sort(list.begin(), list.end(),
std::stable_sort(list.begin(), list.end(),
[&](const wcstring &a, const wcstring &b) {
return (wcsfilecmp_glob(a.c_str(), b.c_str()) < 0) != opts.invert;
if (!opts.invert)
return (wcsfilecmp_glob(a.c_str(), b.c_str()) < 0);
else
return (wcsfilecmp_glob(a.c_str(), b.c_str()) > 0);
});
}

View file

@ -141,3 +141,17 @@ string replace -r "^"(pwd -P | string escape --style=regex)'/' "" -- $path
path resolve /banana//terracota/terracota/booooo/../pie
# CHECK: /banana/terracota/terracota/pie
path sort --what=basename {def,abc}/{456,123,789,abc,def,0} | path sort --what=dirname -v
# CHECK: def/0
# CHECK: def/123
# CHECK: def/456
# CHECK: def/789
# CHECK: def/abc
# CHECK: def/def
# CHECK: abc/0
# CHECK: abc/123
# CHECK: abc/456
# CHECK: abc/789
# CHECK: abc/abc
# CHECK: abc/def