Skip to content

Commit

Permalink
fix: autocompletion for argument values
Browse files Browse the repository at this point in the history
  • Loading branch information
acao committed Nov 29, 2021
1 parent 503c376 commit 76c69d8
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -279,15 +279,15 @@ query name {
]);
});

it('provides correct suggestions when autocompleting for declared variable while typing', () => {
it('provides correct suggestions for declared variables upon typing $', () => {
const result = testSuggestions(
'query($id: String, $ep: Episode!){ hero(episode: $ }',
new Position(0, 51),
);
expect(result).toEqual([{ label: '$ep', detail: 'Episode' }]);
});

it('provides correct suggestions when autocompleting for declared variable', () => {
it('provides correct suggestions for variables based on argument context', () => {
const result = testSuggestions(
'query($id: String!, $episode: Episode!){ hero(episode: ',
new Position(0, 55),
Expand All @@ -297,6 +297,7 @@ query name {
{ label: 'EMPIRE', detail: 'Episode' },
{ label: 'JEDI', detail: 'Episode' },
{ label: 'NEWHOPE', detail: 'Episode' },
// no $id here, it's not compatible :P
]);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export function getAutocompleteSuggestions(
// complete for all variables available in the query
if (kind === RuleKinds.VARIABLE && step === 1) {
const namedInputType = getNamedType(typeInfo.inputType as GraphQLType);
const variableDefinitions = getVariableCompletions(queryText, schema);
const variableDefinitions = getVariableCompletions(queryText, schema, token);
return hintList(
token,
variableDefinitions.filter(v => v.detail === namedInputType?.name),
Expand Down Expand Up @@ -311,7 +311,7 @@ function getSuggestionsForInputValues(
const queryVariables: CompletionItem[] = getVariableCompletions(
queryText,
schema,
true,
token
).filter(v => v.detail === namedInputType.name);

if (namedInputType instanceof GraphQLEnumType) {
Expand Down Expand Up @@ -579,11 +579,12 @@ const getParentDefinition = (state: State, kind: RuleKind) => {
export function getVariableCompletions(
queryText: string,
schema: GraphQLSchema,
forcePrefix: boolean = false,
token: ContextToken
): CompletionItem[] {
let variableName: null | string;
let variableType: GraphQLInputObjectType | undefined | null;
const definitions: Record<string, any> = Object.create({});
// TODO: gather this as part of `AllTypeInfo`, as I don't think it's optimal to re-run the parser like this
runOnlineParser(queryText, (_, state: State) => {
if (state.kind === RuleKinds.VARIABLE && state.name) {
variableName = state.name;
Expand All @@ -599,15 +600,14 @@ export function getVariableCompletions(

if (variableName && variableType) {
if (!definitions[variableName]) {
const label = token.string === '$' ? variableName : '$' + variableName
definitions[variableName] = {
detail: variableType.toString(),
label: `$${variableName}`,
label,
type: variableType,
kind: CompletionItemKind.Variable,
} as CompletionItem;
if (forcePrefix) {
definitions[variableName].insertText = `$${variableName}`;
}

variableName = null;
variableType = null;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/monaco-graphql/src/languageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export class CompletionAdapter
}

public get triggerCharacters(): string[] {
return [' ', ':'];
return [' ', ':', '$', '\n', ' ', '('];
}

async provideCompletionItems(
Expand Down
13 changes: 2 additions & 11 deletions packages/monaco-graphql/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ import type {

import { Position } from 'graphql-language-service';

// @ts-ignore
export type MonacoCompletionItem = monaco.languages.CompletionItem & {
isDeprecated?: boolean;
deprecationReason?: string | null;
};
// @ts-ignore
export function toMonacoRange(range: GraphQLRange): monaco.IRange {
return {
startLineNumber: range.start.line + 1,
Expand All @@ -29,28 +27,22 @@ export function toMonacoRange(range: GraphQLRange): monaco.IRange {
};
}

// @ts-ignore
export function toGraphQLPosition(position: monaco.Position): GraphQLPosition {
return new Position(position.lineNumber - 1, position.column - 1);
}

export function toCompletion(
entry: GraphQLCompletionItem,
range?: GraphQLRange,
// @ts-ignore
): GraphQLCompletionItem & { range: monaco.IRange } {
return {
label: entry.label,
// TODO: when adding variables to getAutocompleteSuggestions, we appended the $.
// this appears to cause an issue in monaco, but not vscode
insertText:
entry.insertText ||
(!entry.label.startsWith('$') ? entry.label : entry.label.substring(1)),
insertText: entry.insertText ?? entry.label,
sortText: entry.sortText,
filterText: entry.filterText,
documentation: entry.documentation,
detail: entry.detail,
// @ts-ignore
// @ts-expect-error
range: range ? toMonacoRange(range) : undefined,
kind: entry.kind,
};
Expand Down Expand Up @@ -84,7 +76,6 @@ export function toCompletion(

export function toMarkerData(
diagnostic: Diagnostic,
// @ts-ignore
): monaco.editor.IMarkerData {
return {
startLineNumber: diagnostic.range.start.line + 1,
Expand Down

0 comments on commit 76c69d8

Please sign in to comment.