Skip to content

Commit 723f815

Browse files
Copilotkv9898
andcommitted
Remove VSCode extension changes, keep only binary command-line flags
Co-authored-by: kv9898 <[email protected]>
1 parent 4b0933b commit 723f815

File tree

6 files changed

+59
-282
lines changed

6 files changed

+59
-282
lines changed
Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Selective Language Service Disabling
22

3-
Pyrefly's LSP server now supports selective disabling of individual language services. This allows users to choose exactly which IDE features they want enabled, providing flexibility for different workflows and preferences.
3+
Pyrefly's LSP server supports selective disabling of individual language services via command-line arguments. This allows users to choose exactly which IDE features they want enabled, providing flexibility for different workflows and preferences.
44

55
## Available Language Services
66

@@ -22,24 +22,9 @@ The following language services can be selectively disabled:
2222

2323
## Usage
2424

25-
### VSCode Extension
26-
27-
Add the following to your VSCode settings (`.vscode/settings.json` or user settings):
28-
29-
```json
30-
{
31-
"python.pyrefly.disabledLanguageServices": {
32-
"hover": true,
33-
"documentSymbol": true
34-
}
35-
}
36-
```
37-
38-
This example disables hover tooltips and document symbols (outline), while keeping all other services enabled.
39-
4025
### Command-Line Arguments
4126

42-
When starting the LSP server manually, you can use command-line flags:
27+
When starting the LSP server, you can use command-line flags to disable specific services:
4328

