mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add autocomplete for slash commands
This commit is contained in:
@ -41,7 +41,7 @@ export {
|
||||
class SlashCommandParser {
|
||||
constructor() {
|
||||
this.commands = {};
|
||||
this.helpStrings = [];
|
||||
this.helpStrings = {};
|
||||
}
|
||||
|
||||
addCommand(command, callback, aliases, helpString = '', interruptsGeneration = false, purgeFromMessage = true) {
|
||||
@ -64,7 +64,7 @@ class SlashCommandParser {
|
||||
let aliasesString = `(alias: ${aliases.map(x => `<span class="monospace">/${x}</span>`).join(', ')})`;
|
||||
stringBuilder += aliasesString;
|
||||
}
|
||||
this.helpStrings.push(stringBuilder);
|
||||
this.helpStrings[command] = stringBuilder;
|
||||
}
|
||||
|
||||
parse(text) {
|
||||
@ -108,7 +108,12 @@ class SlashCommandParser {
|
||||
}
|
||||
|
||||
getHelpString() {
|
||||
const listItems = this.helpStrings.map(x => `<li>${x}</li>`).join('\n');
|
||||
const listItems = Object
|
||||
.entries(this.helpStrings)
|
||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||
.map(x => x[1])
|
||||
.map(x => `<li>${x}</li>`)
|
||||
.join('\n');
|
||||
return `<p>Slash commands:</p><ol>${listItems}</ol>
|
||||
<small>Slash commands can be batched into a single input by adding a pipe character | at the end, and then writing a new slash command.</small>
|
||||
<ul><li><small>Example:</small><code>/cut 1 | /sys Hello, | /continue</code></li>
|
||||
@ -717,3 +722,42 @@ function executeSlashCommands(text) {
|
||||
|
||||
return { interrupt, newText };
|
||||
}
|
||||
|
||||
function setSlashCommandAutocomplete(textarea) {
|
||||
textarea.autocomplete({
|
||||
source: (input, output) => {
|
||||
// Only show for slash commands and if there's no space
|
||||
if (!input.term.startsWith('/') || input.term.includes(' ')) {
|
||||
output([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const slashCommand = input.term.toLowerCase().substring(1); // Remove the slash
|
||||
const result = Object
|
||||
.keys(parser.helpStrings) // Get all slash commands
|
||||
.filter(x => x.startsWith(slashCommand)) // Filter by the input
|
||||
.sort((a, b) => a.localeCompare(b)) // Sort alphabetically
|
||||
// .slice(0, 20) // Limit to 20 results
|
||||
.map(x => ({ label: parser.helpStrings[x], value: `/${x} ` })); // Map to the help string
|
||||
|
||||
output(result); // Return the results
|
||||
},
|
||||
select: (e, u) => {
|
||||
// unfocus the input
|
||||
$(e.target).val(u.item.value);
|
||||
},
|
||||
minLength: 1,
|
||||
position: { my: "left bottom", at: "left top", collision: "none" },
|
||||
});
|
||||
|
||||
textarea.autocomplete("instance")._renderItem = function (ul, item) {
|
||||
const width = $(textarea).innerWidth();
|
||||
const content = $('<div></div>').html(item.label);
|
||||
return $("<li>").width(width).append(content).appendTo(ul);
|
||||
};
|
||||
}
|
||||
|
||||
jQuery(function () {
|
||||
const textarea = $('#send_textarea');
|
||||
setSlashCommandAutocomplete(textarea);
|
||||
})
|
||||
|
Reference in New Issue
Block a user