Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Convert whitespace package source to JS
Browse files Browse the repository at this point in the history
  • Loading branch information
mnquintana committed Oct 15, 2016
1 parent ad6b1ee commit 737bd9c
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 132 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1 +1,2 @@
node_modules
npm-debug.log
9 changes: 0 additions & 9 deletions lib/main.coffee

This file was deleted.

14 changes: 14 additions & 0 deletions lib/main.js
@@ -0,0 +1,14 @@
/** @babel */

import Whitespace from './whitespace'

export default {
activate () {
this.whitespace = new Whitespace()
},

deactivate () {
if (this.whitespace) this.whitespace.destroy()
this.whitespace = null
}
}
123 changes: 0 additions & 123 deletions lib/whitespace.coffee

This file was deleted.

223 changes: 223 additions & 0 deletions lib/whitespace.js
@@ -0,0 +1,223 @@
/** @babel */

import {CompositeDisposable} from 'atom'

export default class Whitespace {
constructor () {
this.subscriptions = new CompositeDisposable()

this.subscriptions.add(atom.workspace.observeTextEditors(editor => {
return this.handleEvents(editor)
}))

this.subscriptions.add(atom.commands.add('atom-workspace', {
'whitespace:remove-trailing-whitespace': () => {
let editor = atom.workspace.getActiveTextEditor()

if (editor) {
this.removeTrailingWhitespace(editor, editor.getGrammar().scopeName)
}
},

'whitespace:save-with-trailing-whitespace': () => {
let editor = atom.workspace.getActiveTextEditor()

if (editor) {
this.ignore = true
editor.save()
this.ignore = false
}
},

'whitespace:save-without-trailing-whitespace': () => {
let editor = atom.workspace.getActiveTextEditor()

if (editor) {
this.removeTrailingWhitespace(editor, editor.getGrammar().scopeName)
editor.save()
}
},

'whitespace:convert-tabs-to-spaces': () => {
let editor = atom.workspace.getActiveTextEditor()

if (editor) {
this.convertTabsToSpaces(editor)
}
},

'whitespace:convert-spaces-to-tabs': () => {
let editor = atom.workspace.getActiveTextEditor()

if (editor) {
return this.convertSpacesToTabs(editor)
}
},

'whitespace:convert-all-tabs-to-spaces': () => {
let editor = atom.workspace.getActiveTextEditor()

if (editor) {
return this.convertTabsToSpaces(editor, true)
}
}
}))
}

destroy () {
return this.subscriptions.dispose()
}

handleEvents (editor) {
let buffer = editor.getBuffer()

let bufferSavedSubscription = buffer.onWillSave(() => {
return buffer.transact(() => {
let scopeDescriptor = editor.getRootScopeDescriptor()

if (atom.config.get('whitespace.removeTrailingWhitespace', {
scope: scopeDescriptor
}) && !this.ignore) {
this.removeTrailingWhitespace(editor, editor.getGrammar().scopeName)
}

if (atom.config.get('whitespace.ensureSingleTrailingNewline', {scope: scopeDescriptor})) {
return this.ensureSingleTrailingNewline(editor)
}
})
})

let editorTextInsertedSubscription = editor.onDidInsertText(function (event) {
if (event.text !== '\n') {
return
}

if (!buffer.isRowBlank(event.range.start.row)) {
return
}

let scopeDescriptor = editor.getRootScopeDescriptor()

if (atom.config.get('whitespace.removeTrailingWhitespace', {
scope: scopeDescriptor
})) {
if (!atom.config.get('whitespace.ignoreWhitespaceOnlyLines', {
scope: scopeDescriptor
})) {
return editor.setIndentationForBufferRow(event.range.start.row, 0)
}
}
})

let editorDestroyedSubscription = editor.onDidDestroy(() => {
bufferSavedSubscription.dispose()
editorTextInsertedSubscription.dispose()
editorDestroyedSubscription.dispose()
this.subscriptions.remove(bufferSavedSubscription)
this.subscriptions.remove(editorTextInsertedSubscription)
this.subscriptions.remove(editorDestroyedSubscription)
})

this.subscriptions.add(bufferSavedSubscription)
this.subscriptions.add(editorTextInsertedSubscription)
this.subscriptions.add(editorDestroyedSubscription)
}

removeTrailingWhitespace (editor, grammarScopeName) {
let buffer = editor.getBuffer()
let scopeDescriptor = editor.getRootScopeDescriptor()

let ignoreCurrentLine = atom.config.get('whitespace.ignoreWhitespaceOnCurrentLine', {
scope: scopeDescriptor
})

let ignoreWhitespaceOnlyLines = atom.config.get('whitespace.ignoreWhitespaceOnlyLines', {
scope: scopeDescriptor
})

return buffer.backwardsScan(/[ \t]+$/g, function ({lineText, match, replace}) {
let whitespaceRow = buffer.positionForCharacterIndex(match.index).row

let cursorRows = editor.getCursors().map(cursor => {
return cursor.getBufferRow()
})

if (ignoreCurrentLine && cursorRows.includes(whitespaceRow)) {
return
}

let [whitespace] = match

if (ignoreWhitespaceOnlyLines && whitespace === lineText) {
return
}

if (grammarScopeName === 'source.gfm' && atom.config.get('whitespace.keepMarkdownLineBreakWhitespace')) {
if (!(whitespace.length >= 2 && whitespace !== lineText)) {
return replace('')
}
} else {
return replace('')
}
})
}

ensureSingleTrailingNewline (editor) {
let selectedBufferRanges
let row
let buffer = editor.getBuffer()
let lastRow = buffer.getLastRow()

if (buffer.lineForRow(lastRow) === '') {
row = lastRow - 1

return (() => {
while (row && buffer.lineForRow(row) === '') {
buffer.deleteRow(row--)
}
})()
} else {
selectedBufferRanges = editor.getSelectedBufferRanges()
buffer.append('\n')
return editor.setSelectedBufferRanges(selectedBufferRanges)
}
}

convertTabsToSpaces (editor, convertAllTabs) {
let buffer = editor.getBuffer()
let spacesText = new Array(editor.getTabLength() + 1).join(' ')
let regex = (convertAllTabs ? /\t/g : /^\t+/g)

buffer.transact(function () {
return buffer.scan(regex, function ({replace}) {
return replace(spacesText)
})
})

return editor.setSoftTabs(true)
}

convertSpacesToTabs (editor) {
let buffer = editor.getBuffer()
let scope = editor.getRootScopeDescriptor()
let fileTabSize = editor.getTabLength()

let userTabSize = atom.config.get('editor.tabLength', {
scope: scope
})

let regex = new RegExp(' '.repeat(fileTabSize), 'g')

buffer.transact(function () {
return buffer.scan(/^[ \t]+/g, function ({matchText, replace}) {
return replace(matchText.replace(regex, '\t').replace(/[ ]+\t/g, '\t'))
})
})

editor.setSoftTabs(false)

if (fileTabSize !== userTabSize) {
return editor.setTabLength(userTabSize)
}
}
}

0 comments on commit 737bd9c

Please sign in to comment.