Add in-app help, formula reference outlines, underline and auto-closing

- Help dialog (?, F1, Datei > Hilfe): user topics, all shortcuts and the
  formula functions with one search over everything. Topics and shortcuts
  are plain data in data/help.ts; the function list comes from
  codeReference.ts so new built-ins appear by themselves.
- While a formula is edited, the grid outlines each referenced cell/range
  in the colour of its position in the text, and the outline can be
  dragged to move or resize the reference, as in Excel. Point-mode picks
  (click, drag, arrow keys) are outlined too, so keyboard picking is no
  longer blind.
- Underline as a cell format, plus Mod+Shift+B/I/U toggles that switch on
  unless every selected cell already has the format.
- A formula committed with open parentheses or an open text literal gets
  the missing closers appended; anything that still doesn't parse is left
  alone so the usual error shows instead of a guess.
- Cells and tables with a fill but no text colour get dark or light text
  by WCAG contrast instead of the theme colour (no black on black).
This commit is contained in:
wkh
2026-10-24 00:38:01 +02:00
parent 0368e96e0c
commit 0fca61eb65
19 changed files with 1420 additions and 16 deletions
@@ -1,6 +1,7 @@
import { describe, it, expect } from 'vitest';
import {
parseFormula,
completeFormula,
parseFunctionBlock,
parseMacroBlock,
collectRefs,
@@ -489,3 +490,21 @@ describe('collectRefsInBlock -- reference walk used by the macro save-time quali
expect(refs).toHaveLength(2);
});
});
describe('completeFormula -- closing what Enter left open', () => {
it('appends missing closing parentheses', () => {
expect(completeFormula('=SUMME(A1:A5')).toBe('=SUMME(A1:A5)');
expect(completeFormula('=RUNDEN(SUMME(A1;B1)*(2+3')).toBe('=RUNDEN(SUMME(A1;B1)*(2+3))');
expect(completeFormula('=SUMME(A1 ')).toBe('=SUMME(A1 )');
});
it('closes an open text literal before the parentheses', () => {
expect(completeFormula('=WENN(A1>0;"ja')).toBe('=WENN(A1>0;"ja")');
});
it('leaves valid formulas, plain text and unfixable input alone', () => {
expect(completeFormula('=SUMME(A1:A5)')).toBe('=SUMME(A1:A5)');
expect(completeFormula('Hallo (Welt')).toBe('Hallo (Welt');
expect(completeFormula('=SUMME(A1+')).toBe('=SUMME(A1+');
expect(completeFormula('=A1)')).toBe('=A1)');
expect(completeFormula('=(')).toBe('=(');
});
});