add minimum requirement of 2 [A-za-z] for slashcommand autocomplete to show up (#4080) * add minimum requirement of 2 [A-za-z] for slashcommand autocomplete to show up * Migrate to dedicated AC toggle * Replace state checkbox with select --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Signed| @@ -5041,6 +5041,14 @@ | |||
| 5041 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | 5041 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> |
| 5042 | </div> | 5042 | </div> |
| 5043 | <div class="inline-drawer-content"> | 5043 | <div class="inline-drawer-content"> |
| 5044 | <label for="stscript_autocomplete_state"> | ||
| 5045 | <small data-i18n="Visibility">Visibility</small> | ||
| 5046 | </label> | ||
| 5047 | <select id="stscript_autocomplete_state"> | ||
| 5048 | <option value="0" data-i18n="Don't show">Don't show</option> | ||
| 5049 | <option value="1" data-i18n="Input length > 1">Input length > 1</option> | ||
| 5050 | <option value="2" data-i18n="Always show">Always show</option> | ||
| 5051 | </select> | ||
| 5044 | <label class="checkbox_label" for="stscript_autocomplete_autoHide"> | 5052 | <label class="checkbox_label" for="stscript_autocomplete_autoHide"> |
| 5045 | <input id="stscript_autocomplete_autoHide" type="checkbox" /> | 5053 | <input id="stscript_autocomplete_autoHide" type="checkbox" /> |
| 5046 | <small data-i18n="Automatically hide details"> | 5054 | <small data-i18n="Automatically hide details"> |
| @@ -21,6 +21,14 @@ export const AUTOCOMPLETE_SELECT_KEY = { | |||
| 21 | 'ENTER': 2, // 2^1 | 21 | 'ENTER': 2, // 2^1 |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | /** @readonly */ | ||
| 25 | /** @enum {Number} */ | ||
| 26 | export const AUTOCOMPLETE_STATE = { | ||
| 27 | DISABLED: 0, | ||
| 28 | MIN_LENGTH: 1, | ||
| 29 | ALWAYS: 2, | ||
| 30 | }; | ||
| 31 | |||
| 24 | export class AutoComplete { | 32 | export class AutoComplete { |
| 25 | /**@type {HTMLTextAreaElement|HTMLInputElement}*/ textarea; | 33 | /**@type {HTMLTextAreaElement|HTMLInputElement}*/ textarea; |
| 26 | /**@type {boolean}*/ isFloating = false; | 34 | /**@type {boolean}*/ isFloating = false; |
| @@ -109,20 +117,20 @@ export class AutoComplete { | |||
| 109 | this.updateDetailsPositionDebounced = debounce(this.updateDetailsPosition.bind(this), 10); | 117 | this.updateDetailsPositionDebounced = debounce(this.updateDetailsPosition.bind(this), 10); |
| 110 | this.updateFloatingPositionDebounced = debounce(this.updateFloatingPosition.bind(this), 10); | 118 | this.updateFloatingPositionDebounced = debounce(this.updateFloatingPosition.bind(this), 10); |
| 111 | 119 | ||
| 112 | textarea.addEventListener('input', ()=>{ | 120 | textarea.addEventListener('input', () => { |
| 113 | this.selectionStart = this.textarea.selectionStart; | 121 | this.selectionStart = this.textarea.selectionStart; |
| 114 | if (this.text != this.textarea.value) this.show(true, this.wasForced); | 122 | if (this.text != this.textarea.value) this.show(true, this.wasForced); |
| 115 | }); | 123 | }); |
| 116 | textarea.addEventListener('keydown', (evt)=>this.handleKeyDown(evt)); | 124 | textarea.addEventListener('keydown', (evt) => this.handleKeyDown(evt)); |
| 117 | textarea.addEventListener('click', ()=>{ | 125 | textarea.addEventListener('click', () => { |
| 118 | this.selectionStart = this.textarea.selectionStart; | 126 | this.selectionStart = this.textarea.selectionStart; |
| 119 | if (this.isActive) this.show(); | 127 | if (this.isActive) this.show(); |
| 120 | }); | 128 | }); |
| 121 | textarea.addEventListener('blur', ()=>this.hide()); | 129 | textarea.addEventListener('blur', () => this.hide()); |
| 122 | if (isFloating) { | 130 | if (isFloating) { |
| 123 | textarea.addEventListener('scroll', ()=>this.updateFloatingPositionDebounced()); | 131 | textarea.addEventListener('scroll', () => this.updateFloatingPositionDebounced()); |
| 124 | } | 132 | } |
| 125 | window.addEventListener('resize', ()=>this.updatePositionDebounced()); | 133 | window.addEventListener('resize', () => this.updatePositionDebounced()); |
| 126 | } | 134 | } |
| 127 | 135 | ||
| 128 | /** | 136 | /** |
| @@ -132,9 +140,9 @@ export class AutoComplete { | |||
| 132 | makeItem(option) { | 140 | makeItem(option) { |
| 133 | const li = option.renderItem(); | 141 | const li = option.renderItem(); |
| 134 | // gotta listen to pointerdown (happens before textarea-blur) | 142 | // gotta listen to pointerdown (happens before textarea-blur) |
| 135 | li.addEventListener('pointerdown', (evt)=>{ | 143 | li.addEventListener('pointerdown', (evt) => { |
| 136 | evt.preventDefault(); | 144 | evt.preventDefault(); |
| 137 | this.selectedItem = this.result.find(it=>it.name == li.getAttribute('data-name')); | 145 | this.selectedItem = this.result.find(it => it.name == li.getAttribute('data-name')); |
| 138 | this.select(); | 146 | this.select(); |
| 139 | }); | 147 | }); |
| 140 | return li; | 148 | return li; |
| @@ -149,7 +157,7 @@ export class AutoComplete { | |||
| 149 | const chars = Array.from(item.dom.querySelector('.name').children); | 157 | const chars = Array.from(item.dom.querySelector('.name').children); |
| 150 | switch (this.matchType) { | 158 | switch (this.matchType) { |
| 151 | case 'strict': { | 159 | case 'strict': { |
| 152 | chars.forEach((it, idx)=>{ | 160 | chars.forEach((it, idx) => { |
| 153 | if (idx + item.nameOffset < item.name.length) { | 161 | if (idx + item.nameOffset < item.name.length) { |
| 154 | it.classList.add('matched'); | 162 | it.classList.add('matched'); |
| 155 | } else { | 163 | } else { |
| @@ -160,7 +168,7 @@ export class AutoComplete { | |||
| 160 | } | 168 | } |
| 161 | case 'includes': { | 169 | case 'includes': { |
| 162 | const start = item.name.toLowerCase().search(this.name); | 170 | const start = item.name.toLowerCase().search(this.name); |
| 163 | chars.forEach((it, idx)=>{ | 171 | chars.forEach((it, idx) => { |
| 164 | if (idx + item.nameOffset < start) { | 172 | if (idx + item.nameOffset < start) { |
| 165 | it.classList.remove('matched'); | 173 | it.classList.remove('matched'); |
| 166 | } else if (idx + item.nameOffset < start + item.name.length) { | 174 | } else if (idx + item.nameOffset < start + item.name.length) { |
| @@ -172,18 +180,18 @@ export class AutoComplete { | |||
| 172 | break; | 180 | break; |
| 173 | } | 181 | } |
| 174 | case 'fuzzy': { | 182 | case 'fuzzy': { |
| 175 | item.name.replace(this.fuzzyRegex, (_, ...parts)=>{ | 183 | item.name.replace(this.fuzzyRegex, (_, ...parts) => { |
| 176 | parts.splice(-2, 2); | 184 | parts.splice(-2, 2); |
| 177 | if (parts.length == 2) { | 185 | if (parts.length == 2) { |
| 178 | chars.forEach(c=>c.classList.remove('matched')); | 186 | chars.forEach(c => c.classList.remove('matched')); |
| 179 | } else { | 187 | } else { |
| 180 | let cIdx = item.nameOffset; | 188 | let cIdx = item.nameOffset; |
| 181 | parts.forEach((it, idx)=>{ | 189 | parts.forEach((it, idx) => { |
| 182 | if (it === null || it.length == 0) return ''; | 190 | if (it === null || it.length == 0) return ''; |
| 183 | if (idx % 2 == 1) { | 191 | if (idx % 2 == 1) { |
| 184 | chars.slice(cIdx, cIdx + it.length).forEach(c=>c.classList.add('matched')); | 192 | chars.slice(cIdx, cIdx + it.length).forEach(c => c.classList.add('matched')); |
| 185 | } else { | 193 | } else { |
| 186 | chars.slice(cIdx, cIdx + it.length).forEach(c=>c.classList.remove('matched')); | 194 | chars.slice(cIdx, cIdx + it.length).forEach(c => c.classList.remove('matched')); |
| 187 | } | 195 | } |
| 188 | cIdx += it.length; | 196 | cIdx += it.length; |
| 189 | }); | 197 | }); |
| @@ -230,7 +238,7 @@ export class AutoComplete { | |||
| 230 | if (current.length > 0) { | 238 | if (current.length > 0) { |
| 231 | consecutive.push(current); | 239 | consecutive.push(current); |
| 232 | } | 240 | } |
| 233 | consecutive.sort((a,b)=>b.length - a.length); | 241 | consecutive.sort((a, b) => b.length - a.length); |
| 234 | option.score = new AutoCompleteFuzzyScore(start, consecutive[0]?.length ?? 0); | 242 | option.score = new AutoCompleteFuzzyScore(start, consecutive[0]?.length ?? 0); |
| 235 | return option; | 243 | return option; |
| 236 | } | 244 | } |
| @@ -254,8 +262,7 @@ export class AutoComplete { | |||
| 254 | + this.parserResult.name.length | 262 | + this.parserResult.name.length |
| 255 | + (this.startQuote ? 1 : 0) | 263 | + (this.startQuote ? 1 : 0) |
| 256 | + (this.endQuote ? 1 : 0) | 264 | + (this.endQuote ? 1 : 0) |
| 257 | + 1 | 265 | + 1; |
| 258 | ; | ||
| 259 | } | 266 | } |
| 260 | 267 | ||
| 261 | /** | 268 | /** |
| @@ -344,7 +351,7 @@ export class AutoComplete { | |||
| 344 | 351 | ||
| 345 | if (this.matchType == 'fuzzy') { | 352 | if (this.matchType == 'fuzzy') { |
| 346 | // only build the fuzzy regex if match type is set to fuzzy | 353 | // only build the fuzzy regex if match type is set to fuzzy |
| 347 | this.fuzzyRegex = new RegExp(`^(.*?)${this.name.split('').map(char=>`(${escapeRegex(char)})`).join('(.*?)')}(.*?)$`, 'i'); | 354 | this.fuzzyRegex = new RegExp(`^(.*?)${this.name.split('').map(char => `(${escapeRegex(char)})`).join('(.*?)')}(.*?)$`, 'i'); |
| 348 | } | 355 | } |
| 349 | 356 | ||
| 350 | //TODO maybe move the matchers somewhere else; a single match function? matchType is available as property | 357 | //TODO maybe move the matchers somewhere else; a single match function? matchType is available as property |
| @@ -358,12 +365,12 @@ export class AutoComplete { | |||
| 358 | // filter the list of options by the partial name according to the matching type | 365 | // filter the list of options by the partial name according to the matching type |
| 359 | .filter(it => this.isReplaceable || it.name == '' ? (it.matchProvider ? it.matchProvider(this.name) : matchers[this.matchType](it.name)) : it.name.toLowerCase() == this.name) | 366 | .filter(it => this.isReplaceable || it.name == '' ? (it.matchProvider ? it.matchProvider(this.name) : matchers[this.matchType](it.name)) : it.name.toLowerCase() == this.name) |
| 360 | // remove aliases | 367 | // remove aliases |
| 361 | .filter((it,idx,list) => list.findIndex(opt=>opt.value == it.value) == idx); | 368 | .filter((it, idx, list) => list.findIndex(opt => opt.value == it.value) == idx); |
| 362 | 369 | ||
| 363 | if (this.result.length == 0 && this.effectiveParserResult != this.parserResult && isForced) { | 370 | if (this.result.length == 0 && this.effectiveParserResult != this.parserResult && isForced) { |
| 364 | // no matching secondary results and forced trigger -> show current command details | 371 | // no matching secondary results and forced trigger -> show current command details |
| 365 | this.secondaryParserResult = null; | 372 | this.secondaryParserResult = null; |
| 366 | this.result = [this.effectiveParserResult.optionList.find(it=>it.name == this.effectiveParserResult.name)]; | 373 | this.result = [this.effectiveParserResult.optionList.find(it => it.name == this.effectiveParserResult.name)]; |
| 367 | this.name = this.effectiveParserResult.name; | 374 | this.name = this.effectiveParserResult.name; |
| 368 | this.fuzzyRegex = /(.*)(.*)(.*)/; | 375 | this.fuzzyRegex = /(.*)(.*)(.*)/; |
| 369 | } | 376 | } |
| @@ -387,8 +394,7 @@ export class AutoComplete { | |||
| 387 | return option; | 394 | return option; |
| 388 | }) | 395 | }) |
| 389 | // sort by fuzzy score or alphabetical | 396 | // sort by fuzzy score or alphabetical |
| 390 | .toSorted(this.matchType == 'fuzzy' ? this.fuzzyScoreCompare : (a, b) => a.name.localeCompare(b.name)) | 397 | .toSorted(this.matchType == 'fuzzy' ? this.fuzzyScoreCompare : (a, b) => a.name.localeCompare(b.name)); |
| 391 | ; | ||
| 392 | 398 | ||
| 393 | 399 | ||
| 394 | 400 | ||
| @@ -628,12 +634,12 @@ export class AutoComplete { | |||
| 628 | this.clone.style.position = 'fixed'; | 634 | this.clone.style.position = 'fixed'; |
| 629 | this.clone.style.visibility = 'hidden'; | 635 | this.clone.style.visibility = 'hidden'; |
| 630 | document.body.append(this.clone); | 636 | document.body.append(this.clone); |
| 631 | const mo = new MutationObserver(muts=>{ | 637 | const mo = new MutationObserver(muts => { |
| 632 | if (muts.find(it=>Array.from(it.removedNodes).includes(this.textarea))) { | 638 | if (muts.find(it => Array.from(it.removedNodes).includes(this.textarea))) { |
| 633 | this.clone.remove(); | 639 | this.clone.remove(); |
| 634 | } | 640 | } |
| 635 | }); | 641 | }); |
| 636 | mo.observe(this.textarea.parentElement, { childList:true }); | 642 | mo.observe(this.textarea.parentElement, { childList: true }); |
| 637 | } | 643 | } |
| 638 | this.clone.style.height = `${inputRect.height}px`; | 644 | this.clone.style.height = `${inputRect.height}px`; |
| 639 | this.clone.style.left = `${inputRect.left}px`; | 645 | this.clone.style.left = `${inputRect.left}px`; |
| @@ -685,7 +691,7 @@ export class AutoComplete { | |||
| 685 | this.textarea.selectionDirection = selectionEnd; | 691 | this.textarea.selectionDirection = selectionEnd; |
| 686 | } | 692 | } |
| 687 | this.wasForced = false; | 693 | this.wasForced = false; |
| 688 | this.textarea.dispatchEvent(new Event('input', { bubbles:true })); | 694 | this.textarea.dispatchEvent(new Event('input', { bubbles: true })); |
| 689 | this.onSelect?.(this.selectedItem); | 695 | this.onSelect?.(this.selectedItem); |
| 690 | } | 696 | } |
| 691 | 697 | ||
| @@ -700,7 +706,7 @@ export class AutoComplete { | |||
| 700 | this.selectedItem.dom.classList.add('selected'); | 706 | this.selectedItem.dom.classList.add('selected'); |
| 701 | const rect = this.selectedItem.dom.children[0].getBoundingClientRect(); | 707 | const rect = this.selectedItem.dom.children[0].getBoundingClientRect(); |
| 702 | const rectParent = this.dom.getBoundingClientRect(); | 708 | const rectParent = this.dom.getBoundingClientRect(); |
| 703 | if (rect.top < rectParent.top || rect.bottom > rectParent.bottom ) { | 709 | if (rect.top < rectParent.top || rect.bottom > rectParent.bottom) { |
| 704 | this.dom.scrollTop += rect.top < rectParent.top ? rect.top - rectParent.top : rect.bottom - rectParent.bottom; | 710 | this.dom.scrollTop += rect.top < rectParent.top ? rect.top - rectParent.top : rect.bottom - rectParent.bottom; |
| 705 | } | 711 | } |
| 706 | this.renderDetailsDebounced(); | 712 | this.renderDetailsDebounced(); |
| @@ -809,8 +815,8 @@ export class AutoComplete { | |||
| 809 | } | 815 | } |
| 810 | // await keyup to see if cursor position or text has changed | 816 | // await keyup to see if cursor position or text has changed |
| 811 | const oldText = this.textarea.value; | 817 | const oldText = this.textarea.value; |
| 812 | await new Promise(resolve=>{ | 818 | await new Promise(resolve => { |
| 813 | window.addEventListener('keyup', resolve, { once:true }); | 819 | window.addEventListener('keyup', resolve, { once: true }); |
| 814 | }); | 820 | }); |
| 815 | if (this.selectionStart != this.textarea.selectionStart) { | 821 | if (this.selectionStart != this.textarea.selectionStart) { |
| 816 | this.selectionStart = this.textarea.selectionStart; | 822 | this.selectionStart = this.textarea.selectionStart; |
| @@ -49,7 +49,7 @@ import { FILTER_TYPES } from './filters.js'; | |||
| 49 | import { PARSER_FLAG, SlashCommandParser } from './slash-commands/SlashCommandParser.js'; | 49 | import { PARSER_FLAG, SlashCommandParser } from './slash-commands/SlashCommandParser.js'; |
| 50 | import { SlashCommand } from './slash-commands/SlashCommand.js'; | 50 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| 51 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; | 51 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; |
| 52 | import { AUTOCOMPLETE_SELECT_KEY, AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js'; | 52 | import { AUTOCOMPLETE_SELECT_KEY, AUTOCOMPLETE_STATE, AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js'; |
| 53 | import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js'; | 53 | import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js'; |
| 54 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; | 54 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 55 | import { POPUP_TYPE, callGenericPopup, fixToastrForDialogs } from './popup.js'; | 55 | import { POPUP_TYPE, callGenericPopup, fixToastrForDialogs } from './popup.js'; |
| @@ -306,6 +306,7 @@ let power_user = { | |||
| 306 | stscript: { | 306 | stscript: { |
| 307 | matching: 'fuzzy', | 307 | matching: 'fuzzy', |
| 308 | autocomplete: { | 308 | autocomplete: { |
| 309 | state: AUTOCOMPLETE_STATE.ALWAYS, | ||
| 309 | autoHide: false, | 310 | autoHide: false, |
| 310 | style: 'theme', | 311 | style: 'theme', |
| 311 | font: { | 312 | font: { |
| @@ -1505,6 +1506,9 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1505 | if (power_user.stscript.autocomplete === undefined) { | 1506 | if (power_user.stscript.autocomplete === undefined) { |
| 1506 | power_user.stscript.autocomplete = defaultStscript.autocomplete; | 1507 | power_user.stscript.autocomplete = defaultStscript.autocomplete; |
| 1507 | } else { | 1508 | } else { |
| 1509 | if (power_user.stscript.autocomplete.state === undefined) { | ||
| 1510 | power_user.stscript.autocomplete.state = defaultStscript.autocomplete.state; | ||
| 1511 | } | ||
| 1508 | if (power_user.stscript.autocomplete.width === undefined) { | 1512 | if (power_user.stscript.autocomplete.width === undefined) { |
| 1509 | power_user.stscript.autocomplete.width = defaultStscript.autocomplete.width; | 1513 | power_user.stscript.autocomplete.width = defaultStscript.autocomplete.width; |
| 1510 | } | 1514 | } |
| @@ -1642,6 +1646,7 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1642 | $('#aux_field').val(power_user.aux_field); | 1646 | $('#aux_field').val(power_user.aux_field); |
| 1643 | $('#tag_import_setting').val(power_user.tag_import_setting); | 1647 | $('#tag_import_setting').val(power_user.tag_import_setting); |
| 1644 | 1648 | ||
| 1649 | $('#stscript_autocomplete_state').val(power_user.stscript.autocomplete.state).trigger('input'); | ||
| 1645 | $('#stscript_autocomplete_autoHide').prop('checked', power_user.stscript.autocomplete.autoHide ?? false).trigger('input'); | 1650 | $('#stscript_autocomplete_autoHide').prop('checked', power_user.stscript.autocomplete.autoHide ?? false).trigger('input'); |
| 1646 | $('#stscript_matching').val(power_user.stscript.matching ?? 'fuzzy'); | 1651 | $('#stscript_matching').val(power_user.stscript.matching ?? 'fuzzy'); |
| 1647 | $('#stscript_autocomplete_style').val(power_user.stscript.autocomplete.style ?? 'theme'); | 1652 | $('#stscript_autocomplete_style').val(power_user.stscript.autocomplete.style ?? 'theme'); |
| @@ -3871,6 +3876,11 @@ $(document).ready(() => { | |||
| 3871 | saveSettingsDebounced(); | 3876 | saveSettingsDebounced(); |
| 3872 | }); | 3877 | }); |
| 3873 | 3878 | ||
| 3879 | $('#stscript_autocomplete_state').on('input', function () { | ||
| 3880 | power_user.stscript.autocomplete.state = Number($(this).val()); | ||
| 3881 | saveSettingsDebounced(); | ||
| 3882 | }); | ||
| 3883 | |||
| 3874 | $('#stscript_autocomplete_autoHide').on('input', function () { | 3884 | $('#stscript_autocomplete_autoHide').on('input', function () { |
| 3875 | power_user.stscript.autocomplete.autoHide = !!$(this).prop('checked'); | 3885 | power_user.stscript.autocomplete.autoHide = !!$(this).prop('checked'); |
| 3876 | saveSettingsDebounced(); | 3886 | saveSettingsDebounced(); |
| @@ -67,7 +67,7 @@ import { background_settings } from './backgrounds.js'; | |||
| 67 | import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; | 67 | import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; |
| 68 | import { SlashCommandClosureResult } from './slash-commands/SlashCommandClosureResult.js'; | 68 | import { SlashCommandClosureResult } from './slash-commands/SlashCommandClosureResult.js'; |
| 69 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; | 69 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; |
| 70 | import { AutoComplete } from './autocomplete/AutoComplete.js'; | 70 | import { AutoComplete, AUTOCOMPLETE_STATE } from './autocomplete/AutoComplete.js'; |
| 71 | import { SlashCommand } from './slash-commands/SlashCommand.js'; | 71 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| 72 | import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js'; | 72 | import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js'; |
| 73 | import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashCommandNamedArgumentAssignment.js'; | 73 | import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashCommandNamedArgumentAssignment.js'; |
| @@ -4927,7 +4927,7 @@ export async function setSlashCommandAutoComplete(textarea, isFloating = false) | |||
| 4927 | const parser = new SlashCommandParser(); | 4927 | const parser = new SlashCommandParser(); |
| 4928 | const ac = new AutoComplete( | 4928 | const ac = new AutoComplete( |
| 4929 | textarea, | 4929 | textarea, |
| 4930 | () => ac.text[0] == '/', | 4930 | () => ac.text[0] == '/' && (power_user.stscript.autocomplete.state === AUTOCOMPLETE_STATE.ALWAYS || power_user.stscript.autocomplete.state === AUTOCOMPLETE_STATE.MIN_LENGTH && ac.text.length > 2), |
| 4931 | async (text, index) => await parser.getNameAt(text, index), | 4931 | async (text, index) => await parser.getNameAt(text, index), |
| 4932 | isFloating, | 4932 | isFloating, |
| 4933 | ); | 4933 | ); |