зеркало из
https://github.com/glebtv/tui-textarea.git
synced 2026-09-08 08:25:51 +03:00
minimal implementation
Этот коммит содержится в:
4
.github/workflows/ci.yml
поставляемый
4
.github/workflows/ci.yml
поставляемый
@@ -15,5 +15,5 @@ jobs:
|
|||||||
- uses: Swatinem/rust-cache@v1
|
- uses: Swatinem/rust-cache@v1
|
||||||
- name: rustfmt
|
- name: rustfmt
|
||||||
run: cargo fmt -- --check --color always
|
run: cargo fmt -- --check --color always
|
||||||
# - name: clippy
|
- name: clippy
|
||||||
# run: cargo clippy --color always -- -D warnings
|
run: cargo clippy --color always -- -D warnings
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
tui = "0.18"
|
||||||
|
|||||||
6
README.md
Обычный файл
6
README.md
Обычный файл
@@ -0,0 +1,6 @@
|
|||||||
|
tui-textarea
|
||||||
|
============
|
||||||
|
|
||||||
|
tui-textarea is a simple text editor like `<textarea>` in HTML for [tui-rs][]. This library is designed as backend-agnostic.
|
||||||
|
|
||||||
|
[tui-rs]: https://github.com/fdehau/tui-rs
|
||||||
104
src/lib.rs
104
src/lib.rs
@@ -1,8 +1,100 @@
|
|||||||
#[cfg(test)]
|
use tui::style::{Modifier, Style};
|
||||||
mod tests {
|
use tui::text::{Span, Spans, Text};
|
||||||
#[test]
|
use tui::widgets::{Block, Paragraph, Widget};
|
||||||
fn it_works() {
|
|
||||||
let result = 2 + 2;
|
pub enum Key {
|
||||||
assert_eq!(result, 4);
|
Char(char),
|
||||||
|
Backspace,
|
||||||
|
Enter,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Tab,
|
||||||
|
Delete,
|
||||||
|
Home,
|
||||||
|
End,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Input {
|
||||||
|
pub key: Key,
|
||||||
|
pub ctrl: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TextArea<'a> {
|
||||||
|
lines: Vec<String>,
|
||||||
|
block: Option<Block<'a>>,
|
||||||
|
style: Style,
|
||||||
|
cursor: (usize, usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Default for TextArea<'a> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
lines: vec![" ".to_string()],
|
||||||
|
block: None,
|
||||||
|
style: Style::default(),
|
||||||
|
cursor: (0, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TextArea<'a> {
|
||||||
|
pub fn input(&mut self, input: Input) {
|
||||||
|
if input.ctrl {
|
||||||
|
// TODO
|
||||||
|
} else {
|
||||||
|
match input.key {
|
||||||
|
Key::Char(c) => self.insert_char(c),
|
||||||
|
Key::Backspace => self.delete_char(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_char(&mut self, c: char) {
|
||||||
|
let (row, col) = self.cursor;
|
||||||
|
let line = &mut self.lines[row];
|
||||||
|
if let Some((i, _)) = line.char_indices().nth(col) {
|
||||||
|
line.insert(i, c);
|
||||||
|
self.cursor.1 += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_char(&mut self) {
|
||||||
|
let (row, col) = self.cursor;
|
||||||
|
let line = &mut self.lines[row];
|
||||||
|
if col == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some((i, _)) = line.char_indices().nth(col - 1) {
|
||||||
|
line.remove(i);
|
||||||
|
self.cursor.1 -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn widget(&'a self) -> impl Widget + 'a {
|
||||||
|
let mut lines = Vec::with_capacity(self.lines.len());
|
||||||
|
for (i, l) in self.lines.iter().enumerate() {
|
||||||
|
if i == self.cursor.0 {
|
||||||
|
let (i, c) = l
|
||||||
|
.char_indices()
|
||||||
|
.nth(self.cursor.1)
|
||||||
|
.unwrap_or((l.len() - 1, ' '));
|
||||||
|
let j = i + c.len_utf8();
|
||||||
|
lines.push(Spans::from(vec![
|
||||||
|
Span::from(&l[..i]),
|
||||||
|
Span::styled(&l[i..j], Style::default().add_modifier(Modifier::REVERSED)),
|
||||||
|
Span::from(&l[j..]),
|
||||||
|
]));
|
||||||
|
} else {
|
||||||
|
lines.push(Spans::from(l.as_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut p = Paragraph::new(Text::from(lines)).style(self.style);
|
||||||
|
if let Some(b) = self.block.clone() {
|
||||||
|
p = p.block(b);
|
||||||
|
}
|
||||||
|
p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user