alm
Version:
The best IDE for TypeScript
192 lines (191 loc) • 7.64 kB
JavaScript
;
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;