qutebrowser: Make use of dotter for dir structure

Since we now use dotter we can simplify the dir structure for
qutebrowser a lot. Everything dot-filed earlier can now reside
in simple directories called config (for ~/.config/qutebrowser),
data (for ~/.local/share/qutebrowser), and scripts
(for ~/.local/bin) files.
This commit is contained in:
Marty Oehme 2023-10-03 13:43:00 +02:00
parent dcde027a67
commit 8681d34946
Signed by: Marty
GPG key ID: EDBF2ED917B2EF6A
49 changed files with 9 additions and 5 deletions

View file

@ -0,0 +1,41 @@
c.aliases["gem"] = "spawn --userscript qute-gemini "
# Use q for quitting a tab (mimicks vim buffer) - qa is used for exiting
c.aliases["q"] = "tab-close"
# if we save sessions with w, load sessions with e (again, mimicks vim)
c.aliases["e"] = "session-load"
# wallabag add current page, either with walla command, or <leader>bw
c.aliases["add-wallabag"] = "spawn --userscript wallabag_add.sh"
# add to (my) shaarli instance
c.aliases["add-shaarli"] = "spawn --userscript shaarli_add.sh"
# re-opens the current page on the web archive overview page
c.aliases["send-to-archive"] = "open https://web.archive.org/web/{url}"
# save current page to pdf file
c.aliases["save-to-pdf"] = "spawn --userscript pagetopdf.sh"
# open sci-hub pdf for doi
c.aliases["send-to-scihub"] = "spawn --userscript doi2scihub"
# translate current page / selection with google translate
c.aliases["translate-page-google"] = "spawn --userscript translate_google.sh"
c.aliases[
"translate-selection-google"
] = "spawn --userscript translate_google.sh --text"
# open the current page in more readable version
c.aliases["readable"] = "spawn --userscript readability"
# print picture of current url as qr code
c.aliases["show-qr"] = "spawn --userscript qr"
# add a task of current page to taskwarrior
c.aliases["taskadd"] = "spawn --userscript taskadd"
# try to remove the cookie banner from a website
c.aliases["cookie-block"] = "spawn --userscript qute-cookie-block"
# open last downloads in dmenu-like
c.aliases["recent-downloads"] = "spawn --userscript recently-downloaded"

View file

@ -0,0 +1,79 @@
import os
from qutebrowser.config.config import ConfigContainer # noqa: F401
from qutebrowser.config.configfiles import ConfigAPI # noqa: F401
# Autogenerated config.py
# Documentation:
# qute://help/configuring.html
# qute://help/settings.html
# load additional settings configured via autoconfig.yml
config.load_autoconfig()
term = os.getenv("TERMINAL", "xterm")
c.completion.web_history.max_items = 1000
c.hints.uppercase = True
c.editor.command = [
term,
"start",
"--always-new-process",
"nvim",
"-f",
"{file}",
"-c",
"normal {line}G{column0}l",
]
# change filepicker
c.fileselect.handler = "external"
picker = [
term,
"start",
"--class",
"float",
"vifm",
"--choose-files",
"{}",
]
c.fileselect.single_file.command = picker
c.fileselect.multiple_files.command = picker
c.downloads.location.directory = os.getenv("XDG_DOWNLOAD_DIR", "~/downloads")
c.downloads.location.prompt = False
config.source("alias.py")
config.source("maps.py")
config.source("content.py")
config.source("searchengines.py")
config.source("redirects.py")
# Tab-Bar
# have tab bar on the right, not on the top
c.tabs.background = True
c.tabs.title.format = "{index} {audio}{perc}{current_title}"
c.tabs.position = "right"
c.tabs.width = "15%"
c.tabs.show = "multiple"
c.tabs.show_switching_delay = 2000
c.statusbar.show = "always"
c.colors.webpage.bg = "#555555"
# Prevents *all* tabs from being loaded on restore, only loads on activating them
c.session.lazy_restore = True
# for code_select.py userscript
# Allows copying code sections to clipboard easily
c.hints.selectors["code"] = [
# Selects all code tags whose direct parent is not a pre tag
":not(pre) > code",
"pre",
]
# give the browser nice theme colors
state_dir=os.environ.get('XDG_STATE_HOME', f"{os.environ['HOME']}/.local/state")
colorscheme=f"{state_dir}/qutebrowser/colorscheme.py"
if os.path.isfile(colorscheme):
config.source(colorscheme)

View file

