Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
feat(config): add .editorconfig support
Browse files Browse the repository at this point in the history
Support the loading of .editorconfig configuration over plugin global config

90
  • Loading branch information
RoM4iK committed Apr 26, 2017
1 parent c3d3358 commit e2aff36
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 13 deletions.
11 changes: 11 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@
"contributions": [
"code"
]
},
{
"login": "RoM4iK",
"name": "Roman",
"avatar_url": "https://avatars0.githubusercontent.com/u/2602767?v=3",
"profile": "https://github.com/RoM4iK",
"contributions": [
"code",
"review",
"talk"
]
}
]
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ This repository was created by [James Long][james-long] to go along with his Pre
Thanks goes to these people ([emoji key][emojis]):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
| [<img src="https://github.com/avatars/u/17031?v=3" width="100px;"/><br /><sub>James Long</sub>](http://jlongster.com)<br />💬 [💻](https://github.com/prettier/prettier-atom/commits?author=jlongster) [📖](https://github.com/prettier/prettier-atom/commits?author=jlongster) 🔌 👀 | [<img src="https://github.com/avatars/u/6173488?v=3" width="100px;"/><br /><sub>Rob Wise</sub>](https://robwise.github.io)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=robwise) [📖](https://github.com/prettier/prettier-atom/commits?author=robwise) 💬 💡 👀 [⚠️](https://github.com/prettier/prettier-atom/commits?author=robwise) | [<img src="https://github.com/avatars/u/1500684?v=3" width="100px;"/><br /><sub>Kent C. Dodds</sub>](https://kentcdodds.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=kentcdodds) [📖](https://github.com/prettier/prettier-atom/commits?author=kentcdodds) 🚇 | [<img src="https://github.com/avatars/u/1144075?v=3" width="100px;"/><br /><sub>Luca Barone</sub>](https://github.com/cloud-walker)<br /> | [<img src="https://github.com/avatars/u/4514159?v=3" width="100px;"/><br /><sub>Arnar Þór Sveinsson</sub>](https://github.com/arnarthor)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=arnarthor) | [<img src="https://github.com/avatars/u/131916?v=3" width="100px;"/><br /><sub>Adam Miskiewicz</sub>](http://www.adammiskiewicz.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=skevy) | [<img src="https://github.com/avatars/u/2685242?v=3" width="100px;"/><br /><sub>Ori Livni</sub>](http://www.orilivni.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=oriSomething) |
| [<img src="https://github.com/avatars/u/17031?v=3" width="100px;"/><br /><sub>James Long</sub>](http://jlongster.com)<br />[💬](#question-jlongster "Answering Questions") [💻](https://github.com/prettier/prettier-atom/commits?author=jlongster "Code") [📖](https://github.com/prettier/prettier-atom/commits?author=jlongster "Documentation") [🔌](#plugin-jlongster "Plugin/utility libraries") [👀](#review-jlongster "Reviewed Pull Requests") | [<img src="https://github.com/avatars/u/6173488?v=3" width="100px;"/><br /><sub>Rob Wise</sub>](https://robwise.github.io)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=robwise "Code") [📖](https://github.com/prettier/prettier-atom/commits?author=robwise "Documentation") [💬](#question-robwise "Answering Questions") [💡](#example-robwise "Examples") [👀](#review-robwise "Reviewed Pull Requests") [⚠️](https://github.com/prettier/prettier-atom/commits?author=robwise "Tests") | [<img src="https://github.com/avatars/u/1500684?v=3" width="100px;"/><br /><sub>Kent C. Dodds</sub>](https://kentcdodds.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=kentcdodds "Code") [📖](https://github.com/prettier/prettier-atom/commits?author=kentcdodds "Documentation") [🚇](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") | [<img src="https://github.com/avatars/u/1144075?v=3" width="100px;"/><br /><sub>Luca Barone</sub>](https://github.com/cloud-walker)<br /> | [<img src="https://github.com/avatars/u/4514159?v=3" width="100px;"/><br /><sub>Arnar Þór Sveinsson</sub>](https://github.com/arnarthor)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=arnarthor "Code") | [<img src="https://github.com/avatars/u/131916?v=3" width="100px;"/><br /><sub>Adam Miskiewicz</sub>](http://www.adammiskiewicz.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=skevy "Code") | [<img src="https://github.com/avatars/u/2685242?v=3" width="100px;"/><br /><sub>Ori Livni</sub>](http://www.orilivni.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=oriSomething "Code") |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| [<img src="https://github.com/avatars/u/6182852?v=3" width="100px;"/><br /><sub>Leon Chen</sub>](https://transcranial.github.io)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=transcranial) | [<img src="https://github.com/avatars/u/197597?v=3" width="100px;"/><br /><sub>Christopher Chedeau</sub>](http://blog.vjeux.com/)<br />💬 [💻](https://github.com/prettier/prettier-atom/commits?author=vjeux) 🔌 | [<img src="https://github.com/avatars/u/646693?v=3" width="100px;"/><br /><sub>Christoph Geschwind</sub>](http://christoph-geschwind.de)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=1st8) | [<img src="https://github.com/avatars/u/35026?v=3" width="100px;"/><br /><sub>Andrew Hutchings</sub>](https://andrewhutchings.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=ahutchings) | [<img src="https://github.com/avatars/u/875591?v=3" width="100px;"/><br /><sub>David Schnurr</sub>](http://davidschnurr.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=schnerd) | [<img src="https://github.com/avatars/u/484801?v=3" width="100px;"/><br /><sub>Ryan Cole</sub>](http://rycole.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=ryancole) | [<img src="https://avatars0.githubusercontent.com/u/11488612?v=3" width="100px;"/><br /><sub>Dara Hak</sub>](https://github.com/darahak)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=darahak) [📖](https://github.com/prettier/prettier-atom/commits?author=darahak) |
| [<img src="https://avatars3.githubusercontent.com/u/487068?v=3" width="100px;"/><br /><sub>Stephen John Sorensen</sub>](http://www.stephenjohnsorensen.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=spudly) | [<img src="https://avatars2.githubusercontent.com/u/13285808?v=3" width="100px;"/><br /><sub>Lukas Geiger</sub>](https://github.com/lgeiger)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=lgeiger) [⚠️](https://github.com/prettier/prettier-atom/commits?author=lgeiger) | [<img src="https://avatars2.githubusercontent.com/u/1517854?v=3" width="100px;"/><br /><sub>Viktor Charypar</sub>](https://github.com/charypar)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=charypar) [⚠️](https://github.com/prettier/prettier-atom/commits?author=charypar) | [<img src="https://avatars0.githubusercontent.com/u/1007436?v=3" width="100px;"/><br /><sub>Mats Högberg</sub>](http://mats.hgbrg.se)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=mhgbrg) |
| [<img src="https://github.com/avatars/u/6182852?v=3" width="100px;"/><br /><sub>Leon Chen</sub>](https://transcranial.github.io)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=transcranial "Code") | [<img src="https://github.com/avatars/u/197597?v=3" width="100px;"/><br /><sub>Christopher Chedeau</sub>](http://blog.vjeux.com/)<br />[💬](#question-vjeux "Answering Questions") [💻](https://github.com/prettier/prettier-atom/commits?author=vjeux "Code") [🔌](#plugin-vjeux "Plugin/utility libraries") | [<img src="https://github.com/avatars/u/646693?v=3" width="100px;"/><br /><sub>Christoph Geschwind</sub>](http://christoph-geschwind.de)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=1st8 "Code") | [<img src="https://github.com/avatars/u/35026?v=3" width="100px;"/><br /><sub>Andrew Hutchings</sub>](https://andrewhutchings.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=ahutchings "Code") | [<img src="https://github.com/avatars/u/875591?v=3" width="100px;"/><br /><sub>David Schnurr</sub>](http://davidschnurr.com)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=schnerd "Code") | [<img src="https://github.com/avatars/u/484801?v=3" width="100px;"/><br /><sub>Ryan Cole</sub>](http://rycole.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=ryancole "Code") | [<img src="https://avatars0.githubusercontent.com/u/11488612?v=3" width="100px;"/><br /><sub>Dara Hak</sub>](https://github.com/darahak)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=darahak "Code") [📖](https://github.com/prettier/prettier-atom/commits?author=darahak "Documentation") |
| [<img src="https://avatars3.githubusercontent.com/u/487068?v=3" width="100px;"/><br /><sub>Stephen John Sorensen</sub>](http://www.stephenjohnsorensen.com/)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=spudly "Code") | [<img src="https://avatars2.githubusercontent.com/u/13285808?v=3" width="100px;"/><br /><sub>Lukas Geiger</sub>](https://github.com/lgeiger)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=lgeiger "Code") [⚠️](https://github.com/prettier/prettier-atom/commits?author=lgeiger "Tests") | [<img src="https://avatars2.githubusercontent.com/u/1517854?v=3" width="100px;"/><br /><sub>Viktor Charypar</sub>](https://github.com/charypar)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=charypar "Code") [⚠️](https://github.com/prettier/prettier-atom/commits?author=charypar "Tests") | [<img src="https://avatars0.githubusercontent.com/u/1007436?v=3" width="100px;"/><br /><sub>Mats Högberg</sub>](http://mats.hgbrg.se)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=mhgbrg "Code") | [<img src="https://avatars0.githubusercontent.com/u/2602767?v=3" width="100px;"/><br /><sub>Roman</sub>](https://github.com/RoM4iK)<br />[💻](https://github.com/prettier/prettier-atom/commits?author=RoM4iK "Code") [👀](#review-RoM4iK "Reviewed Pull Requests") [📢](#talk-RoM4iK "Talks") |
<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors][all-contributors] specification. Contributions of any kind welcome!
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"dependencies": {
"atom-linter": "^10.0.0",
"editorconfig": "^0.13.2",
"ignore": "^3.2.7",
"loophole": "^1.1.0",
"prettier": "^1.2.2",
Expand Down
10 changes: 6 additions & 4 deletions src/executePrettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { allowUnsafeNewFunction } = require('loophole');

const {
getPrettierOptions,
getEditorConfigOptions,
getPrettierEslintOptions,
getCurrentFilePath,
getPrettier,
Expand All @@ -29,20 +30,21 @@ const handleError = (error) => {

const executePrettier = (editor, text) => {
try {
const filePath = getCurrentFilePath(editor);
if (shouldUseEslint()) {
return allowUnsafeNewFunction(() =>
prettierEslint({
...getPrettierEslintOptions(),
text,
filePath: getCurrentFilePath(editor),
filePath,
}),
);
}

const prettier = getPrettier(getCurrentFilePath(editor));
const prettier = getPrettier(filePath);
const prettierOptions = getPrettierOptions(editor);

return prettier.format(text, prettierOptions);
const editorConfigOptions = filePath ? getEditorConfigOptions(filePath) : null;
return prettier.format(text, { ...prettierOptions, ...editorConfigOptions });
} catch (error) {
return handleError(error);
}
Expand Down
22 changes: 18 additions & 4 deletions src/executePrettier.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,24 @@ beforeEach(() => {
describe('executePrettierOnBufferRange()', () => {
test('transforms the given buffer range using prettier', () => {
// $FlowFixMe
helpers.getPrettierOptions.mockImplementation(() => 'fake prettier options');
helpers.getPrettierOptions.mockImplementation(() => ({ option: 'fake prettier option' }));
executePrettierOnBufferRange(editor, bufferRangeFixture);

expect(prettier.format).toHaveBeenCalledWith('untransformed text', 'fake prettier options');
expect(prettier.format).toHaveBeenCalledWith('untransformed text', { option: 'fake prettier option' });
});

test('uses editorconfig options if available', () => {
// $FlowFixMe
helpers.getPrettierOptions.mockImplementation(() => ({ option: 'fake prettier option' }));
// $FlowFixMe
helpers.getCurrentFilePath.mockImplementation(() => 'foo.js');
// $FlowFixMe
helpers.getEditorConfigOptions.mockImplementation(() => ({ option: 'fake editorconfig option' }));
executePrettierOnBufferRange(editor, bufferRangeFixture);

expect(prettier.format).toHaveBeenCalledWith('untransformed text', {
option: 'fake editorconfig option',
});
});

test('sets the transformed text in the buffer range', () => {
Expand Down Expand Up @@ -140,7 +154,7 @@ describe('executePrettierOnBufferRange()', () => {
describe('executePrettierOnEmbeddedScripts()', () => {
test('finds embedded scripts in buffer and transforms each', () => {
// $FlowFixMe
helpers.getPrettierOptions.mockImplementation(() => 'fake prettier options');
helpers.getPrettierOptions.mockImplementation(() => ({ option: 'fake prettier option' }));
const fileBufferRange = { range: { start: { row: 0, column: 0 }, end: { row: 4, column: 5 } } };
editor.getBuffer.mockImplementation(() => ({ getRange: () => fileBufferRange }));
editor.backwardsScanInBufferRange.mockImplementation((regex, range, iterator) =>
Expand All @@ -149,6 +163,6 @@ describe('executePrettierOnEmbeddedScripts()', () => {

executePrettierOnEmbeddedScripts(editor);

expect(prettier.format).toHaveBeenCalledWith('untransformed text', 'fake prettier options');
expect(prettier.format).toHaveBeenCalledWith('untransformed text', { option: 'fake prettier option' });
});
});
20 changes: 18 additions & 2 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const ignore = require('ignore');
const path = require('path');
const bundledPrettier = require('prettier');
const readPkg = require('read-pkg');
const editorconfig = require('editorconfig');

// constants
const LINE_SEPERATOR_REGEX = /(\r|\n|\r\n)/;
Expand Down Expand Up @@ -69,7 +70,7 @@ const someGlobsMatchFilePath = (globs: Globs, filePath: FilePath) => ignore().ad
const getAtomTabLength = (editor: TextEditor) =>
atom.config.get('editor.tabLength', { scope: editor.getLastCursor().getScopeDescriptor() });

const useAtomTabLengthIfAuto = (editor, tabLength) =>
const tabLengthOption = (editor, tabLength) =>
(tabLength === 'auto' ? getAtomTabLength(editor) : Number(tabLength));

const isLinterLintCommandDefined = (editor: TextEditor) =>
Expand Down Expand Up @@ -124,7 +125,7 @@ const isWhitelistProvided = () => getConfigOption('formatOnSaveOptions.whitelist

const getPrettierOptions = (editor: TextEditor) => ({
printWidth: getPrettierOption('printWidth'),
tabWidth: useAtomTabLengthIfAuto(editor, getPrettierOption('tabWidth')),
tabWidth: tabLengthOption(editor, getPrettierOption('tabWidth')),
parser: getPrettierOption('parser'),
singleQuote: getPrettierOption('singleQuote'),
trailingComma: getPrettierOption('trailingComma'),
Expand All @@ -134,6 +135,20 @@ const getPrettierOptions = (editor: TextEditor) => ({
jsxBracketSameLine: getPrettierOption('jsxBracketSameLine'),
});

const mapEditorConfigOptions = (options: Object) => {
const { indent_style: indentStyle, tab_width: tabWidth, max_line_length: printWidth } = options;
return {
...(tabWidth ? { tabWidth } : null),
...(printWidth ? { printWidth } : null),
...(indentStyle ? { useTabs: indentStyle === 'tab' } : null),
};
};

const getEditorConfigOptions = (file: FilePath) => {
const options = editorconfig.parseSync(file);
return options ? mapEditorConfigOptions(options) : null;
};

const getPrettierEslintOptions = () => ({
prettierLast: getPrettierEslintOption('prettierLast'),
});
Expand Down Expand Up @@ -169,6 +184,7 @@ module.exports = {
shouldUseEslint,
shouldRespectEslintignore,
getPrettierOptions,
getEditorConfigOptions,
getPrettierEslintOptions,
runLinter,
getDebugInfo,
Expand Down
42 changes: 42 additions & 0 deletions src/helpers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
const path = require('path');
const atomLinter = require('atom-linter');
const prettier = require('prettier');
const editorconfig = require('editorconfig');

const textEditor = require('../tests/mocks/textEditor');
const {
Expand All @@ -21,12 +22,14 @@ const {
shouldUseEslint,
getPrettierOptions,
getPrettierEslintOptions,
getEditorConfigOptions,
runLinter,
getDebugInfo,
} = require('./helpers');

jest.mock('atom-linter');
jest.mock('prettier');
jest.mock('editorconfig');

describe('getConfigOption', () => {
test('retrieves a config option from the prettier-atom config', () => {
Expand Down Expand Up @@ -375,6 +378,45 @@ describe('getPrettierEslintOptions', () => {
});
});

describe('getEditorConfigOptions', () => {
test('parse editorconfig by filename', () => {
getEditorConfigOptions('filename');
expect(editorconfig.parseSync).toHaveBeenCalledWith('filename');
});
test('maps editorconfig options', () => {
editorconfig.parseSync.mockImplementation(() => ({
indent_size: 4,
end_of_line: 'lf',
charset: 'utf-8',
trim_trailing_whitespace: true,
insert_final_newline: true,
tab_width: 2,
max_line_length: 100,
}));
const expected = {
tabWidth: 2,
printWidth: 100,
};
expect(getEditorConfigOptions('')).toEqual(expected);
});

test('returns boolean for useTabs option', () => {
const setIndentStyle = (style) => {
editorconfig.parseSync.mockImplementation(() => ({
indent_style: style,
}));
};
const getUseTabsConfig = () => {
const options = getEditorConfigOptions('');
return options ? options.useTabs : null;
};
setIndentStyle('tab');
expect(getUseTabsConfig()).toEqual(true);
setIndentStyle('space');
expect(getUseTabsConfig()).toEqual(false);
});
});

describe('runLinter()', () => {
test('runs `linter:lint` command', () => {
const editor = textEditor();
Expand Down

0 comments on commit e2aff36

Please sign in to comment.