4429
```bash
4530
pyrefly lsp --disable-hover --disable-document-symbol
@@ -60,9 +45,9 @@ Available flags:
6045
- `--disable-workspace-symbol`
6146
- `--disable-semantic-tokens`
6247

63-
### Passing Arguments via VSCode Extension
48+
### Configuring via Editor Settings
6449

65-
You can also pass these command-line arguments through the VSCode extension settings:
50+
For editors that support passing arguments to the LSP server (like VSCode), you can configure the arguments through editor settings. For VSCode, use the `pyrefly.lspArguments` setting:
6651

6752
```json
6853
{
@@ -74,26 +59,26 @@ You can also pass these command-line arguments through the VSCode extension sett
7459
}
7560
```
7661

62+
This allows you to configure which services are disabled without manually starting the LSP server.
63+
7764
## Implementation Details
7865

7966
### Architecture Decision
8067

81-
The selective disabling is implemented at the **binary level** (LSP server) rather than the VSCode extension level. This design decision provides several benefits:
68+
The selective disabling is implemented at the **binary level** (LSP server) via command-line arguments. This design provides several benefits:
8269

8370
1. **Cross-editor compatibility** - Works with any editor that uses Pyrefly's LSP server
84-
2. **Cleaner architecture** - The server respects capabilities rather than the client filtering
85-
3. **Performance** - Server doesn't process requests for disabled services
71+
2. **Cleaner architecture** - The server respects capabilities through standard LSP initialization
72+
3. **Performance** - Disabled services are not advertised as capabilities
8673
4. **Maintainability** - Logic is centralized in one place
8774

8875
### How It Works
8976

90-
1. **Initialization**: Disabled services are communicated to the server via:
91-
- Command-line arguments (stored in `LspArgs`)
92-
- IDE configuration (sent via `workspace/configuration` request)
77+
1. **Initialization**: Disabled services are passed via command-line arguments (stored in `LspArgs`)
9378

9479
2. **Capability Negotiation**: The server's `capabilities` function checks disabled services and omits them from the advertised capabilities during LSP initialization.
9580

96-
3. **Runtime Checks**: For services that are disabled via IDE configuration after initialization, the server performs runtime checks before processing requests.
81+
3. **Service Availability**: Once capabilities are negotiated, clients will not request disabled services since they are not advertised.
9782

9883
## Use Cases
9984

@@ -103,10 +88,11 @@ If you're working on a very large codebase and find that certain language servic
10388

10489
```json
10590
{
106-
"python.pyrefly.disabledLanguageServices": {
107-
"references": true,
108-
"workspaceSymbol": true
109-
}
91+
"pyrefly.lspArguments": [
92+
"lsp",
93+
"--disable-references",
94+
"--disable-workspace-symbol"
95+
]
11096
}
11197
```
11298

@@ -116,10 +102,11 @@ If you're using multiple language servers and want to use Pyrefly for type check
116102

117103
```json
118104
{
119-
"python.pyrefly.disabledLanguageServices": {
120-
"completion": true,
121-
"hover": true
122-
}
105+
"pyrefly.lspArguments": [
106+
"lsp",
107+
"--disable-completion",
108+
"--disable-hover"
109+
]
123110
}
124111
```
125112

@@ -129,34 +116,28 @@ For a minimal setup with only type checking and go-to-definition:
129116

130117
```json
131118
{
132-
"python.pyrefly.disabledLanguageServices": {
133-
"hover": true,
134-
"completion": true,
135-
"signatureHelp": true,
136-
"documentHighlight": true,
137-
"documentSymbol": true,
138-
"workspaceSymbol": true,
139-
"semanticTokens": true,
140-
"inlayHint": true
141-
}
119+
"pyrefly.lspArguments": [
120+
"lsp",
121+
"--disable-hover",
122+
"--disable-completion",
123+
"--disable-signature-help",
124+
"--disable-document-highlight",
125+
"--disable-document-symbol",
126+
"--disable-workspace-symbol",
127+
"--disable-semantic-tokens",
128+
"--disable-inlay-hint"
129+
]
142130
}
143131
```
144132

145-
## Backward Compatibility
146-
147-
The existing `python.pyrefly.disableLanguageServices` (plural, present tense) boolean setting still works and will disable **all** language services when set to `true`.
148-
149-
The new `python.pyrefly.disabledLanguageServices` (past tense) object allows for selective disabling of individual services. Both settings are fully backward compatible and can be used independently or together.
150-
151133
## Testing
152134

153-
The implementation includes comprehensive tests to ensure:
154-
- Individual services can be disabled independently
155-
- Other services continue to work when one is disabled
156-
- Configuration changes are applied correctly
157-
- Command-line arguments work as expected
135+
The implementation includes tests to ensure:
136+
- Command-line arguments are correctly parsed
137+
- Disabled services are omitted from capabilities
138+
- The LSP server functions correctly with services disabled
158139

159140
Run tests with:
160141
```bash
161-
cargo test --package pyrefly --lib test::lsp::lsp_interaction::configuration
142+
cargo test --package pyrefly --lib
162143
```

lsp/README.md

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,13 @@ to ensure your project is set up properly, see
2424
The following configuration options are IDE-specific and exposed as VSCode
2525
settings:
2626

27-
- `python.pyrefly.displayTypeErrors` [enum: default, force-on, force-off]: by
27+
- `python.pyrefly.disableTypeErrors` [enum: default, force-on, force-off]: by
2828
default, Pyrefly will only provide type errors in your project if a
2929
`pyrefly.toml` is present. Modify this setting to override the IDE
3030
diagnostics.
3131
- `python.pyrefly.disableLanguageServices` [boolean: false]: by default, Pyrefly
3232
will provide both type errors and other language features like go-to
3333
definition, intellisense, hover, etc. Enable this option to keep type errors
3434
from Pyrefly unchanged but use VSCode's Python extension for everything else.
35-
- `python.pyrefly.disabledLanguageServices` [object]: selectively disable
36-
individual language services. This is an object with boolean properties for
37-
each service: `definition`, `typeDefinition`, `codeAction`, `completion`,
38-
`documentHighlight`, `references`, `rename`, `signatureHelp`, `hover`,
39-
`inlayHint`, `documentSymbol`, `workspaceSymbol`, and `semanticTokens`.
40-
For example, to disable hover and document symbols:
41-
```json
42-
"python.pyrefly.disabledLanguageServices": {
43-
"hover": true,
44-
"documentSymbol": true
45-
}
46-
```
4735
- `pyrefly.lspPath` [string: '']: if your platform is not supported, you can
4836
build pyrefly from source and specify the binary here.

lsp/package.json

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -77,78 +77,6 @@
7777
"default": false,
7878
"description": "If true, pyrefly will not provide other IDE services like completions, hover, definition, etc. To control type errors, see `python.pyrefly.displayTypeErrors`"
7979
},
80-
"python.pyrefly.disabledLanguageServices": {
81-
"type": "object",
82-
"default": {},
83-
"description": "Selectively disable individual language services",
84-
"properties": {
85-
"definition": {
86-
"type": "boolean",
87-
"default": false,
88-
"description": "Disable go-to-definition"
89-
},
90-
"typeDefinition": {
91-
"type": "boolean",
92-
"default": false,
93-
"description": "Disable go-to-type-definition"
94-
},
95-
"codeAction": {
96-
"type": "boolean",
97-
"default": false,
98-
"description": "Disable code actions (quick fixes)"
99-
},
100-
"completion": {
101-
"type": "boolean",
102-
"default": false,
103-
"description": "Disable completion (autocomplete)"
104-
},
105-
"documentHighlight": {
106-
"type": "boolean",
107-
"default": false,
108-
"description": "Disable document highlight"
109-
},
110-
"references": {
111-
"type": "boolean",
112-
"default": false,
113-
"description": "Disable find references"
114-
},
115-
"rename": {
116-
"type": "boolean",
117-
"default": false,
118-
"description": "Disable rename"
119-
},
120-
"signatureHelp": {
121-
"type": "boolean",
122-
"default": false,
123-
"description": "Disable signature help (parameter hints)"
124-
},
125-
"hover": {
126-
"type": "boolean",
127-
"default": false,
128-
"description": "Disable hover (tooltips)"
129-
},
130-
"inlayHint": {
131-
"type": "boolean",
132-
"default": false,
133-
"description": "Disable inlay hints"
134-
},
135-
"documentSymbol": {
136-
"type": "boolean",
137-
"default": false,
138-
"description": "Disable document symbols (outline)"
139-
},
140-
"workspaceSymbol": {
141-
"type": "boolean",
142-
"default": false,
143-
"description": "Disable workspace symbols"
144-
},
145-
"semanticTokens": {
146-
"type": "boolean",
147-
"default": false,
148-
"description": "Disable semantic tokens"
149-
}
150-
}
151-
},
15280
"python.pyrefly.displayTypeErrors": {
15381
"type": "string",
15482
"description": "If 'default', Pyrefly will only provide type check squiggles in the IDE if your file is covered by a Pyrefly configuration. If 'force-off', Pyrefly will never provide type check squiggles in the IDE. If 'force-on', Pyrefly will always provide type check squiggles in the IDE.",

pyrefly/lib/lsp/non_wasm/server.rs

Lines changed: 21 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ use crate::lsp::non_wasm::queue::HeavyTaskQueue;
187187
use crate::lsp::non_wasm::queue::LspEvent;
188188
use crate::lsp::non_wasm::queue::LspQueue;
189189
use crate::lsp::non_wasm::transaction_manager::TransactionManager;
190-
use crate::lsp::non_wasm::workspace::DisabledLanguageServicesConfig;
191190
use crate::lsp::non_wasm::workspace::LspAnalysisConfig;
192191
use crate::lsp::non_wasm::workspace::Workspace;
193192
use crate::lsp::non_wasm::workspace::Workspaces;
@@ -854,28 +853,17 @@ impl Server {
854853
if let Some(params) = self
855854
.extract_request_params_or_send_err_response::<HoverRequest>(params, &x.id)
856855
{
857-
// Check if hover is disabled
858-
if self.is_service_disabled(&params.text_document_position_params.text_document.uri, |d| d.hover.unwrap_or(false)) {
859-
self.send_response(new_response(
860-
x.id,
861-
Ok(Hover {
862-
contents: HoverContents::Array(Vec::new()),
863-
range: None,
864-
}),
865-
));
866-
} else {
867-
let default_response = Hover {
868-
contents: HoverContents::Array(Vec::new()),
869-
range: None,
870-
};
871-
let transaction =
872-
ide_transaction_manager.non_committable_transaction(&self.state);
873-
self.send_response(new_response(
874-
x.id,
875-
Ok(self.hover(&transaction, params).unwrap_or(default_response)),
876-
));
877-
ide_transaction_manager.save(transaction);
878-
}
856+
let default_response = Hover {
857+
contents: HoverContents::Array(Vec::new()),
858+
range: None,
859+
};
860+
let transaction =
861+
ide_transaction_manager.non_committable_transaction(&self.state);
862+
self.send_response(new_response(
863+
x.id,
864+
Ok(self.hover(&transaction, params).unwrap_or(default_response)),
865+
));
866+
ide_transaction_manager.save(transaction);
879867
}
880868
} else if let Some(params) = as_request::<InlayHintRequest>(&x) {
881869
if let Some(params) = self
@@ -937,24 +925,16 @@ impl Server {
937925
params, &x.id,
938926
)
939927
{
940-
// Check if document symbols are disabled
941-
if self.is_service_disabled(&params.text_document.uri, |d| d.document_symbol.unwrap_or(false)) {
942-
self.send_response(new_response(
943-
x.id,
944-
Ok(DocumentSymbolResponse::Nested(Vec::new())),
945-
));
946-
} else {
947-
let transaction =
948-
ide_transaction_manager.non_committable_transaction(&self.state);
949-
self.send_response(new_response(
950-
x.id,
951-
Ok(DocumentSymbolResponse::Nested(
952-
self.hierarchical_document_symbols(&transaction, params)
953-
.unwrap_or_default(),
954-
)),
955-
));
956-
ide_transaction_manager.save(transaction);
957-
}
928+
let transaction =
929+
ide_transaction_manager.non_committable_transaction(&self.state);
930+
self.send_response(new_response(
931+
x.id,
932+
Ok(DocumentSymbolResponse::Nested(
933+
self.hierarchical_document_symbols(&transaction, params)
934+
.unwrap_or_default(),
935+
)),
936+
));
937+
ide_transaction_manager.save(transaction);
958938
}
959939
} else if let Some(params) = as_request::<WorkspaceSymbolRequest>(&x) {
960940
if let Some(params) = self
@@ -1708,22 +1688,6 @@ impl Server {
17081688
.map(|(handle, _)| handle)
17091689
}
17101690

1711-
/// Check if a specific language service is disabled for the given URI
1712-
fn is_service_disabled(&self, uri: &Url, service_check: impl Fn(&DisabledLanguageServicesConfig) -> bool) -> bool {
1713-
let path = uri.to_file_path().unwrap();
1714-
self.workspaces.get_with(path, |(_, workspace)| {
1715-
// First check the global disable_language_services flag
1716-
if workspace.disable_language_services {
1717-
return true;
1718-
}
1719-
// Then check if this specific service is disabled
1720-
if let Some(disabled_services) = &workspace.disabled_language_services {
1721-
return service_check(disabled_services);
1722-
}
1723-
false
1724-
})
1725-
}
1726-
17271691
fn goto_definition(
17281692
&self,
17291693
transaction: &Transaction<'_>,

0 commit comments

Comments
 (0)