Commit 085b2f3d by Ryan McKinley Committed by GitHub

Monaco: check suggestions against current word (#25992)

* trigger on current word

* proper index

* test suggestsions

* test suggestsions

* fix test
parent 9e47114c
import { findInsertIndex } from './suggestions';
describe('Check suggestion index', () => {
it('find last $ sign', () => {
const line = ' hello $123';
const { index, prefix } = findInsertIndex(line);
expect(index).toEqual(line.indexOf('$'));
expect(prefix).toEqual('$123');
});
it('insert into empty line', () => {
const line = '';
const { index, prefix } = findInsertIndex(line);
expect(index).toEqual(0);
expect(prefix).toEqual('');
});
it('insert new word', () => {
const line = 'this is a new ';
const { index, prefix } = findInsertIndex(line);
expect(index).toEqual(line.length);
expect(prefix).toEqual('');
});
it('complte a simple word', () => {
const line = 'SELECT * FROM tab';
const { index, prefix } = findInsertIndex(line);
expect(index).toEqual(line.lastIndexOf(' ') + 1);
expect(prefix).toEqual('tab');
});
it('complete a quoted word', () => {
const line = 'SELECT "hello", "wo';
const { index, prefix } = findInsertIndex(line);
expect(index).toEqual(line.lastIndexOf('"') + 1);
expect(prefix).toEqual('wo');
});
});
......@@ -2,6 +2,33 @@ import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import { CodeEditorSuggestionItem, CodeEditorSuggestionItemKind, CodeEditorSuggestionProvider } from './types';
/**
* @internal -- only exported for tests
*/
export function findInsertIndex(line: string): { index: number; prefix: string } {
for (let i = line.length - 1; i > 0; i--) {
const ch = line.charAt(i);
if (ch === '$') {
return {
index: i,
prefix: line.substring(i),
};
}
// Keep these seperators
if (ch === ' ' || ch === '\t' || ch === '"' || ch === "'") {
return {
index: i + 1,
prefix: line.substring(i + 1),
};
}
}
return {
index: 0,
prefix: line,
};
}
function getCompletionItems(
prefix: string,
suggestions: CodeEditorSuggestionItem[],
......@@ -53,51 +80,39 @@ export function registerSuggestions(
triggerCharacters: ['$'],
provideCompletionItems: (model, position, context) => {
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: position.column,
endColumn: position.column,
};
// Simple check if this was triggered by pressing `$`
if (context.triggerCharacter === '$') {
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: position.column - 1,
endColumn: position.column,
};
range.startColumn = position.column - 1;
return {
suggestions: getCompletionItems('$', getSuggestions(), range),
};
}
// find out if we are completing a property in the 'dependencies' object.
const lineText = model.getValueInRange({
// Find the replacement region
const currentLine = model.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column,
});
const idx = lineText.lastIndexOf('$');
if (idx >= 0) {
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: idx, // the last $ we found
endColumn: position.column,
};
return {
suggestions: getCompletionItems(lineText.substr(idx), getSuggestions(), range),
};
}
const { index, prefix } = findInsertIndex(currentLine);
range.startColumn = index + 1;
// Empty line that asked for suggestion
if (lineText.trim().length < 1) {
return {
suggestions: getCompletionItems('', getSuggestions(), {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: position.column,
endColumn: position.column,
}),
};
const suggestions = getCompletionItems(prefix, getSuggestions(), range);
if (suggestions.length) {
// NOTE, this will replace any language provided suggestions
return { suggestions };
}
// console.log('complete?', lineText, context);
// Default language suggestions
return undefined;
},
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment