mirror of https://github.com/lapce/lapce.git
code action to use context menu
This commit is contained in:
parent
f94d55f629
commit
c19f2bf222
|
@ -13,8 +13,8 @@
|
|||
source_control::DiffInfo, style::Style, terminal::TermId,
|
||||
};
|
||||
use lsp_types::{
|
||||
CodeActionResponse, CompletionItem, CompletionResponse, Location, Position,
|
||||
ProgressParams, PublishDiagnosticsParams, TextEdit,
|
||||
CodeActionOrCommand, CodeActionResponse, CompletionItem, CompletionResponse,
|
||||
Location, Position, ProgressParams, PublishDiagnosticsParams, TextEdit,
|
||||
};
|
||||
use serde_json::Value;
|
||||
use strum::{self, EnumMessage, IntoEnumIterator};
|
||||
|
@ -405,6 +405,7 @@ pub enum LapceUICommand {
|
|||
UpdateHover(usize, Arc<Vec<RichText>>),
|
||||
UpdateCodeActions(PathBuf, u64, usize, CodeActionResponse),
|
||||
CancelPalette,
|
||||
RunCodeAction(CodeActionOrCommand),
|
||||
ShowCodeActions,
|
||||
CancelCodeActions,
|
||||
Hide,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
use crate::command::{CommandExecuted, CommandKind};
|
||||
use crate::completion::{CompletionData, CompletionStatus, Snippet};
|
||||
use crate::config::Config;
|
||||
use crate::data::LapceData;
|
||||
use crate::data::{
|
||||
EditorDiagnostic, InlineFindDirection, LapceEditorData, LapceMainSplitData,
|
||||
SplitContent,
|
||||
|
@ -40,6 +41,7 @@
|
|||
};
|
||||
use lapce_core::mode::{Mode, MotionMode};
|
||||
pub use lapce_core::syntax::Syntax;
|
||||
use lsp_types::CodeActionOrCommand;
|
||||
use lsp_types::CompletionTextEdit;
|
||||
use lsp_types::{
|
||||
CodeActionResponse, CompletionItem, DiagnosticSeverity, GotoDefinitionResponse,
|
||||
|
@ -1628,11 +1630,32 @@ fn run_focus_command(
|
|||
ShowCodeActions => {
|
||||
if let Some(actions) = self.current_code_actions() {
|
||||
if !actions.is_empty() {
|
||||
ctx.submit_command(Command::new(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::ShowCodeActions,
|
||||
Target::Auto,
|
||||
));
|
||||
let mut menu = druid::Menu::new("");
|
||||
|
||||
for action in actions.iter() {
|
||||
let title = match action {
|
||||
CodeActionOrCommand::Command(c) => c.title.clone(),
|
||||
CodeActionOrCommand::CodeAction(a) => {
|
||||
a.title.clone()
|
||||
}
|
||||
};
|
||||
let mut item = druid::MenuItem::new(title);
|
||||
item = item.command(Command::new(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::RunCodeAction(action.clone()),
|
||||
Target::Widget(*self.main_split.tab_id),
|
||||
));
|
||||
menu = menu.entry(item);
|
||||
}
|
||||
let offset = self.editor.new_cursor.offset();
|
||||
let point = self.doc.point_of_offset(
|
||||
ctx.text(),
|
||||
offset,
|
||||
self.config.editor.font_size,
|
||||
&self.config,
|
||||
);
|
||||
let point = ctx.to_window(point);
|
||||
ctx.show_context_menu::<LapceData>(menu, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ fn mouse_down(
|
|||
match mouse_event.button {
|
||||
MouseButton::Left => {
|
||||
self.left_click(ctx, mouse_event, editor_data, config);
|
||||
editor_data.get_code_actions(ctx);
|
||||
editor_data.cancel_completion();
|
||||
// TODO: Don't cancel over here, because it would good to allow the user to
|
||||
// select text inside the hover data
|
||||
|
@ -202,6 +203,7 @@ fn mouse_down(
|
|||
MouseButton::Right => {
|
||||
self.mouse_hover_timer = TimerToken::INVALID;
|
||||
self.right_click(ctx, editor_data, mouse_event, config);
|
||||
editor_data.get_code_actions(ctx);
|
||||
editor_data.cancel_completion();
|
||||
editor_data.cancel_hover();
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
use crate::svg::get_svg;
|
||||
use druid::{
|
||||
piet::{Text, TextLayout, TextLayoutBuilder},
|
||||
BoxConstraints, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx,
|
||||
PaintCtx, Point, Rect, RenderContext, Size, UpdateCtx, Widget, WidgetId,
|
||||
piet::{PietText, Text, TextLayout, TextLayoutBuilder},
|
||||
BoxConstraints, Command, Env, Event, EventCtx, LayoutCtx, LifeCycle,
|
||||
LifeCycleCtx, PaintCtx, Point, Rect, RenderContext, Size, Target, UpdateCtx,
|
||||
Widget, WidgetId,
|
||||
};
|
||||
use lapce_core::buffer::DiffLines;
|
||||
use lapce_core::{buffer::DiffLines, command::FocusCommand};
|
||||
use lapce_data::{
|
||||
config::LapceTheme,
|
||||
command::{
|
||||
CommandKind, LapceCommand, LapceUICommand, LAPCE_COMMAND, LAPCE_UI_COMMAND,
|
||||
},
|
||||
config::{Config, LapceTheme},
|
||||
data::{EditorView, LapceTabData},
|
||||
editor::{LapceEditorBufferData, Syntax},
|
||||
};
|
||||
|
@ -14,6 +18,7 @@
|
|||
pub struct LapceEditorGutter {
|
||||
view_id: WidgetId,
|
||||
width: f64,
|
||||
mouse_down_pos: Point,
|
||||
}
|
||||
|
||||
impl LapceEditorGutter {
|
||||
|
@ -21,6 +26,7 @@ pub fn new(view_id: WidgetId) -> Self {
|
|||
Self {
|
||||
view_id,
|
||||
width: 0.0,
|
||||
mouse_down_pos: Point::ZERO,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +34,39 @@ pub fn new(view_id: WidgetId) -> Self {
|
|||
impl Widget<LapceTabData> for LapceEditorGutter {
|
||||
fn event(
|
||||
&mut self,
|
||||
_ctx: &mut EventCtx,
|
||||
_event: &Event,
|
||||
_data: &mut LapceTabData,
|
||||
ctx: &mut EventCtx,
|
||||
event: &Event,
|
||||
data: &mut LapceTabData,
|
||||
_env: &Env,
|
||||
) {
|
||||
match event {
|
||||
Event::MouseDown(mouse_event) => {
|
||||
self.mouse_down_pos = mouse_event.pos;
|
||||
}
|
||||
Event::MouseUp(mouse_event) => {
|
||||
let data = data.editor_view_content(self.view_id);
|
||||
if let Some(actions) = data.current_code_actions() {
|
||||
if !actions.is_empty() {
|
||||
let rect = self.code_actions_rect(ctx.text(), &data);
|
||||
if rect.contains(self.mouse_down_pos)
|
||||
&& rect.contains(mouse_event.pos)
|
||||
{
|
||||
ctx.submit_command(Command::new(
|
||||
LAPCE_COMMAND,
|
||||
LapceCommand {
|
||||
kind: CommandKind::Focus(
|
||||
FocusCommand::ShowCodeActions,
|
||||
),
|
||||
data: None,
|
||||
},
|
||||
Target::Widget(*data.main_split.tab_id),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn lifecycle(
|
||||
|
@ -436,6 +470,26 @@ fn paint_gutter_code_lens(
|
|||
}
|
||||
}
|
||||
|
||||
fn code_actions_rect(
|
||||
&self,
|
||||
text: &mut PietText,
|
||||
data: &LapceEditorBufferData,
|
||||
) -> Rect {
|
||||
let line_height = data.config.editor.line_height as f64;
|
||||
let offset = data.editor.new_cursor.offset();
|
||||
let (line, _) = data.doc.buffer().offset_to_line_col(offset);
|
||||
|
||||
let width = 16.0;
|
||||
let height = 16.0;
|
||||
let char_width = data.config.editor_char_width(text);
|
||||
let rect = Size::new(width, height).to_rect().with_origin(Point::new(
|
||||
self.width + char_width + 3.0,
|
||||
(line_height - height) / 2.0 + line_height * line as f64
|
||||
- data.editor.scroll_offset.y,
|
||||
));
|
||||
rect
|
||||
}
|
||||
|
||||
fn paint_code_actions_hint(
|
||||
&self,
|
||||
data: &LapceEditorBufferData,
|
||||
|
@ -443,19 +497,8 @@ fn paint_code_actions_hint(
|
|||
) {
|
||||
if let Some(actions) = data.current_code_actions() {
|
||||
if !actions.is_empty() {
|
||||
let line_height = data.config.editor.line_height as f64;
|
||||
let offset = data.editor.new_cursor.offset();
|
||||
let (line, _) = data.doc.buffer().offset_to_line_col(offset);
|
||||
let svg = get_svg("lightbulb.svg").unwrap();
|
||||
let width = 16.0;
|
||||
let height = 16.0;
|
||||
let char_width = data.config.editor_char_width(ctx.text());
|
||||
let rect =
|
||||
Size::new(width, height).to_rect().with_origin(Point::new(
|
||||
self.width + char_width + 3.0,
|
||||
(line_height - height) / 2.0 + line_height * line as f64
|
||||
- data.editor.scroll_offset.y,
|
||||
));
|
||||
let rect = self.code_actions_rect(ctx.text(), data);
|
||||
ctx.draw_svg(
|
||||
&svg,
|
||||
rect,
|
||||
|
|
Loading…
Reference in New Issue