We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Option to disable validation underline and hover
Similar to https://github.com/sublimelsp/LSP/issues/762 but not looking to disable completely, just the underline (and hover) in the document.  Since the gutter mark can be disabled, why not the underline?

As far as I can tell, the capabilities provided by linters can go well beyond what the language servers provide in terms of identifying (and fixing) code style type issues.  If not disabling entirely, disabling underline (and hover) would eliminate the "collision"/duplication issues.  Would be especially useful if configurable by language.

FWIW, VSCode provides options to disable validations for languages.  Examples for Javascript and CSS:

![image](https://user-images.githubusercontent.com/1944277/72464066-9e66fa80-37a2-11ea-858b-1413860a74a5.png)

![image](https://user-images.githubusercontent.com/1944277/72463537-73c87200-37a1-11ea-8f6c-cad21f93fccf.png)



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugin/session_view.py`
Content:
```
1 from .core.protocol import Diagnostic
2 from .core.sessions import Session
3 from .core.types import view2scope
4 from .core.typing import Any, Iterable, List, Tuple
5 from .core.views import DIAGNOSTIC_SEVERITY
6 from .core.windows import AbstractViewListener
7 from .session_buffer import SessionBuffer
8 from weakref import ref
9 from weakref import WeakValueDictionary
10 import sublime
11 
12 
13 class SessionView:
14     """
15     Holds state per session per view.
16     """
17 
18     LANGUAGE_ID_KEY = "lsp_language"
19     SHOW_DEFINITIONS_KEY = "show_definitions"
20     HOVER_PROVIDER_KEY = "hoverProvider"
21     HOVER_PROVIDER_COUNT_KEY = "lsp_hover_provider_count"
22 
23     _session_buffers = WeakValueDictionary()  # type: WeakValueDictionary[Tuple[str, int], SessionBuffer]
24 
25     def __init__(self, listener: AbstractViewListener, session: Session) -> None:
26         self.view = listener.view
27         self.session = session
28         settings = self.view.settings()
29         # TODO: Language ID must be UNIQUE!
30         languages = settings.get(self.LANGUAGE_ID_KEY)
31         self._language_id = ''
32         if not isinstance(languages, dict):
33             languages = {}
34         for language in session.config.languages:
35             if language.match_scope(view2scope(self.view)):
36                 languages[session.config.name] = language.id
37                 self._language_id = language.id
38                 break
39         settings.set(self.LANGUAGE_ID_KEY, languages)
40         buffer_id = self.view.buffer_id()
41         key = (session.config.name, buffer_id)
42         session_buffer = self._session_buffers.get(key)
43         if session_buffer is None:
44             session_buffer = SessionBuffer(self, buffer_id, self._language_id)
45             self._session_buffers[key] = session_buffer
46         else:
47             session_buffer.add_session_view(self)
48         self.session_buffer = session_buffer
49         self.listener = ref(listener)
50         session.register_session_view_async(self)
51         session.config.set_view_status(self.view, "")
52         if self.session.has_capability(self.HOVER_PROVIDER_KEY):
53             self._increment_hover_count()
54 
55     def __del__(self) -> None:
56         if self.session.has_capability(self.HOVER_PROVIDER_KEY):
57             self._decrement_hover_count()
58         # If the session is exiting then there's no point in sending textDocument/didClose and there's also no point
59         # in unregistering ourselves from the session.
60         if not self.session.exiting:
61             self.session.unregister_session_view_async(self)
62         self.session.config.erase_view_status(self.view)
63         settings = self.view.settings()  # type: sublime.Settings
64         # TODO: Language ID must be UNIQUE!
65         languages = settings.get(self.LANGUAGE_ID_KEY)
66         if isinstance(languages, dict):
67             languages.pop(self.session.config.name, None)
68             if languages:
69                 settings.set(self.LANGUAGE_ID_KEY, languages)
70             else:
71                 settings.erase(self.LANGUAGE_ID_KEY)
72         for severity in range(1, len(DIAGNOSTIC_SEVERITY) + 1):
73             self.view.erase_regions(self.diagnostics_key(severity))
74 
75     def _increment_hover_count(self) -> None:
76         settings = self.view.settings()
77         count = settings.get(self.HOVER_PROVIDER_COUNT_KEY, 0)
78         if isinstance(count, int):
79             count += 1
80             settings.set(self.HOVER_PROVIDER_COUNT_KEY, count)
81             settings.set(self.SHOW_DEFINITIONS_KEY, False)
82 
83     def _decrement_hover_count(self) -> None:
84         settings = self.view.settings()
85         count = settings.get(self.HOVER_PROVIDER_COUNT_KEY)
86         if isinstance(count, int):
87             count -= 1
88             if count == 0:
89                 settings.erase(self.HOVER_PROVIDER_COUNT_KEY)
90                 settings.set(self.SHOW_DEFINITIONS_KEY, True)
91 
92     def register_capability_async(self, capability_path: str, options: Any) -> None:
93         if capability_path == self.HOVER_PROVIDER_KEY:
94             self._increment_hover_count()
95 
96     def unregister_capability_async(self, capability_path: str) -> None:
97         if capability_path == self.HOVER_PROVIDER_KEY:
98             self._decrement_hover_count()
99 
100     def shutdown_async(self) -> None:
101         listener = self.listener()
102         if listener:
103             listener.on_session_shutdown_async(self.session)
104 
105     def diagnostics_key(self, severity: int) -> str:
106         return "lsp{}d{}".format(self.session.config.name, severity)
107 
108     def present_diagnostics_async(self, flags: int) -> None:
109         data_per_severity = self.session_buffer.data_per_severity
110         for severity in reversed(range(1, len(DIAGNOSTIC_SEVERITY) + 1)):
111             key = self.diagnostics_key(severity)
112             data = data_per_severity.get(severity)
113             if data is None:
114                 self.view.erase_regions(key)
115             elif data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE):
116                 self.view.add_regions(key, data.regions, data.scope, data.icon, flags)
117             else:
118                 self.view.erase_regions(key)
119         listener = self.listener()
120         if listener:
121             listener.update_total_errors_and_warnings_status_async()
122             listener.update_diagnostic_in_status_bar_async()
123 
124     def get_diagnostics_async(self) -> List[Diagnostic]:
125         return self.session_buffer.diagnostics
126 
127     def on_text_changed_async(self, changes: Iterable[sublime.TextChange]) -> None:
128         self.session_buffer.on_text_changed_async(changes)
129 
130     def on_revert_async(self) -> None:
131         self.session_buffer.on_revert_async()
132 
133     def on_reload_async(self) -> None:
134         self.session_buffer.on_reload_async()
135 
136     def purge_changes_async(self) -> None:
137         self.session_buffer.purge_changes_async()
138 
139     def on_pre_save_async(self, old_file_name: str) -> None:
140         self.session_buffer.on_pre_save_async(old_file_name)
141 
142     def on_post_save_async(self) -> None:
143         self.session_buffer.on_post_save_async()
144 
145     def __str__(self) -> str:
146         return '{}:{}'.format(self.session.config.name, self.view.id())
147
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plugin/session_view.py b/plugin/session_view.py
--- a/plugin/session_view.py
+++ b/plugin/session_view.py
@@ -1,5 +1,6 @@
 from .core.protocol import Diagnostic
 from .core.sessions import Session
+from .core.settings import settings as global_settings
 from .core.types import view2scope
 from .core.typing import Any, Iterable, List, Tuple
 from .core.views import DIAGNOSTIC_SEVERITY
@@ -112,7 +113,8 @@
             data = data_per_severity.get(severity)
             if data is None:
                 self.view.erase_regions(key)
-            elif data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE):
+            elif ((severity <= global_settings.show_diagnostics_severity_level) and
+                    (data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE))):
                 self.view.add_regions(key, data.regions, data.scope, data.icon, flags)
             else:
                 self.view.erase_regions(key)

