#[cfg(feature = "keybindings")]
use crate::{
canvas::modes::AppMode,
editor::behavior::YankRegister,
editor::rows::repeated_text,
textarea::{TextAreaDataProvider, TextAreaState},
};
#[cfg(feature = "keybindings")]
impl<P: TextAreaDataProvider> TextAreaState<P> {
pub(crate) fn paste_after_vim(&mut self, count: usize) {
self.paste_yank_vim(true, count);
}
pub(crate) fn paste_before_vim(&mut self, count: usize) {
self.paste_yank_vim(false, count);
}
pub(crate) fn paste_after_helix(&mut self, count: usize) {
self.paste_yank_helix(true, count);
}
pub(crate) fn paste_before_helix(&mut self, count: usize) {
self.paste_yank_helix(false, count);
}
pub(crate) fn paste_after_emacs(&mut self, count: usize) {
self.paste_yank_emacs(true, count);
}
pub(crate) fn paste_before_emacs(&mut self, count: usize) {
self.paste_yank_emacs(false, count);
}
fn paste_yank_vim(&mut self, after: bool, count: usize) {
let Some(register) = self.core.behavior_state.yank().register().cloned() else {
return;
};
match register {
YankRegister::Lines(lines) => self.paste_lines_vim(after, count, lines),
YankRegister::Text(lines) => {
let text = repeated_text(&lines, count);
if text.is_empty() {
return;
}
let field = self.current_field();
let line_len = self.current_text().chars().count();
let col = if after {
self.cursor_position().saturating_add(1).min(line_len)
} else {
self.cursor_position()
};
let (target_field, target_col) = self.insert_text_at(field, col, &text);
let _ = self.transition_to_field(target_field);
self.set_cursor_position(target_col);
self.set_mode(AppMode::Nor);
#[cfg(feature = "gui")]
{
self.edited_this_frame = true;
}
}
}
}
fn paste_yank_helix(&mut self, after: bool, count: usize) {
let Some(register) = self.core.behavior_state.yank().register().cloned() else {
return;
};
match register {
YankRegister::Lines(lines) => self.paste_lines_helix(after, count, lines),
YankRegister::Text(lines) => {
let text = repeated_text(&lines, count);
if text.is_empty() {
return;
}
let (start, end) = self.selection_endpoints();
let (field, col) = if after {
(end.0, end.1.saturating_add(1))
} else {
start
};
let (target_field, target_col) = self.insert_text_at(field, col, &text);
let _ = self.transition_to_field(target_field);
self.set_cursor_position(target_col);
self.core.ui_state.current_mode = AppMode::Nor;
self.ensure_helix_primary_selection();
#[cfg(feature = "gui")]
{
self.edited_this_frame = true;
}
}
}
}
fn paste_yank_emacs(&mut self, after: bool, count: usize) {
let Some(register) = self.core.behavior_state.yank().register().cloned() else {
return;
};
match register {
YankRegister::Lines(lines) => self.paste_lines_emacs(after, count, lines),
YankRegister::Text(lines) => {
let text = repeated_text(&lines, count);
if text.is_empty() {
return;
}
if self.mode() == AppMode::Sel {
self.exit_highlight_mode_emacs();
}
let (target_field, target_col) =
self.insert_text_at(self.current_field(), self.cursor_position(), &text);
let _ = self.transition_to_field(target_field);
self.set_cursor_position(target_col);
#[cfg(feature = "gui")]
{
self.edited_this_frame = true;
}
}
}
}
fn paste_lines_vim(&mut self, after: bool, count: usize, lines: Vec<String>) {
if lines.is_empty() {
return;
}
self.core.paste_lines_dynamic(after, count, lines);
self.set_mode(AppMode::Nor);
#[cfg(feature = "gui")]
{
self.edited_this_frame = true;
}
}
fn paste_lines_helix(&mut self, after: bool, count: usize, lines: Vec<String>) {
if lines.is_empty() {
return;
}
self.core.paste_lines_dynamic(after, count, lines);
self.core.ui_state.current_mode = AppMode::Nor;
self.ensure_helix_primary_selection();
#[cfg(feature = "gui")]
{
self.edited_this_frame = true;
}
}
fn paste_lines_emacs(&mut self, after: bool, count: usize, lines: Vec<String>) {
if lines.is_empty() {
return;
}
if self.mode() == AppMode::Sel {
self.exit_highlight_mode_emacs();
}
self.core.paste_lines_dynamic(after, count, lines);
self.set_mode(AppMode::Nor);
#[cfg(feature = "gui")]
{
self.edited_this_frame = true;
}
}
fn insert_text_at(&mut self, field: usize, col: usize, text: &str) -> (usize, usize) {
self.core.insert_text_dynamic(field, col, text)
}
}