Closes #60. Convert package scripts from JavaScript to CoffeeScript.

This commit is contained in:
Glavin Wiechert 2014-08-10 18:51:44 -03:00
parent 5b5bfc638a
commit 09c6770cd2
23 changed files with 912 additions and 1059 deletions

View File

@ -1,310 +0,0 @@
/* global atom */
'use strict';
var plugin = module.exports;
// Dependencies
var fs = require('fs');
var path = require('path');
// var nopt = require('nopt');
var _ = require('lodash');
var strip = require('strip-json-comments');
var yaml = require('js-yaml');
// Language options
var beautifier = require('./language-options');
var languages = beautifier.languages;
var defaultLanguageOptions = beautifier.defaultLanguageOptions;
// TODO: Copied from jsbeautify, please update it from time to time
var knownOpts = {
// Beautifier
'indent_size': Number,
'indent_char': String,
'indent_level': Number,
'indent_with_tabs': Boolean,
'indent_handlebars': Boolean,
'preserve_newlines': Boolean,
'max_preserve_newlines': Number,
'space_in_paren': Boolean,
'jslint_happy': Boolean,
// TODO: expand-strict is obsolete, now identical to expand. Remove in future version
'brace_style': ['collapse', 'expand', 'end-expand', 'expand-strict'],
'break_chained_methods': Boolean,
'keep_array_indentation': Boolean,
'unescape_strings': Boolean,
'wrap_line_length': Number,
'e4x': Boolean,
// HTML-only
'max_char': Number, // obsolete since 1.3.5
'unformatted': [String, Array],
'indent_inner_html': [Boolean],
'indent_scripts': ['keep', 'separate', 'normal'],
// CLI
'version': Boolean,
'help': Boolean,
'files': [path, Array],
'outfile': path,
'replace': Boolean,
'quiet': Boolean,
'type': ['js', 'css', 'html'],
'config': path
};
var Subscriber = require('emissary').Subscriber;
Subscriber.extend(plugin);
function getUserHome() {
return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
}
// function cleanOptions(data, types) {
// nopt.clean(data, types);
// return data;
// }
function getCursors(editor) {
var cursors = editor.getCursors();
var posArray = [];
for (var idx = 0; idx < cursors.length; idx++) {
var cursor = cursors[idx];
var bufferPosition = cursor.getBufferPosition();
posArray.push([bufferPosition.row, bufferPosition.column]);
}
return posArray;
}
function setCursors(editor, posArray) {
for (var idx = 0; idx < posArray.length; idx++) {
var bufferPosition = posArray[idx];
if (idx === 0) {
editor.setCursorBufferPosition(bufferPosition);
continue;
}
editor.addCursorAtBufferPosition(bufferPosition);
}
}
function verifyExists(fullPath) {
return fs.existsSync(fullPath) ? fullPath : null;
}
// Storage for memoized results from find file
// Should prevent lots of directory traversal &
// lookups when liniting an entire project
var findFileResults = {};
/**
* Searches for a file with a specified name starting with
* 'dir' and going all the way up either until it finds the file
* or hits the root.
*
* @param {string} name filename to search for (e.g. .jshintrc)
* @param {string} dir directory to start search from (default:
* current working directory)
*
* @returns {string} normalized filename
*/
function findFile(name, dir) {
dir = dir || process.cwd();
var filename = path.normalize(path.join(dir, name));
if (findFileResults[filename] !== undefined) {
return findFileResults[filename];
}
var parent = path.resolve(dir, '../');
if (verifyExists(filename)) {
findFileResults[filename] = filename;
return filename;
}
if (dir === parent) {
findFileResults[filename] = null;
return null;
}
return findFile(name, parent);
}
/**
* Tries to find a configuration file in either project directory
* or in the home directory. Configuration files are named
* '.jsbeautifyrc'.
*
* @param {string} config name of the configuration file
* @param {string} file path to the file to be linted
* @returns {string} a path to the config file
*/
function findConfig(config, file) {
var dir = path.dirname(path.resolve(file));
var envs = getUserHome();
var home = path.normalize(path.join(envs, config));
var proj = findFile(config, dir);
if (proj) {
return proj;
}
if (verifyExists(home)) {
return home;
}
return null;
}
function getConfigOptionsFromSettings(langs) {
var config = atom.config.getSettings()['atom-beautify'];
var options = {};
// console.log(langs, config);
// Iterate over keys of the settings
_.every(_.keys(config), function (k) {
// Check if keys start with a language
var p = k.split('_')[0];
var idx = _.indexOf(langs, p);
// console.log(k, p, idx);
if (idx >= 0) {
// Remove the language prefix and nest in options
var lang = langs[idx];
var opt = k.replace(new RegExp('^' + lang + '_'), '');
options[lang] = options[lang] || {};
options[lang][opt] = config[k];
// console.log(lang, opt);
}
return true;
});
// console.log(options);
return options;
}
function beautify() {
var text;
var editor = atom.workspace.getActiveEditor();
var isSelection = !!editor.getSelectedText();
var softTabs = editor.softTabs;
var tabLength = editor.getTabLength();
var editorOptions = {
'indent_size': softTabs ? tabLength : 1,
'indent_char': softTabs ? ' ' : '\t',
'indent_with_tabs': !softTabs
};
var configOptions = getConfigOptionsFromSettings(languages);
// Look for .jsbeautifierrc in file and home path, check env variables
var editedFilePath = editor.getPath();
function getConfig(startPath) {
// Verify that startPath is a string
startPath = (typeof startPath === 'string') ? startPath : '';
if (!startPath) {
return {};
}
// Get the path to the config file
var configPath = findConfig('.jsbeautifyrc', startPath);
var externalOptions;
if (configPath) {
var contents = fs.readFileSync(configPath, {
encoding: 'utf8'
});
if (!contents) {
externalOptions = {};
} else {
try {
externalOptions = JSON.parse(strip(contents));
} catch (e) {
console.log('Failed parsing config as JSON: ' + configPath);
// Attempt as YAML
try {
externalOptions = yaml.safeLoad(contents);
} catch (e) {
console.log('Failed parsing config as YAML: ' + configPath);
externalOptions = {};
}
}
}
} else {
externalOptions = {};
}
return externalOptions;
}
// Get the path to the config file
var projectOptions = getConfig(editedFilePath);
var homeOptions = getConfig(getUserHome());
if (isSelection) {
text = editor.getSelectedText();
} else {
text = editor.getText();
}
var oldText = text;
// All of the options
// Listed in order from default (base) to the one with the highest priority
// Left = Default, Right = Will override the left.
var allOptions = [
editorOptions, // Atom Editor
configOptions, //
homeOptions, // User's Home path
projectOptions // Project path
];
// Asynchronously and callback-style
function beautifyCompleted(text) {
if (oldText !== text) {
var posArray = getCursors(editor);
var origScrollTop = editor.getScrollTop();
if (isSelection) {
editor.setTextInBufferRange(
editor.getSelectedBufferRange(),
text
);
} else {
editor.setText(text);
}
setCursors(editor, posArray);
// Let the scrollTop setting run after all the save related stuff is run,
// otherwise setScrollTop is not working, probably because the cursor
// addition happens asynchronously
setTimeout(function () {
editor.setScrollTop(origScrollTop);
}, 0);
}
}
// Finally, beautify!
beautifier.beautify(text, editor.getGrammar().name, allOptions, beautifyCompleted);
}
function handleSaveEvent() {
atom.workspace.eachEditor(function (editor) {
var buffer = editor.getBuffer();
plugin.unsubscribe(buffer);
if (atom.config.get('atom-beautify.beautifyOnSave')) {
var events = 'will-be-saved';
plugin.subscribe(buffer, events, beautify);
}
});
}
plugin.configDefaults = _.merge({
analytics: true,
beautifyOnSave: false
}, defaultLanguageOptions);
plugin.activate = function () {
handleSaveEvent();
plugin.subscribe(atom.config.observe(
'atom-beautify.beautifyOnSave',
handleSaveEvent));
return atom.workspaceView.command('beautify', beautify);
};

283
lib/beautify.coffee Normal file
View File

@ -0,0 +1,283 @@
# global atom
# CLI
getUserHome = ->
process.env.HOME or process.env.HOMEPATH or process.env.USERPROFILE
# function cleanOptions(data, types) {
# nopt.clean(data, types);
# return data;
# }
getCursors = (editor) ->
cursors = editor.getCursors()
posArray = []
idx = 0
while idx < cursors.length
cursor = cursors[idx]
bufferPosition = cursor.getBufferPosition()
posArray.push [
bufferPosition.row
bufferPosition.column
]
idx++
posArray
setCursors = (editor, posArray) ->
idx = 0
while idx < posArray.length
bufferPosition = posArray[idx]
if idx is 0
editor.setCursorBufferPosition bufferPosition
continue
editor.addCursorAtBufferPosition bufferPosition
idx++
return
verifyExists = (fullPath) ->
(if fs.existsSync(fullPath) then fullPath else null)
# Storage for memoized results from find file
# Should prevent lots of directory traversal &
# lookups when liniting an entire project
###
Searches for a file with a specified name starting with
'dir' and going all the way up either until it finds the file
or hits the root.
@param {string} name filename to search for (e.g. .jshintrc)
@param {string} dir directory to start search from (default:
current working directory)
@returns {string} normalized filename
###
findFile = (name, dir) ->
dir = dir or process.cwd()
filename = path.normalize(path.join(dir, name))
return findFileResults[filename] if findFileResults[filename] isnt `undefined`
parent = path.resolve(dir, "../")
if verifyExists(filename)
findFileResults[filename] = filename
return filename
if dir is parent
findFileResults[filename] = null
return null
findFile name, parent
###
Tries to find a configuration file in either project directory
or in the home directory. Configuration files are named
'.jsbeautifyrc'.
@param {string} config name of the configuration file
@param {string} file path to the file to be linted
@returns {string} a path to the config file
###
findConfig = (config, file) ->
dir = path.dirname(path.resolve(file))
envs = getUserHome()
home = path.normalize(path.join(envs, config))
proj = findFile(config, dir)
return proj if proj
return home if verifyExists(home)
null
getConfigOptionsFromSettings = (langs) ->
config = atom.config.getSettings()["atom-beautify"]
options = {}
# console.log(langs, config);
# Iterate over keys of the settings
_.every _.keys(config), (k) ->
# Check if keys start with a language
p = k.split("_")[0]
idx = _.indexOf(langs, p)
# console.log(k, p, idx);
if idx >= 0
# Remove the language prefix and nest in options
lang = langs[idx]
opt = k.replace(new RegExp("^" + lang + "_"), "")
options[lang] = options[lang] or {}
options[lang][opt] = config[k]
# console.log(lang, opt);
true
# console.log(options);
options
beautify = ->
# Look for .jsbeautifierrc in file and home path, check env variables
getConfig = (startPath) ->
# Verify that startPath is a string
startPath = (if (typeof startPath is "string") then startPath else "")
return {} unless startPath
# Get the path to the config file
configPath = findConfig(".jsbeautifyrc", startPath)
externalOptions = undefined
if configPath
contents = fs.readFileSync(configPath,
encoding: "utf8"
)
unless contents
externalOptions = {}
else
try
externalOptions = JSON.parse(strip(contents))
catch e
console.log "Failed parsing config as JSON: " + configPath
# Attempt as YAML
try
externalOptions = yaml.safeLoad(contents)
catch e
console.log "Failed parsing config as YAML: " + configPath
externalOptions = {}
else
externalOptions = {}
externalOptions
# Get the path to the config file
# All of the options
# Listed in order from default (base) to the one with the highest priority
# Left = Default, Right = Will override the left.
# Atom Editor
#
# User's Home path
# Project path
# Asynchronously and callback-style
beautifyCompleted = (text) ->
if oldText isnt text
posArray = getCursors(editor)
origScrollTop = editor.getScrollTop()
if isSelection
editor.setTextInBufferRange editor.getSelectedBufferRange(), text
else
editor.setText text
setCursors editor, posArray
# Let the scrollTop setting run after all the save related stuff is run,
# otherwise setScrollTop is not working, probably because the cursor
# addition happens asynchronously
setTimeout (->
editor.setScrollTop origScrollTop
return
), 0
return
text = undefined
editor = atom.workspace.getActiveEditor()
isSelection = !!editor.getSelectedText()
softTabs = editor.softTabs
tabLength = editor.getTabLength()
editorOptions =
indent_size: (if softTabs then tabLength else 1)
indent_char: (if softTabs then " " else "\t")
indent_with_tabs: not softTabs
configOptions = getConfigOptionsFromSettings(languages)
editedFilePath = editor.getPath()
projectOptions = getConfig(editedFilePath)
homeOptions = getConfig(getUserHome())
if isSelection
text = editor.getSelectedText()
else
text = editor.getText()
oldText = text
allOptions = [
editorOptions
configOptions
homeOptions
projectOptions
]
# Finally, beautify!
beautifier.beautify text, editor.getGrammar().name, allOptions, beautifyCompleted
return
handleSaveEvent = ->
atom.workspace.eachEditor (editor) ->
buffer = editor.getBuffer()
plugin.unsubscribe buffer
if atom.config.get("atom-beautify.beautifyOnSave")
events = "will-be-saved"
plugin.subscribe buffer, events, beautify
return
return
"use strict"
plugin = module.exports
fs = require("fs")
path = require("path")
_ = require("lodash")
strip = require("strip-json-comments")
yaml = require("js-yaml")
beautifier = require("./language-options")
languages = beautifier.languages
defaultLanguageOptions = beautifier.defaultLanguageOptions
knownOpts =
indent_size: Number
indent_char: String
indent_level: Number
indent_with_tabs: Boolean
indent_handlebars: Boolean
preserve_newlines: Boolean
max_preserve_newlines: Number
space_in_paren: Boolean
jslint_happy: Boolean
brace_style: [
"collapse"
"expand"
"end-expand"
"expand-strict"
]
break_chained_methods: Boolean
keep_array_indentation: Boolean
unescape_strings: Boolean
wrap_line_length: Number
e4x: Boolean
max_char: Number
unformatted: [
String
Array
]
indent_inner_html: [Boolean]
indent_scripts: [
"keep"
"separate"
"normal"
]
version: Boolean
help: Boolean
files: [
path
Array
]
outfile: path
replace: Boolean
quiet: Boolean
type: [
"js"
"css"
"html"
]
config: path
Subscriber = require("emissary").Subscriber
Subscriber.extend plugin
findFileResults = {}
plugin.configDefaults = _.merge(
analytics: true
beautifyOnSave: false
, defaultLanguageOptions)
plugin.activate = ->
handleSaveEvent()
plugin.subscribe atom.config.observe("atom-beautify.beautifyOnSave", handleSaveEvent)
atom.workspaceView.command "beautify", beautify

View File

@ -0,0 +1,92 @@
###
Requires http://pear.php.net/package/PHP_Beautifier
###
"use strict"
fs = require("fs")
temp = require("temp").track()
exec = require("child_process").exec
module.exports = (getCmd, isStdout) ->
(text, options, callback) ->
# Create temp input file
temp.open "input", (err, info) ->
unless err
# Save current text to input file
fs.write info.fd, text or "", ->
fs.close info.fd, (err) ->
unless err
# Create temp output file
outputPath = temp.path()
deleteOutputFile = ->
temp.cleanup()
# Delete the output path
fs.unlink outputPath, (err) ->
console.log "Deleting output file", err if err
return
return
# Process the command
processCmd = (cmd) ->
if cmd
config = env: process.env
isWin = /^win/.test(process.platform)
unless isWin
# We need the $PATH to be correct when executing the command.
# This should normalize the $PATH
# by calling the external files that would usually
# change the $PATH variable on user login.
$path = "[ -f ~/.bash_profile ] && source ~/.bash_profile;"
$path += "[ -f ~/.bash_rc ] && source ~/.bash_rc;"
# See http://stackoverflow.com/a/638980/2578205
# for checking if file exists in Bash
cmd = $path + cmd
# Execute and beautify!
exec cmd, config, (err, stdout, stderr) ->
# console.log(stderr);
unless err
# Beautification has completed
if isStdout
# Execute callback with resulting output text
callback stdout
deleteOutputFile()
else
# Read contents of output file
fs.readFile outputPath, "utf8", (err, newText) ->
# Execute callback with resulting output text
callback newText
deleteOutputFile()
return
else
console.log "Beautifcation Error: ", err
deleteOutputFile()
return
else
console.log "Beautify CLI command not valid."
return
# Get the command
cmd = getCmd(info.path, outputPath, options, processCmd) # jshint ignore: line
processCmd cmd if typeof cmd is "string"
return
return
return
return

View File

@ -1,98 +0,0 @@
/**
Requires http://pear.php.net/package/PHP_Beautifier
*/
'use strict';
var fs = require('fs');
var temp = require('temp').track();
var exec = require('child_process').exec;
module.exports = function (getCmd, isStdout) {
return function (text, options, callback) {
// Create temp input file
temp.open('input', function (err, info) {
if (!err) {
// Save current text to input file
fs.write(info.fd, text || '', function () {
fs.close(info.fd, function (err) {
if (!err) {
// Create temp output file
var outputPath = temp.path();
var deleteOutputFile = function () {
temp.cleanup();
// Delete the output path
fs.unlink(outputPath, function (err) {
if (err) {
console.log('Deleting output file', err);
}
});
};
// Process the command
var processCmd = function (cmd) {
if (cmd) {
var config = {
env: process.env
};
var isWin = /^win/.test(process.platform);
if (!isWin) {
// We need the $PATH to be correct when executing the command.
// This should normalize the $PATH
// by calling the external files that would usually
// change the $PATH variable on user login.
var $path =
'[ -f ~/.bash_profile ] && source ~/.bash_profile;';
$path +=
'[ -f ~/.bash_rc ] && source ~/.bash_rc;';
// See http://stackoverflow.com/a/638980/2578205
// for checking if file exists in Bash
cmd = $path + cmd;
}
// Execute and beautify!
exec(cmd, config, function (err, stdout, stderr) {
// console.log(stderr);
if (!err) {
// Beautification has completed
if (isStdout) {
// Execute callback with resulting output text
callback(stdout);
deleteOutputFile();
} else {
// Read contents of output file
fs.readFile(outputPath, 'utf8', function (
err,
newText) {
// Execute callback with resulting output text
callback(newText);
deleteOutputFile();
});
}
} else {
console.log('Beautifcation Error: ', err);
deleteOutputFile();
}
});
} else {
console.log('Beautify CLI command not valid.');
}
};
// Get the command
var cmd = getCmd(info.path, outputPath, options,
processCmd); // jshint ignore: line
if (typeof cmd === 'string') {
processCmd(cmd);
}
}
});
});
}
});
};
};

View File

@ -0,0 +1,18 @@
"use strict"
CF = require("coffee-formatter")
module.exports = (text, options, callback) ->
lines = text.split("\n")
resultArr = []
i = 0
len = lines.length
while i < len
curr = lines[i]
p = CF.formatTwoSpaceOperator(curr)
p = CF.formatOneSpaceOperator(p)
p = CF.shortenSpaces(p)
resultArr.push p
i++
result = resultArr.join("\n")
callback result
result

View File

@ -1,17 +0,0 @@
'use strict';
var CF = require('coffee-formatter');
module.exports = function (text, options, callback) {
var lines = text.split('\n');
var resultArr = [];
for (var i = 0, len = lines.length; i < len; i++) {
var curr = lines[i];
var p = CF.formatTwoSpaceOperator(curr);
p = CF.formatOneSpaceOperator(p);
p = CF.shortenSpaces(p);
resultArr.push(p);
}
var result = resultArr.join('\n');
callback(result);
return result;
};

View File

@ -0,0 +1,14 @@
"use strict"
prettydiff = require("prettydiff")
module.exports = (text, options, callback) ->
args =
source: text
lang: "css"
mode: "beautify"
inchar: options.indent_character
insize: options.indent_size
output = prettydiff.api(args)
result = output[0]
callback result
result

View File

@ -1,17 +0,0 @@
'use strict';
var prettydiff = require('prettydiff');
module.exports = function (text, options, callback) {
var args = {
source: text,
lang: 'css',
mode: 'beautify',
inchar: options.indent_character,
insize: options.indent_size
},
output = prettydiff.api(args);
var result = output[0];
callback(result);
return result;
};

View File

