UNPKG

nisp

Version:

A language that for easily build cross-language language

159 lines (158 loc) 5.13 kB
"use strict"; 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); };