UNPKG

@phoenix-plugin-registry/brackets-cucumber

Version:

Gherkin/Cucumber/Feature files editor for Brackets, with beautify, row inserting in tables...

503 lines (434 loc) 15.7 kB
define(function (require, exports, module) { 'use strict'; var AppInit = brackets.getModule("utils/AppInit"), LanguageManager = brackets.getModule("language/LanguageManager"), DocumentManager = brackets.getModule("document/DocumentManager"), CommandManager = brackets.getModule('command/CommandManager'), Commands = brackets.getModule('command/Commands'), EditorManager = brackets.getModule('editor/EditorManager'), ExtensionUtils = brackets.getModule("utils/ExtensionUtils"), cm = brackets.getModule("thirdparty/CodeMirror2/lib/codemirror"); AppInit.htmlReady(function () { ExtensionUtils.loadStyleSheet(module, "cucumber.css"); init(); }); function init() { indentFolding(); formatOnSave(); extraKeys(); LanguageManager.defineLanguage("gherkin", { name: "Gherkin", mode: "gherkin", fileExtensions: ["feature"], lineComment: ["#", "#"] }); } function indentFolding() { var indentFold; cm.helpers.fold._global.some(function (g) { if (g.val.toString().match(/^function indentFold/)) { indentFold = g.val; return true; } }); cm.registerGlobalHelper("fold", "indent", function (mode, cm) { return mode.name == 'gherkin'; }, indentFold); } function formatOnSave() { DocumentManager.on('documentSaved', function onSave(event, doc) { if (doc.__FormatingGherkin) return; doc.__FormatingGherkin = true; setTimeout(function () { format(doc); setTimeout(function () { delete doc.__FormatingGherkin; }, 2000); }, 50); // if (doc.__Saving) // return; // try { // doc.addRef(); // doc.__Saving = true; // // } finally { // doc.releaseRef(); // doc.__Saving = false; // } // // setTimeout(function () { // // CommandManager.execute(Commands.FILE_SAVE, { // // doc: doc // // }).always(function () { // // delete doc.__Saving; // // doc.releaseRef(); // // }); // // }); }) } var GROUP_LINE = /^\s*s?cen.r.?.?:/i, FEATURE_LINE = /^\s*(feature|funcionalidade|requisito)\s.*/i, CONJ_LINE = /^\s*(and|but|e|mas)\s.*/i, BLANK_LINE = /^\s*$/, COMMENT_LINE = /^\s*#/, TAG_LINE = /^\s*@/, DASHED_LINE = /^(\s|\-)*$/, STARTING_SPACES = /^\s*/, TRAILING_SPACES = /\s*$/; var error_mark; function format(document, table_fn) { if (document.getLanguage().getId() != 'gherkin') return; var editor = EditorManager.getCurrentFullEditor(); var cursorPos = editor.getCursorPos(), scrollPos = editor.getScrollPos(), unformattedText = document.getText(), lines = unformattedText.split('\n'), tag_start = -1, group_start = -1, table; if (error_mark) { try { error_mark.clear(); } catch (e) {} error_mark = null; } analiseRows(); flush_table(lines.length - 1); var formattedText = lines.join('\n'); if (formattedText != unformattedText) document.batchOperation(function () { document.setText(formattedText); editor.setCursorPos(cursorPos); editor.setScrollPos(scrollPos.x, scrollPos.y); }); function analiseRows() { lines.forEach(function (line, lineIdx) { if (!line) return lines[lineIdx] = ''; if (BLANK_LINE.test(line)) return blankLine(); if (DASHED_LINE.test(line)) return dashedLine(); if (COMMENT_LINE.test(line)) return commentLine(); if (TAG_LINE.test(line)) return tagLine(); if (line.indexOf('|') >= 0) return exampleLine('|'); if (line.indexOf('\u2506') >= 0) return exampleLine('\u2506'); if (GROUP_LINE.test(line)) return groupLine(); if (CONJ_LINE.test(line)) lines[lineIdx] = ' ' + lines[lineIdx].trim(); else if (FEATURE_LINE.test(line)) lines[lineIdx] = ' ' + lines[lineIdx].trim(); else lines[lineIdx] = ' ' + lines[lineIdx].trim(); flush_table(lineIdx); function groupLine() { flush_table(lineIdx - 1); doindent(tag_start, lineIdx, ''); group_start = tag_start >= 0 ? tag_start : lineIdx; tag_start = -1; } function tagLine() { if (tag_start == -1) tag_start = lineIdx; flush_example(lineIdx); } function blankLine() { flush_table(lineIdx) } function commentLine() { //flush_example(lineIdx) } function dashedLine() { table.dashed.push({ lineIdx: lineIdx }); flush_example(lineIdx); } function exampleLine(sep) { if (!table) initExamples(sep); else if (!table.error) calcColumnWidth(sep); tag_start = -1; } function strIndent(s) { var indent = s.match(STARTING_SPACES); return (indent && indent.length && indent[0].length) || 0; } function initExamples(sep) { doindent(group_start, lineIdx - 1, ' '); var cols = line.split(sep); table = { error: false, table_start: lineIdx, cols: cols.map(function (col) { var h = col.trim(); return { indent: strIndent(col), width: h.length, header: h }; }), dashed: [], cursorPos: { example_start_lineIdx: null, example_start_tableIdx: null, example_end_lineIdx: null, example_end_tableIdx: null } }; table.rows = [{ lineIdx: lineIdx, sep: sep, cols: table.cols.map(function (col) { return col.header; }) }]; group_start = -1; } function calcColumnWidth(sep) { //doindent(group_start, lineIdx, ''); var cols = line.split(sep); if (cols.length != table.cols.length) return table.error = show_error( 'Column count mismatch', lineIdx,0,1000 ); if (!table.cursorPos.lineIdx && !table.cursorPos.example_start_lineIdx) { table.cursorPos.example_start_lineIdx = lineIdx; table.cursorPos.example_start_tableIdx = table.rows.length; } var temp = 0; table.rows.push({ lineIdx: lineIdx, sep: sep, cols: cols.map(function (col, idx) { if (table.error) return; var indent = strIndent(col) - table.cols[idx].indent; if (indent < 0) if (col.trim() == '') indent = 0; else return table.error = show_error( 'Invalid indentation', lineIdx, temp, temp+col.length ); if (table_fn && lineIdx == cursorPos.line) { if (temp < cursorPos.ch && temp + table.cols[idx].width >= cursorPos.ch) { table.cursorPos.line = cursorPos.line; table.cursorPos.ch = cursorPos.ch; table.cursorPos.tableIdx = table.rows.length; table.cursorPos.colIdx = idx; table.cursorPos.colPos = cursorPos.ch - temp + 1 - table.cols[idx].indent; } } temp += col.length + 1; col = col.substr(table.cols[idx].indent).replace(TRAILING_SPACES, ''); var width = col.length; if (width > table.cols[idx].width) table.cols[idx].width = width; return col; }) }); } }); } function flush_example(lineIdx) { if (table && table.cursorPos.example_start_lineIdx) { if (table.cursorPos.line) { if (!table.cursorPos.lineIdx) { table.cursorPos.lineIdx = table.cursorPos.line; table.cursorPos.example_end_lineIdx = lineIdx - 1; table.cursorPos.example_end_tableIdx = table.rows.length - 1; } } else { table.cursorPos.example_start_lineIdx = null; table.cursorPos.example_start_tableIdx = null; } } } function flush_table(table_end) { if (!table) return; if (table.error) return; flush_example(table_end); table.table_end = table_end; var lineWidth; if (table_fn && cursorPos.line >= table.table_start && cursorPos.line <= table_end) table_fn(table, lines, table.cursorPos); for (var i = 0; i < table.rows.length; i++) { var row = table.rows[i]; var lineIdx = row.lineIdx; var row = row.cols.map( function (col, idx) { var r; if (idx == 0) r = [' ']; else r = [' ', row.sep, ' ']; var a = r.join('').length; r.push(col); var b = r.join('').length; r.push(spaces(table.cols[idx].width - col.length)); var c = r.join('').length; var t = (table.cols[idx].width - col.length); var r = r.join(''); return r; } ).join(''); lineWidth = row.length; lines[lineIdx] = row.replace(TRAILING_SPACES, ''); } var dash; for (var i = 0; i < table.dashed.length; i++) { var lineIdx = table.dashed[i].lineIdx; if (!dash) { dash = [' ']; for (var j = 4; j < lineWidth; j++) dash.push('-'); dash = dash.join(''); } lines[lineIdx] = dash; } table = null; } function show_error(msg, line, col_init, col_end) { if (!error_mark) { setTimeout(function () { error_mark = editor._codeMirror.markText({ line: line, ch: col_init }, { line: line, ch: col_end }, { className: 'cucumbererror', title: msg, handleMouseEvents: true, }); }, 700); } return true; } var spaces$cache; function spaces(len) { if (len < 1) return ''; if (spaces$cache && len <= spaces$cache.length) return spaces$cache.substr(0, len); var r = []; while (len--) r.push(' '); spaces$cache = r.join(''); return spaces$cache; } function doindent(start, end, indent) { if (start == -1) start = end; for (var lineIdx = start; lineIdx <= end; lineIdx++) { lines[lineIdx] = indent + lines[lineIdx].trim(); } } } function extraKeys() { // EditorManager.on('activeEditorChange', function () { // var doc = DocumentManager.getCurrentDocument(); // if (doc.getLanguage().getId() == 'gherkin') { // // debugger; // // var editor = EditorManager.getCurrentFullEditor(); // editor._codeMirror.addEventListener('keydown', function (e) { // e.preventDefault(); // if (e.keyCode == 15) // doNewLine(doc, editor); // }) // // } // }); document.addEventListener('keypress', function (e) { var doc = DocumentManager.getCurrentDocument(); if (doc.getLanguage().getId() == 'gherkin') { if (e.keyCode == 16) doInsertLine(doc); } }); function doInsertLine(document) { format(document, function (table, lines, cursorPos) { if (!cursorPos.example_start_tableIdx) return; table.dashed.forEach(function (row) { if (row.lineIdx >= cursorPos.line) row.lineIdx++; }); var rowA = table.rows[cursorPos.tableIdx]; var rowB = table.rows[cursorPos.tableIdx + 1]; var rowL = { lineIdx: cursorPos.example_end_lineIdx + 1, sep: rowA.sep, cols: rowA.cols.map(function (col) { return ''; }) }; table.rows.splice(cursorPos.example_end_tableIdx + 1, 0, rowL); lines.splice(cursorPos.example_end_lineIdx + 1, 0, ''); for (var row_idx = cursorPos.example_end_tableIdx; row_idx > cursorPos.tableIdx; row_idx--) { table.rows[row_idx + 1].cols[cursorPos.colIdx] = table.rows[row_idx].cols[cursorPos.colIdx]; } var s = rowA.cols[cursorPos.colIdx]; rowA.cols[cursorPos.colIdx] = s.substr(0, cursorPos.colPos); rowB.cols[cursorPos.colIdx] = s.substr(cursorPos.colPos); for (var row_idx = cursorPos.example_end_tableIdx + 2; row_idx < table.rows.length; row_idx++) table.rows[row_idx].lineIdx++; }); } // function doDeleteLine(document) { // // format(document, function (table, lines, cursorPos) { // var start_example_idx, end_example_idx, end_table_idx; // table.rows.forEach(function (row, idx) { // if (!start_example_idx) { // if (row.lineIdx == cursorPos.line) // start_example_idx = idx; // } else { // if (row.lineIdx > cursorPos.line) // row.lineIdx--; // end_table_idx = idx; // if (end_example_idx && table.rows[end_example_idx].lineIdx != row.lineIdx - 1) // return; // end_example_idx = idx; // } // }); // // if (!start_example_idx) // return; // table.dashed.forEach(function (row) { // if (row.lineIdx >= cursorPos.line) // row.lineIdx--; // }); // var rowA = table.rows[cursorPos.start_example_idx]; // var rowB = { // lineIdx: table.rows[cursorPos.start_example_idx].lineIdx + 1, // cols: rowA.cols.map(function (col) { // return ''; // }), // sep: rowA.sep // }; // table.rows.splice(start_example_idx, 0, rowB); // lines.splice(table.rows[end_example_idx].lineIdx + 1, 0, ''); // }); // } // debugger; // cm.defaults.extraKeys = { // Enter: onNewLine, // Tab: function (cm) { // var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); // cm.replaceSelection(spaces); // } // }; } function onNewLine(cm) { debugger; cm.replaceSelection("\n", "end"); } });