summaryrefslogtreecommitdiffstats
path: root/src/textfield.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/textfield.rs')
-rw-r--r--src/textfield.rs231
1 files changed, 82 insertions, 149 deletions
diff --git a/src/textfield.rs b/src/textfield.rs
index 3b4ef1c..e5f799c 100644
--- a/src/textfield.rs
+++ b/src/textfield.rs
@@ -1,9 +1,25 @@
-use crate::window;
-use crate::KEYMAP_T;
+use std::io::{self, Write};
use rustyline::completion::{Candidate, Completer, FilenameCompleter, Pair};
use rustyline::line_buffer;
+use termion::cursor::Goto;
+use termion::event::Key;
+use termion::input::TermRead;
+use termion::raw::IntoRawMode;
+use termion::screen::AlternateScreen;
+use tui::backend::{Backend, TermionBackend};
+use tui::layout::{Constraint, Direction, Layout, Rect};
+use tui::style::{Color, Style};
+use tui::widgets::{Block, Borders, List, Paragraph, Text, Widget};
+use tui::Terminal;
+use unicode_width::UnicodeWidthStr;
+
+use crate::util::event::{Event, Events};
+use crate::window;
+
+use crate::KEYMAP_T;
+
struct CompletionTracker {
pub index: usize,
pub pos: usize,
@@ -22,160 +38,77 @@ impl CompletionTracker {
}
}
-pub struct JoshutoTextField<'a> {
- pub win: window::JoshutoPanel,
- pub prompt: &'a str,
- pub prefix: &'a str,
- pub suffix: &'a str,
-}
-
-impl<'a> std::fmt::Debug for JoshutoTextField<'a> {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- f.debug_struct("JoshutoTextField")
- .field("prompt", &self.prompt)
- .field("prefix", &self.prefix)
- .field("suffix", &self.suffix)
- .finish()
- }
+pub struct TextField<'a, W>
+where
+ W: std::io::Write,
+{
+ terminal: &'a mut Terminal<TermionBackend<W>>,
+ events: &'a Events,
}
-impl<'a> JoshutoTextField<'a> {
- pub fn new(
- rows: i32,
- cols: i32,
- coord: (usize, usize),
- prompt: &'a str,
- prefix: &'a str,
- suffix: &'a str,
- ) -> Self {
- let win = window::JoshutoPanel::new(rows, cols, coord);
- JoshutoTextField {
- win,
- prompt,
- prefix,
- suffix,
- }
+impl<'a, W> TextField<'a, W>
+where
+ W: std::io::Write,
+{
+ pub fn new(terminal: &'a mut Terminal<TermionBackend<W>>, events: &'a Events) -> Self {
+ Self { terminal, events }
}
-
- pub fn readline(&self) -> Option<String> {
- self.win.move_to_top();
- let win = self.win.win;
-
- let prompt_len = self.prompt.len();
- let coord = (0, self.win.coords.1 + prompt_len);
-
- ncurses::mvwaddstr(win, 0, 0, &self.prompt);
-
- let mut line_buffer = line_buffer::LineBuffer::with_capacity(255);
- let completer = FilenameCompleter::new();
-
- line_buffer.insert_str(0, self.prefix);
- line_buffer.insert_str(line_buffer.len(), self.suffix);
- line_buffer.set_pos(self.prefix.as_bytes().len());
-
- let mut completion_tracker: Option<CompletionTracker> = None;
-
- let mut curr_pos = unicode_width::UnicodeWidthStr::width(self.prefix);
+ /*
+ Paragraph::new(paragraph_contents.iter())
+ .wrap(true)
+ .render(&mut f, Rect { x: 0, y: 0, height: 2, width: f_size.width});
+ */
+
+ pub fn readline(&mut self) -> Option<String> {
+ let mut input_string = String::with_capacity(64);
+ let events = self.events;
loop {
- ncurses::mvwaddstr(win, coord.0, coord.1 as i32, line_buffer.as_str());
- ncurses::wclrtoeol(win);
-
- /* draws cursor */
- ncurses::mvwchgat(
- win,
- coord.0,
- (coord.1 + curr_pos) as i32,
- 1,
- ncurses::A_STANDOUT(),
- 0,
+ // Draw UI
+ self.terminal.draw(|mut f| {
+ let f_size = f.size();
+ Paragraph::new([Text::raw(&input_string)].iter())
+ .style(Style::default().fg(Color::Yellow))
+ .render(
+ &mut f,
+ Rect {
+ x: 0,
+ y: 0,
+ height: 2,
+ width: f_size.width,
+ },
+ );
+ });
+
+ write!(
+ self.terminal.backend_mut(),
+ "{}",
+ Goto(4 + input_string.width() as u16, 5)
);
- ncurses::wrefresh(win);
-
- let ch = ncurses::wget_wch(win).unwrap();
- let ch = match ch {
- ncurses::WchResult::Char(s) => s as i32,
- ncurses::WchResult::KeyCode(s) => s,
- };
-
- if ch == KEYMAP_T.escape {
- return None;
- } else if ch == KEYMAP_T.enter {
- break;
- } else if ch == KEYMAP_T.home {
- line_buffer.move_home();
- curr_pos = 0;
- completion_tracker.take();
- } else if ch == KEYMAP_T.end {
- line_buffer.move_end();
- curr_pos = unicode_width::UnicodeWidthStr::width(line_buffer.as_str());
- completion_tracker.take();
- } else if ch == KEYMAP_T.left {
- if line_buffer.move_backward(1) {
- let pos = line_buffer.pos();
- curr_pos = unicode_width::UnicodeWidthStr::width(&line_buffer.as_str()[..pos]);
- completion_tracker.take();
- }
- } else if ch == KEYMAP_T.right {
- if line_buffer.move_forward(1) {
- let pos = line_buffer.pos();
- curr_pos = unicode_width::UnicodeWidthStr::width(&line_buffer.as_str()[..pos]);
- completion_tracker.take();
- }
- } else if ch == KEYMAP_T.backspace {
- if line_buffer.backspace(1) {
- let pos = line_buffer.pos();
- curr_pos = unicode_width::UnicodeWidthStr::width(&line_buffer.as_str()[..pos]);
- completion_tracker.take();
- }
- } else if ch == KEYMAP_T.delete {
- if line_buffer.delete(1).is_some() {
- completion_tracker.take();
- }
- } else if ch == KEYMAP_T.tab {
- if completion_tracker.is_none() {
- let res = completer.complete_path(line_buffer.as_str(), line_buffer.pos());
- if let Ok((pos, mut candidates)) = res {
- candidates.sort_by(|x, y| {
- x.display()
- .partial_cmp(y.display())
- .unwrap_or(std::cmp::Ordering::Less)
- });
- let ct = CompletionTracker::new(
- pos,
- candidates,
- String::from(line_buffer.as_str()),
- );
- completion_tracker = Some(ct);
- }
- }
-
- if let Some(ref mut s) = completion_tracker {
- if s.index < s.candidates.len() {
- let candidate = &s.candidates[s.index];
- completer.update(&mut line_buffer, s.pos, candidate.display());
- s.index += 1;
- }
- }
- curr_pos = unicode_width::UnicodeWidthStr::width(
- &line_buffer.as_str()[..line_buffer.pos()],
- );
- } else if ch == KEYMAP_T.up {
- // TODO
- } else if ch == KEYMAP_T.down {
- // TODO
- } else if let Some(ch) = std::char::from_u32(ch as u32) {
- if line_buffer.insert(ch, 1).is_some() {
- curr_pos += unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1);
- completion_tracker.take();
+ io::stdout().flush().ok();
+
+ // Handle input
+ if let Ok(event) = events.next() {
+ match event {
+ Event::Input(input) => match input {
+ Key::Char('\n') => {
+ break;
+ }
+ Key::Esc => {
+ return None;
+ }
+ Key::Backspace => {
+ input_string.pop();
+ }
+ Key::Char(c) => {
+ input_string.push(c);
+ }
+ _ => {}
+ },
+ _ => {}
}
}
}
- if line_buffer.as_str().is_empty() {
- None
- } else {
- // let strin = rustyline::completion::unescape(line_buffer.as_str(), ESCAPE_CHAR).into_owned();
- let strin = line_buffer.to_string();
- Some(strin)
- }
+ eprintln!("You typed: {}", input_string);
+ Some(input_string)
}
}