Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 36 additions & 11 deletions src/components/composer/composer/abstract_composer_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,20 @@ export abstract class AbstractComposerStore extends SpreadsheetStore {
return;
}

const missingParenthesis = this.getNumberOfMissingParenthesis(tokens);
if (missingParenthesis > 0) {
tokens.push(...Array(missingParenthesis).fill({ value: ")", type: "RIGHT_PAREN" }));
const missingSymbols = this.getMissingSymbols(this.currentTokens);
if (missingSymbols) {
for (const symb of missingSymbols) {
const typeOfSymb: "RIGHT_PAREN" | "RIGHT_BRACE" =
symb === ")" ? "RIGHT_PAREN" : "RIGHT_BRACE";
const lastStart = tokens[tokens.length - 1].start;
tokens.push({
value: symb,
type: typeOfSymb,
start: lastStart + 1,
end: lastStart + 2,
length: 1,
});
}
}

let hoveredContextTokens = tokens;
Expand Down Expand Up @@ -470,10 +481,8 @@ export abstract class AbstractComposerStore extends SpreadsheetStore {
}
if (content) {
if (isFormula(content)) {
const missing = this.getNumberOfMissingParenthesis(this.currentTokens);
if (missing > 0) {
content += concat(new Array(missing).fill(")"));
}
const missingSymbols = this.getMissingSymbols(this.currentTokens);
content += concat(missingSymbols);
}
}
this.confirmEdition(content);
Expand Down Expand Up @@ -1011,9 +1020,25 @@ export abstract class AbstractComposerStore extends SpreadsheetStore {
return false;
}

private getNumberOfMissingParenthesis(tokens: EnrichedToken[]): number {
const left = tokens.filter((t) => t.type === "LEFT_PAREN").length;
const right = tokens.filter((t) => t.type === "RIGHT_PAREN").length;
return left - right;
private getMissingSymbols(tokens: EnrichedToken[]): (")" | "}")[] {
const stack: (")" | "}")[] = [];
for (const symb of tokens) {
switch (symb.value) {
case "(":
stack.push(")");
break;
case "{":
stack.push("}");
break;
case ")":
case "}":
if (stack.length > 0 && stack[stack.length - 1] === symb.value) {
stack.pop();
}
break;
}
}
stack.reverse();
return stack;
}
}
22 changes: 22 additions & 0 deletions tests/composer/composer_hover.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,28 @@ describe("Composer hover", () => {
expect(".o-speech-bubble").toHaveText("1");
});

test("Hovering an unfinished formula add the missing braces before evaluating", async () => {
await typeInComposer("={1,2,3");
await hoverComposerContent("=");
expect(".o-speech-bubble").toHaveText("{1,2,3}");
});

test("Hovering an unfinished formula add the missing parenthesis then braces before evaluating", async () => {
await typeInComposer("={1,2,SUM(3,4");
await hoverComposerContent("=");
expect(".o-speech-bubble").toHaveText("{1,2,7}");
await hoverComposerContent("SUM");
expect(".o-speech-bubble").toHaveText("7");
});

test("Hovering an unfinished formula add the missing braces then parenthesis before evaluating", async () => {
await typeInComposer("=SUM(1,2,{3,4");
await hoverComposerContent("=");
expect(".o-speech-bubble").toHaveText("10");
await hoverComposerContent("{");
expect(".o-speech-bubble").toHaveText("{3,4}");
});

test("Hovering elements do nothing if the selection start and end are different", async () => {
await typeInComposer("=12");
composerStore.changeComposerCursorSelection(0, 2);
Expand Down