Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions crates/ui/src/input/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use std::rc::Rc;

use gpui::prelude::FluentBuilder as _;
use gpui::{
AnyElement, App, Context, DefiniteLength, Edges, EdgesRefinement, Entity, Hsla,
AnyElement, App, DefiniteLength, Edges, EdgesRefinement, Entity, Hsla,
InteractiveElement as _, IntoElement, MouseButton, ParentElement as _, Rems, RenderOnce,
StyleRefinement, Styled, TextAlign, Window, div, px, relative,
};

use crate::button::{Button, ButtonVariants as _};
use crate::input::clear_button;
use crate::menu::PopupMenu;
use crate::native_menu::NativeMenu;
use crate::spinner::Spinner;
use crate::{ActiveTheme, Colorize, v_flex};
use crate::{IconName, Size};
Expand Down Expand Up @@ -50,9 +50,8 @@ pub struct Input {

/// An optional context menu builder to allow a custom context menu on the input.
///
/// If set, this will override the built-in context menu.
context_menu_builder:
Option<Rc<dyn Fn(PopupMenu, &mut Window, &mut Context<PopupMenu>) -> PopupMenu>>,
/// If set, this overrides the built-in context menu.
context_menu_builder: Option<Rc<dyn Fn(NativeMenu, &mut Window, &mut App) -> NativeMenu>>,
}

impl Sizable for Input {
Expand Down Expand Up @@ -159,10 +158,12 @@ impl Input {
self
}

/// Sets the context menu for the input.
/// Sets a custom context menu builder for the input, shown as a native OS menu.
///
/// If set, this overrides the built-in right-click context menu.
pub fn context_menu(
mut self,
f: impl Fn(PopupMenu, &mut Window, &mut Context<PopupMenu>) -> PopupMenu + 'static,
f: impl Fn(NativeMenu, &mut Window, &mut App) -> NativeMenu + 'static,
) -> Self {
self.context_menu_builder = Some(Rc::new(f));
self
Expand Down
1 change: 0 additions & 1 deletion crates/ui/src/input/lsp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ impl InputState {
handled = menu.handle_action(action, window, cx)
});
}
ContextMenu::RightClick(..) => {}
};

handled
Expand Down
160 changes: 0 additions & 160 deletions crates/ui/src/input/popovers/context_menu.rs

This file was deleted.

5 changes: 0 additions & 5 deletions crates/ui/src/input/popovers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
mod code_action_menu;
mod completion_menu;
mod context_menu;
mod diagnostic_popover;
mod hover_popover;

pub(crate) use code_action_menu::*;
pub(crate) use completion_menu::*;
pub(crate) use context_menu::*;
pub(crate) use diagnostic_popover::*;
pub(crate) use hover_popover::*;