@ -0,0 +1,16 @@
###
Requires http://pear.php.net/package/PHP_Beautifier
###
getCmd = (inputPath, outputPath, options) ->
phpBeautifierPath = options.beautifier_path # jshint ignore: line
if phpBeautifierPath
# Use absolute path
"php \"" + phpBeautifierPath + "\" \"" + inputPath + "\" \"" + outputPath + "\""
else
# Use command available in $PATH
"php_beautifier \"" + inputPath + "\" \"" + outputPath + "\""
"use strict"
cliBeautify = require("./cli-beautify")
module.exports = cliBeautify(getCmd)

View File

@ -1,19 +0,0 @@
/**
Requires http://pear.php.net/package/PHP_Beautifier
*/
'use strict';
var cliBeautify = require('./cli-beautify');
function getCmd(inputPath, outputPath, options) {
var phpBeautifierPath = options.beautifier_path; // jshint ignore: line
if (phpBeautifierPath) {
// Use absolute path
return 'php "' + phpBeautifierPath + '" "' + inputPath + '" "' + outputPath + '"';
} else {
// Use command available in $PATH
return 'php_beautifier "' + inputPath + '" "' + outputPath + '"';
}
}
module.exports = cliBeautify(getCmd);

View File

@ -0,0 +1,20 @@
###
Requires https://github.com/hhatto/autopep8
###
getCmd = (inputPath, outputPath, options) ->
path = options.autopep8_path # jshint ignore: line
# jshint ignore: line
# jshint ignore: line
optionsStr = "--max-line-length " + options.max_line_length + " --indent-size " + options.indent_size + " --ignore " + options.ignore.join(",") # jshint ignore: line
if path
# Use absolute path
"python \"" + path + "\" \"" + inputPath + "\" " + optionsStr
else
# Use command available in $PATH
"autopep8 \"" + inputPath + "\" " + optionsStr
"use strict"
cliBeautify = require("./cli-beautify")
isStdout = true
module.exports = cliBeautify(getCmd, isStdout)

View File

@ -1,23 +0,0 @@
/**
Requires https://github.com/hhatto/autopep8
*/
'use strict';
var cliBeautify = require('./cli-beautify');
function getCmd(inputPath, outputPath, options) {
var path = options.autopep8_path; // jshint ignore: line
var optionsStr = '--max-line-length ' + options.max_line_length + // jshint ignore: line
' --indent-size ' + options.indent_size // jshint ignore: line
+ ' --ignore ' + options.ignore.join(','); // jshint ignore: line
if (path) {
// Use absolute path
return 'python "' + path + '" "' + inputPath + '" ' + optionsStr;
} else {
// Use command available in $PATH
return 'autopep8 "' + inputPath + '" ' + optionsStr;
}
}
var isStdout = true;
module.exports = cliBeautify(getCmd, isStdout);

View File

@ -0,0 +1,17 @@
###
Requires https://github.com/erniebrodeur/ruby-beautify
###
getCmd = (inputPath, outputPath, options) ->
path = options.rbeautify_path # jshint ignore: line
if path
# Use absolute path
"ruby \"" + path + "\" \"" + inputPath + "\""
else
# Use command available in $PATH
"rbeautify \"" + inputPath + "\""
"use strict"
cliBeautify = require("./cli-beautify")
isStdout = true
module.exports = cliBeautify(getCmd, isStdout)

View File

@ -1,20 +0,0 @@
/**
Requires https://github.com/erniebrodeur/ruby-beautify
*/
'use strict';
var cliBeautify = require('./cli-beautify');
function getCmd(inputPath, outputPath, options) {
var path = options.rbeautify_path; // jshint ignore: line
if (path) {
// Use absolute path
return 'ruby "' + path + '" "' + inputPath + '"';
} else {
// Use command available in $PATH
return 'rbeautify "' + inputPath + '"';
}
}
var isStdout = true;
module.exports = cliBeautify(getCmd, isStdout);

View File

@ -0,0 +1,78 @@
###
Original SQL Beautifier Source code from https://github.com/vkiryukhin/pretty-data
###
"use strict"
module.exports = (text, options) ->
SQL = ->
self = this
self.step = " " # 2 spaces
self.shift = [ "\n" ] # array of shifts
maxdeep = 100 # nesting level
ix = 0
# initialize array with shifts //
ix = 0
while ix < maxdeep
self.shift.push self.shift[ix] + self.step
ix++
isSubquery = (str, parenthesisLevel) ->
parenthesisLevel - (str.replace(/\(/g, "").length - str.replace(/\)/g, "").length)
splitSql = (str, tab) ->
#.replace(/ IN /ig,'~::~'+tab+'IN ')
#.replace(/\,\s{0,}\(/ig,',~::~( ')
#.replace(/\,/ig,',~::~'+tab+tab+'')
str.replace(/\s{1,}/g, " ").replace(RegExp(" AND ", "g"), "~::~" + tab + tab + "AND ").replace(RegExp(" BETWEEN ", "g"), "~::~" + tab + "BETWEEN ").replace(RegExp(" CASE ", "g"), "~::~" + tab + "CASE ").replace(RegExp(" ELSE ", "g"), "~::~" + tab + "ELSE ").replace(RegExp(" END ", "g"), "~::~" + tab + "END ").replace(RegExp(" FROM ", "g"), "~::~FROM ").replace(RegExp(" GROUP\\s{1,}BY", "g"), "~::~GROUP BY ").replace(RegExp(" HAVING ", "g"), "~::~HAVING ").replace(RegExp(" IN ", "g"), " IN ").replace(RegExp(" JOIN ", "g"), "~::~JOIN ").replace(RegExp(" CROSS~::~{1,}JOIN ", "g"), "~::~CROSS JOIN ").replace(RegExp(" INNER~::~{1,}JOIN ", "g"), "~::~INNER JOIN ").replace(RegExp(" LEFT~::~{1,}JOIN ", "g"), "~::~LEFT JOIN ").replace(RegExp(" RIGHT~::~{1,}JOIN ", "g"), "~::~RIGHT JOIN ").replace(RegExp(" ON ", "g"), "~::~" + tab + "ON ").replace(RegExp(" OR ", "g"), "~::~" + tab + tab + "OR ").replace(RegExp(" ORDER\\s{1,}BY", "g"), "~::~ORDER BY ").replace(RegExp(" OVER ", "g"), "~::~" + tab + "OVER ").replace(/\(\s{0,}SELECT /g, "~::~(SELECT ").replace(/\)\s{0,}SELECT /g, ")~::~SELECT ").replace(RegExp(" THEN ", "g"), " THEN~::~" + tab + "").replace(RegExp(" UNION ", "g"), "~::~UNION~::~").replace(RegExp(" USING ", "g"), "~::~USING ").replace(RegExp(" WHEN ", "g"), "~::~" + tab + "WHEN ").replace(RegExp(" WHERE ", "g"), "~::~WHERE ").replace(RegExp(" WITH ", "g"), "~::~WITH ").replace(RegExp(" ALL ", "g"), " ALL ").replace(RegExp(" AS ", "g"), " AS ").replace(RegExp(" ASC ", "g"), " ASC ").replace(RegExp(" DESC ", "g"), " DESC ").replace(RegExp(" DISTINCT ", "g"), " DISTINCT ").replace(RegExp(" EXISTS ", "g"), " EXISTS ").replace(RegExp(" NOT ", "g"), " NOT ").replace(RegExp(" NULL ", "g"), " NULL ").replace(RegExp(" LIKE ", "g"), " LIKE ").replace(/\s{0,}SELECT /g, "SELECT ").replace(/~::~{1,}/g, "~::~").split "~::~"
SQL::beautify = (text, options) ->
# jshint camelcase: false
# Apply options
# options.indent_size = Indentation size [4]
# options.indent_char = Indentation character [" "]
@step = new Array(options.indent_size).join(options.indent_char)
# Initial indentation level [0]
options.indent_level
# Not supported.
# Indent with tabs, overrides indent_size and indent_char
@step = "\t" unless not options.indent_with_tabs
arByQuote = text.replace(/\s{1,}/g, " ").replace(/\'/g, "~::~'").split("~::~")
len = arByQuote.length
ar = []
deep = 0
tab = @step
inComment = true
inQuote = false
parenthesisLevel = 0
str = ""
ix = 0
ix = 0
while ix < len
if ix % 2
ar = ar.concat(arByQuote[ix])
else
ar = ar.concat(splitSql(arByQuote[ix], tab))
ix++
len = ar.length
ix = 0
while ix < len
parenthesisLevel = isSubquery(ar[ix], parenthesisLevel)
ar[ix] = ar[ix].replace(/\,/g, ",\n" + tab + tab + "") if /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix])
if /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix])
deep++
str += @shift[deep] + ar[ix]
else if /\'/.exec(ar[ix])
deep-- if parenthesisLevel < 1 and deep
str += ar[ix]
else
str += @shift[deep] + ar[ix]
deep-- if parenthesisLevel < 1 and deep
ix++
str = str.replace(/^\n{1,}/, "").replace(/\n{1,}/g, "\n")
str
new SQL().beautify text, options

