Skip to content

Commit 09944f0

Browse files
committed
feat(lsp): add TCP transport support for LSP server
Add optional --port flag to start LSP server over TCP instead of stdio, enabling remote editor connections and easier debugging.
1 parent b548a24 commit 09944f0

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

ci/src/cli/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,15 @@ enum Commands {
8787
about = "Start LSP server for IDE integration",
8888
long_about = "Starts a Language Server Protocol (LSP) server that provides CODEOWNERS information to supported editors"
8989
)]
90-
Lsp,
90+
Lsp {
91+
/// Use stdio for communication (default, flag exists for client compatibility)
92+
#[arg(long, hide = true)]
93+
stdio: bool,
94+
95+
/// Port for TCP communication (if not specified, uses stdio)
96+
#[arg(long, value_name = "PORT")]
97+
port: Option<u16>,
98+
},
9199
}
92100

93101
#[derive(Subcommand, PartialEq, Debug)]
@@ -292,7 +300,7 @@ pub fn cli_match() -> Result<()> {
292300
}
293301
Commands::Config => commands::config::run()?,
294302
#[cfg(feature = "lsp")]
295-
Commands::Lsp => commands::lsp::run()?,
303+
Commands::Lsp { port, .. } => commands::lsp::run(*port)?,
296304
}
297305

298306
Ok(())

codeinput/src/core/commands/lsp.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
use crate::utils::error::Result;
66

77
#[cfg(feature = "tower-lsp")]
8-
use crate::lsp::server::run_lsp_server;
8+
use crate::lsp::server::{run_lsp_server, run_lsp_server_tcp};
99

1010
/// Run the LSP server
1111
#[cfg(feature = "tower-lsp")]
12-
pub fn run() -> Result<()> {
12+
pub fn run(port: Option<u16>) -> Result<()> {
1313
let rt = tokio::runtime::Runtime::new()?;
14-
rt.block_on(async { run_lsp_server().await })
14+
rt.block_on(async {
15+
match port {
16+
Some(p) => run_lsp_server_tcp(p).await,
17+
None => run_lsp_server().await,
18+
}
19+
})
1520
}

codeinput/src/lsp/server.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ fn is_codeowners_file(uri: &Url) -> bool {
474474
path.contains("CODEOWNERS") || path.contains("codeowners")
475475
}
476476

477-
/// Run the LSP server
477+
/// Run the LSP server over stdio
478478
pub async fn run_lsp_server() -> Result<()> {
479479
let stdin = tokio::io::stdin();
480480
let stdout = tokio::io::stdout();
@@ -485,3 +485,21 @@ pub async fn run_lsp_server() -> Result<()> {
485485

486486
Ok(())
487487
}
488+
489+
/// Run the LSP server over TCP
490+
pub async fn run_lsp_server_tcp(port: u16) -> Result<()> {
491+
use tokio::net::TcpListener;
492+
493+
let addr = format!("127.0.0.1:{}", port);
494+
let listener = TcpListener::bind(&addr).await?;
495+
496+
eprintln!("LSP server listening on {}", addr);
497+
498+
loop {
499+
let (stream, _) = listener.accept().await?;
500+
let (read, write) = tokio::io::split(stream);
501+
let (service, socket) = tower_lsp::LspService::new(|client| LspServer::new(client));
502+
503+
tokio::spawn(tower_lsp::Server::new(read, write, socket).serve(service));
504+
}
505+
}

0 commit comments

Comments
 (0)