anon-iclr-submission/benchname-bug-localization huggingface dataset:
Repository: sublimelinter/sublimelinter
Issue: [Version 4] with the default lint mode, "background", the linter is not run when a file is opened

Using ST 3 dev build 3157, SublimeLinter 4.0.1, SublimeLinter-eslint 4.0.0, ESlint 4.18.1 in win10x64

I quote from the SublimeLinter.sublime-settings:

```javascript
    // Lint Modes determine when the linter is run
    // background: asynchronously on every change
    // load_save: when a file is opened and every time it's saved
    // manual: only when calling the Lint This View command
    "lint_mode": "background",
```

i.e. i. SL4 with the default lint mode, "background", whenever you open a file, the linter is not run. It's only run if you modify the file, i.e. type or delete something on it.
But, if you don't want or just forget to modify it, then it's not linted, giving you the wrong impression that the file is fine.

_For reference, in SL3, with the "background" lint mode, the file was linted on load._

What I'd prefer is having a 4th mode, something like" load_and_background",
i.e. lint the file on load, and then lint it again asynchronously on every change.

<br/>

So, could you please consider adding such a lint mode? That's my suggestion.

Changed files:
sublime_linter.py

diff --git a/sublime_linter.py b/sublime_linter.py
index 220a3ab..404685c 100644
--- a/sublime_linter.py
+++ b/sublime_linter.py
@@ -162,7 +162,7 @@ def has_syntax_changed(view):
     try:
         old_value = buffer_syntaxes[bid]
     except KeyError:
-        return False
+        return True
     else:
         return old_value != current_syntax
     finally:
Repository: sublimelinter/sublimelinter
Issue: `window.extract_variables` depends on the active view

`window.extract_variables` depends on the active view so we probably need to replace the variables around the current file/filename with custom definitions. 



Changed files:
lint/linter.py

diff --git a/lint/linter.py b/lint/linter.py
index 3678306..db2d2e3 100644
--- a/lint/linter.py
+++ b/lint/linter.py
@@ -494,6 +494,20 @@ class Linter(metaclass=LinterMeta):
         if project_folder:
             variables['folder'] = project_folder
 
+        # `window.extract_variables` actually resembles data from the
+        # `active_view`, so we need to pass in all the relevant data around
+        # the filename manually in case the user switches to a different
+        # view, before we're done here.
+        if filename:
+            basename = os.path.basename(filename)
+            file_base_name, file_extension = os.path.splitext(basename)
+
+            variables['file'] = filename
+            variables['file_path'] = os.path.dirname(filename)
+            variables['file_name'] = basename
+            variables['file_base_name'] = file_base_name
+            variables['file_extension'] = file_extension
+
         return recursive_replace(variables, settings)
 
     @staticmethod
Repository: sublimelinter/sublimelinter
Issue: apply new linter-specific styles without ST restart

This is a recent regression where creating a linter specific style doesn't apply that style until ST has been restarted.

Changed files:
lint/style.py

diff --git a/lint/style.py b/lint/style.py
index 01e83a9..9cbd86f 100644
--- a/lint/style.py
+++ b/lint/style.py
@@ -1,6 +1,5 @@
 import sublime
 from . import persist, util
-from abc import ABCMeta, abstractmethod
 
 import os
 from glob import glob
@@ -58,22 +57,10 @@ def load_gutter_icons():
     GUTTER_ICONS = new_gutter_dict
 
 
-class StyleBaseStore(metaclass=ABCMeta):
-    @abstractmethod
-    def update(cls):
-        pass
-
-
-class Borg:
-    _shared_state = {}
-
-    def __init__(self):
-        self.__dict__ = self._shared_state
-
-
-class HighlightStyleStore(StyleBaseStore, Borg):
+class HighlightStyleStore:
     styles = {}
 
+    @classmethod
     def update(self, name, dict):
         self.styles[name] = dict
 