View File

@ -1,144 +0,0 @@
/**
Original SQL Beautifier Source code from https://github.com/vkiryukhin/pretty-data
*/
'use strict';
module.exports = function (text, options) {
function SQL() {
var self = this;
self.step = ' '; // 2 spaces
self.shift = ['\n']; // array of shifts
var maxdeep = 100, // nesting level
ix = 0;
// initialize array with shifts //
for (ix = 0; ix < maxdeep; ix++) {
self.shift.push(self.shift[ix] + self.step);
}
}
function isSubquery(str, parenthesisLevel) {
return parenthesisLevel - (str.replace(/\(/g, '').length - str.replace(/\)/g, '').length);
}
function splitSql(str, tab) {
return str.replace(/\s{1,}/g, ' ')
.replace(/ AND /ig, '~::~' + tab + tab + 'AND ')
.replace(/ BETWEEN /ig, '~::~' + tab + 'BETWEEN ')
.replace(/ CASE /ig, '~::~' + tab + 'CASE ')
.replace(/ ELSE /ig, '~::~' + tab + 'ELSE ')
.replace(/ END /ig, '~::~' + tab + 'END ')
.replace(/ FROM /ig, '~::~FROM ')
.replace(/ GROUP\s{1,}BY/ig, '~::~GROUP BY ')
.replace(/ HAVING /ig, '~::~HAVING ')
//.replace(/ IN /ig,'~::~'+tab+'IN ')
.replace(/ IN /ig, ' IN ')
.replace(/ JOIN /ig, '~::~JOIN ')
.replace(/ CROSS~::~{1,}JOIN /ig, '~::~CROSS JOIN ')
.replace(/ INNER~::~{1,}JOIN /ig, '~::~INNER JOIN ')
.replace(/ LEFT~::~{1,}JOIN /ig, '~::~LEFT JOIN ')
.replace(/ RIGHT~::~{1,}JOIN /ig, '~::~RIGHT JOIN ')
.replace(/ ON /ig, '~::~' + tab + 'ON ')
.replace(/ OR /ig, '~::~' + tab + tab + 'OR ')
.replace(/ ORDER\s{1,}BY/ig, '~::~ORDER BY ')
.replace(/ OVER /ig, '~::~' + tab + 'OVER ')
.replace(/\(\s{0,}SELECT /ig, '~::~(SELECT ')
.replace(/\)\s{0,}SELECT /ig, ')~::~SELECT ')
.replace(/ THEN /ig, ' THEN~::~' + tab + '')
.replace(/ UNION /ig, '~::~UNION~::~')
.replace(/ USING /ig, '~::~USING ')
.replace(/ WHEN /ig, '~::~' + tab + 'WHEN ')
.replace(/ WHERE /ig, '~::~WHERE ')
.replace(/ WITH /ig, '~::~WITH ')
//.replace(/\,\s{0,}\(/ig,',~::~( ')
//.replace(/\,/ig,',~::~'+tab+tab+'')
.replace(/ ALL /ig, ' ALL ')
.replace(/ AS /ig, ' AS ')
.replace(/ ASC /ig, ' ASC ')
.replace(/ DESC /ig, ' DESC ')
.replace(/ DISTINCT /ig, ' DISTINCT ')
.replace(/ EXISTS /ig, ' EXISTS ')
.replace(/ NOT /ig, ' NOT ')
.replace(/ NULL /ig, ' NULL ')
.replace(/ LIKE /ig, ' LIKE ')
.replace(/\s{0,}SELECT /ig, 'SELECT ')
.replace(/~::~{1,}/g, '~::~')
.split('~::~');
}
SQL.prototype.beautify = function (text, options) {
/* jshint camelcase: false */
// Apply options
// options.indent_size = Indentation size [4]
// options.indent_char = Indentation character [" "]
this.step = new Array(options.indent_size).join(options.indent_char);
// Initial indentation level [0]
if (options.indent_level) {
// Not supported.
}
// Indent with tabs, overrides indent_size and indent_char
if (!!options.indent_with_tabs) {
this.step = '\t';
}
var arByQuote = text.replace(/\s{1,}/g, ' ')
.replace(/\'/ig, '~::~\'')
.split('~::~'),
len = arByQuote.length,
ar = [],
deep = 0,
tab = this.step,
inComment = true,
inQuote = false,
parenthesisLevel = 0,
str = '',
ix = 0;
for (ix = 0; ix < len; ix++) {
if (ix % 2) {
ar = ar.concat(arByQuote[ix]);
} else {
ar = ar.concat(splitSql(arByQuote[ix], tab));
}
}
len = ar.length;
for (ix = 0; ix < len; ix++) {
parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
if (/\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g, ',\n' + tab + tab + '');
}
if (/\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
deep++;
str += this.shift[deep] + ar[ix];
} else
if (/\'/.exec(ar[ix])) {
if (parenthesisLevel < 1 && deep) {
deep--;
}
str += ar[ix];
} else {
str += this.shift[deep] + ar[ix];
if (parenthesisLevel < 1 && deep) {
deep--;
}
}
}
str = str.replace(/^\n{1,}/, '').replace(/\n{1,}/g, '\n');
return str;
};
return new SQL().beautify(text, options);
};

