extend eidtor mode
Co-authored-by: Oleksiy Syvokon <oleksiy.syvokon@gmail.com>
This commit is contained in:
parent
c6d0d75711
commit
fd0316f7d1
12 changed files with 261 additions and 227 deletions
|
@ -50,14 +50,17 @@ pub enum NotifyWhenAgentWaiting {
|
|||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
|
||||
pub enum AgentEditorMode {
|
||||
Vim,
|
||||
VimInsert,
|
||||
Helix,
|
||||
Default,
|
||||
EditorModeOverride(EditorMode),
|
||||
#[default]
|
||||
Inherit,
|
||||
}
|
||||
|
||||
impl From<EditorMode> for AgentEditorMode {
|
||||
fn from(b: EditorMode) -> Self {
|
||||
AgentEditorMode::EditorModeOverride(b)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct AgentSettings {
|
||||
pub enabled: bool,
|
||||
|
|
|
@ -112,6 +112,14 @@ impl MessageEditor {
|
|||
range: Cell::new(None),
|
||||
});
|
||||
let mention_set = MentionSet::default();
|
||||
|
||||
let editor_mode = match settings.editor_mode {
|
||||
agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode,
|
||||
agent_settings::AgentEditorMode::Inherit => {
|
||||
vim_mode_setting::EditorModeSetting::get_global(cx).0
|
||||
}
|
||||
};
|
||||
|
||||
let editor = cx.new(|cx| {
|
||||
let buffer = cx.new(|cx| Buffer::local("", cx).with_language(Arc::new(language), cx));
|
||||
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
|
@ -120,7 +128,7 @@ impl MessageEditor {
|
|||
editor.set_placeholder_text(placeholder, cx);
|
||||
editor.set_show_indent_guides(false, cx);
|
||||
editor.set_soft_wrap();
|
||||
editor.set_use_modal_editing(true);
|
||||
editor.set_use_modal_editing(editor_mode);
|
||||
editor.set_completion_provider(Some(Rc::new(completion_provider)));
|
||||
editor.set_context_menu_options(ContextMenuOptions {
|
||||
min_entries_visible: 12,
|
||||
|
|
|
@ -117,10 +117,7 @@ pub(crate) fn create_editor(
|
|||
let settings = agent_settings::AgentSettings::get_global(cx);
|
||||
|
||||
let editor_mode = match settings.editor_mode {
|
||||
agent_settings::AgentEditorMode::Vim => vim_mode_setting::EditorMode::Vim,
|
||||
agent_settings::AgentEditorMode::VimInsert => vim_mode_setting::EditorMode::VimInsert,
|
||||
agent_settings::AgentEditorMode::Helix => vim_mode_setting::EditorMode::Helix,
|
||||
agent_settings::AgentEditorMode::Default => vim_mode_setting::EditorMode::Default,
|
||||
agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode,
|
||||
agent_settings::AgentEditorMode::Inherit => {
|
||||
vim_mode_setting::EditorModeSetting::get_global(cx).0
|
||||
}
|
||||
|
@ -139,7 +136,6 @@ pub(crate) fn create_editor(
|
|||
editor.set_placeholder_text("Message the agent – @ to include context", cx);
|
||||
editor.set_show_indent_guides(false, cx);
|
||||
editor.set_soft_wrap();
|
||||
editor.set_use_modal_editing(true);
|
||||
editor.set_default_editor_mode(editor_mode);
|
||||
editor.set_context_menu_options(ContextMenuOptions {
|
||||
min_entries_visible: 12,
|
||||
|
|
|
@ -76,6 +76,7 @@ util.workspace = true
|
|||
workspace-hack.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
vim_mode_settings.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
dap = { workspace = true, features = ["test-support"] }
|
||||
|
|
|
@ -26,6 +26,7 @@ use std::{cell::RefCell, ops::Range, rc::Rc, usize};
|
|||
use theme::{Theme, ThemeSettings};
|
||||
use ui::{ContextMenu, Divider, PopoverMenu, SplitButton, Tooltip, prelude::*};
|
||||
use util::ResultExt;
|
||||
use vim_mode_settings::EditorMode;
|
||||
|
||||
actions!(
|
||||
console,
|
||||
|
@ -74,7 +75,7 @@ impl Console {
|
|||
editor.set_show_wrap_guides(false, cx);
|
||||
editor.set_show_indent_guides(false, cx);
|
||||
editor.set_show_edit_predictions(Some(false), window, cx);
|
||||
editor.set_use_modal_editing(false);
|
||||
editor.set_default_editor_mode(EditorMode::Default);
|
||||
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
|
||||
editor
|
||||
});
|
||||
|
|
|
@ -165,7 +165,6 @@ use project::{
|
|||
};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use rpc::{ErrorCode, ErrorExt, proto::PeerId};
|
||||
use schemars::JsonSchema;
|
||||
use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide};
|
||||
use selections_collection::{
|
||||
MutableSelectionsCollection, SelectionsCollection, resolve_selections,
|
||||
|
@ -202,7 +201,6 @@ use ui::{
|
|||
IconSize, Indicator, Key, Tooltip, h_flex, prelude::*,
|
||||
};
|
||||
use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc};
|
||||
use vim_mode_setting::EditorModeSetting;
|
||||
use workspace::{
|
||||
CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal,
|
||||
RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast,
|
||||
|
@ -2185,7 +2183,6 @@ impl Editor {
|
|||
collapse_matches: false,
|
||||
workspace: None,
|
||||
input_enabled: !is_minimap,
|
||||
use_modal_editing: full_mode,
|
||||
read_only: is_minimap,
|
||||
use_autoclose: true,
|
||||
use_auto_surround: true,
|
||||
|
@ -22940,6 +22937,7 @@ pub enum EditorEvent {
|
|||
anchor: Anchor,
|
||||
is_deactivate: bool,
|
||||
},
|
||||
EditorModeChanged,
|
||||
}
|
||||
|
||||
impl EventEmitter<EditorEvent> for Editor {}
|
||||
|
|
|
@ -406,7 +406,7 @@ pub(crate) fn commit_message_editor(
|
|||
commit_editor.set_collaboration_hub(Box::new(project));
|
||||
commit_editor.set_use_autoclose(false);
|
||||
commit_editor.set_show_gutter(false, cx);
|
||||
commit_editor.set_use_modal_editing(true);
|
||||
// commit_editor.set_use_modal_editing(true); TODO
|
||||
commit_editor.set_show_wrap_guides(false, cx);
|
||||
commit_editor.set_show_indent_guides(false, cx);
|
||||
let placeholder = placeholder.unwrap_or("Enter commit message".into());
|
||||
|
|
|
@ -75,7 +75,8 @@ pub fn init(cx: &mut App) {
|
|||
return;
|
||||
};
|
||||
|
||||
if !editor.use_modal_editing() || !editor.buffer().read(cx).is_singleton() {
|
||||
if !editor.default_editor_mode().is_modal() || !editor.buffer().read(cx).is_singleton()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -637,7 +637,7 @@ impl RulesLibrary {
|
|||
editor.set_show_gutter(false, cx);
|
||||
editor.set_show_wrap_guides(false, cx);
|
||||
editor.set_show_indent_guides(false, cx);
|
||||
editor.set_use_modal_editing(false);
|
||||
editor.set_default_editor_mode(EditorMode::Default);
|
||||
editor.set_current_line_highlight(Some(CurrentLineHighlight::None));
|
||||
editor.set_completion_provider(Some(make_completion_provider()));
|
||||
if focus {
|
||||
|
|
|
@ -32,49 +32,10 @@ use ui::{
|
|||
StyledTypography, Window, h_flex, rems,
|
||||
};
|
||||
use util::ResultExt;
|
||||
use vim_mode_setting::ModalMode;
|
||||
use workspace::searchable::Direction;
|
||||
use workspace::{Workspace, WorkspaceDb, WorkspaceId};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Mode {
|
||||
Normal,
|
||||
Insert,
|
||||
Replace,
|
||||
Visual,
|
||||
VisualLine,
|
||||
VisualBlock,
|
||||
HelixNormal,
|
||||
}
|
||||
|
||||
impl Display for Mode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Mode::Normal => write!(f, "NORMAL"),
|
||||
Mode::Insert => write!(f, "INSERT"),
|
||||
Mode::Replace => write!(f, "REPLACE"),
|
||||
Mode::Visual => write!(f, "VISUAL"),
|
||||
Mode::VisualLine => write!(f, "VISUAL LINE"),
|
||||
Mode::VisualBlock => write!(f, "VISUAL BLOCK"),
|
||||
Mode::HelixNormal => write!(f, "HELIX NORMAL"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
pub fn is_visual(&self) -> bool {
|
||||
match self {
|
||||
Self::Visual | Self::VisualLine | Self::VisualBlock => true,
|
||||
Self::Normal | Self::Insert | Self::Replace | Self::HelixNormal => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Mode {
|
||||
fn default() -> Self {
|
||||
Self::Normal
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Operator {
|
||||
Change,
|
||||
|
@ -976,7 +937,7 @@ pub struct SearchState {
|
|||
|
||||
pub prior_selections: Vec<Range<Anchor>>,
|
||||
pub prior_operator: Option<Operator>,
|
||||
pub prior_mode: Mode,
|
||||
pub prior_mode: ModalMode,
|
||||
}
|
||||
|
||||
impl Operator {
|
||||
|
@ -1043,7 +1004,7 @@ impl Operator {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_waiting(&self, mode: Mode) -> bool {
|
||||
pub fn is_waiting(&self, mode: ModalMode) -> bool {
|
||||
match self {
|
||||
Operator::AddSurrounds { target } => target.is_some() || mode.is_visual(),
|
||||
Operator::FindForward { .. }
|
||||
|
|
|
@ -40,7 +40,7 @@ use schemars::JsonSchema;
|
|||
use serde::Deserialize;
|
||||
use serde_derive::Serialize;
|
||||
use settings::{Settings, SettingsSources, SettingsStore, update_settings_file};
|
||||
use state::{Mode, Operator, RecordedSelection, SearchState, VimGlobals};
|
||||
use state::{Operator, RecordedSelection, SearchState, VimGlobals};
|
||||
use std::{mem, ops::Range, sync::Arc};
|
||||
use surrounds::SurroundsType;
|
||||
use theme::ThemeSettings;
|
||||
|
@ -360,8 +360,8 @@ impl editor::Addon for VimAddon {
|
|||
|
||||
/// The state pertaining to Vim mode.
|
||||
pub(crate) struct Vim {
|
||||
pub(crate) mode: Mode,
|
||||
pub last_mode: Mode,
|
||||
pub(crate) mode: ModalMode,
|
||||
pub last_mode: ModalMode,
|
||||
pub temp_mode: bool,
|
||||
pub status_label: Option<SharedString>,
|
||||
pub exit_temporary_mode: bool,
|
||||
|
@ -369,11 +369,11 @@ pub(crate) struct Vim {
|
|||
operator_stack: Vec<Operator>,
|
||||
pub(crate) replacements: Vec<(Range<editor::Anchor>, String)>,
|
||||
|
||||
pub(crate) stored_visual_mode: Option<(Mode, Vec<bool>)>,
|
||||
pub(crate) stored_visual_mode: Option<(ModalMode, Vec<bool>)>,
|
||||
|
||||
pub(crate) current_tx: Option<TransactionId>,
|
||||
pub(crate) current_anchor: Option<Selection<Anchor>>,
|
||||
pub(crate) undo_modes: HashMap<TransactionId, Mode>,
|
||||
pub(crate) undo_modes: HashMap<TransactionId, ModalMode>,
|
||||
pub(crate) undo_last_line_tx: Option<TransactionId>,
|
||||
|
||||
selected_register: Option<char>,
|
||||
|
@ -407,16 +407,9 @@ impl Vim {
|
|||
pub fn new(window: &mut Window, cx: &mut Context<Editor>) -> Entity<Self> {
|
||||
let editor = cx.entity();
|
||||
|
||||
let mut initial_mode = VimSettings::get_global(cx).default_mode;
|
||||
if initial_mode == Mode::Normal
|
||||
&& matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix)
|
||||
{
|
||||
initial_mode = Mode::HelixNormal;
|
||||
}
|
||||
|
||||
cx.new(|cx| Vim {
|
||||
mode: initial_mode,
|
||||
last_mode: Mode::Normal,
|
||||
mode: ModalMode::Normal,
|
||||
last_mode: ModalMode::Normal,
|
||||
temp_mode: false,
|
||||
exit_temporary_mode: false,
|
||||
operator_stack: Vec::new(),
|
||||
|
@ -450,56 +443,45 @@ impl Vim {
|
|||
return;
|
||||
};
|
||||
|
||||
if !editor.use_modal_editing() {
|
||||
if !editor.default_editor_mode().is_modal() {
|
||||
return;
|
||||
}
|
||||
|
||||
if editor.default_editor_mode() == EditorMode::Default {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut was_enabled = Vim::enabled(cx);
|
||||
let mut was_toggle = VimSettings::get_global(cx).toggle_relative_line_numbers;
|
||||
cx.observe_global_in::<SettingsStore>(window, move |editor, window, cx| {
|
||||
let enabled = Vim::enabled(cx);
|
||||
let toggle = VimSettings::get_global(cx).toggle_relative_line_numbers;
|
||||
if enabled && was_enabled && (toggle != was_toggle) {
|
||||
if toggle != was_toggle {
|
||||
if toggle {
|
||||
let is_relative = editor
|
||||
.addon::<VimAddon>()
|
||||
.map(|vim| vim.entity.read(cx).mode != Mode::Insert);
|
||||
.map(|vim| vim.entity.read(cx).mode != ModalMode::Insert);
|
||||
editor.set_relative_line_number(is_relative, cx)
|
||||
} else {
|
||||
editor.set_relative_line_number(None, cx)
|
||||
}
|
||||
}
|
||||
was_toggle = VimSettings::get_global(cx).toggle_relative_line_numbers;
|
||||
if was_enabled == enabled {
|
||||
return;
|
||||
}
|
||||
was_enabled = enabled;
|
||||
if enabled {
|
||||
Self::activate(editor, window, cx)
|
||||
} else {
|
||||
Self::deactivate(editor, cx)
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
if was_enabled {
|
||||
Self::activate(editor, window, cx)
|
||||
}
|
||||
|
||||
let mut was_enabled = true;
|
||||
cx.observe::<Editor>(window, move |editor, window, cx| {})
|
||||
.detach();
|
||||
|
||||
Self::activate(editor, window, cx)
|
||||
}
|
||||
|
||||
fn activate(editor: &mut Editor, window: &mut Window, cx: &mut Context<Editor>) {
|
||||
let vim = Vim::new(window, cx);
|
||||
|
||||
let default_editor_mode = editor.default_editor_mode();
|
||||
|
||||
if default_editor_mode == EditorMode::VimInsert {
|
||||
vim.update(cx, |vim, _| {
|
||||
vim.mode = Mode::Insert;
|
||||
});
|
||||
}
|
||||
vim.update(cx, |vim, _| {
|
||||
let initial_mode = match editor.default_editor_mode() {
|
||||
EditorMode::Default => return,
|
||||
EditorMode::Vim(modal_mode) => modal_mode,
|
||||
EditorMode::Helix(modal_mode) => modal_mode,
|
||||
};
|
||||
vim.mode = initial_mode;
|
||||
});
|
||||
|
||||
editor.register_addon(VimAddon {
|
||||
entity: vim.clone(),
|
||||
|
@ -511,34 +493,34 @@ impl Vim {
|
|||
cx,
|
||||
move |vim, _: &SwitchToNormalMode, window, cx| {
|
||||
if matches!(default_editor_mode, EditorMode::Helix) {
|
||||
vim.switch_mode(Mode::HelixNormal, false, window, cx)
|
||||
vim.switch_mode(ModalMode::HelixNormal, false, window, cx)
|
||||
} else {
|
||||
vim.switch_mode(Mode::Normal, false, window, cx)
|
||||
vim.switch_mode(ModalMode::Normal, false, window, cx)
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &SwitchToInsertMode, window, cx| {
|
||||
vim.switch_mode(Mode::Insert, false, window, cx)
|
||||
vim.switch_mode(ModalMode::Insert, false, window, cx)
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &SwitchToReplaceMode, window, cx| {
|
||||
vim.switch_mode(Mode::Replace, false, window, cx)
|
||||
vim.switch_mode(ModalMode::Replace, false, window, cx)
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &SwitchToVisualMode, window, cx| {
|
||||
vim.switch_mode(Mode::Visual, false, window, cx)
|
||||
vim.switch_mode(ModalMode::Visual, false, window, cx)
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &SwitchToVisualLineMode, window, cx| {
|
||||
vim.switch_mode(Mode::VisualLine, false, window, cx)
|
||||
vim.switch_mode(ModalMode::VisualLine, false, window, cx)
|
||||
});
|
||||
|
||||
Vim::action(
|
||||
editor,
|
||||
cx,
|
||||
|vim, _: &SwitchToVisualBlockMode, window, cx| {
|
||||
vim.switch_mode(Mode::VisualBlock, false, window, cx)
|
||||
vim.switch_mode(ModalMode::VisualBlock, false, window, cx)
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -546,7 +528,7 @@ impl Vim {
|
|||
editor,
|
||||
cx,
|
||||
|vim, _: &SwitchToHelixNormalMode, window, cx| {
|
||||
vim.switch_mode(Mode::HelixNormal, false, window, cx)
|
||||
vim.switch_mode(ModalMode::HelixNormal, false, window, cx)
|
||||
},
|
||||
);
|
||||
Vim::action(editor, cx, |_, _: &PushForcedMotion, _, cx| {
|
||||
|
@ -766,8 +748,8 @@ impl Vim {
|
|||
// displayed (and performed by `accept_edit_prediction`). This switches to
|
||||
// insert mode so that the prediction is displayed after the jump.
|
||||
match vim.mode {
|
||||
Mode::Replace => {}
|
||||
_ => vim.switch_mode(Mode::Insert, true, window, cx),
|
||||
ModalMode::Replace => {}
|
||||
_ => vim.switch_mode(ModalMode::Insert, true, window, cx),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -859,7 +841,7 @@ impl Vim {
|
|||
{
|
||||
return;
|
||||
}
|
||||
self.switch_mode(Mode::Insert, false, window, cx)
|
||||
self.switch_mode(ModalMode::Insert, false, window, cx)
|
||||
}
|
||||
if let Some(action) = keystroke_event.action.as_ref() {
|
||||
// Keystroke is handled by the vim system, so continue forward
|
||||
|
@ -935,6 +917,24 @@ impl Vim {
|
|||
vim.set_mark(mark, vec![*anchor], editor.buffer(), window, cx);
|
||||
});
|
||||
}
|
||||
EditorEvent::EditorModeChanged => {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let enabled = editor.default_editor_mode().is_modal();
|
||||
if was_enabled == enabled {
|
||||
return;
|
||||
}
|
||||
if !enabled {
|
||||
editor.set_relative_line_number(None, cx);
|
||||
}
|
||||
was_enabled = enabled;
|
||||
if enabled {
|
||||
Self::activate(editor, window, cx)
|
||||
} else {
|
||||
Self::deactivate(editor, cx)
|
||||
}
|
||||
//
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -961,18 +961,21 @@ impl Vim {
|
|||
|
||||
pub fn switch_mode(
|
||||
&mut self,
|
||||
mode: Mode,
|
||||
mode: ModalMode,
|
||||
leave_selections: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.temp_mode && mode == Mode::Normal {
|
||||
if self.temp_mode && mode == ModalMode::Normal {
|
||||
self.temp_mode = false;
|
||||
self.switch_mode(Mode::Normal, leave_selections, window, cx);
|
||||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.switch_mode(ModalMode::Normal, leave_selections, window, cx);
|
||||
self.switch_mode(ModalMode::Insert, false, window, cx);
|
||||
return;
|
||||
} else if self.temp_mode
|
||||
&& !matches!(mode, Mode::Visual | Mode::VisualLine | Mode::VisualBlock)
|
||||
&& !matches!(
|
||||
mode,
|
||||
ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock
|
||||
)
|
||||
{
|
||||
self.temp_mode = false;
|
||||
}
|
||||
|
@ -986,7 +989,7 @@ impl Vim {
|
|||
self.operator_stack.clear();
|
||||
self.selected_register.take();
|
||||
self.cancel_running_command(window, cx);
|
||||
if mode == Mode::Normal || mode != last_mode {
|
||||
if mode == ModalMode::Normal || mode != last_mode {
|
||||
self.current_tx.take();
|
||||
self.current_anchor.take();
|
||||
self.update_editor(cx, |_, editor, _| {
|
||||
|
@ -994,7 +997,7 @@ impl Vim {
|
|||
});
|
||||
}
|
||||
Vim::take_forced_motion(cx);
|
||||
if mode != Mode::Insert && mode != Mode::Replace {
|
||||
if mode != ModalMode::Insert && mode != ModalMode::Replace {
|
||||
Vim::take_count(cx);
|
||||
}
|
||||
|
||||
|
@ -1003,10 +1006,10 @@ impl Vim {
|
|||
|
||||
if VimSettings::get_global(cx).toggle_relative_line_numbers
|
||||
&& self.mode != self.last_mode
|
||||
&& (self.mode == Mode::Insert || self.last_mode == Mode::Insert)
|
||||
&& (self.mode == ModalMode::Insert || self.last_mode == ModalMode::Insert)
|
||||
{
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let is_relative = vim.mode != Mode::Insert;
|
||||
let is_relative = vim.mode != ModalMode::Insert;
|
||||
editor.set_relative_line_number(Some(is_relative), cx)
|
||||
});
|
||||
}
|
||||
|
@ -1021,13 +1024,15 @@ impl Vim {
|
|||
|
||||
// Adjust selections
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
if last_mode != Mode::VisualBlock && last_mode.is_visual() && mode == Mode::VisualBlock
|
||||
if last_mode != ModalMode::VisualBlock
|
||||
&& last_mode.is_visual()
|
||||
&& mode == ModalMode::VisualBlock
|
||||
{
|
||||
vim.visual_block_motion(true, editor, window, cx, |_, point, goal| {
|
||||
Some((point, goal))
|
||||
})
|
||||
}
|
||||
if (last_mode == Mode::Insert || last_mode == Mode::Replace)
|
||||
if (last_mode == ModalMode::Insert || last_mode == ModalMode::Replace)
|
||||
&& let Some(prior_tx) = prior_tx
|
||||
{
|
||||
editor.group_until_transaction(prior_tx, cx)
|
||||
|
@ -1037,15 +1042,15 @@ impl Vim {
|
|||
// we cheat with visual block mode and use multiple cursors.
|
||||
// the cost of this cheat is we need to convert back to a single
|
||||
// cursor whenever vim would.
|
||||
if last_mode == Mode::VisualBlock
|
||||
&& (mode != Mode::VisualBlock && mode != Mode::Insert)
|
||||
if last_mode == ModalMode::VisualBlock
|
||||
&& (mode != ModalMode::VisualBlock && mode != ModalMode::Insert)
|
||||
{
|
||||
let tail = s.oldest_anchor().tail();
|
||||
let head = s.newest_anchor().head();
|
||||
s.select_anchor_ranges(vec![tail..head]);
|
||||
} else if last_mode == Mode::Insert
|
||||
&& prior_mode == Mode::VisualBlock
|
||||
&& mode != Mode::VisualBlock
|
||||
} else if last_mode == ModalMode::Insert
|
||||
&& prior_mode == ModalMode::VisualBlock
|
||||
&& mode != ModalMode::VisualBlock
|
||||
{
|
||||
let pos = s.first_anchor().head();
|
||||
s.select_anchor_ranges(vec![pos..pos])
|
||||
|
@ -1110,7 +1115,7 @@ impl Vim {
|
|||
pub fn cursor_shape(&self, cx: &mut App) -> CursorShape {
|
||||
let cursor_shape = VimSettings::get_global(cx).cursor_shape;
|
||||
match self.mode {
|
||||
Mode::Normal => {
|
||||
ModalMode::Normal => {
|
||||
if let Some(operator) = self.operator_stack.last() {
|
||||
match operator {
|
||||
// Navigation operators -> Block cursor
|
||||
|
@ -1129,12 +1134,12 @@ impl Vim {
|
|||
cursor_shape.normal.unwrap_or(CursorShape::Block)
|
||||
}
|
||||
}
|
||||
Mode::HelixNormal => cursor_shape.normal.unwrap_or(CursorShape::Block),
|
||||
Mode::Replace => cursor_shape.replace.unwrap_or(CursorShape::Underline),
|
||||
Mode::Visual | Mode::VisualLine | Mode::VisualBlock => {
|
||||
ModalMode::HelixNormal => cursor_shape.normal.unwrap_or(CursorShape::Block),
|
||||
ModalMode::Replace => cursor_shape.replace.unwrap_or(CursorShape::Underline),
|
||||
ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => {
|
||||
cursor_shape.visual.unwrap_or(CursorShape::Block)
|
||||
}
|
||||
Mode::Insert => cursor_shape.insert.unwrap_or({
|
||||
ModalMode::Insert => cursor_shape.insert.unwrap_or({
|
||||
let editor_settings = EditorSettings::get_global(cx);
|
||||
editor_settings.cursor_shape.unwrap_or_default()
|
||||
}),
|
||||
|
@ -1143,45 +1148,45 @@ impl Vim {
|
|||
|
||||
pub fn editor_input_enabled(&self) -> bool {
|
||||
match self.mode {
|
||||
Mode::Insert => {
|
||||
ModalMode::Insert => {
|
||||
if let Some(operator) = self.operator_stack.last() {
|
||||
!operator.is_waiting(self.mode)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
Mode::Normal
|
||||
| Mode::HelixNormal
|
||||
| Mode::Replace
|
||||
| Mode::Visual
|
||||
| Mode::VisualLine
|
||||
| Mode::VisualBlock => false,
|
||||
ModalMode::Normal
|
||||
| ModalMode::HelixNormal
|
||||
| ModalMode::Replace
|
||||
| ModalMode::Visual
|
||||
| ModalMode::VisualLine
|
||||
| ModalMode::VisualBlock => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn should_autoindent(&self) -> bool {
|
||||
!(self.mode == Mode::Insert && self.last_mode == Mode::VisualBlock)
|
||||
!(self.mode == ModalMode::Insert && self.last_mode == ModalMode::VisualBlock)
|
||||
}
|
||||
|
||||
pub fn clip_at_line_ends(&self) -> bool {
|
||||
match self.mode {
|
||||
Mode::Insert
|
||||
| Mode::Visual
|
||||
| Mode::VisualLine
|
||||
| Mode::VisualBlock
|
||||
| Mode::Replace
|
||||
| Mode::HelixNormal => false,
|
||||
Mode::Normal => true,
|
||||
ModalMode::Insert
|
||||
| ModalMode::Visual
|
||||
| ModalMode::VisualLine
|
||||
| ModalMode::VisualBlock
|
||||
| ModalMode::Replace
|
||||
| ModalMode::HelixNormal => false,
|
||||
ModalMode::Normal => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend_key_context(&self, context: &mut KeyContext, cx: &App) {
|
||||
let mut mode = match self.mode {
|
||||
Mode::Normal => "normal",
|
||||
Mode::Visual | Mode::VisualLine | Mode::VisualBlock => "visual",
|
||||
Mode::Insert => "insert",
|
||||
Mode::Replace => "replace",
|
||||
Mode::HelixNormal => "helix_normal",
|
||||
ModalMode::Normal => "normal",
|
||||
ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => "visual",
|
||||
ModalMode::Insert => "insert",
|
||||
ModalMode::Replace => "replace",
|
||||
ModalMode::HelixNormal => "helix_normal",
|
||||
}
|
||||
.to_string();
|
||||
|
||||
|
@ -1226,12 +1231,12 @@ impl Vim {
|
|||
|
||||
if editor_mode.is_full()
|
||||
&& !newest_selection_empty
|
||||
&& self.mode == Mode::Normal
|
||||
&& self.mode == ModalMode::Normal
|
||||
// When following someone, don't switch vim mode.
|
||||
&& editor.leader_id().is_none()
|
||||
{
|
||||
if preserve_selection {
|
||||
self.switch_mode(Mode::Visual, true, window, cx);
|
||||
self.switch_mode(ModalMode::Visual, true, window, cx);
|
||||
} else {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
|
@ -1257,13 +1262,13 @@ impl Vim {
|
|||
});
|
||||
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let is_relative = vim.mode != Mode::Insert;
|
||||
let is_relative = vim.mode != ModalMode::Insert;
|
||||
editor.set_relative_line_number(Some(is_relative), cx)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let is_relative = vim.mode != Mode::Insert;
|
||||
let is_relative = vim.mode != ModalMode::Insert;
|
||||
editor.set_relative_line_number(Some(is_relative), cx)
|
||||
});
|
||||
}
|
||||
|
@ -1351,19 +1356,19 @@ impl Vim {
|
|||
|
||||
if let Some((oldest, newest)) = selections {
|
||||
globals.recorded_selection = match self.mode {
|
||||
Mode::Visual if newest.end.row == newest.start.row => {
|
||||
ModalMode::Visual if newest.end.row == newest.start.row => {
|
||||
RecordedSelection::SingleLine {
|
||||
cols: newest.end.column - newest.start.column,
|
||||
}
|
||||
}
|
||||
Mode::Visual => RecordedSelection::Visual {
|
||||
ModalMode::Visual => RecordedSelection::Visual {
|
||||
rows: newest.end.row - newest.start.row,
|
||||
cols: newest.end.column,
|
||||
},
|
||||
Mode::VisualLine => RecordedSelection::VisualLine {
|
||||
ModalMode::VisualLine => RecordedSelection::VisualLine {
|
||||
rows: newest.end.row - newest.start.row,
|
||||
},
|
||||
Mode::VisualBlock => RecordedSelection::VisualBlock {
|
||||
ModalMode::VisualBlock => RecordedSelection::VisualBlock {
|
||||
rows: newest.end.row.abs_diff(oldest.start.row),
|
||||
cols: newest.end.column.abs_diff(oldest.start.column),
|
||||
},
|
||||
|
@ -1480,9 +1485,9 @@ impl Vim {
|
|||
_window: &mut Window,
|
||||
_: &mut Context<Self>,
|
||||
) {
|
||||
let mode = if (self.mode == Mode::Insert
|
||||
|| self.mode == Mode::Replace
|
||||
|| self.mode == Mode::Normal)
|
||||
let mode = if (self.mode == ModalMode::Insert
|
||||
|| self.mode == ModalMode::Replace
|
||||
|| self.mode == ModalMode::Normal)
|
||||
&& self.current_tx.is_none()
|
||||
{
|
||||
self.current_tx = Some(transaction_id);
|
||||
|
@ -1490,7 +1495,7 @@ impl Vim {
|
|||
} else {
|
||||
self.mode
|
||||
};
|
||||
if mode == Mode::VisualLine || mode == Mode::VisualBlock {
|
||||
if mode == ModalMode::VisualLine || mode == ModalMode::VisualBlock {
|
||||
self.undo_modes.insert(transaction_id, mode);
|
||||
}
|
||||
}
|
||||
|
@ -1502,12 +1507,12 @@ impl Vim {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
match self.mode {
|
||||
Mode::VisualLine | Mode::VisualBlock | Mode::Visual => {
|
||||
ModalMode::VisualLine | ModalMode::VisualBlock | ModalMode::Visual => {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let original_mode = vim.undo_modes.get(transaction_id);
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
match original_mode {
|
||||
Some(Mode::VisualLine) => {
|
||||
Some(ModalMode::VisualLine) => {
|
||||
s.move_with(|map, selection| {
|
||||
selection.collapse_to(
|
||||
map.prev_line_boundary(selection.start.to_point(map)).1,
|
||||
|
@ -1515,7 +1520,7 @@ impl Vim {
|
|||
)
|
||||
});
|
||||
}
|
||||
Some(Mode::VisualBlock) => {
|
||||
Some(ModalMode::VisualBlock) => {
|
||||
let mut first = s.first_anchor();
|
||||
first.collapse_to(first.start, first.goal);
|
||||
s.select_anchors(vec![first]);
|
||||
|
@ -1531,9 +1536,9 @@ impl Vim {
|
|||
}
|
||||
});
|
||||
});
|
||||
self.switch_mode(Mode::Normal, true, window, cx)
|
||||
self.switch_mode(ModalMode::Normal, true, window, cx)
|
||||
}
|
||||
Mode::Normal => {
|
||||
ModalMode::Normal => {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
|
@ -1543,7 +1548,7 @@ impl Vim {
|
|||
})
|
||||
});
|
||||
}
|
||||
Mode::Insert | Mode::Replace | Mode::HelixNormal => {}
|
||||
ModalMode::Insert | ModalMode::Replace | ModalMode::HelixNormal => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1556,7 +1561,7 @@ impl Vim {
|
|||
|
||||
let newest = editor.read(cx).selections.newest_anchor().clone();
|
||||
let is_multicursor = editor.read(cx).selections.count() > 1;
|
||||
if self.mode == Mode::Insert && self.current_tx.is_some() {
|
||||
if self.mode == ModalMode::Insert && self.current_tx.is_some() {
|
||||
if self.current_anchor.is_none() {
|
||||
self.current_anchor = Some(newest);
|
||||
} else if self.current_anchor.as_ref().unwrap() != &newest
|
||||
|
@ -1566,17 +1571,22 @@ impl Vim {
|
|||
editor.group_until_transaction(tx_id, cx)
|
||||
});
|
||||
}
|
||||
} else if self.mode == Mode::Normal && newest.start != newest.end {
|
||||
} else if self.mode == ModalMode::Normal && newest.start != newest.end {
|
||||
if matches!(newest.goal, SelectionGoal::HorizontalRange { .. }) {
|
||||
self.switch_mode(Mode::VisualBlock, false, window, cx);
|
||||
self.switch_mode(ModalMode::VisualBlock, false, window, cx);
|
||||
} else {
|
||||
self.switch_mode(Mode::Visual, false, window, cx)
|
||||
self.switch_mode(ModalMode::Visual, false, window, cx)
|
||||
}
|
||||
} else if newest.start == newest.end
|
||||
&& !is_multicursor
|
||||
&& [Mode::Visual, Mode::VisualLine, Mode::VisualBlock].contains(&self.mode)
|
||||
&& [
|
||||
ModalMode::Visual,
|
||||
ModalMode::VisualLine,
|
||||
ModalMode::VisualBlock,
|
||||
]
|
||||
.contains(&self.mode)
|
||||
{
|
||||
self.switch_mode(Mode::Normal, true, window, cx);
|
||||
self.switch_mode(ModalMode::Normal, true, window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1649,11 +1659,11 @@ impl Vim {
|
|||
}
|
||||
}
|
||||
Some(Operator::Replace) => match self.mode {
|
||||
Mode::Normal => self.normal_replace(text, window, cx),
|
||||
Mode::Visual | Mode::VisualLine | Mode::VisualBlock => {
|
||||
ModalMode::Normal => self.normal_replace(text, window, cx),
|
||||
ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => {
|
||||
self.visual_replace(text, window, cx)
|
||||
}
|
||||
Mode::HelixNormal => self.helix_replace(&text, window, cx),
|
||||
ModalMode::HelixNormal => self.helix_replace(&text, window, cx),
|
||||
_ => self.clear_operator(window, cx),
|
||||
},
|
||||
Some(Operator::Digraph { first_char }) => {
|
||||
|
@ -1671,20 +1681,20 @@ impl Vim {
|
|||
self.handle_literal_input(prefix.unwrap_or_default(), &text, window, cx)
|
||||
}
|
||||
Some(Operator::AddSurrounds { target }) => match self.mode {
|
||||
Mode::Normal => {
|
||||
ModalMode::Normal => {
|
||||
if let Some(target) = target {
|
||||
self.add_surrounds(text, target, window, cx);
|
||||
self.clear_operator(window, cx);
|
||||
}
|
||||
}
|
||||
Mode::Visual | Mode::VisualLine | Mode::VisualBlock => {
|
||||
ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => {
|
||||
self.add_surrounds(text, SurroundsType::Selection, window, cx);
|
||||
self.clear_operator(window, cx);
|
||||
}
|
||||
_ => self.clear_operator(window, cx),
|
||||
},
|
||||
Some(Operator::ChangeSurrounds { target }) => match self.mode {
|
||||
Mode::Normal => {
|
||||
ModalMode::Normal => {
|
||||
if let Some(target) = target {
|
||||
self.change_surrounds(text, target, window, cx);
|
||||
self.clear_operator(window, cx);
|
||||
|
@ -1693,7 +1703,7 @@ impl Vim {
|
|||
_ => self.clear_operator(window, cx),
|
||||
},
|
||||
Some(Operator::DeleteSurrounds) => match self.mode {
|
||||
Mode::Normal => {
|
||||
ModalMode::Normal => {
|
||||
self.delete_surrounds(text, window, cx);
|
||||
self.clear_operator(window, cx);
|
||||
}
|
||||
|
@ -1707,7 +1717,7 @@ impl Vim {
|
|||
self.replay_register(text.chars().next().unwrap(), window, cx)
|
||||
}
|
||||
Some(Operator::Register) => match self.mode {
|
||||
Mode::Insert => {
|
||||
ModalMode::Insert => {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
if let Some(register) = Vim::update_globals(cx, |globals, cx| {
|
||||
globals.read_register(text.chars().next(), Some(editor), cx)
|
||||
|
@ -1729,11 +1739,11 @@ impl Vim {
|
|||
},
|
||||
Some(Operator::Jump { line }) => self.jump(text, line, true, window, cx),
|
||||
_ => {
|
||||
if self.mode == Mode::Replace {
|
||||
if self.mode == ModalMode::Replace {
|
||||
self.multi_replace(text, window, cx)
|
||||
}
|
||||
|
||||
if self.mode == Mode::Normal {
|
||||
if self.mode == ModalMode::Normal {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.accept_edit_prediction(
|
||||
&editor::actions::AcceptEditPrediction {},
|
||||
|
@ -1753,9 +1763,9 @@ impl Vim {
|
|||
editor.set_collapse_matches(true);
|
||||
editor.set_input_enabled(vim.editor_input_enabled());
|
||||
editor.set_autoindent(vim.should_autoindent());
|
||||
editor.selections.line_mode = matches!(vim.mode, Mode::VisualLine);
|
||||
editor.selections.line_mode = matches!(vim.mode, ModalMode::VisualLine);
|
||||
|
||||
let hide_edit_predictions = !matches!(vim.mode, Mode::Insert | Mode::Replace);
|
||||
let hide_edit_predictions = !matches!(vim.mode, ModalMode::Insert | ModalMode::Replace);
|
||||
editor.set_edit_predictions_hidden_for_vim_mode(hide_edit_predictions, window, cx);
|
||||
});
|
||||
cx.notify()
|
||||
|
@ -1797,7 +1807,6 @@ struct CursorShapeSettings {
|
|||
|
||||
#[derive(Deserialize)]
|
||||
struct VimSettings {
|
||||
pub default_mode: Mode,
|
||||
pub toggle_relative_line_numbers: bool,
|
||||
pub use_system_clipboard: UseSystemClipboard,
|
||||
pub use_smartcase_find: bool,
|
||||
|
@ -1808,7 +1817,6 @@ struct VimSettings {
|
|||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||
struct VimSettingsContent {
|
||||
pub default_mode: Option<ModeContent>,
|
||||
pub toggle_relative_line_numbers: Option<bool>,
|
||||
pub use_system_clipboard: Option<UseSystemClipboard>,
|
||||
pub use_smartcase_find: Option<bool>,
|
||||
|
@ -1817,33 +1825,6 @@ struct VimSettingsContent {
|
|||
pub cursor_shape: Option<CursorShapeSettings>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ModeContent {
|
||||
#[default]
|
||||
Normal,
|
||||
Insert,
|
||||
Replace,
|
||||
Visual,
|
||||
VisualLine,
|
||||
VisualBlock,
|
||||
HelixNormal,
|
||||
}
|
||||
|
||||
impl From<ModeContent> for Mode {
|
||||
fn from(mode: ModeContent) -> Self {
|
||||
match mode {
|
||||
ModeContent::Normal => Self::Normal,
|
||||
ModeContent::Insert => Self::Insert,
|
||||
ModeContent::Replace => Self::Replace,
|
||||
ModeContent::Visual => Self::Visual,
|
||||
ModeContent::VisualLine => Self::VisualLine,
|
||||
ModeContent::VisualBlock => Self::VisualBlock,
|
||||
ModeContent::HelixNormal => Self::HelixNormal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Settings for VimSettings {
|
||||
const KEY: Option<&'static str> = Some("vim");
|
||||
|
||||
|
@ -1853,10 +1834,6 @@ impl Settings for VimSettings {
|
|||
let settings: VimSettingsContent = sources.json_merge()?;
|
||||
|
||||
Ok(Self {
|
||||
default_mode: settings
|
||||
.default_mode
|
||||
.ok_or_else(Self::missing_default)?
|
||||
.into(),
|
||||
toggle_relative_line_numbers: settings
|
||||
.toggle_relative_line_numbers
|
||||
.ok_or_else(Self::missing_default)?,
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
use anyhow::Result;
|
||||
use gpui::App;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use settings::{Settings, SettingsSources};
|
||||
use std::fmt::Display;
|
||||
|
||||
/// Initializes the `vim_mode_setting` crate.
|
||||
pub fn init(cx: &mut App) {
|
||||
|
@ -20,13 +22,93 @@ pub fn init(cx: &mut App) {
|
|||
/// Default: `EditMode::Default`
|
||||
pub struct EditorModeSetting(pub EditorMode);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, JsonSchema, Default)]
|
||||
pub enum EditorMode {
|
||||
Vim,
|
||||
VimInsert,
|
||||
Helix,
|
||||
#[default]
|
||||
Default,
|
||||
Vim(ModalMode),
|
||||
Helix(ModalMode),
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for EditorMode {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
match s.as_str() {
|
||||
"default" => Ok(EditorMode::Default),
|
||||
"vim" => Ok(EditorMode::Vim(ModalMode::Normal)),
|
||||
"vim_normal" => Ok(EditorMode::Vim(ModalMode::Normal)),
|
||||
"vim_insert" => Ok(EditorMode::Vim(ModalMode::Insert)),
|
||||
"vim_replace" => Ok(EditorMode::Vim(ModalMode::Replace)),
|
||||
"vim_visual" => Ok(EditorMode::Vim(ModalMode::Visual)),
|
||||
"vim_visual_line" => Ok(EditorMode::Vim(ModalMode::VisualLine)),
|
||||
"vim_visual_block" => Ok(EditorMode::Vim(ModalMode::VisualBlock)),
|
||||
"helix_experimental" => Ok(EditorMode::Helix(ModalMode::HelixNormal)),
|
||||
_ => Err(D::Error::custom(format!("Unknown editor mode: {}", s))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for EditorMode {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let s = match self {
|
||||
EditorMode::Default => "default",
|
||||
EditorMode::Vim(ModalMode::Normal) => "vim",
|
||||
EditorMode::Vim(ModalMode::Insert) => "vim_insert",
|
||||
EditorMode::Vim(ModalMode::Replace) => "vim_replace",
|
||||
EditorMode::Vim(ModalMode::Visual) => "vim_visual",
|
||||
EditorMode::Vim(ModalMode::VisualLine) => "vim_visual_line",
|
||||
EditorMode::Vim(ModalMode::VisualBlock) => "vim_visual_block",
|
||||
EditorMode::Helix(ModalMode::Normal) => "helix_experimental",
|
||||
_ => return Err(serde::ser::Error::custom("unsupported editor mode variant")),
|
||||
};
|
||||
serializer.serialize_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||
pub enum ModalMode {
|
||||
Normal,
|
||||
Insert,
|
||||
Replace,
|
||||
Visual,
|
||||
VisualLine,
|
||||
VisualBlock,
|
||||
HelixNormal,
|
||||
}
|
||||
|
||||
impl Display for ModalMode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ModalMode::Normal => write!(f, "NORMAL"),
|
||||
ModalMode::Insert => write!(f, "INSERT"),
|
||||
ModalMode::Replace => write!(f, "REPLACE"),
|
||||
ModalMode::Visual => write!(f, "VISUAL"),
|
||||
ModalMode::VisualLine => write!(f, "VISUAL LINE"),
|
||||
ModalMode::VisualBlock => write!(f, "VISUAL BLOCK"),
|
||||
ModalMode::HelixNormal => write!(f, "HELIX NORMAL"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalMode {
|
||||
pub fn is_visual(&self) -> bool {
|
||||
match self {
|
||||
Self::Visual | Self::VisualLine | Self::VisualBlock => true,
|
||||
Self::Normal | Self::Insert | Self::Replace | Self::HelixNormal => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ModalMode {
|
||||
fn default() -> Self {
|
||||
Self::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl Settings for EditorModeSetting {
|
||||
|
@ -49,3 +131,9 @@ impl Settings for EditorModeSetting {
|
|||
// TODO: could possibly check if any of the `vim.<foo>` keys are set?
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorMode {
|
||||
pub fn is_modal(&self) -> bool {
|
||||
matches!(self, EditorMode::Vim(_) | EditorMode::Helix(_))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue