vscode-extensionslanguage-server-protocol

VSCode Language Server extension does not return correct results if my cursor is in the middle of a line


I am developing a fork of a Cucumber Language Server as a VSCode extension, and I've run into a strange problem.

My autocomplete (onCompletion) works as expected if there is nothing to the right of my cursor, however if there is something then it does not return anything. However, using the debugger, I can see that it returns the correct result in the allCompletionItems, but it seems like this is deleted or lost when actually returned? Or it might be overwritten by the VSCode Language Server framework somewhere.

Here is a snippet of my server.ts, the initialize function and onCompletion.

connection.onInitialize((params): InitializeResult => {
    workspaceRoot = params.rootPath;
    return {
        capabilities: {
            // Full text sync mode
            textDocumentSync: documents.syncKind,
            //Completion will be triggered after every character pressing
            completionProvider: {
                resolveProvider: true,
                triggerCharacters: [' ', '.']
            },
            definitionProvider: true,
            documentFormattingProvider: true,
            documentRangeFormattingProvider: true,
            documentOnTypeFormattingProvider: {
                firstTriggerCharacter: ' ',
                moreTriggerCharacter: ['@', '#', ':']
            }
        }
    };
});

...

connection.onCompletion((position: TextDocumentPositionParams): CompletionItem[] => {
    const text = documents.get(position.textDocument.uri).getText();
    const lines = text.split(/\r?\n/g);
    const line = lines[position.position.line];
    const lineUntilCursor = line.slice(0, position.position.character);
    const char = position.position.character;

    const wordBeforeCursor = getWordBeforeCursor(line, char);
    const caseHandlers = findCaseHandlers(text, position.position.line);

    let allCompletionItems: CompletionItem[] = [];

    if (wordBeforeCursor === "case" || wordBeforeCursor === "field" || wordBeforeCursor === "enum") {
        allCompletionItems = addCaseHandlersToCompletionItems(lineUntilCursor, caseHandlers, allCompletionItems);
    }

    allCompletionItems = extractFieldsForCaseHandlerIfPossible(caseHandlers, wordBeforeCursor, allCompletionItems);

    if (pagesPosition(line, char) && pagesHandler) {
        allCompletionItems = allCompletionItems.concat(pagesHandler.getCompletion(line, position.position));
    }
    if (handleSteps() && stepsHandler) {
        allCompletionItems = allCompletionItems.concat(stepsHandler.getCompletion(line, position.position.line, text));
    }

    return allCompletionItems;
});

This is my cucumber code, and the _ is where my cursor is and it does not return the correct results. If I delete "is 50" afterwards, then it works flawlessly.

Scenario: Update original case, aswell as new case variable
  Given case case3 is case1.caseField
  Given field case3.intField is 100
  Given field case2.intField is 50
  Given field _ is 50

Any help is much appreciated!

I have tried to use the debugger, and there it shows the correct allCompletionItems as being returned. I have tried to change it, so it always runs addCaseHandlersToCompletionItems instead of it being inside an if statement. I have tried to look at the wordBeforeCursor method as well.


Solution

  • I solved it, it was due to a null object in my CompletionItems list. I made sure no null objects were there, and now it shows the correct CompletionItems

    I could see it in the VSCode Output console, and switch it to Window.