diff --git a/src/components/composer/composer/abstract_composer_store.ts b/src/components/composer/composer/abstract_composer_store.ts index 2401e3207..267c456b2 100644 --- a/src/components/composer/composer/abstract_composer_store.ts +++ b/src/components/composer/composer/abstract_composer_store.ts @@ -1,3 +1,4 @@ +import { isSheetAutocomplete } from "../../../formulas"; import { composerTokenize, EnrichedToken } from "../../../formulas/composer_tokenizer"; import { POSTFIX_UNARY_OPERATORS } from "../../../formulas/tokenizer"; import { functionRegistry } from "../../../functions"; @@ -713,9 +714,11 @@ export abstract class AbstractComposerStore extends SpreadsheetStore { get autocompleteProvider(): AutoCompleteProvider | undefined { const content = this.currentContent; - const tokenAtCursor = isFormula(content) - ? this.tokenAtCursor - : { type: "STRING", value: content }; + const tokenAtCursor = + (isFormula(content) && !this.currentTokens.some((token) => token.type === "UNKNOWN")) || + isSheetAutocomplete(this.tokenAtCursor) + ? this.tokenAtCursor + : { type: "STRING", value: content }; if ( this.editionMode === "inactive" || !tokenAtCursor || diff --git a/src/components/composer/composer/composer.ts b/src/components/composer/composer/composer.ts index 8194a9959..2d899b377 100644 --- a/src/components/composer/composer/composer.ts +++ b/src/components/composer/composer/composer.ts @@ -3,6 +3,7 @@ import { NEWLINE, PRIMARY_BUTTON_BG, SCROLLBAR_WIDTH } from "../../../constants" import { functionRegistry } from "../../../functions/index"; import { clip, isFormula, setColorAlpha } from "../../../helpers/index"; +import { isSheetAutocomplete } from "../../../formulas"; import { EnrichedToken } from "../../../formulas/composer_tokenizer"; import { argTargeting } from "../../../functions/arguments"; import { Store, useLocalStore, useStore } from "../../../store_engine"; @@ -743,8 +744,14 @@ export class Composer extends Component } const token = this.props.composerStore.tokenAtCursor; - if (isFormula(composerStore.currentContent) && token && token.type !== "SYMBOL") { - const tokenContext = token.functionContext; + if ( + (isFormula(composerStore.currentContent) && + token && + token.type !== "SYMBOL" && + !this.props.composerStore.currentTokens.some((t) => t.type === "UNKNOWN")) || + isSheetAutocomplete(this.props.composerStore.tokenAtCursor) + ) { + const tokenContext = token?.functionContext; const parentFunction = tokenContext?.parent.toUpperCase(); if ( tokenContext && diff --git a/src/formulas/helpers.ts b/src/formulas/helpers.ts index f3c2f270d..e78774d14 100644 --- a/src/formulas/helpers.ts +++ b/src/formulas/helpers.ts @@ -1,4 +1,5 @@ import { functionRegistry } from "../functions"; +import { EnrichedToken } from "./composer_tokenizer"; import { AST, ASTFuncall, iterateAstNodes, parseTokens } from "./parser"; import { Token } from "./tokenizer"; @@ -38,3 +39,10 @@ function getFunctionsFromAST(ast: AST, functionNames: string[]) { args: node.args, })); } + +export function isSheetAutocomplete(tokenAtCursor: EnrichedToken | undefined): boolean { + return ( + (tokenAtCursor?.type === "SYMBOL" || tokenAtCursor?.type === "UNKNOWN") && + tokenAtCursor?.value.startsWith("'") + ); +} diff --git a/tests/composer/auto_complete/function_auto_complete_store.test.ts b/tests/composer/auto_complete/function_auto_complete_store.test.ts index 5612d45c1..757b93b80 100644 --- a/tests/composer/auto_complete/function_auto_complete_store.test.ts +++ b/tests/composer/auto_complete/function_auto_complete_store.test.ts @@ -15,4 +15,22 @@ describe("Function auto complete", () => { autoComplete?.selectProposal(proposals![0].text); expect(composer.currentContent).toEqual("=SUM("); }); + + test("starting with unknown character should stop autocomplete even when adding a valid character", () => { + const { store: composer, model } = makeStore(CellComposerStore); + setCellContent(model, "A1", "=éSUM"); + composer.startEdition(); + const autoComplete = composer.autocompleteProvider; + const proposals = autoComplete?.proposals; + expect(proposals).toBeUndefined(); + }); + + test("adding an unknown character in the middle of a function should stop autocomplete", () => { + const { store: composer, model } = makeStore(CellComposerStore); + setCellContent(model, "A1", "=SéSUM"); + composer.startEdition(); + const autoComplete = composer.autocompleteProvider; + const proposals = autoComplete?.proposals; + expect(proposals).toBeUndefined(); + }); });