{"golden_diff": "diff --git a/plugin/session_view.py b/plugin/session_view.py\n--- a/plugin/session_view.py\n+++ b/plugin/session_view.py\n@@ -1,5 +1,6 @@\n from .core.protocol import Diagnostic\n from .core.sessions import Session\n+from .core.settings import settings as global_settings\n from .core.types import view2scope\n from .core.typing import Any, Iterable, List, Tuple\n from .core.views import DIAGNOSTIC_SEVERITY\n@@ -112,7 +113,8 @@\n             data = data_per_severity.get(severity)\n             if data is None:\n                 self.view.erase_regions(key)\n-            elif data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE):\n+            elif ((severity <= global_settings.show_diagnostics_severity_level) and\n+                    (data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE))):\n                 self.view.add_regions(key, data.regions, data.scope, data.icon, flags)\n             else:\n                 self.view.erase_regions(key)\n", "issue": "Option to disable validation underline and hover\nSimilar to https://github.com/sublimelsp/LSP/issues/762 but not looking to disable completely, just the underline (and hover) in the document.  Since the gutter mark can be disabled, why not the underline?\r\n\r\nAs far as I can tell, the capabilities provided by linters can go well beyond what the language servers provide in terms of identifying (and fixing) code style type issues.  If not disabling entirely, disabling underline (and hover) would eliminate the \"collision\"/duplication issues.  Would be especially useful if configurable by language.\r\n\r\nFWIW, VSCode provides options to disable validations for languages.  Examples for Javascript and CSS:\r\n\r\n![image](https://user-images.githubusercontent.com/1944277/72464066-9e66fa80-37a2-11ea-858b-1413860a74a5.png)\r\n\r\n![image](https://user-images.githubusercontent.com/1944277/72463537-73c87200-37a1-11ea-8f6c-cad21f93fccf.png)\r\n\r\n\n", "before_files": [{"content": "from .core.protocol import Diagnostic\nfrom .core.sessions import Session\nfrom .core.types import view2scope\nfrom .core.typing import Any, Iterable, List, Tuple\nfrom .core.views import DIAGNOSTIC_SEVERITY\nfrom .core.windows import AbstractViewListener\nfrom .session_buffer import SessionBuffer\nfrom weakref import ref\nfrom weakref import WeakValueDictionary\nimport sublime\n\n\nclass SessionView:\n    \"\"\"\n    Holds state per session per view.\n    \"\"\"\n\n    LANGUAGE_ID_KEY = \"lsp_language\"\n    SHOW_DEFINITIONS_KEY = \"show_definitions\"\n    HOVER_PROVIDER_KEY = \"hoverProvider\"\n    HOVER_PROVIDER_COUNT_KEY = \"lsp_hover_provider_count\"\n\n    _session_buffers = WeakValueDictionary()  # type: WeakValueDictionary[Tuple[str, int], SessionBuffer]\n\n    def __init__(self, listener: AbstractViewListener, session: Session) -> None:\n        self.view = listener.view\n        self.session = session\n        settings = self.view.settings()\n        # TODO: Language ID must be UNIQUE!\n        languages = settings.get(self.LANGUAGE_ID_KEY)\n        self._language_id = ''\n        if not isinstance(languages, dict):\n            languages = {}\n        for language in session.config.languages:\n            if language.match_scope(view2scope(self.view)):\n                languages[session.config.name] = language.id\n                self._language_id = language.id\n                break\n        settings.set(self.LANGUAGE_ID_KEY, languages)\n        buffer_id = self.view.buffer_id()\n        key = (session.config.name, buffer_id)\n        session_buffer = self._session_buffers.get(key)\n        if session_buffer is None:\n            session_buffer = SessionBuffer(self, buffer_id, self._language_id)\n            self._session_buffers[key] = session_buffer\n        else:\n            session_buffer.add_session_view(self)\n        self.session_buffer = session_buffer\n        self.listener = ref(listener)\n        session.register_session_view_async(self)\n        session.config.set_view_status(self.view, \"\")\n        if self.session.has_capability(self.HOVER_PROVIDER_KEY):\n            self._increment_hover_count()\n\n    def __del__(self) -> None:\n        if self.session.has_capability(self.HOVER_PROVIDER_KEY):\n            self._decrement_hover_count()\n        # If the session is exiting then there's no point in sending textDocument/didClose and there's also no point\n        # in unregistering ourselves from the session.\n        if not self.session.exiting:\n            self.session.unregister_session_view_async(self)\n        self.session.config.erase_view_status(self.view)\n        settings = self.view.settings()  # type: sublime.Settings\n        # TODO: Language ID must be UNIQUE!\n        languages = settings.get(self.LANGUAGE_ID_KEY)\n        if isinstance(languages, dict):\n            languages.pop(self.session.config.name, None)\n            if languages:\n                settings.set(self.LANGUAGE_ID_KEY, languages)\n            else:\n                settings.erase(self.LANGUAGE_ID_KEY)\n        for severity in range(1, len(DIAGNOSTIC_SEVERITY) + 1):\n            self.view.erase_regions(self.diagnostics_key(severity))\n\n    def _increment_hover_count(self) -> None:\n        settings = self.view.settings()\n        count = settings.get(self.HOVER_PROVIDER_COUNT_KEY, 0)\n        if isinstance(count, int):\n            count += 1\n            settings.set(self.HOVER_PROVIDER_COUNT_KEY, count)\n            settings.set(self.SHOW_DEFINITIONS_KEY, False)\n\n    def _decrement_hover_count(self) -> None:\n        settings = self.view.settings()\n        count = settings.get(self.HOVER_PROVIDER_COUNT_KEY)\n        if isinstance(count, int):\n            count -= 1\n            if count == 0:\n                settings.erase(self.HOVER_PROVIDER_COUNT_KEY)\n                settings.set(self.SHOW_DEFINITIONS_KEY, True)\n\n    def register_capability_async(self, capability_path: str, options: Any) -> None:\n        if capability_path == self.HOVER_PROVIDER_KEY:\n            self._increment_hover_count()\n\n    def unregister_capability_async(self, capability_path: str) -> None:\n        if capability_path == self.HOVER_PROVIDER_KEY:\n            self._decrement_hover_count()\n\n    def shutdown_async(self) -> None:\n        listener = self.listener()\n        if listener:\n            listener.on_session_shutdown_async(self.session)\n\n    def diagnostics_key(self, severity: int) -> str:\n        return \"lsp{}d{}\".format(self.session.config.name, severity)\n\n    def present_diagnostics_async(self, flags: int) -> None:\n        data_per_severity = self.session_buffer.data_per_severity\n        for severity in reversed(range(1, len(DIAGNOSTIC_SEVERITY) + 1)):\n            key = self.diagnostics_key(severity)\n            data = data_per_severity.get(severity)\n            if data is None:\n                self.view.erase_regions(key)\n            elif data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE):\n                self.view.add_regions(key, data.regions, data.scope, data.icon, flags)\n            else:\n                self.view.erase_regions(key)\n        listener = self.listener()\n        if listener:\n            listener.update_total_errors_and_warnings_status_async()\n            listener.update_diagnostic_in_status_bar_async()\n\n    def get_diagnostics_async(self) -> List[Diagnostic]:\n        return self.session_buffer.diagnostics\n\n    def on_text_changed_async(self, changes: Iterable[sublime.TextChange]) -> None:\n        self.session_buffer.on_text_changed_async(changes)\n\n    def on_revert_async(self) -> None:\n        self.session_buffer.on_revert_async()\n\n    def on_reload_async(self) -> None:\n        self.session_buffer.on_reload_async()\n\n    def purge_changes_async(self) -> None:\n        self.session_buffer.purge_changes_async()\n\n    def on_pre_save_async(self, old_file_name: str) -> None:\n        self.session_buffer.on_pre_save_async(old_file_name)\n\n    def on_post_save_async(self) -> None:\n        self.session_buffer.on_post_save_async()\n\n    def __str__(self) -> str:\n        return '{}:{}'.format(self.session.config.name, self.view.id())\n", "path": "plugin/session_view.py"}], "after_files": [{"content": "from .core.protocol import Diagnostic\nfrom .core.sessions import Session\nfrom .core.settings import settings as global_settings\nfrom .core.types import view2scope\nfrom .core.typing import Any, Iterable, List, Tuple\nfrom .core.views import DIAGNOSTIC_SEVERITY\nfrom .core.windows import AbstractViewListener\nfrom .session_buffer import SessionBuffer\nfrom weakref import ref\nfrom weakref import WeakValueDictionary\nimport sublime\n\n\nclass SessionView:\n    \"\"\"\n    Holds state per session per view.\n    \"\"\"\n\n    LANGUAGE_ID_KEY = \"lsp_language\"\n    SHOW_DEFINITIONS_KEY = \"show_definitions\"\n    HOVER_PROVIDER_KEY = \"hoverProvider\"\n    HOVER_PROVIDER_COUNT_KEY = \"lsp_hover_provider_count\"\n\n    _session_buffers = WeakValueDictionary()  # type: WeakValueDictionary[Tuple[str, int], SessionBuffer]\n\n    def __init__(self, listener: AbstractViewListener, session: Session) -> None:\n        self.view = listener.view\n        self.session = session\n        settings = self.view.settings()\n        # TODO: Language ID must be UNIQUE!\n        languages = settings.get(self.LANGUAGE_ID_KEY)\n        self._language_id = ''\n        if not isinstance(languages, dict):\n            languages = {}\n        for language in session.config.languages:\n            if language.match_scope(view2scope(self.view)):\n                languages[session.config.name] = language.id\n                self._language_id = language.id\n                break\n        settings.set(self.LANGUAGE_ID_KEY, languages)\n        buffer_id = self.view.buffer_id()\n        key = (session.config.name, buffer_id)\n        session_buffer = self._session_buffers.get(key)\n        if session_buffer is None:\n            session_buffer = SessionBuffer(self, buffer_id, self._language_id)\n            self._session_buffers[key] = session_buffer\n        else:\n            session_buffer.add_session_view(self)\n        self.session_buffer = session_buffer\n        self.listener = ref(listener)\n        session.register_session_view_async(self)\n        session.config.set_view_status(self.view, \"\")\n        if self.session.has_capability(self.HOVER_PROVIDER_KEY):\n            self._increment_hover_count()\n\n    def __del__(self) -> None:\n        if self.session.has_capability(self.HOVER_PROVIDER_KEY):\n            self._decrement_hover_count()\n        # If the session is exiting then there's no point in sending textDocument/didClose and there's also no point\n        # in unregistering ourselves from the session.\n        if not self.session.exiting:\n            self.session.unregister_session_view_async(self)\n        self.session.config.erase_view_status(self.view)\n        settings = self.view.settings()  # type: sublime.Settings\n        # TODO: Language ID must be UNIQUE!\n        languages = settings.get(self.LANGUAGE_ID_KEY)\n        if isinstance(languages, dict):\n            languages.pop(self.session.config.name, None)\n            if languages:\n                settings.set(self.LANGUAGE_ID_KEY, languages)\n            else:\n                settings.erase(self.LANGUAGE_ID_KEY)\n        for severity in range(1, len(DIAGNOSTIC_SEVERITY) + 1):\n            self.view.erase_regions(self.diagnostics_key(severity))\n\n    def _increment_hover_count(self) -> None:\n        settings = self.view.settings()\n        count = settings.get(self.HOVER_PROVIDER_COUNT_KEY, 0)\n        if isinstance(count, int):\n            count += 1\n            settings.set(self.HOVER_PROVIDER_COUNT_KEY, count)\n            settings.set(self.SHOW_DEFINITIONS_KEY, False)\n\n    def _decrement_hover_count(self) -> None:\n        settings = self.view.settings()\n        count = settings.get(self.HOVER_PROVIDER_COUNT_KEY)\n        if isinstance(count, int):\n            count -= 1\n            if count == 0:\n                settings.erase(self.HOVER_PROVIDER_COUNT_KEY)\n                settings.set(self.SHOW_DEFINITIONS_KEY, True)\n\n    def register_capability_async(self, capability_path: str, options: Any) -> None:\n        if capability_path == self.HOVER_PROVIDER_KEY:\n            self._increment_hover_count()\n\n    def unregister_capability_async(self, capability_path: str) -> None:\n        if capability_path == self.HOVER_PROVIDER_KEY:\n            self._decrement_hover_count()\n\n    def shutdown_async(self) -> None:\n        listener = self.listener()\n        if listener:\n            listener.on_session_shutdown_async(self.session)\n\n    def diagnostics_key(self, severity: int) -> str:\n        return \"lsp{}d{}\".format(self.session.config.name, severity)\n\n    def present_diagnostics_async(self, flags: int) -> None:\n        data_per_severity = self.session_buffer.data_per_severity\n        for severity in reversed(range(1, len(DIAGNOSTIC_SEVERITY) + 1)):\n            key = self.diagnostics_key(severity)\n            data = data_per_severity.get(severity)\n            if data is None:\n                self.view.erase_regions(key)\n            elif ((severity <= global_settings.show_diagnostics_severity_level) and\n                    (data.icon or flags != (sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE))):\n                self.view.add_regions(key, data.regions, data.scope, data.icon, flags)\n            else:\n                self.view.erase_regions(key)\n        listener = self.listener()\n        if listener:\n            listener.update_total_errors_and_warnings_status_async()\n            listener.update_diagnostic_in_status_bar_async()\n\n    def get_diagnostics_async(self) -> List[Diagnostic]:\n        return self.session_buffer.diagnostics\n\n    def on_text_changed_async(self, changes: Iterable[sublime.TextChange]) -> None:\n        self.session_buffer.on_text_changed_async(changes)\n\n    def on_revert_async(self) -> None:\n        self.session_buffer.on_revert_async()\n\n    def on_reload_async(self) -> None:\n        self.session_buffer.on_reload_async()\n\n    def purge_changes_async(self) -> None:\n        self.session_buffer.purge_changes_async()\n\n    def on_pre_save_async(self, old_file_name: str) -> None:\n        self.session_buffer.on_pre_save_async(old_file_name)\n\n    def on_post_save_async(self) -> None:\n        self.session_buffer.on_post_save_async()\n\n    def __str__(self) -> str:\n        return '{}:{}'.format(self.session.config.name, self.view.id())\n", "path": "plugin/session_view.py"}]}