@ -0,0 +1,41 @@
# disable html5 canvas fingerprinting (at the cost of a couple streaming pages)
c.content.canvas_reading = False
c.content.blocking.enabled = True
c.content.blocking.method = "both"
c.content.blocking.adblock.lists = [
"https://easylist.to/easylist/easylist.txt",
"https://easylist.to/easylist/easyprivacy.txt",
"https://someonewhocares.org/hosts/hosts",
"https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext",
"https://secure.fanboy.co.nz/fanboy-cookiemonster.txt",
]
c.content.blocking.whitelist = ["piwik.org"]
c.content.autoplay = False
c.content.prefers_reduced_motion = True
c.content.pdfjs = False
c.content.javascript.enabled = False
js_whitelist = [
"*://*.youtube.com/*",
"*://127.0.0.1/*",
"*://asciinema.org/*",
"*://calendar.google.com/*",
"*://darksky.net/*",
"*://deepl.com/*",
"*://duckduckgo.com/*",
"*://fosstodon.org/*",
"*://github.com/*",
"*://gitlab.com/*",
"*://localhost/*",
"*://mail.google.com/*",
"*://maps.google.com/*",
"*://*.martyoeh.me/*",
"*://news.ycombinator.com/*",
"*://old.reddit.com/*",
"*://translate.google.com/*",
"chrome://*/*",
"file://*",
"qute://*/*",
]
for page in js_whitelist:
with config.pattern(page) as p:
p.content.javascript.enabled = True

110
qutebrowser/config/maps.py Normal file
View file

@ -0,0 +1,110 @@
# Key mappings
# 'Leader' key binding -- for general personal maps
leader = "<Space>"
# 'LocalLeader' key binding -- intended for 'in-page' personal maps
lleader = ","
## CHANGED DEFAULTS
# rebind moving tabs to free for download
config.bind("gG", "tab-give")
# switch binds for scroll-marks and quick-/book-marks
config.bind("m", "mode-enter set_mark")
config.bind("`", "quickmark-save")
config.bind("~", "bookmark-add")
config.bind("<Ctrl-J>", "command-history-next", mode="command")
config.bind("<Ctrl-K>", "command-history-prev", mode="command")
config.bind("<Ctrl-P>", "completion-item-focus prev", mode="command")
config.bind("<Ctrl-N>", "completion-item-focus next", mode="command")
config.bind("<Alt-Backspace>", "rl-backward-kill-word", mode="command")
config.bind("<Alt-D>", "rl-kill-word", mode="command")
config.bind("<Alt-F>", "rl-forward-word", mode="command")
config.bind("<Ctrl-?>", "rl-delete-char", mode="command")
config.bind("<Ctrl-A>", "rl-beginning-of-line", mode="command")
config.bind("<Ctrl-B>", "rl-backward-char", mode="command")
config.bind("<Ctrl-C>", "completion-item-yank", mode="command")
config.bind("<Ctrl-D>", "completion-item-del", mode="command")
config.bind("<Ctrl-E>", "rl-end-of-line", mode="command")
config.bind("<Ctrl-F>", "rl-forward-char", mode="command")
config.bind("<Ctrl-H>", "rl-backward-delete-char", mode="command")
config.bind("<Ctrl-Shift-Tab>", "completion-item-focus prev-category", mode="command")
config.bind("<Ctrl-Tab>", "completion-item-focus next-category", mode="command")
config.bind("<Ctrl-U>", "rl-unix-line-discard", mode="command")
config.bind("<Ctrl-W>", "rl-unix-word-rubout", mode="command")
config.bind("<Ctrl-Y>", "rl-yank", mode="command")
## ADDED
# toggles ('cycles') between tabs always showing, or only when switching between them
config.bind(
leader + "tt",
"config-cycle -t tabs.show multiple switching ;; config-cycle -t statusbar.show always in-mode",
)
config.bind(leader + "th", "set tabs.position bottom")
config.bind(leader + "tH", "set tabs.position top")
config.bind(leader + "tv", "set tabs.position right")
config.bind(leader + "tV", "set tabs.position left")
# [M]edia shortcuts - watch, queue, download media
# bind mpv to play the current page/links, using a single instance which queues the next link passed
config.bind(lleader + "M", "spawn umpv {url}")
config.bind(lleader + "m", "hint links spawn umpv {hint-url}")
config.bind(lleader + "I", "spawn uoeia -v imv {url}")
config.bind(lleader + "i", "hint links spawn uoeia -v imv {hint-url}")
config.bind(lleader + "<Ctrl-i>", "hint images spawn uoeia -v imv {hint-url}")
# [G]emini shortcuts
# the full power of qutebrowser at your fingertips for any gemini page!
config.bind(f"{lleader}g", "hint all userscript qute-gemini")
config.bind(f"{lleader}G", "hint all userscript qute-gemini-tab")
# bind youtube-dl to download the current page/links
config.bind(lleader + "dM", "spawn vidl {url}")
config.bind(
lleader + "dm",
"hint --rapid links spawn vidl {hint-url}",
)
# Download shortcuts
config.bind(lleader + "dd", "download", mode="normal")
config.bind(lleader + "dp", "save-to-pdf", mode="normal")
# open last download
config.bind("gD", "recent-downloads", mode="normal")
config.bind('"w', "add-wallabag", mode="normal") # add current page to wallabag
config.bind(';w', "hint links userscript wallabag_add.sh") # add link to wallabag
config.bind('"s', "add-shaarli", mode="normal")
config.bind(';s', "hint links userscript shaarli_add.sh")
config.bind('"a', "send-to-archive", mode="normal")
config.bind('"t', "translate-page-google", mode="normal")
config.bind('"t', "translate-selection-google", mode="caret")
config.bind('"q', "show-qr")
config.bind('"p', "send-to-scihub", mode="normal") # view current page doi on scihub
config.bind(";p", "hint links run send-to-scihub") # view linked doi on scihub
config.bind(lleader + "r", "readable", mode="normal")
# set stylesheets for the browser to use
config.bind(
leader + "s",
"config-cycle content.user_stylesheets " + 'stylesheets/stylesheet.css ""',
)
config.bind(leader + "a", "set-cmd-text -s :taskadd")
# Enable and disable javascript
config.bind(leader + "js", "config-cycle content.javascript.enabled true false")
# Reload configuration
config.bind(leader + "VV", "config-source")
# Enable code snippet hinting mode
config.bind(";c", "hint code userscript code_select.py")
# first looks if it's a gemini link and then fall back to http
config.bind(";g", "hint links userscript qute-gemini")
config.bind(";G", "hint links userscript qute-gemini-tab")

