diff --git a/src/ui.rs b/src/ui.rs index 4cadee1..4b19766 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -84,32 +84,6 @@ impl UI { .map_err(|e| self.error(&e.to_string())); } - // Display a status message to the user. - fn status(&self, s: &str) { - print!( - "{}{}{}{}{}", - "\x1b[93m", - termion::cursor::Goto(1, self.size.1 as u16), - termion::clear::CurrentLine, - s, - color::Fg(color::Reset) - ); - stdout().flush(); - } - - // Display an error message to the user. - fn error(&self, e: &str) { - print!( - "{}{}{}{}{}", - "\x1b[91m", - termion::cursor::Goto(1, self.size.1 as u16), - termion::clear::CurrentLine, - e, - color::Fg(color::Reset) - ); - stdout().flush(); - } - pub fn open(&mut self, url: &str) -> io::Result<()> { // non-gopher URL if !url.starts_with("gopher://") { @@ -154,6 +128,89 @@ impl UI { self.size = (cols, rows); } + // Display a status message to the user. + fn status(&self, s: &str) { + print!( + "{}{}{}{}{}", + "\x1b[93m", + termion::cursor::Goto(1, self.size.1 as u16), + termion::clear::CurrentLine, + s, + color::Fg(color::Reset) + ); + stdout().flush(); + } + + // Display an error message to the user. + fn error(&self, e: &str) { + print!( + "{}{}{}{}{}", + "\x1b[91m", + termion::cursor::Goto(1, self.size.1 as u16), + termion::clear::CurrentLine, + e, + color::Fg(color::Reset) + ); + stdout().flush(); + } + + // Prompt user for input. + fn prompt(&self, prompt: &str) -> Option { + print!( + "{}{}{}{}{}", + color::Fg(color::Reset), + termion::cursor::Goto(1, self.size.1 as u16), + termion::clear::CurrentLine, + prompt, + termion::cursor::Show, + ); + stdout().flush(); + + let mut input = String::new(); + for k in stdin().keys() { + if let Ok(key) = k { + match key { + Key::Char('\n') => { + print!("{}{}", termion::clear::CurrentLine, termion::cursor::Hide); + stdout().flush(); + return Some(input); + } + Key::Char(c) => input.push(c), + Key::Esc | Key::Ctrl('c') => { + if input.is_empty() { + print!("{}{}", termion::clear::CurrentLine, termion::cursor::Hide); + stdout().flush(); + return None; + } else { + input.clear(); + } + } + Key::Backspace | Key::Delete => { + input.pop(); + } + _ => {} + } + } else { + break; + } + + print!( + "{}{}{}{}", + termion::cursor::Goto(1, self.size.1 as u16), + termion::clear::CurrentLine, + prompt, + input, + ); + stdout().flush(); + } + + if !input.is_empty() { + Some(input) + } else { + None + } + } + fn add_page(&mut self, view: T) { self.dirty = true; if !self.pages.is_empty() && self.page < self.pages.len() - 1 { @@ -201,6 +258,15 @@ impl UI { self.page += 1; } } + Action::Keypress(Key::Ctrl('g')) => { + if let Some(url) = self.prompt("Go to URL: ") { + if !url.contains("://") && !url.starts_with("gopher://") { + self.open(&format!("gopher://{}", url))?; + } else { + self.open(&url)?; + } + } + } Action::Keypress(Key::Ctrl('u')) => { if let Some(page) = self.pages.get(self.page) { self.status(&format!("Current URL: {}", page.url()));