Skip to content

Commit f8f57fd

Browse files
authored
Handle "formattingOptions" workspace configuration request (#285)
1 parent e7f86d7 commit f8f57fd

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ Open the configuration file using the Command Palette `Preferences: LSP-typescri
1818
To sort or remove unused imports you can trigger the `LSP-typescript: Organize Imports` command from the Command Palette or create a key binding. For example:
1919

2020
```json
21-
{ "keys": ["ctrl+k"], "command": "lsp_execute",
21+
{
22+
"keys": ["ctrl+k"],
23+
"command": "lsp_execute",
2224
"args": {
2325
"session_name": "LSP-typescript",
2426
"command_name": "_typescript.organizeImports",
@@ -27,6 +29,28 @@ To sort or remove unused imports you can trigger the `LSP-typescript: Organize I
2729
},
2830
```
2931

32+
Optionally you can provide the "mode" option that specifies what type of organization should be performed:
33+
34+
```jsonc
35+
{
36+
"keys": ["ctrl+k"],
37+
"command": "lsp_execute",
38+
"args": {
39+
"session_name": "LSP-typescript",
40+
"command_name": "_typescript.organizeImports",
41+
"command_args": [
42+
"${file}",
43+
{
44+
// 'All' - organizes imports including destructive actions (removing unused imports)
45+
// 'SortAndCombine' - Doesn't perform destructive actions.
46+
// 'RemoveUnused' - Only removes unused imports.
47+
"mode": "RemoveUnused"
48+
}
49+
]
50+
}
51+
},
52+
```
53+
3054
## Code Actions on Save
3155

3256
The server supports the following code actions that can be specified in the global `lsp_code_actions_on_save` setting and run on saving files:

plugin.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,22 @@
99
from LSP.plugin import ClientConfig
1010
from LSP.plugin import parse_uri
1111
from LSP.plugin import WorkspaceFolder
12-
from LSP.plugin.core.protocol import Error, Point, TextDocumentPositionParams, ExecuteCommandParams
13-
from LSP.plugin.core.typing import cast, Callable, List, Optional, Tuple
12+
from LSP.plugin.core.protocol import Error, Point
1413
from LSP.plugin.core.views import point_to_offset
1514
from LSP.plugin.locationpicker import LocationPicker
1615
from lsp_utils import notification_handler
1716
from lsp_utils import NpmClientHandler
1817
from lsp_utils import request_handler
1918
from pathlib import Path
2019
from sublime_lib import ResourcePath
20+
from typing import TYPE_CHECKING, Any, cast, Callable
21+
from typing_extensions import override
2122
import os
2223
import sublime
2324

25+
if TYPE_CHECKING:
26+
from LSP.protocol import ConfigurationItem, ExecuteCommandParams, TextDocumentPositionParams
27+
2428

2529
MOVE_TO_FILE_QUICK_PANEL_ITEMS: list[MoveToFileQuickPanelItem] = [
2630
{'id': MoveToFileQuickPanelItemId.ExistingFile, 'title': 'Select existing file...'},
@@ -81,8 +85,8 @@ class LspTypescriptPlugin(NpmClientHandler):
8185
typescript_plugins: list[TypescriptPluginContribution] | None = None
8286

8387
@classmethod
84-
def minimum_node_version(cls) -> Tuple[int, int, int]:
85-
return (14, 16, 0)
88+
def minimum_node_version(cls) -> tuple[int, int, int]:
89+
return (20, 0, 0)
8690

8791
@classmethod
8892
def selector(cls, view: sublime.View, config: ClientConfig) -> str:
@@ -95,10 +99,10 @@ def selector(cls, view: sublime.View, config: ClientConfig) -> str:
9599

96100
@classmethod
97101
def on_pre_start(cls, window: sublime.Window, initiating_view: sublime.View,
98-
workspace_folders: List[WorkspaceFolder], configuration: ClientConfig) -> Optional[str]:
102+
workspace_folders: list[WorkspaceFolder], configuration: ClientConfig) -> str | None:
99103
plugins = configuration.init_options.get('plugins') or []
100104
for ts_plugin in cls._get_typescript_plugins():
101-
plugin = {
105+
plugin: TypescriptPluginContribution = {
102106
'name': ts_plugin['name'],
103107
'location': ts_plugin['location'],
104108
}
@@ -140,10 +144,24 @@ def on_typescript_version_async(self, params: TypescriptVersionNotificationParam
140144
if status_text:
141145
session.set_config_status_async(status_text)
142146

147+
@override
148+
def on_workspace_configuration(self, params: ConfigurationItem, configuration: Any) -> Any:
149+
if params.get('section') == 'formattingOptions' and (scope_uri := params.get('scopeUri')) \
150+
and (session := self.weaksession()) \
151+
and (buf := session.get_session_buffer_for_uri_async(scope_uri)) \
152+
and (session_view := next(iter(buf.session_views), None)):
153+
view_settings = session_view.view.settings()
154+
return {
155+
**(configuration if isinstance(configuration, dict) else {}),
156+
'tabSize': view_settings.get('tab_size'),
157+
'insertSpaces': view_settings.get('translate_tabs_to_spaces'),
158+
}
159+
return configuration
160+
143161
def on_pre_server_command(self, command: ExecuteCommandParams, done_callback: Callable[[], None]) -> bool:
144162
command_name = command['command']
145163
if command_name == 'editor.action.showReferences':
146-
references_command = cast(ShowReferencesCommand, command)
164+
references_command = cast('ShowReferencesCommand', command)
147165
self._handle_show_references(references_command)
148166
done_callback()
149167
return True

plugin_types.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
from __future__ import annotations
2-
from LSP.plugin.core.protocol import Location, Position
3-
from LSP.plugin.core.typing import List, Literal, NotRequired, StrEnum, Tuple, TypedDict, Union
2+
from LSP.plugin.core.typing import StrEnum
3+
from typing import TYPE_CHECKING, Literal, TypedDict
4+
from typing_extensions import NotRequired
5+
6+
if TYPE_CHECKING:
7+
from LSP.protocol import Location, Position
48

59

610
class TypescriptVersionNotificationParams(TypedDict):
711
version: str
8-
source: Union[Literal['bundled'], Literal['user-setting'], Literal['workspace']]
12+
source: Literal['bundled', 'user-setting', 'workspace']
913

1014

1115
class TypescriptPluginContribution(TypedDict):
1216
name: str
13-
languages: NotRequired[List[str]]
17+
languages: NotRequired[list[str]]
1418
location: str
1519
selector: NotRequired[str]
1620

@@ -27,7 +31,7 @@ class ApplyRefactoringArgument(TypedDict):
2731

2832
class ApplyRefactoringCommand(TypedDict):
2933
command: str
30-
arguments: Tuple[ApplyRefactoringArgument]
34+
arguments: tuple[ApplyRefactoringArgument]
3135

3236

3337
class MoveToFileQuickPanelItemId(StrEnum):
@@ -42,4 +46,4 @@ class MoveToFileQuickPanelItem(TypedDict):
4246

4347
class ShowReferencesCommand(TypedDict):
4448
command: str
45-
arguments: Tuple[str, Position, List[Location]]
49+
arguments: tuple[str, Position, list[Location]]

0 commit comments

Comments
 (0)