@@ -118,7 +105,7 @@ class HighlightStyleStore(StyleBaseStore, Borg):
         3. Default error type
         """
         # 1. Individual style definition.
-        y = self.styles.setdefault(style, {}).get(key)
+        y = self.styles.get(style, {}).get(key)
         if y:
             return y
 
@@ -146,7 +133,7 @@ class HighlightStyleStore(StyleBaseStore, Borg):
             return val
 
 
-class LinterStyleStore(StyleBaseStore):
+class LinterStyleStore:
     all_linter_styles = {}
     default_styles = {}
 
@@ -161,7 +148,7 @@ class LinterStyleStore(StyleBaseStore):
         self.linter_styles = self.all_linter_styles.get(linter_name, {})
 
     def traverse_dict(self, dict, error_type):
-        return dict.setdefault("types", {}).get(error_type)
+        return dict.get("types", {}).get(error_type)
 
     def get_default_style(self, error_type):
         """Return default style for error_type of this linter.
@@ -187,6 +174,11 @@ class LinterStyleStore(StyleBaseStore):
 
 class StyleParser:
     def __call__(self):
+        linter_style_stores.clear()
+        LinterStyleStore.all_linter_styles.clear()
+        LinterStyleStore.default_styles.clear()
+        HighlightStyleStore.styles.clear()
+
         rule_validities = []
 
         # 1 - for default styles
@@ -245,7 +237,7 @@ class StyleParser:
             for code in node.get("codes", []):
                 lint_dict["codes"][code] = rule_name
 
-            HighlightStyleStore().update(rule_name, style_dict)
+            HighlightStyleStore.update(rule_name, style_dict)
 
         LinterStyleStore.update(linter_name, lint_dict)
Repository: sublimelinter/sublimelinter
Issue: Default working_dir should be equivalent to `${folder:$file_path}`

We previously talked about how the default for `working_dir` should be `${folder:$file_path}`, but in #918 I was made aware that the actual default is just `${folder}` (compare `Linter.get_working_dir`).

https://github.com/SublimeLinter/SublimeLinter/blob/329b5d78ca6d6146cd475a7ead307a265d861481/lint/linter.py#L885-L899

To add this, we either have the option to have settings expansion do the work for us, which would be easy on the surface but require a way to specify a setting default *before* expansion, which currently does not exist, or just enhance `get_working_dir` to check for `self.view.file_name()` and return its dirname if `self._guess_project_path` returned `None`.

Changed files:
lint/linter.py

diff --git a/lint/linter.py b/lint/linter.py
index 3678306..9dc5dfd 100644
--- a/lint/linter.py
+++ b/lint/linter.py
@@ -510,7 +510,7 @@ class Linter(metaclass=LinterMeta):
 
         for folder in folders:
             # Take the first one; should we take the deepest one? The shortest?
-            if folder in filename:
+            if filename.startswith(folder + os.path.sep):
                 return folder
 
     @classmethod
@@ -883,7 +883,11 @@ class Linter(metaclass=LinterMeta):
                 )
                 return None
 
-        return self._guess_project_path(self.view.window(), self.view.file_name())
+        filename = self.view.file_name()
+        return (
+            self._guess_project_path(self.view.window(), filename) or
+            (os.path.dirname(filename) if filename else None)
+        )
 
     def get_environment(self, settings):
         """Return runtime environment for this lint."""
Repository: sublimelinter/sublimelinter
Issue: Linters are run for console input if that has its syntax set to Python

Linters are run for the console input widget if you have a `Widget Console Input.sublime-settngs` that changes its defautl syntax to Python. However, added regions are not rendered for that because ST will not be able to find the view associated with the underlying buffer id in `window.views()` (I presume). I'd expect the lint to be aborted because of the `is_widget` setting being set, but maybe that isn't the case for widgets with syntax highlighting?

Same for the find input widget.

Changed files:
lint/util.py

diff --git a/lint/util.py b/lint/util.py
index 7dff3f7..1da3909 100644
--- a/lint/util.py
+++ b/lint/util.py
@@ -77,7 +77,8 @@ def is_lintable(view):
         not view.window() or
         view.is_scratch() or
         view.is_read_only() or
