use {
reovim_driver_command::{Command, CommandContext, CommandHandler, CommandResult},
reovim_driver_session::{
SessionRuntime, TransitionContext,
api::{ModeApi, SelectionMode},
},
reovim_kernel::api::v1::CommandId,
};
use crate::{ids, modes::VimMode};
#[derive(Debug, Clone, Copy, Default)]
pub struct SwapAnchor;
impl Command for SwapAnchor {
fn id(&self) -> CommandId {
ids::VISUAL_SWAP_ANCHOR
}
fn description(&self) -> &'static str {
"Swap cursor and anchor in visual mode"
}
}
impl CommandHandler for SwapAnchor {
#[cfg_attr(coverage_nightly, coverage(off))]
fn execute(&self, runtime: &mut SessionRuntime<'_>, _args: &CommandContext) -> CommandResult {
let Some(selection) = runtime.windows().active().and_then(|w| w.selection.clone()) else {
return CommandResult::Success; };
let swapped = reovim_driver_session::api::Selection {
start: selection.end,
end: selection.start,
mode: selection.mode,
};
if let Some(window) = runtime.windows_mut().active_mut() {
window.selection = Some(swapped);
}
CommandResult::Success
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct ToggleVisualChar;
impl Command for ToggleVisualChar {
fn id(&self) -> CommandId {
ids::TOGGLE_VISUAL_CHAR
}
fn description(&self) -> &'static str {
"Toggle to character-wise visual mode"
}
}
impl CommandHandler for ToggleVisualChar {
#[cfg_attr(coverage_nightly, coverage(off))]
fn execute(&self, runtime: &mut SessionRuntime<'_>, _args: &CommandContext) -> CommandResult {
let selection = runtime.windows().active().and_then(|w| w.selection.clone());
let target_mode = match selection {
Some(sel) if sel.mode == SelectionMode::Character => {
if let Some(window) = runtime.windows_mut().active_mut() {
window.selection = None;
}
VimMode::NORMAL_ID
}
Some(mut sel) => {
sel.mode = SelectionMode::Character;
if let Some(window) = runtime.windows_mut().active_mut() {
window.selection = Some(sel);
}
VimMode::VISUAL_ID
}
None => {
return CommandResult::Success;
}
};
runtime.set_mode(target_mode, TransitionContext::new());
CommandResult::Success
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct ToggleVisualLine;
impl Command for ToggleVisualLine {
fn id(&self) -> CommandId {
ids::TOGGLE_VISUAL_LINE
}
fn description(&self) -> &'static str {
"Toggle to line-wise visual mode"
}
}
impl CommandHandler for ToggleVisualLine {
#[cfg_attr(coverage_nightly, coverage(off))]
fn execute(&self, runtime: &mut SessionRuntime<'_>, _args: &CommandContext) -> CommandResult {
let selection = runtime.windows().active().and_then(|w| w.selection.clone());
let target_mode = match selection {
Some(sel) if sel.mode == SelectionMode::Line => {
if let Some(window) = runtime.windows_mut().active_mut() {
window.selection = None;
}
VimMode::NORMAL_ID
}
Some(mut sel) => {
sel.mode = SelectionMode::Line;
if let Some(window) = runtime.windows_mut().active_mut() {
window.selection = Some(sel);
}
VimMode::VISUAL_LINE_ID
}
None => {
return CommandResult::Success;
}
};
runtime.set_mode(target_mode, TransitionContext::new());
CommandResult::Success
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct ToggleVisualBlock;
impl Command for ToggleVisualBlock {
fn id(&self) -> CommandId {
ids::TOGGLE_VISUAL_BLOCK
}
fn description(&self) -> &'static str {
"Toggle to block-wise visual mode"
}
}
impl CommandHandler for ToggleVisualBlock {
#[cfg_attr(coverage_nightly, coverage(off))]
fn execute(&self, runtime: &mut SessionRuntime<'_>, _args: &CommandContext) -> CommandResult {
let selection = runtime.windows().active().and_then(|w| w.selection.clone());
let target_mode = match selection {
Some(sel) if sel.mode == SelectionMode::Block => {
if let Some(window) = runtime.windows_mut().active_mut() {
window.selection = None;
}
VimMode::NORMAL_ID
}
Some(mut sel) => {
sel.mode = SelectionMode::Block;
if let Some(window) = runtime.windows_mut().active_mut() {
window.selection = Some(sel);
}
VimMode::VISUAL_BLOCK_ID
}
None => {
return CommandResult::Success;
}
};
runtime.set_mode(target_mode, TransitionContext::new());
CommandResult::Success
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct ReselectLast;
impl Command for ReselectLast {
fn id(&self) -> CommandId {
ids::RESELECT_LAST
}
fn description(&self) -> &'static str {
"Reselect the last visual selection (gv)"
}
}
impl CommandHandler for ReselectLast {
#[cfg_attr(coverage_nightly, coverage(off))]
fn execute(&self, _runtime: &mut SessionRuntime<'_>, _args: &CommandContext) -> CommandResult {
CommandResult::Success
}
}