Merge branch 'feature/executables' into greenkeeper/initial

This commit is contained in:
Glavin Wiechert 2017-06-16 22:53:27 -03:00
commit 996cf91887
31 changed files with 1521 additions and 447 deletions

View File

@ -23,6 +23,13 @@ go:
matrix:
include:
- os: linux
dist: trusty
sudo: required
services:
- docker
env:
- ATOM_CHANNEL=stable
# - os: linux
# dist: trusty
# sudo: require
@ -78,7 +85,7 @@ before_install:
git clone --depth=1 https://github.com/Linuxbrew/brew.git ~/.linuxbrew || true;
fi
# Update Homebrew
- brew update
# - brew update
- brew tap homebrew/dupes
- brew tap homebrew/versions
# Ruby language support
@ -87,7 +94,11 @@ before_install:
- gem install htmlbeautifier
- gem install puppet-lint
# Sass language support
- gem install sass
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
gem install sass;
else
docker pull unibeautify/sass-convert;
fi
# Python language support
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo chmod 777 -R /opt/python; fi
- pip install --upgrade pip
@ -96,10 +107,19 @@ before_install:
# SQL language support
- pip install --upgrade sqlparse
# Java, C, C++, C#, Objective-C, D, Pawn, Vala
- brew install uncrustify
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew install uncrustify;
else
docker pull unibeautify/uncrustify;
fi
# R
- brew tap homebrew/science
- brew install r
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew install r;
rscript --version;
else
docker pull unibeautify/rscript;
fi
# PHP
- brew tap homebrew/homebrew-php
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
@ -122,11 +142,12 @@ before_install:
# - stack install stylish-haskell
# Elm
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
curl -L -o /tmp/elm-format.tgz https://github.com/avh4/elm-format/releases/download/0.2.0-alpha/elm-format-0.2.0-alpha-mac-x64.tgz;
curl -L -o /tmp/elm-format.tgz
https://github.com/avh4/elm-format/releases/download/0.7.0-exp/elm-format-0.17-0.7.0-exp-mac-x64.tgz;
tar xvzf /tmp/elm-format.tgz -C /usr/local/bin;
fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
curl -L -o /tmp/elm-format.tgz https://github.com/avh4/elm-format/releases/download/0.2.0-alpha/elm-format-0.2.0-alpha-linux-x64.tgz;
curl -L -o /tmp/elm-format.tgz https://github.com/avh4/elm-format/releases/download/0.7.0-exp/elm-format-0.17-0.7.0-exp-linux-x64.tgz;
tar xvzf /tmp/elm-format.tgz -C $HOME/.linuxbrew/bin;
fi
# OCaml

View File

@ -63,6 +63,10 @@ Thank you.
Atom-Beautify is going to be completely rewritten with [Unibeautify](https://github.com/Unibeautify/unibeautify) at its core!
See [`unibeautify` branch](../../tree/unibeautify) for work in progress and [Issue #1174](https://github.com/Glavin001/atom-beautify/issues/1174).
### Want automated installation?
See [Issue #1678](https://github.com/Glavin001/atom-beautify/issues/1687) for a solution utilizing [Docker](https://www.docker.com/) to achieve automated installation of beautifiers which are not already preinstalled.
## Beautifiers
Some of the supported beautifiers are developed for Node.js and are automatically installed when Atom-Beautify is installed. However, other beautifiers are command-line interface (CLI) applications and require you to manually install them.

View File

@ -1,6 +1,4 @@
# :lipstick: [atom-beautify](https://github.com/Glavin001/atom-beautify)
[![Greenkeeper badge](https://badges.greenkeeper.io/Glavin001/atom-beautify.svg)](https://greenkeeper.io/)
[![GitHub issues](https://img.shields.io/github/issues/Glavin001/atom-beautify.svg?style=flat-square)](https://github.com/Glavin001/atom-beautify/issues)
[![GitHub stars](https://img.shields.io/github/stars/Glavin001/atom-beautify.svg?style=flat-square)](https://github.com/Glavin001/atom-beautify/stargazers)
[![Gitter](https://img.shields.io/gitter/room/Glavin001/atom-beautify.svg?style=flat-square)](https://gitter.im/Glavin001/atom-beautify)
@ -65,6 +63,10 @@ Thank you.
Atom-Beautify is going to be completely rewritten with [Unibeautify](https://github.com/Unibeautify/unibeautify) at its core!
See [`unibeautify` branch](../../tree/unibeautify) for work in progress and [Issue #1174](https://github.com/Glavin001/atom-beautify/issues/1174).
### Want automated installation?
See [Issue #1678](https://github.com/Glavin001/atom-beautify/issues/1687) for a solution utilizing [Docker](https://www.docker.com/) to achieve automated installation of beautifiers which are not already preinstalled.
## Beautifiers
Some of the supported beautifiers are developed for Node.js and are automatically installed when Atom-Beautify is installed. However, other beautifiers are command-line interface (CLI) applications and require you to manually install them.
@ -93,7 +95,7 @@ Some of the supported beautifiers are developed for Node.js and are automaticall
| JS Beautify | :white_check_mark: | Nothing! |
| JSCS Fixer | :white_check_mark: | Nothing! |
| Latex Beautify | :x: | Go to https://github.com/cmhughes/latexindent.pl and follow the instructions. |
| Lua beautifier | :x: | Go to https://www.perl.org/ and follow the instructions. |
| Lua beautifier | :white_check_mark: | Nothing! |
| Marko Beautifier | :white_check_mark: | Nothing! |
| Nginx Beautify | :white_check_mark: | Nothing! |
| ocp-indent | :x: | Go to https://www.typerex.org/ocp-indent.html and follow the instructions. |
@ -155,7 +157,7 @@ See [all supported options in the documentation at `docs/options.md`](docs/opti
| JSX | `JSX`, `JavaScript (JSX)`, `Babel ES6 JavaScript`, `JavaScript with JSX` |`.jsx`, `.js` | [`JS Beautify`](https://github.com/beautify-web/js-beautify), [`Pretty Diff`](https://github.com/prettydiff/prettydiff) (Default) |
| LaTeX | `BibTeX`, `LaTeX`, `TeX` |`.bib`, `.tex`, `.sty`, `.cls`, `.dtx`, `.ins`, `.bbx`, `.cbx` | [`Latex Beautify`](https://github.com/cmhughes/latexindent.pl) (Default) |
| LESS | `LESS` |`.less` | [`CSScomb`](https://github.com/csscomb/csscomb.js), [`Pretty Diff`](https://github.com/prettydiff/prettydiff) (Default) |
| Lua | `Lua` |`.lua` | [`Lua beautifier`](https://www.perl.org/) (Default) |
| Lua | `Lua` |`.lua` | [`Lua beautifier`](https://github.com/Glavin001/atom-beautify/blob/master/src/beautifiers/lua-beautifier/beautifier.coffee) (Default) |
| Markdown | `GitHub Markdown` |`.markdown`, `.md` | [`Remark`](https://github.com/wooorm/remark), [`Tidy Markdown`](https://github.com/slang800/tidy-markdown) (Default) |
| Marko | `Marko` |`.marko` | [`Marko Beautifier`](https://github.com/marko-js/marko-prettyprint) (Default) |
| Mustache | `HTML (Mustache)` |`.mustache` | [`JS Beautify`](https://github.com/beautify-web/js-beautify) (Default), [`Pretty Diff`](https://github.com/prettydiff/prettydiff) |

View File

@ -1,5 +1,5 @@
version: "{build}"
os: Windows Server 2012 R2
image: Visual Studio 2017
test: off
deploy: off
@ -46,9 +46,6 @@ install:
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""
- ECHO "Installed SDKs:"
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
- cinst atom -y
- cd %APPVEYOR_BUILD_FOLDER%
# Add Atom's bin (apm, etc) to PATH
@ -116,18 +113,22 @@ install:
- where php-cs-fixer
# Uncrustify
- curl -k -L http://sourceforge.net/projects/uncrustify/files/uncrustify/uncrustify-0.61/uncrustify-0.61.3-gf65394e-win32.zip/download -o uncrustify.zip
- curl -k -L https://sourceforge.net/projects/uncrustify/files/uncrustify/uncrustify-0.65/uncrustify-0.65-win32.zip/download -o uncrustify.zip
- cinst 7zip.commandline -y
- 7za e uncrustify.zip -ouncrustify-d
- "SET PATH=%cd%\\uncrustify-d;%PATH%"
- where uncrustify
# elm-format
- curl -k -L https://github.com/avh4/elm-format/releases/download/0.2.0-alpha/elm-format-0.2.0-alpha-win-x64.zip -o elm-format.zip
- curl -k -L https://github.com/avh4/elm-format/releases/download/0.7.0-exp/elm-format-0.18-0.7.0-exp-win-i386.zip -o elm-format.zip
- 7za e elm-format.zip -oelm-format-d
- "SET PATH=%cd%\\elm-format-d;%PATH%"
- where elm-format
# Beautysh
- pip install beautysh
- where beautysh
build_script:
- cd %APPVEYOR_BUILD_FOLDER%

View File

@ -1,3 +1,4 @@
#!/usr/bin/env coffee
# Dependencies
@ -11,7 +12,10 @@ pkg = require('../package.json')
console.log('Generating options...')
beautifier = new Beautifiers()
languageOptions = beautifier.options
executableOptions = languageOptions.executables
delete languageOptions.executables
packageOptions = require('../src/config.coffee')
packageOptions.executables = executableOptions
# Build options by Beautifier
beautifiersMap = _.keyBy(beautifier.beautifiers, 'name')
languagesMap = _.keyBy(beautifier.languages.languages, 'name')
@ -82,25 +86,28 @@ Handlebars.registerHelper('example-config', (key, option, options) ->
Handlebars.registerHelper('language-beautifiers-support', (languageOptions, options) ->
rows = _.map(languageOptions, (val, k) ->
name = val.title
defaultBeautifier = _.get(val, "properties.default_beautifier.default")
beautifiers = _.map(val.beautifiers, (b) ->
beautifier = beautifiersMap[b]
isDefault = b is defaultBeautifier
if beautifier.link
r = "[`#{b}`](#{beautifier.link})"
else
r = "`#{b}`"
if isDefault
r += " (Default)"
return r
)
grammars = _.map(val.grammars, (b) -> "`#{b}`")
extensions = _.map(val.extensions, (b) -> "`.#{b}`")
rows = _.chain(languageOptions)
.filter((val, k) -> k isnt "executables")
.map((val, k) ->
name = val.title
defaultBeautifier = _.get(val, "properties.default_beautifier.default")
beautifiers = _.map(val.beautifiers, (b) ->
beautifier = beautifiersMap[b]
isDefault = b is defaultBeautifier
if beautifier.link
r = "[`#{b}`](#{beautifier.link})"
else
r = "`#{b}`"
if isDefault
r += " (Default)"
return r
)
grammars = _.map(val.grammars, (b) -> "`#{b}`")
extensions = _.map(val.extensions, (b) -> "`.#{b}`")
return "| #{name} | #{grammars.join(', ')} |#{extensions.join(', ')} | #{beautifiers.join(', ')} |"
)
return "| #{name} | #{grammars.join(', ')} |#{extensions.join(', ')} | #{beautifiers.join(', ')} |"
)
.value()
results = """
| Language | Grammars | File Extensions | Supported Beautifiers |
| --- | --- | --- | ---- |
@ -157,6 +164,8 @@ Handlebars.registerHelper('beautifiers-info', (beautifiers, options) ->
rows = _.map(beautifiers, (beautifier, k) ->
name = beautifier.name
isPreInstalled = beautifier.isPreInstalled
if typeof isPreInstalled is "function"
isPreInstalled = beautifier.isPreInstalled()
link = beautifier.link
installationInstructions = if isPreInstalled then "Nothing!" else "Go to #{link} and follow the instructions."
return "| #{name} | #{if isPreInstalled then ':white_check_mark:' else ':x:'} | #{installationInstructions} |"

View File

@ -124,6 +124,250 @@ Show loading view when beautifying
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*Show Loading View*" and change it to your desired configuration.
#### [Executables](#executables)
**Description**:
Configure executables used by beautifiers.
##### [autopep8](#autopep8)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for autopep8 executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*autopep8*" and change it to your desired configuration.
##### [beautysh](#beautysh)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for beautysh executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*beautysh*" and change it to your desired configuration.
##### [ClangFormat](#clangformat)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for ClangFormat executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*ClangFormat*" and change it to your desired configuration.
##### [Crystal](#crystal)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for Crystal executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*Crystal*" and change it to your desired configuration.
##### [Dfmt](#dfmt)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for Dfmt executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*Dfmt*" and change it to your desired configuration.
##### [elm-format](#elm-format)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for elm-format executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*elm-format*" and change it to your desired configuration.
##### [Emacs](#emacs)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for Emacs executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*Emacs*" and change it to your desired configuration.
##### [isort](#isort)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for isort executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*isort*" and change it to your desired configuration.
##### [PHP](#php)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for PHP executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*PHP*" and change it to your desired configuration.
##### [PHP-CS-Fixer](#php-cs-fixer)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for PHP-CS-Fixer executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*PHP-CS-Fixer*" and change it to your desired configuration.
##### [PHPCBF](#phpcbf)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for PHPCBF executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*PHPCBF*" and change it to your desired configuration.
##### [Rscript](#rscript)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for Rscript executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*Rscript*" and change it to your desired configuration.
##### [SassConvert](#sassconvert)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for SassConvert executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*SassConvert*" and change it to your desired configuration.
##### [Uncrustify](#uncrustify)
**Important**: This option is only configurable from within Atom Beautify's setting panel.
**Type**: `object`
**Description**:
Options for Uncrustify executable.
**How to Configure**
1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to
*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*.
2. Go into *Packages* and search for "*Atom Beautify*" package.
3. Find the option "*Uncrustify*" and change it to your desired configuration.
## Language Options

View File

@ -1,9 +1,9 @@
module Main (..) where
module Main exposing (..)
addThings x y =
x + y
x + y
main =
addThings 4 5
addThings 4 5

View File

@ -149,47 +149,49 @@
},
"dependencies": {
"align-yaml": "^0.1.8",
"async": "^2.0.1",
"atom-message-panel": "^1.2.4",
"atom-space-pen-views": "^2.0.5",
"bluebird": "^3.4.3",
"async": "^2.4.1",
"atom-message-panel": "^1.3.0",
"atom-space-pen-views": "^2.2.0",
"bluebird": "^3.5.0",
"coffee-fmt": "^0.12.0",
"coffee-formatter": "^0.1.2",
"coffee-script": "^1.11.0",
"csscomb": "^4.0.1",
"diff": "3.2.0",
"coffee-script": "^1.12.6",
"csscomb": "^4.2.0",
"diff": "^3.2.0",
"editorconfig": "^0.13.2",
"eslint": "^3.13.1",
"event-kit": "^2.1.0",
"eslint": "^4.0.0",
"event-kit": "^2.3.0",
"expand-home-dir": "0.0.3",
"extend": "^3.0.0",
"gherkin": "4.1.3",
"handlebars": "^4.0.2",
"js-beautify": "^1.6.3",
"extend": "^3.0.1",
"gherkin": "^2.12.2",
"handlebars": "^4.0.10",
"js-beautify": "^1.6.14",
"jscs": "^3.0.7",
"lodash": "^4.14.2",
"loophole": "^1.0.0",
"marko-prettyprint": "^1.3.5",
"nginxbeautify": "^2.0.0",
"node-cljfmt": "^0.5.3-1",
"node-dir": "^0.1.16",
"node-uuid": "^1.4.3",
"lodash": "^4.17.4",
"loophole": "^1.1.0",
"marko-prettyprint": "^1.3.6",
"nginxbeautify": "^2.0.1",
"node-cljfmt": "0.5.3",
"node-dir": "0.1.17",
"node-uuid": "1.4.8",
"open": "0.0.5",
"prettydiff": "^99.0.1",
"prettydiff": "1.16.37",
"pug-beautify": "^0.1.1",
"remark": "^7.0.1",
"season": "^6.0.0",
"space-pen": "^5.1.1",
"remark": "6.0.1",
"season": "6.0.0",
"semver": "^5.3.0",
"shell-env": "^0.3.0",
"space-pen": "5.1.2",
"strip-json-comments": "^2.0.1",
"temp": "^0.8.3",
"tidy-markdown": "2.0.5",
"typescript": "^2.3.3",
"typescript-formatter": "^5.2.0",
"tidy-markdown": "2.0.3",
"typescript": "1.8.10",
"typescript-formatter": "2.3.0",
"underscore-plus": "^1.6.6",
"universal-analytics": "^0.4.2",
"which": "^1.2.11",
"winston": "^2.2.0",
"yaml-front-matter": "^3.2.3"
"universal-analytics": "0.4.13",
"which": "1.2.14",
"winston": "2.3.1",
"yaml-front-matter": "3.4.0"
},
"activationCommands": {
"atom-workspace": [
@ -397,14 +399,38 @@
"align-yaml"
],
"devDependencies": {
"coffeelint": "^1.10.1",
"handlebars": "^4.0.2"
"coffeelint": "1.16.0"
},
"scripts": {
"build-options": "node script/build-options.js",
"docs": "npm run build-options && coffee docs/",
"prepublish": "npm run docs",
"lint": "coffeelint src/ spec/",
"code-docs": "codo && open docs/code/index.html"
"code-docs": "codo && open docs/code/index.html",
"test": "atom --test spec"
},
"config": {
"next-update": {
"skip": [
"gherkin",
"expand-home-dir",
"typescript",
"typescript-formatter",
"tidy-markdown",
"underscore-plus",
"prettydiff"
]
}
},
"greenkeeper": {
"ignore": [
"gherkin",
"expand-home-dir",
"typescript",
"typescript-formatter",
"tidy-markdown",
"underscore-plus",
"prettydiff"
]
}
}
}

View File

@ -172,6 +172,53 @@ buildOptionsForBeautifiers = function(beautifiers, allLanguages) {
return flatOptions;
};
buildOptionsForExecutables = function(beautifiers) {
executables = _.chain(beautifiers)
.map((beautifier) => {
const executables = beautifier.executables || [];
executables.forEach((executable) => executable.beautifiers = [beautifier.name]);
return executables;
})
.flatten()
.value();
const properties = {}
_.forEach(executables, (executable) => {
const { name, cmd, beautifiers } = executable;
const key = cmd;
const option = {
key: key,
title: name,
type: "object",
collapsed: true,
description: `Options for ${name} executable.`,
// beautifiers,
properties: {
path: {
key: "path",
title: "Binary/Script Path",
type: "string",
default: "",
description: `Absolute path to the "${cmd}" executable's binary/script.`,
}
}
}
properties[key] = option;
});
const options = {
executables: {
title: 'Executables',
type: 'object',
collapsed: true,
order: -1,
description: 'Configure executables used by beautifiers.',
properties
}
}
return options
};
buildOptionsForBeautifiers = function(beautifiers, allLanguages) {
var beautifier, beautifierName, defaultBeautifier, f, fallback, field, fields, fn, g, group, i, j, k, l, laOp, lang, langName, langOptions, languageName, languages, len, len1, len2, len3, len4, len5, m, n, name, name1, namespace, namespaceDest, namespaceSrc, o, op, optionDef, optionName, options, optionsDest, optionsSrc, p, q, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, unsupportedOptions;
langOptions = {};
@ -374,10 +421,11 @@ beautifier = new Beautifiers();
console.log('Building options for beautifiers');
beautifierOptions = buildOptionsForBeautifiers(beautifier.beautifiers, beautifier.languages.languages);
executableOptions = buildOptionsForExecutables(beautifier.beautifiers)
console.log('Done building options for beautifiers');
optionsStr = JSON.stringify(beautifierOptions, null, 2);
combinedOptions = Object.assign({}, beautifierOptions, executableOptions)
optionsStr = JSON.stringify(combinedOptions, null, 2);
outputFilename = path.resolve(__dirname, '../src/options.json');

View File

@ -1,4 +1,5 @@
Beautifiers = require "../src/beautifiers"
Executable = require "../src/beautifiers/executable"
beautifiers = new Beautifiers()
Beautifier = require "../src/beautifiers/beautifier"
Languages = require('../src/languages/')
@ -30,7 +31,7 @@ describe "Atom-Beautify", ->
pack = atom.packages.getLoadedPackage("atom-beautify")
pack.activateNow()
# Change logger level
# atom.config.set('atom-beautify._loggerLevel', 'verbose')
atom.config.set('atom-beautify.general.loggerLevel', 'info')
# Return promise
return activationPromise
@ -124,7 +125,7 @@ describe "Atom-Beautify", ->
pathOption: "Lang - Test Program Path"
}
# Force to be Windows
beautifier.isWindows = true
Executable.isWindows = () ->true
terminal = 'CMD prompt'
whichCmd = "where.exe"
# Process
@ -132,7 +133,7 @@ describe "Atom-Beautify", ->
expect(p).not.toBe(null)
expect(p instanceof beautifier.Promise).toBe(true)
cb = (v) ->
# console.log(v)
console.log("error", v, v.description)
expect(v).not.toBe(null)
expect(v instanceof Error).toBe(true)
expect(v.code).toBe("CommandNotFound")
@ -167,7 +168,7 @@ describe "Atom-Beautify", ->
pathOption: "Lang - Test Program Path"
}
# Force to be Mac/Linux (not Windows)
beautifier.isWindows = false
Executable.isWindows = () ->false
terminal = "Terminal"
whichCmd = "which"
# Process

View File

@ -1,5 +1,6 @@
PHPCSFixer = require "../src/beautifiers/php-cs-fixer"
Beautifier = require "../src/beautifiers/beautifier"
Executable = require "../src/beautifiers/executable"
path = require 'path'
# Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs.
@ -23,17 +24,22 @@ describe "PHP-CS-Fixer Beautifier", ->
pack = atom.packages.getLoadedPackage("atom-beautify")
pack.activateNow()
# Change logger level
# atom.config.set('atom-beautify._loggerLevel', 'verbose')
atom.config.set('atom-beautify.general.loggerLevel', 'info')
# Return promise
return activationPromise
describe "Beautifier::beautify", ->
beautifier = null
execSpawn = null
beforeEach ->
beautifier = new PHPCSFixer()
# console.log('new beautifier')
execSpawn = Executable.prototype.spawn
afterEach ->
Executable.prototype.spawn = execSpawn
OSSpecificSpecs = ->
text = "<?php echo \"test\"; ?>"
@ -49,13 +55,14 @@ describe "PHP-CS-Fixer Beautifier", ->
levels: ""
}
# Mock spawn
beautifier.spawn = (exe, args, options) ->
# beautifier.spawn
Executable.prototype.spawn = (exe, args, options) ->
# console.log('spawn', exe, args, options)
er = new Error('ENOENT')
er.code = 'ENOENT'
return beautifier.Promise.reject(er)
# Beautify
p = beautifier.beautify(text, language, options)
p = beautifier.loadExecutables().then(() -> beautifier.beautify(text, language, options))
expect(p).not.toBe(null)
expect(p instanceof beautifier.Promise).toBe(true)
cb = (v) ->
@ -74,7 +81,7 @@ describe "PHP-CS-Fixer Beautifier", ->
expect(beautifier).not.toBe(null)
expect(beautifier instanceof Beautifier).toBe(true)
if not beautifier.isWindows and failingProgram is "php"
if not Executable.isWindows and failingProgram is "php"
# Only applicable on Windows
return
@ -104,8 +111,9 @@ describe "PHP-CS-Fixer Beautifier", ->
# console.log('fake exe path', exe)
beautifier.Promise.resolve("/#{exe}")
oldSpawn = beautifier.spawn.bind(beautifier)
beautifier.spawn = (exe, args, options) ->
# oldSpawn = beautifier.spawn.bind(beautifier)
# beautifier.spawn
Executable.prototype.spawn = (exe, args, options) ->
# console.log('spawn', exe, args, options)
if exe is failingProgram
er = new Error('ENOENT')
@ -117,21 +125,21 @@ describe "PHP-CS-Fixer Beautifier", ->
stdout: 'stdout',
stderr: ''
})
p = beautifier.beautify(text, language, options)
p = beautifier.loadExecutables().then(() -> beautifier.beautify(text, language, options))
expect(p).not.toBe(null)
expect(p instanceof beautifier.Promise).toBe(true)
p.then(cb, cb)
return p
# failWhichProgram('php')
failWhichProgram('php-cs-fixer')
failWhichProgram('PHP')
# failWhichProgram('php-cs-fixer')
unless isWindows
describe "Mac/Linux", ->
beforeEach ->
# console.log('mac/linx')
beautifier.isWindows = false
Executable.isWindows = () -> false
do OSSpecificSpecs
@ -139,6 +147,6 @@ describe "PHP-CS-Fixer Beautifier", ->
beforeEach ->
# console.log('windows')
beautifier.isWindows = true
Executable.isWindows = () -> true
do OSSpecificSpecs

View File

@ -15,6 +15,25 @@ isWindows = process.platform is 'win32' or
process.env.OSTYPE is 'cygwin' or
process.env.OSTYPE is 'msys'
unsupportedLangs = {
all: [
]
windows: [
"ocaml"
"r"
"clojure"
# Broken
"apex"
"bash"
"csharp"
"d"
"elm"
"java"
"objectivec"
"opencl"
]
}
describe "BeautifyLanguages", ->
optionsDir = path.resolve(__dirname, "../examples")
@ -53,9 +72,8 @@ describe "BeautifyLanguages", ->
pack = atom.packages.getLoadedPackage("atom-beautify")
pack.activateNow()
# Need more debugging on Windows
if isWindows
# Change logger level
atom.config.set('atom-beautify._loggerLevel', 'verbose')
# Change logger level
atom.config.set('atom-beautify.general.loggerLevel', 'info')
# Return promise
return activationPromise
@ -95,9 +113,12 @@ describe "BeautifyLanguages", ->
langNames = fs.readdirSync(langsDir)
for lang in langNames
# FIXME: Skip testing ocaml in Windows
if isWindows && lang == 'ocaml'
continue
shouldSkipLang = false
if unsupportedLangs.all.indexOf(lang) isnt -1
shouldSkipLang = true
if isWindows and unsupportedLangs.windows.indexOf(lang) isnt -1
console.warn("Tests for Windows do not support #{lang}")
shouldSkipLang = true
do (lang) ->
# Generate the path to where al of the tests are
@ -119,7 +140,7 @@ describe "BeautifyLanguages", ->
fs.mkdirSync(expectedDir)
# Language group tests
describe "when beautifying language '#{lang}'", ->
describe "#{if shouldSkipLang then '#' else ''}when beautifying language '#{lang}'", ->
# All tests for language
testNames = fs.readdirSync(originalDir)
@ -128,11 +149,12 @@ describe "BeautifyLanguages", ->
ext = path.extname(testFileName)
testName = path.basename(testFileName, ext)
# If prefixed with underscore (_) then this is a hidden test
shouldSkip = false
if testFileName[0] is '_'
# Do not show this test
return
shouldSkip = true
# Confirm this is a test
it "#{testName} #{testFileName}", ->
it "#{if shouldSkip then '# ' else ''}#{testName} #{testFileName}", ->
# Generate paths to test files
originalTestPath = path.resolve(originalDir, testFileName)
@ -162,7 +184,7 @@ describe "BeautifyLanguages", ->
beautifyCompleted = false
completionFun = (text) ->
try
expect(text instanceof Error).not.toEqual(true, text)
expect(text instanceof Error).not.toEqual(true, text.message or text.toString())
return beautifyCompleted = true if text instanceof Error
# logger.verbose(expectedTestPath, text) if ext is ".less"
# if text instanceof Error

View File

@ -9,36 +9,59 @@ module.exports = class Autopep8 extends Beautifier
name: "autopep8"
link: "https://github.com/hhatto/autopep8"
isPreInstalled: false
executables: [
{
name: "autopep8"
cmd: "autopep8"
homepage: "https://github.com/hhatto/autopep8"
installation: "https://github.com/hhatto/autopep8#installation"
version: {
parse: (text) -> text.match(/autopep8 (\d+\.\d+\.\d+)/)[1]
runOptions: {
returnStderr: true
}
}
docker: {
image: "unibeautify/autopep8"
}
}
{
name: "isort"
cmd: "isort"
optional: true
homepage: "https://github.com/timothycrosley/isort"
installation: "https://github.com/timothycrosley/isort#installing-isort"
version: {
parse: (text) -> text.match(/VERSION (\d+\.\d+\.\d+)/)[1]
}
}
]
options: {
Python: true
}
beautify: (text, language, options) ->
@run("autopep8", [
tempFile = @tempFile("input", text)
"-i"
["--max-line-length", "#{options.max_line_length}"] if options.max_line_length?
["--indent-size","#{options.indent_size}"] if options.indent_size?
["--ignore","#{options.ignore.join(',')}"] if options.ignore?
], help: {
link: "https://github.com/hhatto/autopep8"
})
@exe("autopep8").run([
tempFile = @tempFile("input", text)
"-i"
["--max-line-length", "#{options.max_line_length}"] if options.max_line_length?
["--indent-size","#{options.indent_size}"] if options.indent_size?
["--ignore","#{options.ignore.join(',')}"] if options.ignore?
])
.then(=>
if options.sort_imports
editor = atom.workspace.getActiveTextEditor()
filePath = editor.getPath()
projectPath = atom.project.relativizePath(filePath)[0]
@run("isort",
["-sp", projectPath, tempFile],
help: {
link: "https://github.com/timothycrosley/isort"
})
.then(=>
@readFile(tempFile)
)
@exe("isort")
.run(
["-sp", projectPath, tempFile],
)
.then(=>
@readFile(tempFile)
)
else
@readFile(tempFile)
)

View File

@ -4,8 +4,9 @@ fs = require('fs')
temp = require('temp').track()
readFile = Promise.promisify(fs.readFile)
which = require('which')
spawn = require('child_process').spawn
path = require('path')
shellEnv = require('shell-env')
Executable = require('./executable')
module.exports = class Beautifier
@ -31,10 +32,49 @@ module.exports = class Beautifier
###
options: {}
executables: []
###
Is the beautifier a command-line interface beautifier?
###
isPreInstalled: true
isPreInstalled: () ->
@executables.length is 0
_exe: {}
loadExecutables: () ->
@debug("Load executables")
if Object.keys(@_exe).length is @executables.length
Promise.resolve(@_exe)
else
Promise.resolve(executables = @executables.map((e) -> new Executable(e)))
.then((executables) -> Promise.all(executables.map((exe) -> exe.init())))
.then((es) =>
@debug("Executables loaded", es)
exe = {}
missingInstalls = []
es.forEach((e) ->
exe[e.cmd] = e
if not e.isInstalled and e.required
missingInstalls.push(e)
)
@_exe = exe
@debug("exe", exe)
if missingInstalls.length is 0
return @_exe
else
@debug("Missing required executables: #{missingInstalls.map((e) -> e.cmd).join(' and ')}.")
throw Executable.commandNotFoundError(missingInstalls[0].cmd)
)
.catch((error) =>
@debug("Error loading executables", error)
Promise.reject(error)
)
exe: (cmd) ->
console.log('exe', cmd, @_exe)
e = @_exe[cmd]
if !e?
throw Executable.commandNotFoundError(cmd)
e
###
Supported languages by this Beautifier
@ -102,7 +142,7 @@ module.exports = class Beautifier
startDir.pop()
return null
# Retrieves the default line ending based upon the Atom configuration
# Retrieves the default line ending based upon the Atom configuration
# `line-ending-selector.defaultLineEnding`. If the Atom configuration
# indicates "OS Default", the `process.platform` is queried, returning
# CRLF for Windows systems and LF for all other systems.
@ -124,64 +164,6 @@ module.exports = class Beautifier
else
return lf
###
If platform is Windows
###
isWindows: do ->
return new RegExp('^win').test(process.platform)
###
Get Shell Environment variables
Special thank you to @ioquatix
See https://github.com/ioquatix/script-runner/blob/v1.5.0/lib/script-runner.coffee#L45-L63
###
_envCache: null
_envCacheDate: null
_envCacheExpiry: 10000 # 10 seconds
getShellEnvironment: ->
return new Promise((resolve, reject) =>
# Check Cache
if @_envCache? and @_envCacheDate?
# Check if Cache is old
if (new Date() - @_envCacheDate) < @_envCacheExpiry
# Still fresh
return resolve(@_envCache)
# Check if Windows
if @isWindows
# Windows
# Use default
resolve(process.env)
else
# Mac & Linux
# I tried using ChildProcess.execFile but there is no way to set detached and
# this causes the child shell to lock up.
# This command runs an interactive login shell and
# executes the export command to get a list of environment variables.
# We then use these to run the script:
child = spawn process.env.SHELL, ['-ilc', 'env'],
# This is essential for interactive shells, otherwise it never finishes:
detached: true,
# We don't care about stdin, stderr can go out the usual way:
stdio: ['ignore', 'pipe', process.stderr]
# We buffer stdout:
buffer = ''
child.stdout.on 'data', (data) -> buffer += data
# When the process finishes, extract the environment variables and pass them to the callback:
child.on 'close', (code, signal) =>
if code isnt 0
return reject(new Error("Could not get Shell Environment. Exit code: "+code+", Signal: "+signal))
environment = {}
for definition in buffer.split('\n')
[key, value] = definition.split('=', 2)
environment[key] = value if key != ''
# Cache Environment
@_envCache = environment
@_envCacheDate = new Date()
resolve(environment)
)
###
Like the unix which utility.
@ -191,182 +173,21 @@ module.exports = class Beautifier
See https://github.com/isaacs/node-which
###
which: (exe, options = {}) ->
# Get PATH and other environment variables
@getShellEnvironment()
.then((env) =>
new Promise((resolve, reject) =>
options.path ?= env.PATH
if @isWindows
# Environment variables are case-insensitive in windows
# Check env for a case-insensitive 'path' variable
if !options.path
for i of env
if i.toLowerCase() is "path"
options.path = env[i]
break
# Trick node-which into including files
# with no extension as executables.
# Put empty extension last to allow for other real extensions first
options.pathExt ?= "#{process.env.PATHEXT ? '.EXE'};"
which(exe, options, (err, path) ->
resolve(exe) if err
resolve(path)
)
)
)
###
Add help to error.description
Note: error.description is not officially used in JavaScript,
however it is used internally for Atom Beautify when displaying errors.
###
commandNotFoundError: (exe, help) ->
# Create new improved error
# notify user that it may not be
# installed or in path
message = "Could not find '#{exe}'. \
The program may not be installed."
er = new Error(message)
er.code = 'CommandNotFound'
er.errno = er.code
er.syscall = 'beautifier::run'
er.file = exe
if help?
if typeof help is "object"
# Basic notice
helpStr = "See #{help.link} for program \
installation instructions.\n"
# Help to configure Atom Beautify for program's path
helpStr += "You can configure Atom Beautify \
with the absolute path \
to '#{help.program or exe}' by setting \
'#{help.pathOption}' in \
the Atom Beautify package settings.\n" if help.pathOption
# Optional, additional help
helpStr += help.additional if help.additional
# Common Help
issueSearchLink =
"https://github.com/Glavin001/atom-beautify/\
search?q=#{exe}&type=Issues"
docsLink = "https://github.com/Glavin001/\
atom-beautify/tree/master/docs"
helpStr += "Your program is properly installed if running \
'#{if @isWindows then 'where.exe' \
else 'which'} #{exe}' \
in your #{if @isWindows then 'CMD prompt' \
else 'Terminal'} \
returns an absolute path to the executable. \
If this does not work then you have not \
installed the program correctly and so \
Atom Beautify will not find the program. \
Atom Beautify requires that the program be \
found in your PATH environment variable. \n\
Note that this is not an Atom Beautify issue \
if beautification does not work and the above \
command also does not work: this is expected \
behaviour, since you have not properly installed \
your program. Please properly setup the program \
and search through existing Atom Beautify issues \
before creating a new issue. \
See #{issueSearchLink} for related Issues and \
#{docsLink} for documentation. \
If you are still unable to resolve this issue on \
your own then please create a new issue and \
ask for help.\n"
er.description = helpStr
else #if typeof help is "string"
er.description = help
return er
# @deprecate("Beautifier.which function has been deprecated. Please use Executables.")
Executable.which(exe, options)
###
Run command-line interface command
###
run: (executable, args, {cwd, ignoreReturnCode, help, onStdin} = {}) ->
# Flatten args first
args = _.flatten(args)
# Resolve executable and all args
Promise.all([executable, Promise.all(args)])
.then(([exeName, args]) =>
@debug('exeName, args:', exeName, args)
# Get PATH and other environment variables
Promise.all([exeName, args, @getShellEnvironment(), @which(exeName)])
)
.then(([exeName, args, env, exePath]) =>
@debug('exePath, env:', exePath, env)
@debug('args', args)
exe = exePath ? exeName
options = {
cwd: cwd
env: env
}
@spawn(exe, args, options, onStdin)
.then(({returnCode, stdout, stderr}) =>
@verbose('spawn result', returnCode, stdout, stderr)
# If return code is not 0 then error occured
if not ignoreReturnCode and returnCode isnt 0
# operable program or batch file
windowsProgramNotFoundMsg = "is not recognized as an internal or external command"
@verbose(stderr, windowsProgramNotFoundMsg)
if @isWindows and returnCode is 1 and stderr.indexOf(windowsProgramNotFoundMsg) isnt -1
throw @commandNotFoundError(exeName, help)
else
throw new Error(stderr)
else
stdout
)
.catch((err) =>
@debug('error', err)
# Check if error is ENOENT (command could not be found)
if err.code is 'ENOENT' or err.errno is 'ENOENT'
throw @commandNotFoundError(exeName, help)
else
# continue as normal error
throw err
)
)
###
Spawn
###
spawn: (exe, args, options, onStdin) ->
# Remove undefined/null values
args = _.without(args, undefined)
args = _.without(args, null)
return new Promise((resolve, reject) =>
@debug('spawn', exe, args)
cmd = spawn(exe, args, options)
stdout = ""
stderr = ""
cmd.stdout.on('data', (data) ->
stdout += data
)
cmd.stderr.on('data', (data) ->
stderr += data
)
cmd.on('close', (returnCode) =>
@debug('spawn done', returnCode, stderr, stdout)
resolve({returnCode, stdout, stderr})
)
cmd.on('error', (err) =>
@debug('error', err)
reject(err)
)
onStdin cmd.stdin if onStdin
)
# @deprecate("Beautifier.run function has been deprecated. Please use Executables.")
exe = new Executable({
name: @name
homepage: @link
installation: @link
cmd: executable
})
exe.run(args, {cwd, ignoreReturnCode, help, onStdin})
###
Logger instance

View File

@ -4,7 +4,22 @@ Beautifier = require('./beautifier')
module.exports = class BashBeautify extends Beautifier
name: "beautysh"
link: "https://github.com/bemeurer/beautysh"
isPreInstalled: false
executables: [
{
name: "beautysh"
cmd: "beautysh"
homepage: "https://github.com/bemeurer/beautysh"
installation: "https://github.com/bemeurer/beautysh#installation"
version: {
# Does not display version
args: ['--help'],
parse: (text) -> text.indexOf("usage: beautysh") isnt -1 and "0.0.0"
}
docker: {
image: "unibeautify/beautysh"
}
}
]
options: {
Bash:
@ -12,6 +27,7 @@ module.exports = class BashBeautify extends Beautifier
}
beautify: (text, language, options) ->
beautysh = @exe("beautysh")
file = @tempFile("input", text)
@run('beautysh', [ '-i', options.indent_size, '-f', file ], help: { link: "https://github.com/bemeurer/beautysh" })
.then(=> @readFile file)
beautysh.run([ '-i', options.indent_size, '-f', file ])
.then(=> @readFile file)

View File

@ -11,7 +11,20 @@ module.exports = class ClangFormat extends Beautifier
name: "clang-format"
link: "https://clang.llvm.org/docs/ClangFormat.html"
isPreInstalled: false
executables: [
{
name: "ClangFormat"
cmd: "clang-format"
homepage: "https://clang.llvm.org/docs/ClangFormat.html"
installation: "https://clang.llvm.org/docs/ClangFormat.html"
version: {
parse: (text) -> text.match(/version (\d+\.\d+\.\d+)/)[1]
}
docker: {
image: "unibeautify/clang-format"
}
}
]
options: {
"C++": false
@ -64,12 +77,10 @@ module.exports = class ClangFormat extends Beautifier
)
.then((dumpFile) =>
# console.log("clang-format", dumpFile)
return @run("clang-format", [
return @exe("clang-format").run([
@dumpToFile(dumpFile, text)
["--style=file"]
], help: {
link: "https://clang.llvm.org/docs/ClangFormat.html"
}).finally( ->
]).finally( ->
fs.unlink(dumpFile)
)
)

View File

@ -8,28 +8,31 @@ Beautifier = require('./beautifier')
module.exports = class Crystal extends Beautifier
name: "Crystal"
link: "http://crystal-lang.org"
isPreInstalled: false
executables: [
{
name: "Crystal"
cmd: "crystal"
homepage: "http://crystal-lang.org"
installation: "https://crystal-lang.org/docs/installation/"
version: {
parse: (text) -> text.match(/Crystal (\d+\.\d+\.\d+)/)[1]
}
docker: {
image: "unibeautify/crystal"
}
}
]
options: {
Crystal: false
}
beautify: (text, language, options) ->
# Seems that Crystal dosen't have Windows support yet.
if @isWindows
@Promise.reject(@commandNotFoundError(
'crystal'
{
link: "http://crystal-lang.org"
program: "crystal"
})
@exe("crystal").run([
'tool',
'format',
tempFile = @tempFile("temp", text)
], {ignoreReturnCode: true})
.then(=>
@readFile(tempFile)
)
else
@run("crystal", [
'tool',
'format',
tempFile = @tempFile("temp", text)
], {ignoreReturnCode: true})
.then(=>
@readFile(tempFile)
)

View File

@ -7,13 +7,20 @@ Beautifier = require('./beautifier')
module.exports = class Dfmt extends Beautifier
name: "dfmt"
link: "https://github.com/Hackerpilot/dfmt"
isPreInstalled: false
executables: [
{
name: "Dfmt"
cmd: "dfmt"
homepage: "https://github.com/Hackerpilot/dfmt"
installation: "https://github.com/dlang-community/dfmt#building"
}
]
options: {
D: false
}
beautify: (text, language, options) ->
@run("dfmt", [
@exe("dfmt").run([
@tempFile("input", text)
])

View File

@ -7,7 +7,25 @@ Beautifier = require('./beautifier')
module.exports = class ElmFormat extends Beautifier
name: "elm-format"
link: "https://github.com/avh4/elm-format"
isPreInstalled: false
executables: [
{
name: "elm-format"
cmd: "elm-format"
homepage: "https://github.com/avh4/elm-format"
installation: "https://github.com/avh4/elm-format#installation-"
version: {
args: ['--help']
parse: (text) ->
try
return text.match(/elm-format-\d+.\d+ (\d+\.\d+\.\d+)/)[1]
catch
return text.match(/elm-format (\d+\.\d+\.\d+)/)[1]
}
docker: {
image: "unibeautify/elm-format"
}
}
]
options: {
Elm: true
@ -16,11 +34,10 @@ module.exports = class ElmFormat extends Beautifier
beautify: (text, language, options) ->
tempfile = @tempFile("input", text, ".elm")
.then (name) =>
@run("elm-format", [
'--yes',
name
],
{ help: { link: 'https://github.com/avh4/elm-format#installation-' } }
)
.then () =>
@readFile(name)
@exe("elm-format")
.run([
'--yes',
name
])
.then () =>
@readFile(name)

View File

@ -0,0 +1,453 @@
Promise = require('bluebird')
_ = require('lodash')
which = require('which')
spawn = require('child_process').spawn
path = require('path')
semver = require('semver')
shellEnv = require('shell-env')
os = require('os')
fs = require('fs')
parentConfigKey = "atom-beautify.executables"
class Executable
name: null
cmd: null
key: null
homepage: null
installation: null
versionArgs: ['--version']
versionParse: (text) -> semver.clean(text)
versionRunOptions: {}
versionsSupported: '>= 0.0.0'
required: true
constructor: (options) ->
# Validation
if !options.cmd?
throw new Error("The command (i.e. cmd property) is required for an Executable.")
@name = options.name
@cmd = options.cmd
@key = @cmd
@homepage = options.homepage
@installation = options.installation
@required = not options.optional
if options.version?
versionOptions = options.version
@versionArgs = versionOptions.args if versionOptions.args
@versionParse = versionOptions.parse if versionOptions.parse
@versionRunOptions = versionOptions.runOptions if versionOptions.runOptions
@versionsSupported = versionOptions.supported if versionOptions.supported
@setupLogger()
init: () ->
Promise.all([
@loadVersion()
])
.then(() => @verbose("Done init of #{@name}"))
.then(() => @)
.catch((error) =>
if not @.required
@
else
Promise.reject(error)
)
###
Logger instance
###
logger: null
###
Initialize and configure Logger
###
setupLogger: ->
@logger = require('../logger')("#{@name} Executable")
for key, method of @logger
@[key] = method
@verbose("#{@name} executable logger has been initialized.")
isInstalled = null
version = null
loadVersion: (force = false) ->
@verbose("loadVersion", @version, force)
if force or !@version?
@verbose("Loading version without cache")
@runVersion()
.then((text) => @saveVersion(text))
else
@verbose("Loading cached version")
Promise.resolve(@version)
runVersion: () ->
@run(@versionArgs, @versionRunOptions)
.then((version) =>
@info("Version text: " + version)
version
)
saveVersion: (text) ->
Promise.resolve()
.then( => @versionParse(text))
.then((version) ->
valid = Boolean(semver.valid(version))
if not valid
throw new Error("Version is not valid: "+version)
version
)
.then((version) =>
@isInstalled = true
@version = version
)
.then((version) =>
@info("#{@cmd} version: #{version}")
version
)
.catch((error) =>
@isInstalled = false
@error(error)
help = {
program: @cmd
link: @installation or @homepage
pathOption: "Executable - #{@name or @cmd} - Path"
}
Promise.reject(@commandNotFoundError(@name or @cmd, help))
)
isSupported: () ->
@isVersion(@versionsSupported)
isVersion: (range) ->
semver.satisfies(@version, range)
getConfig: () ->
atom?.config.get("#{parentConfigKey}.#{@key}") or {}
###
Run command-line interface command
###
run: (args, options = {}) ->
@debug("Run: ", @cmd, args, options)
{ cwd, ignoreReturnCode, help, onStdin, returnStderr } = options
exeName = @cmd
config = @getConfig()
cwd ?= os.tmpDir()
# Resolve executable and all args
Promise.all([@shellEnv(), this.resolveArgs(args)])
.then(([env, args]) =>
@debug('exeName, args:', exeName, args)
# Get PATH and other environment variables
if config and config.path
exePath = config.path
else
exePath = @which(exeName)
Promise.all([exeName, args, env, exePath])
)
.then(([exeName, args, env, exePath]) =>
@debug('exePath:', exePath)
@debug('env:', env)
@debug('PATH:', env.PATH)
@debug('args', args)
args = this.relativizePaths(args)
@debug('relativized args', args)
exe = exePath ? exeName
spawnOptions = {
cwd: cwd
env: env
}
@debug('spawnOptions', spawnOptions)
@spawn(exe, args, spawnOptions, onStdin)
.then(({returnCode, stdout, stderr}) =>
@verbose('spawn result, returnCode', returnCode)
@verbose('spawn result, stdout', stdout)
@verbose('spawn result, stderr', stderr)
# If return code is not 0 then error occured
if not ignoreReturnCode and returnCode isnt 0
# operable program or batch file
windowsProgramNotFoundMsg = "is not recognized as an internal or external command"
@verbose(stderr, windowsProgramNotFoundMsg)
if @isWindows() and returnCode is 1 and stderr.indexOf(windowsProgramNotFoundMsg) isnt -1
throw @commandNotFoundError(exeName, help)
else
throw new Error(stderr or stdout)
else
if returnStderr
stderr
else
stdout
)
.catch((err) =>
@debug('error', err)
# Check if error is ENOENT (command could not be found)
if err.code is 'ENOENT' or err.errno is 'ENOENT'
throw @commandNotFoundError(exeName, help)
else
# continue as normal error
throw err
)
)
resolveArgs: (args) ->
args = _.flatten(args)
Promise.all(args)
relativizePaths: (args) ->
tmpDir = os.tmpDir()
newArgs = args.map((arg) ->
isTmpFile = (typeof arg is 'string' and not arg.includes(':') and \
path.isAbsolute(arg) and path.dirname(arg).startsWith(tmpDir))
if isTmpFile
return path.relative(tmpDir, arg)
return arg
)
newArgs
###
Spawn
###
spawn: (exe, args, options, onStdin) ->
# Remove undefined/null values
args = _.without(args, undefined)
args = _.without(args, null)
return new Promise((resolve, reject) =>
@debug('spawn', exe, args)
cmd = spawn(exe, args, options)
stdout = ""
stderr = ""
cmd.stdout.on('data', (data) ->
stdout += data
)
cmd.stderr.on('data', (data) ->
stderr += data
)
cmd.on('close', (returnCode) =>
@debug('spawn done', returnCode, stderr, stdout)
resolve({returnCode, stdout, stderr})
)
cmd.on('error', (err) =>
@debug('error', err)
reject(err)
)
onStdin cmd.stdin if onStdin
)
###
Add help to error.description
Note: error.description is not officially used in JavaScript,
however it is used internally for Atom Beautify when displaying errors.
###
commandNotFoundError: (exe, help) ->
exe ?= @name or @cmd
@constructor.commandNotFoundError(exe, help)
@commandNotFoundError: (exe, help) ->
# Create new improved error
# notify user that it may not be
# installed or in path
message = "Could not find '#{exe}'. \
The program may not be installed."
er = new Error(message)
er.code = 'CommandNotFound'
er.errno = er.code
er.syscall = 'beautifier::run'
er.file = exe
if help?
if typeof help is "object"
# Basic notice
helpStr = "See #{help.link} for program \
installation instructions.\n"
# Help to configure Atom Beautify for program's path
helpStr += "You can configure Atom Beautify \
with the absolute path \
to '#{help.program or exe}' by setting \
'#{help.pathOption}' in \
the Atom Beautify package settings.\n" if help.pathOption
# Optional, additional help
helpStr += help.additional if help.additional
# Common Help
issueSearchLink =
"https://github.com/Glavin001/atom-beautify/\
search?q=#{exe}&type=Issues"
docsLink = "https://github.com/Glavin001/\
atom-beautify/tree/master/docs"
helpStr += "Your program is properly installed if running \
'#{if @isWindows() then 'where.exe' \
else 'which'} #{exe}' \
in your #{if @isWindows() then 'CMD prompt' \
else 'Terminal'} \
returns an absolute path to the executable. \
If this does not work then you have not \
installed the program correctly and so \
Atom Beautify will not find the program. \
Atom Beautify requires that the program be \
found in your PATH environment variable. \n\
Note that this is not an Atom Beautify issue \
if beautification does not work and the above \
command also does not work: this is expected \
behaviour, since you have not properly installed \
your program. Please properly setup the program \
and search through existing Atom Beautify issues \
before creating a new issue. \
See #{issueSearchLink} for related Issues and \
#{docsLink} for documentation. \
If you are still unable to resolve this issue on \
your own then please create a new issue and \
ask for help.\n"
er.description = helpStr
else #if typeof help is "string"
er.description = help
return er
@_envCache = null
shellEnv: () ->
@constructor.shellEnv()
@shellEnv: () ->
if @_envCache
return Promise.resolve(@_envCache)
else
shellEnv()
.then((env) =>
@_envCache = env
)
###
Like the unix which utility.
Finds the first instance of a specified executable in the PATH environment variable.
Does not cache the results,
so hash -r is not needed when the PATH changes.
See https://github.com/isaacs/node-which
###
which: (exe, options) ->
@.constructor.which(exe, options)
@_whichCache = {}
@which: (exe, options = {}) ->
if @_whichCache[exe]
return Promise.resolve(@_whichCache[exe])
# Get PATH and other environment variables
@shellEnv()
.then((env) =>
new Promise((resolve, reject) =>
options.path ?= env.PATH
if @isWindows()
# Environment variables are case-insensitive in windows
# Check env for a case-insensitive 'path' variable
if !options.path
for i of env
if i.toLowerCase() is "path"
options.path = env[i]
break
# Trick node-which into including files
# with no extension as executables.
# Put empty extension last to allow for other real extensions first
options.pathExt ?= "#{process.env.PATHEXT ? '.EXE'};"
which(exe, options, (err, path) =>
return resolve(exe) if err
@_whichCache[exe] = path
resolve(path)
)
)
)
###
If platform is Windows
###
isWindows: () -> @constructor.isWindows()
@isWindows: () -> new RegExp('^win').test(process.platform)
class HybridExecutable extends Executable
dockerOptions: {
image: undefined
workingDir: "/workdir"
}
constructor: (options) ->
super(options)
if options.docker?
@dockerOptions = Object.assign({}, @dockerOptions, options.docker)
@docker = @constructor.dockerExecutable()
@docker: undefined
@dockerExecutable: () ->
if not @docker?
@docker = new Executable({
name: "Docker"
cmd: "docker"
homepage: "https://www.docker.com/"
installation: "https://www.docker.com/get-docker"
version: {
parse: (text) -> text.match(/version [0]*([1-9]\d*).[0]*([1-9]\d*).[0]*([1-9]\d*)/).slice(1).join('.')
}
})
return @docker
installedWithDocker: false
init: () ->
super()
.catch((error) =>
return Promise.reject(error) if not @docker?
@docker.init()
.then(=> @runImage(@versionArgs, @versionRunOptions))
.then((text) => @saveVersion(text))
.then(() => @installedWithDocker = true)
.then(=> @)
.catch((dockerError) =>
@debug(dockerError)
Promise.reject(error)
)
)
run: (args, options = {}) ->
if @installedWithDocker and @docker and @docker.isInstalled
return @runImage(args, options)
super(args, options)
runImage: (args, options) ->
@debug("Run Docker executable: ", args, options)
this.resolveArgs(args)
.then((args) =>
{ cwd } = options
tmpDir = os.tmpDir()
pwd = fs.realpathSync(cwd or tmpDir)
image = @dockerOptions.image
workingDir = @dockerOptions.workingDir
rootPath = '/mountedRoot'
newArgs = args.map((arg) ->
if (typeof arg is 'string' and not arg.includes(':') \
and path.isAbsolute(arg) and not path.dirname(arg).startsWith(tmpDir))
then path.join(rootPath, arg) else arg
)
@docker.run([
"run",
"--volume", "#{pwd}:#{workingDir}",
"--volume", "#{path.resolve('/')}:#{rootPath}",
"--workdir", workingDir,
image,
newArgs
],
options
)
)
module.exports = HybridExecutable

View File

@ -9,18 +9,33 @@ Beautifier = require('../beautifier')
module.exports = class R extends Beautifier
name: "formatR"
link: "https://github.com/yihui/formatR"
isPreInstalled: false
executables: [
{
name: "Rscript"
cmd: "rscript"
homepage: "https://github.com/yihui/formatR"
installation: "https://github.com/yihui/formatR"
version: {
parse: (text) -> text.match(/version (\d+\.\d+\.\d+) /)[1]
runOptions: {
returnStderr: true
}
}
docker: {
image: "unibeautify/rscript"
}
}
]
options: {
R: true
}
beautify: (text, language, options) ->
rscript = @exe("rscript")
r_beautifier = path.resolve(__dirname, "formatR.r")
@run("Rscript", [
rscript.run([
r_beautifier,
options.indent_size,
@tempFile("input", text),
'>',
@tempFile("input", text)
])
])

View File

@ -9,7 +9,17 @@ path = require("path")
module.exports = class FortranBeautifier extends Beautifier
name: "Fortran Beautifier"
link: "https://www.gnu.org/software/emacs/"
isPreInstalled: false
executables: [
{
name: "Emacs"
cmd: "emacs"
homepage: "https://www.gnu.org/software/emacs/"
installation: "https://www.gnu.org/software/emacs/"
version: {
parse: (text) -> text.match(/Emacs (\d+\.\d+\.\d+)/)[1]
}
}
]
options: {
Fortran: true
@ -17,6 +27,7 @@ module.exports = class FortranBeautifier extends Beautifier
beautify: (text, language, options) ->
@debug('fortran-beautifier', options)
emacs = @exe("emacs")
emacs_path = options.emacs_path
emacs_script_path = options.emacs_script_path
@ -36,12 +47,13 @@ module.exports = class FortranBeautifier extends Beautifier
]
if emacs_path
@deprecate("The \"emacs_path\" has been deprecated. Please switch to using the config with path \"Executables - Emacs - Path\" in Atom-Beautify package settings now.")
@run(emacs_path, args, {ignoreReturnCode: false})
.then(=>
@readFile(tempFile)
)
else
@run("emacs", args, {ignoreReturnCode: false})
emacs.run(args, {ignoreReturnCode: false})
.then(=>
@readFile(tempFile)
)

View File

@ -3,8 +3,6 @@
"use strict"
Beautifier = require('./beautifier')
Lexer = require('gherkin').Lexer('en')
logger = require('../logger')(__filename)
module.exports = class Gherkin extends Beautifier
name: "Gherkin formatter"
@ -15,6 +13,8 @@ module.exports = class Gherkin extends Beautifier
}
beautify: (text, language, options) ->
Lexer = require('gherkin').Lexer('en')
logger = @logger
return new @Promise((resolve, reject) ->
recorder = {
lines: []

View File

@ -278,10 +278,11 @@ module.exports = class Beautifiers extends EventEmitter
return Promise.all(allOptions)
.then((allOptions) =>
return new Promise((resolve, reject) =>
logger.info('beautify', text, allOptions, grammar, filePath, onSave, language)
logger.debug('beautify', text, allOptions, grammar, filePath, onSave, language)
logger.verbose(allOptions)
language ?= @getLanguage(grammar, filePath)
fileExtension = @getExtension(filePath)
# Check if unsupported language
if !language
@ -343,38 +344,44 @@ module.exports = class Beautifiers extends EventEmitter
context =
filePath: filePath
fileExtension: fileExtension
startTime = new Date()
beautifier.beautify(text, language.name, options, context)
.then((result) =>
resolve(result)
# Track Timing
@trackTiming({
utc: "Beautify" # Category
utv: language?.name # Variable
utt: (new Date() - startTime) # Value
utl: version # Label
})
# Track Empty beautification results
if not result
beautifier.loadExecutables()
.then((executables) ->
logger.verbose('executables', executables)
beautifier.beautify(text, language.name, options, context)
)
.then((result) =>
resolve(result)
# Track Timing
@trackTiming({
utc: "Beautify" # Category
utv: language?.name # Variable
utt: (new Date() - startTime) # Value
utl: version # Label
})
# Track Empty beautification results
if not result
@trackEvent({
ec: version, # Category
ea: "Beautify:Empty" # Action
el: language?.name # Label
})
)
.catch((error) =>
logger.error(error)
reject(error)
# Track Errors
@trackEvent({
ec: version, # Category
ea: "Beautify:Empty" # Action
ea: "Beautify:Error" # Action
el: language?.name # Label
})
)
.catch((error) =>
reject(error)
# Track Errors
@trackEvent({
ec: version, # Category
ea: "Beautify:Error" # Action
el: language?.name # Label
})
)
.finally(=>
@emit "beautify::end"
)
)
.finally(=>
@emit "beautify::end"
)
# Check if Analytics is enabled
@trackEvent({
@ -400,7 +407,6 @@ module.exports = class Beautifiers extends EventEmitter
if atom.config.get("atom-beautify.general.muteUnsupportedLanguageErrors")
return resolve( null )
else
fileExtension = @getExtension(filePath)
repoBugsUrl = pkg.bugs.url
title = "Atom Beautify could not find a supported beautifier for this file"
detail = """

View File

@ -8,8 +8,7 @@ format = require './beautifier'
module.exports = class Lua extends Beautifier
name: "Lua beautifier"
link: "https://www.perl.org/"
isPreInstalled: false
link: "https://github.com/Glavin001/atom-beautify/blob/master/src/beautifiers/lua-beautifier/beautifier.coffee"
options: {
Lua: true

View File

@ -10,7 +10,30 @@ module.exports = class PHPCSFixer extends Beautifier
name: 'PHP-CS-Fixer'
link: "https://github.com/FriendsOfPHP/PHP-CS-Fixer"
isPreInstalled: false
executables: [
{
name: "PHP"
cmd: "php"
homepage: "http://php.net/"
installation: "http://php.net/manual/en/install.php"
version: {
parse: (text) -> text.match(/PHP (.*) \(cli\)/)[1]
}
}
{
name: "PHP-CS-Fixer"
cmd: "php-cs-fixer"
homepage: "https://github.com/FriendsOfPHP/PHP-CS-Fixer"
installation: "https://github.com/FriendsOfPHP/PHP-CS-Fixer#installation"
version: {
parse: (text) -> text.match(/version (.*) by/)[1] + ".0"
}
docker: {
image: "unibeautify/php-cs-fixer"
workingDir: "/project"
}
}
]
options:
PHP:
@ -24,7 +47,8 @@ module.exports = class PHPCSFixer extends Beautifier
beautify: (text, language, options, context) ->
@debug('php-cs-fixer', options)
version = options.cs_fixer_version
php = @exe('php')
phpCsFixer = @exe('php-cs-fixer')
configFiles = ['.php_cs', '.php_cs.dist']
# Find a config file in the working directory if a custom one was not provided
@ -42,7 +66,7 @@ module.exports = class PHPCSFixer extends Beautifier
"--allow-risky=#{options.allow_risky}" if options.allow_risky
"--using-cache=no"
]
if version is 1
if phpCsFixer.isVersion('1.x')
phpCsFixerOptions = [
"fix"
"--level=#{options.level}" if options.level
@ -57,10 +81,15 @@ module.exports = class PHPCSFixer extends Beautifier
}
# Find php-cs-fixer.phar script
if options.cs_fixer_path
@deprecate("The \"cs_fixer_path\" has been deprecated. Please switch to using the config with path \"Executables - PHP-CS-Fixer - Path\" in Atom-Beautify package settings now.")
@Promise.all([
@which(options.cs_fixer_path) if options.cs_fixer_path
@which('php-cs-fixer')
]).then((paths) =>
tempFile = @tempFile("temp", text, '.php')
]).then(([customPath, phpCsFixerPath]) =>
paths = [customPath, phpCsFixerPath]
@debug('php-cs-fixer paths', paths)
_ = require 'lodash'
# Get first valid, absolute path
@ -71,10 +100,8 @@ module.exports = class PHPCSFixer extends Beautifier
# Check if PHP-CS-Fixer path was found
if phpCSFixerPath?
# Found PHP-CS-Fixer path
tempFile = @tempFile("temp", text)
if @isWindows
@run("php", [phpCSFixerPath, phpCsFixerOptions, tempFile], runOptions)
php.run([phpCSFixerPath, phpCsFixerOptions, tempFile], runOptions)
.then(=>
@readFile(tempFile)
)

View File

@ -8,6 +8,20 @@ Beautifier = require('./beautifier')
module.exports = class PHPCBF extends Beautifier
name: "PHPCBF"
link: "http://php.net/manual/en/install.php"
executables: [
{
name: "PHPCBF"
cmd: "phpcbf"
homepage: "https://github.com/squizlabs/PHP_CodeSniffer"
installation: "https://github.com/squizlabs/PHP_CodeSniffer#installation"
version: {
args: ['--version']
}
docker: {
image: "unibeautify/phpcbf"
}
}
]
isPreInstalled: false
options: {
@ -78,7 +92,7 @@ module.exports = class PHPCBF extends Beautifier
@run("phpcbf", [
"--no-patch" unless options.phpcbf_version is 3
"--standard=#{options.standard}" if options.standard
tempFile = @tempFile("temp", text)
tempFile = @tempFile("temp", text, ".php")
], {
ignoreReturnCode: true
help: {

View File

@ -4,7 +4,20 @@ Beautifier = require('./beautifier')
module.exports = class SassConvert extends Beautifier
name: "SassConvert"
link: "http://sass-lang.com/documentation/file.SASS_REFERENCE.html#syntax"
isPreInstalled: false
executables: [
{
name: "SassConvert"
cmd: "sass-convert"
homepage: "http://sass-lang.com/documentation/file.SASS_REFERENCE.html#syntax"
installation: "http://sass-lang.com/documentation/file.SASS_REFERENCE.html#syntax"
version: {
parse: (text) -> text.match(/Sass (\d+\.\d+\.\d+)/)[1]
}
docker: {
image: "unibeautify/sass-convert"
}
}
]
options:
# TODO: Add support for options
@ -14,8 +27,7 @@ module.exports = class SassConvert extends Beautifier
beautify: (text, language, options, context) ->
lang = language.toLowerCase()
@run("sass-convert", [
@exe("sass-convert").run([
@tempFile("input", text),
"--from", lang, "--to", lang
])

View File

@ -11,7 +11,27 @@ _ = require('lodash')
module.exports = class Uncrustify extends Beautifier
name: "Uncrustify"
link: "https://github.com/uncrustify/uncrustify"
isPreInstalled: false
executables: [
{
name: "Uncrustify"
cmd: "uncrustify"
homepage: "http://uncrustify.sourceforge.net/"
installation: "https://github.com/uncrustify/uncrustify"
version: {
parse: (text) ->
try
v = text.match(/uncrustify (\d+\.\d+)/)[1]
catch error
@error(error)
v = text.match(/Uncrustify-(\d+\.\d+)/)[1] if not v?
if v
return v + ".0"
}
docker: {
image: "unibeautify/uncrustify"
}
}
]
options: {
Apex: true
@ -26,7 +46,10 @@ module.exports = class Uncrustify extends Beautifier
Arduino: true
}
beautify: (text, language, options) ->
beautify: (text, language, options, context) ->
fileExtension = context.fileExtension
uncrustify = @exe("uncrustify")
# console.log('uncrustify.beautify', language, options)
return new @Promise((resolve, reject) ->
configPath = options.configPath
@ -50,8 +73,6 @@ module.exports = class Uncrustify extends Beautifier
reject(new Error("No Uncrustify Config Path set! Please configure Uncrustify with Atom Beautify."))
)
.then((configPath) =>
# Select Uncrustify language
lang = "C" # Default is C
switch language
@ -76,18 +97,16 @@ module.exports = class Uncrustify extends Beautifier
when "Arduino"
lang = "CPP"
@run("uncrustify", [
uncrustify.run([
"-c"
configPath
"-f"
@tempFile("input", text)
@tempFile("input", text, fileExtension and ".#{fileExtension}")
"-o"
outputFile = @tempFile("output", text)
outputFile = @tempFile("output", text, fileExtension and ".#{fileExtension}")
"-l"
lang
], help: {
link: "http://sourceforge.net/projects/uncrustify/"
})
])
.then(=>
@readFile(outputFile)
)

View File

@ -3,7 +3,7 @@ module.exports = {
title: 'General'
type: 'object'
collapsed: true
order: -1
order: -2
description: 'General options for Atom Beautify'
properties:
_analyticsUserId :

View File

@ -9122,5 +9122,238 @@
"description": "Automatically beautify YAML files on save"
}
}
},
"executables": {
"title": "Executables",
"type": "object",
"collapsed": true,
"order": -1,
"description": "Configure executables used by beautifiers.",
"properties": {
"uncrustify": {
"key": "uncrustify",
"title": "Uncrustify",
"type": "object",
"collapsed": true,
"description": "Options for Uncrustify executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"uncrustify\" executable's binary/script."
}
}
},
"autopep8": {
"key": "autopep8",
"title": "autopep8",
"type": "object",
"collapsed": true,
"description": "Options for autopep8 executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"autopep8\" executable's binary/script."
}
}
},
"isort": {
"key": "isort",
"title": "isort",
"type": "object",
"collapsed": true,
"description": "Options for isort executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"isort\" executable's binary/script."
}
}
},
"clang-format": {
"key": "clang-format",
"title": "ClangFormat",
"type": "object",
"collapsed": true,
"description": "Options for ClangFormat executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"clang-format\" executable's binary/script."
}
}
},
"crystal": {
"key": "crystal",
"title": "Crystal",
"type": "object",
"collapsed": true,
"description": "Options for Crystal executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"crystal\" executable's binary/script."
}
}
},
"dfmt": {
"key": "dfmt",
"title": "Dfmt",
"type": "object",
"collapsed": true,
"description": "Options for Dfmt executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"dfmt\" executable's binary/script."
}
}
},
"elm-format": {
"key": "elm-format",
"title": "elm-format",
"type": "object",
"collapsed": true,
"description": "Options for elm-format executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"elm-format\" executable's binary/script."
}
}
},
"emacs": {
"key": "emacs",
"title": "Emacs",
"type": "object",
"collapsed": true,
"description": "Options for Emacs executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"emacs\" executable's binary/script."
}
}
},
"php": {
"key": "php",
"title": "PHP",
"type": "object",
"collapsed": true,
"description": "Options for PHP executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"php\" executable's binary/script."
}
}
},
"php-cs-fixer": {
"key": "php-cs-fixer",
"title": "PHP-CS-Fixer",
"type": "object",
"collapsed": true,
"description": "Options for PHP-CS-Fixer executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"php-cs-fixer\" executable's binary/script."
}
}
},
"phpcbf": {
"key": "phpcbf",
"title": "PHPCBF",
"type": "object",
"collapsed": true,
"description": "Options for PHPCBF executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"phpcbf\" executable's binary/script."
}
}
},
"sass-convert": {
"key": "sass-convert",
"title": "SassConvert",
"type": "object",
"collapsed": true,
"description": "Options for SassConvert executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"sass-convert\" executable's binary/script."
}
}
},
"rscript": {
"key": "rscript",
"title": "Rscript",
"type": "object",
"collapsed": true,
"description": "Options for Rscript executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"rscript\" executable's binary/script."
}
}
},
"beautysh": {
"key": "beautysh",
"title": "beautysh",
"type": "object",
"collapsed": true,
"description": "Options for beautysh executable.",
"properties": {
"path": {
"key": "path",
"title": "Binary/Script Path",
"type": "string",
"default": "",
"description": "Absolute path to the \"beautysh\" executable's binary/script."
}
}
}
}
}
}