View file

@ -0,0 +1,229 @@
import random
from urllib import parse
import re
from qutebrowser.api import interceptor
from qutebrowser.extensions.interceptors import QUrl, RedirectException
from qutebrowser.utils import message
def fixScribePath(url: QUrl):
"""Fix external medium blog to scribe translation.
Some paths from medium will go through a 'global identity'
path which messes up the actual url path we want to go
to and puts it in queries. This puts it back on the path.
"""
# double unquoting necessary!
# I suppose we double-wrap it earlier somewhere?
# unquoted = parse.unquote(
# url.path(options=QUrl.ComponentFormattingOption.FullyEncoded)
# )
path = parse.unquote(f"{url.path()}{url.query()}", encoding="ascii")
url.setQuery(None)
new_path = re.sub(r"m/global-identity-2redirectUrl=", "", path)
url.setPath(
parse.quote(new_path),
mode=QUrl.ParsingMode.StrictMode,
)
return url
redirects = {
"youtube": {
"source": ["youtube.com"],
"target": [
"yt.oelrichsgarcia.de",
"invidious.weblibre.org",
"invidious.dhusch.de",
"iv.ggtyler.dev",
"invidious.baczek.me",
"yt.funami.tech",
"iv.melmac.space",
"invidious.silur.me",
"invidious.lidarshield.cloud",
"invidious.flokinet.to",
"invidious.snopyta.org",
"invidious.kavin.rocks",
"vid.puffyan.us",
"yt.artemislena.eu",
"invidious.nerdvpn.de",
"invidious.tiekoetter.com",
"invidious.namazso.eu",
"inv.vern.cc",
"yewtu.be",
"inv.bp.projectsegfau.lt",
"invidious.epicsite.xyz",
"y.com.sb",
"invidious.sethforprivacy.com",
],
},
"lbry": {
"source": ["odysee.com"],
"target": [
"lbry.bcow.xyz",
"odysee.076.ne.jp",
"librarian.pussthecat.org",
"lbry.mutahar.rocks",
"lbry.vern.cc",
],
},
"reddit": {
"source": ["reddit.com"],
"target": [
"td.vern.cc",
"teddit.artemislena.eu",
"teddit.bus-hit.me",
"teddit.hostux.net",
"teddit.namazso.eu",
"teddit.net",
"teddit.pussthecat.org",
"teddit.sethforprivacy.com",
"teddit.zaggy.nl",
],
},
"twitter": {
"source": ["twitter.com"],
"target": [
"nitter.net",
"nitter.42l.fr",
"nitter.fdn.fr",
"nitter.1d4.us",
"nitter.kavin.rocks",
"nitter.unixfox.eu",
"nitter.namazso.eu",
"nitter.moomoo.me",
"bird.trom.tf",
"nitter.it",
"twitter.censors.us",
"nitter.grimneko.de",
"twitter.076.ne.jp",
"n.l5.ca",
"unofficialbird.com",
"nitter.ungovernable.men",
],
},
"imdb": {
"source": ["imdb.com"],
"target": [
"libremdb.iket.me",
"libremdb.pussthecat.org",
"ld.vern.cc",
"binge.whatever.social",
"libremdb.lunar.icu",
],
},
"translate": {
"source": ["translate.google.com"],
"target": [
"lingva.ml",
"translate.igna.wtf",
"translate.plausibility.cloud",
"translate.projectsegfau.lt",
"translate.dr460nf1r3.org",
"lingva.garudalinux.org",
"translate.jae.fi",
],
},
"tiktok": {
"source": ["tiktok.com"],
"target": [
"proxitok.pabloferreiro.es",
"proxitok.pussthecat.org",
"tok.habedieeh.re",
"proxitok.privacydev.net",
"proxitok.odyssey346.dev",
"tok.artemislena.eu",
"tok.adminforge.de",
"proxitok.manasiwibi.com",
"tik.hostux.net",
"tt.vern.cc",
"proxitok.mha.fi",
"proxitok.pufe.org",
"proxitok.marcopisco.com",
"cringe.whatever.social",
"proxitok.lunar.icu",
],
},
"imgur": {
"source": ["imgur.com"],
"target": [
"imgur.artemislena.eu",
"ri.zzls.xyz",
"rimgo.bus-hit.me",
"rimgo.fascinated.cc",
"rimgo.hostux.net",
"rimgo.kling.gg",
"rimgo.lunar.icu",
"rimgo.marcopisco.com",
"rimgo.privacytools.io",
"rimgo.projectsegfau.lt",
"rimgo.pussthecat.org",
"rimgo.totaldarkness.net",
"rimgo.whateveritworks.org",
],
},
"medium": {
"source": ["medium.com"],
"target": [
"scribe.rip",
"scribe.citizen4.eu",
"scribe.bus-hit.me",
"sc.vern.cc",
],
"postprocess": fixScribePath,
},
"google": {
"source": ["google.com"],
"target": [
"whoogle.dcs0.hu",
],
},
"wiki-en": {
"source": ["en.wikipedia.org"],
"target": [
"wiki.slipfox.xyz",
"wikiless.funami.tech",
"wikiless.org",
"wikiless.tiekoetter.com",
],
},
"wiki-de": {
"source": ["de.wikipedia.org"],
"target": [
"wiki.adminforge.de",
],
},
}
def rewrite(request: interceptor.Request) -> None:
# if config.get(name="content.oss_redirects") is False:
# return
if (
request.resource_type != interceptor.ResourceType.main_frame
or request.request_url.scheme() in {"data", "blob"}
):
return
url = request.request_url
if service := _should_be_redirected(url.host()):
# TODO integrate pinging and always surf to fastest?
target = service["target"][random.randint(0, len(service["target"]) - 1)]
if target is not None and url.setHost(target) is not False:
if "postprocess" in service:
url = service["postprocess"](url)
try:
request.redirect(url)
except RedirectException as e:
message.error(str(e))
def _should_be_redirected(host: str, redirects: dict = redirects) -> dict | None:
for service in redirects.values():
for source in service["source"]:
if re.search(source, host):
return service
return None
interceptor.register(rewrite)

