зеркало из
https://github.com/glebtv/tui-textarea.git
synced 2026-09-07 16:05:50 +03:00
yank removed strings
Этот коммит содержится в:
@@ -17,6 +17,7 @@ pub struct TextArea<'a> {
|
|||||||
history: History,
|
history: History,
|
||||||
cursor_line_style: Style,
|
cursor_line_style: Style,
|
||||||
scroll_top: (AtomicU16, AtomicU16),
|
scroll_top: (AtomicU16, AtomicU16),
|
||||||
|
yank: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> From<I> for TextArea<'a>
|
impl<'a, I> From<I> for TextArea<'a>
|
||||||
@@ -49,6 +50,7 @@ impl<'a> TextArea<'a> {
|
|||||||
history: History::new(50),
|
history: History::new(50),
|
||||||
cursor_line_style: Style::default().add_modifier(Modifier::UNDERLINED),
|
cursor_line_style: Style::default().add_modifier(Modifier::UNDERLINED),
|
||||||
scroll_top: (AtomicU16::new(0), AtomicU16::new(0)),
|
scroll_top: (AtomicU16::new(0), AtomicU16::new(0)),
|
||||||
|
yank: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +214,11 @@ impl<'a> TextArea<'a> {
|
|||||||
ctrl: true,
|
ctrl: true,
|
||||||
alt: false,
|
alt: false,
|
||||||
} => self.redo(),
|
} => self.redo(),
|
||||||
|
Input {
|
||||||
|
key: Key::Char('y' | 'v'),
|
||||||
|
ctrl: true,
|
||||||
|
alt: false,
|
||||||
|
} => self.paste(),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +287,12 @@ impl<'a> TextArea<'a> {
|
|||||||
self.push_history(EditKind::InsertChar(c, i), (row, col));
|
self.push_history(EditKind::InsertChar(c, i), (row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_str(&mut self, s: &str) {
|
pub fn insert_str<S: Into<String>>(&mut self, s: S) {
|
||||||
|
let s = s.into();
|
||||||
|
if s.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let (row, col) = self.cursor;
|
let (row, col) = self.cursor;
|
||||||
let line = &mut self.lines[row];
|
let line = &mut self.lines[row];
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
@@ -288,20 +300,23 @@ impl<'a> TextArea<'a> {
|
|||||||
None,
|
None,
|
||||||
"string given to insert_str must not contain newline",
|
"string given to insert_str must not contain newline",
|
||||||
);
|
);
|
||||||
|
|
||||||
let i = line
|
let i = line
|
||||||
.char_indices()
|
.char_indices()
|
||||||
.nth(col)
|
.nth(col)
|
||||||
.map(|(i, _)| i)
|
.map(|(i, _)| i)
|
||||||
.unwrap_or(line.len());
|
.unwrap_or(line.len());
|
||||||
line.insert_str(i, s);
|
line.insert_str(i, &s);
|
||||||
|
|
||||||
self.cursor.1 += s.chars().count();
|
self.cursor.1 += s.chars().count();
|
||||||
self.push_history(EditKind::Insert(s.to_string(), i), (row, col));
|
self.push_history(EditKind::Insert(s, i), (row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_str(&mut self, col: usize, chars: usize) {
|
pub fn delete_str(&mut self, col: usize, chars: usize) {
|
||||||
if chars == 0 {
|
if chars == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let row = self.cursor.0;
|
let row = self.cursor.0;
|
||||||
let line = &mut self.lines[row];
|
let line = &mut self.lines[row];
|
||||||
if let Some((i, _)) = line.char_indices().nth(col) {
|
if let Some((i, _)) = line.char_indices().nth(col) {
|
||||||
@@ -315,8 +330,10 @@ impl<'a> TextArea<'a> {
|
|||||||
let removed = line[i..i + bytes].to_string();
|
let removed = line[i..i + bytes].to_string();
|
||||||
line.replace_range(i..i + bytes, "");
|
line.replace_range(i..i + bytes, "");
|
||||||
line.push(' ');
|
line.push(' ');
|
||||||
|
|
||||||
self.cursor = (row, col);
|
self.cursor = (row, col);
|
||||||
self.push_history(EditKind::Remove(removed, i), (row, col));
|
self.push_history(EditKind::Remove(removed.clone(), i), (row, col));
|
||||||
|
self.yank = removed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +354,7 @@ impl<'a> TextArea<'a> {
|
|||||||
.unwrap_or(line.len());
|
.unwrap_or(line.len());
|
||||||
let next_line = line[idx..].to_string();
|
let next_line = line[idx..].to_string();
|
||||||
line.truncate(idx);
|
line.truncate(idx);
|
||||||
|
|
||||||
self.lines.insert(row + 1, next_line);
|
self.lines.insert(row + 1, next_line);
|
||||||
self.cursor = (row + 1, 0);
|
self.cursor = (row + 1, 0);
|
||||||
self.push_history(EditKind::InsertNewline(idx), (row, col));
|
self.push_history(EditKind::InsertNewline(idx), (row, col));
|
||||||
@@ -349,6 +367,7 @@ impl<'a> TextArea<'a> {
|
|||||||
let line = self.lines.remove(row);
|
let line = self.lines.remove(row);
|
||||||
let prev_line = &mut self.lines[row - 1];
|
let prev_line = &mut self.lines[row - 1];
|
||||||
let prev_line_end = prev_line.len();
|
let prev_line_end = prev_line.len();
|
||||||
|
|
||||||
self.cursor = (row - 1, prev_line.chars().count());
|
self.cursor = (row - 1, prev_line.chars().count());
|
||||||
prev_line.push_str(&line);
|
prev_line.push_str(&line);
|
||||||
self.push_history(EditKind::DeleteNewline(prev_line_end), (row, col));
|
self.push_history(EditKind::DeleteNewline(prev_line_end), (row, col));
|
||||||
@@ -381,6 +400,11 @@ impl<'a> TextArea<'a> {
|
|||||||
self.delete_str(0, self.cursor.1);
|
self.delete_str(0, self.cursor.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn paste(&mut self) {
|
||||||
|
let yank = std::mem::take(&mut self.yank);
|
||||||
|
self.insert_str(yank);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_cursor(&mut self, m: CursorMove) {
|
pub fn move_cursor(&mut self, m: CursorMove) {
|
||||||
if let Some(cursor) = m.next_cursor(self.cursor, &self.lines) {
|
if let Some(cursor) = m.next_cursor(self.cursor, &self.lines) {
|
||||||
self.cursor = cursor;
|
self.cursor = cursor;
|
||||||
@@ -421,6 +445,7 @@ impl<'a> TextArea<'a> {
|
|||||||
lines.push(Spans::from(l.as_str()));
|
lines.push(Spans::from(l.as_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner = Paragraph::new(Text::from(lines)).style(self.style);
|
let inner = Paragraph::new(Text::from(lines)).style(self.style);
|
||||||
TextAreaWidget {
|
TextAreaWidget {
|
||||||
scroll_top: &self.scroll_top,
|
scroll_top: &self.scroll_top,
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user