diff --git a/lib/jade-beautify.js b/lib/jade-beautify.js index 1dfd4ef..ec736b2 100644 --- a/lib/jade-beautify.js +++ b/lib/jade-beautify.js @@ -1,10 +1,9 @@ +var pugBeautify = require('pug-beautify'); var CompositeDisposable = require('atom').CompositeDisposable; var jadeBeautify = { subscriptions: new CompositeDisposable(), - debug: function() { - return true; - }, + DEBUG: false, config: { FILL_TAB: { title: 'Indent with Tabs', @@ -32,7 +31,7 @@ var jadeBeautify = { }, }, activate: function() { - if (jadeBeautify.debug()) console.log('JadeBeautify is activated!!'); + if (jadeBeautify.DEBUG) console.log('JadeBeautify is activated with pugBeautify!!'); this.subscriptions.add(atom.commands.add('atom-workspace', 'jade-beautify:convert', this.handleConvert)); this.subscriptions.add(atom.commands.add('atom-workspace', 'core:save', this.handleSaveEvent)); this.subscriptions.add(atom.commands.add('atom-workspace', 'window:save-all', this.handleSaveAllEvent)); @@ -49,13 +48,13 @@ var jadeBeautify = { }, // trigger on command handleConvert: function() { - if (jadeBeautify.debug()) console.log('handleConvert'); + if (jadeBeautify.DEBUG) console.log('handleConvert'); var editor = atom.workspace.getActiveTextEditor(); jadeBeautify.convert(editor); }, // trigger on core:save handleSaveEvent: function() { - if (jadeBeautify.debug()) console.log('handleSaveEvent'); + if (jadeBeautify.DEBUG) console.log('handleSaveEvent'); var beautify = atom.config.get('jade-beautify.BEAUTIFY_ON_SAVE'); if (!beautify) return; // It works only jade file. @@ -64,111 +63,42 @@ var jadeBeautify = { }, // trigger on window:save-all handleSaveAllEvent: function() { - if (jadeBeautify.debug()) console.log('handleSaveAllEvent'); + if (jadeBeautify.DEBUG) console.log('handleSaveAllEvent'); var beautify = atom.config.get('jade-beautify.BEAUTIFY_ON_SAVE_ALL'); if (!beautify) return; var editors = atom.workspace.getTextEditors(); editors.forEach(function(editor) { - if(editor.isModified()) + if (editor.isModified()) jadeBeautify.convert(editor); }); }, convert: function(editor) { // It works only jade file. if (!jadeBeautify.isJadeFile(editor)) return; - if (jadeBeautify.debug()) console.log('convert ', editor.getPath()); - - // var debug = false; - var fill_tab = atom.config.get('jade-beautify.FILL_TAB'); - var omit_div = atom.config.get('jade-beautify.OMIT_DIV'); - if (jadeBeautify.debug()) console.log(fill_tab, omit_div); + var option = { + fill_tab: atom.config.get('jade-beautify.FILL_TAB'), + omit_div: atom.config.get('jade-beautify.OMIT_DIV'), + tab_size: editor.getTabLength() + }; - // var editor = atom.workspace.getActiveTextEditor(); - var tabSize = editor.getTabLength(); - var indentList = []; + if (jadeBeautify.DEBUG) console.log(option); // Moves the cursor to the end of the file on save. #6 var prev_position = editor.getCursorScreenPosition(); - var prevIndent = { - type: 'code', // type 'code','remark' - indent: 0, // count of indent space. it replace tab as space - tab: 0, // count of tab ,line indent will be filled up with this value. - input: '', // input line after removing indent. - }; - - var lines = editor.getText().split('\n'); - - lines.forEach(function(line, n) { - // it return matching space --> data[0], data[index] = 0, remained input --> data.input - var data = line.match(/^\s*/); - - // when tab and space mixed, it replace all tab to spaces. - var tmp = data[0].replace(/\t/g, Array(tabSize + 1).join(' ')); - var remainedInput = data.input.replace(/^\s*/, ''); - var indent = (remainedInput.length === 0) ? 0 : tmp.length; - - var tab = 0; - var type = (remainedInput.match(/^\/\/|^\/\*|^\*/)) ? 'remark' : 'code'; - - if (omit_div) { - remainedInput = remainedInput.replace(/^div(\.|#)/i, '$1'); - } - - if (indent === 0) { - tab = 0; - } else { - // when this line & prev line is 'remark', it fallow prev line tab. - if (indentList.length > 0 && type === 'remark' && indentList[indentList.length - 1].type == 'remark') { - tab = prevIndent.tab; - } else { - if (indent === prevIndent.indent) { // when same indent, follow prev tab. - tab = prevIndent.tab; - } else if (indent > prevIndent.indent) { // when indented, add tab - tab = prevIndent.tab + 1; - } else { // when new indent, if find the same indent, and follow it's tab. - for (i = indentList.length - 1; i >= 0; i--) { - if (indent == indentList[i].indent) { - tab = indentList[i].tab; - break; - } - } - } - } - } - // if (jadeBeautify.debug()) console.log(n + 1, indent, tab, prevIndent.indent); - - var curIndent = { - type: type, - indent: indent, - tab: tab, - input: remainedInput, - }; - - indentList.push(curIndent); - - if (remainedInput.length !== 0) { // discard null line - prevIndent = curIndent; - } - }); - - // // Here,it reformat with it's tab count. - var formatedLine = indentList.map(function(line, n) { - var space = Array(line.tab + 1).join('\t'); - //when fill with space - if (!fill_tab) space = space.replace(/\t/g, Array(tabSize + 1).join(' ')); - - // if (jadeBeautify.debug()) console.log(n + 1, line.indent, line.tab, space + line.input); - return space + line.input; - }); - - //Rewrite data - editor.setText(formatedLine.join('\n')); + // Beautify Jade(Pug) Template. + try { + var beautifiedCode = pugBeautify(editor.getText(),option); + editor.setText(beautifiedCode); + if (prev_position) editor.setCursorScreenPosition(prev_position); + }catch(error){ + // error occured + atom.notifications.addError('Fail to beautify.',{detail:error}); + } // #6 Move Cursor to Previous Postion. - if (prev_position) editor.setCursorScreenPosition(prev_position); } }; module.exports = jadeBeautify; diff --git a/lib/jade-beautify.js.bak b/lib/jade-beautify.js.bak deleted file mode 100644 index d238c7e..0000000 --- a/lib/jade-beautify.js.bak +++ /dev/null @@ -1,92 +0,0 @@ -var CompositeDisposable = require('atom').CompositeDisposable; - -module.exports = { - subscriptions: new CompositeDisposable(), - // make this filed as config later - fillTab: false, - activate: function() { - return this.subscriptions.add(atom.commands.add('atom-workspace', 'jade-beautify:convert', this.convert)); - }, - deactivate: function() { - this.subscriptions.dispose(); - }, - convert: function() { - var editor = atom.workspace.getActiveTextEditor(); - // Base tabSize = 2, is more readable. - var tabSize = editor.getTabLength(); - var indentList = []; - - var prevIndent = 0; - var lines = editor.getText().split('\n'); - - lines.forEach(function(line, n) { - // it return matching space --> data[0], data[index] = 0, remained input --> data.input - var data = line.match(/^\s*/); - - // when tab and space mixed, it replace all tab to spaces. - var space = data[0].replace(/\t/g, Array(tabSize + 1).join(' ')); - var inputAfterRemoveSpace = data.input.replace(/^\s*/, ''); - var indent = (inputAfterRemoveSpace.length === 0) ? 0 : space.length; - - var newindent = 0; - var type = (inputAfterRemoveSpace.match(/^\/\/|^\/\*|^\*/)) ? 'remark' : 'code'; - - if (indent === 0) { - newindent = 0; - } else { - // 현재 라인이 remark이고 앞 라인이 remark인 경우는 앞 라인 indent를 따른다. - if (indentList.length > 0 && type === 'remark' && indentList[indentList.length - 1].type == 'remark') { - newindent = indentList[indentList.length - 1].newindent; - } else { - if (indent === prevIndent) { - for (i = indentList.length - 1; i >= 0; i--) { - if (indentList[i].input !== '') { - newindent = indentList[i].newindent; - break; - } - } - } else if (indent > prevIndent) { - for (i = indentList.length - 1; i >= 0; i--) { - if (indentList[i].input !== '') { - newindent = indentList[i].newindent + 1; - break; - } - } - } else { - for (i = indentList.length - 1; i >= 0; i--) { - if (indent == indentList[i].indent) { - newindent = indentList[i].newindent; - break; - } - } - } - } - } - console.log(n + 1, indent, newindent, prevIndent); - - indentList.push({ - type: type, - indent: indent, - newindent: newindent, - input: inputAfterRemoveSpace, - }); - - if (inputAfterRemoveSpace.length !== 0) { // null 라인은 무시한다. - prevIndent = indent; - } - }); - - // // Here,it reformat as it's order - var formatedLine = indentList.map(function(line) { - var space = Array(line.newindent + 1).join('\t'); - if (!this.fillTab) space = space.replace(/\t/g, Array(tabSize + 1).join(' ')); - - console.log(line.type, line.indent, line.newindent, space + line.input); - return space + line.input; - }); - - //Reset data - editor.setText(formatedLine.join('\n')); - - } -}; diff --git a/lib/jade-beautify0.js b/lib/jade-beautify0.js new file mode 100644 index 0000000..0728888 --- /dev/null +++ b/lib/jade-beautify0.js @@ -0,0 +1,172 @@ +var CompositeDisposable = require('atom').CompositeDisposable; + +var jadeBeautify = { + subscriptions: new CompositeDisposable(), + DEBUG: false, + config: { + FILL_TAB: { + title: 'Indent with Tabs', + description: 'Indent with Tabs, if false, with spaces.', + type: 'boolean', + default: true + }, + OMIT_DIV: { + title: 'Omit div tag', + description: 'Omit div tag when it has id or class.', + type: 'boolean', + default: false + }, + BEAUTIFY_ON_SAVE: { // Issue #1 + title: 'Force beautify when save', + description: 'force beautify when save.', + type: 'boolean', + default: false + }, + BEAUTIFY_ON_SAVE_ALL: { // Issue #4 + title: 'Force beautify when save-all', + description: 'force beautify on modified files when save all.', + type: 'boolean', + default: false + }, + }, + activate: function() { + if (jadeBeautify.DEBUG) console.log('JadeBeautify is activated!!'); + this.subscriptions.add(atom.commands.add('atom-workspace', 'jade-beautify:convert', this.handleConvert)); + this.subscriptions.add(atom.commands.add('atom-workspace', 'core:save', this.handleSaveEvent)); + this.subscriptions.add(atom.commands.add('atom-workspace', 'window:save-all', this.handleSaveAllEvent)); + }, + deactivate: function() { + this.subscriptions.dispose(); + }, + isJadeFile: function(editor) { + // issue #3 + if (editor && editor.getPath()) + return editor.getPath().endsWith('.jade') ? true : false; + else + return false; + }, + // trigger on command + handleConvert: function() { + if (jadeBeautify.DEBUG) console.log('handleConvert'); + var editor = atom.workspace.getActiveTextEditor(); + jadeBeautify.convert(editor); + }, + // trigger on core:save + handleSaveEvent: function() { + if (jadeBeautify.DEBUG) console.log('handleSaveEvent'); + var beautify = atom.config.get('jade-beautify.BEAUTIFY_ON_SAVE'); + if (!beautify) return; + // It works only jade file. + var editor = atom.workspace.getActiveTextEditor(); + jadeBeautify.convert(editor); + }, + // trigger on window:save-all + handleSaveAllEvent: function() { + if (jadeBeautify.DEBUG) console.log('handleSaveAllEvent'); + var beautify = atom.config.get('jade-beautify.BEAUTIFY_ON_SAVE_ALL'); + if (!beautify) return; + + var editors = atom.workspace.getTextEditors(); + editors.forEach(function(editor) { + if (editor.isModified()) + jadeBeautify.convert(editor); + }); + }, + convert: function(editor) { + // It works only jade file. + if (!jadeBeautify.isJadeFile(editor)) return; + if (jadeBeautify.DEBUG) console.log('convert ', editor.getPath()); + + // var debug = false; + var fill_tab = atom.config.get('jade-beautify.FILL_TAB'); + var omit_div = atom.config.get('jade-beautify.OMIT_DIV'); + + if (jadeBeautify.DEBUG) console.log(fill_tab, omit_div); + + // var editor = atom.workspace.getActiveTextEditor(); + var tabSize = editor.getTabLength(); + var indentList = []; + + // Moves the cursor to the end of the file on save. #6 + var prev_position = editor.getCursorScreenPosition(); + + var prevIndent = { + type: 'code', // type 'code','remark' + indent: 0, // count of indent space. it replace tab as space + tab: 0, // count of tab ,line indent will be filled up with this value. + input: '', // input line after removing indent. + }; + + var lines = editor.getText().split('\n'); + + lines.forEach(function(line, n) { + // it return matching space --> data[0], data[index] = 0, remained input --> data.input + var data = line.match(/^\s*/); + + // when tab and space mixed, it replace all tab to spaces. + var tmp = data[0].replace(/\t/g, Array(tabSize + 1).join(' ')); + var remainedInput = data.input.replace(/^\s*/, ''); + var indent = (remainedInput.length === 0) ? 0 : tmp.length; + + var tab = 0; + var type = (remainedInput.match(/^\/\/|^\/\*|^\*/)) ? 'remark' : 'code'; + + if (omit_div) { + remainedInput = remainedInput.replace(/^div(\.|#)/i, '$1'); + } + + if (indent === 0) { + tab = 0; + } else { + // when this line & prev line is 'remark', it fallow prev line tab. + if (indentList.length > 0 && type === 'remark' && indentList[indentList.length - 1].type == 'remark') { + tab = prevIndent.tab; + } else { + if (indent === prevIndent.indent) { // when same indent, follow prev tab. + tab = prevIndent.tab; + } else if (indent > prevIndent.indent) { // when indented, add tab + tab = prevIndent.tab + 1; + } else { // when new indent, if find the same indent, and follow it's tab. + for (i = indentList.length - 1; i >= 0; i--) { + if (indent == indentList[i].indent) { + tab = indentList[i].tab; + break; + } + } + } + } + } + // if (jadeBeautify.DEBUG) console.log(n + 1, indent, tab, prevIndent.indent); + + var curIndent = { + type: type, + indent: indent, + tab: tab, + input: remainedInput, + }; + + indentList.push(curIndent); + + if (remainedInput.length !== 0) { // discard null line + prevIndent = curIndent; + } + }); + + // // Here,it reformat with it's tab count. + var formatedLine = indentList.map(function(line, n) { + var space = Array(line.tab + 1).join('\t'); + //when fill with space + if (!fill_tab) space = space.replace(/\t/g, Array(tabSize + 1).join(' ')); + + // if (jadeBeautify.DEBUG) console.log(n + 1, line.indent, line.tab, space + line.input); + return space + line.input; + }); + + //Rewrite data + editor.setText(formatedLine.join('\n')); + + // #6 Move Cursor to Previous Postion. + if (prev_position) editor.setCursorScreenPosition(prev_position); + } +}; +module.exports = jadeBeautify; diff --git a/package.json b/package.json index 3e789a6..719a61e 100644 --- a/package.json +++ b/package.json @@ -22,5 +22,7 @@ "engines": { "atom": ">=1.0.0 <2.0.0" }, - "dependencies": {} + "dependencies": { + "pug-beautify": ">=0.0.2" + } }