138 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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)
 |