Skip to content

Commit

Permalink
polish on completion suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
joswig committed Feb 5, 2025
1 parent e2f946e commit 3a20f23
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 21 deletions.
5 changes: 4 additions & 1 deletion src/utilities/codemirror/vml/vml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const VmlLanguage = LRLanguage.define({
props: [
foldNodeProp.add(FoldBehavior),
styleTags({
ABSOLUTE_SEQUENCE: t.macroName,
ADD: t.arithmeticOperator,
ASSIGNMENT: t.updateOperator,
BLOCK: t.namespace,
Expand All @@ -60,16 +61,18 @@ export const VmlLanguage = LRLanguage.define({
END_BODY: t.namespace,
END_MODULE: t.namespace,
EXTERNAL_CALL: t.controlKeyword,
FLAGS: t.namespace,
FULL_TIME_CONST: t.className,
HEX_CONST: t.number,
INPUT: t.keyword,
INT_CONST: t.number,
ISSUE: t.controlKeyword,
ISSUE_DYNAMIC: t.controlKeyword,
MODULE: t.namespace,
MODULE: t.macroName,
MODULO: t.arithmeticOperator,
MULTIPLY: t.arithmeticOperator,
POWER: t.arithmeticOperator,
RELATIVE_SEQUENCE: t.macroName,
RETURN: t.keyword,
SEQUENCE: t.macroName,
SHORT_TIME_CONST: t.className,
Expand Down
83 changes: 68 additions & 15 deletions src/utilities/codemirror/vml/vmlAdaptation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { snippet, type CompletionContext, type CompletionResult } from '@codemirror/autocomplete';
import { snippet, type Completion, type CompletionContext, type CompletionResult } from '@codemirror/autocomplete';
import { syntaxTree } from '@codemirror/language';
import type { CommandDictionary, EnumMap, FswCommand, FswCommandArgument } from '@nasa-jpl/aerie-ampcs';
import type { VariableDeclaration } from '@nasa-jpl/seq-json-schema/types';
Expand All @@ -8,14 +8,24 @@ import { getNearestAncestorNodeOfType } from '../../sequence-editor/tree-utils';
import { VmlLanguage } from './vml';
import { vmlBlockLibraryToCommandDictionary } from './vmlBlockLibrary';
import {
RULE_FUNCTION,
RULE_FUNCTION_NAME,
RULE_ISSUE,
RULE_PARAMETER,
RULE_STATEMENT,
RULE_TIME_TAGGED_STATEMENT,
RULE_VARIABLE_NAME,
TOKEN_ABSOLUTE_SEQUENCE,
TOKEN_BLOCK,
TOKEN_END_MODULE,
TOKEN_MODULE,
TOKEN_RELATIVE_SEQUENCE,
TOKEN_SEQUENCE,
TOKEN_STRING_CONST,
TOKEN_SYMBOL_CONST,
TOKEN_TIME_CONST,
} from './vmlConstants';
import { getArgumentPosition } from './vmlTreeUtils';
import { getArgumentPosition, getVmlVariables } from './vmlTreeUtils';

function structureSnippets(timePrefix: string) {
return [
Expand Down Expand Up @@ -59,9 +69,33 @@ export function vmlAutoComplete(

if (!cursorLineTrimmed) {
// line is empty
const options: Completion[] = [];
if (!tree.topNode.getChild(TOKEN_MODULE)) {
options.push({
apply: `${TOKEN_MODULE}\n\n\n${TOKEN_END_MODULE}\n\n`,
label: 'MODULE',
type: 'function',
});
} else if (!getNearestAncestorNodeOfType(nodeCurrent, [RULE_FUNCTION])) {
options.push(
...[TOKEN_BLOCK, TOKEN_ABSOLUTE_SEQUENCE, TOKEN_RELATIVE_SEQUENCE, TOKEN_SEQUENCE].map(seqType => ({
apply: snippet(`${seqType} \${function_name}
FLAGS \${AUTOEXECUTE} \${AUTOUNLOAD} \${REENTRANT}
BODY
END_BODY
`),
label: seqType,
type: 'function',
})),
);
} else {
options.push(...structureSnippets('R00:00:00.00 '));
}

return {
from: context.pos,
options: structureSnippets('R00:00:00.00 '),
options,
};
} else if (nodeCurrent.name === RULE_TIME_TAGGED_STATEMENT) {
const timeConstToken = nodeCurrent.getChild(TOKEN_TIME_CONST);
Expand All @@ -88,7 +122,17 @@ export function vmlAutoComplete(
type: 'function',
})),
};
} else if (nodeCurrent.name === TOKEN_STRING_CONST) {
}

const globalOptions: CompletionResult['options'] = globals.map(g => ({
apply: g.name,
detail: 'category' in g && typeof g.category === 'string' ? g.category : 'global',
label: g.name,
section: 'globals, constants',
type: 'builtin',
}));

if (nodeCurrent.name === TOKEN_STRING_CONST) {
// also show if before argument

const containingStatement = getNearestAncestorNodeOfType(nodeCurrent, [RULE_STATEMENT]);
Expand Down Expand Up @@ -120,24 +164,33 @@ export function vmlAutoComplete(
}),
);

// 'builtin', 'atom'
const globalOptions: CompletionResult['options'] = globals.map(g => ({
apply: g.name,
label: `${g.name} (GLOBAL)`,
section: 'globals, constants',
type: 'builtin',
}));

const options = [...enumOptions, ...globalOptions];

return {
filter: false,
from: nodeCurrent.from,
options,
options: enumOptions,
to: nodeCurrent.to,
};
}
}
} else if (
nodeCurrent.name === TOKEN_SYMBOL_CONST &&
nodeCurrent?.parent?.name === RULE_VARIABLE_NAME &&
!getNearestAncestorNodeOfType(nodeCurrent?.parent, [RULE_PARAMETER])
) {
const variableOptions = getVmlVariables(context.state.sliceDoc(), tree, context.pos).map(variable => ({
apply: variable,
detail: 'local',
label: variable,
section: 'locals',
type: 'atom',
}));
const options = [...variableOptions, ...globalOptions];
return {
filter: false,
from: nodeCurrent.from,
options,
to: nodeCurrent.to,
};
}

return null;
Expand Down
20 changes: 15 additions & 5 deletions src/utilities/codemirror/vml/vmlConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

export const RULE_TEXT_FILE = 'Text_file';

export const RULE_FUNCTIONS = 'Functions';
export const RULE_FUNCTION = 'Function';
export const RULE_BODY = 'Body';

export const RULE_ABSOLUTE_SEQUENCE = 'Absolute_Sequence';
export const RULE_RELATIVE_SEQUENCE = 'Relative_sequence';
export const RULE_BLOCK = 'Block';
export const RULE_SEQUENCE = 'Sequence';

export const RULE_COMMON_FUNCTION = 'Common_Function';

export const RULE_BODY = 'Body';

export const RULE_BLOCK = 'Block';
export const RULE_FUNCTIONS = 'Functions';
export const RULE_FUNCTION = 'Function';

export const RULE_IF = 'If';
export const RULE_ELSE_IF = 'Else_if';
Expand Down Expand Up @@ -63,6 +64,9 @@ export const RULE_BYTE_ARRAY = 'Byte_array';
export const GROUP_STATEMENT_SUB = 'StatementSub';

// Terminals in grammar
export const TOKEN_MODULE = 'MODULE';
export const TOKEN_END_MODULE = 'END_MODULE';

export const TOKEN_INT = 'INT';
export const TOKEN_UINT = 'UINT';
export const TOKEN_DOUBLE = 'DOUBLE';
Expand All @@ -80,6 +84,7 @@ export const TOKEN_UINT_CONST = 'UINT_CONST';
export const TOKEN_HEX_CONST = 'HEX_CONST';
export const TOKEN_TIME_CONST = 'TIME_CONST';
export const TOKEN_INT_RANGE_CONST = 'INT_RANGE_CONST';
export const TOKEN_SYMBOL_CONST = 'SYMBOL_CONST';

export const TOKEN_EXTERNAL_CALL = 'EXTERNAL_CALL';
export const TOKEN_CALL = 'CALL';
Expand All @@ -100,3 +105,8 @@ export const TOKEN_TO = 'TO';
export const TOKEN_STEP = 'STEP';
export const TOKEN_DO = 'DO';
export const TOKEN_END_FOR = 'END_FOR';

export const TOKEN_ABSOLUTE_SEQUENCE = 'ABSOLUTE_SEQUENCE';
export const TOKEN_RELATIVE_SEQUENCE = 'RELATIVE_SEQUENCE';
export const TOKEN_BLOCK = 'BLOCK';
export const TOKEN_SEQUENCE = 'SEQUENCE';

0 comments on commit 3a20f23

Please sign in to comment.