diff --git a/lib/main.js b/lib/main.js index 62bad7f..ff8836c 100644 --- a/lib/main.js +++ b/lib/main.js @@ -10,5 +10,9 @@ export default { deactivate () { if (this.whitespace) this.whitespace.destroy() this.whitespace = null + }, + + consumeSuppressor (suppressor) { + return this.whitespace.addSuppressor(suppressor) } } diff --git a/lib/whitespace.js b/lib/whitespace.js index 7034ad8..f92513b 100644 --- a/lib/whitespace.js +++ b/lib/whitespace.js @@ -1,11 +1,12 @@ /** @babel */ -import {CompositeDisposable, Point, Range} from 'atom' +import {Disposable, CompositeDisposable, Point, Range} from 'atom' const TRAILING_WHITESPACE_REGEX = /[ \t]+(?=\r?$)/g export default class Whitespace { constructor () { + this.suppressors = [] this.subscriptions = new CompositeDisposable() this.subscriptions.add(atom.workspace.observeTextEditors(editor => { @@ -70,6 +71,35 @@ export default class Whitespace { return this.subscriptions.dispose() } + addSuppressor (suppressor) { + this.suppressors.push(suppressor) + return new Disposable(() => { + this.suppressors.splice(this.suppressors.findIndex( + x => x === suppressor + ), 1) + }) + } + + shouldSuppressRemoveTrailingWhitespace (editor) { + for (let i = 0, n = this.suppressors.length; i < n; i++) { + if (this.suppressors[i].shouldSuppressRemoveTrailingWhitespace(editor)) { + return true; + } + } + + return false; + } + + shouldSuppressEnsureSingleTrailingNewline (editor) { + for (let i = 0, n = this.suppressors.length; i < n; i++) { + if (this.suppressors[i].shouldSuppressEnsureSingleTrailingNewline(editor)) { + return true; + } + } + + return false; + } + handleEvents (editor) { let buffer = editor.getBuffer() @@ -79,11 +109,12 @@ export default class Whitespace { if (atom.config.get('whitespace.removeTrailingWhitespace', { scope: scopeDescriptor - }) && !this.ignore) { + }) && !this.ignore && !this.shouldSuppressRemoveTrailingWhitespace(editor)) { this.removeTrailingWhitespace(editor, editor.getGrammar().scopeName) } - if (atom.config.get('whitespace.ensureSingleTrailingNewline', {scope: scopeDescriptor})) { + if (atom.config.get('whitespace.ensureSingleTrailingNewline', {scope: scopeDescriptor}) && + !this.shouldSuppressEnsureSingleTrailingNewline(editor)) { return this.ensureSingleTrailingNewline(editor) } }) @@ -102,7 +133,7 @@ export default class Whitespace { if (atom.config.get('whitespace.removeTrailingWhitespace', { scope: scopeDescriptor - })) { + }) && !this.shouldSuppressRemoveTrailingWhitespace(editor)) { if (!atom.config.get('whitespace.ignoreWhitespaceOnlyLines', { scope: scopeDescriptor })) { diff --git a/package.json b/package.json index 18e71d2..d1af670 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,13 @@ "waitsForPromise" ] }, + "consumedServices": { + "whitespace.suppressor": { + "versions": { + "^1.0.0": "consumeSuppressor" + } + } + }, "configSchema": { "removeTrailingWhitespace": { "type": "boolean",