View File

@ -0,0 +1,72 @@
###
Requires http://pear.php.net/package/PHP_Beautifier
###
"use strict"
fs = require("fs")
temp = require("temp").track()
module.exports = (options, cb) ->
text = ""
# Apply indent_size to output_tab_size
options.output_tab_size = options.output_tab_size or options.indent_size # jshint ignore: line
options.input_tab_size = options.input_tab_size or options.indent_size # jshint ignore: line
delete options.indent_size # jshint ignore: line
# Indent with Tabs?
# How to use tabs when indenting code
# 0=spaces only
# 1=indent with tabs to brace level, align with spaces
# 2=indent and align with tabs, using spaces when not on a tabstop
# jshint ignore: start
ic = options.indent_char
if options.indent_with_tabs is 0 or options.indent_with_tabs is 1 or options.indent_with_tabs is 2
# Ignore indent_char option
else if ic is " "
options.indent_with_tabs = 0 # Spaces only
else if ic is "\t"
options.indent_with_tabs = 2 # indent and align with tabs, using spaces when not on a tabstop
else
options.indent_with_tabs = 1 # indent with tabs to brace level, align with spaces
delete options.indent_char
# jshint ignore: end
# Remove misc
delete options.languageOverride
delete options.configPath
# Iterate over each property and write to configuration file
for k of options
v = options[k]
vs = v
if typeof vs is "boolean"
if vs is true
vs = "True"
else
vs = "False"
text += k + " = " + vs + "\n"
# Create temp input file
temp.open
suffix: ".cfg"
, (err, info) ->
unless err
# Save current text to input file
fs.write info.fd, text or "", (err) ->
# console.log(err);
return cb(err) if err
fs.close info.fd, (err) ->
# console.log(err);
return cb(err) if err
cb null, info.path
else
cb err

View File

@ -1,76 +0,0 @@
/**
Requires http://pear.php.net/package/PHP_Beautifier
*/
'use strict';
var fs = require('fs');
var temp = require('temp').track();
module.exports = function (options, cb) {
var text = '';
// Apply indent_size to output_tab_size
options.output_tab_size = options.output_tab_size || options.indent_size; // jshint ignore: line
options.input_tab_size = options.input_tab_size || options.indent_size; // jshint ignore: line
delete options.indent_size; // jshint ignore: line
// Indent with Tabs?
// How to use tabs when indenting code
// 0=spaces only
// 1=indent with tabs to brace level, align with spaces
// 2=indent and align with tabs, using spaces when not on a tabstop
// jshint ignore: start
var ic = options.indent_char;
if (options.indent_with_tabs === 0 ||
options.indent_with_tabs === 1 ||
options.indent_with_tabs === 2) {
// Ignore indent_char option
} else if (ic === ' ') {
options.indent_with_tabs = 0; // Spaces only
} else if (ic === '\t') {
options.indent_with_tabs = 2; // indent and align with tabs, using spaces when not on a tabstop
} else {
options.indent_with_tabs = 1; // indent with tabs to brace level, align with spaces
}
delete options.indent_char;
// jshint ignore: end
// Remove misc
delete options.languageOverride;
delete options.configPath;
// Iterate over each property and write to configuration file
for (var k in options) {
var v = options[k];
var vs = v;
if (typeof vs === 'boolean') {
if (vs === true) {
vs = 'True';
} else {
vs = 'False';
}
}
text += k + ' = ' + vs + '\n';
}
// Create temp input file
temp.open({
suffix: '.cfg'
}, function (err, info) {
if (!err) {
// Save current text to input file
fs.write(info.fd, text || '', function (err) {
// console.log(err);
if (err) {
return cb(err);
}
fs.close(info.fd, function (err) {
// console.log(err);
if (err) {
return cb(err);
}
return cb(null, info.path);
});
});
} else {
return cb(err);
}
});
};

View File

@ -0,0 +1,38 @@
###
Requires http://pear.php.net/package/PHP_Beautifier
###
getCmd = (inputPath, outputPath, options, cb) ->
# console.log('Uncrustify options:', options);
done = (configPath) ->
# console.log(configPath);
# Use command available in $PATH
cmd = "uncrustify -c \"" + configPath + "\" -f \"" + inputPath + "\" -o \"" + outputPath + "\" -l \"" + lang + "\""
# console.log(cmd);
cb cmd
configPath = options.configPath
lang = options.languageOverride or "C"
unless configPath
# No custom config path
cfg options, (error, path) ->
throw error if error
done path
else
# Has custom config path
editor = atom.workspace.getActiveEditor()
basePath = path.dirname(editor.getPath())
# console.log(basePath);
configPath = path.resolve(basePath, configPath)
done configPath
return
"use strict"
cliBeautify = require("../cli-beautify")
cfg = require("./cfg")
path = require("path")
module.exports = cliBeautify(getCmd)

View File

@ -1,44 +0,0 @@
/**
Requires http://pear.php.net/package/PHP_Beautifier
*/
'use strict';
var cliBeautify = require('../cli-beautify');
var cfg = require('./cfg');
var path = require('path');
function getCmd(inputPath, outputPath, options, cb) {
// console.log('Uncrustify options:', options);
var configPath = options.configPath;
var lang = options.languageOverride || 'C';
function done(configPath) {
// console.log(configPath);
// Use command available in $PATH
var cmd = 'uncrustify -c "' + configPath +
'" -f "' + inputPath +
'" -o "' + outputPath +
'" -l "' + lang + '"';
// console.log(cmd);
return cb(cmd);
}
if (!configPath) {
// No custom config path
cfg(options, function (error, path) {
if (error) {
throw error;
}
return done(path);
});
} else {
// Has custom config path
var editor = atom.workspace.getActiveEditor();
var basePath = path.dirname(editor.getPath());
// console.log(basePath);
configPath = path.resolve(basePath, configPath);
done(configPath);
}
return;
}
module.exports = cliBeautify(getCmd);

263
lib/language-options.coffee Normal file
View File

