on master help sign in
Add unique id to each lsp client/server pair
38cb934wojciechkepka
helix-lsp/src/client.rs+12−2
@@ -18,6 +18,7 @@ use tokio::{
18
18
19#[derive(Debug)]
19#[derive(Debug)]
20pub struct Client {
20pub struct Client {
21+ id: usize,
21 _process: Child,
22 _process: Child,
22 server_tx: UnboundedSender<Payload>,
23 server_tx: UnboundedSender<Payload>,
23 request_counter: AtomicU64,
24 request_counter: AtomicU64,
@@ -26,7 +27,11 @@ pub struct Client {
26}
27}
27
28
28impl Client {
29impl Client {
30+ pub fn start(
31+ cmd: &str,
32+ args: &[String],
33+ id: usize,
29− pub fn start(cmd: &str, args: &[String]) -> Result<(Self, UnboundedReceiver<Call>)> {
34+ ) -> Result<(Self, UnboundedReceiver<(usize, Call)>)> {
30 let process = Command::new(cmd)
35 let process = Command::new(cmd)
31 .args(args)
36 .args(args)
32 .stdin(Stdio::piped())
37 .stdin(Stdio::piped())
@@ -43,9 +48,10 @@ impl Client {
43 let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
48 let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
44 let stderr = BufReader::new(process.stderr.take().expect("Failed to open stderr"));
49 let stderr = BufReader::new(process.stderr.take().expect("Failed to open stderr"));
45
50
46− let (server_rx, server_tx) = Transport::start(reader, writer, stderr);
51+ let (server_rx, server_tx) = Transport::start(reader, writer, stderr, id);
47
52
48 let client = Self {
53 let client = Self {
54+ id,
49 _process: process,
55 _process: process,
50 server_tx,
56 server_tx,
51 request_counter: AtomicU64::new(0),
57 request_counter: AtomicU64::new(0),
@@ -59,6 +65,10 @@ impl Client {
59 Ok((client, server_rx))
65 Ok((client, server_rx))
60 }
66 }
61
67
68+ pub fn id(&self) -> usize {
69+ self.id
70+ }
71+
62 fn next_request_id(&self) -> jsonrpc::Id {
72 fn next_request_id(&self) -> jsonrpc::Id {
63 let id = self.request_counter.fetch_add(1, Ordering::Relaxed);
73 let id = self.request_counter.fetch_add(1, Ordering::Relaxed);
64 jsonrpc::Id::Num(id)
74 jsonrpc::Id::Num(id)
helix-lsp/src/lib.rs+19−6
@@ -13,7 +13,10 @@ use helix_core::syntax::LanguageConfiguration;
13
13
14use std::{
14use std::{
15 collections::{hash_map::Entry, HashMap},
15 collections::{hash_map::Entry, HashMap},
16− sync::Arc,
16+ sync::{
17+ atomic::{AtomicUsize, Ordering},
18+ Arc,
19+ },
17};
20};
18
21
19use serde::{Deserialize, Serialize};
22use serde::{Deserialize, Serialize};
@@ -254,9 +257,10 @@ impl Notification {
254
257
255#[derive(Debug)]
258#[derive(Debug)]
256pub struct Registry {
259pub struct Registry {
257− inner: HashMap<LanguageId, Arc<Client>>,
260+ inner: HashMap<LanguageId, (usize, Arc<Client>)>,
258
261
262+ counter: AtomicUsize,
259− pub incoming: SelectAll<UnboundedReceiverStream<Call>>,
263+ pub incoming: SelectAll<UnboundedReceiverStream<(usize, Call)>>,
260}
264}
261
265
262impl Default for Registry {
266impl Default for Registry {
@@ -269,10 +273,18 @@ impl Registry {
269 pub fn new() -> Self {
273 pub fn new() -> Self {
270 Self {
274 Self {
271 inner: HashMap::new(),
275 inner: HashMap::new(),
276+ counter: AtomicUsize::new(0),
272 incoming: SelectAll::new(),
277 incoming: SelectAll::new(),
273 }
278 }
274 }
279 }
275
280
281+ pub fn get_by_id(&mut self, id: usize) -> Option<&Client> {
282+ self.inner
283+ .values()
284+ .find(|(client_id, _)| client_id == &id)
285+ .map(|(_, client)| client.as_ref())
286+ }
287+
276 pub fn get(&mut self, language_config: &LanguageConfiguration) -> Result<Arc<Client>> {
288 pub fn get(&mut self, language_config: &LanguageConfiguration) -> Result<Arc<Client>> {
277 if let Some(config) = &language_config.language_server {
289 if let Some(config) = &language_config.language_server {
278 // avoid borrow issues
290 // avoid borrow issues
@@ -280,16 +292,17 @@ impl Registry {
280 let s_incoming = &mut self.incoming;
292 let s_incoming = &mut self.incoming;
281
293
282 match inner.entry(language_config.scope.clone()) {
294 match inner.entry(language_config.scope.clone()) {
283− Entry::Occupied(language_server) => Ok(language_server.get().clone()),
295+ Entry::Occupied(entry) => Ok(entry.get().1.clone()),
284 Entry::Vacant(entry) => {
296 Entry::Vacant(entry) => {
285 // initialize a new client
297 // initialize a new client
298+ let id = self.counter.fetch_add(1, Ordering::Relaxed);
286− let (mut client, incoming) = Client::start(&config.command, &config.args)?;
299+ let (mut client, incoming) = Client::start(&config.command, &config.args, id)?;
287 // TODO: run this async without blocking
300 // TODO: run this async without blocking
288 futures_executor::block_on(client.initialize())?;
301 futures_executor::block_on(client.initialize())?;
289 s_incoming.push(UnboundedReceiverStream::new(incoming));
302 s_incoming.push(UnboundedReceiverStream::new(incoming));
290 let client = Arc::new(client);
303 let client = Arc::new(client);
291
304
292− entry.insert(client.clone());
305+ entry.insert((id, client.clone()));
293 Ok(client)
306 Ok(client)
294 }
307 }
295 }
308 }
helix-lsp/src/transport.rs+9−3
@@ -33,7 +33,8 @@ enum ServerMessage {
33
33
34#[derive(Debug)]
34#[derive(Debug)]
35pub struct Transport {
35pub struct Transport {
36+ id: usize,
36− client_tx: UnboundedSender<jsonrpc::Call>,
37+ client_tx: UnboundedSender<(usize, jsonrpc::Call)>,
37 client_rx: UnboundedReceiver<Payload>,
38 client_rx: UnboundedReceiver<Payload>,
38
39
39 pending_requests: HashMap<jsonrpc::Id, Sender<Result<Value>>>,
40 pending_requests: HashMap<jsonrpc::Id, Sender<Result<Value>>>,
@@ -48,11 +49,16 @@ impl Transport {
48 server_stdout: BufReader<ChildStdout>,
49 server_stdout: BufReader<ChildStdout>,
49 server_stdin: BufWriter<ChildStdin>,
50 server_stdin: BufWriter<ChildStdin>,
50 server_stderr: BufReader<ChildStderr>,
51 server_stderr: BufReader<ChildStderr>,
52+ id: usize,
53+ ) -> (
51− ) -> (UnboundedReceiver<jsonrpc::Call>, UnboundedSender<Payload>) {
54+ UnboundedReceiver<(usize, jsonrpc::Call)>,
55+ UnboundedSender<Payload>,
56+ ) {
52 let (client_tx, rx) = unbounded_channel();
57 let (client_tx, rx) = unbounded_channel();
53 let (tx, client_rx) = unbounded_channel();
58 let (tx, client_rx) = unbounded_channel();
54
59
55 let transport = Self {
60 let transport = Self {
61+ id,
56 server_stdout,
62 server_stdout,
57 server_stdin,
63 server_stdin,
58 server_stderr,
64 server_stderr,
@@ -156,7 +162,7 @@ impl Transport {
156 match msg {
162 match msg {
157 ServerMessage::Output(output) => self.process_request_response(output).await?,
163 ServerMessage::Output(output) => self.process_request_response(output).await?,
158 ServerMessage::Call(call) => {
164 ServerMessage::Call(call) => {
159− self.client_tx.send(call).unwrap();
165+ self.client_tx.send((self.id, call)).unwrap();
160 // let notification = Notification::parse(&method, params);
166 // let notification = Notification::parse(&method, params);
161 }
167 }
162 };
168 };
helix-term/src/application.rs+8−4
@@ -109,8 +109,8 @@ impl Application {
109 event = reader.next() => {
109 event = reader.next() => {
110 self.handle_terminal_events(event)
110 self.handle_terminal_events(event)
111 }
111 }
112− Some(call) = self.editor.language_servers.incoming.next() => {
112+ Some((id, call)) = self.editor.language_servers.incoming.next() => {
113− self.handle_language_server_message(call).await
113+ self.handle_language_server_message(call, id).await
114 }
114 }
115 Some(callback) = &mut self.callbacks.next() => {
115 Some(callback) = &mut self.callbacks.next() => {
116 self.handle_language_server_callback(callback)
116 self.handle_language_server_callback(callback)
@@ -153,8 +153,12 @@ impl Application {
153 }
153 }
154 }
154 }
155
155
156− pub async fn handle_language_server_message(&mut self, call: helix_lsp::Call) {
156+ pub async fn handle_language_server_message(
157+ &mut self,
158+ call: helix_lsp::Call,
159+ server_id: usize,
160+ ) {
157− use helix_lsp::{Call, Notification};
161+ use helix_lsp::{Call, MethodCall, Notification};
158 match call {
162 match call {
159 Call::Notification(helix_lsp::jsonrpc::Notification { method, params, .. }) => {
163 Call::Notification(helix_lsp::jsonrpc::Notification { method, params, .. }) => {
160 let notification = match Notification::parse(&method, params) {
164 let notification = match Notification::parse(&method, params) {