use crossterm::event::{KeyCode, KeyEvent};
use super::{
EditMode, TextCursor, edit::apply_edit_key, keys::is_command,
mutate::delete_selection,
};
use crate::clipboard;
pub fn handle_clipboard(
text: &mut String,
cursor: &mut TextCursor,
key: KeyEvent,
mode: EditMode,
) -> bool {
if !is_command(key) {
return false;
}
if !matches!(key.code, KeyCode::Char('c' | 'x' | 'v')) {
return false;
}
apply_edit_key(text, cursor, key, mode, None)
}
pub fn paste_text(
text: &mut String,
cursor: &mut TextCursor,
mode: EditMode,
max_len: Option<usize>,
payload: &str,
) {
let mut chars: Vec<char> = text.chars().collect();
cursor.pos = cursor.pos.min(chars.len());
insert_pasted(&mut chars, cursor, max_len, payload, paste_keep(mode));
*text = chars.into_iter().collect();
}
pub(super) fn paste_keep(mode: EditMode) -> fn(char) -> bool {
if mode.keeps_newlines() {
|ch| ch == '\n' || !ch.is_control()
} else {
|ch| !ch.is_control()
}
}
pub(super) fn insert_pasted(
chars: &mut Vec<char>,
cursor: &mut TextCursor,
max_len: Option<usize>,
payload: &str,
keep: impl Fn(char) -> bool,
) {
delete_selection(chars, cursor);
for ch in payload.chars().filter(|&ch| keep(ch)) {
if max_len.is_some_and(|max| chars.len() >= max) {
break;
}
chars.insert(cursor.pos, ch);
cursor.pos += 1;
}
cursor.anchor = None;
}
pub(super) fn paste_clipboard(
chars: &mut Vec<char>,
cursor: &mut TextCursor,
max_len: Option<usize>,
mode: EditMode,
) {
let Some(text) = clipboard::paste() else {
return;
};
insert_pasted(chars, cursor, max_len, &text, paste_keep(mode));
}
pub(crate) fn copy_selection(chars: &[char], cursor: &TextCursor) {
if let Some((start, end)) = cursor.selection() {
let text: String = chars[start..end].iter().collect();
clipboard::copy(&text);
}
}