Skip to content

Commit cf0eee1

Browse files
committed
feat: Add command names to phoenix tab-completion
Gives CommandProviders a `complete(query, {ctx})` method where they can provide completed command names, and then make use of this in CommandCompleter. Supported CommandProvider sources: - Shell built-ins (was supported previously) - PATH executables (when running under Node) - Puter app names (when running in Puter) Script filenames are not yet supported.
1 parent dc5b010 commit cf0eee1

File tree

6 files changed

+80
-10
lines changed

6 files changed

+80
-10
lines changed

packages/phoenix/src/puter-shell/completers/CommandCompleter.js

+7-10
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,12 @@ export class CommandCompleter {
2525
return [];
2626
}
2727

28-
const completions = [];
29-
30-
// TODO: Match executable names as well as builtins
31-
for ( const commandName of Object.keys(builtins) ) {
32-
if ( commandName.startsWith(query) ) {
33-
completions.push(commandName.slice(query.length));
34-
}
35-
}
36-
37-
return completions;
28+
return (await ctx.externs.commandProvider.complete(query, { ctx }))
29+
// Remove any duplicate results
30+
.filter((item, pos, self) => self.indexOf(item) === pos)
31+
// TODO: Sort completions?
32+
// Remove the `query` part of each result, as that's what is expected
33+
// TODO: Supply whole results instead?
34+
.map(it => it.slice(query.length));
3835
}
3936
}

packages/phoenix/src/puter-shell/providers/BuiltinCommandProvider.js

+5
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@ export class BuiltinCommandProvider {
3131
}
3232
return undefined;
3333
}
34+
35+
async complete (query) {
36+
return Object.keys(builtins)
37+
.filter(commandName => commandName.startsWith(query));
38+
}
3439
}

packages/phoenix/src/puter-shell/providers/CompositeCommandProvider.js

+11
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,15 @@ export class CompositeCommandProvider {
4242
if ( results.length === 0 ) return undefined;
4343
return results;
4444
}
45+
46+
async complete (...a) {
47+
const query = a[0];
48+
if (query === '') return [];
49+
50+
const results = [];
51+
for (const provider of this.providers) {
52+
results.push(...await provider.complete(...a));
53+
}
54+
return results;
55+
}
4556
}

packages/phoenix/src/puter-shell/providers/PathCommandProvider.js

+22
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,26 @@ export class PathCommandProvider {
200200
async lookupAll(id, { ctx }) {
201201
return findCommandsInPath(id, ctx, false);
202202
}
203+
204+
async complete(query, { ctx }) {
205+
if (query === '') return [];
206+
207+
const PATH = ctx.env['PATH'];
208+
if (!PATH)
209+
return [];
210+
const path_directories = PATH.split(path_.delimiter);
211+
212+
const results = [];
213+
214+
for (const dir of path_directories) {
215+
const dir_entries = await ctx.platform.filesystem.readdir(dir);
216+
for (const dir_entry of dir_entries) {
217+
if (dir_entry.name.startsWith(query)) {
218+
results.push(dir_entry.name);
219+
}
220+
}
221+
}
222+
223+
return results;
224+
}
203225
}

packages/phoenix/src/puter-shell/providers/PuterAppCommandProvider.js

+30
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,34 @@ export class PuterAppCommandProvider {
114114
}
115115
return undefined;
116116
}
117+
118+
async complete (query, { ctx }) {
119+
if (query === '') return [];
120+
121+
const results = [];
122+
123+
for (const app_name of BUILT_IN_APPS) {
124+
if (app_name.startsWith(query)) {
125+
results.push(app_name);
126+
}
127+
}
128+
129+
const request = await fetch(`${puter.APIOrigin}/drivers/call`, {
130+
"headers": {
131+
"Content-Type": "application/json",
132+
"Authorization": `Bearer ${puter.authToken}`,
133+
},
134+
"body": JSON.stringify({ interface: 'puter-apps', method: 'select', args: { predicate: [ 'name-like', query + '%' ] } }),
135+
"method": "POST",
136+
});
137+
138+
const json = await request.json();
139+
if (json.success) {
140+
for (const app of json.result) {
141+
results.push(app.name);
142+
}
143+
}
144+
145+
return results;
146+
}
117147
}

packages/phoenix/src/puter-shell/providers/ScriptCommandProvider.js

+5
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,9 @@ export class ScriptCommandProvider {
6464
}
6565
return undefined;
6666
}
67+
68+
async complete (query, { ctx }) {
69+
// TODO: Implement this
70+
return [];
71+
}
6772
}

0 commit comments

Comments
 (0)