lil help menu

pull/6/head
dvkt 5 years ago
parent 86eebf04d6
commit fffc48bfc6

@ -51,6 +51,7 @@ Just unzip/untar the `phetch` program into your $PATH and get going!
### basics
- [ ] download to ~/Downloads
gopher://zaibatsu.circumlunar.space/1/~cardboard64/
- [ ] `?` to show all keyboard shortcuts
- [ ] save history to file
- [ ] load history from file

@ -0,0 +1,37 @@
pub const GOPHERMAP: &str = "
i
i
i / / /
i ___ (___ ___ (___ ___ (___
i| )| )|___)| | | )
i|__/ | / |__ |__ |__ | /
i|
i
i ** keyboard shortcuts **
i
ileft back in history
iright forward in history
iup select prev link
idown select next link
ipage up scroll page up
ipage down scroll page down
i
ictrl-g go to gopher url
ictrl-u show current gopher url
ictrl-y copy url to clipboard
ictrl-r view raw version of page
i
i ~ * ~
i
iPress the # of a link to visit
ior select it. Use ENTER to open
ithe selected link.
i
iJust start typing to select links.
i
1text mode shortcuts /text help
1menu mode shortcuts /menu help
i
1....some of my poetry /poetry help
i
";

@ -3,6 +3,7 @@
extern crate termion;
mod gopher;
mod help;
mod menu;
mod text;
mod ui;
@ -53,7 +54,7 @@ fn main() {
let mut ui = UI::new();
if let Err(e) = ui.open(&url) {
ui.error(&e.to_string());
ui::error(&e.to_string());
exit(1);
}
ui.run();

@ -3,7 +3,8 @@ use gopher::Type;
use menu::{Line, Menu};
use std::io::stdout;
use std::io::Write;
use ui::{prompt, Action, Key, View, MAX_COLS, SCROLL_LINES};
use ui;
use ui::{Action, Key, View, MAX_COLS, SCROLL_LINES};
pub struct MenuView {
pub input: String, // user's inputted value
@ -26,6 +27,10 @@ impl View for MenuView {
self.render_lines()
}
fn raw(&self) -> String {
self.menu.raw.to_string()
}
fn process_input(&mut self, key: Key) -> Action {
self.process_key(key)
}
@ -365,7 +370,7 @@ impl MenuView {
let url = line.url.to_string();
let (typ, _, _, _) = gopher::parse_url(&url);
if typ == Type::Search {
if let Some(query) = prompt(&format!("{}> ", line.name)) {
if let Some(query) = ui::prompt(&format!("{}> ", line.name)) {
Action::Open(format!("{}?{}", url, query))
} else {
Action::None

@ -9,6 +9,7 @@ pub struct Menu {
pub lines: Vec<Line>, // lines
pub links: Vec<usize>, // links (index of line in lines vec)
pub longest: usize, // size of the longest line
pub raw: String, // raw response
}
#[derive(Debug)]
@ -85,7 +86,7 @@ impl Menu {
url.push_str("/");
url.push(first_char);
// add trailing / if the selector is blank
if parts.len() == 0 || parts[1].len() == 0 {
if parts.len() == 0 || parts.len() > 1 && parts[1].len() == 0 {
url.push('/');
}
}
@ -106,6 +107,7 @@ impl Menu {
lines,
links,
longest,
raw,
}
}
}

@ -2,7 +2,7 @@ use ui::{Action, Key, View, MAX_COLS, SCROLL_LINES};
pub struct TextView {
url: String,
raw: String,
raw_response: String,
scroll: usize, // offset
lines: usize, // # of lines
longest: usize, // longest line
@ -14,6 +14,10 @@ impl View for TextView {
self.url.to_string()
}
fn raw(&self) -> String {
self.raw_response.to_string()
}
fn set_size(&mut self, cols: usize, rows: usize) {
self.size = (cols, rows);
}
@ -95,7 +99,7 @@ impl View for TextView {
String::from("")
};
let iter = self
.raw
.raw_response
.split_terminator('\n')
.skip(self.scroll)
.take(rows - 1);
@ -125,7 +129,7 @@ impl TextView {
TextView {
url,
raw: response,
raw_response: response,
scroll: 0,
lines,
longest,

@ -9,6 +9,7 @@ use termion::raw::IntoRawMode;
use gopher;
use gopher::io_error;
use gopher::Type;
use help;
use menu::MenuView;
use text::TextView;
@ -41,6 +42,7 @@ pub trait View {
fn process_input(&mut self, c: Key) -> Action;
fn render(&self) -> String;
fn url(&self) -> String;
fn raw(&self) -> String;
fn set_size(&mut self, cols: usize, rows: usize);
}
@ -85,7 +87,7 @@ impl UI {
let action = self.process_page_input();
self.process_action(action)
.map_err(|e| self.error(&e.to_string()));
.map_err(|e| error(&e.to_string()));
}
pub fn open(&mut self, url: &str) -> io::Result<()> {
@ -95,7 +97,7 @@ impl UI {
}
// gopher URL
self.status(&format!(
status(&format!(
"{}Loading...{}",
color::Fg(color::LightBlack),
termion::cursor::Show
@ -136,32 +138,6 @@ 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.
pub 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();
}
fn add_page<T: View + 'static>(&mut self, view: T) {
self.dirty = true;
if !self.pages.is_empty() && self.page < self.pages.len() - 1 {
@ -209,6 +185,13 @@ impl UI {
self.page += 1;
}
}
Action::Keypress(Key::Ctrl('r')) => {
if let Some(page) = self.pages.get(self.page) {
let url = page.url().to_string();
let raw = page.raw().to_string();
self.add_page(TextView::from(url, raw));
}
}
Action::Keypress(Key::Ctrl('g')) => {
if let Some(url) = prompt("Go to URL: ") {
if !url.contains("://") && !url.starts_with("gopher://") {
@ -218,15 +201,18 @@ impl UI {
}
}
}
Action::Keypress(Key::Ctrl('h')) => {
self.add_page(MenuView::from("help".into(), help::GOPHERMAP.into()));
}
Action::Keypress(Key::Ctrl('u')) => {
if let Some(page) = self.pages.get(self.page) {
self.status(&format!("Current URL: {}", page.url()));
status(&format!("Current URL: {}", page.url()));
}
}
Action::Keypress(Key::Ctrl('y')) => {
if let Some(page) = self.pages.get(self.page) {
copy_to_clipboard(&page.url())?;
self.status(&format!("Copied {} to clipboard.", page.url()));
status(&format!("Copied {} to clipboard.", page.url()));
}
}
_ => (),
@ -329,3 +315,31 @@ pub fn prompt(prompt: &str) -> Option<String> {
None
}
}
// Display a status message to the user.
pub fn status(s: &str) {
let (_cols, rows) = termion::terminal_size().unwrap();
print!(
"{}{}{}{}{}",
"\x1b[93m",
termion::cursor::Goto(1, rows),
termion::clear::CurrentLine,
s,
color::Fg(color::Reset)
);
stdout().flush();
}
// Display an error message to the user.
pub fn error(e: &str) {
let (_cols, rows) = termion::terminal_size().unwrap();
print!(
"{}{}{}{}{}",
"\x1b[91m",
termion::cursor::Goto(1, rows),
termion::clear::CurrentLine,
e,
color::Fg(color::Reset)
);
stdout().flush();
}

Loading…
Cancel
Save