nisp
Version:
A language that for easily build cross-language language
159 lines (158 loc) • 5.13 kB
JavaScript
;
exports.__esModule = true;
var CodeMirror = require("codemirror/lib/codemirror");
var fuzzaldrin = require("fuzzaldrin");
var _ = require("lodash");
var parser_1 = require("../parser");
var Set = (function () {
function Set() {
this.list = [];
}
Set.prototype.add = function (item) {
var i = this.list.indexOf(item);
if (i > -1) {
this.list[i] = item;
return;
}
this.list.push(item);
};
return Set;
}());
function add(list) {
var items = [];
for (var _i = 1; _i < arguments.length; _i++) {
items[_i - 1] = arguments[_i];
}
for (var _a = 0, items_1 = items; _a < items_1.length; _a++) {
var el = items_1[_a];
list[el.text] = el;
}
}
var truncateLen = 100;
var fnTypeContainer = document.createElement('div');
fnTypeContainer.className = 'fn-type-container';
fnTypeContainer.style.position = 'absolute';
fnTypeContainer.style.display = 'none';
document.body.appendChild(fnTypeContainer);
exports["default"] = function (cm) {
var currWord = '';
var wordList = {};
var sortHint = function (el) {
el.displayText = truncate(el.displayText);
el.score = fuzzaldrin.score(el.text, currWord);
return -el.score;
};
var showHintReg = /[\s(]([^\s(]+)$/;
var match = function (line) {
var ms = line.match(showHintReg);
if (!ms)
return false;
currWord = ms[1];
return true;
};
var truncate = function (str) {
if (str.length > truncateLen + 3)
return str.slice(0, truncateLen / 2) + '...' + str.slice(-truncateLen / 2);
else
return str;
};
var parseOpt = {
data: _.noop
};
var scanWords = function (ast, set) {
if (_.isArray(ast)) {
for (var _i = 0, ast_1 = ast; _i < ast_1.length; _i++) {
var el = ast_1[_i];
scanWords(el, set);
}
}
else if (_.isString(ast)) {
set.add(ast);
}
return set;
};
var filterHint = function (el) { return el.score > 0; };
var renderDisplayText = function (elem, _, data) {
var node = document.createElement('div');
node.style.whiteSpace = 'normal';
switch (data.type) {
case 'fn':
node.innerHTML = "\n <span class='pt-icon-standard pt-intent-primary pt-icon-function'></span>\n " + _.escape(data.displayText) + "\n ";
break;
default:
node.innerText = data.displayText;
}
elem.append(node);
};
var renderFnType = function (completion, elem) {
closeFnType();
if (completion.type !== 'fn')
return;
fnTypeContainer.style.display = 'block';
fnTypeContainer.innerHTML = completion.fnType;
var rect = elem.getBoundingClientRect();
fnTypeContainer.style.left = 5 + rect.left + rect.width + 'px';
var top = 0;
while (elem) {
top += elem.offsetTop;
elem = elem.offsetParent;
}
fnTypeContainer.style.top = top + 'px';
};
var closeFnType = function () {
fnTypeContainer.style.display = 'none';
};
var updateWordList = _.debounce(function () {
try {
var ast = parser_1.parse(cm.getValue(), parseOpt);
wordList = {};
add(wordList, {
text: 'null',
displayText: 'null'
}, {
text: 'true',
displayText: 'true'
}, {
text: 'false',
displayText: 'false'
});
var set = scanWords(ast, new Set());
for (var _i = 0, _a = set.list; _i < _a.length; _i++) {
var str = _a[_i];
add(wordList, {
text: str,
displayText: str
});
}
_.assign(wordList, cm.getOption('nispFnList'));
_.each(wordList, function (el) {
el.render = renderDisplayText;
});
}
catch (err) {
null;
}
}, 300);
var showHint = _.debounce(function () {
var cursor = cm.getCursor();
var line = cm.getLine(cursor.line).slice(0, cursor.ch);
if (!match(line))
return;
cm.showHint({
completeSingle: false,
hint: function () {
var sorted = _.sortBy(wordList, sortHint).filter(filterHint);
var data = {
list: sorted,
from: CodeMirror.Pos(cursor.line, cursor.ch - currWord.length),
to: CodeMirror.Pos(cursor.line, cursor.ch)
};
CodeMirror.on(data, 'select', renderFnType);
CodeMirror.on(data, 'close', closeFnType);
return data;
}
});
}, 100);
cm.on('change', updateWordList);
cm.on('inputRead', showHint);
};