|
|
|
|
@ -40,10 +40,13 @@ impl FromStr for Status {
|
|
|
|
|
|
|
|
|
|
const HELP: &'static str = " |
|
|
|
|
Press g to visit an URL |
|
|
|
|
Press b to go back |
|
|
|
|
Press q to exit |
|
|
|
|
"; |
|
|
|
|
|
|
|
|
|
fn main() { |
|
|
|
|
File::create("/tmp/asuka_history").expect("unable to create file"); |
|
|
|
|
|
|
|
|
|
let mut siv = Cursive::default(); |
|
|
|
|
|
|
|
|
|
siv.add_fullscreen_layer( |
|
|
|
|
@ -63,6 +66,8 @@ fn main() {
|
|
|
|
|
siv.add_global_callback('q', |s| s.quit()); |
|
|
|
|
// pressing g prompt for an URL
|
|
|
|
|
siv.add_global_callback('g', |s| prompt_for_url(s)); |
|
|
|
|
// pressing b goes back in history
|
|
|
|
|
siv.add_global_callback('b', |s| go_back(s)); |
|
|
|
|
|
|
|
|
|
siv.run(); |
|
|
|
|
} |
|
|
|
|
@ -82,13 +87,12 @@ fn prompt_for_url(s: &mut Cursive) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn visit_url(s: &mut Cursive, url: &str) { |
|
|
|
|
s.pop_layer(); |
|
|
|
|
// s.pop_layer();
|
|
|
|
|
|
|
|
|
|
match get_data(&url) { |
|
|
|
|
Ok(new_content) => { |
|
|
|
|
let mut select = SelectView::new() |
|
|
|
|
.h_align(HAlign::Left) |
|
|
|
|
.autojump(); |
|
|
|
|
.h_align(HAlign::Left); |
|
|
|
|
|
|
|
|
|
s.add_layer(Dialog::info(url)); |
|
|
|
|
|
|
|
|
|
@ -107,27 +111,31 @@ fn visit_url(s: &mut Cursive, url: &str) {
|
|
|
|
|
|
|
|
|
|
fn follow_link(s: &mut Cursive, line: &str) { |
|
|
|
|
let text = format!("{}", line); |
|
|
|
|
let re1 = Regex::new(r"^\[(.*)\|(.*)\]$").unwrap(); // `[Foo|link]` links
|
|
|
|
|
let re2 = Regex::new(r"^=>\s(\S*)\s(\w*)$").unwrap(); // `=> link Foo` links
|
|
|
|
|
let re1 = Regex::new(r"^\[(.*)\|(URL:)?(.*)\]$").unwrap(); // `[Foo|URL:link]` links
|
|
|
|
|
let re2 = Regex::new(r"^=>\s(\S*)\s(\w*)$").unwrap(); // `=> link Foo` links
|
|
|
|
|
|
|
|
|
|
if re1.is_match(&text) { |
|
|
|
|
let caps = re1.captures(&text).unwrap(); |
|
|
|
|
s.pop_layer(); |
|
|
|
|
let url = caps.get(2).map_or("", |m| m.as_str()); |
|
|
|
|
let next_url = match url.chars().next() { |
|
|
|
|
Some('/') => format!("{}{}", get_last_url(), url), |
|
|
|
|
Some(_) => url.to_owned(), |
|
|
|
|
None => url.to_owned() |
|
|
|
|
let url = caps.get(3).map_or("", |m| m.as_str()); |
|
|
|
|
let next_url = if url.starts_with("gemini://") { |
|
|
|
|
url.to_owned() |
|
|
|
|
} else if url.starts_with("/") { |
|
|
|
|
format!("{}{}", get_last_url(), url) |
|
|
|
|
} else { |
|
|
|
|
format!("{}/{}", get_last_url(), url) |
|
|
|
|
}; |
|
|
|
|
visit_url(s, &next_url) |
|
|
|
|
} else if re2.is_match(&text) { |
|
|
|
|
let caps = re2.captures(&text).unwrap(); |
|
|
|
|
s.pop_layer(); |
|
|
|
|
let url = caps.get(1).map_or("", |m| m.as_str()); |
|
|
|
|
let next_url = match url.chars().next() { |
|
|
|
|
Some('/') => format!("{}{}", get_last_url(), url), |
|
|
|
|
Some(_) => url.to_owned(), |
|
|
|
|
None => url.to_owned() |
|
|
|
|
let next_url = if url.starts_with("gemini://") { |
|
|
|
|
url.to_owned() |
|
|
|
|
} else if url.starts_with("/") { |
|
|
|
|
format!("{}{}", get_last_url(), url) |
|
|
|
|
} else { |
|
|
|
|
format!("{}/{}", get_last_url(), url) |
|
|
|
|
}; |
|
|
|
|
visit_url(s, &next_url) |
|
|
|
|
} else { |
|
|
|
|
@ -169,6 +177,13 @@ fn get_data(url: &str) -> Result<String, String> {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn go_back(s: &mut Cursive) { |
|
|
|
|
match get_previous_url() { |
|
|
|
|
Some(url) => visit_url(s, &url), |
|
|
|
|
None => () |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn get_last_url() -> String { |
|
|
|
|
let mut file = File::open("/tmp/asuka_history").expect("file not found"); |
|
|
|
|
let mut content = String::new(); |
|
|
|
|
@ -176,6 +191,19 @@ fn get_last_url() -> String {
|
|
|
|
|
content.lines().last().unwrap().to_owned() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn get_previous_url() -> Option<String> { |
|
|
|
|
let mut file = OpenOptions::new().read(true).open("/tmp/asuka_history").unwrap(); |
|
|
|
|
let mut content = String::new(); |
|
|
|
|
file.read_to_string(&mut content).expect("Unable to read file"); |
|
|
|
|
let lines_count = content.lines().count(); |
|
|
|
|
|
|
|
|
|
if lines_count > 1 { |
|
|
|
|
Some(content.lines().nth(lines_count - 2).unwrap().to_owned()) |
|
|
|
|
} else { |
|
|
|
|
None |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn append_history(url: &str) { |
|
|
|
|
let mut file = OpenOptions::new() |
|
|
|
|
.read(true) |
|
|
|
|
|