Skip to content

Conversation

@kv9898
Copy link
Contributor

@kv9898 kv9898 commented Oct 29, 2025

Resolves #1410.

This allows users to choose exactly which IDE features they want enabled, providing flexibility for different workflows and preferences, especially when running multiple Python LSP extensions.

Selective Language Service Disabling

Pyrefly's LSP server supports selective disabling of individual language services via workspace configuration. This allows users to choose exactly which IDE features they want enabled, providing flexibility for different workflows and preferences.

Available Language Services

The following language services can be selectively disabled:

  1. definition - Go-to-definition
  2. typeDefinition - Go-to-type-definition
  3. codeAction - Code actions (quick fixes)
  4. completion - Autocomplete
  5. documentHighlight - Highlight references
  6. references - Find references
  7. rename - Rename symbol
  8. signatureHelp - Parameter hints
  9. hover - Hover tooltips
  10. inlayHint - Inlay hints
  11. documentSymbol - Document symbols (outline)
  12. semanticTokens - Semantic highlighting

Usage

Workspace Configuration

You can configure which language services to disable through your editor's settings or workspace configuration. The configuration is part of the LSP Analysis settings:

VSCode

Add the following to your settings.json (workspace or user settings):

{
  "python.pyrefly.analysis.disabledLanguageServices": {
    "hover": true,
    "documentSymbol": true
  }
}

General LSP Configuration

For other editors that support LSP workspace configuration, send a configuration with the following structure:

{
  "pyrefly": {
    "analysis": {
      "disabledLanguageServices": {
        "hover": true,
        "completion": true,
        "signatureHelp": true
      }
    }
  }
}

Implementation Details

Architecture Decision

The selective disabling is implemented at the workspace configuration level. This design provides several benefits over the previous command-line argument approach:

  1. Dynamic Configuration - Services can be disabled/enabled without restarting the LSP server (unlike command-line flags which required restart)
  2. Per-workspace Control - Different workspace folders can have different service configurations (command-line flags applied globally)
  3. Editor Integration - Works seamlessly with editor configuration systems like VSCode settings (more natural than editing launch arguments)
  4. Standard LSP Pattern - Uses the standard LSP workspace configuration protocol (better compatibility across editors)

How It Works

  1. Workspace Configuration: Each workspace can have its own disabled services configuration in the analysis.disabledLanguageServices field of the LSP analysis config.

  2. Request Handling: When a language service request is received (e.g., hover, completion), the server checks the workspace configuration for the file being edited.

  3. Service Availability: If a service is disabled for that workspace, the server returns None and logs that the request was skipped.

  4. Configuration Changes: When workspace configuration changes, the new settings take effect immediately for subsequent requests.

Use Cases

Scenario 1: Performance Optimization

If you're working on a very large codebase and find that certain language services are slow, you can disable them to improve performance:

{
  "python.pyrefly.analysis.disabledLanguageServices": {
    "references": true,
  }
}

Scenario 2: Conflict Resolution

If you're using multiple language servers and want to use Pyrefly for type checking but another server for certain features:

{
  "python.pyrefly.analysis.disabledLanguageServices": {
    "completion": true,
    "hover": true
  }
}

Scenario 3: Minimal Mode

For a minimal setup with only type checking and go-to-definition:

{
  "python.pyrefly.analysis.disabledLanguageServices": {
    "hover": true,
    "completion": true,
    "signatureHelp": true,
    "documentHighlight": true,
    "documentSymbol": true,
    "semanticTokens": true,
    "inlayHint": true
  }
}

Scenario 4: Per-Workspace Configuration

You can have different configurations for different workspace folders:

{
  "folders": [
    {
      "path": "/path/to/project1",
      "settings": {
        "python.pyrefly.analysis.disabledLanguageServices": {
          "hover": true
        }
      }
    },
    {
      "path": "/path/to/project2",
      "settings": {
        "python.pyrefly.analysis.disabledLanguageServices": {
          "completion": true
        }
      }
    }
  ]
}

Testing

The implementation includes tests to ensure:

  • Workspace configurations are correctly parsed
  • Disabled services return early from request handlers
  • The LSP server functions correctly with services disabled
  • Configuration changes take effect dynamically

To test dynamic configuration changes:

  1. Start the LSP server with a workspace
  2. Make a request for a service (e.g., hover) - it should work
  3. Update the workspace configuration to disable that service
  4. Make the same request again - it should now return no response
  5. Re-enable the service in configuration - it should work again

Run tests with:

cargo test --package pyrefly --lib

@meta-cla
Copy link

meta-cla bot commented Oct 29, 2025

Hi @kv9898!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@kv9898
Copy link
Contributor Author

kv9898 commented Oct 29, 2025

I have now signed the CLA, what should I do next?

@meta-cla
Copy link

meta-cla bot commented Oct 29, 2025

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla bot added the cla signed label Oct 29, 2025
@kv9898 kv9898 force-pushed the feature/lsp-disabling-options branch from 87cf144 to 723f815 Compare October 29, 2025 15:56
@kinto0
Copy link
Contributor

