history: fix going back

Ultimately a simple link list does not do all you want, so now the
history maintains a list of visited links that are useful to display,
but also a backlink list to let the user move to the previous pages.
This commit is contained in:
dece 2021-05-09 00:46:26 +02:00
parent 397a143695
commit f1c5d8dfc9
4 changed files with 60 additions and 28 deletions

View file

@ -31,3 +31,4 @@ handle soft-hyphens on wrapping
bug: combining chars reduce lengths
non shit command-line
response code 11 (if still there)
gopher?

View file

@ -56,7 +56,7 @@ class Browser:
self.command_line = None
self.running = True
self.status_data = ("", 0, 0)
self.history = History()
self.history = History(self.config["history_limit"])
self.cache = {}
self.special_pages = self.setup_special_pages()
self._current_url = ""
@ -203,10 +203,15 @@ class Browser:
elif char == ord("l"):
self.scroll_page_horizontally(1)
self.screen.nodelay(False)
# else:
# unctrled = curses.unctrl(char)
# if unctrled == b"^T":
# self.set_status("test!")
# elif char == ord("@"):
# self.current_url = "bebop:debugzone"
# t = "\n".join("* " + u for u in self.history.urls)
# t += "\n\n" + "\n".join("* " + u for u in self.history.backlist)
# self.load_page(Page.from_text(t))
# # unctrled = curses.unctrl(char)
# # if unctrled == b"^T":
# # self.set_status("test!")
# pass
@property
def page_pad_size(self):
@ -310,7 +315,7 @@ class Browser:
else:
parts = parse_url(url)
if parts["netloc"] is None:
if parts["scheme"] is None and parts["netloc"] is None:
base_url = base_url or self.current_url
if base_url:
parts = parse_url(join_url(base_url, url))
@ -475,7 +480,10 @@ class Browser:
def go_back(self):
"""Go back in history if possible."""
previous_url = self.history.get_previous()
if self.current_url.startswith("bebop:"):
previous_url = self.history.get_previous(actual_previous=True)
else:
previous_url = self.history.get_previous()
if previous_url:
self.open_url(previous_url, history=False)
@ -489,14 +497,19 @@ class Browser:
if self.current_url:
self.open_url(get_root_url(self.current_url))
def open_internal_page(self, name, gemtext):
"""Open some content corresponding to a "bebop:" internal URL."""
page = Page.from_gemtext(gemtext, self.config["text_width"])
self.load_page(page)
self.current_url = "bebop:" + name
def open_bookmarks(self):
"""Open bookmarks."""
content = get_bookmarks_document()
if content is None:
self.set_status_error("Failed to open bookmarks.")
return
self.load_page(Page.from_gemtext(content, self.config["text_width"]))
self.current_url = "bebop:bookmarks"
self.open_internal_page("bookmarks", content)
def add_bookmark(self):
"""Add the current URL as bookmark."""
@ -551,8 +564,7 @@ class Browser:
def open_help(self):
"""Show the help page."""
self.load_page(Page.from_gemtext(HELP_PAGE, self.config["text_width"]))
self.current_url = "bebop:help"
self.open_internal_page("help", HELP_PAGE)
def prompt(self, text, keys):
"""Display the text and allow it to type one of the given keys."""
@ -561,8 +573,4 @@ class Browser:
def open_history(self):
"""Show a generated history of visited pages."""
self.load_page(Page.from_gemtext(
self.history.to_gemtext(),
self.config["text_width"]
))
self.current_url = "bebop:history"
self.open_internal_page("history", self.history.to_gemtext())

View file

@ -9,6 +9,7 @@ DEFAULT_CONFIG = {
"text_width": 80,
"source_editor": ["vi"],
"command_editor": ["vi"],
"history_limit": 1000,
}

View file

@ -4,32 +4,54 @@
class History:
"""Basic browsing history manager.
The history follows the "by last visited" behaviour of Firefox for the lack
of a better idea. Links are pushed as they are visited. If a link is visited
again, it bubbles up to the top of the history.
"""
def __init__(self):
def __init__(self, limit):
self.urls = []
self.backlist = []
self.limit = limit
def push(self, url):
"""Add an URL to the history.
If the URL is already in the list, it is moved to the top.
"""
"""Add an URL to the history."""
# Append url to our URLs, bubbling it up if it's already there.
try:
self.urls.remove(url)
except ValueError:
pass
self.urls.append(url)
if len(self.urls) > self.limit:
self.urls.pop(0)
def get_previous(self):
# Also simply push it to the backlist.
self.backlist.append(url)
if len(self.backlist) > self.limit:
self.backlist.pop(0)
def get_previous(self, actual_previous=False):
"""Return previous URL, or None if there is only one or zero URL."""
try:
return self.urls[-2]
if actual_previous:
return self.backlist[-1]
# The backlist should be populated with the first link visited and
# never completely emptied afterwards, or we end up in situation
# where you can't get away from internal pages.
if len(self.backlist) > 1:
self.backlist.pop()
return self.backlist[-1]
except IndexError:
return None
def to_gemtext(self):
"""Generate a simple Gemtext page of the current history."""
return "\n".join("=> " + url for url in self.urls)
"""Generate a simple Gemtext page of the current history.
Present a page that follows the "by last visited" behaviour of Firefox
for the lack of a better idea, avoiding duplicated entries.
"""
urls = []
seen = set()
for url in reversed(self.urls):
if url in seen:
continue
urls.append(url)
seen.add(url)
return "\n".join("=> " + url for url in urls)