UNPKG

alm

Version:

The best IDE for TypeScript

192 lines (191 loc) 7.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var socketClient_1 = require("../../../../socket/socketClient"); var state = require("../../../state/state"); var utils = require("../../../../common/utils"); var snippets_1 = require("./snippets"); var monacoUtils = require("../../monacoUtils"); require('./autocomplete.css'); /** * Autocomplete */ var SuggestAdapter = /** @class */ (function () { function SuggestAdapter() { } Object.defineProperty(SuggestAdapter.prototype, "triggerCharacters", { get: function () { return ['.', '(']; }, enumerable: true, configurable: true }); SuggestAdapter.prototype.provideCompletionItems = function (model, position, token) { var wordInfo = model.getWordUntilPosition(position); var prefix = wordInfo.word; // NOTE: monaco is a bit touchy about `wordInfo` // e.g. for `test(|` it will return `wordInfo.word == ""`. // We would rather it give us `(`. // Lets fix that: if (prefix == '' && wordInfo.startColumn > 2) { prefix = model.getLineContent(position.lineNumber).substr(wordInfo.startColumn - 2, 1); } // console.log({ prefix }); // DEBUG var filePath = model.filePath; var offset = monacoUtils.positionToOffset(model, position); if (!state.inActiveProjectFilePath(model.filePath)) { return Promise.resolve([]); } return socketClient_1.server .getCompletionsAtPosition({ prefix: prefix, filePath: filePath, position: offset }) .then(function (info) { if (!info) { return; } var suggestions = info.completions.map(function (entry) { var result = { label: entry.name, kind: SuggestAdapter.convertKind(entry.kind), // MyCompletionItem orig: entry, position: offset, filePath: filePath, }; // Support function completions if (entry.kind === 'snippet') { result.insertText = entry.insertText; } // For path completions we should create a text edit that eats all the text content // This should work but doesn't (monaco bug). So disabling (= null) for now. if (entry.textEdit) { // console.log(entry.textEdit, {position}); // DEBUG result.textEdit = { range: { startLineNumber: entry.textEdit.from.line + 1, startColumn: entry.textEdit.from.ch + 1, endLineNumber: entry.textEdit.to.line + 1, endColumn: entry.textEdit.to.ch + 1, }, text: entry.textEdit.newText, }; // Need this otherwise monaco tries to filter based on `textEdit` // and that might remove our entry. result.filterText = entry.name; } return result; }); // add all snips snippets_1.defaultSnippets.forEach(function (item) { var snip = { label: item.name, kind: monaco.languages.CompletionItemKind.Snippet, detail: 'snippet', documentation: item.description, insertText: item.template, }; suggestions.push(snip); }); return suggestions; }); }; SuggestAdapter.prototype.resolveCompletionItem = function (item, token) { var myItem = item; var filePath = myItem.filePath; var position = myItem.position; /** We have a chance to return `detail` and `documentation` */ // If we already have the result return it if (myItem.orig && myItem.orig.display) { return utils.extend(myItem, { detail: myItem.orig.display, documentation: myItem.orig.comment }); } if (myItem.detail || myItem.documentation) { return myItem; } // If not a resolvable completion then return orig if (!filePath || !position) { return myItem; } // Otherwise get it from the server return socketClient_1.server .getCompletionEntryDetails({ filePath: filePath, position: position, label: myItem.label }) .then(function (res) { // You basically return the same thing with comments if any. If we don't have them just return. if (!res.display && !res.comment) { return myItem; } var detail = res.display, documentation = res.comment; return utils.extend(myItem, { detail: detail, documentation: documentation }); }); }; SuggestAdapter.convertKind = function (kind) { switch (kind) { case Kind.primitiveType: case Kind.keyword: return monaco.languages.CompletionItemKind.Keyword; case Kind.variable: case Kind.localVariable: return monaco.languages.CompletionItemKind.Variable; case Kind.memberVariable: case Kind.memberGetAccessor: case Kind.memberSetAccessor: return monaco.languages.CompletionItemKind.Field; case Kind.function: case Kind.memberFunction: case Kind.constructSignature: case Kind.callSignature: case Kind.indexSignature: return monaco.languages.CompletionItemKind.Function; case Kind.enum: return monaco.languages.CompletionItemKind.Enum; case Kind.module: return monaco.languages.CompletionItemKind.Module; case Kind.class: return monaco.languages.CompletionItemKind.Class; case Kind.interface: return monaco.languages.CompletionItemKind.Interface; case Kind.warning: case Kind.file: return monaco.languages.CompletionItemKind.File; } return monaco.languages.CompletionItemKind.Property; }; return SuggestAdapter; }()); exports.SuggestAdapter = SuggestAdapter; var Kind = /** @class */ (function () { function Kind() { } Kind.unknown = ''; Kind.keyword = 'keyword'; Kind.script = 'script'; Kind.module = 'module'; Kind.class = 'class'; Kind.interface = 'interface'; Kind.type = 'type'; Kind.enum = 'enum'; Kind.variable = 'var'; Kind.localVariable = 'local var'; Kind.function = 'function'; Kind.localFunction = 'local function'; Kind.memberFunction = 'method'; Kind.memberGetAccessor = 'getter'; Kind.memberSetAccessor = 'setter'; Kind.memberVariable = 'property'; Kind.constructorImplementation = 'constructor'; Kind.callSignature = 'call'; Kind.indexSignature = 'index'; Kind.constructSignature = 'construct'; Kind.parameter = 'parameter'; Kind.typeParameter = 'type parameter'; Kind.primitiveType = 'primitive type'; Kind.label = 'label'; Kind.alias = 'alias'; Kind.const = 'const'; Kind.let = 'let'; Kind.warning = 'warning'; Kind.file = 'file'; return Kind; }()); exports.Kind = Kind;