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
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -13,6 +13,7 @@ dependencies = [
|
|||
"futures 0.3.30",
|
||||
"gpui",
|
||||
"language",
|
||||
"lsp",
|
||||
"project",
|
||||
"smallvec",
|
||||
"ui",
|
||||
|
@ -6898,6 +6899,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"postage",
|
||||
"release_channel",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smol",
|
||||
|
|
|
@ -20,6 +20,7 @@ extension_host.workspace = true
|
|||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
lsp.workspace = true
|
||||
project.workspace = true
|
||||
smallvec.workspace = true
|
||||
ui.workspace = true
|
||||
|
|
|
@ -7,9 +7,8 @@ use gpui::{
|
|||
InteractiveElement as _, Model, ParentElement as _, Render, SharedString,
|
||||
StatefulInteractiveElement, Styled, Transformation, View, ViewContext, VisualContext as _,
|
||||
};
|
||||
use language::{
|
||||
LanguageRegistry, LanguageServerBinaryStatus, LanguageServerId, LanguageServerName,
|
||||
};
|
||||
use language::{LanguageRegistry, LanguageServerBinaryStatus, LanguageServerId};
|
||||
use lsp::LanguageServerName;
|
||||
use project::{EnvironmentErrorMessage, LanguageServerProgress, Project, WorktreeId};
|
||||
use smallvec::SmallVec;
|
||||
use std::{cmp::Reverse, fmt::Write, sync::Arc, time::Duration};
|
||||
|
|
|
@ -5130,11 +5130,10 @@ async fn test_lsp_hover(
|
|||
});
|
||||
let new_server_name = new_server.server.name();
|
||||
assert!(
|
||||
!servers_with_hover_requests.contains_key(new_server_name),
|
||||
!servers_with_hover_requests.contains_key(&new_server_name),
|
||||
"Unexpected: initialized server with the same name twice. Name: `{new_server_name}`"
|
||||
);
|
||||
let new_server_name = new_server_name.to_string();
|
||||
match new_server_name.as_str() {
|
||||
match new_server_name.as_ref() {
|
||||
"CrabLang-ls" => {
|
||||
servers_with_hover_requests.insert(
|
||||
new_server_name.clone(),
|
||||
|
|
|
@ -21,7 +21,7 @@ use language::{
|
|||
point_from_lsp, point_to_lsp, Anchor, Bias, Buffer, BufferSnapshot, Language, PointUtf16,
|
||||
ToPointUtf16,
|
||||
};
|
||||
use lsp::{LanguageServer, LanguageServerBinary, LanguageServerId};
|
||||
use lsp::{LanguageServer, LanguageServerBinary, LanguageServerId, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use parking_lot::Mutex;
|
||||
use request::StatusNotification;
|
||||
|
@ -446,9 +446,11 @@ impl Copilot {
|
|||
Path::new("/")
|
||||
};
|
||||
|
||||
let server_name = LanguageServerName("copilot".into());
|
||||
let server = LanguageServer::new(
|
||||
Arc::new(Mutex::new(None)),
|
||||
new_server_id,
|
||||
server_name,
|
||||
binary,
|
||||
root_path,
|
||||
None,
|
||||
|
|
|
@ -96,9 +96,7 @@ use language::{
|
|||
CursorShape, Diagnostic, Documentation, IndentKind, IndentSize, Language, OffsetRangeExt,
|
||||
Point, Selection, SelectionGoal, TransactionId,
|
||||
};
|
||||
use language::{
|
||||
point_to_lsp, BufferRow, CharClassifier, LanguageServerName, Runnable, RunnableRange,
|
||||
};
|
||||
use language::{point_to_lsp, BufferRow, CharClassifier, Runnable, RunnableRange};
|
||||
use linked_editing_ranges::refresh_linked_ranges;
|
||||
pub use proposed_changes_editor::{
|
||||
ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,
|
||||
|
@ -111,7 +109,7 @@ use hover_links::{find_file, HoverLink, HoveredLinkState, InlayHighlight};
|
|||
pub use lsp::CompletionContext;
|
||||
use lsp::{
|
||||
CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity, InsertTextFormat,
|
||||
LanguageServerId,
|
||||
LanguageServerId, LanguageServerName,
|
||||
};
|
||||
use mouse_context_menu::MouseContextMenu;
|
||||
use movement::TextLayoutDetails;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use anyhow::{anyhow, Context, Result};
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use fs::Fs;
|
||||
use language::{LanguageName, LanguageServerName};
|
||||
use language::LanguageName;
|
||||
use lsp::LanguageServerName;
|
||||
use semantic_version::SemanticVersion;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
|
|
|
@ -28,6 +28,7 @@ use language::{
|
|||
LanguageConfig, LanguageMatcher, LanguageName, LanguageQueries, LoadedLanguage,
|
||||
QUERY_FILENAME_PREFIXES,
|
||||
};
|
||||
use lsp::LanguageServerName;
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::ContextProviderWithTasks;
|
||||
use release_channel::ReleaseChannel;
|
||||
|
@ -121,12 +122,7 @@ pub trait ExtensionRegistrationHooks: Send + Sync + 'static {
|
|||
|
||||
fn register_lsp_adapter(&self, _language: LanguageName, _adapter: ExtensionLspAdapter) {}
|
||||
|
||||
fn remove_lsp_adapter(
|
||||
&self,
|
||||
_language: &LanguageName,
|
||||
_server_name: &language::LanguageServerName,
|
||||
) {
|
||||
}
|
||||
fn remove_lsp_adapter(&self, _language: &LanguageName, _server_name: &LanguageServerName) {}
|
||||
|
||||
fn register_wasm_grammars(&self, _grammars: Vec<(Arc<str>, PathBuf)>) {}
|
||||
|
||||
|
@ -167,7 +163,7 @@ pub trait ExtensionRegistrationHooks: Send + Sync + 'static {
|
|||
|
||||
fn update_lsp_status(
|
||||
&self,
|
||||
_server_name: language::LanguageServerName,
|
||||
_server_name: lsp::LanguageServerName,
|
||||
_status: language::LanguageServerBinaryStatus,
|
||||
) {
|
||||
}
|
||||
|
|
|
@ -8,10 +8,9 @@ use collections::HashMap;
|
|||
use futures::{Future, FutureExt};
|
||||
use gpui::AsyncAppContext;
|
||||
use language::{
|
||||
CodeLabel, HighlightId, Language, LanguageServerName, LanguageToolchainStore, LspAdapter,
|
||||
LspAdapterDelegate,
|
||||
CodeLabel, HighlightId, Language, LanguageToolchainStore, LspAdapter, LspAdapterDelegate,
|
||||
};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerBinaryOptions};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerName};
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use std::ops::Range;
|
||||
|
|
|
@ -3,6 +3,7 @@ mod since_v0_0_4;
|
|||
mod since_v0_0_6;
|
||||
mod since_v0_1_0;
|
||||
mod since_v0_2_0;
|
||||
use lsp::LanguageServerName;
|
||||
// use indexed_docs::IndexedDocsDatabase;
|
||||
use release_channel::ReleaseChannel;
|
||||
use since_v0_2_0 as latest;
|
||||
|
@ -11,7 +12,7 @@ use crate::DocsDatabase;
|
|||
|
||||
use super::{wasm_engine, WasmState};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use language::{LanguageServerName, LspAdapterDelegate};
|
||||
use language::LspAdapterDelegate;
|
||||
use semantic_version::SemanticVersion;
|
||||
use std::{ops::RangeInclusive, sync::Arc};
|
||||
use wasmtime::{
|
||||
|
|
|
@ -149,7 +149,7 @@ impl ExtensionImports for WasmState {
|
|||
|
||||
self.host
|
||||
.registration_hooks
|
||||
.update_lsp_status(language::LanguageServerName(server_name.into()), status);
|
||||
.update_lsp_status(lsp::LanguageServerName(server_name.into()), status);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ use async_tar::Archive;
|
|||
use async_trait::async_trait;
|
||||
use futures::{io::BufReader, FutureExt as _};
|
||||
use futures::{lock::Mutex, AsyncReadExt};
|
||||
use language::LanguageName;
|
||||
use language::{
|
||||
language_settings::AllLanguageSettings, LanguageServerBinaryStatus, LspAdapterDelegate,
|
||||
};
|
||||
use language::{LanguageName, LanguageServerName};
|
||||
use project::project_settings::ProjectSettings;
|
||||
use semantic_version::SemanticVersion;
|
||||
use std::{
|
||||
|
@ -469,7 +469,7 @@ impl ExtensionImports for WasmState {
|
|||
.and_then(|key| {
|
||||
ProjectSettings::get(location, cx)
|
||||
.lsp
|
||||
.get(&LanguageServerName(key.into()))
|
||||
.get(&::lsp::LanguageServerName(key.into()))
|
||||
})
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
|
@ -513,7 +513,7 @@ impl ExtensionImports for WasmState {
|
|||
|
||||
self.host
|
||||
.registration_hooks
|
||||
.update_lsp_status(language::LanguageServerName(server_name.into()), status);
|
||||
.update_lsp_status(::lsp::LanguageServerName(server_name.into()), status);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ use async_trait::async_trait;
|
|||
use futures::{io::BufReader, FutureExt as _};
|
||||
use futures::{lock::Mutex, AsyncReadExt};
|
||||
use language::{
|
||||
language_settings::AllLanguageSettings, LanguageServerBinaryStatus, LspAdapterDelegate,
|
||||
language_settings::AllLanguageSettings, LanguageName, LanguageServerBinaryStatus,
|
||||
LspAdapterDelegate,
|
||||
};
|
||||
use language::{LanguageName, LanguageServerName};
|
||||
use project::project_settings::ProjectSettings;
|
||||
use semantic_version::SemanticVersion;
|
||||
use std::{
|
||||
|
@ -416,7 +416,7 @@ impl ExtensionImports for WasmState {
|
|||
.and_then(|key| {
|
||||
ProjectSettings::get(location, cx)
|
||||
.lsp
|
||||
.get(&LanguageServerName::from_proto(key))
|
||||
.get(&::lsp::LanguageServerName::from_proto(key))
|
||||
})
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
|
@ -460,7 +460,7 @@ impl ExtensionImports for WasmState {
|
|||
|
||||
self.host
|
||||
.registration_hooks
|
||||
.update_lsp_status(language::LanguageServerName(server_name.into()), status);
|
||||
.update_lsp_status(::lsp::LanguageServerName(server_name.into()), status);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ fuzzy.workspace = true
|
|||
gpui.workspace = true
|
||||
indexed_docs.workspace = true
|
||||
language.workspace = true
|
||||
lsp.workspace = true
|
||||
num-format.workspace = true
|
||||
picker.workspace = true
|
||||
project.workspace = true
|
||||
|
|
|
@ -121,7 +121,7 @@ impl extension_host::ExtensionRegistrationHooks for ConcreteExtensionRegistratio
|
|||
|
||||
fn update_lsp_status(
|
||||
&self,
|
||||
server_name: language::LanguageServerName,
|
||||
server_name: lsp::LanguageServerName,
|
||||
status: LanguageServerBinaryStatus,
|
||||
) {
|
||||
self.language_registry
|
||||
|
@ -140,7 +140,7 @@ impl extension_host::ExtensionRegistrationHooks for ConcreteExtensionRegistratio
|
|||
fn remove_lsp_adapter(
|
||||
&self,
|
||||
language_name: &language::LanguageName,
|
||||
server_name: &language::LanguageServerName,
|
||||
server_name: &lsp::LanguageServerName,
|
||||
) {
|
||||
self.language_registry
|
||||
.remove_lsp_adapter(language_name, server_name);
|
||||
|
|
|
@ -14,7 +14,8 @@ use futures::{io::BufReader, AsyncReadExt, StreamExt};
|
|||
use gpui::{Context, SemanticVersion, TestAppContext};
|
||||
use http_client::{FakeHttpClient, Response};
|
||||
use indexed_docs::IndexedDocsRegistry;
|
||||
use language::{LanguageMatcher, LanguageRegistry, LanguageServerBinaryStatus, LanguageServerName};
|
||||
use language::{LanguageMatcher, LanguageRegistry, LanguageServerBinaryStatus};
|
||||
use lsp::LanguageServerName;
|
||||
use node_runtime::NodeRuntime;
|
||||
use parking_lot::Mutex;
|
||||
use project::{Project, DEFAULT_COMPLETION_CONTEXT};
|
||||
|
|
|
@ -30,7 +30,7 @@ use gpui::{AppContext, AsyncAppContext, Model, SharedString, Task};
|
|||
pub use highlight_map::HighlightMap;
|
||||
use http_client::HttpClient;
|
||||
pub use language_registry::{LanguageName, LoadedLanguage};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerBinaryOptions};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerName};
|
||||
use parking_lot::Mutex;
|
||||
use regex::Regex;
|
||||
use schemars::{
|
||||
|
@ -139,57 +139,6 @@ pub trait ToLspPosition {
|
|||
fn to_lsp_position(self) -> lsp::Position;
|
||||
}
|
||||
|
||||
/// 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())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Location {
|
||||
pub buffer: Model<Buffer>,
|
||||
|
|
|
@ -7,10 +7,10 @@ use gpui::{
|
|||
IntoElement, Model, ModelContext, ParentElement, Render, Styled, Subscription, View,
|
||||
ViewContext, VisualContext, WeakModel, WindowContext,
|
||||
};
|
||||
use language::{LanguageServerId, LanguageServerName};
|
||||
use language::LanguageServerId;
|
||||
use lsp::{
|
||||
notification::SetTrace, IoKind, LanguageServer, MessageType, ServerCapabilities,
|
||||
SetTraceParams, TraceValue,
|
||||
notification::SetTrace, IoKind, LanguageServer, LanguageServerName, MessageType,
|
||||
ServerCapabilities, SetTraceParams, TraceValue,
|
||||
};
|
||||
use project::{search::SearchQuery, Project, WorktreeId};
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
|
|
@ -5,9 +5,8 @@ use crate::lsp_log::LogMenuItem;
|
|||
use super::*;
|
||||
use futures::StreamExt;
|
||||
use gpui::{Context, SemanticVersion, TestAppContext, VisualTestContext};
|
||||
use language::{
|
||||
tree_sitter_rust, FakeLspAdapter, Language, LanguageConfig, LanguageMatcher, LanguageServerName,
|
||||
};
|
||||
use language::{tree_sitter_rust, FakeLspAdapter, Language, LanguageConfig, LanguageMatcher};
|
||||
use lsp::LanguageServerName;
|
||||
use lsp_log::LogKind;
|
||||
use project::{FakeFs, Project};
|
||||
use serde_json::json;
|
||||
|
|
|
@ -4,7 +4,7 @@ use futures::StreamExt;
|
|||
use gpui::AsyncAppContext;
|
||||
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||
pub use language::*;
|
||||
use lsp::LanguageServerBinary;
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use smol::fs::{self, File};
|
||||
use std::{any::Any, env::consts, path::PathBuf, sync::Arc};
|
||||
use util::{fs::remove_matching, maybe, ResultExt};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use futures::StreamExt;
|
||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerBinary;
|
||||
use language::{LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use serde_json::json;
|
||||
use smol::fs;
|
||||
|
|
|
@ -5,7 +5,7 @@ use futures::StreamExt;
|
|||
use gpui::{AppContext, AsyncAppContext, Task};
|
||||
use http_client::github::latest_github_release;
|
||||
pub use language::*;
|
||||
use lsp::LanguageServerBinary;
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use regex::Regex;
|
||||
use serde_json::json;
|
||||
use smol::{fs, process};
|
||||
|
|
|
@ -6,10 +6,8 @@ use collections::HashMap;
|
|||
use futures::StreamExt;
|
||||
use gpui::{AppContext, AsyncAppContext};
|
||||
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||
use language::{
|
||||
LanguageRegistry, LanguageServerName, LanguageToolchainStore, LspAdapter, LspAdapterDelegate,
|
||||
};
|
||||
use lsp::LanguageServerBinary;
|
||||
use language::{LanguageRegistry, LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::ContextProviderWithTasks;
|
||||
use serde_json::{json, Value};
|
||||
|
|
|
@ -2,6 +2,7 @@ use anyhow::Context;
|
|||
use gpui::{AppContext, UpdateGlobal};
|
||||
use json::json_task_context;
|
||||
pub use language::*;
|
||||
use lsp::LanguageServerName;
|
||||
use node_runtime::NodeRuntime;
|
||||
use python::{PythonContextProvider, PythonToolchainProvider};
|
||||
use rust_embed::RustEmbed;
|
||||
|
|
|
@ -8,8 +8,9 @@ use language::LanguageToolchainStore;
|
|||
use language::Toolchain;
|
||||
use language::ToolchainList;
|
||||
use language::ToolchainLister;
|
||||
use language::{ContextProvider, LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||
use language::{ContextProvider, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerBinary;
|
||||
use lsp::LanguageServerName;
|
||||
use node_runtime::NodeRuntime;
|
||||
use pet_core::os_environment::Environment;
|
||||
use pet_core::python_environment::PythonEnvironmentKind;
|
||||
|
|
|
@ -6,7 +6,7 @@ use futures::{io::BufReader, StreamExt};
|
|||
use gpui::{AppContext, AsyncAppContext};
|
||||
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||
pub use language::*;
|
||||
use lsp::LanguageServerBinary;
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use regex::Regex;
|
||||
use smol::fs::{self, File};
|
||||
use std::{
|
||||
|
|
|
@ -3,8 +3,8 @@ use async_trait::async_trait;
|
|||
use collections::HashMap;
|
||||
use futures::StreamExt;
|
||||
use gpui::AsyncAppContext;
|
||||
use language::{LanguageServerName, LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerBinary;
|
||||
use language::{LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::lsp_store::language_server_settings;
|
||||
use serde_json::{json, Value};
|
||||
|
|
|
@ -5,8 +5,8 @@ use async_trait::async_trait;
|
|||
use collections::HashMap;
|
||||
use gpui::AsyncAppContext;
|
||||
use http_client::github::{build_asset_url, AssetKind, GitHubLspBinaryVersion};
|
||||
use language::{LanguageServerName, LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary};
|
||||
use language::{LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::lsp_store::language_server_settings;
|
||||
use project::ContextProviderWithTasks;
|
||||
|
|
|
@ -2,8 +2,8 @@ use anyhow::{anyhow, Result};
|
|||
use async_trait::async_trait;
|
||||
use collections::HashMap;
|
||||
use gpui::AsyncAppContext;
|
||||
use language::{LanguageServerName, LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary};
|
||||
use language::{LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::lsp_store::language_server_settings;
|
||||
use serde_json::Value;
|
||||
|
|
|
@ -3,10 +3,9 @@ use async_trait::async_trait;
|
|||
use futures::StreamExt;
|
||||
use gpui::AsyncAppContext;
|
||||
use language::{
|
||||
language_settings::AllLanguageSettings, LanguageServerName, LanguageToolchainStore, LspAdapter,
|
||||
LspAdapterDelegate,
|
||||
language_settings::AllLanguageSettings, LanguageToolchainStore, LspAdapter, LspAdapterDelegate,
|
||||
};
|
||||
use lsp::LanguageServerBinary;
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::lsp_store::language_server_settings;
|
||||
use serde_json::Value;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -154,7 +154,7 @@ impl Prettier {
|
|||
node: NodeRuntime,
|
||||
cx: AsyncAppContext,
|
||||
) -> anyhow::Result<Self> {
|
||||
use lsp::LanguageServerBinary;
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
|
||||
let executor = cx.background_executor().clone();
|
||||
anyhow::ensure!(
|
||||
|
@ -170,14 +170,17 @@ impl Prettier {
|
|||
let node_path = executor
|
||||
.spawn(async move { node.binary_path().await })
|
||||
.await?;
|
||||
let server_name = LanguageServerName("prettier".into());
|
||||
let server_binary = LanguageServerBinary {
|
||||
path: node_path,
|
||||
arguments: vec![prettier_server.into(), prettier_dir.as_path().into()],
|
||||
env: None,
|
||||
};
|
||||
let server = LanguageServer::new(
|
||||
Arc::new(parking_lot::Mutex::new(None)),
|
||||
server_id,
|
||||
LanguageServerBinary {
|
||||
path: node_path,
|
||||
arguments: vec![prettier_server.into(), prettier_dir.as_path().into()],
|
||||
env: None,
|
||||
},
|
||||
server_name,
|
||||
server_binary,
|
||||
&prettier_dir,
|
||||
None,
|
||||
cx.clone(),
|
||||
|
|
|
@ -38,16 +38,17 @@ use language::{
|
|||
proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
|
||||
range_from_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
|
||||
DiagnosticEntry, DiagnosticSet, Diff, Documentation, File as _, Language, LanguageName,
|
||||
LanguageRegistry, LanguageServerBinaryStatus, LanguageServerName, LanguageToolchainStore,
|
||||
LocalFile, LspAdapter, LspAdapterDelegate, Patch, PointUtf16, TextBufferSnapshot, ToOffset,
|
||||
ToPointUtf16, Transaction, Unclipped,
|
||||
LanguageRegistry, LanguageServerBinaryStatus, LanguageToolchainStore, LocalFile, LspAdapter,
|
||||
LspAdapterDelegate, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction,
|
||||
Unclipped,
|
||||
};
|
||||
use lsp::{
|
||||
CodeActionKind, CompletionContext, DiagnosticSeverity, DiagnosticTag,
|
||||
DidChangeWatchedFilesRegistrationOptions, Edit, FileSystemWatcher, InsertTextFormat,
|
||||
LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
|
||||
LspRequestFuture, MessageActionItem, MessageType, OneOf, ServerHealthStatus, ServerStatus,
|
||||
SymbolKind, TextEdit, Url, WorkDoneProgressCancelParams, WorkspaceFolder,
|
||||
LanguageServerName, LspRequestFuture, MessageActionItem, MessageType, OneOf,
|
||||
ServerHealthStatus, ServerStatus, SymbolKind, TextEdit, Url, WorkDoneProgressCancelParams,
|
||||
WorkspaceFolder,
|
||||
};
|
||||
use node_runtime::read_package_installed_version;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
|
@ -5598,6 +5599,7 @@ impl LspStore {
|
|||
|
||||
let pending_server = cx.spawn({
|
||||
let adapter = adapter.clone();
|
||||
let server_name = adapter.name.clone();
|
||||
let stderr_capture = stderr_capture.clone();
|
||||
|
||||
move |_lsp_store, cx| async move {
|
||||
|
@ -5608,7 +5610,7 @@ impl LspStore {
|
|||
.update(&mut cx.clone(), |this, cx| {
|
||||
this.languages.create_fake_language_server(
|
||||
server_id,
|
||||
&adapter.name,
|
||||
&server_name,
|
||||
binary.clone(),
|
||||
cx.to_async(),
|
||||
)
|
||||
|
@ -5622,6 +5624,7 @@ impl LspStore {
|
|||
lsp::LanguageServer::new(
|
||||
stderr_capture,
|
||||
server_id,
|
||||
server_name,
|
||||
binary,
|
||||
&root_path,
|
||||
adapter.code_action_kinds(),
|
||||
|
@ -6617,7 +6620,7 @@ impl LspStore {
|
|||
|
||||
cx.emit(LspStoreEvent::LanguageServerAdded(
|
||||
server_id,
|
||||
language_server.name().into(),
|
||||
language_server.name(),
|
||||
Some(key.0),
|
||||
));
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ use futures::{
|
|||
use gpui::{AsyncAppContext, EventEmitter, Model, ModelContext, Task, WeakModel};
|
||||
use language::{
|
||||
language_settings::{Formatter, LanguageSettings, SelectedFormatter},
|
||||
Buffer, LanguageRegistry, LanguageServerName, LocalFile,
|
||||
Buffer, LanguageRegistry, LocalFile,
|
||||
};
|
||||
use lsp::{LanguageServer, LanguageServerId};
|
||||
use lsp::{LanguageServer, LanguageServerId, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use paths::default_prettier_dir;
|
||||
use prettier::Prettier;
|
||||
|
|
|
@ -48,12 +48,12 @@ use itertools::Itertools;
|
|||
use language::{
|
||||
language_settings::InlayHintKind, proto::split_operations, Buffer, BufferEvent,
|
||||
CachedLspAdapter, Capability, CodeLabel, DiagnosticEntry, Documentation, File as _, Language,
|
||||
LanguageName, LanguageRegistry, LanguageServerName, PointUtf16, ToOffset, ToPointUtf16,
|
||||
Toolchain, ToolchainList, Transaction, Unclipped,
|
||||
LanguageName, LanguageRegistry, PointUtf16, ToOffset, ToPointUtf16, Toolchain, ToolchainList,
|
||||
Transaction, Unclipped,
|
||||
};
|
||||
use lsp::{
|
||||
CompletionContext, CompletionItemKind, DocumentHighlightKind, LanguageServer, LanguageServerId,
|
||||
MessageActionItem,
|
||||
LanguageServerName, MessageActionItem,
|
||||
};
|
||||
use lsp_command::*;
|
||||
use node_runtime::NodeRuntime;
|
||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::Context;
|
|||
use collections::HashMap;
|
||||
use fs::Fs;
|
||||
use gpui::{AppContext, AsyncAppContext, BorrowAppContext, EventEmitter, Model, ModelContext};
|
||||
use language::LanguageServerName;
|
||||
use lsp::LanguageServerName;
|
||||
use paths::{
|
||||
local_settings_file_relative_path, local_tasks_file_relative_path,
|
||||
local_vscode_tasks_file_relative_path, EDITORCONFIG_NAME,
|
||||
|
|
|
@ -1243,7 +1243,7 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
|||
events.next().await.unwrap(),
|
||||
Event::LanguageServerAdded(
|
||||
LanguageServerId(0),
|
||||
fake_server.server.name().into(),
|
||||
fake_server.server.name(),
|
||||
Some(worktree_id)
|
||||
),
|
||||
);
|
||||
|
@ -1378,7 +1378,7 @@ async fn test_restarting_server_with_diagnostics_running(cx: &mut gpui::TestAppC
|
|||
events.next().await.unwrap(),
|
||||
Event::LanguageServerAdded(
|
||||
LanguageServerId(1),
|
||||
fake_server.server.name().into(),
|
||||
fake_server.server.name(),
|
||||
Some(worktree_id)
|
||||
)
|
||||
);
|
||||
|
@ -4865,11 +4865,10 @@ async fn test_multiple_language_server_hovers(cx: &mut gpui::TestAppContext) {
|
|||
});
|
||||
let new_server_name = new_server.server.name();
|
||||
assert!(
|
||||
!servers_with_hover_requests.contains_key(new_server_name),
|
||||
!servers_with_hover_requests.contains_key(&new_server_name),
|
||||
"Unexpected: initialized server with the same name twice. Name: `{new_server_name}`"
|
||||
);
|
||||
let new_server_name = new_server_name.to_string();
|
||||
match new_server_name.as_str() {
|
||||
match new_server_name.as_ref() {
|
||||
"TailwindServer" | "TypeScriptServer" => {
|
||||
servers_with_hover_requests.insert(
|
||||
new_server_name.clone(),
|
||||
|
@ -5089,11 +5088,10 @@ async fn test_multiple_language_server_actions(cx: &mut gpui::TestAppContext) {
|
|||
let new_server_name = new_server.server.name();
|
||||
|
||||
assert!(
|
||||
!servers_with_actions_requests.contains_key(new_server_name),
|
||||
!servers_with_actions_requests.contains_key(&new_server_name),
|
||||
"Unexpected: initialized server with the same name twice. Name: `{new_server_name}`"
|
||||
);
|
||||
let new_server_name = new_server_name.to_string();
|
||||
match new_server_name.as_str() {
|
||||
match new_server_name.0.as_ref() {
|
||||
"TailwindServer" | "TypeScriptServer" => {
|
||||
servers_with_actions_requests.insert(
|
||||
new_server_name.clone(),
|
||||
|
|
|
@ -6,10 +6,9 @@ use gpui::{Context, Model, SemanticVersion, TestAppContext};
|
|||
use http_client::{BlockedHttpClient, FakeHttpClient};
|
||||
use language::{
|
||||
language_settings::{language_settings, AllLanguageSettings},
|
||||
Buffer, FakeLspAdapter, LanguageConfig, LanguageMatcher, LanguageRegistry, LanguageServerName,
|
||||
LineEnding,
|
||||
Buffer, FakeLspAdapter, LanguageConfig, LanguageMatcher, LanguageRegistry, LineEnding,
|
||||
};
|
||||
use lsp::{CompletionContext, CompletionResponse, CompletionTriggerKind};
|
||||
use lsp::{CompletionContext, CompletionResponse, CompletionTriggerKind, LanguageServerName};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::{
|
||||
search::{SearchQuery, SearchResult},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue