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

Rewrite #11

Merged
merged 5 commits into from
Aug 6, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

* Nothing yet

## 1.0.0

* [#11](https://github.com/AtomLinter/linter-haml/pull/11) Rewrite for new Linter API
* **Breaking change:** Configuration is no longer namespaced under `linter-haml-lint`, but under `linter-haml`. As such, previously configured `hamlLintExecutablePath` will not work. You can either change the namespace in your `config.cson` or change the package settings with Atom's GUI to set an appropriate value.

## 0.4.0

* [#6](https://github.com/AtomLinter/linter-haml/pull/6) Use `activationCommands` instead of deprecated `activationEvents` in `package.json`
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This linter plugin for [Linter](https://github.com/AtomLinter/Linter) provides a

### Dependencies

This plugin requires the Linter package to be installed. If Linter is not installed, please follow the instructions [here](https://github.com/AtomLinter/Linter).
This plugin requires the Linter package to be installed. If Linter is not installed, please follow the instructions [here](https://atom.io/packages/linter).

Linter-haml relies on the HAML-lint gem to perform linting. If you do not currently have HAML-lint installed, follow the instructions [here](https://github.com/causes/haml-lint).

Expand All @@ -21,8 +21,9 @@ $ apm install linter-haml
## Settings
You can configure linter-haml by editing ~/.atom/config.cson (choose Open Your Config in Atom menu):
```
'linter-haml-lint':
'hamlLintExecutablePath': null #haml-lint path. run 'which haml-lint' to find the path
'linter-haml':
'copyRubocopYml': true # Copy rubocop.yml to temporary directory for linting (if it can be found). Set to `false` if this is too slow / too IO-intensive for your needs.
'hamlLintExecutablePath': null # haml-lint path. Run `which haml-lint` to find the path.
```

## Contributing
Expand Down
4 changes: 0 additions & 4 deletions lib/init.coffee

This file was deleted.

29 changes: 0 additions & 29 deletions lib/linter-haml.coffee

This file was deleted.

147 changes: 147 additions & 0 deletions lib/linter.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
{BufferedProcess, CompositeDisposable} = require 'atom'
helpers = require 'atom-linter'
fs = require 'fs'
fse = require 'fs-extra'
path = require 'path'
temp = require 'temp'
XRegExp = require('xregexp').XRegExp

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the helper module for parsing instead of using xregexp directly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, you're fast. :)

My biggest reason for not using the helper module for parsing is that is not able to take into account indenting and ends up underlining all the leading whitespace. My parsing uses the textEditor object to get the indentation level so it can be taken into account (a trick I picked up from linter-coffeelint). Is there some way to have the best of both worlds?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like that was added after I wrote this (and will require a version bump in the dependencies). I will work on refactoring this to use the helper module.


class Linter
constructor: ->
@subscriptions = new CompositeDisposable
@subscriptions.add atom.config.observe 'linter-haml.copyRubocopYml', (copyRubocopYml) =>
@copyRubocopYml = copyRubocopYml
@subscriptions.add atom.config.observe 'linter-haml.hamlLintExecutablePath', (executablePath) =>
@executablePath = executablePath

copyFile: (sourcePath, destinationPath) ->
new Promise (resolve, reject) ->
fse.copy sourcePath, destinationPath, (error) ->
return reject Error(error) if error
resolve()

exists: (filePath) ->
new Promise (resolve, reject) ->
fs.exists filePath, (exists) ->
resolve exists

findFile: (filePath, fileName) =>
new Promise (resolve, reject) =>
foundPath = helpers.findFile filePath, fileName
return resolve foundPath if foundPath

homeDir = process.env.HOME || process.env.USERPROFILE
homePath = path.join homeDir, fileName
@exists homePath
.then (exists) ->
resolve if exists then homePath else undefined

findHamlLintYmlFile: (filePath) =>
new Promise (resolve, reject) =>
@findFile filePath, '.haml-lint.yml'
.then (hamlLintYmlPath) ->
resolve hamlLintYmlPath

findRubocopYmlFile: (filePath) =>
new Promise (resolve, reject) =>
@findFile filePath, '.rubocop.yml'
.then (rubocopYmlPath) ->
resolve rubocopYmlPath

grammarScopes: ['text.haml']

lint: (textEditor) =>
new Promise (resolve, reject) =>
fileContent = textEditor.getText()
filePath = textEditor.getPath()
fileName = path.basename filePath

results = []
rubocopYmlPath = undefined
tempDir = undefined
tempFile = undefined

@makeTempDir().then (dir) =>
tempDir = dir
@writeTempFile(tempDir, fileName, fileContent)
.then (file) =>
tempFile = file
@findRubocopYmlFile(filePath) if @copyRubocopYml
.then (rubocopYmlPath) =>
if rubocopYmlPath
@copyFile rubocopYmlPath, path.join(tempDir, '.rubocop.yml')
.then =>
@findHamlLintYmlFile filePath
.then (hamlLintYmlPath) =>
@lintFile textEditor, tempFile, hamlLintYmlPath
.then (messages) ->
results = messages
.then =>
@removeTempDir tempDir
.then ->
resolve results
.catch (error) ->
console.error 'linter-haml error', error
resolve results

lintFile: (textEditor, tempFile, hamlLintYmlPath) ->
new Promise (resolve, reject) =>
filePath = textEditor.getPath()
tabLength = textEditor.getTabLength()
textBuffer = textEditor.getBuffer()

args = []
if hamlLintYmlPath?
args.push '--config'
args.push hamlLintYmlPath
args.push tempFile

output = []
process = new BufferedProcess
command: @executablePath
args: args
options:
cwd: path.dirname tempFile
stdout: (data) ->
output.push data
exit: (code) ->
regex = XRegExp '.+?:(?<line>\\d+) ' +
'\\[((?<warning>W)|(?<error>E))\\] ' +
'(?<message>.+)'
messages = []
XRegExp.forEach output, regex, (match, i) ->
indentLevel = textEditor.indentationForBufferRow(match.line - 1)
messages.push
type: if match.warning? then 'warning' else 'error'
text: match.message
filePath: filePath
range: [
[match.line - 1, indentLevel * tabLength],
[match.line - 1, textBuffer.lineLengthForRow(match.line - 1)]
]
resolve messages

lintOnFly: true

makeTempDir: ->
new Promise (resolve, reject) ->
temp.mkdir 'AtomLinter', (error, directory) ->
return reject Error(error) if error
resolve directory

removeTempDir: (tempDir) ->
new Promise (resolve, reject) ->
fse.remove tempDir, (error) ->
return reject Error(error) if error
resolve()

scope: 'file'

writeTempFile: (tempDir, fileName, fileContent) ->
new Promise (resolve, reject) ->
tempFile = path.join tempDir, fileName
fse.writeFile tempFile, fileContent, (error) ->
return reject Error(error) if error
resolve tempFile

module.exports = Linter
22 changes: 22 additions & 0 deletions lib/main.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Linter = require './linter'

module.exports =
activate: =>
@linter = new Linter

config:
copyRubocopYml:
default: true
description: 'Copy .rubocop.yml to temporary directory while linting'
type: 'boolean'

hamlLintExecutablePath:
default: 'haml-lint'
description: 'Path to haml-lint executable'
type: 'string'

deactivate: =>
@linter.subscriptions.dispose()

provideLinter: =>
@linter
17 changes: 14 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
{
"name": "linter-haml",
"linter-package": true,
"activationCommands": {},
"main": "./lib/init",
"main": "./lib/main",
"version": "0.4.0",
"description": "Atom linter plugin for HAML, using haml-lint",
"repository": "https://github.com/AtomLinter/linter-haml",
"license": "MIT",
"engines": {
"atom": ">=0.151.0"
},
"dependencies": {}
"dependencies": {
"atom-linter": "1.0.2",
"fs-extra": "0.22.1",
"temp": "0.8.3",
"xregexp": "2.0.0"
},
"providedServices": {
"linter": {
"versions": {
"1.0.0": "provideLinter"
}
}
}
}