pub struct LspConfig {
pub program: OsString,
pub args: Vec<OsString>,
pub workspace_root: PathBuf,
pub initialization_options: Option<Value>,
pub workspace_only: bool,
}Fields§
§program: OsString§args: Vec<OsString>§workspace_root: PathBuf§initialization_options: Option<Value>§workspace_only: boolImplementations§
Source§impl LspConfig
impl LspConfig
pub fn new( program: impl Into<OsString>, workspace_root: impl Into<PathBuf>, ) -> Self
Sourcepub fn for_server(
program: impl Into<OsString>,
workspace_root: impl Into<PathBuf>,
) -> Self
pub fn for_server( program: impl Into<OsString>, workspace_root: impl Into<PathBuf>, ) -> Self
Builds the command line expected by a supported language-server binary.
Most servers enter LSP mode directly. Pyrefly exposes it as the
pyrefly lsp subcommand, so callers should use this constructor when
the configured value is a server executable rather than a raw command.
Examples found in repository?
examples/lsp_workspace_symbols.rs (line 22)
7async fn main() -> Result<()> {
8 let mut args = env::args_os().skip(1);
9 let program = args
10 .next()
11 .context("usage: lsp_workspace_symbols <SERVER> <QUERY> [WORKSPACE]")?;
12 let query = args
13 .next()
14 .context("usage: lsp_workspace_symbols <SERVER> <QUERY> [WORKSPACE]")?
15 .into_string()
16 .map_err(|_| anyhow!("query must be valid UTF-8"))?;
17 let workspace_root = match args.next() {
18 Some(path) => PathBuf::from(path),
19 None => env::current_dir().context("failed to determine current directory")?,
20 };
21
22 let lsp = LspProvider::start(LspConfig::for_server(program, workspace_root)).await?;
23 tokio::time::sleep(Duration::from_secs(2)).await;
24 let symbols = lsp.workspace_symbols(&query).await?;
25
26 for symbol in symbols {
27 let line = symbol
28 .range
29 .map(|range| (range.start.line + 1).to_string())
30 .unwrap_or_else(|| "?".to_owned());
31 println!("{}\t{}:{line}", symbol.name, symbol.uri);
32 }
33
34 lsp.shutdown().await
35}More examples
examples/lsp_hierarchy.rs (line 59)
14async fn main() -> Result<()> {
15 let mut args = env::args_os().skip(1);
16 let program = args.next().context(
17 "usage: lsp_hierarchy <SERVER> <call|type> <incoming|outgoing> <SYMBOL> [WORKSPACE]",
18 )?;
19 let kind = match utf8_arg(args.next(), "hierarchy kind")?.as_str() {
20 "call" => HierarchyKind::Call,
21 "type" => HierarchyKind::Type,
22 value => bail!("unknown hierarchy kind {value:?}; expected call or type"),
23 };
24 let direction = match utf8_arg(args.next(), "direction")?.as_str() {
25 "incoming" => HierarchyDirection::Incoming,
26 "outgoing" => HierarchyDirection::Outgoing,
27 value => bail!("unknown direction {value:?}; expected incoming or outgoing"),
28 };
29 let symbol = utf8_arg(args.next(), "symbol")?;
30 let workspace_root = match args.next() {
31 Some(path) => PathBuf::from(path),
32 None => env::current_dir().context("failed to determine current directory")?,
33 };
34 let location = match args.next() {
35 Some(file) => {
36 let file = PathBuf::from(file)
37 .canonicalize()
38 .context("failed to resolve source file")?;
39 let line = utf8_arg(args.next(), "one-based line")?
40 .parse::<u32>()
41 .context("line must be a positive integer")?;
42 let character = utf8_arg(args.next(), "one-based character")?
43 .parse::<u32>()
44 .context("character must be a positive integer")?;
45 if line == 0 || character == 0 {
46 bail!("line and character are one-based and must be positive");
47 }
48 let uri = Url::from_file_path(&file)
49 .map_err(|()| anyhow!("source file cannot be represented as a file URI"))?;
50 Some(SourceLocation {
51 uri: uri.to_string(),
52 line: Some(line - 1),
53 character: Some(character - 1),
54 })
55 }
56 None => None,
57 };
58
59 let lsp = LspProvider::start(LspConfig::for_server(program, workspace_root)).await?;
60 tokio::time::sleep(Duration::from_secs(12)).await;
61 let response = lsp
62 .hierarchy_client()
63 .query(HierarchyQuery {
64 symbol: SymbolIdentity {
65 symbol,
66 kind,
67 location,
68 },
69 direction,
70 })
71 .await;
72
73 let shutdown_result = lsp.shutdown().await;
74 let response = response?;
75 for child in response.children {
76 let location = child.location.map_or_else(
77 || "unknown location".to_owned(),
78 |location| {
79 format!(
80 "{}:{}:{}",
81 location.uri,
82 location.line.unwrap_or(0) + 1,
83 location.character.unwrap_or(0) + 1
84 )
85 },
86 );
87 println!("{}\t{location}", child.symbol);
88 }
89 shutdown_result
90}pub fn arg(self, arg: impl Into<OsString>) -> Self
pub fn args<I, S>(self, args: I) -> Self
pub fn initialization_options(self, options: Value) -> Self
pub fn workspace_only(self, workspace_only: bool) -> Self
Trait Implementations§
Auto Trait Implementations§
impl Freeze for LspConfig
impl RefUnwindSafe for LspConfig
impl Send for LspConfig
impl Sync for LspConfig
impl Unpin for LspConfig
impl UnsafeUnpin for LspConfig
impl UnwindSafe for LspConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more