WIP: Start on applying code actions

This commit is contained in:
Antonio Scandurra
2022-02-07 12:20:03 +01:00
parent dc20be256e
commit 982e90539d
6 changed files with 154 additions and 32 deletions
+31 -19
View File
@@ -30,7 +30,7 @@ use gpui::{
use items::BufferItemHandle;
use itertools::Itertools as _;
use language::{
AnchorRangeExt as _, BracketPair, Buffer, Completion, CompletionLabel, Diagnostic,
AnchorRangeExt as _, BracketPair, Buffer, CodeAction, Completion, CompletionLabel, Diagnostic,
DiagnosticSeverity, Language, Point, Selection, SelectionGoal, TransactionId,
};
use multi_buffer::MultiBufferChunks;
@@ -654,7 +654,7 @@ impl CompletionsMenu {
}
struct CodeActionsMenu {
actions: Arc<[lsp::CodeAction]>,
actions: Arc<[CodeAction<Anchor>]>,
selected_item: usize,
list: UniformListState,
}
@@ -699,7 +699,7 @@ impl CodeActionsMenu {
settings.style.autocomplete.item
};
Text::new(action.title.clone(), settings.style.text.clone())
Text::new(action.lsp_action.title.clone(), settings.style.text.clone())
.with_soft_wrap(false)
.contained()
.with_style(item_style)
@@ -717,7 +717,7 @@ impl CodeActionsMenu {
self.actions
.iter()
.enumerate()
.max_by_key(|(_, action)| action.title.chars().count())
.max_by_key(|(_, action)| action.lsp_action.title.chars().count())
.map(|(ix, _)| ix),
)
.contained()
@@ -1935,7 +1935,7 @@ impl Editor {
self.completion_tasks.push((id, task));
}
fn confirm_completion(
pub fn confirm_completion(
&mut self,
ConfirmCompletion(completion_ix): &ConfirmCompletion,
cx: &mut ViewContext<Self>,
@@ -2051,23 +2051,35 @@ impl Editor {
}
fn confirm_code_action(
&mut self,
workspace: &mut Workspace,
ConfirmCodeAction(action_ix): &ConfirmCodeAction,
cx: &mut ViewContext<Self>,
cx: &mut ViewContext<Workspace>,
) -> Option<Task<Result<()>>> {
let actions_menu = if let ContextMenu::CodeActions(menu) = self.hide_context_menu(cx)? {
menu
} else {
return None;
};
let active_item = workspace.active_item(cx)?;
let editor = active_item.act_as::<Self>(cx)?;
let (buffer, action) = editor.update(cx, |editor, cx| {
let actions_menu =
if let ContextMenu::CodeActions(menu) = editor.hide_context_menu(cx)? {
menu
} else {
return None;
};
let action_ix = action_ix.unwrap_or(actions_menu.selected_item);
let action = actions_menu.actions.get(action_ix)?.clone();
let (buffer, position) = editor
.buffer
.read(cx)
.text_anchor_for_position(action.position, cx);
let action = CodeAction {
position,
lsp_action: action.lsp_action,
};
Some((buffer, action))
})?;
let action = actions_menu
.actions
.get(action_ix.unwrap_or(actions_menu.selected_item))?;
dbg!(action);
None
Some(workspace.project().update(cx, |project, cx| {
project.apply_code_action(buffer, action, cx)
}))
}
pub fn showing_context_menu(&self) -> bool {
+15 -5
View File
@@ -5,11 +5,11 @@ use anyhow::Result;
use clock::ReplicaId;
use collections::{HashMap, HashSet};
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
pub use language::Completion;
use language::{
Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language, Outline,
OutlineItem, Selection, ToOffset as _, ToPoint as _, ToPointUtf16 as _, TransactionId,
};
pub use language::{CodeAction, Completion};
use std::{
cell::{Ref, RefCell},
cmp, fmt, io,
@@ -864,15 +864,25 @@ impl MultiBuffer {
&self,
position: T,
cx: &mut ModelContext<Self>,
) -> Task<Result<Vec<lsp::CodeAction>>>
) -> Task<Result<Vec<CodeAction<Anchor>>>>
where
T: ToOffset,
{
let anchor = self.read(cx).anchor_before(position);
let buffer = self.buffers.borrow()[&anchor.buffer_id].buffer.clone();
let code_actions =
buffer.update(cx, |buffer, cx| buffer.code_actions(anchor.text_anchor, cx));
cx.spawn(|this, cx| async move { code_actions.await })
let code_actions = buffer.update(cx, |buffer, cx| {
buffer.code_actions(anchor.text_anchor.clone(), cx)
});
cx.foreground().spawn(async move {
Ok(code_actions
.await?
.into_iter()
.map(|action| CodeAction {
position: anchor.clone(),
lsp_action: action.lsp_action,
})
.collect())
})
}
pub fn completions<T>(