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:
parent
dcde027a67
commit
8681d34946
49 changed files with 9 additions and 5 deletions
41
qutebrowser/config/alias.py
Normal file
41
qutebrowser/config/alias.py
Normal 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"
|
||||
79
qutebrowser/config/config.py
Normal file
79
qutebrowser/config/config.py
Normal 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)
|
||||
41
qutebrowser/config/content.py
Normal file
41
qutebrowser/config/content.py
Normal 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
110
qutebrowser/config/maps.py
Normal 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")
|
||||
229
qutebrowser/config/redirects.py
Normal file
229
qutebrowser/config/redirects.py
Normal 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)
|
||||
29
qutebrowser/config/searchengines.py
Normal file
29
qutebrowser/config/searchengines.py
Normal 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"]
|
||||
Loading…
Add table
Add a link
Reference in a new issue