Files
2013-04-04 08:54:25 -04:00

138 lines
4.6 KiB
Python

# Note: Unlike linter modules, changes made to this module will NOT take effect until
# Sublime Text is restarted.
import glob
import os
import os.path
import sys
import modules.base_linter as base_linter
# sys.path appears to ignore individual paths with unicode characters.
# This means that this lib_path will be ignored for Windows 7 users with
# non-ascii characters in their username (thus as their home directory).
#
# libs_path = os.path.abspath(os.path.join(os.path.dirname(__file__.encode('utf-8')), u'modules', u'libs'))
#
# if libs_path not in sys.path:
# sys.path.insert(0, libs_path)
# As a fix for the Windows 7 lib path issue (#181), the individual modules in
# the `libs` folder can be explicitly imported. This obviously doesn't scale
# well, but may be a necessary evil until ST2 upgrades its internal Python.
#
tmpdir = os.getcwdu()
os.chdir(os.path.abspath(os.path.join(os.path.dirname(__file__.encode('utf-8')), u'modules', u'libs')))
for mod in [u'capp_lint', u'pep8', u'pyflakes', u'pyflakes.checker', u'pyflakes.messages']:
__import__(mod)
print u'imported {0}'.format(mod)
os.chdir(tmpdir)
class Loader(object):
'''utility class to load (and reload if necessary) SublimeLinter modules'''
def __init__(self, basedir, linters):
'''assign relevant variables and load all existing linter modules'''
self.basedir = basedir
self.basepath = u'sublimelinter/modules'
self.linters = linters
self.modpath = self.basepath.replace('/', u'.')
self.ignored = ('__init__', 'base_linter')
self.fix_path()
self.load_all()
def fix_path(self):
if os.name != 'posix':
return
path = os.environ['PATH'].encode('utf-8')
if path:
dirs = path.encode('utf-8').split(':')
if u'/usr/local/bin' not in dirs:
dirs.insert(0, u'/usr/local/bin')
if u'~/bin' not in dirs and u'$HOME/bin' not in dirs:
dirs.append(u'$HOME/bin')
os.environ['PATH'] = u':'.join(dirs)
def load_all(self):
'''loads all existing linter modules'''
for modf in glob.glob(u'{0}/*.py'.format(self.basepath)):
base, name = os.path.split(modf)
name = name.split('.', 1)[0]
if name in self.ignored:
continue
self.load_module(name)
def load_module(self, name):
'''loads a single linter module'''
fullmod = u'{0}.{1}'.format(self.modpath, name)
# make sure the path didn't change on us (this is needed for submodule reload)
pushd = os.getcwdu()
os.chdir(self.basedir)
__import__(fullmod)
# this following line of code does two things:
# first, we get the actual module from sys.modules,
# not the base mod returned by __import__
# second, we get an updated version with reload()
# so module development is easier
# (to make sublime text reload language submodule,
# just save sublimelinter_plugin.py )
mod = sys.modules[fullmod] = reload(sys.modules[fullmod])
# update module's __file__ to absolute path so we can reload it
# if saved with sublime text
mod.__file__ = os.path.abspath(mod.__file__.encode('utf-8')).rstrip('co')
language = ''
try:
config = base_linter.CONFIG.copy()
try:
config.update(mod.CONFIG)
language = config['language']
except (AttributeError, KeyError):
pass
if language:
if hasattr(mod, 'Linter'):
linter = mod.Linter(config)
else:
linter = base_linter.BaseLinter(config)
lc_language = language.lower()
self.linters[lc_language] = linter
print u'SublimeLinter: {0} loaded'.format(language)
else:
print u'SublimeLinter: {0} disabled (no language specified in module)'.format(name)
except KeyError:
print u'SublimeLinter: general error importing {0} ({1})'.format(name, language or '<unknown>')
os.chdir(pushd)
def reload_module(self, module):
'''reload a single linter module
This method is meant to be used when editing a given
linter module so that changes can be viewed immediately
upon saving without having to restart Sublime Text'''
fullmod = module.__name__
if not fullmod.startswith(self.modpath):
return
name = fullmod.replace(self.modpath + '.', '', 1)
self.load_module(name)