Repository: sublimelinter/sublimelinter
Issue: 'NoneType' object has no attribute 'run_command'

I start ST, then open a file from the sidebar. Usually seems to happen just the first time, or perhaps before some process is ready.

```
Exception in thread Thread-1:
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 "/Users/koenlageveen/Library/Application Support/Sublime Text 3/Packages/SublimeLinter/sublime_linter.py", line 245, in lint
    linters = get_linters_for_view(view)
  File "/Users/koenlageveen/Library/Application Support/Sublime Text 3/Packages/SublimeLinter/sublime_linter.py", line 336, in get_linters_for_view
    view.window().run_command('sublime_linter_assigned', {
AttributeError: 'NoneType' object has no attribute 'run_command'
```

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

diff --git a/lint/util.py b/lint/util.py
index 8a6fc27..79035e7 100644
--- a/lint/util.py
+++ b/lint/util.py
@@ -84,14 +84,16 @@ def is_lintable(view):
         view.settings().get('is_widget')
     ):
         return False
-    elif (
-        view.file_name() and
-        view.file_name().startswith(sublime.packages_path() + os.path.sep) and
-        not os.path.exists(view.file_name())
+
+    filename = view.file_name()
+    if (
+        filename and
+        filename.startswith(sublime.packages_path() + os.path.sep) and
+        not os.path.exists(filename)
     ):
         return False
-    else:
-        return True
+
+    return True
 
 
 # file/directory/environment utils
diff --git a/sublime_linter.py b/sublime_linter.py
index 97974ad..b3ad30b 100644
--- a/sublime_linter.py
+++ b/sublime_linter.py
@@ -331,9 +331,19 @@ def get_linters_for_view(view):
         linter_class(view, syntax)
         for linter_class in wanted_linter_classes
     }
-    persist.view_linters[bid] = linters
 
-    view.window().run_command('sublime_linter_assigned', {
+    # It is possible that the user closes the view during debounce time,
+    # in that case `window` will get None and we will just abort. We check
+    # here bc above code is slow enough to make the difference. We don't
+    # pass a valid `window` around bc we do not want to update `view_linters`
+    # for detached views as well bc `on_pre_close` already has been called
+    # at this time.
+    window = view.window()
+    if window is None:
+        return []
+
+    persist.view_linters[bid] = linters
+    window.run_command('sublime_linter_assigned', {
         'bid': bid,
         'linter_names': [linter.name for linter in linters]
     })
@@ -358,13 +368,21 @@ def make_view_has_changed_fn(view):
                 'Aborting lint. SublimeLinter needs a restart of Sublime.')
             return True
 
-        changed = view.change_count() != initial_change_count
-        if changed:
+        if view.buffer_id() == 0:
+            logger.info('View detached (no buffer_id). Aborting lint.')
+            return True
+
+        if view.window() is None:
+            logger.info('View detached (no window). Aborting lint.')
+            return True
+
+        if view.change_count() != initial_change_count:
             logger.info(
                 'Buffer {} inconsistent. Aborting lint.'
                 .format(view.buffer_id()))
+            return True
 
-        return changed
+        return False
 
     return view_has_changed