(core) Avoid adding extra "(" when autocompleting

Summary:
This tweaks formula autocomplete to avoid adding an extra "(" when we
detect that a function or method is being renamed.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3877
This commit is contained in:
George Gevoian 2023-04-28 01:39:28 -07:00
parent 603238e966
commit c6ec8339f5

View File

@ -106,10 +106,26 @@ function initCustomCompleter() {
aceLanguageTools.addCompleter({
// For autocompletion we ship text to the sandbox and run standard completion there.
async getCompletions(
editor: ace.Editor, session: ace.IEditSession, pos: ace.Position, prefix: string, callback: any
editor: ace.Editor,
session: ace.IEditSession,
pos: ace.Position,
prefix: string,
callback: any
) {
const options = completionOptions.get(editor);
if (!options || prefix.length === 0) { callback(null, []); return; }
// Autocompletion can be triggered in the middle of a function or method call, like
// in the case where one function is being switched with another. Since we normally
// append a "(" when completing such suggestions, we need to be careful not to do
// so if a "(" is already present. One way to do this in ACE is to check if the
// current token is an identifier, and the next token is a lparen; if both are true,
// we skip appending a "(" to each suggestion.
const wordRange = session.getWordRange(pos.row, pos.column);
const token = session.getTokenAt(pos.row, wordRange.end.column) as TokenInfo;
const nextToken = session.getTokenAt(pos.row, wordRange.end.column + 1) as TokenInfo|null;
const isRenamingFunc = token.type === 'identifier' && nextToken?.type === 'paren.lparen';
const suggestions = await options.getSuggestions(prefix);
// ACE autocompletions are very poorly documented. This is somewhat helpful:
// https://prog.world/implementing-code-completion-in-ace-editor/
@ -118,7 +134,7 @@ function initCustomCompleter() {
if (Array.isArray(suggestion)) {
const [funcname, argSpec] = suggestion;
return {
value: funcname + '(',
value: funcname + (isRenamingFunc ? '' : '('),
caption: funcname + argSpec,
score: 1,
example,