@ -0,0 +1,263 @@
###
Language Support and default options.
###
"use strict"
_ = require("lodash")
extend = require("extend")
# Language Beautifiers
beautifyJS = require("js-beautify")
beautifyHTML = require("js-beautify").html
beautifyCSS = require("js-beautify").css
beautifySQL = require("./langs/sql-beautify")
beautifyPHP = require("./langs/php-beautify")
beautifyPython = require("./langs/python-beautify")
beautifyRuby = require("./langs/ruby-beautify")
beautifyLESS = require("./langs/less-beautify")
beautifyCoffeeScript = require("./langs/coffeescript-beautify")
uncrustifyBeautifier = require("./langs/uncrustify/")
# Misc
Analytics = require("analytics-node")
pkg = require("../package.json")
# Analytics
analyticsWriteKey = "u3c26xkae8"
module.exports =
# Supported unique configuration keys
# Used for detecting nested configurations in .jsbeautifyrc
languages: [
"js"
"html"
"css"
"sql"
"php"
"python"
"ruby"
"coffeescript"
"c"
"cpp"
"cs"
"objectivec"
"java"
"d"
"pawn"
"vala"
]
# Default options per language
defaultLanguageOptions:
# jshint ignore: start
# JavaScript
js_indent_size: 2
js_indent_char: " "
js_indent_level: 0
js_indent_with_tabs: false
js_preserve_newlines: true
js_max_preserve_newlines: 10
js_jslint_happy: false
js_brace_style: "collapse"
js_keep_array_indentation: false
js_keep_function_indentation: false
js_space_before_conditional: true
js_break_chained_methods: false
js_eval_code: false
js_unescape_strings: false
js_wrap_line_length: 0
# CSS
css_indent_size: 2
css_indent_Char: " "
# HTML
html_indent_inner_html: false
html_indent_size: 2
html_indent_char: " "
html_brace_style: "collapse"
html_indent_scripts: "normal"
html_wrap_line_length: 250
# SQL
sql_indent_size: 2
sql_indent_char: " "
# PHP
php_beautifier_path: ""
# Python
python_autopep8_path: ""
python_max_line_length: 79
python_indent_size: 4
python_ignore: ["E24"]
# Ruby
ruby_rbeautify_path: ""
# C
c_configPath: ""
# C++
cpp_configPath: ""
# Objective-C
objectivec_configPath: ""
# C#
cs_configPath: ""
# Objective-C
d_configPath: ""
# Java
java_configPath: ""
# Pawn
pawn_configPath: ""
# VALA
vala_configPath: ""
# jshint ignore: end
# Process each language
beautify: (text, grammar, allOptions, beautifyCompleted) ->
self = this
# Beautify!
unsupportedGrammar = false
options = undefined
switch grammar
# Treat JSON as JavaScript, because it will support comments.
# And Glavin001 has tested JSON beauifying with beautifyJS.
when "JSON", "JavaScript"
text = beautifyJS(text, self.getOptions("js", allOptions))
beautifyCompleted text
when "CoffeeScript"
beautifyCoffeeScript text, self.getOptions("js", allOptions), beautifyCompleted
when "Handlebars"
# jshint ignore: start
allOptions.push indent_handlebars: true # Force jsbeautify to indent_handlebars
# jshint ignore: end
when "HTML (Liquid)", "HTML", "XML"
text = beautifyHTML(text, self.getOptions("html", allOptions))
beautifyCompleted text
when "CSS"
text = beautifyCSS(text, self.getOptions("css", allOptions))
beautifyCompleted text
when "Sass", "SCSS", "LESS"
beautifyLESS text, self.getOptions("css", allOptions), beautifyCompleted
when "SQL (Rails)", "SQL"
text = beautifySQL(text, self.getOptions("sql", allOptions))
beautifyCompleted text
when "PHP"
beautifyPHP text, self.getOptions("php", allOptions), beautifyCompleted
when "Python"
beautifyPython text, self.getOptions("python", allOptions), beautifyCompleted
when "Ruby"
beautifyRuby text, self.getOptions("ruby", allOptions), beautifyCompleted
when "C"
options = self.getOptions("c", allOptions)
options.languageOverride = "C"
uncrustifyBeautifier text, options, beautifyCompleted
when "C++"
options = self.getOptions("cpp", allOptions)
options.languageOverride = "CPP"
uncrustifyBeautifier text, options, beautifyCompleted
when "C#"
options = self.getOptions("cs", allOptions)
options.languageOverride = "CS"
uncrustifyBeautifier text, options, beautifyCompleted
when "Objective-C", "Objective-C++"
options = self.getOptions("objectivec", allOptions)
options.languageOverride = "OC+"
uncrustifyBeautifier text, options, beautifyCompleted
when "D"
options = self.getOptions("d", allOptions)
options.languageOverride = "D"
uncrustifyBeautifier text, options, beautifyCompleted
when "Pawn"
options = self.getOptions("pawn", allOptions)
options.languageOverride = "PAWN"
uncrustifyBeautifier text, options, beautifyCompleted
when "Vala"
options = self.getOptions("vala", allOptions)
options.languageOverride = "VALA"
uncrustifyBeautifier text, options, beautifyCompleted
when "Java"
options = self.getOptions("java", allOptions)
options.languageOverride = "JAVA"
uncrustifyBeautifier text, options, beautifyCompleted
else
unsupportedGrammar = true
# Check if Analytics is enabled
if atom.config.get("atom-beautify.analytics")
# Setup Analytics
analytics = new Analytics(analyticsWriteKey)
unless atom.config.get("atom-beautify._analyticsUserId")
uuid = require("node-uuid")
atom.config.set "atom-beautify._analyticsUserId", uuid.v4()
# Setup Analytics User Id
userId = atom.config.get("atom-beautify._analyticsUserId")
analytics.identify userId: userId
version = pkg.version
analytics.track
userId: atom.config.get("atom-beautify._analyticsUserId")
event: "Beautify"
properties:
grammar: grammar
version: version
options: allOptions
label: grammar
category: version
return
getOptions: (selection, allOptions) ->
self = this
# console.log(selection, allOptions);
# Reduce all options into correctly merged options.
options = _.reduce(allOptions, (result, currOptions) ->
containsNested = false
collectedConfig = {}
key = undefined
# Check to see if config file uses nested object format to split up js/css/html options
for key of currOptions
# Check if is supported language
if _.indexOf(self.languages, key) >= 0 and typeof currOptions[key] is "object" # Check if nested object (more options in value)
containsNested = true
break # Found, break out of loop, no need to continue
# console.log(containsNested, currOptions);
# Create a flat object of config options if nested format was used
unless containsNested
_.merge collectedConfig, currOptions
else
# Merge with selected options
# where `selection` could be `html`, `js`, 'css', etc
# console.log(selection, currOptions[selection]);
_.merge collectedConfig, currOptions[selection]
extend result, collectedConfig
, {})
# TODO: Clean.
# There is a bug in nopt
# See https://github.com/npm/nopt/issues/38#issuecomment-45971505
# console.log('pre-clean', JSON.stringify(options));
#options = cleanOptions(options, knownOpts);
#console.log('post-clean', JSON.stringify(options));
options

View File

