Allow each language adapter to provide their own code action kinds array

This commit is contained in:
Julia 2023-03-30 15:41:54 -04:00
parent 007aa92581
commit cdde523ea4
4 changed files with 41 additions and 10 deletions

View file

@ -20,6 +20,7 @@ use futures::{
use gpui::{executor::Background, MutableAppContext, Task}; use gpui::{executor::Background, MutableAppContext, Task};
use highlight_map::HighlightMap; use highlight_map::HighlightMap;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use lsp::CodeActionKind;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use postage::watch; use postage::watch;
use regex::Regex; use regex::Regex;
@ -140,6 +141,10 @@ impl CachedLspAdapter {
self.adapter.cached_server_binary(container_dir).await self.adapter.cached_server_binary(container_dir).await
} }
pub fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
self.adapter.code_action_kinds()
}
pub fn workspace_configuration( pub fn workspace_configuration(
&self, &self,
cx: &mut MutableAppContext, cx: &mut MutableAppContext,
@ -225,6 +230,16 @@ pub trait LspAdapter: 'static + Send + Sync {
None None
} }
fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
Some(vec![
CodeActionKind::EMPTY,
CodeActionKind::QUICKFIX,
CodeActionKind::REFACTOR,
CodeActionKind::REFACTOR_EXTRACT,
CodeActionKind::SOURCE,
])
}
async fn disk_based_diagnostic_sources(&self) -> Vec<String> { async fn disk_based_diagnostic_sources(&self) -> Vec<String> {
Default::default() Default::default()
} }
@ -825,6 +840,7 @@ impl LanguageRegistry {
&binary.path, &binary.path,
&binary.arguments, &binary.arguments,
&root_path, &root_path,
adapter.code_action_kinds(),
cx, cx,
)?; )?;

View file

