@tui-sandbox/library 11.0.1 → 11.1.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/browser/assets/{index-NiH4zpUV.js → index-0fX9G5V_.js} +7 -7
  3. package/dist/browser/index.html +1 -1
  4. package/dist/src/browser/neovim-client.js +2 -0
  5. package/dist/src/browser/neovim-client.js.map +1 -1
  6. package/dist/src/client/neovim-terminal-client.js +5 -4
  7. package/dist/src/client/neovim-terminal-client.js.map +1 -1
  8. package/dist/src/scripts/tui.js +8 -3
  9. package/dist/src/scripts/tui.js.map +1 -1
  10. package/dist/src/server/applications/neovim/NeovimApplication.d.ts +14 -1
  11. package/dist/src/server/applications/neovim/NeovimApplication.js +15 -11
  12. package/dist/src/server/applications/neovim/NeovimApplication.js.map +1 -1
  13. package/dist/src/server/applications/neovim/api.d.ts +1 -1
  14. package/dist/src/server/applications/neovim/api.js +9 -5
  15. package/dist/src/server/applications/neovim/api.js.map +1 -1
  16. package/dist/src/server/applications/neovim/neovimRouter.d.ts +11 -10
  17. package/dist/src/server/applications/neovim/neovimRouter.js +6 -5
  18. package/dist/src/server/applications/neovim/neovimRouter.js.map +1 -1
  19. package/dist/src/server/applications/terminal/terminalRouter.d.ts +4 -4
  20. package/dist/src/server/blockingCommandInputSchema.d.ts +2 -2
  21. package/dist/src/server/blockingCommandInputSchema.test.js +7 -9
  22. package/dist/src/server/blockingCommandInputSchema.test.js.map +1 -1
  23. package/dist/src/server/dirtree/index.test.js +11 -0
  24. package/dist/src/server/dirtree/index.test.js.map +1 -1
  25. package/dist/src/server/server.d.ts +5 -4
  26. package/dist/src/server/utilities/tabId.d.ts +1 -1
  27. package/dist/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +4 -4
  29. package/src/browser/neovim-client.ts +4 -1
  30. package/src/client/neovim-terminal-client.ts +5 -4
  31. package/src/scripts/tui.ts +12 -3
  32. package/src/server/applications/neovim/NeovimApplication.ts +39 -16
  33. package/src/server/applications/neovim/api.ts +13 -8
  34. package/src/server/applications/neovim/neovimRouter.ts +6 -5
  35. package/src/server/blockingCommandInputSchema.test.ts +7 -9
  36. package/src/server/dirtree/index.test.ts +11 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tui-sandbox/library",
3
- "version": "11.0.1",
3
+ "version": "11.1.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.10",
35
+ "@types/node": "24.0.13",
36
36
  "nodemon": "3.1.10",
37
- "vite": "7.0.2",
37
+ "vite": "7.0.4",
38
38
  "vitest": "3.2.4",
39
- "zod": "4.0.0-beta.20250505T195954"
39
+ "zod": "4.0.5"
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> {
@@ -86,10 +86,11 @@ export class NeovimTerminalClient {
86
86
  filename: args.filename,
87
87
  additionalEnvironmentVariables: args.additionalEnvironmentVariables,
88
88
  startupScriptModifications: args.startupScriptModifications,
89
- terminalDimensions: {
90
- cols: this.terminal.cols,
91
- rows: this.terminal.rows,
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
  })
@@ -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
- console.log("🚀 Installing neovim dependencies...")
34
- await installDependencies(config.directories.testEnvironmentPath, config.directories).catch((err: unknown) => {
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
- { filename: "empty.txt", headlessCmd: command },
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.0-dev-1589+g71507281fb
55
- Build type: RelWithDebInfo
56
- LuaJIT 2.1.1736781742
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 = this.getEnvironmentVariables(testDirectory, startArgs.additionalEnvironmentVariables)
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
- HOME: testDirectory.rootPathAbsolute,
186
-
187
- // this is needed so that neovim can load its configuration, emulating
188
- // a common setup real neovim users have
189
- XDG_CONFIG_HOME: join(testDirectory.rootPathAbsolute, ".config"),
190
- // the data directory is where lazy.nvim stores its plugins. To prevent
191
- // downloading a new set of plugins for each test, share the data
192
- // directory.
193
- XDG_DATA_HOME: join(testDirectory.testEnvironmentPath, ".repro", "data"),
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
- } satisfies TestEnvironmentCommonEnvironmentVariables
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(testEnvironmentPath: string, config: DirectoriesConfig): Promise<void> {
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
- { filename: "empty.txt", headlessCmd: `lua dofile("${prepareFilePath}")` },
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 = neovim.getEnvironmentVariables(testDirectory, input.envOverrides)
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
 
@@ -198,10 +206,7 @@ export async function waitForLuaCode(
198
206
 
199
207
  const failureMessages: string[] = []
200
208
  const reportFailure = () => {
201
- console.warn(
202
- `Polling Lua code: '${options.luaAssertion}' failed after ${maxIterations} iterations. Failure messages:`,
203
- new Set(failureMessages).values()
204
- )
209
+ console.warn(`Polling Lua code: '${options.luaAssertion}' failed. Failure messages:`, failureMessages)
205
210
  }
206
211
 
207
212
  const maxIterations = 100
@@ -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.startNeovimArguments.terminalDimensions,
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
- "issues": [
16
- {
17
- "code": "custom",
18
- "message": "Both cwd and cwdRelative provided. Please provide either but not both at the same time.",
19
- "path": [],
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
  })
@@ -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({
@@ -150,6 +158,9 @@ describe("dirtree", () => {
150
158
  ".config/nvim/init.lua",
151
159
  ".config/nvim/prepare.lua",
152
160
  ".config/nvim",
161
+ ".config/nvim_alt/init.lua",
162
+ ".config/nvim_alt/prepare.lua",
163
+ ".config/nvim_alt",
153
164
  ".config",
154
165
  "config-modifications/add_command_to_count_open_buffers.lua",
155
166
  "config-modifications/add_command_to_update_buffer_after_timeout.lua",