@ -1,290 +0,0 @@
/**
Language Support and default options.
*/
'use strict';
var _ = require('lodash');
var extend = require('extend');
// Language Beautifiers
var beautifyJS = require('js-beautify');
var beautifyHTML = require('js-beautify').html;
var beautifyCSS = require('js-beautify').css;
var beautifySQL = require('./langs/sql-beautify');
var beautifyPHP = require('./langs/php-beautify');
var beautifyPython = require('./langs/python-beautify');
var beautifyRuby = require('./langs/ruby-beautify');
var beautifyLESS = require('./langs/less-beautify');
var beautifyCoffeeScript = require('./langs/coffeescript-beautify');
var uncrustifyBeautifier = require('./langs/uncrustify/');
// Misc
var Analytics = require('analytics-node');
var pkg = require('../package.json');
// Analytics
var analyticsWriteKey = 'u3c26xkae8';
module.exports = {
// Supported unique configuration keys
// Used for detecting nested configurations in .jsbeautifyrc
languages: [
'js',
'html',
'css',
'sql',
'php',
'python',
'ruby',
'coffeescript',
'c',
'cpp',
'cs',
'objectivec',
'java',
'd',
'pawn',
'vala'
],
// Default options per language
defaultLanguageOptions: {
/* jshint ignore: start */
// JavaScript
js_indent_size: 2,
js_indent_char: ' ',
js_indent_level: 0,
js_indent_with_tabs: false,
js_preserve_newlines: true,
js_max_preserve_newlines: 10,
js_jslint_happy: false,
js_brace_style: 'collapse',
js_keep_array_indentation: false,
js_keep_function_indentation: false,
js_space_before_conditional: true,
js_break_chained_methods: false,
js_eval_code: false,
js_unescape_strings: false,
js_wrap_line_length: 0,
// CSS
css_indent_size: 2,
css_indent_Char: ' ',
// HTML
html_indent_inner_html: false,
html_indent_size: 2,
html_indent_char: ' ',
html_brace_style: 'collapse',
html_indent_scripts: 'normal',
html_wrap_line_length: 250,
// SQL
sql_indent_size: 2,
sql_indent_char: ' ',
// PHP
php_beautifier_path: '',
// Python
python_autopep8_path: '',
python_max_line_length: 79,
python_indent_size: 4,
python_ignore: ['E24'],
// Ruby
ruby_rbeautify_path: '',
// C
c_configPath: '',
// C++
cpp_configPath: '',
// Objective-C
objectivec_configPath: '',
// C#
cs_configPath: '',
// Objective-C
d_configPath: '',
// Java
java_configPath: '',
// Pawn
pawn_configPath: '',
// VALA
vala_configPath: ''
/* jshint ignore: end */
},
// Process each language
beautify: function (text, grammar, allOptions, beautifyCompleted) {
var self = this;
// Beautify!
var unsupportedGrammar = false;
var options;
switch (grammar) {
case 'JSON':
// Treat JSON as JavaScript, because it will support comments.
// And Glavin001 has tested JSON beauifying with beautifyJS.
case 'JavaScript':
text = beautifyJS(text, self.getOptions('js', allOptions));
beautifyCompleted(text);
break;
case 'CoffeeScript':
beautifyCoffeeScript(text, self.getOptions('js', allOptions),
beautifyCompleted);
break;
case 'Handlebars':
// jshint ignore: start
allOptions.push({
indent_handlebars: true // Force jsbeautify to indent_handlebars
});
// jshint ignore: end
case 'HTML (Liquid)':
case 'HTML':
case 'XML':
text = beautifyHTML(text, self.getOptions('html', allOptions));
beautifyCompleted(text);
break;
case 'CSS':
text = beautifyCSS(text, self.getOptions('css', allOptions));
beautifyCompleted(text);
break;
case 'Sass':
case 'SCSS':
case 'LESS':
beautifyLESS(text, self.getOptions('css', allOptions), beautifyCompleted);
break;
case 'SQL (Rails)':
case 'SQL':
text = beautifySQL(text, self.getOptions('sql', allOptions));
beautifyCompleted(text);
break;
case 'PHP':
beautifyPHP(text, self.getOptions('php', allOptions), beautifyCompleted);
break;
case 'Python':
beautifyPython(text, self.getOptions('python', allOptions),
beautifyCompleted);
break;
case 'Ruby':
beautifyRuby(text, self.getOptions('ruby', allOptions), beautifyCompleted);
break;
case 'C':
options = self.getOptions('c', allOptions);
options.languageOverride = 'C';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
case 'C++':
options = self.getOptions('cpp', allOptions);
options.languageOverride = 'CPP';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
case 'C#':
options = self.getOptions('cs', allOptions);
options.languageOverride = 'CS';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
case 'Objective-C':
case 'Objective-C++':
options = self.getOptions('objectivec', allOptions);
options.languageOverride = 'OC+';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
case 'D':
options = self.getOptions('d', allOptions);
options.languageOverride = 'D';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
case 'Pawn':
options = self.getOptions('pawn', allOptions);
options.languageOverride = 'PAWN';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
case 'Vala':
options = self.getOptions('vala', allOptions);
options.languageOverride = 'VALA';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
case 'Java':
options = self.getOptions('java', allOptions);
options.languageOverride = 'JAVA';
uncrustifyBeautifier(text, options,
beautifyCompleted);
break;
default:
unsupportedGrammar = true;
}
// Check if Analytics is enabled
if (atom.config.get('atom-beautify.analytics')) {
// Setup Analytics
var analytics = new Analytics(analyticsWriteKey);
if (!atom.config.get('atom-beautify._analyticsUserId')) {
var uuid = require('node-uuid');
atom.config.set('atom-beautify._analyticsUserId', uuid.v4());
}
// Setup Analytics User Id
var userId = atom.config.get('atom-beautify._analyticsUserId');
analytics.identify({
userId: userId
});
var version = pkg.version;
analytics.track({
userId: atom.config.get('atom-beautify._analyticsUserId'),
event: 'Beautify',
properties: {
grammar: grammar,
version: version,
options: allOptions,
label: grammar,
category: version
}
});
}
},
getOptions: function (selection, allOptions) {
var self = this;
// console.log(selection, allOptions);
// Reduce all options into correctly merged options.
var options = _.reduce(allOptions, function (result, currOptions) {
var containsNested = false;
var collectedConfig = {};
var key;
// Check to see if config file uses nested object format to split up js/css/html options
for (key in currOptions) {
if (_.indexOf(self.languages, key) >= 0 && // Check if is supported language
typeof currOptions[key] === 'object') { // Check if nested object (more options in value)
containsNested = true;
break; // Found, break out of loop, no need to continue
}
}
// console.log(containsNested, currOptions);
// Create a flat object of config options if nested format was used
if (!containsNested) {
_.merge(collectedConfig, currOptions);
} else {
// Merge with selected options
// where `selection` could be `html`, `js`, 'css', etc
// console.log(selection, currOptions[selection]);
_.merge(collectedConfig, currOptions[selection]);
}
return extend(result, collectedConfig);
}, {});
// TODO: Clean.
// There is a bug in nopt
// See https://github.com/npm/nopt/issues/38#issuecomment-45971505
// console.log('pre-clean', JSON.stringify(options));
//options = cleanOptions(options, knownOpts);
//console.log('post-clean', JSON.stringify(options));
return options;
}
};

View File

@ -1,6 +1,6 @@
{
"name": "atom-beautify",
"main": "./lib/atom-beautify",
"main": "./lib/beautify",
"version": "0.6.2",
"private": true,
"description": "Beautify HTML, CSS, JavaScript, PHP, Python, Ruby, Java, C, C++, C#, Objective-C, CoffeeScript, and SQL in Atom",