Implement path:join, separator, and list-separator

Resolves #1562
This commit is contained in:
Kurtis Rader 2022-06-24 18:33:16 -07:00 committed by Qi Xiao
parent 27f5c8cf6b
commit 1638311854
3 changed files with 50 additions and 0 deletions

View File

@ -35,3 +35,6 @@ and compiled, even if it is not executed:
- A new type of interactive abbreviation: `edit:command-abbr`
([#1472](https://b.elv.sh/1472)).
- A new `path:join` command and `path:separator` and `path:list-separator`
variables ([#1562](https://b.elv.sh/1562)).

View File

@ -7,10 +7,15 @@ import (
"src.elv.sh/pkg/eval"
"src.elv.sh/pkg/eval/errs"
"src.elv.sh/pkg/eval/vars"
)
// Ns is the namespace for the re: module.
var Ns = eval.BuildNsNamed("path").
AddVars(map[string]vars.Var{
"list-separator": vars.NewReadOnly(string(filepath.ListSeparator)),
"separator": vars.NewReadOnly(string(filepath.Separator)),
}).
AddGoFns(map[string]any{
"abs": filepath.Abs,
"base": filepath.Base,
@ -21,10 +26,31 @@ var Ns = eval.BuildNsNamed("path").
"is-abs": filepath.IsAbs,
"is-dir": isDir,
"is-regular": isRegular,
"join": filepath.Join,
"temp-dir": tempDir,
"temp-file": tempFile,
}).Ns()
//elvdoc:var list-separator
//
// OS-specific path list separator. Colon on UNIX and semi-colon on Windows. This variable is
// read-only.
//
// ```elvish-transcript
// ~> put $path:list-separator
// ▶ :
// ```
//elvdoc:var separator
//
// OS-specific path separator. Forward slash on UNIX and backslash on Windows. This variable is
// read-only.
//
// ```elvish-transcript
// ~> put $path:separator
// ▶ /
// ```
//elvdoc:fn abs
//
// ```elvish
@ -131,6 +157,24 @@ var Ns = eval.BuildNsNamed("path").
// external `realpath` or `readlink` command found on many systems. See the [Go
// documentation](https://pkg.go.dev/path/filepath#EvalSymlinks) for more details.
//elvdoc:fn join
//
// ```elvish
// path:join $path-component...
// ```
//
// Join joins any number of path elements into a single path, separating them with an OS specific
// separator. Empty elements are ignored. The result is cleaned. However, if the argument list is
// empty or all its elements are empty, Join returns an empty string. On Windows, the result will
// only be a UNC path if the first non-empty element is a UNC path.
//
// ```elvish-transcript
// ~> path:join home user bin
// ▶ home/user/bin
// ~> path:join $path:separator home user bin
// ▶ /home/user/bin
// ```
//elvdoc:fn is-dir
//
// ```elvish

View File

@ -36,6 +36,8 @@ func TestPath(t *testing.T) {
// This block of tests is not meant to be comprehensive. Their primary purpose is to simply
// ensure the Elvish command is correctly mapped to the relevant Go function. We assume the
// Go function behaves correctly.
That("put $path:list-separator").Puts(string(filepath.ListSeparator)),
That("put $path:separator").Puts(string(filepath.Separator)),
That("path:abs a/b/c.png").Puts(absPath),
That("path:base a/b/d.png").Puts("d.png"),
That("path:clean ././x").Puts("x"),
@ -45,6 +47,7 @@ func TestPath(t *testing.T) {
That("path:ext a/b/s").Puts(""),
That("path:is-abs a/b/s").Puts(false),
That("path:is-abs "+absPath).Puts(true),
That("path:join a b c").Puts(filepath.Join("a", "b", "c")),
// Elvish "path:" module functions that are not trivial wrappers around a Go stdlib function
// should have comprehensive tests below this comment.