Repository: sublimelsp/LSP

Issue:
LspTextCommand should honor both session_name and capability if defined
If `capability` in [LspTextCommand](https://github.com/sublimelsp/LSP/blob/81a6e6aeb2c3a6aebad59fbd6eb0361301243bd1/plugin/core/registry.py#L52-L70) is defined, `session_name` is ignored. You might say that LSP-* plugins exactly know the capabilities of their server and thus never need to specify `capability` in a derived class, but in particular it's impossible for plugins to derive from LspExecuteCommand (which is derived from LspTextCommand), because that class already comes with a predefined `capability`. It can be convenient for a plugin to declare a derived class from LspExecuteCommand, so that their commands are only shown/enabled for corresponding filetypes:
```python
class FooExecuteCommand(LspExecuteCommand):
    session_name = "foo"
```

**Describe the solution you'd like**
```python
    def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) -> bool:
        if self.capability:
            # At least one active session with the given capability must exist.
            if not bool(self.best_session(self.capability, get_position(self.view, event, point))):
                return False
        if self.session_name:
            # There must exist an active session with the given (config) name.
            if not bool(self.session_by_name(self.session_name)):
                return False
        if not self.capability and not self.session_name:
            # Any session will do.
            return any(self.sessions())
        return True
```

**Describe alternatives you've considered**
Make `session_name` win against `capability`

**Additional context**
Notice that the implementation suggested above doesn't guarantee that the sessions with the specified name and capability are the same (in case of multiple attached sessions for a view).


Discussion:
Sounds good to me. Would you be willing to make a pull request?

Resolving patch:
diff --git a/plugin/core/registry.py b/plugin/core/registry.py
--- a/plugin/core/registry.py
+++ b/plugin/core/registry.py
@@ -49,25 +49,27 @@ class LspTextCommand(sublime_plugin.TextCommand):
     keybinding.
     """
 
-    # When this is defined in a derived class, the command is enabled if and only if there exists a session attached
-    # to the view that has the given capability. When both `capability` and `session_name` are defined, `capability`
-    # wins.
+    # When this is defined in a derived class, the command is enabled only if there exists a session attached to the
+    # view that has the given capability.
     capability = ''
 
-    # When this is defined in a derived class, the command is enabled if and only if there exists a session attached
-    # to the view that has the given name. When both `capability` and `session_name` are defined, `capability` wins.
+    # When this is defined in a derived class, the command is enabled only if there exists a session attached to the
+    # view that has the given name.
     session_name = ''
 
     def is_enabled(self, event: Optional[dict] = None, point: Optional[int] = None) -> bool:
         if self.capability:
             # At least one active session with the given capability must exist.
-            return bool(self.best_session(self.capability, get_position(self.view, event, point)))
-        elif self.session_name:
+            if not self.best_session(self.capability, get_position(self.view, event, point)):
+                return False
+        if self.session_name:
             # There must exist an active session with the given (config) name.
-            return bool(self.session_by_name(self.session_name))
-        else:
+            if not self.session_by_name(self.session_name):
+                return False
+        if not self.capability and not self.session_name:
             # Any session will do.
             return any(self.sessions())
+        return True
 
     def want_event(self) -> bool:
         return True


Test patch: