Skip to content

Commit

Permalink
Added a default adaptation and hooks for auto indent and auto complete
Browse files Browse the repository at this point in the history
  • Loading branch information
cohansen committed Sep 3, 2024
1 parent 4a401b4 commit 19fa13a
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 33 deletions.
6 changes: 3 additions & 3 deletions src/components/sequencing/SequenceEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import { EditorView, basicSetup } from 'codemirror';
import { debounce } from 'lodash-es';
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { get } from 'svelte/store';
import {
inputFormat,
outputFormat,
Expand All @@ -40,7 +41,6 @@
import effects from '../../utilities/effects';
import { downloadBlob, downloadJSON } from '../../utilities/generic';
import { inputLinter, outputLinter } from '../../utilities/sequence-editor/extension-points';
import { sequenceAutoIndent } from '../../utilities/sequence-editor/sequence-autoindent';
import { sequenceCompletion } from '../../utilities/sequence-editor/sequence-completion';
import { sequenceTooltip } from '../../utilities/sequence-editor/sequence-tooltip';
import { showFailureToast, showSuccessToast } from '../../utilities/toast';
Expand Down Expand Up @@ -191,12 +191,12 @@
EditorView.lineWrapping,
EditorView.theme({ '.cm-gutter': { 'min-height': `${clientHeightGridRightTop}px` } }),
lintGutter(),
compartmentSeqLanguage.of(setupLanguageSupport(sequenceCompletion(null, null, []))),
compartmentSeqLanguage.of(setupLanguageSupport(get(sequenceAdaptation).autoComplete(null, null, []))),
compartmentSeqLinter.of(inputLinter()),
compartmentSeqTooltip.of(sequenceTooltip()),
EditorView.updateListener.of(debounce(sequenceUpdateListener, 250)),
EditorView.updateListener.of(selectedCommandUpdateListener),
indentService.of(sequenceAutoIndent()),
indentService.of(get(sequenceAdaptation).autoIndent()),
EditorState.readOnly.of(readOnly),
],
parent: editorSequenceDiv,
Expand Down
79 changes: 55 additions & 24 deletions src/stores/sequence-adaptation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,47 @@ import type { GlobalType } from '../types/global-type';
import type { ISequenceAdaptation, SequenceAdaptation } from '../types/sequencing';
import gql from '../utilities/gql';
import { seqJsonToSequence } from '../utilities/sequence-editor/from-seq-json';
import { sequenceAutoIndent } from '../utilities/sequence-editor/sequence-autoindent';
import { sequenceCompletion } from '../utilities/sequence-editor/sequence-completion';
import { sequenceToSeqJson } from '../utilities/sequence-editor/to-seq-json';
import { gqlSubscribable } from './subscribable';

const defaultAdaptation: ISequenceAdaptation = {
argDelegator: undefined,
autoComplete: sequenceCompletion,
autoIndent: sequenceAutoIndent,
conditionalKeywords: {
else: 'CMD_ELSE',
elseIf: ['CMD_ELSE_IF'],
endIf: 'CMD_END_IF',
if: ['CMD_IF'],
},
globals: [],
inputFormat: {
linter: undefined,
name: 'SeqN',
toInputFormat: seqJsonToSequence,
},
loopKeywords: {
break: 'CMD_BREAK',
continue: 'CMD_CONTINUE',
endWhileLoop: 'CMD_END_WHILE_LOOP',
whileLoop: ['CMD_WHILE_LOOP', 'CMD_WHILE_LOOP_OR'],
},
modifyOutput: undefined,
modifyOutputParse: undefined,
outputFormat: [
{
fileExtension: 'json',
name: 'Seq JSON',
toOutputFormat: sequenceToSeqJson,
},
],
};

/* Writeable */

export const sequenceAdaptation: Writable<ISequenceAdaptation | undefined> = writable(undefined);
export const sequenceAdaptation: Writable<ISequenceAdaptation> = writable(defaultAdaptation);

