Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lsp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ settings:
but not find-references.
- `pyrefly.lspPath` [string: '']: if your platform is not supported, you can
build pyrefly from source and specify the binary here.
- `pyrefly.configPath` [string: '']: path to a `pyrefly.toml` or
`pyproject.toml` configuration file. When set, the LSP will use this config
for all files instead of an upward-filesystem-walk discovery approach.
- `python.analysis.showHoverGoToLinks` [boolean: true]: Controls whether hover
tooltips include "Go to definition" and "Go to type definition" navigation
links. Set to `false` for cleaner tooltips with only type information.
6 changes: 6 additions & 0 deletions lsp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@
"type": "boolean",
"default": false,
"description": "Controls whether comment section folding ranges are included in the editor. When true, comments following the pattern '# Section Name ----' (with 4+ trailing dashes) create collapsible regions, similar to R's code section convention."
},
"pyrefly.configPath": {
"type": "string",
"default": "",
"description": "Path to a pyrefly.toml or pyproject.toml configuration file. When set, the LSP will use this config for all files instead of an upward-filesystem-walk config discovery approach.",
"scope": "resource"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pyrefly/lib/commands/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct FilesArgs {
#[arg(long)]
project_excludes: Option<Vec<String>>,

/// Explicitly set the Pyrefly configuration to use when type checking or starting a language server.
/// Explicitly set the Pyrefly configuration to use when type checking.
/// In "single-file checking mode," this config is applied to all files being checked, ignoring
/// the config's `project_includes` and `project_excludes` and ignoring any config-finding approach
/// that would otherwise be used.
Expand Down
9 changes: 9 additions & 0 deletions pyrefly/lib/commands/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
*/

use std::io::Write;
use std::path::PathBuf;
use std::sync::Arc;

use clap::Parser;
use clap::ValueEnum;
use lsp_types::InitializeParams;
use lsp_types::ServerInfo;
use pyrefly_util::args::clap_env;
use pyrefly_util::telemetry::Telemetry;

use crate::commands::util::CommandExitStatus;
Expand Down Expand Up @@ -57,6 +59,12 @@ pub struct LspArgs {
/// an up-to-date source DB. Only useful for benchmarking.
#[arg(long)]
pub(crate) build_system_blocking: bool,

/// Explicitly set the Pyrefly configuration file to use.
/// When set, the LSP will use this config for all files instead of the
/// upward-filesystem-walk discovery approach.
#[arg(long, short, value_name = "FILE", env = clap_env("CONFIG"))]
pub(crate) config: Option<PathBuf>,
}

/// Run LSP server with optional path remapping.
Expand All @@ -80,6 +88,7 @@ pub fn run_lsp(
args.indexing_mode,
args.workspace_indexing_limit,
args.build_system_blocking,
args.config,
path_remapper,
telemetry,
external_references,
Expand Down
1 change: 1 addition & 0 deletions pyrefly/lib/commands/tsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub fn run_tsp(
args.indexing_mode,
args.workspace_indexing_limit,
false,
None, // No explicit config for TSP
surface,
None, // No path remapping for TSP
Arc::new(NoExternalReferences),
Expand Down
26 changes: 25 additions & 1 deletion pyrefly/lib/lsp/non_wasm/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ use crate::binding::binding::KeyClass;
use crate::binding::binding::KeyClassMro;
use crate::commands::lsp::IndexingMode;
use crate::config::config::ConfigFile;
use crate::config::finder::ConfigFinder;
use crate::error::error::Error;
use crate::lsp::module_helpers::to_real_path;
use crate::lsp::non_wasm::build_system::should_requery_build_system;
Expand Down Expand Up @@ -1015,6 +1016,7 @@ pub fn lsp_loop(
indexing_mode: IndexingMode,
workspace_indexing_limit: usize,
build_system_blocking: bool,
config: Option<PathBuf>,
path_remapper: Option<PathRemapper>,
telemetry: &impl Telemetry,
external_references: Arc<dyn ExternalReferences>,
Expand All @@ -1029,6 +1031,7 @@ pub fn lsp_loop(
indexing_mode,
workspace_indexing_limit,
build_system_blocking,
config,
from,
path_remapper,
external_references,
Expand Down Expand Up @@ -1913,6 +1916,7 @@ impl Server {
indexing_mode: IndexingMode,
workspace_indexing_limit: usize,
build_system_blocking: bool,
config: Option<PathBuf>,
surface: Option<String>,
path_remapper: Option<PathRemapper>,
external_references: Arc<dyn ExternalReferences>,
Expand All @@ -1931,7 +1935,27 @@ impl Server {

let workspaces = Arc::new(Workspaces::new(Workspace::default(), &folders));

let config_finder = Workspaces::config_finder(workspaces.dupe());
// Resolve the config path: CLI --config takes precedence, then
// initializationOptions.configPath from the editor.
let explicit_config = config.or_else(|| {
initialize_params
.initialization_options
.as_ref()
.and_then(|opts| opts.get("configPath"))
.and_then(|v| v.as_str())
.filter(|s| !s.is_empty())
.map(PathBuf::from)
});

let config_finder = if let Some(config_path) = explicit_config {
let (mut config_file, mut errors) = ConfigFile::from_file(&config_path);
errors.extend(config_file.configure());
let finder = ConfigFinder::new_constant(ArcId::new(config_file));
finder.add_errors(errors);
finder
} else {
Workspaces::config_finder(workspaces.dupe())
};

// Parse commentFoldingRanges from initialization options, defaults to false
let comment_folding_ranges = initialize_params
Expand Down
1 change: 1 addition & 0 deletions pyrefly/lib/test/lsp/lsp_interaction/object_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,7 @@ impl LspInteraction {
indexing_mode,
workspace_indexing_limit: 50,
build_system_blocking: false,
config: None,
};
let _ = run_lsp(
conn_server,
Expand Down
2 changes: 2 additions & 0 deletions website/docs/IDE.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ The following configuration options are IDE-specific and exposed as VSCode setti
- `python.pyrefly.displayTypeErrors` [enum: default, force-on, force-off, error-missing-imports]: If `'default'`, Pyrefly will only provide type checking diagnostics in the IDE if your file is covered by a [Pyrefly configuration](../configuration). If `'force-off'`, Pyrefly will never provide type check diagnostics in the IDE. If `'force-on'`, Pyrefly will always provide type check diagnostics in the IDE. If `'error-missing-imports'`, Pyrefly will only show errors for missing imports and missing sources (`missing-import`, `missing-source`, and `missing-source-for-stubs`). Note that syntax errors (`invalid-syntax` and `parse-error`) are shown by default in every mode besides `force-off`.
- Specify a custom Pyrefly Binary (lspPath)
- `pyrefly.lspPath` [string: '']: If your platform is not supported, you can build pyrefly from source and specify the binary path with the `lspPath` config.
- Specify a custom configuration file (configPath)
- `pyrefly.configPath` [string: '']: Path to a `pyrefly.toml` or `pyproject.toml` configuration file. When set, the LSP will use this config for all files instead of an upward-filesystem-walk discovery approach.
- Use a specific interpreter
- If the [`Python`](https://marketplace.visualstudio.com/items?itemName=ms-python.python) VSCode extension is installed, [selecting an interpreter](https://code.visualstudio.com/docs/python/environments) will override the interpreter and settings Pyrefly uses to type check your project, even if one is specified in your Pyrefly configuration.
- `python.defaultInterpreterPath` will override the default interpreter selected by VSCode for your workspace.
Expand Down