mirror of
https://github.com/HeyPuter/puter.git
synced 2026-07-10 17:18:28 +00:00
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.
This commit is contained in:
@@ -25,15 +25,12 @@ export class CommandCompleter {
|
||||
return [];
|
||||
}
|
||||
|
||||
const completions = [];
|
||||
|
||||
// TODO: Match executable names as well as builtins
|
||||
for ( const commandName of Object.keys(builtins) ) {
|
||||
if ( commandName.startsWith(query) ) {
|
||||
completions.push(commandName.slice(query.length));
|
||||
}
|
||||
}
|
||||
|
||||
return completions;
|
||||
return (await ctx.externs.commandProvider.complete(query, { ctx }))
|
||||
// Remove any duplicate results
|
||||
.filter((item, pos, self) => self.indexOf(item) === pos)
|
||||
// TODO: Sort completions?
|
||||
// Remove the `query` part of each result, as that's what is expected
|
||||
// TODO: Supply whole results instead?
|
||||
.map(it => it.slice(query.length));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,9 @@ export class BuiltinCommandProvider {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async complete (query) {
|
||||
return Object.keys(builtins)
|
||||
.filter(commandName => commandName.startsWith(query));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,4 +42,15 @@ export class CompositeCommandProvider {
|
||||
if ( results.length === 0 ) return undefined;
|
||||
return results;
|
||||
}
|
||||
|
||||
async complete (...a) {
|
||||
const query = a[0];
|
||||
if (query === '') return [];
|
||||
|
||||
const results = [];
|
||||
for (const provider of this.providers) {
|
||||
results.push(...await provider.complete(...a));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,4 +200,26 @@ export class PathCommandProvider {
|
||||
async lookupAll(id, { ctx }) {
|
||||
return findCommandsInPath(id, ctx, false);
|
||||
}
|
||||
|
||||
async complete(query, { ctx }) {
|
||||
if (query === '') return [];
|
||||
|
||||
const PATH = ctx.env['PATH'];
|
||||
if (!PATH)
|
||||
return [];
|
||||
const path_directories = PATH.split(path_.delimiter);
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const dir of path_directories) {
|
||||
const dir_entries = await ctx.platform.filesystem.readdir(dir);
|
||||
for (const dir_entry of dir_entries) {
|
||||
if (dir_entry.name.startsWith(query)) {
|
||||
results.push(dir_entry.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,4 +114,34 @@ export class PuterAppCommandProvider {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async complete (query, { ctx }) {
|
||||
if (query === '') return [];
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const app_name of BUILT_IN_APPS) {
|
||||
if (app_name.startsWith(query)) {
|
||||
results.push(app_name);
|
||||
}
|
||||
}
|
||||
|
||||
const request = await fetch(`${puter.APIOrigin}/drivers/call`, {
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${puter.authToken}`,
|
||||
},
|
||||
"body": JSON.stringify({ interface: 'puter-apps', method: 'select', args: { predicate: [ 'name-like', query + '%' ] } }),
|
||||
"method": "POST",
|
||||
});
|
||||
|
||||
const json = await request.json();
|
||||
if (json.success) {
|
||||
for (const app of json.result) {
|
||||
results.push(app.name);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,4 +64,9 @@ export class ScriptCommandProvider {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async complete (query, { ctx }) {
|
||||
// TODO: Implement this
|
||||
return [];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user