@tui-sandbox/library 11.0.2 → 11.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/browser/assets/{index-NiH4zpUV.js → index-D4YBlffP.js} +7 -7
- package/dist/browser/index.html +1 -1
- package/dist/src/browser/neovim-client.js +2 -0
- package/dist/src/browser/neovim-client.js.map +1 -1
- package/dist/src/client/MyNeovimConfigModification.d.ts +4 -0
- package/dist/src/client/MyNeovimConfigModification.js +2 -0
- package/dist/src/client/MyNeovimConfigModification.js.map +1 -0
- package/dist/src/client/MyNeovimConfigModification.test.d.ts +1 -0
- package/dist/src/client/MyNeovimConfigModification.test.js +13 -0
- package/dist/src/client/MyNeovimConfigModification.test.js.map +1 -0
- package/dist/src/client/neovim-terminal-client.js +5 -4
- package/dist/src/client/neovim-terminal-client.js.map +1 -1
- package/dist/src/scripts/tui.js +8 -3
- package/dist/src/scripts/tui.js.map +1 -1
- package/dist/src/server/applications/neovim/NeovimApplication.d.ts +14 -1
- package/dist/src/server/applications/neovim/NeovimApplication.js +15 -11
- package/dist/src/server/applications/neovim/NeovimApplication.js.map +1 -1
- package/dist/src/server/applications/neovim/api.d.ts +1 -1
- package/dist/src/server/applications/neovim/api.js +8 -4
- package/dist/src/server/applications/neovim/api.js.map +1 -1
- package/dist/src/server/applications/neovim/neovimRouter.d.ts +11 -10
- package/dist/src/server/applications/neovim/neovimRouter.js +6 -5
- package/dist/src/server/applications/neovim/neovimRouter.js.map +1 -1
- package/dist/src/server/applications/terminal/terminalRouter.d.ts +4 -4
- package/dist/src/server/blockingCommandInputSchema.d.ts +2 -2
- package/dist/src/server/blockingCommandInputSchema.test.js +7 -9
- package/dist/src/server/blockingCommandInputSchema.test.js.map +1 -1
- package/dist/src/server/cypress-support/contents.js +2 -1
- package/dist/src/server/cypress-support/contents.js.map +1 -1
- package/dist/src/server/dirtree/index.test.js +23 -0
- package/dist/src/server/dirtree/index.test.js.map +1 -1
- package/dist/src/server/server.d.ts +5 -4
- package/dist/src/server/utilities/tabId.d.ts +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/browser/neovim-client.ts +4 -1
- package/src/client/MyNeovimConfigModification.test.ts +24 -0
- package/src/client/MyNeovimConfigModification.ts +8 -0
- package/src/client/neovim-terminal-client.ts +5 -4
- package/src/scripts/tui.ts +12 -3
- package/src/server/applications/neovim/NeovimApplication.ts +39 -16
- package/src/server/applications/neovim/api.ts +12 -4
- package/src/server/applications/neovim/neovimRouter.ts +6 -5
- package/src/server/blockingCommandInputSchema.test.ts +7 -9
- package/src/server/cypress-support/contents.ts +2 -1
- package/src/server/dirtree/index.test.ts +23 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tui-sandbox/library",
|
|
3
|
-
"version": "11.0
|
|
3
|
+
"version": "11.2.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/mikavilpas/tui-sandbox"
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"@types/command-exists": "1.2.3",
|
|
33
33
|
"@types/cors": "2.8.19",
|
|
34
34
|
"@types/express": "5.0.3",
|
|
35
|
-
"@types/node": "24.0
|
|
35
|
+
"@types/node": "24.1.0",
|
|
36
36
|
"nodemon": "3.1.10",
|
|
37
|
-
"vite": "7.0.
|
|
37
|
+
"vite": "7.0.6",
|
|
38
38
|
"vitest": "3.2.4",
|
|
39
|
-
"zod": "4.0.
|
|
39
|
+
"zod": "4.0.10"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"cypress": "^13 || ^14",
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
import type { StartTerminalGenericArguments } from "../server/applications/terminal/TerminalTestApplication.js"
|
|
11
11
|
import type { BlockingCommandClientInput } from "../server/blockingCommandInputSchema.js"
|
|
12
12
|
import type {
|
|
13
|
+
AllKeys,
|
|
13
14
|
BlockingShellCommandOutput,
|
|
14
15
|
RunExCommandOutput,
|
|
15
16
|
RunLuaCodeOutput,
|
|
@@ -42,7 +43,9 @@ window.startNeovim = async function (startArgs?: StartNeovimGenericArguments): P
|
|
|
42
43
|
additionalEnvironmentVariables: startArgs?.additionalEnvironmentVariables,
|
|
43
44
|
filename: startArgs?.filename ?? "initial-file.txt",
|
|
44
45
|
startupScriptModifications: startArgs?.startupScriptModifications ?? [],
|
|
45
|
-
|
|
46
|
+
headlessCmd: undefined,
|
|
47
|
+
NVIM_APPNAME: startArgs?.NVIM_APPNAME,
|
|
48
|
+
} satisfies AllKeys<StartNeovimGenericArguments>)
|
|
46
49
|
|
|
47
50
|
const neovimBrowserApi: GenericNeovimBrowserApi = {
|
|
48
51
|
runBlockingShellCommand(input: BlockingCommandClientInput): Promise<BlockingShellCommandOutput> {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import type { MyNeovimConfigModification } from "./MyNeovimConfigModification.js"
|
|
3
|
+
|
|
4
|
+
const testDirectoryFiles = z.enum([
|
|
5
|
+
"config-modifications/add_command_to_count_open_buffers.lua",
|
|
6
|
+
"config-modifications/add_command_to_update_buffer_after_timeout.lua",
|
|
7
|
+
"config-modifications/don't_crash_when_modification_contains_unescaped_characters\".lua",
|
|
8
|
+
"config-modifications/subdir/subdir-modification.lua",
|
|
9
|
+
"config-modifications/subdir",
|
|
10
|
+
"config-modifications",
|
|
11
|
+
])
|
|
12
|
+
type MyTestDirectoryFile = z.infer<typeof testDirectoryFiles>
|
|
13
|
+
|
|
14
|
+
type result = MyNeovimConfigModification<MyTestDirectoryFile>
|
|
15
|
+
|
|
16
|
+
it("returns config-modifications recursively", () => {
|
|
17
|
+
assertType<
|
|
18
|
+
| "add_command_to_count_open_buffers.lua"
|
|
19
|
+
| "add_command_to_update_buffer_after_timeout.lua"
|
|
20
|
+
| "don't_crash_when_modification_contains_unescaped_characters\".lua"
|
|
21
|
+
| "subdir/subdir-modification.lua"
|
|
22
|
+
| "subdir"
|
|
23
|
+
>(1 as unknown as result)
|
|
24
|
+
})
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Returns all the available Neovim config-modifications, recursively.
|
|
2
|
+
* @type T - the MyTestDirectoryFile type, which is generated by tui-sandbox
|
|
3
|
+
*/
|
|
4
|
+
export type MyNeovimConfigModification<T extends string> = T extends `config-modifications/${infer Rest}`
|
|
5
|
+
? Rest extends ""
|
|
6
|
+
? never
|
|
7
|
+
: Rest
|
|
8
|
+
: never
|
|
@@ -86,10 +86,11 @@ export class NeovimTerminalClient {
|
|
|
86
86
|
filename: args.filename,
|
|
87
87
|
additionalEnvironmentVariables: args.additionalEnvironmentVariables,
|
|
88
88
|
startupScriptModifications: args.startupScriptModifications,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
NVIM_APPNAME: args.NVIM_APPNAME,
|
|
90
|
+
},
|
|
91
|
+
terminalDimensions: {
|
|
92
|
+
cols: this.terminal.cols,
|
|
93
|
+
rows: this.terminal.rows,
|
|
93
94
|
},
|
|
94
95
|
tabId: this.tabId,
|
|
95
96
|
})
|
package/src/scripts/tui.ts
CHANGED
|
@@ -30,8 +30,13 @@ const args = process.argv.slice(2)
|
|
|
30
30
|
|
|
31
31
|
if (args[0] === "neovim") {
|
|
32
32
|
if (args[1] === "prepare" && args.length === 2) {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const NVIM_APPNAME = process.env["NVIM_APPNAME"]
|
|
34
|
+
console.log(`🚀 Installing neovim dependencies${NVIM_APPNAME ? ` for NVIM_APPNAME=${NVIM_APPNAME}` : ""}...`)
|
|
35
|
+
await installDependencies(
|
|
36
|
+
config.directories.testEnvironmentPath,
|
|
37
|
+
process.env["NVIM_APPNAME"],
|
|
38
|
+
config.directories
|
|
39
|
+
).catch((err: unknown) => {
|
|
35
40
|
console.error("Error installing neovim dependencies", err)
|
|
36
41
|
process.exit(1)
|
|
37
42
|
})
|
|
@@ -54,7 +59,11 @@ if (args[0] === "neovim") {
|
|
|
54
59
|
const testDirectory = await prepareNewTestDirectory(config.directories)
|
|
55
60
|
await app.startNextAndKillCurrent(
|
|
56
61
|
testDirectory,
|
|
57
|
-
{
|
|
62
|
+
{
|
|
63
|
+
filename: "empty.txt",
|
|
64
|
+
headlessCmd: command,
|
|
65
|
+
NVIM_APPNAME: process.env["NVIM_APPNAME"],
|
|
66
|
+
},
|
|
58
67
|
{ cols: 80, rows: 24 }
|
|
59
68
|
)
|
|
60
69
|
await app.application.untilExit()
|
|
@@ -51,9 +51,9 @@ Options:
|
|
|
51
51
|
|
|
52
52
|
See ":help startup-options" for all options.
|
|
53
53
|
|
|
54
|
-
NVIM v0.11.
|
|
55
|
-
Build type:
|
|
56
|
-
LuaJIT 2.1.
|
|
54
|
+
NVIM v0.11.2
|
|
55
|
+
Build type: Release
|
|
56
|
+
LuaJIT 2.1.1741730670
|
|
57
57
|
Run "nvim -V1 -v" for more info
|
|
58
58
|
|
|
59
59
|
*/
|
|
@@ -67,6 +67,19 @@ export type StartNeovimGenericArguments = {
|
|
|
67
67
|
/** Executes the given command with --headless -c <command> -c qa */
|
|
68
68
|
headlessCmd?: string
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* This variable controls the sub-directory that Nvim will read from (and
|
|
72
|
+
* auto-create) in each of the base directories.
|
|
73
|
+
*
|
|
74
|
+
* For example, setting $NVIM_APPNAME to "foo" before starting will cause
|
|
75
|
+
* Nvim to look for configuration files in $XDG_CONFIG_HOME/foo instead of
|
|
76
|
+
* $XDG_CONFIG_HOME/nvim. $NVIM_APPNAME must be a name, such as "foo", or a
|
|
77
|
+
* relative path, such as "foo/bar".
|
|
78
|
+
*
|
|
79
|
+
* https://neovim.io/doc/user/starting.html#_nvim_appname
|
|
80
|
+
*/
|
|
81
|
+
NVIM_APPNAME?: string
|
|
82
|
+
|
|
70
83
|
/** Additions to the environment variables for the Neovim process. These
|
|
71
84
|
* override any already existing environment variables. */
|
|
72
85
|
additionalEnvironmentVariables?: Record<string, string> | undefined
|
|
@@ -76,6 +89,7 @@ export type TerminalDimensions = { cols: number; rows: number }
|
|
|
76
89
|
|
|
77
90
|
type ResettableState = {
|
|
78
91
|
testDirectory: TestDirectory
|
|
92
|
+
NVIM_APPNAME: string | undefined
|
|
79
93
|
socketPath: string
|
|
80
94
|
client: Lazy<Promise<NeovimApiClient>>
|
|
81
95
|
}
|
|
@@ -148,7 +162,11 @@ export class NeovimApplication implements AsyncDisposable {
|
|
|
148
162
|
const stdout = this.events
|
|
149
163
|
|
|
150
164
|
await this.application.startNextAndKillCurrent(async () => {
|
|
151
|
-
const env =
|
|
165
|
+
const env = NeovimApplication.getEnvironmentVariables(
|
|
166
|
+
testDirectory,
|
|
167
|
+
startArgs.NVIM_APPNAME,
|
|
168
|
+
startArgs.additionalEnvironmentVariables
|
|
169
|
+
)
|
|
152
170
|
return TerminalApplication.start({
|
|
153
171
|
command: "nvim",
|
|
154
172
|
args: neovimArguments,
|
|
@@ -170,30 +188,35 @@ export class NeovimApplication implements AsyncDisposable {
|
|
|
170
188
|
this.state = {
|
|
171
189
|
testDirectory,
|
|
172
190
|
socketPath,
|
|
191
|
+
NVIM_APPNAME: startArgs.NVIM_APPNAME,
|
|
173
192
|
client: connectNeovimApi(socketPath),
|
|
174
193
|
}
|
|
175
194
|
|
|
176
|
-
log(`🚀 Started Neovim instance ${processId}`)
|
|
195
|
+
log(`🚀 Started Neovim instance ${processId} (NVIM_APPNAME: ${startArgs.NVIM_APPNAME})`)
|
|
177
196
|
}
|
|
178
197
|
|
|
179
|
-
public getEnvironmentVariables(
|
|
198
|
+
public static getEnvironmentVariables(
|
|
180
199
|
testDirectory: TestDirectory,
|
|
200
|
+
NVIM_APPNAME: string | undefined,
|
|
181
201
|
additionalEnvironmentVariables?: Record<string, string>
|
|
182
202
|
): NodeJS.ProcessEnv {
|
|
183
203
|
return {
|
|
184
204
|
...process.env,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
205
|
+
...({
|
|
206
|
+
HOME: testDirectory.rootPathAbsolute,
|
|
207
|
+
|
|
208
|
+
// this is needed so that neovim can load its configuration, emulating
|
|
209
|
+
// a common setup real neovim users have
|
|
210
|
+
XDG_CONFIG_HOME: join(testDirectory.rootPathAbsolute, ".config"),
|
|
211
|
+
// the data directory is where lazy.nvim stores its plugins. To prevent
|
|
212
|
+
// downloading a new set of plugins for each test, share the data
|
|
213
|
+
// directory.
|
|
214
|
+
XDG_DATA_HOME: join(testDirectory.testEnvironmentPath, ".repro", "data"),
|
|
215
|
+
} satisfies TestEnvironmentCommonEnvironmentVariables),
|
|
216
|
+
NVIM_APPNAME: NVIM_APPNAME ?? "nvim",
|
|
194
217
|
|
|
195
218
|
...additionalEnvironmentVariables,
|
|
196
|
-
}
|
|
219
|
+
}
|
|
197
220
|
}
|
|
198
221
|
|
|
199
222
|
async [Symbol.asyncDispose](): Promise<void> {
|
|
@@ -28,10 +28,14 @@ const resources: Lazy<AsyncDisposableStack> = new Lazy(() => {
|
|
|
28
28
|
|
|
29
29
|
const log = debuglog("tui-sandbox.neovim.api")
|
|
30
30
|
|
|
31
|
-
export async function installDependencies(
|
|
31
|
+
export async function installDependencies(
|
|
32
|
+
testEnvironmentPath: string,
|
|
33
|
+
NVIM_APPNAME: string | undefined,
|
|
34
|
+
config: DirectoriesConfig
|
|
35
|
+
): Promise<void> {
|
|
32
36
|
await using app = new NeovimApplication(testEnvironmentPath)
|
|
33
37
|
const testDirectory = await prepareNewTestDirectory(config)
|
|
34
|
-
const prepareFilePath = path.join(testDirectory.rootPathAbsolute, ".config", "nvim", "prepare.lua")
|
|
38
|
+
const prepareFilePath = path.join(testDirectory.rootPathAbsolute, ".config", NVIM_APPNAME ?? "nvim", "prepare.lua")
|
|
35
39
|
try {
|
|
36
40
|
await access(prepareFilePath)
|
|
37
41
|
} catch (e) {
|
|
@@ -56,7 +60,11 @@ export async function installDependencies(testEnvironmentPath: string, config: D
|
|
|
56
60
|
})
|
|
57
61
|
await app.startNextAndKillCurrent(
|
|
58
62
|
testDirectory,
|
|
59
|
-
{
|
|
63
|
+
{
|
|
64
|
+
filename: "empty.txt",
|
|
65
|
+
headlessCmd: `lua dofile("${prepareFilePath}")`,
|
|
66
|
+
NVIM_APPNAME,
|
|
67
|
+
},
|
|
60
68
|
{ cols: 80, rows: 24 }
|
|
61
69
|
)
|
|
62
70
|
await app.application.untilExit()
|
|
@@ -134,7 +142,7 @@ export async function runBlockingShellCommand(
|
|
|
134
142
|
const testDirectory = neovim.state?.testDirectory
|
|
135
143
|
assert(testDirectory, `Test directory not found for client id ${input.tabId.tabId}. Maybe neovim's not started yet?`)
|
|
136
144
|
|
|
137
|
-
const env =
|
|
145
|
+
const env = NeovimApplication.getEnvironmentVariables(testDirectory, neovim.state?.NVIM_APPNAME, input.envOverrides)
|
|
138
146
|
return executeBlockingShellCommand(testDirectory, input, signal, allowFailure, env)
|
|
139
147
|
}
|
|
140
148
|
|
|
@@ -42,18 +42,19 @@ export function createNeovimRouter(config: DirectoriesConfig) {
|
|
|
42
42
|
}),
|
|
43
43
|
]),
|
|
44
44
|
startupScriptModifications: z.array(z.string()).optional(),
|
|
45
|
-
terminalDimensions: z.object({
|
|
46
|
-
cols: z.number(),
|
|
47
|
-
rows: z.number(),
|
|
48
|
-
}),
|
|
49
45
|
additionalEnvironmentVariables: z.record(z.string(), z.string()).optional(),
|
|
46
|
+
NVIM_APPNAME: z.string().optional().default("nvim"),
|
|
47
|
+
}),
|
|
48
|
+
terminalDimensions: z.object({
|
|
49
|
+
cols: z.number(),
|
|
50
|
+
rows: z.number(),
|
|
50
51
|
}),
|
|
51
52
|
})
|
|
52
53
|
)
|
|
53
54
|
.mutation(options => {
|
|
54
55
|
return neovim.start(
|
|
55
56
|
options.input.startNeovimArguments,
|
|
56
|
-
options.input.
|
|
57
|
+
options.input.terminalDimensions,
|
|
57
58
|
options.input.tabId,
|
|
58
59
|
config
|
|
59
60
|
)
|
|
@@ -11,15 +11,13 @@ describe("blockingCommandInputSchema", () => {
|
|
|
11
11
|
} satisfies Partial<BlockingCommandInput>)
|
|
12
12
|
|
|
13
13
|
expect(fails.error).toMatchInlineSnapshot(`
|
|
14
|
-
ZodError
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
],
|
|
22
|
-
}
|
|
14
|
+
[ZodError: [
|
|
15
|
+
{
|
|
16
|
+
"code": "custom",
|
|
17
|
+
"path": [],
|
|
18
|
+
"message": "Both cwd and cwdRelative provided. Please provide either but not both at the same time."
|
|
19
|
+
}
|
|
20
|
+
]]
|
|
23
21
|
`)
|
|
24
22
|
})
|
|
25
23
|
})
|
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
StartNeovimGenericArguments,
|
|
24
24
|
TestDirectory,
|
|
25
25
|
} from "@tui-sandbox/library/dist/src/server/types"
|
|
26
|
+
import type { MyNeovimConfigModification } from "@tui-sandbox/library/src/client/MyNeovimConfigModification"
|
|
26
27
|
import type {
|
|
27
28
|
ExCommandClientInput,
|
|
28
29
|
LuaCodeClientInput,
|
|
@@ -85,7 +86,7 @@ export type MyStartNeovimServerArguments = OverrideProperties<
|
|
|
85
86
|
StartNeovimGenericArguments,
|
|
86
87
|
{
|
|
87
88
|
filename?: MyTestDirectoryFile | { openInVerticalSplits: MyTestDirectoryFile[] }
|
|
88
|
-
startupScriptModifications?: Array<
|
|
89
|
+
startupScriptModifications?: Array<MyNeovimConfigModification<MyTestDirectoryFile>>
|
|
89
90
|
}
|
|
90
91
|
>
|
|
91
92
|
|
|
@@ -53,6 +53,14 @@ describe("dirtree", () => {
|
|
|
53
53
|
"prepare.lua": z.object({ name: z.literal("prepare.lua"), type: z.literal("file") }),
|
|
54
54
|
}),
|
|
55
55
|
}),
|
|
56
|
+
nvim_alt: z.object({
|
|
57
|
+
name: z.literal("nvim_alt/"),
|
|
58
|
+
type: z.literal("directory"),
|
|
59
|
+
contents: z.object({
|
|
60
|
+
"init.lua": z.object({ name: z.literal("init.lua"), type: z.literal("file") }),
|
|
61
|
+
"prepare.lua": z.object({ name: z.literal("prepare.lua"), type: z.literal("file") }),
|
|
62
|
+
}),
|
|
63
|
+
}),
|
|
56
64
|
}),
|
|
57
65
|
}),
|
|
58
66
|
"config-modifications": z.object({
|
|
@@ -71,6 +79,16 @@ describe("dirtree", () => {
|
|
|
71
79
|
name: z.literal("don't_crash_when_modification_contains_unescaped_characters\\".lua"),
|
|
72
80
|
type: z.literal("file"),
|
|
73
81
|
}),
|
|
82
|
+
subdir: z.object({
|
|
83
|
+
name: z.literal("subdir/"),
|
|
84
|
+
type: z.literal("directory"),
|
|
85
|
+
contents: z.object({
|
|
86
|
+
"subdir-modification.lua": z.object({
|
|
87
|
+
name: z.literal("subdir-modification.lua"),
|
|
88
|
+
type: z.literal("file"),
|
|
89
|
+
}),
|
|
90
|
+
}),
|
|
91
|
+
}),
|
|
74
92
|
}),
|
|
75
93
|
}),
|
|
76
94
|
"dir with spaces": z.object({
|
|
@@ -150,10 +168,15 @@ describe("dirtree", () => {
|
|
|
150
168
|
".config/nvim/init.lua",
|
|
151
169
|
".config/nvim/prepare.lua",
|
|
152
170
|
".config/nvim",
|
|
171
|
+
".config/nvim_alt/init.lua",
|
|
172
|
+
".config/nvim_alt/prepare.lua",
|
|
173
|
+
".config/nvim_alt",
|
|
153
174
|
".config",
|
|
154
175
|
"config-modifications/add_command_to_count_open_buffers.lua",
|
|
155
176
|
"config-modifications/add_command_to_update_buffer_after_timeout.lua",
|
|
156
177
|
"config-modifications/don't_crash_when_modification_contains_unescaped_characters\\".lua",
|
|
178
|
+
"config-modifications/subdir/subdir-modification.lua",
|
|
179
|
+
"config-modifications/subdir",
|
|
157
180
|
"config-modifications",
|
|
158
181
|
"dir with spaces/file1.txt",
|
|
159
182
|
"dir with spaces/file2.txt",
|