@ -40,6 +40,7 @@ pub struct LanguageServer {
outbound_tx: channel::Sender<Vec<u8>>, outbound_tx: channel::Sender<Vec<u8>>,
name: String, name: String,
capabilities: ServerCapabilities, capabilities: ServerCapabilities,
code_action_kinds: Option<Vec<CodeActionKind>>,
notification_handlers: Arc<Mutex<HashMap<&'static str, NotificationHandler>>>, notification_handlers: Arc<Mutex<HashMap<&'static str, NotificationHandler>>>,
response_handlers: Arc<Mutex<Option<HashMap<usize, ResponseHandler>>>>, response_handlers: Arc<Mutex<Option<HashMap<usize, ResponseHandler>>>>,
executor: Arc<executor::Background>, executor: Arc<executor::Background>,
@ -110,6 +111,7 @@ impl LanguageServer {
binary_path: &Path, binary_path: &Path,
arguments: &[T], arguments: &[T],
root_path: &Path, root_path: &Path,
code_action_kinds: Option<Vec<CodeActionKind>>,
cx: AsyncAppContext, cx: AsyncAppContext,
) -> Result<Self> { ) -> Result<Self> {
let working_dir = if root_path.is_dir() { let working_dir = if root_path.is_dir() {
@ -135,6 +137,7 @@ impl LanguageServer {
stout, stout,
Some(server), Some(server),
root_path, root_path,
code_action_kinds,
cx, cx,
|notification| { |notification| {
log::info!( log::info!(
@ -160,6 +163,7 @@ impl LanguageServer {
stdout: Stdout, stdout: Stdout,
server: Option<Child>, server: Option<Child>,
root_path: &Path, root_path: &Path,
code_action_kinds: Option<Vec<CodeActionKind>>,
cx: AsyncAppContext, cx: AsyncAppContext,
on_unhandled_notification: F, on_unhandled_notification: F,
) -> Self ) -> Self
@ -197,6 +201,7 @@ impl LanguageServer {
response_handlers, response_handlers,
name: Default::default(), name: Default::default(),
capabilities: Default::default(), capabilities: Default::default(),
code_action_kinds,
next_id: Default::default(), next_id: Default::default(),
outbound_tx, outbound_tx,
executor: cx.background(), executor: cx.background(),
@ -207,6 +212,10 @@ impl LanguageServer {
} }
} }
pub fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
self.code_action_kinds.clone()
}
async fn handle_input<Stdout, F>( async fn handle_input<Stdout, F>(
stdout: Stdout, stdout: Stdout,
mut on_unhandled_notification: F, mut on_unhandled_notification: F,
@ -715,6 +724,7 @@ impl LanguageServer {
stdout_reader, stdout_reader,
None, None,
Path::new("/"), Path::new("/"),
None,
cx.clone(), cx.clone(),
|_| {}, |_| {},
); );
@ -725,6 +735,7 @@ impl LanguageServer {
stdin_reader, stdin_reader,
None, None,
Path::new("/"), Path::new("/"),
None,
cx, cx,
move |msg| { move |msg| {
notifications_tx notifications_tx

View file

@ -3773,7 +3773,7 @@ impl Project {
worktree = file.worktree.clone(); worktree = file.worktree.clone();
buffer_abs_path = file.as_local().map(|f| f.abs_path(cx)); buffer_abs_path = file.as_local().map(|f| f.abs_path(cx));
} else { } else {
return Task::ready(Ok(Default::default())); return Task::ready(Ok(Vec::new()));
}; };
let range = buffer.anchor_before(range.start)..buffer.anchor_before(range.end); let range = buffer.anchor_before(range.start)..buffer.anchor_before(range.end);
@ -3783,13 +3783,13 @@ impl Project {
{ {
server.clone() server.clone()
} else { } else {
return Task::ready(Ok(Default::default())); return Task::ready(Ok(Vec::new()));
}; };
let lsp_range = range_to_lsp(range.to_point_utf16(buffer)); let lsp_range = range_to_lsp(range.to_point_utf16(buffer));
cx.foreground().spawn(async move { cx.foreground().spawn(async move {
if lang_server.capabilities().code_action_provider.is_none() { if lang_server.capabilities().code_action_provider.is_none() {
return Ok(Default::default()); return Ok(Vec::new());
} }
Ok(lang_server Ok(lang_server
@ -3802,13 +3802,7 @@ impl Project {
partial_result_params: Default::default(), partial_result_params: Default::default(),
context: lsp::CodeActionContext { context: lsp::CodeActionContext {
diagnostics: relevant_diagnostics, diagnostics: relevant_diagnostics,
only: Some(vec![ only: lang_server.code_action_kinds(),
lsp::CodeActionKind::EMPTY,
lsp::CodeActionKind::QUICKFIX,
lsp::CodeActionKind::REFACTOR,
lsp::CodeActionKind::REFACTOR_EXTRACT,
lsp::CodeActionKind::SOURCE,
]),
}, },
}) })
.await? .await?

View file

@ -4,6 +4,7 @@ use async_trait::async_trait;
use client::http::HttpClient; use client::http::HttpClient;
use futures::StreamExt; use futures::StreamExt;
use language::{LanguageServerBinary, LanguageServerName, LspAdapter}; use language::{LanguageServerBinary, LanguageServerName, LspAdapter};
use lsp::CodeActionKind;
use serde_json::json; use serde_json::json;
use smol::fs; use smol::fs;
use std::{ use std::{
@ -142,6 +143,15 @@ impl LspAdapter for TypeScriptLspAdapter {
.log_err() .log_err()
} }
fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
Some(vec![
CodeActionKind::QUICKFIX,
CodeActionKind::REFACTOR,
CodeActionKind::REFACTOR_EXTRACT,
CodeActionKind::SOURCE,
])
}
async fn label_for_completion( async fn label_for_completion(
&self, &self,
item: &lsp::CompletionItem, item: &lsp::CompletionItem,