UNPKG

@unisnips/ultisnips

Version:

Utilities for converting ultisnips in unisnips project

277 lines 10.7 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var fs = __importStar(require("fs")); var path = __importStar(require("path")); var lodash_omit_1 = __importDefault(require("lodash.omit")); var tokenizer_1 = require("./tokenizer"); var ultisnips_1 = require("./ultisnips"); var position_1 = require("../util/position"); var ReadState; (function (ReadState) { ReadState[ReadState["BLANK"] = 0] = "BLANK"; ReadState[ReadState["SNIPPET_CONTENT"] = 1] = "SNIPPET_CONTENT"; })(ReadState || (ReadState = {})); var PRIORITY_PATTERN = /^priority (-?\d+)$/; var EXTENDS_PATTERN = /^extends (.+)?$/; var SNIPPET_HEAD_PATTERN = /^snippet\s+(.*)\s+"(.*)"(\s+(\w+)\s*)?$/; var END_SNIPPET_PATTERN = /^endsnippet\s*$/; function parseSnippets(snippetCode, opts) { var snippetsFilePath = opts.snippetsFilePath, verbose = opts.verbose; var list = []; var currentSnippet; var state = ReadState.BLANK; var currentPriority = 0; snippetCode.split(/\n/).forEach(function (line, index) { if (state == ReadState.BLANK) { if (/^\s*$/.test(line)) { return; //=> blank line, nothing to do } if (/^\s*#.*$/.test(line)) { return; //=> comment line, nothing to do. } var priorityMatch = PRIORITY_PATTERN.exec(line); if (priorityMatch) { currentPriority = parseInt(priorityMatch[1]); return; // priority for snippets. } var extendsMatch = EXTENDS_PATTERN.exec(line); if (extendsMatch) { var typeExtended = extendsMatch[1]; if (opts.onExtends) { var extendedTypes = [typeExtended]; try { var extraSnippets = opts.onExtends({ extendedTypes: extendedTypes, snippetsFilePath: opts.snippetsFilePath, }, { parseForDefinitions: function (innerContent, innerOpts) { if (innerOpts === void 0) { innerOpts = {}; } return parseSnippets(innerContent, innerOpts); }, }); list.push.apply(list, __spread(extraSnippets)); } catch (error) { console.error("Error in onExtends " + extendedTypes); if (verbose) { console.error(error); } } } else { if (snippetsFilePath) { var typeExtendedSnippetFile = path.join(path.dirname(snippetsFilePath), typeExtended) + '.snippets'; try { var content = fs.readFileSync(typeExtendedSnippetFile, 'utf-8'); var extraSnippets = parseSnippets(content, __assign(__assign({}, opts), { snippetsFilePath: typeExtendedSnippetFile })); list.push.apply(list, __spread(extraSnippets)); } catch (e) { console.error("Unable to parse: " + typeExtendedSnippetFile + " required via " + snippetsFilePath + ":" + (index + 1) + " : " + line, verbose ? e : ''); } } } return; // extended types } var m = SNIPPET_HEAD_PATTERN.exec(line); if (m) { var start = { line: index, column: 0, }; currentSnippet = { trigger: m[1], description: m[2], code: [], body: '', placeholders: [], priority: currentPriority, flags: m[4], position: { start: start, end: __assign({}, start), }, }; list.push(currentSnippet); state = ReadState.SNIPPET_CONTENT; return; //=> done } else { // console.error('Error at line: ' + (index + 1) + ', unable to parse: ' + line) } } if (state == ReadState.SNIPPET_CONTENT) { if (END_SNIPPET_PATTERN.test(line)) { Object.assign(currentSnippet.position.end, { line: index, column: 0, }); currentSnippet.body = currentSnippet.code.join('\n'); state = ReadState.BLANK; return; // => done reading snippets } currentSnippet.code.push(line); } }); return list; } /** * Calculate 'bodyPosition' of a marker */ function calcMarkerPositionInSnippet(def, marker) { var defStartPosition = position_1.TextPosition.fromUnistPoint(def.position.start); var colOffset = marker.start.column; var lineOffset = marker.start.line - defStartPosition.line - 1; var start = defStartPosition.clone(); start.column += colOffset; start.line = lineOffset; start.offset = marker.start.offset; var end = new position_1.TextPosition(marker.end.line - defStartPosition.line - 1, start.column + (marker.end.column - marker.start.column)); if (marker.token) { end.offset = marker.token.end.offset; } // console.table({ start, end }) return { start: start, end: end, }; } /** * Detect the placeholders names from a UltiSnips template. The placeholders * are surrounded by brackets for easier replacement. */ function detectPlaceholders(def) { var result = []; var markerIdMap = new Map(); var pairs = ultisnips_1.parseUltiSnips(def).pairs; pairs.forEach(function (pair, i) { var token = pair.token, parent = pair.parent, marker = pair.marker; // console.log('token', token) var placeholder; var partialData; if (token instanceof tokenizer_1.VisualToken) { partialData = { valueType: 'variable', variable: { type: 'builtin', name: 'UNI_SELECTED_TEXT', }, }; } else if (token instanceof tokenizer_1.MirrorToken || token instanceof tokenizer_1.TabStopToken) { partialData = { valueType: 'tabstop', index: token.number, description: token.initialText, }; if ('transform' in marker) { if (marker.transform) { partialData.transform = marker.transform.getTokenNodeData(); partialData.description = ''; } } } else if (token instanceof tokenizer_1.ScriptCodeToken) { partialData = { valueType: 'script', scriptInfo: { scriptType: token.scriptType, code: token.scriptCode, }, }; } else if (token instanceof tokenizer_1.UniSnipsVariableToken) { partialData = { valueType: 'variable', variable: { type: 'builtin', name: token.name, }, }; } // else if (token instanceof TransformationToken) { // console.log('trans token', token) // } if (partialData) { var markerNode = marker.toTokenNode(); // console.log('marker', marker.markerType) var p = calcMarkerPositionInSnippet(def, marker); var bodyPosition = { start: p.start.toUnistPosition(), end: p.end.toUnistPosition(), }; placeholder = __assign(__assign({}, partialData), { id: i, bodyPosition: bodyPosition, extra: { marker: markerNode, } }); markerIdMap.set(marker, placeholder.id); if (marker.parent) { var parentId = markerIdMap.get(marker.parent); if (parentId) { placeholder.parentId = parentId; } } result.push(placeholder); } }); return result; } function parse(input, opts) { if (opts === void 0) { opts = {}; } var originSnippets = parseSnippets(input, opts); var snippets = []; originSnippets.forEach(function (ultiSnippet) { var snippet = lodash_omit_1.default(ultiSnippet, ['code']); var placeholders = detectPlaceholders(ultiSnippet); placeholders.forEach(function (placeholder) { snippet.placeholders.push(placeholder); }); snippets.push(snippet); }); return { definitions: snippets, }; } exports.parse = parse; //# sourceMappingURL=index.js.map