aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Gonçalves <me@rgoncalves.se>2022-07-18 22:48:36 +0200
committerRomain Gonçalves <me@rgoncalves.se>2022-07-18 22:48:36 +0200
commit680c4d9f9989fcf4650a741075c54bef4d2b1772 (patch)
treee7bd9714a470f2115ca09bb1471e89009e38820d
parent7de7a8ae6187e5efea3895c593fe554a84178289 (diff)
downloadrgoncalves.se-680c4d9f9989fcf4650a741075c54bef4d2b1772.tar.gz
blog: add qutebrowser organization post
-rw-r--r--src/b/2022-07-organizing-qutebrowser-hyperlinks.md128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/b/2022-07-organizing-qutebrowser-hyperlinks.md b/src/b/2022-07-organizing-qutebrowser-hyperlinks.md
new file mode 100644
index 0000000..6a1a3cd
--- /dev/null
+++ b/src/b/2022-07-organizing-qutebrowser-hyperlinks.md
@@ -0,0 +1,128 @@
+title: Organizing qutebrowser hyperlinks
+date: 2022-07-18
+
+## Actual state
+
+Qutebrowser offers two strategies for saving an hyperlink [^1]:
+
+- `bookmark`: a link relates to a title (without any format constraint).
+- `quickmark`: a link relates to a tag (which must be unique).
+
+I have always used the bookmark strategy, but it lacks a propper
+quality-of-life update for sorting and formatting entries.
+
+## Intended workflow
+
+I have decided to pick the following workflow:
+
+1. Do not use the quickmark strategy.
+2. Store hyperlinks as bookmarks.
+3. Format the bookmarks titles, but allow duplicates.
+4. Sort the bookmarks per title.
+5. Show the same ui of quickmark-add when adding a new bookmark.
+
+A bookmark entry in `.config/qutebrowser/bookmarks/urls` would then look like
+this:
+
+```
+[hyperlink] [tag+1] [tag+2] ... [tag+n]
+
+https://beej.us/guide/bgnet/html/ +network +soft +wiki
+http://cat-v.org/ +wiki
+https://why-vi.rocks/ +wiki
+```
+
+While (1) and (2) are purely related to human behaviors, (3), (4) and (5)
+requires the implementation of logic on qutebrowser side, which does not exist
+on the upstream (yet).
+
+I originally produced multiple hacky scripts for sorting and formatting my
+bookmark file, but ended up doing Python injection from the qutebrowser
+configuration file. Thanks to the functions injection, the sorting and
+formatting operations are hooked to the `bookmark-add` keybind.
+
+![qutebrowser-bookmark-popup](/img/b/qutebrowser-bookmark-popup.jpg)
+
+## Implementation
+
+1. Sort the tags of each bookmark entries, then sort the bookmarks entries by
+ their title:
+
+ ```
+ from os import path
+ from io import SEEK_SET
+
+ from qutebrowser.browser.urlmarks import UrlMarkManager
+
+
+ def sort_bookmarks(url_filepath: str) -> None:
+ file = open(url_filepath, 'r+')
+ marks = (
+ (link, sorted(tags.split())) for link, tags in
+ (line.split(maxsplit=1) for line in file.readlines())
+ )
+ lines = (
+ f'{link} {" ".join(tags)}' for link, tags in
+ sorted(marks, key=lambda mark: mark[1])
+ )
+ file.seek(SEEK_SET)
+ file.writelines('\n'.join(lines))
+ file.close()
+```
+
+2. Hook the sort function when an new entry is added to the url file (Note: I
+ wanted to reuse the original `UrlMarkManager.save` method and extend it, but
+ pythonic shenanigans forced me to copy/paste two loc from the source code):
+
+
+ ```
+ def urlmarkmanager_save(manager: UrlMarkManager, configdir: str) -> None:
+ """Override Qutebrowser builtin method for saving bookmarks."""
+ manager._lineparser.data = [' '.join(tpl) for tpl in manager.marks.items()]
+ manager._lineparser.save()
+ sort_bookmarks(path.join(configdir, 'bookmarks/urls'))
+
+ from qutebrowser.browser.urlmarks import UrlMarkManager
+
+ UrlMarkManager.save = (
+ lambda manager: urlmarkmanager_save(manager, config.configdir)
+ )
+ ```
+
+3. Hook the save function with an homemade pop-up, that appears when adding a
+ new bookmark entry:
+
+ ```
+ from qutebrowser.api import cmdutils
+
+ @cmdutils.register()
+ def bookmark_save(url: QUrl):
+ """Save the current page as a bookmark."""
+ manager = objreg.get('bookmark-manager')
+ tags = message.ask(
+ title="Add bookmark:",
+ mode=PromptMode.text,
+ url=url.toString(QUrl.RemovePassword | QUrl.FullyEncoded),
+ text=(
+ "Please enter bookmark tags for<br/><b>"
+ f"{html.escape(url.toDisplayString())}</b>"
+ ),
+ )
+
+ if not tags:
+ return
+
+ try:
+ manager.add(url, tags)
+ except UrlAlreadyExistsError:
+ message.warning("Bookmark already exists.")
+ ```
+
+Now all my bookmark entries are sorted by their titles automatically, and it
+looks way better when I preview them!
+
+![qutebrowser-bookmark-entries](/img/b/qutebrowser-bookmark-entries.jpg)
+
+(Next step: integrate a fuzzy-finder for searching bookmarks)
+
+[^1]: https://github.com/qutebrowser/qutebrowser/issues/882
remember that computers suck.