/* Subscriptions. */

Expand All @@ -26,38 +61,34 @@ export const outputFormat = derived(
/* Helpers */

export function getGlobals(): GlobalType[] {
return get(sequenceAdaptation)?.globals ?? [];
return get(sequenceAdaptation).globals ?? [];
}

export function setSequenceAdaptation(newSequenceAdaptation: ISequenceAdaptation | undefined): void {
sequenceAdaptation.set({
argDelegator: newSequenceAdaptation?.argDelegator ?? undefined,
argDelegator: newSequenceAdaptation?.argDelegator ?? defaultAdaptation.argDelegator,
autoComplete: newSequenceAdaptation?.autoComplete ?? defaultAdaptation.autoComplete,
autoIndent: newSequenceAdaptation?.autoIndent ?? defaultAdaptation.autoIndent,
conditionalKeywords: {
else: newSequenceAdaptation?.conditionalKeywords?.else ?? 'CMD_ELSE',
elseIf: newSequenceAdaptation?.conditionalKeywords?.elseIf ?? ['CMD_ELSE_IF'],
endIf: newSequenceAdaptation?.conditionalKeywords?.endIf ?? 'CMD_END_IF',
if: newSequenceAdaptation?.conditionalKeywords?.if ?? ['CMD_IF'],
else: newSequenceAdaptation?.conditionalKeywords?.else ?? defaultAdaptation.conditionalKeywords.else,
elseIf: newSequenceAdaptation?.conditionalKeywords?.elseIf ?? defaultAdaptation.conditionalKeywords.elseIf,
endIf: newSequenceAdaptation?.conditionalKeywords?.endIf ?? defaultAdaptation.conditionalKeywords.endIf,
if: newSequenceAdaptation?.conditionalKeywords?.if ?? defaultAdaptation.conditionalKeywords.if,
},
globals: newSequenceAdaptation?.globals ?? [],
globals: newSequenceAdaptation?.globals ?? defaultAdaptation.globals,
inputFormat: {
linter: newSequenceAdaptation?.inputFormat?.linter ?? undefined,
name: newSequenceAdaptation?.inputFormat?.name ?? 'SeqN',
toInputFormat: newSequenceAdaptation?.inputFormat?.toInputFormat ?? seqJsonToSequence,
linter: newSequenceAdaptation?.inputFormat?.linter ?? defaultAdaptation.inputFormat.linter,
name: newSequenceAdaptation?.inputFormat?.name ?? defaultAdaptation.inputFormat.name,
toInputFormat: newSequenceAdaptation?.inputFormat?.toInputFormat ?? defaultAdaptation.inputFormat.toInputFormat,
},
loopKeywords: {
break: newSequenceAdaptation?.loopKeywords?.break ?? 'CMD_BREAK',
continue: newSequenceAdaptation?.loopKeywords?.continue ?? 'CMD_CONTINUE',
endWhileLoop: newSequenceAdaptation?.loopKeywords?.endWhileLoop ?? 'CMD_END_WHILE_LOOP',
whileLoop: newSequenceAdaptation?.loopKeywords?.whileLoop ?? ['CMD_WHILE_LOOP', 'CMD_WHILE_LOOP_OR'],
break: newSequenceAdaptation?.loopKeywords?.break ?? defaultAdaptation.loopKeywords.break,
continue: newSequenceAdaptation?.loopKeywords?.continue ?? defaultAdaptation.loopKeywords.continue,
endWhileLoop: newSequenceAdaptation?.loopKeywords?.endWhileLoop ?? defaultAdaptation.loopKeywords.endWhileLoop,
whileLoop: newSequenceAdaptation?.loopKeywords?.whileLoop ?? defaultAdaptation.loopKeywords.whileLoop,
},
modifyOutput: newSequenceAdaptation?.modifyOutput ?? undefined,
modifyOutputParse: newSequenceAdaptation?.modifyOutputParse ?? undefined,
outputFormat: newSequenceAdaptation?.outputFormat ?? [
{
fileExtension: 'json',
name: 'Seq JSON',
toOutputFormat: sequenceToSeqJson,
},
],
modifyOutput: newSequenceAdaptation?.modifyOutput ?? defaultAdaptation.modifyOutput,
modifyOutputParse: newSequenceAdaptation?.modifyOutputParse ?? defaultAdaptation.modifyOutputParse,
outputFormat: newSequenceAdaptation?.outputFormat ?? defaultAdaptation.outputFormat,
});
}
8 changes: 8 additions & 0 deletions src/types/sequencing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { CompletionContext, CompletionResult } from '@codemirror/autocomplete';
import type { IndentContext } from '@codemirror/language';
import type { Diagnostic } from '@codemirror/lint';
import type { SyntaxNode } from '@lezer/common';
import type {
Expand Down Expand Up @@ -57,6 +59,12 @@ export interface IOutputFormat {

export interface ISequenceAdaptation {
argDelegator?: ArgDelegator;
autoComplete: (
channelDictionary: AmpcsChannelDictionary | null,
commandDictionary: AmpcsCommandDictionary | null,
parameterDictionaries: AmpcsParameterDictionary[],
) => (context: CompletionContext) => CompletionResult | null;
autoIndent: () => (context: IndentContext, pos: number) => number | null | undefined;
conditionalKeywords: { else: string; elseIf: string[]; endIf: string; if: string[] };
globals?: GlobalType[];
inputFormat: {
Expand Down
8 changes: 4 additions & 4 deletions src/utilities/sequence-editor/extension-points.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export function getCustomArgDef(
) {
let delegate = undefined;

if (get(sequenceAdaptation)?.argDelegator !== undefined) {
delegate = get(sequenceAdaptation)?.argDelegator?.[stem]?.[dictArg.name];
if (get(sequenceAdaptation).argDelegator !== undefined) {
delegate = get(sequenceAdaptation).argDelegator?.[stem]?.[dictArg.name];
}

return delegate?.(dictArg, parameterDictionaries, channelDictionary, precedingArgs) ?? dictArg;
Expand All @@ -53,7 +53,7 @@ export async function toInputFormat(
parameterDictionaries: ParameterDictionary[],
channelDictionary: ChannelDictionary | null,
) {
const modifyOutputParse = get(sequenceAdaptation)?.modifyOutputParse;
const modifyOutputParse = get(sequenceAdaptation).modifyOutputParse;
let modifiedOutput = null;

if (modifyOutputParse !== undefined) {
Expand All @@ -71,7 +71,7 @@ export function inputLinter(
parameterDictionaries: ParameterDictionary[] = [],
): Extension {
return linter(view => {
const inputLinter = get(sequenceAdaptation)?.inputFormat.linter;
const inputLinter = get(sequenceAdaptation).inputFormat.linter;
const tree = syntaxTree(view.state);
const treeNode = tree.topNode;
let diagnostics: Diagnostic[];
Expand Down
4 changes: 2 additions & 2 deletions src/utilities/sequence-editor/sequence-linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ function conditionalAndLoopKeywordsLinter(commandNodes: SyntaxNode[], text: stri
const loopStack: WhileOpener[] = [];
const conditionalKeywords = [];
const loopKeywords = [];
const sequenceAdaptationConditionalKeywords = get(sequenceAdaptation)?.conditionalKeywords;
const sequenceAdaptationLoopKeywords = get(sequenceAdaptation)?.loopKeywords;
const sequenceAdaptationConditionalKeywords = get(sequenceAdaptation).conditionalKeywords;
const sequenceAdaptationLoopKeywords = get(sequenceAdaptation).loopKeywords;

conditionalKeywords.push(
sequenceAdaptationConditionalKeywords?.else,
Expand Down

0 comments on commit 19fa13a

Please sign in to comment.