Skip to content

Commit 5ec5b33

Browse files
committed
Fix autocomplete suggestion
fixes #3553
1 parent ece99f6 commit 5ec5b33

File tree

2 files changed

+118
-16
lines changed

2 files changed

+118
-16
lines changed

packages/graphql-language-service/src/interface/getAutocompleteSuggestions.ts

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ import {
6666
RuleKinds,
6767
RuleKind,
6868
ContextTokenForCodeMirror,
69+
ParserOptions,
70+
LexRules,
71+
ParseRules,
6972
} from '../parser';
7073

7174
import {
@@ -968,18 +971,70 @@ export function getTokenAtPosition(
968971
let styleAtCursor = null;
969972
let stateAtCursor = null;
970973
let stringAtCursor = null;
971-
const token = runOnlineParser(queryText, (stream, state, style, index) => {
972-
if (
973-
index !== cursor.line ||
974-
stream.getCurrentPosition() + offset < cursor.character + 1
975-
) {
976-
return;
974+
975+
/** Returns whether a token is before, at or after the cursor */
976+
function compareTokenPositionToCursor(
977+
line: number,
978+
col: number,
979+
): 'before' | 'at' | 'after' {
980+
if (line < cursor.line) {
981+
return 'before';
977982
}
978-
styleAtCursor = style;
979-
stateAtCursor = { ...state };
980-
stringAtCursor = stream.current();
981-
return 'BREAK';
982-
});
983+
if (line > cursor.line) {
984+
return 'after';
985+
}
986+
987+
if (col < cursor.character) {
988+
return 'before';
989+
}
990+
if (col > cursor.character) {
991+
return 'after';
992+
}
993+
return 'at';
994+
}
995+
996+
let lastString: string | null = null;
997+
let lastState: State | null = null;
998+
let lastStyle: string | null = null;
999+
const token = runOnlineParser(
1000+
queryText,
1001+
(stream, state, style, index) => {
1002+
const compare = compareTokenPositionToCursor(
1003+
index,
1004+
stream.getCurrentPosition() + offset,
1005+
);
1006+
1007+
if (compare === 'before') {
1008+
// The token is before the cursor, keep track of it
1009+
lastState = state;
1010+
lastStyle = style;
1011+
lastString = stream.current();
1012+
return;
1013+
}
1014+
1015+
// The token is at or after the cursor, we return the last token before the cursor
1016+
if (
1017+
index !== cursor.line ||
1018+
stream.getCurrentPosition() + offset < cursor.character + 1
1019+
) {
1020+
return;
1021+
}
1022+
1023+
styleAtCursor = lastStyle;
1024+
stateAtCursor = { ...lastState };
1025+
stringAtCursor = lastString;
1026+
return 'BREAK';
1027+
},
1028+
{
1029+
// Don't swallow whitespace to have the token positions match that of the
1030+
// original query text, so we can compare them with the cursor position.
1031+
eatWhitespace: () => false,
1032+
// TODO should ParserOptions have optional fields instead?
1033+
lexRules: LexRules,
1034+
parseRules: ParseRules,
1035+
editorConfig: {},
1036+
},
1037+
);
9831038

9841039
// Return the state/style of parsed token in case those at cursor aren't
9851040
// available.
@@ -1009,9 +1064,10 @@ type callbackFnType = (
10091064
export function runOnlineParser(
10101065
queryText: string,
10111066
callback: callbackFnType,
1067+
options?: ParserOptions,
10121068
): ContextToken {
10131069
const lines = queryText.split('\n');
1014-
const parser = onlineParser();
1070+
const parser = onlineParser(options);
10151071
let state = parser.startState();
10161072
let style = '';
10171073

yarn.lock

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6050,6 +6050,34 @@
60506050
loupe "^2.3.6"
60516051
pretty-format "^27.5.1"
60526052

6053+
"@vscode/vsce@^2.19.0", "@vscode/vsce@^2.23.0":
6054+
version "2.24.0"
6055+
resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.24.0.tgz#7f835b9fdd5bfedcecd62a6c4d684841a74974d4"
6056+
integrity sha512-p6CIXpH5HXDqmUkgFXvIKTjZpZxy/uDx4d/UsfhS9vQUun43KDNUbYeZocyAHgqcJlPEurgArHz9te1PPiqPyA==
6057+
dependencies:
6058+
azure-devops-node-api "^11.0.1"
6059+
chalk "^2.4.2"
6060+
cheerio "^1.0.0-rc.9"
6061+
commander "^6.2.1"
6062+
glob "^7.0.6"
6063+
hosted-git-info "^4.0.2"
6064+
jsonc-parser "^3.2.0"
6065+
leven "^3.1.0"
6066+
markdown-it "^12.3.2"
6067+
mime "^1.3.4"
6068+
minimatch "^3.0.3"
6069+
parse-semver "^1.1.1"
6070+
read "^1.0.7"
6071+
semver "^7.5.2"
6072+
tmp "^0.2.1"
6073+
typed-rest-client "^1.8.4"
6074+
url-join "^4.0.1"
6075+
xml2js "^0.5.0"
6076+
yauzl "^2.3.1"
6077+
yazl "^2.2.2"
6078+
optionalDependencies:
6079+
keytar "^7.7.0"
6080+
60536081
"@vscode/vsce@^2.22.1-2":
60546082
version "2.22.1-2"
60556083
resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.22.1-2.tgz#0f272f97b23986366ea97e29721cb28410b9af68"
@@ -10698,6 +10726,11 @@ follow-redirects@^1.0.0, follow-redirects@^1.14.0:
1069810726
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4"
1069910727
integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==
1070010728

10729+
follow-redirects@^1.13.2:
10730+
version "1.15.5"
10731+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020"
10732+
integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==
10733+
1070110734
follow-redirects@^1.14.6:
1070210735
version "1.15.2"
1070310736
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
@@ -15287,15 +15320,28 @@ outdent@^0.5.0:
1528715320
resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.5.0.tgz#9e10982fdc41492bb473ad13840d22f9655be2ff"
1528815321
integrity sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==
1528915322

15290-
ovsx@0.5.1:
15291-
version "0.5.1"
15292-
resolved "https://registry.yarnpkg.com/ovsx/-/ovsx-0.5.1.tgz#3a8c2707ea120d542d1d226a47f24ac47b078710"
15293-
integrity sha512-3OWq0l7DuVHi2bd2aQe5+QVQlFIqvrcw3/2vGXL404L6Tr+R4QHtzfnYYghv8CCa85xJHjU0RhcaC7pyXkAUbg==
15323+
ovsx@0.8.3:
15324+
version "0.8.3"
15325+
resolved "https://registry.yarnpkg.com/ovsx/-/ovsx-0.8.3.tgz#3c67a595e423f3f70a3d62da3735dd07dfbca69f"
15326+
integrity sha512-LG7wTzy4eYV/KolFeO4AwWPzQSARvCONzd5oHQlNvYOlji2r/zjbdK8pyObZN84uZlk6rQBWrJrAdJfh/SX0Hg==
1529415327
dependencies:
15328+
"@vscode/vsce" "^2.19.0"
1529515329
commander "^6.1.0"
1529615330
follow-redirects "^1.14.6"
1529715331
is-ci "^2.0.0"
1529815332
leven "^3.1.0"
15333+
semver "^7.5.2"
15334+
tmp "^0.2.1"
15335+
15336+
ovsx@^0.3.0:
15337+
version "0.3.0"
15338+
resolved "https://registry.yarnpkg.com/ovsx/-/ovsx-0.3.0.tgz#2f30c80c90fbe3c8fc406730c35371219187ca0a"
15339+
integrity sha512-UjZjzLt6Iq7LS/XFvEuBAWyn0zmsZEe8fuy5DsbcsIb0mW7PbVtB5Dhe4HeK7NJM228nyhYXC9WCeyBoMi4M3A==
15340+
dependencies:
15341+
commander "^6.1.0"
15342+
follow-redirects "^1.13.2"
15343+
is-ci "^2.0.0"
15344+
leven "^3.1.0"
1529915345
tmp "^0.2.1"
1530015346
vsce "^2.6.3"
1530115347

0 commit comments

Comments
 (0)