throwing shit at the wall for /: autocomplete

This commit is contained in:
LenAnderson
2024-04-12 21:43:27 -04:00
parent 18f7b29536
commit 2e1a7b5811
8 changed files with 152 additions and 44 deletions

View File

@ -8,9 +8,9 @@ export class SlashCommandClosure {
/**@type {SlashCommandScope}*/ scope;
/**@type {Boolean}*/ executeNow = false;
// @ts-ignore
/**@type {Map<string,string|SlashCommandClosure>}*/ arguments = {};
/**@type {Object.<string,string|SlashCommandClosure>}*/ arguments = {};
// @ts-ignore
/**@type {Map<string,string|SlashCommandClosure>}*/ providedArguments = {};
/**@type {Object.<string,string|SlashCommandClosure>}*/ providedArguments = {};
/**@type {SlashCommandExecutor[]}*/ executorList = [];
/**@type {String}*/ keptText;

View File

@ -1,5 +1,5 @@
export class SlashCommandClosureExecutor {
/**@type {String}*/ name = '';
// @ts-ignore
/**@type {Map<string,string|SlashCommandClosure>}*/ providedArguments = {};
/**@type {Object.<string,string|SlashCommandClosure>}*/ providedArguments = {};
}

View File

@ -10,7 +10,7 @@ export class SlashCommandExecutor {
/**@type {String}*/ name = '';
/**@type {SlashCommand}*/ command;
// @ts-ignore
/**@type {Map<String,String|SlashCommandClosure>}*/ args = {};
/**@type {Object.<string,String|SlashCommandClosure>}*/ args = {};
/**@type {String|SlashCommandClosure|(String|SlashCommandClosure)[]}*/ value;
constructor(start) {

View File

@ -18,6 +18,7 @@ export class SlashCommandParser {
/**@type {SlashCommandScope}*/ scope;
/**@type {SlashCommandExecutor[]}*/ commandIndex;
/**@type {SlashCommandScope[]}*/ scopeIndex;
get ahead() {
return this.text.slice(this.index + 1);
@ -167,6 +168,12 @@ export class SlashCommandParser {
<li>This will remove the first message in chat, send a system message that starts with 'Hello,', and then ask the AI to continue the message.</li></ul>`;
}
/**
*
* @param {*} text
* @param {*} index
* @returns {SlashCommandExecutor|String[]}
*/
getCommandAt(text, index) {
try {
this.parse(text, false);
@ -180,7 +187,8 @@ export class SlashCommandParser {
.slice(-1)[0]
?? null
;
if (executor && executor.name == ':') return null;
const scope = this.scopeIndex[this.commandIndex.indexOf(executor)];
if (executor && executor.name == ':') return [executor, scope?.allVariableNames];
return executor;
}
@ -205,6 +213,7 @@ export class SlashCommandParser {
this.index = 0;
this.scope = null;
this.commandIndex = [];
this.scopeIndex = [];
const closure = this.parseClosure();
closure.keptText = this.keptText;
return closure;
@ -226,6 +235,7 @@ export class SlashCommandParser {
while (this.testNamedArgument()) {
const arg = this.parseNamedArgument();
closure.arguments[arg.key] = arg.value;
this.scope.variableNames.push(arg.key);
this.discardWhitespace();
}
while (!this.testClosureEnd()) {
@ -269,12 +279,13 @@ export class SlashCommandParser {
return this.testCommandEnd();
}
parseRunShorthand() {
const start = this.index;
const start = this.index + 2;
const cmd = new SlashCommandExecutor(start);
cmd.name = ':';
cmd.value = '';
cmd.command = this.commands[cmd.name];
cmd.command = this.commands['run'];
this.commandIndex.push(cmd);
this.scopeIndex.push(this.scope.getCopy());
this.take(2); //discard "/:"
if (this.testQuotedValue()) cmd.value = this.parseQuotedValue();
else cmd.value = this.parseValue();
@ -303,9 +314,10 @@ export class SlashCommandParser {
return this.testClosureEnd() || this.endOfText || (this.char == '|' && this.behind.slice(-1) != '\\');
}
parseCommand() {
const start = this.index;
const start = this.index + 1;
const cmd = new SlashCommandExecutor(start);
this.commandIndex.push(cmd);
this.scopeIndex.push(this.scope.getCopy());
this.take(); // discard "/"
while (!/\s/.test(this.char) && !this.testCommandEnd()) cmd.name += this.take(); // take chars until whitespace or end
this.discardWhitespace();
@ -319,6 +331,15 @@ export class SlashCommandParser {
this.discardWhitespace();
if (this.testUnnamedArgument()) {
cmd.value = this.parseUnnamedArgument();
if (cmd.name == 'let') {
if (Array.isArray(cmd.value)) {
if (typeof cmd.value[0] == 'string') {
this.scope.variableNames.push(cmd.value[0]);
}
} else if (typeof cmd.value == 'string') {
this.scope.variableNames.push(cmd.value.split(/\s+/)[0]);
}
}
}
if (this.testCommandEnd()) {
cmd.end = this.index;
@ -380,7 +401,7 @@ export class SlashCommandParser {
if (listValues.length == 1) return listValues[0];
return listValues;
}
return value.trim();
return value.trim().replace(/\\([\s{:])/g, '$1');
}
testQuotedValue() {

View File

@ -1,8 +1,13 @@
export class SlashCommandScope {
/**@type {String[]}*/ variableNames = [];
get allVariableNames() {
const names = [...this.variableNames, ...(this.parent?.allVariableNames ?? [])];
return names.filter((it,idx)=>idx == names.indexOf(it));
}
// @ts-ignore
/**@type {Map<String, Object>}*/ variables = {};
/**@type {Object.<string, Object>}*/ variables = {};
// @ts-ignore
/**@type {Map<String, Object>}*/ macros = {};
/**@type {Object.<string, Object>}*/ macros = {};
get macroList() {
return [...Object.keys(this.macros).map(key=>({ key, value:this.macros[key] })), ...(this.parent?.macroList ?? [])];
}
@ -22,6 +27,7 @@ export class SlashCommandScope {
getCopy() {
const scope = new SlashCommandScope(this.parent);
scope.variableNames = [...this.variableNames];
scope.variables = Object.assign({}, this.variables);
scope.macros = this.macros;
scope.#pipe = this.#pipe;