View file

@ -0,0 +1,29 @@
c.url.searchengines = {
"DEFAULT": "https://search.martyoeh.me/?q={}",
"al": "https://wiki.archlinux.org/index.php/{}",
"alt": "https://alternativeto.net/software/{}/?license=opensource",
"aur": "https://aur.archlinux.org/packages/?K={}",
"d": "https://www.dict.cc/?s={}",
"ddg": "https://duckduckgo.com/?q={}",
"docker": "https://hub.docker.com/search?q={}",
"dt": "https://www.deepl.com/translator#en/de/{}",
"g": "https://www.google.com/search?q={}",
"gh": "https://github.com/search?q={}",
"gol": "https://golang.org/pkg/{}/",
"hn": "https://hn.algolia.com/?q={}",
"kb": "https://soeg.kb.dk/discovery/search?query=any,contains,{}&lang=en",
"l": "https://links.martyoeh.me/?searchterm={}&searchtags=",
"man": "https://manned.org/browse/search?q={}",
"maps": "https://www.qwant.com/maps/?q={}",
"pcw": "https://www.pcgamingwiki.com/w/index.php?search={}",
"py": "https://pypi.org/search/?q={}",
"r": "https://www.reddit.com/r/{}",
"t": "https://www.thesaurus.com/browse/{}",
"w": "https://en.wikipedia.org/w/index.php?search={}",
"yt": "https://yewtu.be/search?q={}",
"lib": "http://libgen.fun/search.php?req={}",
"sci": "https://sci-hub.ru/{}",
"anna": "https://annas-archive.org/search?q={}",
}
c.url.default_page = "https://start.duckduckgo.com"
c.url.start_pages = ["https://start.duckduckgo.com"]