Skip to content

Commit c116576

Browse files
authored
Merge pull request #445 from codefori/fix/completion_in_blocks
Improvements to completion provider with subitems
2 parents 58d43c3 + b222be9 commit c116576

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

extension/server/src/providers/completionItem.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import skipRules from './linter/skipRules';
88
import * as Project from "./project";
99
import { getInterfaces } from './project/exportInterfaces';
1010
import Parser from '../../../../language/parser';
11+
import { Token } from '../../../../language/types';
1112

1213
const completionKind = {
1314
function: CompletionItemKind.Interface,
@@ -46,17 +47,19 @@ export default async function completionItemProvider(handler: CompletionParams):
4647

4748
// This means we're just looking for subfields in the struct
4849
if (trigger === `.`) {
49-
const tokens = Parser.lineTokens(isFree ? currentLine : currentLine.length >= 7 ? currentLine.substring(7) : ``, 0, 0, true);
50+
const cursorIndex = handler.position.character;
51+
let tokens = Parser.lineTokens(isFree ? currentLine : currentLine.length >= 7 ? ``.padEnd(7) + currentLine.substring(7) : ``, 0, 0, true);
5052

5153
if (tokens.length > 0) {
52-
const cursorIndex = handler.position.character;
53-
let tokenIndex = tokens.findIndex(token => cursorIndex > token.range.start && cursorIndex <= token.range.end);
54-
console.log(tokens);
55-
console.log({ cPos: handler.position.character, tokenIndex });
54+
55+
// We need to find the innermost block we are part of
56+
tokens = Parser.fromBlocksGetTokens(tokens, cursorIndex);
5657

57-
while (tokens[tokenIndex] && [`block`, `word`, `dot`].includes(tokens[tokenIndex].type) && tokenIndex > 0) {
58-
tokenIndex--;
59-
}
58+
// Remove any tokens after the cursor
59+
tokens = tokens.filter(token => token.range.end <= cursorIndex);
60+
61+
// Get the possible variable we're referring to
62+
let tokenIndex = Parser.getReference(tokens, cursorIndex);
6063

6164
let currentDef: Declaration | undefined;
6265

language/parser.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,28 @@ export default class Parser {
159159
return tokens;
160160
}
161161

162+
static fromBlocksGetTokens(tokensWithBlocks: Token[], cursorIndex: number) {
163+
let insideBlock: Token | undefined;
164+
165+
while (insideBlock = tokensWithBlocks.find(t => t.type === `block` && t.block && t.range.start <= cursorIndex && t.range.end >= cursorIndex)) {
166+
tokensWithBlocks = insideBlock.block || [];
167+
}
168+
169+
return tokensWithBlocks;
170+
}
171+
172+
static getReference(tokens: Token[], cursorIndex: number): number|-1 {
173+
let tokenIndex = tokens.findIndex(token => cursorIndex > token.range.start && cursorIndex <= token.range.end);
174+
175+
let lastToken: Token|undefined;
176+
while (tokens[tokenIndex] && [`block`, `word`, `dot`].includes(tokens[tokenIndex].type) && lastToken?.type !== tokens[tokenIndex].type && tokenIndex > 0) {
177+
lastToken = tokens[tokenIndex];
178+
tokenIndex--;
179+
}
180+
181+
return tokenIndex;
182+
}
183+
162184
async getDocs(workingUri: string, baseContent?: string, options: ParseOptions = {withIncludes: true, collectReferences: true}): Promise<Cache|undefined> {
163185
const existingCache = this.getParsedCache(workingUri);
164186
if (options.ignoreCache !== true && existingCache) {

language/tokens.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ export function createBlocks(tokens: Token[]) {
472472
block: createBlocks(newTokens),
473473
range: {
474474
line: tokens[start].range.line,
475-
start: tokens[i].range.start,
475+
start: tokens[start].range.start,
476476
end: tokens[i].range.end,
477477
}
478478
});

0 commit comments

Comments
 (0)