aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2020-12-21 18:52:51 +0530
committerAkshay Nair <phenax5@gmail.com>2020-12-21 18:52:51 +0530
commitf1cf59ce2df9204f818cfd038538a2a31a5c2262 (patch)
tree35b0a21501615b7551514262b96e9d8113375cbc
parent6ff5a17adcf1ed72cd2f1c7bff606bdd3352b3bb (diff)
downloadnixos-config-f1cf59ce2df9204f818cfd038538a2a31a5c2262.tar.gz
nixos-config-f1cf59ce2df9204f818cfd038538a2a31a5c2262.zip
Adds qutebrowser config
Diffstat (limited to '')
-rw-r--r--config/qutebrowser/.gitignore2
-rw-r--r--config/qutebrowser/bookmarks/urls37
-rw-r--r--config/qutebrowser/config.py325
-rw-r--r--config/qutebrowser/greasemonkey/duckduckgo.js16
-rw-r--r--config/qutebrowser/greasemonkey/gh-pr.js27
-rw-r--r--config/qutebrowser/greasemonkey/hris-reg.js27
-rw-r--r--config/qutebrowser/greasemonkey/slack.js36
-rw-r--r--config/qutebrowser/greasemonkey/whatsapp.js57
-rw-r--r--config/qutebrowser/greasemonkey/youtube-ad.js51
-rw-r--r--config/qutebrowser/greasemonkey/youtube-no-autoplay.js111
-rw-r--r--config/qutebrowser/homepage/index.html258
-rw-r--r--config/qutebrowser/quickmarks17
-rw-r--r--config/qutebrowser/security.py86
-rwxr-xr-xconfig/qutebrowser/setup.sh22
-rw-r--r--config/qutebrowser/styles/adblocker.css108
-rw-r--r--config/qutebrowser/styles/dark.css23
-rw-r--r--config/qutebrowser/styles/default.css0
-rw-r--r--config/qutebrowser/styles/scrollbar.css33
-rw-r--r--config/qutebrowser/ui.py73
-rwxr-xr-xconfig/qutebrowser/userscripts/dl_music16
-rwxr-xr-xconfig/qutebrowser/userscripts/format_json42
-rwxr-xr-xconfig/qutebrowser/userscripts/nodemon11
-rwxr-xr-xconfig/qutebrowser/userscripts/open_downloads4
-rwxr-xr-xconfig/qutebrowser/userscripts/pick_useragent27
-rwxr-xr-xconfig/qutebrowser/userscripts/tor_identity6
-rwxr-xr-xconfig/qutebrowser/userscripts/torrent3
-rwxr-xr-xconfig/qutebrowser/userscripts/yank3
27 files changed, 1421 insertions, 0 deletions
diff --git a/config/qutebrowser/.gitignore b/config/qutebrowser/.gitignore
new file mode 100644
index 0000000..3add446
--- /dev/null
+++ b/config/qutebrowser/.gitignore
@@ -0,0 +1,2 @@
+qsettings/
+autoconfig.yml
diff --git a/config/qutebrowser/bookmarks/urls b/config/qutebrowser/bookmarks/urls
new file mode 100644
index 0000000..4bbdac0
--- /dev/null
+++ b/config/qutebrowser/bookmarks/urls
@@ -0,0 +1,37 @@
+https://keithp.com/~keithp/talks/xtc2001/paper/ The Xft Font Library: Architecture and Users Guide
+https://venam.nixers.net/blog/unix/2018/09/02/fonts-xcb.html Xft but for XCB
+https://gitlab.freedesktop.org/xorg/lib/libxft/-/blob/master/include/X11/Xft/Xft.h.in include/X11/Xft/Xft.h.in · master · xorg / lib / libXft · GitLab
+qute://pdfjs/web/viewer.html?filename=tmpnb_fwc6u_os-dev.pdf&file=&source=https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf tmpnb_fwc6u_os-dev.pdf
+https://github.com/simple-icons/simple-icons#cdn-usage simple-icons/simple-icons: SVG icons for popular brands
+https://www.oreilly.com/openbook/linuxdrive3/book/ Open Book - Linux Device Drivers, 3rd Edition
+https://www.freetype.org/freetype2/docs/tutorial/step1.html FreeType Tutorial / I
+https://crackstation.net/ CrackStation - Online Password Hash Cracking - MD5, SHA1, Linux, Rainbow Tables, etc.
+https://hashcat.net/wiki/doku.php?id=example_hashes example_hashes [hashcat wiki]
+https://radicle.xyz/ radicle
+https://dwm.suckless.org/status_monitor/dwmstatus-mitm.c https://dwm.suckless.org/status_monitor/dwmstatus-mitm.c
+https://www.bettercap.org/modules/ethernet/net.sniff/ bettercap :: net.sniff - net.fuzz
+https://github.com/moxie0/sslstrip moxie0/sslstrip: A tool for exploiting Moxie Marlinspike's SSL "stripping" attack.
+https://247ctf.com/ 247/CTF - The game never stops
+https://www.serverhosh.com/london-1gbps-vps/ London 1Gbps VPS | ServerHosh Internet Service
+https://quackr.io/receive-sms/uk/447418311286 United Kingdom : 447418311286 | Temporary Virtual Phone Numbers | Receive SMS Online - quackr
+https://www.whatsmydns.net/#CNAME/akshay.is-a.dev DNS Checker - DNS Propagation Check & DNS Lookup
+https://github.com/system-f/fp-course system-f/fp-course: Functional Programming Course
+https://app.neilpatel.com/en/seo_analyzer/site_audit?domain=akshay.is-a.dev&view=overview Ubersuggest
+https://medium.com/software-engineering-roundup/the-osi-model-87e5adf35e10 The OSI Model. Ugh, I’ve been struggling with this… | by Ian Ames | Software engineering roundup | Medium
+https://wiki.archlinux.org/index.php/EFISTUB EFISTUB - ArchWiki
+https://www.lenovo.com/in/en/laptops/ideapad/s-series/ideapad-3-15are05/p/81W1004EIN IdeaPad Slim 3 (15, AMD) | Lenovo India
+https://www.amazon.in/Notebook-i5-10210U-Windows-Graphics-XMA1901-FA/dp/B089F4GTDW/ref=sr_1_1_sspa?dchild=1&keywords=asus&qid=1605126083&s=computers&sr=1-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyRUhMOUVDMTBUT01DJmVuY3J5cHRlZElkPUEwNjU0NDg1MlFKQUFNVFJXUlBSNSZlbmNyeXB0ZWRBZElkPUEwMDAwNTA4MzROM1FNN00yVTc4SCZ3aWRnZXROYW1lPXNwX2F0ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU= Amazon.in: Buy Mi Notebook 14 Intel Core i5-10210U 10th Gen Thin and Light Laptop(8GB/512GB SSD/Windows 10/Intel UHD Graphics/Silver/1.5Kg), XMA1901-FA+Webcam Online at Low Prices in India | MI Reviews & Ratings
+https://app.slack.com/client/TNJRQ2H0E/D01FAF42K99 Slack | Akshay Nair | InVideo
+https://www.pivotaltracker.com/n/projects/2465721 Editor - Classic - Pivotal Tracker
+https://danielkeep.github.io/tlborm/book/index.html The Little Book of Rust Macros
+https://github.com/vramana/awesome-reasonml vramana/awesome-reasonml: A collection of awesome things regarding Reason/OCaml ecosystem.
+https://github.com/jayaramsankara/learnhaskell jayaramsankara/learnhaskell: Exercises from the book Pogramming in Haskell by Graham Hutton. Other small code snippets used for learning haskell
+https://adventofcode.com/ Advent of Code 2020
+https://github.com/jivoi/awesome-osint jivoi/awesome-osint: A curated list of amazingly awesome OSINT
+https://reasonml.chat/t/a-gentle-introduction-to-parser-combinators-and-angstrom/2546 A gentle Introduction to Parser Combinators and Angstrom - Showcase - ReasonML Forums
+https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter Using the Compiler API · microsoft/TypeScript Wiki
+https://github.com/wilsonpage/fastdom/blob/master/fastdom.js fastdom/fastdom.js at master · wilsonpage/fastdom
+https://www.2n.pl/blog/how-to-write-neovim-plugins-in-lua How to write neovim plugins in Lua | 2n it sp. z o.o.
+https://nixos.org/manual/nixos/stable/options.html#opt-boot.loader.efi.canTouchEfiVariables NixOS - NixOS 20.09 manual
+https://github.com/raphlinus/pulldown-cmark/blob/master/src/lib.rs pulldown-cmark/lib.rs at master · raphlinus/pulldown-cmark
+https://nixos.org/manual/nixos/stable/#sec-installation NixOS - NixOS 20.09 manual
diff --git a/config/qutebrowser/config.py b/config/qutebrowser/config.py
new file mode 100644
index 0000000..dba0095
--- /dev/null
+++ b/config/qutebrowser/config.py
@@ -0,0 +1,325 @@
+"""Qutebrowser configuration"""
+import os
+import re
+import sys
+import json
+import subprocess
+import random
+from qutebrowser.config.configfiles import ConfigAPI
+from qutebrowser.config.config import ConfigContainer
+config = config
+c = c
+
+leader = '\\'
+localleader = ' '
+
+config.load_autoconfig()
+
+# Helper Functions {{{
+# def toggle_stylesheets(stylesheets):
+ # return 'config-cycle content.user_stylesheets \'' \
+ # + json.dumps(c.content.user_stylesheets) \
+ # + '\' \'' \
+ # + json.dumps(c.content.user_stylesheets + stylesheets) \
+ # + '\''
+
+def bind(key, command, mode): # noqa: E302
+ """Bind key to command in mode."""
+ config.bind(key, command, mode=mode)
+
+
+def nmap(key, command):
+ """Bind key to command in normal mode."""
+ bind(key, command, 'normal')
+
+
+def imap(key, command):
+ """Bind key to command in insert mode."""
+ bind(key, command, 'insert')
+
+
+def cmap(key, command):
+ """Bind key to command in command mode."""
+ bind(key, command, 'command')
+
+def tmap(key, command):
+ """Bind key to command in caret mode."""
+ bind(key, command, 'caret')
+
+
+def pmap(key, command):
+ """Bind key to command in passthrough mode."""
+ bind(key, command, 'passthrough')
+
+
+def unmap(key, mode):
+ """Unbind key in mode."""
+ config.unbind(key, mode=mode)
+
+def nunmap(key):
+ """Unbind key in normal mode."""
+ unmap(key, mode='normal')
+# }}}
+
+#### Config ####
+
+
+#### Settings {{{
+c.backend = "webengine"
+c.auto_save.session = True
+c.session.lazy_restore = True
+c.content.autoplay = True
+c.url.open_base_url = True
+
+c.scrolling.bar = 'always'
+c.scrolling.smooth = True
+c.keyhint.delay = 250
+c.input.partial_timeout = 0
+c.input.spatial_navigation = False
+
+c.content.dns_prefetch = True # Use dns prefetching for speed
+
+# Editor
+c.editor.command = ['sensible-terminal', '-e', 'sensible-editor', '{}']
+c.input.insert_mode.auto_enter = True
+c.input.insert_mode.auto_leave = True
+c.input.insert_mode.auto_load = True
+c.input.insert_mode.leave_on_load = True
+
+# Hints
+c.hints.auto_follow = 'always'
+c.hints.chars = 'azsxdclmknjb'
+c.hints.auto_follow = 'unique-match'
+c.content.pdfjs = True
+
+nunmap('<Ctrl-v>')
+nunmap('<Ctrl-x>')
+nunmap('<Ctrl-V>')
+nunmap('<Ctrl-X>')
+nunmap('<Ctrl-h>')
+nunmap('<Ctrl-p>')
+
+# Edit text and edit url
+imap('<Ctrl-e>', 'open-editor')
+nmap('<Ctrl-e>', 'open-editor')
+# nmap('<Ctrl-l>', 'edit-url')
+nmap(localleader+'e', 'edit-url')
+
+nmap('<Ctrl-p>', 'enter-mode passthrough')
+# pmap('<Shift-Escape>', 'enter-mode normal') # Default
+
+nunmap("+")
+nunmap("-")
+nunmap("=")
+nmap("z=", "zoom-in")
+nmap("z-", "zoom-out")
+nmap("zz", "zoom")
+
+# Add search
+nmap('n', 'search-next')
+nmap('N', 'search-prev')
+
+# Clipboard play
+nmap('yy', 'yank selection') # Copy selected text
+nmap('yu', 'yank') # Copy url
+nmap('yl', 'hint links userscript yank') # Copy a link from page as hints
+
+# Add magnet link to download
+c.hints.selectors['torrents'] = [ 'a[href^="magnet:"]' ]
+c.aliases['find-torrent-magnet-links'] = 'hint torrents userscript torrent'
+nmap(leader + 'td', 'find-torrent-magnet-links')
+
+nmap('<Shift-j>', 'scroll-page 0 0.5')
+nmap('<Shift-k>', 'scroll-page 0 -0.5')
+# }}}
+
+#### Theme {{{
+config.source('ui.py')
+
+## Webpage styles
+c.content.user_stylesheets = [
+ "styles/scrollbar.css",
+ "styles/default.css",
+ "styles/adblocker.css",
+]
+
+# Dark mode
+# c.aliases['toggle-darkmode'] = toggle_stylesheets(['styles/dark.css'])
+
+nmap(localleader + 'td', ':toggle-darkmode')
+# }}}
+
+#### Sessions {{{
+c.aliases['load'] = 'session-load -t';
+
+# Sessions
+nmap(leader + 'sv', ':load video');
+nmap(leader + 'sc', ':load work');
+nmap(leader + 'si', ':load interview');
+# }}}
+
+#### Navigation {{{
+
+# Highlight inputs
+nmap('gi', 'hint inputs')
+
+# Selected
+nmap(localleader + 'gl', 'follow-selected') # Follow selected link
+nmap(localleader + 'gL', 'follow-selected --tab') # Follow selected link
+
+# Increment pagination
+nmap(localleader + 'nn', 'navigate increment')
+nmap(localleader + 'nN', 'navigate decrement')
+
+# From clipboard
+nmap('p', 'open --tab -- {clipboard}') # Open link in keyboard in a new tab
+nmap('P', 'open -- {clipboard}') # Open link in clipboard in the same tab
+
+# }}}
+
+#### TABS {{{
+c.tabs.show = 'multiple'
+c.tabs.title.format = '{perc}{private} {audio}{index}: {host} - {current_title}'
+c.tabs.tooltips = True
+c.tabs.background = True
+c.tabs.select_on_remove = 'next'
+c.tabs.new_position.unrelated = 'next'
+c.tabs.last_close = 'close' # 'close' for closing window on last d
+
+# Keybindings
+nmap('o', 'set-cmd-text -s :open --tab')
+nmap('O', 'set-cmd-text -s :open')
+
+# Tab
+nmap('d', 'tab-close')
+
+nmap('tt', 'open --tab') # New tab
+nmap('tp', 'open -p') # Private window
+
+# Detach tab
+nmap(leader + 'wt', 'tab-give')
+nmap(leader + 'wp', 'tab-pin')
+
+# Tab movement
+nmap('<Ctrl-k>', 'tab-prev')
+nmap('<Ctrl-j>', 'tab-next')
+nmap('<Ctrl-Shift-k>', 'tab-move -')
+nmap('<Ctrl-Shift-j>', 'tab-move +')
+nmap('b', 'set-cmd-text --space :buffer') # List buffers by index
+
+for i in range(1, 10 + 1):
+ key = 0 if i == 10 else i
+ nmap(localleader + str(key), 'tab-focus ' + str(i))
+
+# }}}
+
+#### Downloads {{{
+c.downloads.location.directory = '~/Downloads/qute'
+c.downloads.location.prompt = False
+c.downloads.open_dispatcher = 'dl_move {}'
+c.downloads.position = 'bottom'
+c.downloads.remove_finished = 1000
+c.downloads.open_dispatcher = '~/.bin/open'
+
+# c.qt.force_platformtheme='gtk3'
+
+# Goto downloads directory
+nunmap('gd')
+nmap('gdl', 'spawn --userscript open_downloads')
+
+# Playing Videos with MPV
+nmap(leader + 'tyy', 'spawn --detach bash -c "notify-send \\"Loading mpv\\" && mpv --force-window=immediate \\"{url}\\""')
+
+# Download music from youtube
+nmap(leader + 'tym', 'spawn --userscript dl_music')
+# }}}
+
+#### Security {{{
+config.source('security.py')
+
+nmap(leader + 'pp', 'incognito-enable')
+nmap(leader + 'pc', 'change-identity')
+nmap(leader + 'pd', 'incognito-disable')
+# }}}
+
+#### Perdomain permission config {{{
+
+# Notifications
+c.content.notifications = 'ask'
+c.content.desktop_capture = 'ask'
+
+config.set('content.notifications', True, '*://reddit.com')
+config.set('content.notifications', True, '*://www.reddit.com')
+config.set('content.notifications', True, '*://web.whatsapp.com')
+config.set('content.notifications', True, '*://mail.google.com')
+config.set('content.notifications', True, '*://chat.google.com')
+
+# Google meet
+config.set('content.notifications', False, '*://meet.google.com')
+config.set('content.media.audio_video_capture', True, '*://meet.google.com')
+config.set('content.media.audio_capture', True, '*://meet.google.com')
+config.set('content.media.video_capture', True, '*://meet.google.com')
+
+# }}}
+
+#### Search and bookmarks {{{
+# Default start page
+c.url.default_page = '~/.config/qutebrowser/homepage/index.html'
+c.url.start_pages = [c.url.default_page]
+
+DEFAULT_SEARCH_ENGINE = 'd'
+c.url.searchengines = {
+ # General
+ 'sp': 'https://www.startpage.com/sp/search?q={}',
+ 'sx': 'https://searx.fmac.xyz/?q={}',
+ 'q': 'https://www.qwant.com/search?q={}',
+ 'd': 'https://duckduckgo.com/?q={}',
+ 'go': 'https://google.com/?q={}',
+
+ # Dev stuff
+ 'bp': 'https://bundlephobia.com/result?p={}',
+ 'rs': 'https://crates.io/search?q={}',
+ 'ciu': 'https://caniuse.com/#search={}',
+ 'g': 'https://github.com/{}',
+ 'gh': 'http://github.com/search?q={}',
+ 'hg': 'http://www.haskell.org/hoogle/?hoogle={}',
+ 'aw': 'http://wiki.archlinux.org/index.php?search={}',
+ 'cname': 'https://www.whatsmydns.net/#CNAME/{}',
+
+ # Media
+ 'r': 'http://www.reddit.com/r/{}/',
+ 'y': 'http://www.youtube.com/results?search_query={}',
+ 'az': 'http://search.azlyrics.com/search.php?q={}',
+
+ # Ignore
+ 'DEFAULT': 'http://this-is-a-placeholder.com?q={}',
+}
+
+# Default search engine
+c.url.searchengines['DEFAULT'] = c.url.searchengines[DEFAULT_SEARCH_ENGINE]
+c.url.searchengines['s'] = c.url.searchengines['DEFAULT']
+
+c.aliases['archive'] = 'open --tab http://web.archive.org/save/{url}'
+c.aliases['view-archive'] = 'open --tab http://web.archive.org/web/*/{url}'
+c.aliases['view-google-cache'] = 'open --tab http://www.google.com/search?q=cache:{url}'
+
+# c.aliases['xa'] = 'quit --save'
+c.aliases['h'] = 'help'
+# }}}
+
+#### Dev {{{
+nmap(leader + 'tr', 'config-source') # Reload config
+nmap(leader + 'ti', 'devtools window') # Inspector
+nmap(leader + 'ts', 'view-source') # View page source
+
+# Json formatter
+c.aliases['format-json'] = 'spawn --userscript format_json';
+nmap(leader + 'tj', 'format-json')
+# }}}
+
+#### History {{{
+nmap('<Shift-h>', 'back')
+nmap('<Shift-l>', 'forward')
+nmap(leader + 'hh', 'history --tab')
+# }}}
+
diff --git a/config/qutebrowser/greasemonkey/duckduckgo.js b/config/qutebrowser/greasemonkey/duckduckgo.js
new file mode 100644
index 0000000..f1c9247
--- /dev/null
+++ b/config/qutebrowser/greasemonkey/duckduckgo.js
@@ -0,0 +1,16 @@
+// ==UserScript==
+// @name Github PR helper
+// @namespace phenax.github.io
+// @version 0.0.0
+// @description Github PR helper
+// @author Akshay Nair
+// @match *://duckduckgo.com/*
+// ==/UserScript==
+
+(() => {
+ const load = str =>
+ str.split(' ').forEach(x => (document.cookie = x));
+
+ load('ae=d; 5=2; s=m; p=-2; am=osm; a=JetBrains%20Mono; t=JetBrains%20Mono; j=0f0c19; 7=15121f; 21=1f1c29;')
+})();
+
diff --git a/config/qutebrowser/greasemonkey/gh-pr.js b/config/qutebrowser/greasemonkey/gh-pr.js
new file mode 100644
index 0000000..5803022
--- /dev/null
+++ b/config/qutebrowser/greasemonkey/gh-pr.js
@@ -0,0 +1,27 @@
+// ==UserScript==
+// @name Github PR helper
+// @namespace phenax.github.io
+// @version 0.0.0
+// @description Github PR helper
+// @author Akshay Nair
+// @match *://github.com/*/pull/*/files
+// ==/UserScript==
+
+const keys = {
+ n: () => document.querySelector('.js-reviewed-toggle:not(.js-reviewed-file)').click(),
+ N: () => Array.from(document.querySelectorAll('.js-reviewed-file')).slice(-1)[0].click(),
+ //j: () => {
+ //const $el = document.querySelector('.js-reviewed-toggle:not(.js-reviewed-file)');
+ //if ($el) {
+
+ //}
+ //},
+};
+
+document.addEventListener('keydown', (e) => {
+ console.log(e.key, e.ctrlKey);
+ if (keys[e.key] && e.ctrlKey) {
+ keys[e.key]();
+ }
+});
+
diff --git a/config/qutebrowser/greasemonkey/hris-reg.js b/config/qutebrowser/greasemonkey/hris-reg.js
new file mode 100644
index 0000000..852d357
--- /dev/null
+++ b/config/qutebrowser/greasemonkey/hris-reg.js
@@ -0,0 +1,27 @@
+// ==UserScript==
+// @name Github PR helper
+// @namespace phenax.github.io
+// @version 0.0.0
+// @description Github PR helper
+// @author Akshay Nair
+// @match *://hris.peoplelabs.com/attendance/regularization/apply-regularization/*
+// ==/UserScript==
+
+const $ = document.querySelector.bind(document);
+
+const keys = {
+ r: () => {
+ $('#firstintime').value = '10:30';
+ $('#lastouttime').value = '18:30';
+ $('#reason').value = 'Work from home';
+ setTimeout(() => $('input[type="submit"]').click(), 500);
+ },
+};
+
+document.addEventListener('keydown', (e) => {
+ if (keys[e.key] && e.ctrlKey) {
+ keys[e.key]();
+ }
+});
+
+
diff --git a/config/qutebrowser/greasemonkey/slack.js b/config/qutebrowser/greasemonkey/slack.js
new file mode 100644
index 0000000..b1d6cc4
--- /dev/null
+++ b/config/qutebrowser/greasemonkey/slack.js
@@ -0,0 +1,36 @@
+// ==UserScript==
+// @name Slack helper
+// @namespace phenax.github.io
+// @version 0.0.0
+// @description Slack helper
+// @author Akshay Nair
+// @match *://app.slack.com/*
+// ==/UserScript==
+
+const keys = {};
+
+document.addEventListener('keydown', (e) => {
+ if (keys[e.key] && e.ctrlKey) {
+ keys[e.key]();
+ }
+});
+
+const notificationsButtons = () => document.querySelectorAll('[data-qa="banner"][class*=notifications] button');
+
+let count = 0;
+const timer = setInterval(() => {
+ const $btns = notificationsButtons();
+
+ console.log('>> Notification buttons', $btns);
+
+ Array.from($btns)
+ .filter($btn => $btn.textContent.match(/enable.*notification/))
+ .forEach($btn => {
+ $btn && $btn.click();
+ clearInterval(timer);
+ });
+
+ if (count > 10) clearInterval(timer);
+ count += 1;
+}, 1000);
+
diff --git a/config/qutebrowser/greasemonkey/whatsapp.js b/config/qutebrowser/greasemonkey/whatsapp.js
new file mode 100644
index 0000000..3bd1ab5
--- /dev/null
+++ b/config/qutebrowser/greasemonkey/whatsapp.js
@@ -0,0 +1,57 @@
+// ==UserScript==
+// @name Whatsapp helper
+// @namespace phenax.github.io
+// @version 0.0.0
+// @description Whatsapp helper
+// @author Akshay Nair
+// @match *://web.whatsapp.com/*
+// ==/UserScript==
+
+
+const getPosition = $el => parseInt($el.style.transform.match(/translateY\((.*)\)/)[1], 10);
+
+const getContacts = () => Array.from(document
+ .querySelectorAll('#pane-side > div:nth-child(1) > div > div > div'))
+ .sort(($a, $b) => getPosition($a) - getPosition($b))
+
+const getNext = () => {
+ const list = getContacts();
+ const current_selected = list.findIndex($el => !!$el.querySelector('[aria-selected=true]'));
+ return list[current_selected + 1];
+};
+const getPrev = () => {
+ const list = getContacts();
+ const current_selected = list.findIndex($el => !!$el.querySelector('[aria-selected=true]'));
+ return current_selected <= 0 ? null : list[current_selected - 1];
+};
+
+const clickableElem = $el => $el && $el.querySelector('[aria-selected] > div');
+
+const click = $el => $el && $el.dispatchEvent(new MouseEvent('mousedown', {
+ screenX: 5,
+ screenY: 5,
+ bubbles: true,
+ cancellable: true,
+ relatedTarget: $el,
+}));
+
+const keys = {
+ j: () => click(clickableElem(getNext())),
+ k: () => click(clickableElem(getPrev())),
+};
+
+document.addEventListener('keydown', (e) => {
+ if (keys[e.key] && e.ctrlKey) {
+ keys[e.key]();
+ }
+});
+
+const timer = setInterval(() => {
+ if (Notification.permission !== 'default') {
+ clearInterval(timer);
+ return;
+ }
+
+ Notification.requestPermission().then(console.log);
+}, 1000);
+
diff --git a/config/qutebrowser/greasemonkey/youtube-ad.js b/config/qutebrowser/greasemonkey/youtube-ad.js
new file mode 100644
index 0000000..f545309
--- /dev/null
+++ b/config/qutebrowser/greasemonkey/youtube-ad.js
@@ -0,0 +1,51 @@
+// ==UserScript==
+// @name Hide youtube google ad
+// @namespace vince.youtube
+// @version 2.4.1
+// @description hide youtube google ad,auto click "skip ad"
+// @author vince ding
+// @match *://www.youtube.com/*
+// ==/UserScript==
+
+(function() {
+ 'use strict';
+ var closeAd=function (){
+ var css = '.video-ads .ad-container .adDisplay,#player-ads,.ytp-ad-module,.ytp-ad-image-overlay{ display: none!important; }',
+ head = document.head || document.getElementsByTagName('head')[0],
+ style = document.createElement('style');
+
+ style.type = 'text/css';
+ if (style.styleSheet){
+ style.styleSheet.cssText = css;
+ } else {
+ style.appendChild(document.createTextNode(css));
+ }
+
+ head.appendChild(style);
+ };
+ var skipInt;
+ var log=function(msg){
+ console.log(msg);
+ };
+ var skipAd=function(){
+ //ytp-ad-preview-text
+ //ytp-ad-skip-button
+ var skipbtn=document.querySelector(".ytp-ad-skip-button.ytp-button")||document.querySelector(".videoAdUiSkipButton ");
+ //var skipbtn=document.querySelector(".ytp-ad-skip-button ")||document.querySelector(".videoAdUiSkipButton ");
+ if(skipbtn){
+ skipbtn=document.querySelector(".ytp-ad-skip-button.ytp-button")||document.querySelector(".videoAdUiSkipButton ");
+ log("skip");
+ skipbtn.click();
+ if(skipInt) {clearTimeout(skipInt);}
+ skipInt=setTimeout(skipAd,500);
+ }else{
+ log("checking...");
+ if(skipInt) {clearTimeout(skipInt);}
+ skipInt=setTimeout(skipAd,500);
+ }
+ };
+
+ closeAd();
+ skipAd();
+
+})();
diff --git a/config/qutebrowser/greasemonkey/youtube-no-autoplay.js b/config/qutebrowser/greasemonkey/youtube-no-autoplay.js
new file mode 100644
index 0000000..80a763a
--- /dev/null
+++ b/config/qutebrowser/greasemonkey/youtube-no-autoplay.js
@@ -0,0 +1,111 @@
+// ==UserScript==
+// @author James Edward Lewis II
+// @namespace greasyfork.org
+// @name Disable audio/video autoplay
+// @description Ensures that HTML5 audio and video elements do not autoplay, based on http://diveintohtml5.info/examples/disable_video_autoplay.user.js
+// @icon http://diveintohtml5.info/favicon.ico
+// @include *
+// @grant none
+// @version 1.2.0
+// @run-at document-end
+// @copyright 2015 James Edward Lewis II
+// @match *://www.youtube.com/*
+// ==/UserScript==
+
+var arVideos = document.getElementsByTagName('video'), arAudio = document.getElementsByTagName('audio'), vl = arVideos.length,
+ al = arAudio.length, loc = window.document.location.toString(), ytPlayer = document.getElementById('movie_player'),
+ ytVars = ytPlayer ? ytPlayer.getAttribute('flashvars') : '', arEmbeds = document.getElementsByTagName('embed'),
+ el = arEmbeds.length, ytPause = document.getElementsByClassName('ytp-button-pause'),
+ cb_load = function cb_load(fnc) { // Just for those who still use IE7Pro; IE8 and earlier do not support addEventListener: https://gist.github.com/eduardocereto/955642
+ 'use strict';
+ if (window.addEventListener) { // W3C model
+ window.addEventListener('load', fnc, false);
+ return true;
+ } else if (window.attachEvent) { // Microsoft model
+ return window.attachEvent('onload', fnc);
+ } else { // Browser doesn't support W3C or MSFT model, go on with traditional
+ if (typeof window.onload === 'function') {
+ // Object already has a function on traditional
+ // Let's wrap it with our own function inside another function
+ fnc = (function wrap(f1, f2) {
+ return function wrapped() {
+ f1.apply(this, arguments);
+ f2.apply(this, arguments);
+ };
+ }(window.onload, fnc));
+ }
+ window.onload = fnc;
+ return true;
+ }
+ }, nodeRefresh = function nodeRefresh(nod) {
+ 'use strict';
+ var orig = nod.style.display;
+ nod.style.display = (orig === 'none') ? 'block' : 'none';
+ nod.style.display = orig;
+ }, vidStop = function vidStop(vid) {
+ 'use strict';
+ vid.pause();
+ vid.oncanplay = null;
+ vid.onplay = null;
+ }, stopVideo, i;
+for (i = vl - 1; i >= 0; i--) arVideos[i].autoplay = false;
+for (i = al - 1; i >= 0; i--) arAudio[i].autoplay = false;
+
+// attempted workaround for Vine and modern YouTube, except on YouTube playlists, based on https://greasyfork.org/en/scripts/6487-pause-all-html5-videos-on-load
+if (!loc.match(/^https?\:\/\/(?:\w+\.)?youtube(?:-nocookie)?\.com(?:\:80)?\/watch\?.*list=[A-Z]/i)) {
+ stopVideo = function stopVideo() {
+ 'use strict';
+ var autoPlay, i, yl = ytPause ? +ytPause.length : 0, vidStopper = function vidStopper() {vidStop(autoPlay);};
+ if (yl) { // This comes from Stop Youtube HTML5 Autoplay by Leslie P. Polzer of PORT ZERO <polzer@port-zero.com>: http://www.port-zero.com/en/chrome-plugin-stop-html5-autoplay/
+ for (i = yl - 1; i >= 0; i--) ytPause[i].click();
+ } else {
+ for (i = vl - 1; i >= 0; i--) {
+ autoPlay = arVideos[i];
+ if (autoPlay && autoPlay.readyState === 4) {
+ vidStop(autoPlay);
+ autoPlay.currentTime = 0;
+ nodeRefresh(autoPlay);
+ } else {
+ autoPlay.oncanplay = vidStopper;
+ autoPlay.onplay = vidStopper;
+ }
+ }
+ for (i = al - 1; i >= 0; i--) {
+ autoPlay = arAudio[i];
+ if (autoPlay && autoPlay.readyState === 4) {
+ vidStop(autoPlay);
+ autoPlay.currentTime = 0;
+ nodeRefresh(autoPlay);
+ } else {
+ autoPlay.oncanplay = vidStopper;
+ autoPlay.onplay = vidStopper;
+ }
+ }
+ }
+ };
+ if (!loc.match(/^https?\:\/\/(?:\w+\.)?youtube(?:-nocookie)?\.com[\:\/]/i) || !vl) cb_load(stopVideo);
+ else cb_load(function delayedYTstop() {'use strict'; setTimeout(stopVideo, 0);});
+}
+
+// attempted workaround for old Flash-based YouTube, for older browsers, based on http://userscripts-mirror.org/scripts/review/100858
+if (loc.match(/^https?\:\/\/(?:\w+\.)?youtube(?:-nocookie)?\.com[\:\/]/i) && loc.indexOf('list=') === -1 && !vl && ytVars)
+ cb_load(function delayedYTstop() {'use strict'; setTimeout(function stopOldYT() { // in video page : profile page
+ ytPlayer.setAttribute('flashvars', (loc.indexOf('/watch') !== -1) ? 'autoplay=0&' + ytVars : ytVars.replace(/autoplay=1/i, 'autoplay=0'));
+ ytPlayer.src += (ytPlayer.src.indexOf('#') === -1) ? '#' : '&autoplay=0';
+ nodeRefresh(ytPlayer);
+ }, 0);});
+
+// attempted workaround for Billy-based video players on Tumblr, based on https://greasyfork.org/en/scripts/921-tumblr-disable-autoplay
+// which is also the source of all the CSSOM tomfoolery elsewhere in this script
+if (loc.match(/^https?\:\/\/(?:\w+\.)*tumblr\.com[\:\/]/i))
+ cb_load(function stopBillyTumblr() {
+ 'use strict';
+ var autoPlay, i;
+ for (i = el - 1; i >= 0; i--) {
+ autoPlay = arEmbeds[i];
+ if (autoPlay && autoPlay.src.match(/autoplay=true/gi)) {
+ autoPlay.src = autoPlay.src.replace(/autoplay=true/gi, 'autoplay=false');
+ nodeRefresh(autoPlay);
+ }
+ }
+ });
diff --git a/config/qutebrowser/homepage/index.html b/config/qutebrowser/homepage/index.html
new file mode 100644
index 0000000..0578cb0
--- /dev/null
+++ b/config/qutebrowser/homepage/index.html
@@ -0,0 +1,258 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width" />
+ <title>New tab</title>
+ <style>
+ :root {
+ --col-primary: #14121e;
+ --col-accent: #5e4ab3;
+ --col-accent-light: #8e7ae3;
+ }
+ html, body {
+ margin: 0;
+ padding: 0;
+ background-color: var(--col-primary);
+ color: #fff;
+ font-family: JetBrains Mono, sans-serif;
+ }
+ html, body, body * { box-sizing: border-box }
+
+ .hotkey-display {
+ position: fixed;
+ right: 0;
+ top: 0;
+ padding: 0.3em 0.5em;
+ background-color: var(--col-primary);
+ color: #888;
+ }
+ </style>
+ <script>
+ // Library
+ const $ = document.querySelector.bind(document);
+ const h = (el, props, children) => {
+ const $el = Object.assign(document.createElement(el), props);
+ children.forEach($ch => $el.appendChild($ch));
+ return $el;
+ };
+ const text = str => {
+ const $t = document.createTextNode(str);
+ return $t;
+ };
+ const render = ($el, $tree) => {
+ while($el.firstChild) $el.removeChild($el.firstChild);
+ $el.appendChild($tree);
+ };
+
+ const HotKeys = {
+ hooks: {},
+ accum: '',
+ $el: null,
+ bind: (key, action) => (HotKeys.hooks[key] = { action }),
+ init: () => {
+ HotKeys.$el = h('div', { className: 'hotkey-display' }, [text('')]);
+ document.body.appendChild(HotKeys.$el);
+
+ document.addEventListener('keypress', e => {
+ const maxkeylen = Math.max(...Object.keys(HotKeys.hooks).map(x => x.length));
+
+ if(/[A-Za-z]/.test(e.key) && HotKeys.accum.length + 1 <= maxkeylen) {
+ HotKeys.accum += e.key;
+ } else {
+ HotKeys.accum = '';
+ }
+
+ render(HotKeys.$el, text(`${HotKeys.accum}`));
+
+ if (HotKeys.hooks[HotKeys.accum])
+ HotKeys.hooks[HotKeys.accum].action({ key: HotKeys.accum, event: e });
+ });
+ },
+ };
+ </script>
+ </head>
+ <body>
+ <div class="home">
+ <div id="clock" style='width: 100%;'></div>
+ <div id="grid" style='width: 100%;'></div>
+ </div>
+
+
+ <!-- Init -->
+ <script>
+ HotKeys.init();
+ </script>
+
+
+ <!-- Date/Time -->
+ <style>
+ .home {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ font-weight: 100;
+ min-height: 100vh;
+ max-width: 1300px;
+ margin: 0 auto;
+ padding: 2em 0;
+ }
+ .home-time {
+ font-size: 4em;
+ letter-spacing: -2px;
+ }
+ .home-date {
+ font-size: 2em;
+ color: #aaa;
+ letter-spacing: -1px;
+ }
+ </style>
+ <script>
+ const $clock = $('#clock');
+
+ const formatTime = date => {
+ const format = new Intl.DateTimeFormat('en-IN', {
+ hour12: true,
+ hour: 'numeric', minute: 'numeric'
+ });
+
+ return format.format(date);
+ };
+ const formatDate = date => {
+ const format = new Intl.DateTimeFormat('en-IN', {
+ weekday: 'long', month: 'short', day: 'numeric',
+ });
+
+ return format.format(date);
+ };
+
+ function renderDateTime() {
+ const d = new Date();
+
+ // Update every second
+ setInterval(renderDateTime, 20 * 1000);
+
+ render($clock, h('div', {}, [
+ h('div', { className: 'home-time' }, [ text(formatTime(d)) ]),
+ h('div', { className: 'home-date' }, [ text(formatDate(d)) ]),
+ ]));
+ }
+
+ renderDateTime();
+ </script>
+
+
+
+ <!-- Links -->
+ <style>
+ .grid {
+ display: flex;
+ flex-direction: column;
+ padding: 3em 4em;
+ line-height: 1.4em;
+ font-size: 0.9em;
+
+ --block-margin-h: 0.5em;
+ }
+
+ .grid a {
+ color: var(--col-accent);
+ text-decoration: none;
+ }
+
+ .grid-block {
+ background-color: #0f0c19;
+ box-shadow: 1px 1px 5px 0.2px #000;
+ padding: 2em 3em;
+ color: #ddd;
+ margin: 0 var(--block-margin-h) 1em;
+ width: 100%;
+ text-align: left;
+ }
+
+ .grid-block-title {
+ padding-bottom: 0.5em;
+ }
+
+ .link-shortcut {
+ display: inline-block;
+ margin-right: 1em;
+ font-weight: bold;
+ color: var(--col-accent-light);
+ }
+
+ @media (min-width: 800px) {
+ .grid {
+ flex-direction: row;
+ flex-wrap: wrap;
+ }
+ .grid-block {
+ width: calc(50% - var(--block-margin-h)*2);
+ }
+ }
+ @media (min-width: 1300px) {
+ .grid {
+ flex-direction: row;
+ flex-wrap: nowrap;
+ }
+ }
+
+ </style>
+ <script>
+ const getBlock = ({ title, links }) => h('div', { className: 'grid-block' }, [
+ h('div', { className: 'grid-block-title' }, [ title ]),
+ h('div', {}, links.map(({ label, link, shortcut }) => {
+ HotKeys.bind(shortcut, () => (window.location.href = link));
+
+ return h('div', {}, [
+ h('a', { href: link }, [
+ h('span', { className: 'link-shortcut' }, [ text(`[${shortcut}]`) ]),
+ label,
+ ]),
+ ]);
+ })),
+ ]);
+
+ const blocks = [
+ {
+ title: text('Reddit'),
+ links: [
+ { shortcut: 'rs', label: text('r/suckless'), link: 'https://reddit.com/r/suckless' },
+ { shortcut: 'ru', label: text('r/unixporn'), link: 'https://reddit.com/r/unixporn' },
+ { shortcut: 'rp', label: text('r/ps4'), link: 'https://reddit.com/r/ps4' },
+ { shortcut: 'rc', label: text('r/cursedcomments'), link: 'https://www.reddit.com/r/cursedcomments' },
+ ],
+ },
+ {
+ title: text('Dev'),
+ links: [
+ { shortcut: 'gh', label: text('Github'), link: 'https://github.com' },
+ { shortcut: 'gt', label: text('GH Trending'), link: 'https://github.com/trending' },
+ { shortcut: 'dx', label: text('Xlib'), link: 'https://tronche.com/gui/x/xlib/' },
+ { shortcut: 'su', label: text('Suckless.org'), link: 'https://suckless.org' },
+ ],
+ },
+ {
+ title: text('Blogs'),
+ links: [
+ { shortcut: 'bm', label: text('Hacks mozilla'), link: 'https://hacks.mozilla.org/' },
+ { shortcut: 'ct', label: text('CSS Tricks'), link: 'https://css-tricks.com/' },
+ { shortcut: 'dw', label: text('David Walsh'), link: 'https://davidwalsh.name/' },
+ ],
+ },
+ {
+ title: text('Others'),
+ links: [
+ { shortcut: 'yo', label: text('Youtube'), link: 'https://youtube.com' },
+ { shortcut: 'tw', label: text('Twitter'), link: 'https://twitter.com/' },
+ ],
+ },
+ ];
+
+ const $grid = $('#grid');
+ render($grid, h('div', { className: 'grid' }, blocks.map(getBlock)));
+ </script>
+ </body>
+</html>
diff --git a/config/qutebrowser/quickmarks b/config/qutebrowser/quickmarks
new file mode 100644
index 0000000..a06758b
--- /dev/null
+++ b/config/qutebrowser/quickmarks
@@ -0,0 +1,17 @@
+Basecamp https://3.basecamp.com/3689808/
+Whatsapp https://web.whatsapp.com/
+My Github https://github.com/phenax
+Github trending https://github.com/trending
+Gmail:personal https://mail.google.com/mail/u/0/#inbox
+Gmail:work https://mail.google.com/mail/u/1/#inbox
+Open proxy gitlab https://gitlab.com/shaadi/proxy/open-proxy-platform
+Flutter docs https://api.flutter.dev/
+Xlib docs https://tronche.com/gui/x/xlib/
+Suckless https://suckless.org/
+Reverse shell cheatsheet http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
+Linux Privilege Escalation https://book.hacktricks.xyz/linux-unix/linux-privilege-escalation-checklist
+GTFOBins https://gtfobins.github.io/
+Reverse Shell Cheat Sheet https://highon.coffee/blog/reverse-shell-cheat-sheet/
+Exploit Database https://www.exploit-db.com/
+OSINT Framework https://osintframework.com/
+Gmail:invideo https://mail.google.com/mail/u/2/#inbox/FMfcgxwKjdpcWbFMBtRcBWPWHWTBzhph
diff --git a/config/qutebrowser/security.py b/config/qutebrowser/security.py
new file mode 100644
index 0000000..f503b6d
--- /dev/null
+++ b/config/qutebrowser/security.py
@@ -0,0 +1,86 @@
+import random
+from qutebrowser.config.configfiles import ConfigAPI
+from qutebrowser.config.config import ConfigContainer
+config = config
+c = c
+
+def compose(*args):
+ return ' ;; '.join(args)
+
+def enable(s, ask = False):
+ return 'set ' + s + ' ' + ('ask' if ask else 'True')
+
+def disable(s):
+ return 'set ' + s + ' False'
+
+
+def rand_numstr(a, b):
+ return str(random.randint(a, b))
+
+def random_version(a, b):
+ return rand_numstr(a, b) + '.' + rand_numstr(0, 100)
+
+def random_useragent():
+ chrome_version = random_version(77, 84)
+ # firefox_version = random_version(77, 80)
+ build_version = random_version(1000, 3000)
+
+ agents = [
+ 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML; like Gecko) Chromium/' + chrome_version + '.0.4044.138 Chrome/' + chrome_version + '.' + build_version + ' Safari/{webkit_version}',
+ 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/' + chrome_version + '.0.4147.89 Safari/{webkit_version} Hola/1.173.900',
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/' + chrome_version + '.0.2623.112 Safari/{webkit_version}'
+ # 'Mozilla/5.0 (Linux x86_64; rv:78.0) Gecko/20100101 Firefox/' + firefox_version,
+ ]
+ return agents[random.randint(0, 2)]
+
+c.content.cookies.accept = 'no-3rdparty'
+c.content.geolocation = 'ask'
+c.content.headers.do_not_track = True
+c.content.headers.referer = 'never'
+c.content.headers.user_agent = random_useragent()
+c.content.host_blocking.enabled = True
+c.content.media.audio_capture = 'ask'
+c.content.media.video_capture = 'ask'
+c.content.ssl_strict = 'ask'
+c.content.desktop_capture = 'ask'
+c.content.mouse_lock = 'ask'
+c.content.javascript.can_access_clipboard = True
+c.content.canvas_reading = True
+# c.content.fullscreen.window = True # Fullscreen fixed to window size
+
+# Tor
+c.aliases['tor-enable'] = 'set content.proxy "socks://localhost:9050"'
+c.aliases['tor-disable'] = 'config-unset content.proxy'
+c.aliases['tor-change'] = 'spawn --userscript tor_identity'
+
+# Fingerprinting feature switches
+c.aliases['clipboard-disable'] = disable('content.javascript.can_access_clipboard')
+c.aliases['clipboard-enable'] = enable('content.javascript.can_access_clipboard')
+c.aliases['canvas-disable'] = disable('content.canvas_reading')
+c.aliases['canvas-enable'] = enable('content.canvas_reading')
+c.aliases['webgl-disable'] = disable('content.webgl')
+c.aliases['webgl-enable'] = enable('content.webgl')
+c.aliases['location-disable'] = disable('content.geolocation')
+c.aliases['location-enable'] = enable('content.geolocation', ask=True)
+
+# Incognito identity switch
+c.aliases['change-identity'] = compose('config-source', c.aliases['tor-change'])
+
+def set_incognito(mode):
+ tor = 'enable' if mode else 'disable'
+ features = 'disable' if mode else 'enable'
+ return compose(
+ 'config-source',
+ c.aliases['tor-' + tor],
+ c.aliases['clipboard-' + features],
+ c.aliases['location-' + features],
+ c.aliases['canvas-' + features],
+ c.aliases['webgl-' + features],
+ )
+
+c.aliases['incognito-enable'] = set_incognito(True)
+c.aliases['incognito-disable'] = set_incognito(False)
+
+
+c.aliases['ask-useragent'] = 'spawn --userscript pick_useragent'
+
diff --git a/config/qutebrowser/setup.sh b/config/qutebrowser/setup.sh
new file mode 100755
index 0000000..b6b343d
--- /dev/null
+++ b/config/qutebrowser/setup.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+mkdir -p /tmp/backupDir;
+
+link() {
+ if [[ -f "$2" ]]; then
+ return 0;
+ else
+ mv "$2" /tmp/backupDir/ 2> /dev/null
+ ln -s "$1" "$2";
+ fi
+}
+
+# Create userscripts symlink
+link ~/.config/qutebrowser/userscripts ~/.local/share/qutebrowser/userscripts;
+
+# Create greasemonkey symlink
+link ~/.config/qutebrowser/greasemonkey ~/.local/share/qutebrowser/greasemonkey;
+
+# Create sessions symlink
+link ~/.work-config/qutebrowser/sessions ~/.local/share/qutebrowser/sessions;
+
diff --git a/config/qutebrowser/styles/adblocker.css b/config/qutebrowser/styles/adblocker.css
new file mode 100644
index 0000000..2fa6b83
--- /dev/null
+++ b/config/qutebrowser/styles/adblocker.css
@@ -0,0 +1,108 @@
+/*
+ * This file can be used to apply a style to all web pages you view
+ * Rules without !important are overruled by author rules if the
+ * author sets any. Rules with !important overrule author rules.
+ */
+
+/* You can find the latest version of this ad blocking css at:
+ * http://www.floppymoose.com
+ * hides many ads by preventing display of images that are inside
+ * links when the link HREF contans certain substrings.
+ */
+
+A:link[HREF*="addata"] IMG,
+A:link[HREF*="ad."] IMG,
+A:link[HREF*="ads."] IMG,
+A:link[HREF*="/ad"] IMG,
+A:link[HREF*="/A="] IMG,
+A:link[HREF*="/click"] IMG,
+A:link[HREF*="?click"] IMG,
+A:link[HREF*="?banner"] IMG,
+A:link[HREF*="=click"] IMG,
+A:link[HREF*="clickurl="] IMG,
+A:link[HREF*=".atwola."] IMG,
+A:link[HREF*="spinbox."] IMG,
+A:link[HREF*="transfer.go"] IMG,
+A:link[HREF*="adfarm"] IMG,
+A:link[HREF*="adSpace"] IMG,
+A:link[HREF*="adserve"] IMG,
+A:link[HREF*=".banner"] IMG,
+A:link[HREF*="bluestreak"] IMG,
+A:link[HREF*="doubleclick"] IMG,
+A:link[HREF*="/rd."] IMG,
+A:link[HREF*="/0AD"] IMG,
+A:link[HREF*=".falkag."] IMG,
+A:link[HREF*="trackoffer."] IMG,
+A:link[HREF*="casalemedia."] IMG,
+A:link[HREF*="valueclick."] IMG,
+A:link[HREF*="betterbasketball."] IMG,
+A:link[HREF*="sponsors.phtml"] IMG,
+A:link[HREF*="realgmtix.phtml"] IMG,
+A:link[HREF*="BurstingPipe"] IMG,
+A:link[HREF*="ebayobjects"] IMG,
+A:link[HREF*="tracksponsor."] IMG { display: none ! important }
+
+/* disable ad iframes */
+IFRAME[SRC*="addata"],
+IFRAME[SRC*="ad."],
+IFRAME[SRC*="ads."],
+IFRAME[SRC*="/ad"],
+IFRAME[SRC*="/A="],
+IFRAME[SRC*="/click"],
+IFRAME[SRC*="?click"],
+IFRAME[SRC*="?banner"],
+IFRAME[SRC*="=click"],
+IFRAME[SRC*="clickurl="],
+IFRAME[SRC*=".atwola."],
+IFRAME[SRC*="spinbox."],
+IFRAME[SRC*="transfer.go"],
+IFRAME[SRC*="adfarm"],
+IFRAME[SRC*="adSpace"],
+IFRAME[SRC*="adserve"],
+IFRAME[SRC*="adjuggler"],
+IFRAME[SRC*=".banner"],
+IFRAME[SRC*="bluestreak"],
+IFRAME[SRC*="doubleclick"],
+IFRAME[SRC*="/rd."],
+IFRAME[SRC*="/0AD"],
+IFRAME[SRC*=".falkag."],
+IFRAME[SRC*="trackoffer."],
+IFRAME[SRC*="connextra."],
+IFRAME[ID*="merchandisingMERC"],
+IFRAME[SRC*="tracksponsor."] { display: none ! important }
+
+
+/* miscellaneous different blocking rules to block some stuff that gets through */
+
+A:link[onmouseover*="AdSolution"] IMG,
+*[class=sponsors],
+*[class=sp_links],
+*[class=advertising],
+*[ID=sponsors],
+*[ID=ad],
+*[ID=inlinead],
+*[ID=ad_creative],
+*[ID=contextualLinks],
+IMG[SRC*=".msads."] { display: none ! important }
+
+
+/* turning some false positives back off */
+
+A:link[HREF*="/add"] IMG,
+A:link[HREF*="/adsl"] IMG,
+A:link[HREF*="thread."] IMG,
+A:link[HREF*="download."] IMG,
+A:link[HREF*="downloads."] IMG,
+A:link[HREF*="netflix.com/AddToQueue"] IMG,
+A:link[HREF*="load."],
+A:link[HREF*="loads."],
+IFRAME[SRC*="load."],
+IFRAME[SRC*="loads."],
+A:link[HREF*="click.mp3"] IMG { display: inline ! important }
+
+
+/*
+ * For more examples see http://www.mozilla.org/unix/customizing.html
+ */
+
+
diff --git a/config/qutebrowser/styles/dark.css b/config/qutebrowser/styles/dark.css
new file mode 100644
index 0000000..86b65fa
--- /dev/null
+++ b/config/qutebrowser/styles/dark.css
@@ -0,0 +1,23 @@
+/*html, body, body * {*/
+ /*background-color: #111 !important;*/
+ /*color: #ddd !important;*/
+/*}*/
+
+/*body {*/
+html, body, body * {
+ color: #d7d7d8 !important;
+ background-color: #0f0c19 !important;
+}
+
+a {
+ color: #4e3aA3 !important;
+}
+
+code {
+ /*color: #d5dada;*/
+ /*background: #313231 !important;*/
+}
+
+figcaption {
+ color: #d7d7d8 !important;
+}
diff --git a/config/qutebrowser/styles/default.css b/config/qutebrowser/styles/default.css
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/config/qutebrowser/styles/default.css
diff --git a/config/qutebrowser/styles/scrollbar.css b/config/qutebrowser/styles/scrollbar.css
new file mode 100644
index 0000000..2e58110
--- /dev/null
+++ b/config/qutebrowser/styles/scrollbar.css
@@ -0,0 +1,33 @@
+:root {
+ --scroll-bar-color: #aabaca;
+}
+
+::-webkit-scrollbar {
+ width: 4px;
+ height: 8px;
+}
+
+::-webkit-scrollbar-track:vertical {
+ background: black;
+ border-left: 1px solid black;
+}
+
+::-webkit-scrollbar-thumb:vertical {
+ background: var(--scroll-bar-color);
+ border-left: 1px solid black;
+}
+
+::-webkit-scrollbar-track:horizontal {
+ background: var(--scroll-bar-color);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:horizontal {
+ background: var(--scroll-bar-color);
+ border-radius: 4px;
+ box-shadow: inset 0 0 8px black;
+}
+
+::-webkit-scrollbar-corner {
+ background: silver;
+}
diff --git a/config/qutebrowser/ui.py b/config/qutebrowser/ui.py
new file mode 100644
index 0000000..5259115
--- /dev/null
+++ b/config/qutebrowser/ui.py
@@ -0,0 +1,73 @@
+import subprocess
+from qutebrowser.config.configfiles import ConfigAPI
+from qutebrowser.config.config import ConfigContainer
+config = config
+c = c
+
+def read_xresources(prefix):
+ props = {}
+ x = subprocess.run(['xrdb', '-query'], stdout=subprocess.PIPE)
+ lines = x.stdout.decode().split('\n')
+ for line in filter(lambda l : l.startswith(prefix), lines):
+ prop, _, value = line.partition(':\t')
+ props[prop] = value
+ return props
+
+xresources = read_xresources('*')
+
+c.fonts.default_family = 'JetBrains Mono'
+c.fonts.default_size = '12px'
+c.colors.webpage.prefers_color_scheme_dark = True
+c.colors.webpage.bg = "white"
+c.colors.webpage.darkmode.enabled = True
+
+## Hints
+c.colors.hints.bg = 'yellow'
+c.hints.border = '1px solid #000000'
+
+
+# c.colors.statusbar.normal.bg = xresources['*.background']
+## Context menu styles
+c.colors.contextmenu.menu.bg = xresources['*.background']
+c.colors.contextmenu.menu.fg = xresources['*.foreground']
+c.colors.contextmenu.selected.bg = xresources['*.accent']
+c.colors.contextmenu.selected.fg = xresources['*.foreground']
+
+## Completion
+c.colors.completion.category.bg = xresources['*.background']
+c.colors.completion.category.fg = xresources['*.accent']
+c.colors.completion.even.bg = xresources['*.background']
+c.colors.completion.odd.bg = xresources['*.color0']
+c.colors.completion.item.selected.fg = xresources['*.foreground']
+c.colors.completion.item.selected.bg = xresources['*.accent']
+c.colors.completion.item.selected.border.bottom = xresources['*.accent']
+c.colors.completion.item.selected.border.top = xresources['*.accent']
+c.colors.statusbar.insert.bg = 'red'
+c.colors.statusbar.insert.fg = 'white'
+
+## Tabs
+c.tabs.padding = { 'bottom': 2, 'top': 2, 'left': 5, 'right': 5 }
+
+## Unselected tabs
+c.colors.tabs.even.bg = xresources['*.background']
+c.colors.tabs.even.fg = xresources['*.foreground']
+c.colors.tabs.odd.bg = c.colors.tabs.even.bg
+c.colors.tabs.odd.fg = c.colors.tabs.even.fg
+
+## Selected tab
+c.colors.tabs.selected.even.bg = xresources['*.accent']
+c.colors.tabs.selected.even.fg = xresources['*.foreground']
+c.colors.tabs.selected.odd.bg = c.colors.tabs.selected.even.bg
+c.colors.tabs.selected.odd.fg = c.colors.tabs.selected.even.fg
+
+# Pinned tab
+c.colors.tabs.pinned.even.bg = xresources['*.background']
+c.colors.tabs.pinned.even.fg = c.colors.tabs.even.fg
+c.colors.tabs.pinned.odd.bg = xresources['*.background']
+c.colors.tabs.pinned.odd.fg = c.colors.tabs.odd.fg
+
+c.colors.tabs.pinned.selected.even.bg = c.colors.tabs.selected.even.bg
+c.colors.tabs.pinned.selected.even.fg = c.colors.tabs.selected.even.fg
+c.colors.tabs.pinned.selected.odd.bg = c.colors.tabs.selected.odd.bg
+c.colors.tabs.pinned.selected.odd.fg = c.colors.tabs.selected.odd.fg
+
diff --git a/config/qutebrowser/userscripts/dl_music b/config/qutebrowser/userscripts/dl_music
new file mode 100755
index 0000000..39e6ac0
--- /dev/null
+++ b/config/qutebrowser/userscripts/dl_music
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+cd ~/Downloads/music/untagged;
+
+~/scripts/notify.sh "Downloading audio in the background...";
+
+youtube-dl \
+ --add-metadata \
+ --ignore-errors \
+ --output '%(title)s.%(ext)s' \
+ --extract-audio \
+ --yes-playlist \
+ "$QUTE_URL";
+
+~/scripts/notify.sh "Download complete";
+
diff --git a/config/qutebrowser/userscripts/format_json b/config/qutebrowser/userscripts/format_json
new file mode 100755
index 0000000..1977078
--- /dev/null
+++ b/config/qutebrowser/userscripts/format_json
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+set -euo pipefail
+#
+# Behavior:
+# Userscript for qutebrowser which will take the raw JSON text of the current
+# page, format it using `jq`, will add syntax highlighting using `pygments`,
+# and open the syntax highlighted pretty printed html in a new tab. If the file
+# is larger than 10MB then this script will only indent the json and will forego
+# syntax highlighting using pygments.
+#
+# In order to use this script, just start it using `spawn --userscript` from
+# qutebrowser. I recommend using an alias, e.g.
+#
+# :config-dict-add aliases json "spawn --userscript /path/to/json_format"
+#
+# Note that the color style defaults to monokai, but a different pygments style
+# can be passed as the first parameter to the script. A full list of the pygments
+# styles can be found at: https://help.farbox.com/pygments.html
+#
+# Bryan Gilbert, 2017
+
+# do not run pygmentize on files larger than this amount of bytes
+MAX_SIZE_PRETTIFY=10485760 # 10 MB
+# default style to monokai if none is provided
+STYLE=${1:-fruity}
+
+TEMP_FILE="$(mktemp --suffix .html)"
+jq . "$QUTE_TEXT" >"$TEMP_FILE"
+
+# try GNU stat first and then OSX stat if the former fails
+FILE_SIZE=$(
+ stat --printf="%s" "$TEMP_FILE" 2>/dev/null ||
+ stat -f%z "$TEMP_FILE" 2>/dev/null
+)
+
+if [ "$FILE_SIZE" -lt "$MAX_SIZE_PRETTIFY" ]; then
+ pygmentize -l json -f html -O full,style="$STYLE" <"$TEMP_FILE" >"${TEMP_FILE}_"
+ mv -f "${TEMP_FILE}_" "$TEMP_FILE"
+fi
+
+# send the command to qutebrowser to open the new file containing the formatted json
+echo "open -t file://$TEMP_FILE" >> "$QUTE_FIFO"
diff --git a/config/qutebrowser/userscripts/nodemon b/config/qutebrowser/userscripts/nodemon
new file mode 100755
index 0000000..99da415
--- /dev/null
+++ b/config/qutebrowser/userscripts/nodemon
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+WATCH_DIR="$1";
+EXTENSIONS="${2:-"js,html,css"}";
+
+nodemon --exec "echo 'reload' >> $QUTE_FIFO" -e $EXTENSIONS -w "$WATCH_DIR" &
+
+~/scripts/notify.sh "[$PID] Watching $WATCH_DIR for $EXTENSIONS...";
+
+disown;
+
diff --git a/config/qutebrowser/userscripts/open_downloads b/config/qutebrowser/userscripts/open_downloads
new file mode 100755
index 0000000..c4098a9
--- /dev/null
+++ b/config/qutebrowser/userscripts/open_downloads
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+sensible-terminal -e ~/.bin/with_zsh "lf ${QUTE_DOWNLOAD_DIR:-$HOME/Downloads}";
+
diff --git a/config/qutebrowser/userscripts/pick_useragent b/config/qutebrowser/userscripts/pick_useragent
new file mode 100755
index 0000000..dce67e7
--- /dev/null
+++ b/config/qutebrowser/userscripts/pick_useragent
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+trim() { sed '/^$/ d'; }
+
+useragents=`echo "
+Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
+Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0
+Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0
+Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
+
+Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
+Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
+Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36
+Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Brave Chrome/76.0.3809.132 Safari/537.36
+
+Mozilla/5.0 (Linux; U; Android 2.2) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
+Mozilla/5.0 (Linux; Android 6.0.1; RedMi Note 5 Build/RB3N5C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3440.91 Mobile Safari/537.36
+Mozilla/5.0 (Linux; Android 7.0; K10000 Max) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Mobile Safari/537.36 Brave/74
+
+" | trim`;
+
+ua=`echo -e "$useragents" | dmenu -p "User-agent ::"`;
+
+[[ -z "$ua" ]] && exit 0;
+
+echo "set content.headers.user_agent '$ua'" >> "$QUTE_FIFO";
+
diff --git a/config/qutebrowser/userscripts/tor_identity b/config/qutebrowser/userscripts/tor_identity
new file mode 100755
index 0000000..bf23014
--- /dev/null
+++ b/config/qutebrowser/userscripts/tor_identity
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+mypass=$(pass show Tor/client);
+
+echo -e "AUTHENTICATE \"$mypass\"\\r\\nsignal NEWNYM\\r\\nQUIT" | nc 127.0.0.1 9051;
+
diff --git a/config/qutebrowser/userscripts/torrent b/config/qutebrowser/userscripts/torrent
new file mode 100755
index 0000000..84b6555
--- /dev/null
+++ b/config/qutebrowser/userscripts/torrent
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+~/scripts/torrent.sh magnet "$QUTE_URL";
diff --git a/config/qutebrowser/userscripts/yank b/config/qutebrowser/userscripts/yank
new file mode 100755
index 0000000..a235041
--- /dev/null
+++ b/config/qutebrowser/userscripts/yank
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+echo "$QUTE_URL" | xclip -selection clipboard -i;