Skip to content
This repository was archived by the owner on Aug 7, 2023. It is now read-only.

Commit e5928b0

Browse files
committed
Merge branch 'master' into patch-1
2 parents ea997ce + 8ae10a4 commit e5928b0

File tree

11 files changed

+1863
-1186
lines changed

11 files changed

+1863
-1186
lines changed

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,40 @@
1+
## [4.4.3](https://github.com/AtomLinter/linter-stylelint/compare/v4.4.2...v4.4.3) (2019-01-22)
2+
3+
4+
### Bug Fixes
5+
6+
* **deps:** update dependency stylelint to v9.10.1 ([f5465a4](https://github.com/AtomLinter/linter-stylelint/commit/f5465a4))
7+
8+
## [4.4.2](https://github.com/AtomLinter/linter-stylelint/compare/v4.4.1...v4.4.2) (2019-01-22)
9+
10+
11+
### Bug Fixes
12+
13+
* **deps:** update dependency atom-package-deps to v5 ([9018f56](https://github.com/AtomLinter/linter-stylelint/commit/9018f56))
14+
15+
## [4.4.1](https://github.com/AtomLinter/linter-stylelint/compare/v4.4.0...v4.4.1) (2019-01-22)
16+
17+
18+
### Bug Fixes
19+
20+
* **deps:** update dependency resolve to v1.10.0 ([e56e754](https://github.com/AtomLinter/linter-stylelint/commit/e56e754))
21+
22+
# [4.4.0](https://github.com/AtomLinter/linter-stylelint/compare/v4.3.2...v4.4.0) (2019-01-22)
23+
24+
25+
### Bug Fixes
26+
27+
* add default option object ([a4d6c92](https://github.com/AtomLinter/linter-stylelint/commit/a4d6c92))
28+
* check passed-in editor, not a new one ([d9489c7](https://github.com/AtomLinter/linter-stylelint/commit/d9489c7))
29+
* don’t change editor text unless necessary ([32427ea](https://github.com/AtomLinter/linter-stylelint/commit/32427ea))
30+
* only save files (buffers) once ([cfd5b9c](https://github.com/AtomLinter/linter-stylelint/commit/cfd5b9c))
31+
* restore cursors ([5ebb26f](https://github.com/AtomLinter/linter-stylelint/commit/5ebb26f))
32+
33+
34+
### Features
35+
36+
* added autofix on save ([3164aab](https://github.com/AtomLinter/linter-stylelint/commit/3164aab))
37+
138
## [4.3.2](https://github.com/AtomLinter/linter-stylelint/compare/v4.3.1...v4.3.2) (2018-06-29)
239

340

lib/helpers.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,31 @@ export async function getStylelintInstance(filePath) {
182182
return require(stylelintPath);
183183
}
184184

185+
export const applyFixedStyles = async (editor, results) => {
186+
// eslint-disable-next-line no-underscore-dangle
187+
const result = results._postcssResult;
188+
const newText = result.root.toString(result.opts.syntax);
189+
// Only set new text if it's changed
190+
if (newText !== editor.getText()) {
191+
// Save the cursor positions so that we can restore them after the `setText`,
192+
// which consolodates all cursors together into one at the end of the file.
193+
const bufferPositions = editor.getCursorBufferPositions();
194+
editor.setText(newText);
195+
bufferPositions.forEach((position, index) => {
196+
// Buffer positions are returned in order they were created, so we
197+
// want to restore them in order as well.
198+
if (index === 0) {
199+
// We'll have one cursor in the editor after the `setText`, so the first
200+
// one can just be a move
201+
editor.setCursorBufferPosition(position, { autoscroll: false });
202+
} else {
203+
// After that, we need to create new cursors
204+
editor.addCursorAtBufferPosition(position);
205+
}
206+
});
207+
}
208+
};
209+
185210
export const runStylelint = async (editor, stylelintOptions, filePath, settings) => {
186211
startMeasure('linter-stylelint: Stylelint');
187212
let data;
@@ -230,6 +255,11 @@ export const runStylelint = async (editor, stylelintOptions, filePath, settings)
230255
endMeasure('linter-stylelint: Lint');
231256
return null;
232257
}
258+
259+
if (stylelintOptions.fix) {
260+
applyFixedStyles(editor, results);
261+
}
262+
233263
return parseResults(editor, results, filePath, settings.showIgnored);
234264
};
235265

lib/index.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
// eslint-disable-next-line import/extensions, import/no-extraneous-dependencies
44
import { CompositeDisposable } from 'atom';
5+
import hasValidScope from './validate';
56

67
// Dependencies
78
let helpers;
@@ -58,8 +59,29 @@ export default {
5859
atom.config.observe('core.excludeVcsIgnoredPaths', (value) => {
5960
this.coreIgnored = value;
6061
}),
62+
atom.config.observe('linter-stylelint.fixOnSave', (value) => {
63+
this.fixOnSave = value;
64+
}),
6165
);
6266

67+
const textBuffers = new Map();
68+
this.subscriptions.add(atom.workspace.observeTextEditors((editor) => {
69+
const buffer = editor.getBuffer();
70+
if (!textBuffers.has(buffer)) {
71+
textBuffers.set(buffer, buffer.onWillSave(() => {
72+
if (this.fixOnSave && hasValidScope(editor, this.baseScopes)) {
73+
return this.fixJob(editor);
74+
}
75+
return Promise.resolve();
76+
}));
77+
buffer.onDidDestroy(() => {
78+
// Maybe this is handled in the destruction of the buffer itself?
79+
textBuffers.get(buffer).dispose();
80+
textBuffers.delete(buffer);
81+
});
82+
}
83+
}));
84+
6385
this.baseScopes = [
6486
'source.css',
6587
'source.scss',
@@ -78,13 +100,28 @@ export default {
78100
this.subscriptions.dispose();
79101
},
80102

103+
fixJob(editor) {
104+
// Silently return if the editor is invalid
105+
if (!editor || !atom.workspace.isTextEditor(editor)) {
106+
return Promise.resolve(null);
107+
}
108+
109+
// Do not try to make fixes on an empty file
110+
const text = editor.getText();
111+
if (text.length === 0) {
112+
return Promise.resolve(null);
113+
}
114+
115+
return this.provideLinter().lint(editor, { shouldFix: true });
116+
},
117+
81118
provideLinter() {
82119
return {
83120
name: 'stylelint',
84121
grammarScopes: this.baseScopes,
85122
scope: 'file',
86123
lintsOnChange: true,
87-
lint: async (editor) => {
124+
lint: async (editor, { shouldFix } = {}) => {
88125
// Force the dependencies to load if they haven't already
89126
loadDeps();
90127

@@ -100,7 +137,8 @@ export default {
100137

101138
const options = {
102139
code: text,
103-
codeFilename: filePath
140+
codeFilename: filePath,
141+
fix: Boolean(shouldFix)
104142
};
105143

106144
const scopes = editor.getLastCursor().getScopeDescriptor().getScopesArray();

lib/validate.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use babel';
2+
3+
const hasValidScope = (editor, validScopes) => editor.getCursors()
4+
.some(cursor => cursor.getScopeDescriptor()
5+
.getScopesArray()
6+
.some(scope => validScopes.includes(scope)));
7+
8+
export default hasValidScope;

0 commit comments

Comments
 (0)