on master help sign in
configurable lsp request timeout (#2405)
807cdc6EmmChriss
helix-core/src/syntax.rs+6
@@ -50,6 +50,10 @@ where
50 Ok(Option::<AutoPairConfig>::deserialize(deserializer)?.and_then(AutoPairConfig::into))
50 Ok(Option::<AutoPairConfig>::deserialize(deserializer)?.and_then(AutoPairConfig::into))
51}
51}
52
52
53+fn default_timeout() -> u64 {
54+ 20
55+}
56+
53#[derive(Debug, Serialize, Deserialize)]
57#[derive(Debug, Serialize, Deserialize)]
54pub struct Configuration {
58pub struct Configuration {
55 pub language: Vec<LanguageConfiguration>,
59 pub language: Vec<LanguageConfiguration>,
@@ -116,6 +120,8 @@ pub struct LanguageServerConfiguration {
116 #[serde(default)]
120 #[serde(default)]
117 #[serde(skip_serializing_if = "Vec::is_empty")]
121 #[serde(skip_serializing_if = "Vec::is_empty")]
118 pub args: Vec<String>,
122 pub args: Vec<String>,
123+ #[serde(default = "default_timeout")]
124+ pub timeout: u64,
119 pub language_id: Option<String>,
125 pub language_id: Option<String>,
120}
126}
121
127
helix-lsp/src/client.rs+6−2
@@ -35,6 +35,7 @@ pub struct Client {
35 root_path: Option<std::path::PathBuf>,
35 root_path: Option<std::path::PathBuf>,
36 root_uri: Option<lsp::Url>,
36 root_uri: Option<lsp::Url>,
37 workspace_folders: Vec<lsp::WorkspaceFolder>,
37 workspace_folders: Vec<lsp::WorkspaceFolder>,
38+ req_timeout: u64,
38}
39}
39
40
40impl Client {
41impl Client {
@@ -45,6 +46,7 @@ impl Client {
45 config: Option<Value>,
46 config: Option<Value>,
46 root_markers: &[String],
47 root_markers: &[String],
47 id: usize,
48 id: usize,
49+ req_timeout: u64,
48 ) -> Result<(Self, UnboundedReceiver<(usize, Call)>, Arc<Notify>)> {
50 ) -> Result<(Self, UnboundedReceiver<(usize, Call)>, Arc<Notify>)> {
49 // Resolve path to the binary
51 // Resolve path to the binary
50 let cmd = which::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
52 let cmd = which::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
@@ -97,6 +99,7 @@ impl Client {
97 capabilities: OnceCell::new(),
99 capabilities: OnceCell::new(),
98 offset_encoding: OffsetEncoding::Utf8,
100 offset_encoding: OffsetEncoding::Utf8,
99 config,
101 config,
102+ req_timeout,
100
103
101 root_path,
104 root_path,
102 root_uri,
105 root_uri,
@@ -170,6 +173,7 @@ impl Client {
170 {
173 {
171 let server_tx = self.server_tx.clone();
174 let server_tx = self.server_tx.clone();
172 let id = self.next_request_id();
175 let id = self.next_request_id();
176+ let timeout_secs = self.req_timeout;
173
177
174 async move {
178 async move {
175 use std::time::Duration;
179 use std::time::Duration;
@@ -193,8 +197,8 @@ impl Client {
193 })
197 })
194 .map_err(|e| Error::Other(e.into()))?;
198 .map_err(|e| Error::Other(e.into()))?;
195
199
196− // TODO: specifiable timeout, delay other calls until initialize success
200+ // TODO: delay other calls until initialize success
197− timeout(Duration::from_secs(20), rx.recv())
201+ timeout(Duration::from_secs(timeout_secs), rx.recv())
198 .await
202 .await
199 .map_err(|_| Error::Timeout)? // return Timeout
203 .map_err(|_| Error::Timeout)? // return Timeout
200 .ok_or(Error::StreamClosed)?
204 .ok_or(Error::StreamClosed)?
helix-lsp/src/lib.rs+1
@@ -360,6 +360,7 @@ impl Registry {
360 language_config.config.clone(),
360 language_config.config.clone(),
361 &language_config.roots,
361 &language_config.roots,
362 id,
362 id,
363+ config.timeout,
363 )?;
364 )?;
364 self.incoming.push(UnboundedReceiverStream::new(incoming));
365 self.incoming.push(UnboundedReceiverStream::new(incoming));
365 let client = Arc::new(client);
366 let client = Arc::new(client);