-        view.settings().get("repl")
+        view.settings().get("repl") or
+        view.settings().get('is_widget')
     ):
         return False
     elif (
Repository: sublimelinter/sublimelinter
Issue: Method for removing unused errors.

After merging #898, errors are based solely on `buffer_id`. This necessitates a new way to remove unused errors.

Quoting @kaste:
> We need to add some logic to remove bid from errors when it's not used anymore.

> This can be tricky. Generally we can multiple views into the same buffer. So we can remove only if this view here is the last one. But one has to check/test how we can iterate here over window.views() for example. Is this view here still in window.views(). What if the user closes the window?

Changed files:
sublime_linter.py

diff --git a/sublime_linter.py b/sublime_linter.py
index 3f35c52..8aad5a0 100644
--- a/sublime_linter.py
+++ b/sublime_linter.py
@@ -147,6 +147,21 @@ class Listener:
 
         queue.cleanup(vid)
 
+        bid = view.buffer_id()
+        buffers = []
+        view_count = 0
+        for w in sublime.windows():
+            for v in w.views():
+                view_count = view_count + 1
+                buffers.append(v.buffer_id())
+
+        if view_count <= 1:
+            # Wipe clean after last view closes
+            persist.errors.clear()
+        elif buffers.count(bid) <= 1:
+            # Remove bid from persist.errors if it's the last view on the buffer
+            persist.errors.pop(bid, None)
+
     def on_hover(self, view, point, hover_zone):
         """On mouse hover event hook.
Repository: sublimelinter/sublimelinter
Issue: CSSLinter not working with latest SublimeLinter update

I've updated CSSLinter to latest 1.0.5 and restarted Sublime text a few times after SublimeLinter update, but the error still appears.

```
SublimeLinter: #133 csslint styleold.css ERROR:

 Linter crashed.

Traceback (most recent call last):
  File "lint.backend in C:\\Users\\Lee\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 97, in execute_lint_task
  File "lint.linter in C:\\Users\\Lee\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 813, in lint
  File "lint.linter in C:\\Users\\Lee\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 847, in find_errors
  File "linter in C:\\Users\\Lee\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter-csslint.sublime-package", line 57, in split_match
TypeError: 'NoneType' object is not iterable

Changed files:
lint/linter.py

diff --git a/lint/linter.py b/lint/linter.py
index 041a856..14e3822 100644
--- a/lint/linter.py
+++ b/lint/linter.py
@@ -872,8 +872,10 @@ class Linter(metaclass=LinterMeta):
         if line:
             match_dict["line"] = int(line) - self.line_col_base[0]
         else:
-            logger.info("'line' is not optional. {}".format(match_dict))
-            return None  # log but do not err for now
+            # `line` is not optional, but if a user implements `split_match`
+            # and calls `super` first, she has still the chance to fill in
+            # a value on her own.
+            match_dict["line"] = None
 
         col = match_dict["col"]
         if col:
Repository: sublimelinter/sublimelinter
Issue: AssertionError: must have a panel now!

```
Traceback (most recent call last):
  File "/Users/koenlageveen/Library/Application Support/Sublime Text 3/Packages/SublimeLinter/panel_view.py", line 70, in <lambda>
    sublime.set_timeout_async(lambda: fill_panel(window, update=True))
  File "/Users/koenlageveen/Library/Application Support/Sublime Text 3/Packages/SublimeLinter/panel_view.py", line 275, in fill_panel
    assert panel, "must have a panel now!"
AssertionError: must have a panel now!
```

1. Open a file with highlights
2. Open SublimeLinter settings (e.g. via command palette)
3. Change the style, e.g. specifically for "pylint"
4. Quickly close the settings window
5. Inspect the console

Changed files:
panel_view.py

diff --git a/panel_view.py b/panel_view.py
index 461e80e..64f4d27 100644
--- a/panel_view.py
+++ b/panel_view.py
@@ -269,10 +269,12 @@ def fill_panel(window, update=False, **panel_filter):
     errors_by_bid = get_window_errors(window, persist.errors, panel_filter)
 
     path_dict, base_dir = create_path_dict(window, errors_by_bid.keys())
-    assert window, "missing window!"
 
     panel = ensure_panel(window)
-    assert panel, "must have a panel now!"
+    # If we're here and the user actually closed the window in the meantime,
+    # we cannot create a panel anymore, and just pass.
+    if not panel:
+        return
 
     settings = panel.settings()
     settings.set("result_base_dir", base_dir)
Repository: sublimelinter/sublimelinter
Issue: linter will not print no-match-for-regex debug message for multiline regexes

https://github.com/SublimeLinter/SublimeLinter/blob/965fba0445a5b7c68b886e5fd229e93c15ae697e/lint/linter.py#L936-L941

Bc `finditer` returns an iterator the else branch is unreachable.

Changed files:
lint/linter.py

diff --git a/lint/linter.py b/lint/linter.py
index ebbb544..04c2959 100644
--- a/lint/linter.py
+++ b/lint/linter.py
@@ -928,15 +928,22 @@ class Linter(metaclass=LinterMeta):
         in output.
         """
         if self.multiline:
-            errors = self.regex.finditer(output)
-            if errors:
-                for error in errors:
-                    yield self.split_match(error)
-            else:
-                yield self.split_match(None)
+            matches = list(self.regex.finditer(output))
+            if not matches:
+                persist.debug(
+                    '{}: No matches for regex: {}'.format(self.name, self.regex.pattern))
+                return
+
+            for match in matches:
+                yield self.split_match(match)
         else:
             for line in output.splitlines():
-                yield self.split_match(self.regex.match(line.rstrip()))
+                match = self.regex.match(line.rstrip())
+                if match:
+                    yield self.split_match(match)
+                else:
+                    persist.debug(
+                        "{}: No match for line: '{}'".format(self.name, line))
 
     def split_match(self, match):
         """
@@ -949,28 +956,25 @@ class Linter(metaclass=LinterMeta):
         """
         match_dict = MATCH_DICT.copy()
 
-        if not match:
-            persist.debug('No match for regex: {}'.format(self.regex.pattern))
-        else:
-            match_dict.update({
-                k: v
-                for k, v in match.groupdict().items()
-                if k in match_dict
-            })
-            match_dict["match"] = match
-
-            # normalize line and col if necessary
-            line = match_dict["line"]
-            if line:
-                match_dict["line"] = int(line) - self.line_col_base[0]
-
-            col = match_dict["col"]
-            if col:
-                if col.isdigit():
-                    col = int(col) - self.line_col_base[1]
-                else:
-                    col = len(col)
-                match_dict["col"] = col
+        match_dict.update({
+            k: v
+            for k, v in match.groupdict().items()
+            if k in match_dict
+        })
+        match_dict["match"] = match
+
+        # normalize line and col if necessary
+        line = match_dict["line"]
+        if line:
+            match_dict["line"] = int(line) - self.line_col_base[0]
+
+        col = match_dict["col"]
+        if col:
+            if col.isdigit():
+                col = int(col) - self.line_col_base[1]
+            else:
+                col = len(col)
+            match_dict["col"] = col
 
         return LintMatch(**match_dict)
Repository: sublimelinter/sublimelinter
Issue: Merge backend threads into the shared Sublime thread when done

We cannot and don't want to guarantee that the lint callback is thread aware or even 'safe'. If we merge into the shared thread, Sublime runs all the queued tasks sequentially.

Changed files:
lint/backend.py

diff --git a/lint/backend.py b/lint/backend.py
index 78af5ec..863de35 100644
--- a/lint/backend.py
+++ b/lint/backend.py
@@ -41,30 +41,11 @@ def lint_view(view, hit_time, callback):
 
     all_errors = chain.from_iterable(results)
 
-    callback(view, list(all_errors), hit_time)
-
-
-def run_concurrently(max_workers=2):
-    def run(tasks):
-        with ThreadPoolExecutor(max_workers=max_workers) as executor:
-            work = [executor.submit(task) for task in tasks]
-            yield from await_futures(work)
-
-    return run
-
-
-def await_futures(fs, ordered=False):
-    if ordered:
-        done, _ = wait(fs)
-    else:
-        done = as_completed(fs)
-
-    for future in done:
-        try:
-            yield future.result()
-        except Exception:
-            ...
-            traceback.print_exc()
+    # We don't want to guarantee that our consumers/views are thread aware.
+    # So we merge here into Sublime's shared worker thread. Sublime guarantees
+    # here to execute all scheduled tasks ordered and sequentially.
+    sublime.set_timeout_async(
+        lambda: callback(view, list(all_errors), hit_time))
 
 
 def execute_lint_task(linter, code, offset, hit_time):
@@ -155,3 +136,26 @@ def get_linters(view):
                     continue
 
         yield linter
+
+
+def run_concurrently(max_workers=2):
+    def run(tasks):
+        with ThreadPoolExecutor(max_workers=max_workers) as executor:
+            work = [executor.submit(task) for task in tasks]
+            yield from await_futures(work)
+
+    return run
+
+
+def await_futures(fs, ordered=False):
+    if ordered:
+        done, _ = wait(fs)
+    else:
+        done = as_completed(fs)
+
+    for future in done:
+        try:
+            yield future.result()
+        except Exception:
+            ...
+            traceback.print_exc()
Repository: sublimelinter/sublimelinter
Issue: view.window() may be None during on_post_save_async

I renamed a file with AdvancedNewFile's "rename" command and observed the following in my console:

```
Traceback (most recent call last):
  File "/opt/sublime_text/sublime_plugin.py", line 487, in on_post_save_async
    callback.on_post_save_async(v)
  File "/home/fichte/.config/sublime-text-3/Packages/SublimeLinter/sublime_linter.py", line 136, in on_post_save_async
    if view.window().project_file_name() == view.file_name():
AttributeError: 'NoneType' object has no attribute 'project_file_name'
```

Changed files:
sublime_linter.py

diff --git a/sublime_linter.py b/sublime_linter.py
index 7261223..c142961 100644
--- a/sublime_linter.py
+++ b/sublime_linter.py
@@ -133,7 +133,7 @@ class BackendController(sublime_plugin.EventListener):
             return
 
         # check if the project settings changed
-        if view.window().project_file_name() == view.file_name():
+        if view.window() and view.window().project_file_name() == view.file_name():
             lint_all_views()
             return
Repository: sublimelinter/sublimelinter
Issue: Linter mode "manual" throwing an exception

Context:
macOS 10.13.5
Sublime Text 3.1.1 Build 3176
SublimeLinter v4.6.4
SublimeLinter-flake8 v4.1.0

Background:
When adding the setting `"lint_mode": "manual"` to my settings for SublimeLinter, I see an error. All other settings ("background". "load_save", and "save") do not produce an error.

Settings:
```
// SublimeLinter Settings - User
{
	"debug": true,
	"lint_mode": "manual",
	"linters": {
		"flake8": {
			"executable": "~/miniconda3/bin/flake8",
			"show-code": false
		},
	},
}
```


Error (from SublimeText console):
```
SublimeLinter: linter.py:798: Checking lint mode manual vs lint reason None
Exception in thread Thread-44:
Traceback (most recent call last):
  File "./python3.3/threading.py", line 901, in _bootstrap_inner
  File "./python3.3/threading.py", line 1142, in run
  File "<home>/Library/Application Support/Sublime Text 3/Installed Packages/SublimeLinter.sublime-package/sublime_linter.py", line 257, in lint
    linter for linter in linters
  File "<home>/Library/Application Support/Sublime Text 3/Installed Packages/SublimeLinter.sublime-package/sublime_linter.py", line 258, in <listcomp>
    if linter.should_lint(reason)]
  File "<home>/Library/Application Support/Sublime Text 3/Installed Packages/SublimeLinter.sublime-package/lint/linter.py", line 801, in should_lint
    return reason in _ACCEPTABLE_REASONS_MAP[lint_mode]
TypeError: 'in <string>' requires string as left operand, not NoneType
```

Changed files:
lint/linter.py

diff --git a/lint/linter.py b/lint/linter.py
index 4f94ae1..23e58c4 100644
--- a/lint/linter.py
+++ b/lint/linter.py
@@ -36,7 +36,7 @@ UTF8_ENV_VARS = {
 # how lint_mode is implemented. The map is supposed to be used in
 # this module only.
 _ACCEPTABLE_REASONS_MAP = {
-    "manual": ("on_user_request"),
+    "manual": ("on_user_request",),
     "save": ("on_user_request", "on_save"),
     "load_save": ("on_user_request", "on_save", "on_load"),
     "background": ("on_user_request", "on_save", "on_load", None),
Repository: sublimelinter/sublimelinter
Issue: ValueError: path is on mount 'S:', start on mount 'C:'

On Windows 10, using SublimeLinter 4, I have some symlinks from within my home at `C:\\Users\\bmix` to `S:\\Users\\bmix`. I occasionally get the following error. What does it mean?

> Traceback (most recent call last):
>   File "lint.events in C:\\Users\\bmix\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 28, in broadcast
>   File "panel_view in C:\\Users\\bmix\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 48, in on_lint_result
>   File "panel_view in C:\\Users\\bmix\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 277, in fill_panel
>   File "panel_view in C:\\Users\\bmix\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 166, in create_path_dict
>   File "panel_view in C:\\Users\\bmix\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package", line 166, in <dictcomp>
>   File "./python3.3/ntpath.py", line 564, in relpath
> ValueError: path is on mount 'S:', start on mount 'C:'

Changed files:
panel_view.py

diff --git a/panel_view.py b/panel_view.py
index 70f6c82..7b8cb87 100644
--- a/panel_view.py
+++ b/panel_view.py
@@ -159,9 +159,9 @@ def create_path_dict(window, bids):
 
     rel_paths = {
         bid: (
-            abs_path
-            if abs_path.startswith('<untitled')
-            else os.path.relpath(abs_path, base_dir)
+            os.path.relpath(abs_path, base_dir)
+            if base_dir and not abs_path.startswith('<untitled')
+            else abs_path
         )
         for bid, abs_path in file_names_by_bid.items()
     }
Repository: sublimelinter/sublimelinter
Issue: Context menu "Lint this view" shows up on scratch views

Of course you need a linter installed matching the syntax. Easy to reproduce with the 'annotations' linter. Then you can actually 'lint' GitSavvy interfaces and even our own error panel. 😲 



Changed files:
sublime_linter.py

diff --git a/sublime_linter.py b/sublime_linter.py
index f684b1d..a1e886e 100644
--- a/sublime_linter.py
+++ b/sublime_linter.py
@@ -289,7 +289,13 @@ class sublime_linter_lint(sublime_plugin.TextCommand):
     """A command that lints the current view if it has a linter."""
 
     def is_enabled(self):
-        return any(elect.runnable_linters_for_view(self.view, 'on_user_request'))
+        return (
+            util.is_lintable(self.view)
+            and any(elect.runnable_linters_for_view(self.view, 'on_user_request'))
+        )
+
+    def is_visible(self):
+        return util.is_lintable(self.view)
 
     def run(self, edit):
         hit(self.view, 'on_user_request')
Repository: sublimelinter/sublimelinter
Issue: [beta]console log error

I got this error in console when sublime text startup;
my ST version is `3156`,my SublimeLinter version is `4.0.0-rc.9.8`
```
Traceback (most recent call last):
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 210, in on_api_ready
    m.plugin_loaded()
  File "sublime_linter in /Users/johnnyyang/Library/Application Support/Sublime Text 3/Installed Packages/SublimeLinter.sublime-package", line 65, in plugin_loaded
  File "sublime_linter in /Users/johnnyyang/Library/Application Support/Sublime Text 3/Installed Packages/SublimeLinter.sublime-package", line 282, in hit
KeyError: 13
```

```
Traceback (most recent call last):
  File "/Applications/Sublime Text.app/Contents/MacOS/sublime_plugin.py", line 538, in on_activated_async
    callback.on_activated_async(v)
  File "sublime_linter in /Users/johnnyyang/Library/Application Support/Sublime Text 3/Installed Packages/SublimeLinter.sublime-package", line 112, in on_activated_async
  File "sublime_linter in /Users/johnnyyang/Library/Application Support/Sublime Text 3/Installed Packages/SublimeLinter.sublime-package", line 282, in hit
KeyError: 4
```

Changed files:
sublime_linter.py, lint/backend.py

diff --git a/lint/backend.py b/lint/backend.py
index 76b563f..78af5ec 100644
--- a/lint/backend.py
+++ b/lint/backend.py
@@ -125,7 +125,7 @@ def get_linters(view):
     filename = view.file_name()
     vid = view.id()
 
-    for linter in persist.view_linters.get(vid):
+    for linter in persist.view_linters.get(vid, []):
         # First check to see if the linter can run in the current lint mode.
         if linter.tempfile_suffix == '-' and view.is_dirty():
             continue
diff --git a/sublime_linter.py b/sublime_linter.py
index 5784c5b..ae25e10 100644
--- a/sublime_linter.py
+++ b/sublime_linter.py
@@ -279,7 +279,7 @@ class SublimeLinter(sublime_plugin.EventListener, Listener):
         self.linted_views.add(vid)
 
         if view.size() == 0:
-            for linter in persist.view_linters[vid]:
+            for linter in persist.view_linters.get(vid, []):
                 linter.clear()
             return
Repository: sublimelinter/sublimelinter
Issue: ValueError: path is on mount 'C:', start on mount 'E:'

## Reproduce

Probably only happens on Windows due to having a problem when calculating relative path between `C:` and `E:`.

Steps:
- Enable SL's debug mode.
- Open a ST project which is on `E:`.
- Open a file on `C:`.
- The opened file from `C:` cannot be linted.

```
SublimeLinter: #1 __init__.py:1273    ERROR: Unhandled exception:
Traceback (most recent call last):
  File "C:\\Users\\Clover\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package\\lint/backend.py", line 155, in execute_lint_task
    errors = linter.lint(code, view_has_changed)
  File "C:\\Users\\Clover\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package\\lint/linter.py", line 1085, in lint
    output = self.run(cmd, code)
  File "C:\\Users\\Clover\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package\\lint/linter.py", line 1469, in run
    return self.communicate(cmd, code)
  File "C:\\Users\\Clover\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package\\lint/linter.py", line 1480, in communicate
    return self._communicate(cmd, code)
  File "C:\\Users\\Clover\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package\\lint/linter.py", line 1576, in _communicate
    'Running ...', cmd, uses_stdin, cwd, view, env=None))
  File "C:\\Users\\Clover\\AppData\\Roaming\\Sublime Text 3\\Installed Packages\\SublimeLinter.sublime-package\\lint/linter.py", line 1668, in make_nice_log_message
    rel_filename = os.path.relpath(filename, cwd)
  File "./python3.3/ntpath.py", line 564, in relpath
ValueError: path is on mount 'C:', start on mount 'E:'
SublimeLinter: sublime_linter.py:482  Linting 'test.cpp' took 0.05s
```

## Related?

https://github.com/SublimeLinter/SublimeLinter/issues/1179
https://github.com/SublimeLinter/SublimeLinter/issues/721
https://github.com/SublimeLinter/SublimeLinter-gcc/pull/17#issuecomment-514397950

Changed files:
lint/linter.py

diff --git a/lint/linter.py b/lint/linter.py
index 1d129a1..28c6570 100644
--- a/lint/linter.py
+++ b/lint/linter.py
@@ -1677,7 +1677,11 @@ def make_nice_log_message(headline, cmd, is_stdin,
 
     filename = view.file_name()
     if filename and cwd:
-        rel_filename = os.path.relpath(filename, cwd)
+        rel_filename = (
+            os.path.relpath(filename, cwd)
+            if os.path.commonprefix([filename, cwd])
+            else filename
+        )
     elif not filename:
         rel_filename = '<buffer {}>'.format(view.buffer_id())
Repository: sublimelinter/sublimelinter
Issue: Panel View horizontal scrolling is not stable

If the messages become very long, so that the panel view shows scroll bars for both directions, we scroll in all directions depending on where the cursor is. 

- For testing, just make the window small enough.
- Now place the cursor on an error. The line will be selected and Sublime scrolls showing the end of the selection. 

We want to restrict scrolling to the y-axis here.

Changed files:
panel_view.py

diff --git a/panel_view.py b/panel_view.py
index 2a2c08a..b91aa44 100644
--- a/panel_view.py
+++ b/panel_view.py
@@ -436,11 +436,21 @@ def update_selection(panel, region=None):
 
 class _sublime_linter_update_selection(sublime_plugin.TextCommand):
     def run(self, edit, a, b):
+        x1, y1 = self.view.viewport_position()
+
         region = sublime.Region(a, b)
         self.view.sel().clear()
         self.view.sel().add(region)
         self.view.show_at_center(region)
 
+        # `show_at_center` will scroll the `b` part into the viewport. If
+        # we have long lines that means we scroll on the x-axis as well.
+        # But we don't want that, so we maybe halfway undo and pin the x-axis
+        # to the previous value.
+        x2, y2 = self.view.viewport_position()
+        if x1 != x2:
+            self.view.set_viewport_position((x1, y2))
+
 
 def draw_position_marker(panel, line):
     line_start = panel.text_point(line - 1, 0)