Expand All @@ -23,23 +21,20 @@ use crate::{
pub(crate) enum ContextMenu {
Completion(Entity<CompletionMenu>),
CodeAction(Entity<CodeActionMenu>),
RightClick(Entity<InputContextMenu>),
}

impl ContextMenu {
pub(crate) fn is_open(&self, cx: &App) -> bool {
match self {
ContextMenu::Completion(menu) => menu.read(cx).is_open(),
ContextMenu::CodeAction(menu) => menu.read(cx).is_open(),
ContextMenu::RightClick(menu) => menu.read(cx).is_open(),
}
}

pub(crate) fn render(&self) -> impl IntoElement {
match self {
ContextMenu::Completion(menu) => menu.clone().into_any_element(),
ContextMenu::CodeAction(menu) => menu.clone().into_any_element(),
ContextMenu::RightClick(menu) => menu.clone().into_any_element(),
}
}
}
Expand Down
89 changes: 79 additions & 10 deletions crates/ui/src/input/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ use crate::input::{
HoverDefinition, InlineCompletion, Lsp, Position, RopeExt as _, Selection,
display_map::LineLayout,
element::RIGHT_MARGIN,
popovers::{ContextMenu, DiagnosticPopover, HoverPopover, InputContextMenu},
popovers::{ContextMenu, DiagnosticPopover, HoverPopover},
search::SearchPanel,
};
use crate::menu::PopupMenu;
use crate::native_menu::NativeMenu;
use crate::scroll::AutoScroll;
use crate::{Root, history::History};

Expand Down Expand Up @@ -396,17 +396,16 @@ pub struct InputState {
diagnostic_popover: Option<Entity<DiagnosticPopover>>,
/// Completion/CodeAction context menu
pub(super) context_menu_content: Option<ContextMenu>,
pub(super) context_menu: Entity<InputContextMenu>,

/// An optional context menu builder to allow a custom context menu on the input.
/// An optional context menu builder to allow a custom right-click context menu on the input.
///
/// If set, this will override the built-in context menu and ignore the value set in [`Self::enable_context_menu`].
/// If set, this overrides the built-in context menu (and ignores [`Self::enable_context_menu`]).
pub(super) context_menu_builder:
Option<Rc<dyn Fn(PopupMenu, &mut Window, &mut Context<PopupMenu>) -> PopupMenu>>,
Option<Rc<dyn Fn(NativeMenu, &mut Window, &mut App) -> NativeMenu>>,

/// Whether the context menu that shows on right-click is enabled.
///
/// This value will be ignored if a context menu builder is defined in [`Self::context_menu_builder`].
/// This value is ignored if a context menu builder is defined in [`Self::context_menu_builder`].
pub(super) enable_context_menu: bool,

/// A flag to indicate if we are currently inserting a completion item.
Expand Down Expand Up @@ -469,7 +468,6 @@ impl InputState {
];

let text_style = window.text_style();
let mouse_context_menu = InputContextMenu::new(cx.entity(), window, cx);

Self {
focus_handle: focus_handle.clone(),
Expand Down Expand Up @@ -519,7 +517,6 @@ impl InputState {
lsp: Lsp::default(),
diagnostic_popover: None,
context_menu_content: None,
context_menu: mouse_context_menu,
context_menu_builder: None,
enable_context_menu: true,
completion_inserting: false,
Expand Down Expand Up @@ -582,7 +579,7 @@ impl InputState {
/// Sets whether the context menu that shows on right-click is enabled.
///
/// The context menu is enabled by default.
/// This value will be ignored if a custom context menu is defined on the input.
/// This value is ignored if a custom context menu builder is defined on the input.
pub fn context_menu(mut self, enable: bool) -> Self {
self.enable_context_menu = enable;
self
Expand Down Expand Up @@ -1503,6 +1500,78 @@ impl InputState {
cx.propagate();
}

/// Show the right-click context menu as a native OS menu.
pub(crate) fn handle_right_click_menu(
&mut self,
event: &MouseDownEvent,
offset: usize,
window: &mut Window,
cx: &mut Context<Self>,
) {
if crate::global_state::GlobalState::global(cx).is_in_deferred_context() {
return;
}

if !self.selected_range.contains(offset) {
self.move_to(offset, None, cx);
}

// A custom builder fully replaces the built-in context menu.
let menu = if let Some(builder) = self.context_menu_builder.clone() {
builder(NativeMenu::new(), window, cx)
} else {
let is_code_editor = self.mode.is_code_editor();
if is_code_editor {
self.handle_hover_definition(offset, window, cx);
}

let is_enable = !self.disabled;
let has_goto_definition = is_enable && self.lsp.definition_provider.is_some();
let has_code_action = is_enable && !self.lsp.code_action_providers.is_empty();
let is_selected = !self.selected_range.is_empty();
let has_paste = is_enable && cx.read_from_clipboard().is_some();

let mut menu = NativeMenu::new();
if is_code_editor {
menu = menu
.menu_with_disabled(
rust_i18n::t!("Input.Go to Definition"),
!has_goto_definition,
Box::new(crate::input::GoToDefinition),
)
.menu_with_disabled(
rust_i18n::t!("Input.Show Code Actions"),
!has_code_action,
Box::new(crate::input::ToggleCodeActions),
)
.separator();
}

menu.menu_with_disabled(
rust_i18n::t!("Input.Cut"),
!(is_enable && is_selected),
Box::new(crate::input::Cut),
)
.menu_with_disabled(
rust_i18n::t!("Input.Copy"),
!is_selected,
Box::new(crate::input::Copy),
)
.menu_with_disabled(
rust_i18n::t!("Input.Paste"),
!has_paste,
Box::new(crate::input::Paste),
)
.separator()
.menu(
rust_i18n::t!("Input.Select All"),
Box::new(crate::input::SelectAll),
)
};

menu.show(event.position, window, cx);
}

pub(super) fn on_mouse_down(
&mut self,
event: &MouseDownEvent,
Expand Down
Loading
Loading