kinto0 commented Oct 29, 2025

hey, thanks for the contribution - this seems really useful. and sorry about the delay in responding to your initial issue yesterday.

I have now signed the CLA, what should I do next?

This is great. All that's required now is an approval from us then a merge.

I wonder if a better place to put these settings would be in the workspace configuration. This has a few benefits:

  • with an extra argument, we can reusing the existing make handle if enabled functionality (to avoid needing this extra check in every method)
  • changing these settings would not require the language server to entirely restart (right now I imagine these lsp args require a window reload to take effect, not very straightforward)
  • editors like VSCode where configurations can be set on a workspace / folder basis would now be accurate if users wanted to disable certain features for certain folders

What do you think? Are there reasons I'm not seeing for why command-line arguments would be easier for your use case?

@kv9898
Copy link
Contributor Author

kv9898 commented Oct 29, 2025

Ahh that makes sense! I thought command line arguments were the only way for this PR to be applicable beyond VSCode. It now seems that there's a protocol for transmitting such config?

@kinto0
Copy link
Contributor

kinto0 commented Oct 29, 2025

Ahh that makes sense! I thought command line arguments were the only way for this PR to be applicable beyond VSCode. It now seems that there's a protocol for transmitting such config?

Yup. There's a few different way to send it (it can be part of the initialize request or as back/forth) but it's all outlined here.

Copilot AI and others added 2 commits October 29, 2025 21:50
…guration (#2)

* Initial plan

* Implement workspace-based language service disabling

Replace command-line arguments with workspace configuration approach.
- Add DisabledLanguageServices to LspAnalysisConfig in workspace.rs
- Create LanguageService enum to identify different services
- Update make_handle_if_enabled to check per-service enablement
- Remove command-line arguments from LspArgs
- Update all LSP handlers to specify which service they use
- Update capabilities() to not depend on disabled services parameter

Co-authored-by: kv9898 <[email protected]>

* Update documentation and fix tests for workspace config approach

- Update selective-language-services.md to document workspace configuration
- Remove old command-line argument references from test files
- Document dynamic configuration benefits

Co-authored-by: kv9898 <[email protected]>

* Add example config file and improve documentation based on code review

- Add example workspace configuration JSON file
- Enhance documentation to explain improvements over command-line approach
- Add testing instructions for dynamic configuration changes

Co-authored-by: kv9898 <[email protected]>

* Add config to package.json

* working

* remove workspace symbol

* remove debugging lines

* remove example json

* fix documentation
@kv9898
Copy link
Contributor Author

kv9898 commented Oct 29, 2025

@kinto0 Job done! It now works well on my machine, would you give it a go? Here's a simple demonstration with clashing hover support:

pyrefly.mp4

I do note that python.pyrefly.analysis.disabledLanguageServices my not be the best config name, please feel free to overwrite my PR.

Copy link
Contributor

@kinto0 kinto0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! I think we should reuse lsp_types to make sure it's consistent with the LS methods.

another thing we should do is update lsp/readme.md and website/docs/IDE.mdx (the customization section).

otherwise looks great! thanks for making the change :)

…vice enum (#3)

* Initial plan

* Replace custom LanguageService enum with lsp_types request METHOD strings

Co-authored-by: kv9898 <[email protected]>

* Apply rustfmt formatting fixes

Co-authored-by: kv9898 <[email protected]>
@kv9898
Copy link
Contributor Author

kv9898 commented Oct 30, 2025

@kinto0 all done!

@meta-codesync
Copy link

meta-codesync bot commented Oct 30, 2025

@kinto0 has imported this pull request. If you are a Meta employee, you can view this in D85869656.

@kv9898
Copy link
Contributor Author

kv9898 commented Oct 30, 2025

@kinto0 Sorry I forgot to update the docs, and have just done that. Note I haven't included a complete list of all options (which can be accessed via package.json) - there are 14 of them and I don't know if it's a good idea to put all of them in.

@kinto0
Copy link
Contributor

kinto0 commented Oct 30, 2025

@kinto0 Sorry I forgot to update the docs, and have just done that. Note I haven't included a complete list of all options (which can be accessed via package.json) - there are 14 of them and I don't know if it's a good idea to put all of them in.

oops - I ended up just adding docs already. there were a few merge conflicts and other things I fixed. once I get a second set of eyes on it, we can merge (ill force push the merge conflict resolution here if I can)

@kv9898
Copy link
Contributor Author

kv9898 commented Oct 30, 2025

@kinto0 haha, don't mind my doc changes then - they are AI generated anyway :)

Copy link
Contributor

@stroxler stroxler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review automatically exported from Phabricator review in Meta.

@meta-codesync
Copy link

meta-codesync bot commented Oct 31, 2025

@kinto0 merged this pull request in 4100d8c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Allow Selective Disabling of Language Services

5 participants