diff --git a/lib/init.coffee b/lib/init.coffee deleted file mode 100644 index 101448c..0000000 --- a/lib/init.coffee +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = - config: - executable: - type: 'string' - default: 'pylint' - rcFile: - type: 'string' - default: '' - messageFormat: - type: 'string' - default: '%m' - description: - 'Format for Pylint messages where %m is the message, %i is the - numeric mesasge ID (e.g. W0613) and %s is the human-readable - message ID (e.g. unused-argument).' - - activate: -> - console.log 'Linter-Pylint: package loaded, - ready to get initialized by AtomLinter.' diff --git a/lib/linter-pylint.coffee b/lib/linter-pylint.coffee deleted file mode 100644 index eda3850..0000000 --- a/lib/linter-pylint.coffee +++ /dev/null @@ -1,52 +0,0 @@ -{exec} = require 'child_process' -linterPath = atom.packages.getLoadedPackage("linter").path -Linter = require "#{linterPath}/lib/linter" - -class LinterPylint extends Linter - @syntax: 'source.python' # fits all *.py-files - - linterName: 'pylint' - - regex: '^(?\\d+),(?\\d+),\ - ((?fatal|error)|(?warning|convention|refactor)),\ - (?\\w\\d+):(?.*)$' - regexFlags: 'm' - - constructor: (@editor) -> - super @editor - - # sets @cwd to the dirname of the current file - # if we're in a project, use that path instead - # TODO: Fix this up so it works with multiple directories - paths = atom.project.getPaths() - @cwd = paths[0] || @cwd - - # Set to observe config options - @executableListener = atom.config.observe 'linter-pylint.executable', => @updateCommand() - @rcFileListener = atom.config.observe 'linter-pylint.rcFile', => @updateCommand() - @messageFormatListener = atom.config.observe 'linter-pylint.messageFormat', => @updateCommand() - - destroy: -> - super - @executableListener.dispose() - @rcFileListener.dispose() - @messageFormat.dispose() - - # Sets the command based on config options - updateCommand: -> - format = atom.config.get 'linter-pylint.messageFormat' - for pattern, value of {'%m': 'msg', '%i': 'msg_id', '%s': 'symbol'} - format = format.replace(new RegExp(pattern, 'g'), "{#{value}}") - cmd = [atom.config.get 'linter-pylint.executable'] - cmd.push "--msg-template='{line},{column},{category},{msg_id}:#{format}'" - cmd.push '--reports=n' - cmd.push '--output-format=text' - - rcFile = atom.config.get 'linter-pylint.rcFile' - if rcFile - cmd.push "--rcfile=#{rcFile}" - - @cmd = cmd - - -module.exports = LinterPylint diff --git a/lib/main.coffee b/lib/main.coffee new file mode 100644 index 0000000..477ef26 --- /dev/null +++ b/lib/main.coffee @@ -0,0 +1,87 @@ +{CompositeDisposable} = require 'atom' +helpers = require 'atom-linter' +path = require 'path' +_ = require 'lodash' +qFs = require 'q-io/fs' +q = require 'q' +qTmpFile = q.denodeify require('tmp').file + +module.exports = + config: + executable: + type: 'string' + default: 'pylint' + description: 'Command or path to executable.' + pythonPath: + type: 'string' + default: '' + description: 'Paths to be added to $PYTHONPATH. Use %p for current project directory (no trailing /).' + rcFile: + type: 'string' + default: '' + description: 'Path to .pylintrc file.' + messageFormat: + type: 'string' + default: '%i %m' + description: + 'Format for Pylint messages where %m is the message, %i is the + numeric mesasge ID (e.g. W0613) and %s is the human-readable + message ID (e.g. unused-argument).' + + activate: -> + @subscriptions = new CompositeDisposable + @subscriptions.add atom.config.observe 'linter-pylint.executable', + (newExecutableValue) => + @executable = newExecutableValue + @subscriptions.add atom.config.observe 'linter-pylint.rcFile', + (newRcFileValue) => + @rcFile = newRcFileValue + @subscriptions.add atom.config.observe 'linter-pylint.messageFormat', + (newMessageFormatValue) => + @messageFormat = newMessageFormatValue + @subscriptions.add atom.config.observe 'linter-pylint.pythonPath', + (newPythonPathValue) => + @pythonPath = _.trim newPythonPathValue, ':' + + @regex = '^(?\\d+),(?\\d+),\ + (?\\w+),\ + (\\w\\d+):(?.*)$' + + deactivate: -> + @subscriptions.dispose() + + provideLinter: -> + provider = + grammarScopes: ['source.python'] + scope: 'file' + lintOnFly: true + lint: (activeEditor) => + return @writeTmpFile(activeEditor.getText()).then (tmpFilename) => + file = activeEditor.getPath() + projDir = @getProjDir(file) + cwd = projDir + pythonPath = @pythonPath.replace(/%p/g, projDir) + env = _.merge {}, process.env, + PYTHONPATH: _.compact([process.env.PYTHONPATH, projDir, pythonPath]).join(':') + format = @messageFormat + for pattern, value of {'%m': 'msg', '%i': 'msg_id', '%s': 'symbol'} + format = format.replace(new RegExp(pattern, 'g'), "{#{value}}") + args = [ + "--msg-template='{line},{column},{category},{msg_id}:#{format}'" + '--reports=n' + '--output-format=text' + ] + if @rcFile + args.push "--rcfile=#{@rcFile}" + args.push tmpFilename + return helpers.exec(@executable, args, {env: env, cwd: cwd}).then (output) => + _.reject helpers.parse(output, @regex, {filePath: file}), {type: 'info'} + + getProjDir: (filePath) -> + _.find atom.project.getPaths(), (projPath) -> + filePath.indexOf(projPath) == 0 + + writeTmpFile: (contents) -> + qTmpFile({}).spread (filename) -> + qFs.write filename, contents + filename diff --git a/package.json b/package.json index 42897b5..160638f 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,26 @@ { "name": "linter-pylint", "linter-package": true, - "main": "./lib/init", + "main": "./lib/main", "version": "0.2.2", "description": "Lint python on the fly, using pylint", "repository": "https://github.com/AtomLinter/linter-pylint", "license": "MIT", "engines": { - "atom": ">0.50.0" + "atom": ">=1" }, - "dependencies": {} + "providedServices": { + "linter": { + "versions": { + "1.0.0": "provideLinter" + } + } + }, + "dependencies": { + "atom-linter": "^3.1.1", + "lodash": "^3.10.1", + "q": "^1.4.1", + "q-io": "^1.13.1", + "tmp": "0.0.26" + } }