mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
cut text with Ctrl+X
This commit is contained in:
parent
cc81c6e5ba
commit
ae57b87b1e
4 changed files with 89 additions and 19 deletions
|
@ -1,6 +1,6 @@
|
|||
use crate::error::EdResult;
|
||||
use crate::mvc::app_model::AppModel;
|
||||
use crate::mvc::app_update::{handle_copy, handle_paste, pass_keydown_to_focused};
|
||||
use crate::mvc::app_update::{handle_copy, handle_cut, handle_paste, pass_keydown_to_focused};
|
||||
use winit::event::VirtualKeyCode::*;
|
||||
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
||||
|
||||
|
@ -22,11 +22,7 @@ pub fn handle_keydown(
|
|||
|
||||
Copy => handle_copy(app_model)?,
|
||||
Paste => handle_paste(app_model)?,
|
||||
Cut => {
|
||||
//handle_cut(app_model)?
|
||||
todo!("cut");
|
||||
}
|
||||
|
||||
Cut => handle_cut(app_model)?,
|
||||
C => {
|
||||
if modifiers.ctrl() {
|
||||
handle_copy(app_model)?
|
||||
|
@ -39,8 +35,7 @@ pub fn handle_keydown(
|
|||
}
|
||||
X => {
|
||||
if modifiers.ctrl() {
|
||||
//handle_cut(app_model)?
|
||||
todo!("cut");
|
||||
handle_cut(app_model)?
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
@ -8,7 +8,7 @@ use winit::event::{ModifiersState, VirtualKeyCode};
|
|||
pub fn handle_copy(app_model: &mut AppModel) -> EdResult<()> {
|
||||
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
||||
if ed_model.has_focus {
|
||||
let selected_str_opt = super::ed_model::get_selected_str(ed_model)?;
|
||||
let selected_str_opt = ed_model.get_selected_str()?;
|
||||
|
||||
if let Some(selected_str) = selected_str_opt {
|
||||
app_model::set_clipboard_txt(&mut app_model.clipboard_opt, selected_str)?;
|
||||
|
@ -76,6 +76,22 @@ pub fn handle_paste(app_model: &mut AppModel) -> EdResult<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_cut(app_model: &mut AppModel) -> EdResult<()> {
|
||||
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
||||
if ed_model.has_focus {
|
||||
let selected_str_opt = ed_model.get_selected_str()?;
|
||||
|
||||
if let Some(selected_str) = selected_str_opt {
|
||||
app_model::set_clipboard_txt(&mut app_model.clipboard_opt, selected_str)?;
|
||||
|
||||
ed_model.del_selection()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pass_keydown_to_focused(
|
||||
modifiers: &ModifiersState,
|
||||
virtual_keycode: VirtualKeyCode,
|
||||
|
@ -102,7 +118,7 @@ pub fn handle_new_char(received_char: &char, app_model: &mut AppModel) -> EdResu
|
|||
pub mod test_app_update {
|
||||
use crate::mvc::app_model;
|
||||
use crate::mvc::app_model::{AppModel, Clipboard};
|
||||
use crate::mvc::app_update::{handle_copy, handle_paste};
|
||||
use crate::mvc::app_update::{handle_copy, handle_cut, handle_paste};
|
||||
use crate::mvc::ed_model::{EdModel, Position, RawSelection};
|
||||
use crate::mvc::ed_update::test_ed_update::gen_caret_text_buf;
|
||||
use crate::selection::test_selection::{all_lines_vec, convert_selection_to_dsl};
|
||||
|
@ -171,12 +187,42 @@ pub mod test_app_update {
|
|||
Ok(app_model.clipboard_opt)
|
||||
}
|
||||
|
||||
fn assert_cut(
|
||||
pre_lines_str: &[&str],
|
||||
expected_clipboard_content: &str,
|
||||
expected_post_lines_str: &[&str],
|
||||
clipboard_opt: Option<Clipboard>,
|
||||
) -> Result<Option<Clipboard>, String> {
|
||||
let (caret_pos, selection_opt, pre_text_buf) = gen_caret_text_buf(pre_lines_str)?;
|
||||
|
||||
let mut app_model = mock_app_model(pre_text_buf, caret_pos, selection_opt, clipboard_opt);
|
||||
|
||||
handle_cut(&mut app_model)?;
|
||||
|
||||
let clipboard_content = app_model::get_clipboard_txt(&mut app_model.clipboard_opt)?;
|
||||
|
||||
assert_eq!(clipboard_content, expected_clipboard_content);
|
||||
|
||||
let ed_model = app_model.ed_model_opt.unwrap();
|
||||
let mut text_buf_lines = all_lines_vec(&ed_model.text_buf);
|
||||
let post_lines_str = convert_selection_to_dsl(
|
||||
ed_model.selection_opt,
|
||||
ed_model.caret_pos,
|
||||
&mut text_buf_lines,
|
||||
)?;
|
||||
|
||||
assert_eq!(post_lines_str, expected_post_lines_str);
|
||||
|
||||
Ok(app_model.clipboard_opt)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // ignored because of clipboard problems on ci
|
||||
fn copy_paste() -> Result<(), String> {
|
||||
fn copy_paste_cut() -> Result<(), String> {
|
||||
// can only init clipboard once
|
||||
let mut clipboard_opt = AppModel::init_clipboard_opt();
|
||||
|
||||
// copy
|
||||
clipboard_opt = assert_copy(&["[a]|"], "a", clipboard_opt)?;
|
||||
clipboard_opt = assert_copy(&["|[b]"], "b", clipboard_opt)?;
|
||||
clipboard_opt = assert_copy(&["a[ ]|"], " ", clipboard_opt)?;
|
||||
|
@ -188,6 +234,8 @@ pub mod test_app_update {
|
|||
"ef\nghi",
|
||||
clipboard_opt,
|
||||
)?;
|
||||
|
||||
// paste
|
||||
clipboard_opt = assert_paste(&["|"], "", &["|"], clipboard_opt)?;
|
||||
clipboard_opt = assert_paste(&["|"], "a", &["a|"], clipboard_opt)?;
|
||||
clipboard_opt = assert_paste(&["a|"], "b", &["ab|"], clipboard_opt)?;
|
||||
|
@ -196,13 +244,27 @@ pub mod test_app_update {
|
|||
clipboard_opt = assert_paste(&["[ab]|"], "d", &["d|"], clipboard_opt)?;
|
||||
clipboard_opt = assert_paste(&["a[b]|c"], "e", &["ae|c"], clipboard_opt)?;
|
||||
clipboard_opt = assert_paste(&["a\n", "[b\n", "]|"], "f", &["a\n", "f|"], clipboard_opt)?;
|
||||
assert_paste(
|
||||
clipboard_opt = assert_paste(
|
||||
&["abc\n", "d[ef\n", "ghi]|\n", "jkl"],
|
||||
"ef\nghi",
|
||||
&["abc\n", "def\n", "ghi|\n", "jkl"],
|
||||
clipboard_opt,
|
||||
)?;
|
||||
|
||||
// cut
|
||||
clipboard_opt = assert_cut(&["[a]|"], "a", &["|"], clipboard_opt)?;
|
||||
clipboard_opt = assert_cut(&["|[b]"], "b", &["|"], clipboard_opt)?;
|
||||
clipboard_opt = assert_cut(&["a[ ]|"], " ", &["a|"], clipboard_opt)?;
|
||||
clipboard_opt = assert_cut(&["[ ]|b"], " ", &["|b"], clipboard_opt)?;
|
||||
clipboard_opt = assert_cut(&["a\n", "[b\n", "]|"], "b\n", &["a\n", "|"], clipboard_opt)?;
|
||||
clipboard_opt = assert_cut(&["[a\n", " b\n", "]|"], "a\n b\n", &["|"], clipboard_opt)?;
|
||||
assert_cut(
|
||||
&["abc\n", "d[ef\n", "ghi]|\n", "jkl"],
|
||||
"ef\nghi",
|
||||
&["abc\n", "d|\n", "jkl"],
|
||||
clipboard_opt,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,27 @@ pub fn init_model(file_path: &Path) -> EdResult<EdModel> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn get_selected_str(ed_model: &EdModel) -> EdResult<Option<&str>> {
|
||||
if let Some(curr_selection) = ed_model.selection_opt {
|
||||
let selected_str = ed_model.text_buf.get_selection(curr_selection)?;
|
||||
impl EdModel {
|
||||
pub fn get_selected_str(&self) -> EdResult<Option<&str>> {
|
||||
if let Some(curr_selection) = self.selection_opt {
|
||||
let selected_str = self.text_buf.get_selection(curr_selection)?;
|
||||
|
||||
Ok(Some(selected_str))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn del_selection(&mut self) -> EdResult<()> {
|
||||
if let Some(selection) = self.selection_opt {
|
||||
self.text_buf.del_selection(selection)?;
|
||||
|
||||
self.caret_pos = selection.start_pos;
|
||||
}
|
||||
self.selection_opt = None;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
|
|
@ -353,7 +353,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
|
|||
}
|
||||
'\u{3}' // Ctrl + C
|
||||
| '\u{16}' // Ctrl + V
|
||||
| '\u{30}' // Ctrl + X
|
||||
| '\u{18}' // Ctrl + X
|
||||
| '\u{e000}'..='\u{f8ff}' // http://www.unicode.org/faq/private_use.html
|
||||
| '\u{f0000}'..='\u{ffffd}' // ^
|
||||
| '\u{100000}'..='\u{10fffd}' // ^
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue