language servers: Fix wrong language server name (#20428)
This fixes the issue of multiple language servers showing up as `node` in the language server logs dropdown. It does this by changing `language_server.name()` to return the adapter's name, not the binary name, and changing types to make sure that we always use this. Release Notes: - Fixed language server names showing up only as `"node"` --------- Co-authored-by: Sam Rose <hello@samwho.dev> Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
parent
f4024cc602
commit
a97ab5eb3d
39 changed files with 172 additions and 151 deletions
|
@ -27,6 +27,7 @@ parking_lot.workspace = true
|
|||
postage.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
schemars.workspace = true
|
||||
smol.workspace = true
|
||||
util.workspace = true
|
||||
release_channel.workspace = true
|
||||
|
|
|
@ -6,9 +6,14 @@ pub use lsp_types::*;
|
|||
use anyhow::{anyhow, Context, Result};
|
||||
use collections::HashMap;
|
||||
use futures::{channel::oneshot, io::BufWriter, select, AsyncRead, AsyncWrite, Future, FutureExt};
|
||||
use gpui::{AppContext, AsyncAppContext, BackgroundExecutor, Task};
|
||||
use gpui::{AppContext, AsyncAppContext, BackgroundExecutor, SharedString, Task};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use postage::{barrier, prelude::Stream};
|
||||
use schemars::{
|
||||
gen::SchemaGenerator,
|
||||
schema::{InstanceType, Schema, SchemaObject},
|
||||
JsonSchema,
|
||||
};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde_json::{json, value::RawValue, Value};
|
||||
use smol::{
|
||||
|
@ -21,7 +26,7 @@ use smol::{
|
|||
use smol::process::windows::CommandExt;
|
||||
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
ffi::{OsStr, OsString},
|
||||
fmt,
|
||||
io::Write,
|
||||
ops::DerefMut,
|
||||
|
@ -78,7 +83,8 @@ pub struct LanguageServer {
|
|||
server_id: LanguageServerId,
|
||||
next_id: AtomicI32,
|
||||
outbound_tx: channel::Sender<String>,
|
||||
name: Arc<str>,
|
||||
name: LanguageServerName,
|
||||
process_name: Arc<str>,
|
||||
capabilities: RwLock<ServerCapabilities>,
|
||||
code_action_kinds: Option<Vec<CodeActionKind>>,
|
||||
notification_handlers: Arc<Mutex<HashMap<&'static str, NotificationHandler>>>,
|
||||
|
@ -108,6 +114,58 @@ impl LanguageServerId {
|
|||
}
|
||||
}
|
||||
|
||||
/// A name of a language server.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
|
||||
pub struct LanguageServerName(pub SharedString);
|
||||
|
||||
impl std::fmt::Display for LanguageServerName {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for LanguageServerName {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<OsStr> for LanguageServerName {
|
||||
fn as_ref(&self) -> &OsStr {
|
||||
self.0.as_ref().as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl JsonSchema for LanguageServerName {
|
||||
fn schema_name() -> String {
|
||||
"LanguageServerName".into()
|
||||
}
|
||||
|
||||
fn json_schema(_: &mut SchemaGenerator) -> Schema {
|
||||
SchemaObject {
|
||||
instance_type: Some(InstanceType::String.into()),
|
||||
..Default::default()
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl LanguageServerName {
|
||||
pub const fn new_static(s: &'static str) -> Self {
|
||||
Self(SharedString::new_static(s))
|
||||
}
|
||||
|
||||
pub fn from_proto(s: String) -> Self {
|
||||
Self(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for LanguageServerName {
|
||||
fn from(str: &'a str) -> LanguageServerName {
|
||||
LanguageServerName(str.to_string().into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle to a language server RPC activity subscription.
|
||||
pub enum Subscription {
|
||||
Notification {
|
||||
|
@ -269,6 +327,7 @@ impl LanguageServer {
|
|||
pub fn new(
|
||||
stderr_capture: Arc<Mutex<Option<String>>>,
|
||||
server_id: LanguageServerId,
|
||||
server_name: LanguageServerName,
|
||||
binary: LanguageServerBinary,
|
||||
root_path: &Path,
|
||||
code_action_kinds: Option<Vec<CodeActionKind>>,
|
||||
|
@ -310,6 +369,7 @@ impl LanguageServer {
|
|||
let stderr = server.stderr.take().unwrap();
|
||||
let mut server = Self::new_internal(
|
||||
server_id,
|
||||
server_name,
|
||||
stdin,
|
||||
stdout,
|
||||
Some(stderr),
|
||||
|
@ -330,7 +390,7 @@ impl LanguageServer {
|
|||
);
|
||||
|
||||
if let Some(name) = binary.path.file_name() {
|
||||
server.name = name.to_string_lossy().into();
|
||||
server.process_name = name.to_string_lossy().into();
|
||||
}
|
||||
|
||||
Ok(server)
|
||||
|
@ -339,6 +399,7 @@ impl LanguageServer {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
fn new_internal<Stdin, Stdout, Stderr, F>(
|
||||
server_id: LanguageServerId,
|
||||
server_name: LanguageServerName,
|
||||
stdin: Stdin,
|
||||
stdout: Stdout,
|
||||
stderr: Option<Stderr>,
|
||||
|
@ -408,7 +469,8 @@ impl LanguageServer {
|
|||
notification_handlers,
|
||||
response_handlers,
|
||||
io_handlers,
|
||||
name: Arc::default(),
|
||||
name: server_name,
|
||||
process_name: Arc::default(),
|
||||
capabilities: Default::default(),
|
||||
code_action_kinds,
|
||||
next_id: Default::default(),
|
||||
|
@ -725,7 +787,7 @@ impl LanguageServer {
|
|||
cx.spawn(|_| async move {
|
||||
let response = self.request::<request::Initialize>(params).await?;
|
||||
if let Some(info) = response.server_info {
|
||||
self.name = info.name.into();
|
||||
self.process_name = info.name.into();
|
||||
}
|
||||
self.capabilities = RwLock::new(response.capabilities);
|
||||
|
||||
|
@ -937,8 +999,12 @@ impl LanguageServer {
|
|||
}
|
||||
|
||||
/// Get the name of the running language server.
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
pub fn name(&self) -> LanguageServerName {
|
||||
self.name.clone()
|
||||
}
|
||||
|
||||
pub fn process_name(&self) -> &str {
|
||||
&self.process_name
|
||||
}
|
||||
|
||||
/// Get the reported capabilities of the running language server.
|
||||
|
@ -1179,8 +1245,11 @@ impl FakeLanguageServer {
|
|||
|
||||
let root = Self::root_path();
|
||||
|
||||
let server_name = LanguageServerName(name.clone().into());
|
||||
let process_name = Arc::from(name.as_str());
|
||||
let mut server = LanguageServer::new_internal(
|
||||
server_id,
|
||||
server_name.clone(),
|
||||
stdin_writer,
|
||||
stdout_reader,
|
||||
None::<async_pipe::PipeReader>,
|
||||
|
@ -1192,12 +1261,13 @@ impl FakeLanguageServer {
|
|||
cx.clone(),
|
||||
|_| {},
|
||||
);
|
||||
server.name = name.as_str().into();
|
||||
server.process_name = process_name;
|
||||
let fake = FakeLanguageServer {
|
||||
binary,
|
||||
server: Arc::new({
|
||||
let mut server = LanguageServer::new_internal(
|
||||
server_id,
|
||||
server_name,
|
||||
stdout_writer,
|
||||
stdin_reader,
|
||||
None::<async_pipe::PipeReader>,
|
||||
|
@ -1216,7 +1286,7 @@ impl FakeLanguageServer {
|
|||
.ok();
|
||||
},
|
||||
);
|
||||
server.name = name.as_str().into();
|
||||
server.process_name = name.as_str().into();
|
||||
server
|
||||
}),
|
||||
notifications_rx,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue