From 17a3d1781f56b9f580b5b588571c00166d867647 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 22 Mar 2014 17:52:01 -0500 Subject: [PATCH] Add better project file support for virtualenv usage Added code to find the project file and add $project_path var in the settings file to prefix other paths. Also did this for $working_dir. This is to avoid hard coded paths to virtualenvs in your project settings. Getting the project file is straight forward in ST3. In ST2, the code will search open folders to find the first *.sublime-project file and load settings using JSON * Add ability to use $project_path in settings paths * Add ability to use $working_dir in settings paths --- pylinter.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/pylinter.py b/pylinter.py index 6f3f23e..ae068ae 100755 --- a/pylinter.py +++ b/pylinter.py @@ -17,6 +17,8 @@ import collections import sublime import sublime_plugin +import string +import fnmatch #pylint: disable=E1101 @@ -63,6 +65,12 @@ # ["pylint"] or [, ] if the former is not found. DEFAULT_PYLINT_COMMAND = None +def isstr(s): + try: + return isinstance(s, basestring) + except NameError: + return isinstance(s, str) + def speak(*msg): """ Log messages to the console if PYLINTER_VERBOSE is True """ if PYLINTER_VERBOSE: @@ -100,14 +108,33 @@ class PylSet(object): """ Pylinter Settings class""" @classmethod def _get_settings_obj(cls): + + proj_settings = {} + if not ST3: + project_file = cls.get_project_file() + if project_file is not None: + try: + import json + data = json.load(open(project_file, 'rb')) + except: + speak("No project settings") + else: + proj_settings = data.get('settings', {}).get('pylinter', {}) + try: view_settings = sublime.active_window().active_view().settings() view_settings = view_settings.get('pylinter') if view_settings: + if not ST3: + for key, val in proj_settings.iteriems(): + view_settings.set(key, val) return view_settings except AttributeError: pass + if not ST3: + for key, val in proj_settings.iteritems(): + PYLINT_SETTINGS.set(key, val) return PYLINT_SETTINGS @classmethod @@ -124,7 +151,51 @@ def get_or(cls, setting_name, default): if isinstance(settings_obj, collections.Iterable): if not setting_name in settings_obj: settings_obj = PYLINT_SETTINGS - return multiconf.get(settings_obj, setting_name, default) + val = multiconf.get(settings_obj, setting_name, default) + if val is None: + val = settings_obj.get(setting_name) + return cls.apply_path_templates(setting_name, val) + + @classmethod + def get_project_file(cls): + """ return the project_file_path or None if no project is active + """ + window = sublime.active_window() + if window is None: + return + project_file_name = None + if not hasattr(window, 'project_file_name'): + for folder in window.folders(): + for root, dirnames, filenames in os.walk(folder): + for filename in fnmatch.filter(filenames, '*.sublime-project'): + project_file_name = os.path.join(root, filename) + else: + project_file_name = sublime.active_window().project_file_name() + return project_file_name + + @classmethod + def get_project_path(cls): + """ return the directory of the project fileh or None if no project is active + """ + project_file_name = cls.get_project_file() + if project_file_name is not None: + return os.path.dirname(project_file_name) + + @classmethod + def apply_path_templates(cls, setting_name, val): + """ replace variables in paths from settings + setting_name is passed in to allow substitution in variables passed + into the template without hitting recursion + """ + if not isstr(val): + return val + + var_values = { + 'project_path': cls.get_project_path(), + 'working_dir': None if setting_name == 'working_dir' else cls.get_or('working_dir', None) + } + val = string.Template(val).safe_substitute(dict((k, v) for k, v in var_values.items() if v is not None)) + return val @classmethod def read_settings(cls): @@ -191,7 +262,7 @@ def get_default_pylint_command(cls): speak("Pylint executable *not* found") speak("Seaching for lint.py module...") - cmd = ["python", "-c"] + cmd = [python_bin, "-c"] if PYTHON_VERSION == 2: cmd.append("import pylint; print pylint.__path__[0]")