Compare commits

58 Commits

Author SHA1 Message Date
18b7782847 Merge branch 'master' of git.opal.sh:opal/opalfiles 2025-06-19 08:05:02 -07:00
828859d181 stoof 2025-06-19 08:04:47 -07:00
73dc064dc5 boop 2025-06-10 18:26:44 -07:00
212da72c8e fixed redirects 2025-06-10 18:25:53 -07:00
25088f9307 stoof 2025-06-10 10:16:46 -07:00
b14baec356 Update 2025-06-08 13:45:29 -07:00
b274531ff6 commenting out unused comments + updating browser keybind 2025-06-03 20:01:08 -07:00
58884693b0 Updating org agenda stuff + elfeed 2025-06-02 11:29:16 -07:00
6f4021d0af stoof 2025-05-28 08:58:30 -07:00
9414b6b6a2 weee 2025-05-27 15:59:35 -07:00
6ef833676c doom stuff 2025-05-25 08:38:33 -07:00
6644389a84 re-adding doom cuz I miss emacs dawg 2025-05-24 18:28:28 -07:00
9551cdac86 stuff 2025-05-19 13:07:27 -07:00
4f2ad8dcce stoof 2025-05-16 21:19:06 -07:00
c518795c21 adding idle, idleinhibit waybar stuff, archiving old waybar stuff 2025-05-16 11:24:16 -07:00
7110044b2b adding screen env vars 2025-05-15 21:55:27 -07:00
52b29d6431 fixing some stuff, will move away from bash soon 2025-05-15 20:54:41 -07:00
41b726a85e fixed some bugs in todo add and made todo print ls after todo done 2025-05-14 09:10:05 -07:00
50609ea1a6 ignoring mpd stuff 2025-05-09 17:33:43 -07:00
62752db358 derp 2025-05-08 20:30:01 -07:00
ce61e9d0c8 changed todo, pass_autofill and bash aliases use nmcli 2025-05-07 16:33:00 -07:00
aa7ea36ff7 chaning font on emoji menu 2025-05-05 17:51:22 -07:00
6fcacba990 fixed pass_autofill 2025-05-04 20:24:54 -07:00
91089507d2 fixed recipemenu 2025-05-04 15:18:02 -07:00
5f9a4b5d0f adding scripts and such 2025-05-03 13:20:09 -07:00
95c5a519bb adding zmenu, arching qutebrowser again cuz it crashes too much, fixed vault script 2025-05-03 12:46:37 -07:00
92a464415c Merge branch 'master' of git.opal.sh:opal/opalfiles 2025-05-03 11:31:30 -07:00
89f628fbb2 stoof 2025-05-03 11:31:18 -07:00
674f083980 added scripts + config stuff 2025-05-02 22:42:39 -07:00
989b4d473b fixing mimeapps + .bash_env 2025-05-01 17:34:45 -07:00
ba2b5e286c fixed up my todo app to be even more robust + aliases for todo 2025-04-30 14:19:18 -07:00
005589be05 fancifying sway more 2025-04-30 08:54:26 -07:00
aaa45d6009 bashrc alias add pluys battery alert scrip 2025-04-29 23:19:57 -07:00
e5b720af93 Stop tracking qutebrowser autoconfig.yml 2025-04-29 23:19:22 -07:00
4818c27b93 stuff 2025-04-29 22:36:07 -07:00
25ad40f68b fixing keychain 2025-04-29 19:58:21 -07:00
f9d22072a6 makin' moves to sync computers 2025-04-29 19:43:59 -07:00
db0d98c0d9 todo script 2025-04-29 18:43:54 -07:00
22a4db35f5 more gitignore 2025-04-29 18:26:25 -07:00
6a4a6a8c3e updating .gitignore, user-dirs.dirs, etc 2025-04-29 18:25:43 -07:00
b8e6598a7f fixing pass_user_copy 2025-04-24 12:02:07 -07:00
5b00715c4b pushin 2025-04-19 09:14:26 -07:00
dbca282194 fixing sleep in pass autofill 2025-04-17 11:21:34 -07:00
f08e29bbd9 fixing booksmarks scripts 2025-04-17 11:20:45 -07:00
35ed3e1343 fixing 2025-04-17 10:49:27 -07:00
739e3f8837 stoof 2025-04-16 15:40:35 -07:00
opal
330b094069 moving files around 2025-04-15 23:57:28 -07:00
9e424589de trying qutebrowser again, tweaking scripts and sway keybinds 2025-04-15 17:53:45 -07:00
23f53a5ac4 adding gopass stuff 2025-04-15 15:02:25 -07:00
b3911b0f36 removing unnecessary file 2025-03-24 17:09:09 -07:00
35d7d0ae23 decom calcurse cuz it didn't work out for me 2025-03-24 17:08:26 -07:00
20ce61bedb changing stuff 2025-03-24 17:06:36 -07:00
3ab067c35e stuff 2024-12-11 08:40:43 -08:00
f6997c69cc stuff 2024-12-07 20:26:58 -08:00
b1ebde8e27 changes 2024-12-07 09:33:45 -08:00
7e09920f02 buncha stuff 2024-10-21 18:57:26 -07:00
ecc289897c im going through changes 2024-10-15 11:35:43 -07:00
625b61a4cc changed fonts + stuff 2024-09-30 19:27:17 -07:00
67 changed files with 6077 additions and 577 deletions

View File

@@ -2,25 +2,20 @@
# Environment exports
export MOZ_ENABLE_WAYLAND=1
export XDG_CONFIG_HOME=~/.config
export XDG_CACHE_HOME=~/.cache
export XDG_DATA_HOME=~/.local/share
export BROWSER=/usr/bin/firefox
export VISUAL=emacsclient
export EDITOR=emacsclient
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"
export BROWSER=/usr/bin/librewolf
export VISUAL=nvim
export EDITOR=nvim
export QT_QPA_PLATFORMTHEME=qt5ct
export DESKTOP_SESSION=sway
export SCREENRC="$XDG_CONFIG_HOME"/screen/screenrc
export SCREENDIR="${XDG_RUNTIME_DIR}/screen"
export XDG_DATA_DIRS="/var/lib/flatpak/exports/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
# Scripts Path
PATH=$PATH:~/.local/bin
PATH=$PATH:~/bin
# Paths
export PATH="$PATH:$HOME/.local/bin"
export PATH="$PATH:$HOME/.config/emacs/bin"
export PATH="$PATH:/var/lib/flatpak/exports/bin"
# Doom Path
PATH=$PATH:~/.config/emacs/bin/
# Flatpak path
PATH=$PATH:/var/lib/flatpak/exports/bin
PATH=$PATH:/var/lib/flatpak/app
# Guile Load Path
export GUILE_LOAD_PATH="/usr/local/share/guile/site/3.0"

63
.bashrc
View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
@@ -50,6 +50,8 @@ export LESS_TERMCAP_so=$'\E[01;44;33m'
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;32m'
export PATH="$HOME/scripts:$PATH"
#######################################################
# GOPASS
#######################################################
@@ -68,19 +70,20 @@ alias gpe='gopass edit'
#######################################################
# ALIAS
#######################################################
# To temporarily bypass an alias, we preceed the command with a \
# EG: the ls command is aliased, but to use the normal ls command you would type \ls
alias dot='cd ~/code/opalfiles'
alias ans='cd ~/code/ansible'
alias v='nvim'
alias vim='nvim'
alias vi='nvim'
# DNF
alias dnf='dnf5'
alias din='sudo dnf5 install'
alias dre='sudo dnf5 remove'
alias dup='sudo dnf5 update'
alias dse='dnf5 search'
alias dnf='dnf'
alias din='sudo dnf install'
alias dre='sudo dnf remove'
alias dup='sudo dnf update'
alias dse='dnf search'
# alias to show the date
alias da='date "+%Y-%m-%d %A %T %Z"'
@@ -107,9 +110,6 @@ alias .....='cd ../../../..'
# cd into the old directory
alias bd='cd "$OLDPWD"'
# ls -> exa
alias ls='exa'
# Search command line history
alias h="history | grep "
@@ -127,7 +127,7 @@ alias mountedinfo='df -hT'
# Alias's for archives
alias mktar='tar -cvf'
alias mkbz2='tar -cvjf'
alias mkgz='tar -cvzf'
alias mgz='tar -cvzf'
alias untar='tar -xvf'
alias unbz2='tar -xvjf'
alias ungz='tar -xvzf'
@@ -138,18 +138,30 @@ alias wget='wget --hsts-file="$XDG_CACHE_HOME/wget-hsts"'
# Translate
alias tbr='trans :pt-BR'
# ncmpcpp
alias ncmpcpp='ncmpcpp -b ~/.config/ncmpcpp/bindings'
# todo
alias t='todo'
alias tl='todo ls'
alias ta='todo lsa'
alias td='todo done'
alias te='todo edit'
alias tj='todo jira'
alias wo='glow ~/sync/workout/workout.md'
alias vwo='vim ~/sync/workout/workout.md'
alias pu='glow ~/sync/workout/pullup.md'
alias vpu='vim ~/sync/workout/pullup.md'
#######################################################
# WORK
#######################################################
# Wireguard
alias wgup='sudo wg-quick up /etc/wireguard/wg0.conf'
alias wgdown='sudo wg-quick down /etc/wireguard/wg0.conf'
# Keychain
alias keys='eval $(keychain --eval --quiet ry_ecdsa) && eval $(keychain --eval --quiet id_rsa)'
alias wgup='nmcli connection up wg0'
alias wgdown='nmcli connection down wg0'
#######################################################
# SPECIAL FUNCTIONS
@@ -171,9 +183,8 @@ function parse_git_branch {
git branch 2>/dev/null | grep -e '^*' | sed 's/^* \(.*\)/ (\1)/'
}
# Define colors
export RED='\[\033[0;31m\]'
export BLUE='\[\033[0;34m\]'
RED='\[\033[0;31m\]'
BLUE='\[\033[0;34m\]'
GREEN='\[\033[0;32m\]'
YELLOW='\[\033[0;33m\]'
CYAN='\[\033[0;36m\]'
@@ -187,5 +198,11 @@ PS1="${CYAN}[\u@\h ${YELLOW}\w${GREEN}\$(parse_git_branch)${CYAN}]${WHITE}${RESE
#######################################################
# SSH
#######################################################
eval $(keychain --eval --quiet ry_ecdsa)
eval $(keychain --eval --quiet id_rsa)
keys()
{
eval "$(keychain --quiet --absolute --dir "$XDG_CONFIG_HOME"/keychain --eval ry_ecdsa)"
eval "$(keychain --quiet --absolute --dir "$XDG_CONFIG_HOME"/keychain --eval id_rsa)"
}
keys

View File

@@ -1,13 +1,12 @@
import = ["/home/opal/.config/alacritty/gruvbox-light.toml"]
[env]
TERM = "alacritty"
TERM = "xterm-256color"
[font]
size = 22
size = 16
[font.normal]
family = "Terminus"
family = "Monospace"
style = "Regular"
[font.offset]
@@ -17,3 +16,5 @@ y = 0
[window]
opacity = 0.9
[general]
import = ["/home/opal/.config/alacritty/theme.toml"]

View File

@@ -0,0 +1,26 @@
# Default colors
[colors.primary]
background = '#1c1408' # matches -bg
foreground = '#5b8512' # matches fg
# Normal colors
[colors.normal]
black = '#1B2229' # matches base0
red = '#ff4e00' # matches red
green = '#7cb518' # matches green
yellow = '#ffbf00' # matches yellow
blue = '#0075c4' # matches blue
magenta = '#d72638' # matches magenta
cyan = '#898989' # matches cyan
white = '#dfdfdf' # matches base8
# Bright colors
[colors.bright]
black = '#1c1f24' # matches base1
red = '#ff7000' # matches orange
green = '#dbc077' # matches teal (sand/beige)
yellow = '#ffbf00' # matches yellow
blue = '#0060a1' # matches dark-blue
magenta = '#76597b' # matches violet
cyan = '#4f7410' # matches dark-cyan
white = '#9ca0a4' # matches base7

View File

@@ -0,0 +1,28 @@
# Colors (Solarized Dark)
# Default colors
[colors.primary]
background = '#002b36'
foreground = '#839496'
# Normal colors
[colors.normal]
black = '#073642'
red = '#dc322f'
green = '#859900'
yellow = '#b58900'
blue = '#268bd2'
magenta = '#d33682'
cyan = '#2aa198'
white = '#eee8d5'
# Bright colors
[colors.bright]
black = '#002b36'
red = '#cb4b16'
green = '#586e75'
yellow = '#657b83'
blue = '#839496'
magenta = '#6c71c4'
cyan = '#93a1a1'
white = '#fdf6e3'

Binary file not shown.

View File

@@ -1,74 +0,0 @@
# If you want to synchronize calcurse with a CalDAV server using
# calcurse-caldav, create a new directory at $XDG_CONFIG_HOME/calcurse/caldav/
# (~/.config/calcurse/caldav/) and $XDG_DATA_HOME/calcurse/caldav/
# (~/.local/share/calcurse/caldav/) and copy this file to
# $XDG_CONFIG_HOME/calcurse/caldav/config and adjust the configuration below.
# Alternatively, if using ~/.calcurse, create a new directory at
# ~/.calcurse/caldav/ and copy this file to ~/.calcurse/caldav/config and adjust
# the configuration file below.
[General]
# Path to the calcurse binary that is used for importing/exporting items.
Binary = calcurse
# Host name of the server that hosts CalDAV. Do NOT prepend a protocol prefix,
# such as http:// or https://. Append :<port> for a port other than 80.
Hostname = dav.opal.sh
# Path to the CalDAV calendar on the host specified above. This is the base
# path following your host name in the URL.
Path = /dav.php/calendars/ryan/ryan-cal/
# Type of authentication to use. Must be "basic" or "oauth2"
#AuthMethod = basic
# Enable this if you want to skip SSL certificate checks.
InsecureSSL = No
# Disable this if you want to use HTTP instead of HTTPS.
# Using plain HTTP is highly discouraged.
HTTPS = Yes
# This option allows you to filter the types of tasks synced. To this end, the
# value of this option should be a comma-separated list of item types, where
# each item type is either "event", "apt", "recur-event", "recur-apt", "todo",
# "recur" or "cal". Note that the comma-separated list must not contain any
# spaces. Refer to the documentation of the --filter-type command line argument
# of calcurse for more details. Set this option to "cal" if the configured
# CalDAV server doesn't support tasks, such as is the case with Google
# Calendar.
SyncFilter = cal,todo
# Disable this option to actually enable synchronization. If it is enabled,
# nothing is actually written to the server or to the local data files. If you
# combine DryRun = Yes with Verbose = Yes, you get a log of what would have
# happened with this option disabled.
DryRun = No
# Enable this if you want detailed logs written to stdout.
Verbose = Yes
# Credentials for HTTP Basic Authentication (if required).
# Set `Password` to your password in plaintext (unsafe),
# or `PasswordCommand` to a shell command that retrieves it (recommended).
[Auth]
Username = ryan
#Password = password
PasswordCommand = gopass show -o self-hosted/dav.opal.sh
# Optionally specify additional HTTP headers here.
#[CustomHeaders]
#User-Agent = Mac_OS_X/10.9.2 (13C64) CalendarAgent/176
# Use the following to synchronize with an OAuth2-based service
# such as Google Calendar.
#[OAuth2]
#ClientID = your_client_id
#ClientSecret = your_client_secret
# Scope of access for API calls. Synchronization requires read/write.
#Scope = https://example.com/resource/scope
# Change the redirect URI if you receive errors, but ensure that it is identical
# to the redirect URI you specified in the API settings.
#RedirectURI = http://127.0.0.1

View File

@@ -1,26 +0,0 @@
#!/bin/sh
#
# 1. Make a commit if the calcurse directories contain a Git repository.
# 2. Synchronize with a CalDAV server if calcurse-caldav is configured.
data_dir="$HOME/.calcurse"
config_dir="$HOME/.calcurse"
if [ ! -d "$data_dir" ]; then
data_dir="${XDG_DATA_HOME:-$HOME/.local/share}/calcurse"
config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/calcurse"
fi
# Do not do anything when synchronizing with a CalDAV server.
[ -f "$data_dir/caldav/lock" ] && exit
# Run the CalDAV synchronization script in the background.
cd "$data_dir" || exit
if [ -d caldav ] && command -v calcurse-caldav >/dev/null; then
(
date="$(date +'%b %d %H:%M:%S')"
echo "$date Running calcurse-caldav from the post-save hook..."
calcurse-caldav
echo
) >>caldav/log 2>&1 &
fi

View File

@@ -1,18 +0,0 @@
#!/bin/sh
[ -d "$HOME/.calcurse" ] && data_dir="$HOME/.calcurse" || data_dir="${XDG_DATA_HOME:-$HOME/.local/share}/calcurse"
cd "$data_dir" || exit
# Do not do anything when synchronizing with a CalDAV server.
[ -f caldav/lock ] && exit
# Run the CalDAV synchronization script in the background.
if [ -d caldav ] && command -v calcurse-caldav >/dev/null; then
(
date="$(date +'%b %d %H:%M:%S')"
echo "$date Running calcurse-caldav from the pre-load hook..."
calcurse-caldav
echo
) >>caldav/log 2>&1 &
fi

View File

@@ -13,8 +13,8 @@
user-mail-address "ry.orlando@proton.me")
;; Theme & background color
(load-theme 'ef-eagle t)
(set-face-background 'default "#E8D8B0")
(load-theme 'doom-gruvbox t)
;;(set-face-background 'default "#E8D8B0")
;; Lockfiles
(setq create-lockfiles nil)
@@ -27,9 +27,9 @@
(add-hook mode (lambda () (display-line-numbers-mode 0))))
;; Font configuration
(set-face-attribute 'default nil :font "Terminus" :height 200)
(set-face-attribute 'fixed-pitch nil :font "Terminus" :height 200)
(set-face-attribute 'variable-pitch nil :font "ETBembo" :height 200)
(set-face-attribute 'default nil :font "Monospace" :height 170)
(set-face-attribute 'fixed-pitch nil :font "Monospace" :height 170)
(set-face-attribute 'variable-pitch nil :font "ETBembo" :height 170)
(defun opal/org-font-setup ()
;; Replace list hyphen with dot
@@ -90,7 +90,8 @@
(setq org-indent-indentation-per-level 2)
(setq org-hide-emphasis-markers t)
(setq org-agenda-files
'("~/documents/org/agenda/todo.org"))
'("~/sync/org/agenda/work.org"
"~/sync/org/agenda/personal.org"))
(require 'org-habit)
(add-to-list 'org-modules 'org-habit)
@@ -98,7 +99,7 @@
(setq org-todo-keywords
'((sequence "NEXT(n)" "TODO(t)" "|" "DONE(d!)")
(sequence "ACTIVE(a)" "PROJ(p)" "READY(r)" "HOLD(h)" "BACKLOG(b)" "|" "CANC(k@)")))
(sequence "ACTIVE(a)" "PROJ(p)" "READY(r)" "WAIT(w)" "HOLD(h)" "BACKLOG(b)" "|" "CANC(k@)")))
(setq org-todo-keyword-faces
'(("NEXT" . "red") ("TODO" . "orange") ("WAIT" . "yellow") ("DONE" . "green")))
@@ -139,9 +140,9 @@
;; Create capture templates
(setq org-capture-templates
`(("t" "Tasks")
("tw" "Work Task" entry (file+headline "~/documents/org/agenda/todo.org" "Work")
("tw" "Work Task" entry (file+headline "~/sync/org/agenda/work.org" "Inbox")
"* TODO %?\n %U\n %i" :empty-lines 1)
("tp" "Personal Task" entry (file+headline "~/documents/org/agenda/todo.org" "Personal")
("tp" "Personal Task" entry (file+headline "~/sync/org/agenda/personal.org" "Inbox")
"* TODO %?\n %U\n %i" :empty-lines 1)
("tb" "Backlog Task" entry (file+headline "~/documents/org/agenda/todo.org" "Backlog")
"* BACKLOG %?\n %U\n %i" :empty-lines 1)))
@@ -150,7 +151,9 @@
(setq org-edit-src-content-indentation 0)
;; Set org agenda dir
(setq org-directory "~/documents/org/")
(setq org-directory "~/sync/org/agenda")
(setq org-agenda-include-diary t)
(setq diary-file "~/sync/org/diary")
;; Init org font setup
(opal/org-font-setup))
@@ -163,7 +166,7 @@
(defun opal/org-mode-visual-fill ()
(setq visual-fill-column-width 150
visual-fill-column-center-text t)
visual-fill-column-center-text t)
(visual-fill-column-mode 1))
(use-package visual-fill-column
@@ -203,14 +206,6 @@
(global-set-key (kbd "C-c y") 'opal/play-yt-url-at-point)
;; Elfeed
(defun opal/elfeed-open-in-firefox ()
"Open the current Elfeed entry link in Firefox."
(interactive)
(let ((link (elfeed-entry-link (elfeed-search-selected :single))))
(if link
(browse-url-firefox link)
(message "No link to open."))))
(defun opal/elfeed-open-in-eww()
"Open the current Elfeed entry link in eww."
(interactive)
@@ -219,6 +214,15 @@
(eww-browse-url link)
(message "No link to open."))))
(defun opal/elfeed-open-in-librewolf ()
"Open the current Elfeed entry link in LibreWolf."
(interactive)
(let ((link (elfeed-entry-link (elfeed-search-selected :single))))
(if link
(let ((browse-url-generic-program "librewolf"))
(browse-url-generic link))
(message "No link to open."))))
(defun opal/elfeed-mark-all-read ()
"Marks all feeds in *elfeed-search* as read."
(interactive)
@@ -248,25 +252,35 @@
;; Evil keybindings for Elfeed
(evil-define-key 'normal elfeed-search-mode-map
"f" 'opal/elfeed-open-in-firefox ;; Open link in Firefox
"e" 'opal/elfeed-open-in-eww ;; Open link in Firefox
"r" 'opal/elfeed-mark-all-read ;; Marks all feeds as read
"gr" 'elfeed-update ;; Refresh feeds
"q" 'quit-window)) ;; Quit Elfeed
"e" 'opal/elfeed-open-in-eww ;; Open link in eww
"o" 'opal/elfeed-open-in-librewolf ;; Open link in eww
"r" 'opal/elfeed-mark-all-read ;; Marks all feeds as read
"gr" 'elfeed-update ;; Refresh feeds
"q" 'quit-window)) ;; Quit Elfeed
(setq create-lockfiles nil)
;; Make sure eww opens in it's own buffer
(after! eww
(set-popup-rule! "^\\*eww\\*" :ignore t))
(use-package elfeed-org
:ensure t
:config
(setq rmh-elfeed-org-files '("~/sync/org/elfeed/feeds.org")))
(after! osm
(set-popup-rule! "^\\*osm\\*" :ignore t))
;; eww
(defun opal/eww-reddit-redirect(url)
"Redirect reddit.com to custom URL."
(replace-regexp-in-string "https://www.reddit.com" "https://eddrit.com" url))
(defun opal/eww-reddit-redirect (url)
"Redirect reddit.com (with or without www) to a privacy frontend."
(replace-regexp-in-string "^https://\\(www\\.\\)?reddit\\.com" "https://eddrit.com" url))
(defun opal/eww-x-redirect (url)
"Redirect x.com (with or without www) to a privacy frontend."
(replace-regexp-in-string "^https://\\(www\\.\\)?x\\.com" "https://xcancel.com" url))
(defun opal/eww-twitter-redirect (url)
"Redirect twitter.com (with or without www) to a privacy frontend."
(replace-regexp-in-string "^https://\\(www\\.\\)?twitter\\.com" "https://xcancel.com" url))
(global-set-key (kbd "C-c w") #'eww)
(global-set-key (kbd "C-c f") #'elfeed-goodies/show-link-hint)
(use-package eww
:config
@@ -279,7 +293,11 @@
(setq reddit-proxy "https://eddrit.com")
;; Redirect reddit links to privacy respecting frontends.
(setq eww-url-transformers '(eww-remove-tracking opal/eww-reddit-redirect))
(setq eww-url-transformers
'(eww-remove-tracking
opal/eww-reddit-redirect
opal/eww-twitter-redirect
opal/eww-x-redirect))
;; Make sure eww opens in it's own buffer
(after! eww
@@ -314,3 +332,6 @@
(setq +lookup-dictionary-prefer-offline t)
(setq dictionary-server "dict.org")
(setq browse-url-generic-program "librewolf")
(setq browse-url-browser-function 'browse-url-generic)

View File

@@ -7,7 +7,7 @@
["#282c34" "#ff6c6b" "#98be65" "#ECBE7B" "#51afef" "#c678dd" "#46D9FF" "#bbc2cf"])
'(auth-source-save-behavior nil)
'(custom-safe-themes
'("b00cb300c114f3b971370c9ef9b6b8a347fa02b1af2aa4c02dab47eaa0ad930b" "d6d4e0512dcaae663f7bd304557d6bc8b78c576be5af9c0b62b8447fb79b5fde" "13096a9a6e75c7330c1bc500f30a8f4407bd618431c94aeab55c9855731a95e1" "48042425e84cd92184837e01d0b4fe9f912d875c43021c3bcb7eeb51f1be5710" "c5878086e65614424a84ad5c758b07e9edcf4c513e08a1c5b1533f313d1b17f1" "10e5d4cc0f67ed5cafac0f4252093d2119ee8b8cb449e7053273453c1a1eb7cc" "ffafb0e9f63935183713b204c11d22225008559fa62133a69848835f4f4a758c" "7964b513f8a2bb14803e717e0ac0123f100fb92160dcf4a467f530868ebaae3e" "f053f92735d6d238461da8512b9c071a5ce3b9d972501f7a5e6682a90bf29725" "944d52450c57b7cbba08f9b3d08095eb7a5541b0ecfb3a0a9ecd4a18f3c28948" "dad40020beea412623b04507a4c185079bff4dcea20a93d8f8451acb6afc8358" "a0415d8fc6aeec455376f0cbcc1bee5f8c408295d1c2b9a1336db6947b89dd98" "a9a67b318b7417adbedaab02f05fa679973e9718d9d26075c6235b1f0db703c8" "1704976a1797342a1b4ea7a75bdbb3be1569f4619134341bd5a4c1cfb16abad4" "b5803dfb0e4b6b71f309606587dd88651efe0972a5be16ece6a958b197caeed8" default))
'("d9a947788a4c5f7051c4ad3a3e0e9d76218209899683d3e9ed1e2aa6cd10d462" "b00cb300c114f3b971370c9ef9b6b8a347fa02b1af2aa4c02dab47eaa0ad930b" "d6d4e0512dcaae663f7bd304557d6bc8b78c576be5af9c0b62b8447fb79b5fde" "13096a9a6e75c7330c1bc500f30a8f4407bd618431c94aeab55c9855731a95e1" "48042425e84cd92184837e01d0b4fe9f912d875c43021c3bcb7eeb51f1be5710" "c5878086e65614424a84ad5c758b07e9edcf4c513e08a1c5b1533f313d1b17f1" "10e5d4cc0f67ed5cafac0f4252093d2119ee8b8cb449e7053273453c1a1eb7cc" "ffafb0e9f63935183713b204c11d22225008559fa62133a69848835f4f4a758c" "7964b513f8a2bb14803e717e0ac0123f100fb92160dcf4a467f530868ebaae3e" "f053f92735d6d238461da8512b9c071a5ce3b9d972501f7a5e6682a90bf29725" "944d52450c57b7cbba08f9b3d08095eb7a5541b0ecfb3a0a9ecd4a18f3c28948" "dad40020beea412623b04507a4c185079bff4dcea20a93d8f8451acb6afc8358" "a0415d8fc6aeec455376f0cbcc1bee5f8c408295d1c2b9a1336db6947b89dd98" "a9a67b318b7417adbedaab02f05fa679973e9718d9d26075c6235b1f0db703c8" "1704976a1797342a1b4ea7a75bdbb3be1569f4619134341bd5a4c1cfb16abad4" "b5803dfb0e4b6b71f309606587dd88651efe0972a5be16ece6a958b197caeed8" default))
'(exwm-floating-border-color "#191b20")
'(fci-rule-color "#5B6268")
'(highlight-tail-colors

View File

@@ -98,7 +98,7 @@
:os
(:if IS-MAC macos) ; improve compatibility with macOS
;;tty ; improve the terminal Emacs experience
tty ; improve the terminal Emacs experience
:lang
;;agda ; types of types of types of types...

4
.config/eww/eww.yuck Normal file
View File

@@ -0,0 +1,4 @@
(widget my-panel
(box :class "panel-container"
(label :text "Hello, world!" :class "hello-label")))

16
.config/eww/style.css Normal file
View File

@@ -0,0 +1,16 @@
* {
all: unset;
font-family: "JetBrainsMono Nerd Font", "monospace";
}
.panel-container {
background-color: rgba(30, 30, 30, 0.9);
border-radius: 10px;
padding: 20px;
margin: 10px;
}
.hello-label {
color: white;
font-size: 20px;
}

View File

@@ -1,22 +1,22 @@
[Added Associations]
video/mp4=org.videolan.VLC.desktop;org.kde.dragonplayer.desktop;mpv.desktop;
video/quicktime=org.videolan.VLC.desktop;org.kde.dragonplayer.desktop;mpv.desktop;
video/mp4=org.videolan.VLC.deskop;mpv.desktop;
video/quicktime=org.videolan.VLC.deskop;mpv.desktop;
video/x-matroska=org.videolan.VLC.desktop;
application/vnd.rar=xarchiver.desktop;userapp-p7zipForFilemanager-FIKDV2.desktop;
[Default Applications]
inode/directory=pcmanfm-qt
video/mp4=org.videolan.VLC.desktop;
video/quicktime=org.videolan.VLC.desktop
text/html=/usr/bin/firefox
application/xhtml+xml=/usr/bin/firefox
application/xml=/usr/bin/firefox
text/xml=/usr/bin/firefox
text/xsl=/usr/bin/firefox
application/rss+xml=/usr/bin/firefox
application/atom+xml=/usr/bin/firefox
x-scheme-handler/http=/usr/bin/firefox
x-scheme-handler/https=/usr/bin/firefox
x-scheme-handler/ftp=/usr/bin/firefox
x-scheme-handler/chrome=/usr/bin/firefox
x-scheme-handler/about=/usr/bin/firefox
x-scheme-handler/mailto=/usr/bin/firefox
text/html=librewolf.desktop
application/xhtml+xml=librewolf.desktop
application/xml=librewolf.desktop
text/xml=librewolf.desktop
text/xsl=librewolf.desktop
application/rss+xml=librewolf.desktop
application/atom+xml=librewolf.desktop
x-scheme-handler/http=librewolf.desktop
x-scheme-handler/https=librewolf.desktop
x-scheme-handler/ftp=librewolf.desktop
x-scheme-handler/chrome=librewolf.desktop
x-scheme-handler/about=librewolf.desktop
x-scheme-handler/mailto=librewolf.desktop

14
.config/mpd/mpd.conf Normal file
View File

@@ -0,0 +1,14 @@
music_directory "~/music"
playlist_directory "~/.local/share/mpd/playlists"
db_file "~/.local/share/mpd/db"
log_file "~/.local/share/mpd/log"
pid_file "~/.local/share/mpd/pid"
state_file "~/.local/share/mpd/state"
sticker_file "~/.local/share/mpd/sticker.sql"
bind_to_address "~/.local/share/mpd/socket"
audio_output {
type "pulse"
name "My Audio"
}

479
.config/ncmpcpp/bindings Normal file
View File

@@ -0,0 +1,479 @@
##############################################################
## This is the example bindings file. Copy it to ##
## ~/.ncmpcpp/bindings or $XDG_CONFIG_HOME/ncmpcpp/bindings ##
## and set up your preferences ##
##############################################################
#
#def_key "mouse"
# mouse_event
#
#def_key "up"
# scroll_up
#
#def_key "shift-up"
# select_item
# scroll_up
#
#def_key "down"
# scroll_down
#
#def_key "shift-down"
# select_item
# scroll_down
#
#def_key "["
# scroll_up_album
#
#def_key "]"
# scroll_down_album
#
#def_key "{"
# scroll_up_artist
#
#def_key "}"
# scroll_down_artist
#
#def_key "page_up"
# page_up
#
#def_key "page_down"
# page_down
#
#def_key "home"
# move_home
#
#def_key "end"
# move_end
#
#def_key "insert"
# select_item
#
#def_key "enter"
# enter_directory
#
#def_key "enter"
# toggle_output
#
#def_key "enter"
# run_action
#
#def_key "enter"
# play_item
#
#def_key "space"
# add_item_to_playlist
#
#def_key "space"
# toggle_lyrics_update_on_song_change
#
#def_key "space"
# toggle_visualization_type
#
#def_key "delete"
# delete_playlist_items
#
#def_key "delete"
# delete_browser_items
#
#def_key "delete"
# delete_stored_playlist
#
#def_key "right"
# next_column
#
#def_key "right"
# slave_screen
#
#def_key "right"
# volume_up
#
#def_key "+"
# volume_up
#
#def_key "left"
# previous_column
#
#def_key "left"
# master_screen
#
#def_key "left"
# volume_down
#
#def_key "-"
# volume_down
#
#def_key ":"
# execute_command
#
#def_key "tab"
# next_screen
#
#def_key "shift-tab"
# previous_screen
#
#def_key "f1"
# show_help
#
#def_key "1"
# show_playlist
#
#def_key "2"
# show_browser
#
#def_key "2"
# change_browse_mode
#
#def_key "3"
# show_search_engine
#
#def_key "3"
# reset_search_engine
#
#def_key "4"
# show_media_library
#
#def_key "4"
# toggle_media_library_columns_mode
#
#def_key "5"
# show_playlist_editor
#
#def_key "6"
# show_tag_editor
#
#def_key "7"
# show_outputs
#
#def_key "8"
# show_visualizer
#
#def_key "="
# show_clock
#
#def_key "@"
# show_server_info
#
#def_key "s"
# stop
#
#def_key "p"
# pause
#
#def_key ">"
# next
#
#def_key "<"
# previous
#
#def_key "ctrl-h"
# jump_to_parent_directory
#
#def_key "ctrl-h"
# replay_song
#
#def_key "backspace"
# jump_to_parent_directory
#
#def_key "backspace"
# replay_song
#
#def_key "f"
# seek_forward
#
#def_key "b"
# seek_backward
#
#def_key "r"
# toggle_repeat
#
#def_key "z"
# toggle_random
#
#def_key "y"
# save_tag_changes
#
#def_key "y"
# start_searching
#
#def_key "y"
# toggle_single
#
#def_key "R"
# toggle_consume
#
#def_key "Y"
# toggle_replay_gain_mode
#
#def_key "T"
# toggle_add_mode
#
#def_key "|"
# toggle_mouse
#
#def_key "#"
# toggle_bitrate_visibility
#
#def_key "Z"
# shuffle
#
#def_key "x"
# toggle_crossfade
#
#def_key "X"
# set_crossfade
#
#def_key "u"
# update_database
#
#def_key "ctrl-s"
# sort_playlist
#
#def_key "ctrl-s"
# toggle_browser_sort_mode
#
#def_key "ctrl-s"
# toggle_media_library_sort_mode
#
#def_key "ctrl-r"
# reverse_playlist
#
#def_key "ctrl-f"
# apply_filter
#
#def_key "ctrl-_"
# select_found_items
#
#def_key "/"
# find
#
#def_key "/"
# find_item_forward
#
#def_key "?"
# find
#
#def_key "?"
# find_item_backward
#
#def_key "."
# next_found_item
#
#def_key ","
# previous_found_item
#
#def_key "w"
# toggle_find_mode
#
#def_key "e"
# edit_song
#
#def_key "e"
# edit_library_tag
#
#def_key "e"
# edit_library_album
#
#def_key "e"
# edit_directory_name
#
#def_key "e"
# edit_playlist_name
#
#def_key "e"
# edit_lyrics
#
#def_key "i"
# show_song_info
#
#def_key "I"
# show_artist_info
#
#def_key "g"
# jump_to_position_in_song
#
#def_key "l"
# show_lyrics
#
#def_key "ctrl-v"
# select_range
#
#def_key "v"
# reverse_selection
#
#def_key "V"
# remove_selection
#
#def_key "B"
# select_album
#
#def_key "a"
# add_selected_items
#
#def_key "c"
# clear_playlist
#
#def_key "c"
# clear_main_playlist
#
#def_key "C"
# crop_playlist
#
#def_key "C"
# crop_main_playlist
#
#def_key "m"
# move_sort_order_up
#
#def_key "m"
# move_selected_items_up
#
#def_key "n"
# move_sort_order_down
#
#def_key "n"
# move_selected_items_down
#
#def_key "M"
# move_selected_items_to
#
#def_key "A"
# add
#
#def_key "S"
# save_playlist
#
#def_key "o"
# jump_to_playing_song
#
#def_key "G"
# jump_to_browser
#
#def_key "G"
# jump_to_playlist_editor
#
#def_key "~"
# jump_to_media_library
#
#def_key "E"
# jump_to_tag_editor
#
#def_key "U"
# toggle_playing_song_centering
#
#def_key "P"
# toggle_display_mode
#
#def_key "\\"
# toggle_interface
#
#def_key "!"
# toggle_separators_between_albums
#
#def_key "L"
# toggle_lyrics_fetcher
#
#def_key "F"
# fetch_lyrics_in_background
#
#def_key "alt-l"
# toggle_fetching_lyrics_in_background
#
#def_key "ctrl-l"
# toggle_screen_lock
#
#def_key "`"
# toggle_library_tag_type
#
#def_key "`"
# refetch_lyrics
#
#def_key "`"
# add_random_items
#
#def_key "ctrl-p"
# set_selected_items_priority
#
#def_key "q"
# quit
#
#
#def_key "f"
# find
#def_key "f"
# find_item_forward
def_key "+"
show_clock
def_key "="
volume_up
def_key "j"
scroll_down
def_key "k"
scroll_up
def_key "ctrl-u"
page_up
#push_characters "kkkkkkkkkkkkkkk"
def_key "ctrl-d"
page_down
#push_characters "jjjjjjjjjjjjjjj"
def_key "u"
page_up
#push_characters "kkkkkkkkkkkkkkk"
def_key "d"
page_down
#push_characters "jjjjjjjjjjjjjjj"
def_key "h"
previous_column
def_key "l"
next_column
def_key "."
show_lyrics
def_key "n"
next_found_item
def_key "N"
previous_found_item
# not used but bound
def_key "J"
move_sort_order_down
def_key "K"
move_sort_order_up
def_key "h"
jump_to_parent_directory
def_key "l"
enter_directory
def_key "l"
run_action
def_key "l"
play_item
def_key "m"
show_media_library
def_key "m"
toggle_media_library_columns_mode
def_key "t"
show_tag_editor
def_key "v"
show_visualizer
def_key "G"
move_end
def_key "g"
move_home
#jump_to_position_in_song
def_key "U"
update_database
def_key "s"
reset_search_engine
def_key "s"
show_search_engine
def_key "f"
show_browser
def_key "f"
change_browse_mode
def_key "x"
delete_playlist_items
def_key "P"
show_playlist

9
.config/ncmpcpp/config Normal file
View File

@@ -0,0 +1,9 @@
mpd_music_dir = "~/music"
mpd_host = "/home/opal/.local/share/mpd/socket"
mpd_port = "6600" # Ignored when using a socket
ncmpcpp_directory = "~/.config/ncmpcpp"
lyrics_directory = "~/.config/ncmpcpp/lyrics"
visualizer_type = "spectrum"

View File

@@ -1,16 +1,39 @@
"query:all articles:unread = \"yes\" or unread = \"no\""
---Reddit---
https://www.reddit.com/r/stupidpol/.rss
---News---
https://thegrayzone.com/rss
https://multipolarista.com/rss
https://www.telesurenglish.net/feed/
https://theintercept.com/feed/
https://jacobin.com/feed
https://www.propublica.org/feeds
https://www.racket.news/feed
https://feeds.a.dj.com/rss/RSSWorldNews.xml "Wall Street Journal (World)"
https://www.npr.org/rss/rss.php?id=1001 "NPR (US News)"
https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml "NYTimes Front Page"
https://www.wsws.org/en/rss.xml
---Tech---
https://landchad.net/rss.xml
https://videos.lukesmith.xyz/feeds/videos.xml?videoChannelId=2 "~Luke Smith (Videos)"
https://hnrss.org/frontpage "Hacker News (Top Stories)"
https://pluralistic.net/feed/
https://blog.privacyguides.org/feed_rss_created.xml
https://lukesmith.xyz/index.xml "~Luke Smith (Blog)"
https://www.techdirt.com/techdirt_rss.xml "~TechDirt"
https://www.theverge.com/rss/index.xml "~The Verge"
https://www.linuxlinks.com/feed/ "~LinuxLinks"
https://itsfoss.com/feed/ "~It's FOSS"
https://lwn.net/headlines/rss "~LWN.net"
https://www.youtube.com/feeds/videos.xml?channel_id=UCld68syR8Wi-GY_n4CaoJGA
---Podcasts---
https://feeds.simplecast.com/dCXMIpJz "Last Podcast On the Left"
http://feeds.soundcloud.com/users/soundcloud:users:572119410/sounds.rss podcasts "Fall of Civilziation"
https://feeds.feedburner.com/dancarlin/history?format=xml podcasts "Hardcore History"
http://feeds.soundcloud.com/users/soundcloud:users:572119410/sounds.rss "Fall of Civilziation"
https://feeds.feedburner.com/dancarlin/history?format=xml "Hardcore History"
---Youtube---
https://www.youtube.com/feeds/videos.xml?channel_id=UCCZ40QwZtFs_7h5MZ0ZTTwg # Lefie

View File

@@ -1,53 +1,17 @@
require("config.lazy")
-- ~/.config/nvim/init.lua
vim.o.number = true
vim.o.relativenumber = true
vim.o.clipboard = "unnamedplus"
vim.opt.title = true
vim.opt.background = 'dark'
vim.opt.guicursor = ''
vim.opt.mouse = 'a'
vim.opt.hlsearch = false
vim.opt.clipboard:append('unnamedplus')
vim.opt.showmode = false
vim.opt.ruler = false
vim.opt.laststatus = 0
vim.opt.showcmd = false
vim.cmd [[highlight Normal guibg=NONE ctermbg=NONE]]
vim.cmd [[highlight NormalNC guibg=NONE ctermbg=NONE]]
vim.cmd [[highlight EndOfBuffer guibg=NONE ctermbg=NONE]]
vim.cmd('highlight Normal ctermbg=NONE guibg=NONE')
-- Some basics:
vim.api.nvim_set_keymap('n', 'c', '"_c', { noremap = true })
vim.opt.compatible = false
vim.cmd('filetype plugin on')
vim.cmd('syntax on')
vim.opt.encoding = 'utf-8'
vim.opt.number = true
vim.opt.relativenumber = true
-- Enable autocompletion:
vim.opt.wildmode = { 'longest', 'list', 'full' }
-- Disables automatic commenting on newline:
vim.api.nvim_exec([[
autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o
]], false)
-- Perform dot commands over visual blocks:
vim.api.nvim_set_keymap('v', '.', ':normal .<CR>', { noremap = true })
-- Goyo plugin makes text more readable when writing prose:
vim.api.nvim_set_keymap('n', '<leader>f', ':Goyo | set bg=light | set linebreak<CR>', { noremap = true })
-- Spell-check set to <leader>o, 'o' for 'orthography':
vim.api.nvim_set_keymap('n', '<leader>o', ':setlocal spell! spelllang=en_us<CR>', { noremap = true })
-- Splits open at the bottom and right, which is non-retarded, unlike vim defaults.
vim.opt.splitbelow = true
vim.opt.splitright = true
-- Shortcutting split navigation, saving a keypress:
vim.api.nvim_set_keymap('n', '<C-h>', '<C-w>h', { noremap = true })
vim.api.nvim_set_keymap('n', '<C-j>', '<C-w>j', { noremap = true })
vim.api.nvim_set_keymap('n', '<C-k>', '<C-w>k', { noremap = true })
vim.api.nvim_set_keymap('n', '<C-l>', '<C-w>l', { noremap = true })
vim.cmd("colorscheme gruvbox")
vim.o.background = "light" -- or "light" for light mode
vim.api.nvim_create_autocmd("BufRead", {
pattern = "*",
callback = function()
if vim.fn.getline(1):match("^#!.*/python") then
vim.bo.filetype = "python"
end
end
})

View File

@@ -14,8 +14,7 @@ set $mod Mod4
set $term alacritty
# Application Launcher
set $menu bemenu-run -p Run: -l 10 -c -M 500 --fn 'Terminus 17' --tf '#ff4e00' --ff '#dbc077' --hf '#ff4e00'
#set $menu rofi -show
set $menu bemenu-run -i -p "Run:" -l 10 -c -M 500 --fn 'Monospace 14' --tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' --cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' --hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' --ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98'
#######################
# GENERAL KEYBINDS
@@ -163,163 +162,24 @@ bindsym $mod+Ctrl+g exec grimshot save window
#bindsym $mod+Shift+e exec wlogout -p layer-shell
# Bookmarks
bindsym $mod+Insert exec wtype $(grep -v '^#' ~/.local/share/bookmarks/bookmarks | bemenu -p Bookmark: -l 50 -c -M 500 --fn 'Terminus 16' --tf '#ff4e00' --ff '#dbc077' --hf '#ff4e00' | cut -d ' ' -f1)
# Enter selected bookmark into target text field
bindsym $mod+i exec wtype $(grep -v '^#' ~/.local/share/bookmarks/bookmarks | bemenu -p Bookmark: -l 25 -c -M 500 --fn 'Monospace 14' --tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' --cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' --hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' --ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98' | cut -d ' ' -f1)
bindsym $mod+Shift+Insert exec ~/.local/bin/bookmark_insert
# Insert bookmark into bookmark file (~/.local/share/bookmarks/bookmarks)
bindsym $mod+Shift+i exec ~/.local/bin/bookmark_insert
# Emojis
bindsym $mod+Shift+e exec wtype $(awk '{print $1, $0}' ~/.local/share/chars/emojis* | bemenu -p Emoji: -l 25 -c -M 500 --fn 'Noto Color Emoji,Terminus 16' --tf '#ff4e00' --ff '#dbc077' --hf '#ff4e00' | awk '{print $1}')
bindsym $mod+Shift+e exec wtype $(awk '{print $1, $0}' ~/.local/share/chars/emojis* | bemenu -p Emoji: -l 25 -c -M 500 --fn 'Monospace 14' --tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' --cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' --hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' --ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98' | awk '{print $1}')
#######################
# EXECS
#######################
set $gnome-schema org.gnome.desktop.interface
# Set GTK/icon theme
exec_always {
gsettings set $gnome-schema gtk-theme 'ArcDarker'
gsettings set $gnome-schema icon-theme 'Papirus-Dark'
gsettings set $gnome-schema cursor-theme 'Breeze_Light'
gsettings set $gnome-schema cursor-size 30
}
# Syncthing
exec /usr/bin/syncthing
# Notifications
exec_always dunst
# Wlsunset (Night Light)
exec_always wlsunset -l 47.6 -L -122.3 -t 2000 -T 3000
# udiskie - auto usb mounting
exec /usr/bin/udiskie &
# Network Manager tray applet
exec_always /usr/bin/nm-applet
# Bluetooth manager tray applet
exec /usr/bin/blueman-applet
# KDE polkit
exec /usr/lib/x86_64-linux-gnu/libexec/polkit-kde-authentication-agent-1
# Gtk
exec systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK
exec hash dbus-update-activation-environment 2>/dev/null && dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK
# Idle configuration
#exec swayidle -w \
# timeout 3200 'swaymsg "output * dpms off"' \
# resume 'swaymsg "output * dpms on"' \
# before-sleep 'swaylock -f'
# timeout 15 'if pgrep -x swaylock; then swaymsg "output * dpms off"; fi' \
#######################
# DECORATIONS
#######################
# SwayFX specific directions
corner_radius 3
shadows enable
#default_dim_inactive 0.1
blur enable
blur_xray disable
# Gaps
smart_gaps off
gaps inner 5
gaps outer 5
# Window Borders
default_border pixel 3
default_floating_border none
client.focused "#D27A31" "#5F9EA0" "#000000" "#D27A31"
set $opacity 0.9
for_window [app_id="emacs"] opacity $opacity
for_window [app_id="strawberry"] opacity $opacity
for_window [app_id="pcmanfm-qt"] opacity $opacity
for_window [app_id="org.kde.polkit-kde-authentication-agent-1"] floating enable
for_window [app_id="bemenu"] floating enable
for_window [app_id="bemenu"] layer top
#######################
# INPUTS
#######################
input type:keyboard {
# Capslock key should work as escape key
# See /usr/share/X11/xkb/rules/xorg.lst for options
xkb_layout "us(altgr-intl)"
xkb_options caps:escape
repeat_delay 250
repeat_rate 45
}
# Disable trackpad by default
#input "1739:52824:SYNA8008:00_06CB:CE58_Touchpad" {
# events disable
#}
# Set trackpoint sensitivity on Laptop
input "2:10:TPPS/2_Elan_TrackPoint" {
pointer_accel 1.0
accel_profile "flat"
}
# Set trackpoint sensitivity on Tex Shinobi USB
input "1241:1031:USB-HID_Keyboard_Mouse" {
pointer_accel 0.3
accel_profile "flat"
}
seat seat0 xcursor_theme Breeze_Light 30
# Hide mouse cursor after inactivity
seat * hide_cursor 10000
# Gopass
bindsym $mod+y exec ~/.local/bin/pass_copy
bindsym $mod+u exec ~/.local/bin/pass_user_copy
bindsym $mod+p exec ~/.local/bin/pass_autofill
# Enable/disable trackpad
bindsym $mod+t exec swaymsg input "1739:52824:SYNA8008:00_06CB:CE58_Touchpad" events disabled
bindsym $mod+Shift+t exec swaymsg input "1739:52824:SYNA8008:00_06CB:CE58_Touchpad" events enabled
#######################
# OUTPUTS
#######################
# Lid stuff
set $laptop eDP-1
bindswitch --reload --locked lid:on output $laptop disable
bindswitch --reload --locked lid:off output $laptop enable
# Monitors
output HDMI-A-1 scale 2.0
# Wallpaper
output * bg ~/.config/wallpapers/greek-ruins.jpg fill
# Enable/Disable extra HDMI screens
bindsym $mod+Shift+m output "HDMI-A-1" enable
bindsym $mod+Shift+n output "HDMI-A-1" disable
#######################
# WORKSPACES
#######################
# Assign workspaces to numbers
set $ws1 "1:I"
set $ws2 "2:II"
set $ws3 "3:III"
set $ws4 "4:IV"
set $ws5 "5:V"
set $ws6 "6:VI"
set $ws7 "7:VII"
# Switch to workspace
bindsym $mod+1 workspace $ws1
bindsym $mod+2 workspace $ws2
@@ -338,6 +198,186 @@ bindsym $mod+Shift+5 move container to workspace $ws5
bindsym $mod+Shift+6 move container to workspace $ws6
bindsym $mod+Shift+0 move container to workspace $ws7
# Unused $mod+<key> bindings
# bindsym $mod+a exec <command>
# bindsym $mod+c exec
# bindsym $mod+m exec ~/.local/bin/manmenu
# bindsym $mod+n exec <command>
# bindsym $mod+o exec <command>
# bindsym $mod+q exec <command>
# bindsym $mod+s exec <command>
# bindsym $mod+t exec <command>
bindsym $mod+w exec /usr/bin/librewolf
# bindsym $mod+x exec <command>
# bindsym $mod+y exec <command>
# bindsym $mod+z exec ~/.local/bin/zmenu
# bindsym $mod+9 exec <command>
# bindsym $mod+grave exec <command>
# bindsym $mod+Tab exec <command>
# bindsym $mod+Backspace exec <command>
# bindsym $mod+equal exec <command>
# bindsym $mod+bracketleft exec <command>
# bindsym $mod+bracketright exec <command>
#bindsym $mod+semicolon exec ~/.local/bin/unimenu
# bindsym $mod+apostrophe exec <command>
# bindsym $mod+comma exec <command>
# bindsym $mod+period exec <command>
# bindsym $mod+slash exec <command>
# bindsym $mod+backslash exec <command>
# Unused $mod+Shift+<key> bindings
# bindsym $mod+Shift+a exec <command>
# bindsym $mod+Shift+b exec <command>
# bindsym $mod+Shift+d exec <command>
# bindsym $mod+Shift+i exec <command>
# bindsym $mod+Shift+o exec <command>
# bindsym $mod+Shift+p exec <command>
# bindsym $mod+Shift+q exec <command>
# bindsym $mod+Shift+r exec ~/.local/bin/recipemenu
# bindsym $mod+Shift+s exec <command>
# bindsym $mod+Shift+t exec <command>
# bindsym $mod+Shift+u exec <command>
# bindsym $mod+Shift+w exec <command>
# bindsym $mod+Shift+x exec <command>
# bindsym $mod+Shift+y exec <command>
# bindsym $mod+Shift+z exec <command>
# bindsym $mod+Shift+9 exec <command>
# bindsym $mod+Shift+grave exec <command>
# bindsym $mod+Shift+Tab exec <command>
# bindsym $mod+Shift+Backspace exec <command>
# bindsym $mod+Shift+equal exec <command>
# bindsym $mod+Shift+bracketleft exec <command>
# bindsym $mod+Shift+bracketright exec <command>
# bindsym $mod+Shift+semicolon exec <command>
# bindsym $mod+Shift+apostrophe exec <command>
# bindsym $mod+Shift+comma exec <command>
# bindsym $mod+Shift+period exec <command>
# bindsym $mod+Shift+slash exec <command>
# bindsym $mod+Shift+backslash exec <command>
#######################
# EXECS
#######################
# Wlsunset (Night Light)
exec_always pgrep -x wlsunset > /dev/null || wlsunset -l 47.6 -L -122.3 -t 3500 -T 6000
# udiskie - auto usb mounting
exec /usr/bin/udiskie &
# Network Manager tray applet
exec /usr/bin/nm-applet
# SSH Agent
exec eval $(ssh-agent -s)
# Bluetooth manager tray applet
exec /usr/bin/blueman-applet
# KDE polkit
exec /usr/lib/x86_64-linux-gnu/libexec/polkit-kde-authentication-agent-1
# Gtk
exec systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK
exec hash dbus-update-activation-environment 2>/dev/null && dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK
# No idle on audio
exec sway-audio-idle-inhibit
# Idle configuration
exec swayidle -w \
timeout 300 'swaylock -f' \
timeout 600 'swaymsg "output * dpms off"' \
resume 'swaymsg "output * dpms on"' \
before-sleep 'swaylock -f' \
timeout 1800 'systemctl suspend'
#######################
# DECORATIONS
#######################
# SwayFX specific directions
#corner_radius 3
#shadows enable
#default_dim_inactive 0.1
#blur enable
#blur_xray disable
# Gaps
smart_gaps off
gaps inner 3
gaps outer 3
# Window Borders
default_border pixel 3
default_floating_border none
client.focused "#D27A31" "#5F9EA0" "#000000" "#D27A31"
set $opacity 0.95
for_window [app_id="emacs"] opacity $opacity
for_window [app_id="org.kde.polkit-kde-authentication-agent-1"] floating enable
for_window [app_id="bemenu"] floating enable
for_window [app_id="bemenu"] layer top
#######################
# INPUTS
#######################
input type:keyboard {
# Capslock key should work as escape key
# See /usr/share/X11/xkb/rules/xorg.lst for options
xkb_layout "us(altgr-intl)"
xkb_options caps:escape
repeat_delay 250
repeat_rate 45
}
# Set trackpoint sensitivity on Laptop
input "2:10:TPPS/2_Elan_TrackPoint" {
pointer_accel 1.0
accel_profile "flat"
}
# Set trackpoint sensitivity on Tex Shinobi USB
input "1241:1031:USB-HID_Keyboard_Mouse" {
pointer_accel 0.3
accel_profile "flat"
}
seat seat0 xcursor_theme Breeze_Light 30
# Hide mouse cursor after inactivity
seat * hide_cursor 10000
#######################
# OUTPUTS
#######################
# Lid stuff
#set $laptop eDP-1
#bindswitch --reload --locked lid:on output $laptop disable
#bindswitch --reload --locked lid:off output $laptop enable
output HDMI-A-1 pos 0 402 scale 1.5
output DP-2 scale 1.5
# Wallpaper
output * bg ~/.config/wallpapers/wall.jpg fill #0D0703
#######################
# WORKSPACES
#######################
# Assign workspaces to numbers
set $ws1 1:I
set $ws2 2:II
set $ws3 3:III
set $ws4 4:IV
set $ws5 5:V
set $ws6 6:VI
set $ws7 7:VII
#######################
# BAR

View File

@@ -1,5 +1,5 @@
# Image
image=~/.config/wallpapers/greek-ruins.jpg
image=~/.config/wallpapers/wall.jpg
scaling=fill
# Indicator

View File

@@ -6,10 +6,11 @@
# absolute path. No other format is supported.
#
XDG_DESKTOP_DIR="$HOME/desktop"
XDG_DOWNLOAD_DIR="$HOME/downloads"
XDG_DESKTOP_DIR="$HOME/"
XDG_DOWNLOAD_DIR="$HOME/dls"
XDG_TEMPLATES_DIR="$HOME/"
XDG_PUBLICSHARE_DIR="$HOME/"
XDG_DOCUMENTS_DIR="$HOME/documents"
XDG_DOCUMENTS_DIR="$HOME/docs"
XDG_MUSIC_DIR="$HOME/music"
XDG_PICTURES_DIR="$HOME/pictures"
XDG_PICTURES_DIR="$HOME/pics"
XDG_VIDEOS_DIR="$HOME/"

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
.config/wallpapers/pine.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

BIN
.config/wallpapers/wall.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

View File

@@ -4,7 +4,7 @@
"height": 44,
"modules-left": ["sway/workspaces"],
"modules-center": ["clock","custom/padd","custom/weather"],
"modules-right": ["custom/l_end","custom/music","custom/padd","pulseaudio","custom/padd","network", "custom/padd","battery","custom/padd", "tray","custom/power","custom/padd"],
"modules-right": ["custom/l_end","custom/music","custom/padd","idle_inhibitor","custom/padd","pulseaudio","custom/padd","network", "custom/padd","battery","custom/padd","tray","custom/power","custom/padd"],
"sway/workspaces": {
"disable-scroll": true,
"all-outputs": true,
@@ -29,7 +29,7 @@
"tooltip": false
},
"custom/weather": {
"exec": "~/.config/waybar/scripts/weather.scm",
"exec": "~/.config/waybar/scripts/weather.py",
"interval": 600,
"tooltip": false
},
@@ -67,14 +67,13 @@
"on-scroll-down": "amixer set Master 3%-",
"format": "",
"format": "{icon} {volume}%",
"format-muted": "",
"format-muted": "",
"format-icons": {
"headset": "",
"headphone": "",
"default": ["", "", ""]
},
},
"custom/power": {
"format": "",
//"exec": "echo ; echo  logout",
@@ -123,5 +122,13 @@
"format": " ",
"interval" : "once",
"tooltip": false
},
"idle_inhibitor": {
"format": "{icon}",
"format-icons": {
"activated": "",
"deactivated": ""
},
"timeout": 30.5
}
}

View File

@@ -1,36 +0,0 @@
#!/usr/bin/env guile3.0
!#
(use-modules (ice-9 popen)
(ice-9 rdelim))
;; Function to get playerctl metadata
(define (get-playerctl-metadata field)
(let* ((command (string-append "playerctl --player=strawberry metadata " field))
(port (open-input-pipe command))
(output (read-line port)))
(close-pipe port)
output))
;; Function to abbreviate a string if it's longer than max-length
(define (abbreviate text max-length)
(if (> (string-length text) max-length)
(string-append (substring text 0 (- max-length 3)) "...")
text))
(define music-note "🎵")
;; Main logic to display artist and title
(let* ((artist (get-playerctl-metadata "artist"))
(title (get-playerctl-metadata "title"))
(display-text
(if (and (string? artist) (string? title))
(abbreviate (string-append artist " - " title) 30)
#f))) ;; Set to #f if artist or title is not available
(if display-text
(begin
(display music-note) ;; Display the music note icon
(display " ")
(display display-text)
(newline))
(display "")))

View File

@@ -21,8 +21,10 @@ def get_weather_icon(description):
"overcast clouds": "☁️",
"shower rain": "🌦️",
"light rain": "🌧️",
"rain": "🌧️",
"light intensity drizzle": "🌧️",
"moderate rain": "🌧️",
"rain": "🌧️",
"heavy intensity rain": "🌧️",
"thunderstorm": "⛈️",
"snow": "❄️",
"mist": "🌫️",
@@ -42,7 +44,7 @@ try:
#print(weather_data)
weather_desc = weather_data["weather"][0]["description"]
#print(weather_desc)
(weather_desc)
temp_c = round(weather_data["main"]["temp"])
temp_f = round(celsius_to_fahrenheit(temp_c))
weather_icon = get_weather_icon(weather_desc)

View File

@@ -1,86 +0,0 @@
#!/usr/bin/env guile3.0
!#
(use-modules (web client)
(json)
(rnrs bytevectors)
(ice-9 receive))
(define api-key "99631af2d6db903d1f689c7d2cb13764")
(define city-id "5809844")
(define units "metric")
;; Construct the openweathermap URL with API token, city ID, and unit of measurement
(define weather-url
(format #f "http://api.openweathermap.org/data/2.5/weather?id=~a&units=~a&appid=~a"
city-id units api-key))
;; Define weather icons as an association list
(define weather-icons
'(("clear sky" . "☀️")
("few clouds" . "🌤️")
("scattered clouds" . "🌥️")
("broken clouds" . "☁️")
("overcast clouds" . "☁️")
("shower rain" . "🌦️")
("light rain" . "🌧️")
("light intensity drizzle" . "🌧️")
("rain" . "🌧️")
("moderate rain" . "🌧️")
("thunderstorm" . "⛈️")
("snow" . "❄️")
("mist" . "🌫️")
("haze" . "🌫️")
("smoke" . "🌫️")
("fog" . "🌫️")))
;; Convert Celsius to Fahrenheit
(define (celsius-to-fahrenheit celsius)
(+ (* celsius (/ 9 5)) 32))
;; Get weather icon based on description
(define (get-weather-icon description)
(or (assoc-ref weather-icons description) "❓"))
;; Parse and extract weather data from JSON
(define (extract-weather-data json-data)
(let* ((main (assoc "main" json-data))
(temp-c (and main
(cdr (assoc "temp" (cdr main)))))
;; Round and convert to exact integer
(temp-c-value (and temp-c
(inexact->exact
(round temp-c))))
(weather-description
(cdr (assoc "description"
(vector-ref (cdr (assoc "weather" json-data)) 0)))))
;; Return temperature (C, F), description, and icon
(values temp-c-value
(and temp-c-value
(inexact->exact
(round (celsius-to-fahrenheit temp-c-value))))
weather-description
(get-weather-icon weather-description))))
;; Fetch and display weather data
(define (get-weather)
;; Request and parse the data
(receive (response-status response-body)
(http-request weather-url)
(let ((json-data (json-string->scm
(utf8->string response-body))))
(call-with-values
(lambda () (extract-weather-data json-data))
(lambda (temp-c temp-f description icon)
;; For debugging
;;(format #t "Description: ~a ~%" description)
;; Display the weather information
(if temp-c
(format #t "~a ~d°C / ~d°F~%"
icon temp-c temp-f)
(display "Error: Temperature data not available.\n")))))))
(get-weather)

View File

@@ -9,8 +9,8 @@
}
window#waybar {
opacity: 0.7;
background: #000000;
opacity: 1;
background: #0D0703;
}
/* Specific module styles */

5
.gitignore vendored
View File

@@ -1,8 +1,13 @@
.config/qutebrowser/quickmarks
.config/qutebrowser/qsettings/*
.config/qutebrowser/autoconfig.yml
.config/borgmatic/config.yaml
.config/beets/beets-library.db
.config/beets/state.pickle
.local/share/mpd
*.swp
lazy-lock.json
*.sync-conflict*
.stfolder
flycheck-packages.el
*.log

22
.local/bin/battery_alert.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/sh
BAT_PATH="/sys/class/power_supply/BAT0"
CAPACITY=$(cat "$BAT_PATH/capacity")
STATUS=$(cat "$BAT_PATH/status")
notify() {
dunstify -u critical -r 999 "⚡ Battery low: $1%" "Plug in your charger NOW!"
}
if [ "$STATUS" != "Charging" ]; then
if [ "$CAPACITY" -le 5 ]; then
notify 5
elif [ "$CAPACITY" -le 10 ]; then
notify 10
elif [ "$CAPACITY" -le 20 ]; then
notify 20
elif [ "$CAPACITY" -le 30 ]; then
notify 30
fi
fi

View File

@@ -1,6 +1,6 @@
#!/bin/sh
clipboard_text=$(wl-paste -p)
clipboard_text=$(wl-paste)
bookmarks_file="$HOME/.local/share/bookmarks/bookmarks"
if [ ! -f "$bookmarks_file" ]; then
@@ -9,20 +9,21 @@ if [ ! -f "$bookmarks_file" ]; then
exit 1
fi
# Trim leading and trailing whitespace from clipboard
# Trim leading/trailing whitespace
clipboard_text=$(echo "$clipboard_text" | xargs)
# Remove trailing slashes
clipboard_text=$(echo "$clipboard_text" | sed 's#/$##')
# Check if clipboard is not empty
if [ -n "$clipboard_text" ]; then
# Escape special characters for grep and check for exact match
if grep -Fxq "$clipboard_text" "$bookmarks_file"; then
notify-send "Bookmark already exists!" "$clipboard_text"
else
# Append the text to the bookmarks file
echo "$clipboard_text" >> "$bookmarks_file"
notify-send "Bookmark saved" "$clipboard_text"
# Run git update script
# Run git update script
sh "$HOME/.local/bin/bookmark_update"
fi
else

View File

@@ -1,5 +1,15 @@
#!/bin/sh
# Try to source keychain's environment file
if [ -f "$HOME/.keychain/$(hostname)-sh" ]; then
. "$HOME/.keychain/$(hostname)-sh"
fi
# Fallback to gnome-keyring if keychain not used
if [ -z "$SSH_AUTH_SOCK" ] && [ -S "/run/user/$(id -u)/keyring/ssh" ]; then
export SSH_AUTH_SOCK="/run/user/$(id -u)/keyring/ssh"
fi
# Define the paths and repository
bookmarks_file="$HOME/.local/share/bookmarks/bookmarks"
repo_path="$HOME/.local/share/bookmarks"
@@ -15,9 +25,9 @@ if [ -n "$(git status --porcelain "$bookmarks_file")" ]; then
git commit -m "Update bookmarks file"
# Push the changes and log output
#git push origin master
GIT_SSH_COMMAND="ssh -i ~/.ssh/ry_ecdsa" git push origin master 2>&1 | tee -a /tmp/bookmark_git_push.log
notify-send "Bookmarks updated" "Please push your changes."
notify-send "Bookmarks updated" "Changes pushed."
else
notify-send "No changes" "No changes to the bookmarks file."
fi

18
.local/bin/manmenu Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
TERMINAL="alacritty"
# Grab man entries
man_entries=$(apropos . | awk -F ' - ' '{print $1}' | sort -u)
# Show in bemenu
selection=$(printf '%s\n' "$man_entries" | \
bemenu -p "man:" -l 10 -c -M 500 \
--fn 'Monospace 14' \
--tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' \
--cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' \
--hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' \
--ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98')
# Open the man page in the terminal
[ -n "$selection" ] && "$TERMINAL" -e man "$(echo "$selection" | awk '{print $1}')"

25
.local/bin/pass_autofill Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/sh
entry=$(gopass list --flat | bemenu -p Autofill: -l 25 -c -M 500 --fn 'Monospace 14' --tf '#ff4e00' --ff '#dbc077' --hf '#ff4e00')
if [ -n "$entry" ]; then
username=$(gopass show "$entry" | grep '^username:' | cut -d' ' -f2-)
password=$(gopass show -o "$entry")
if [ -z "$password" ]; then
notify-send "Gopass Error" "No password for $entry"
exit 1
fi
notify-send "Autofill in 1s: Focus username field in form"
sleep 1
# Type username, press Tab, then password, then Enter
wtype "$username"
sleep 0.2
wtype -k Tab
sleep 0.2
wtype "$password"
sleep 0.2
wtype -k Return
fi

8
.local/bin/pass_copy Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
entry=$(gopass list --flat | bemenu -p Password: -l 25 -c -M 500 --fn 'Monospace 14' --tf '#ff4e00' --ff '#dbc077' --hf '#ff4e00')
if [ -n "$entry" ]; then
gopass show -c "$entry" 2>/dev/null || notify-send "Gopass Error" "Failed to copy: $entry"
fi

11
.local/bin/pass_user_copy Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
entry=$(gopass list --flat | bemenu -p Username: -l 25 -c -M 500 --fn 'Monospace 14' --tf '#ff4e00' --ff '#dbc077' --hf '#ff4e00')
if [ -n "$entry" ]; then
if gopass show -c "$entry" username 2>/dev/null; then
notify-send "Gopass" "Username copied from: $entry"
else
notify-send "Gopass Error" "Failed to copy username from: $entry"
fi
fi

18
.local/bin/recipemenu Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
RECIPE_DIR="$HOME/sync/recipes"
choice=$(
find "$RECIPE_DIR" -type f -printf '%f\n' | \
bemenu -p "Recipe:" -l 10 -c -M 500 \
--fn 'Monospace 14' \
--tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' \
--cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' \
--hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' \
--ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98'
)
if [ -n "$choice" ]; then
file=$(find "$RECIPE_DIR" -type f -name "$choice" -print -quit)
[ -n "$file" ] && alacritty -e sh -c "glow -p \"$file\""
fi

401
.local/bin/todo Executable file
View File

@@ -0,0 +1,401 @@
#!/usr/bin/env python3
"""
todo.py
A minimalist CLI todo application with priorities, tags, sorting, JIRA import,
and completion-date tracking. Uses INI config at ~/.config/todo/config.ini.
"""
import os
import argparse
import re
import configparser
import urllib.request
import urllib.parse
import urllib.error
import json
from datetime import datetime, date
from pathlib import Path
from rich.console import Console
from rich.table import Table
from rich.prompt import Prompt, IntPrompt
from rich.text import Text
# -------------------------------------------------------------------
# Configuration loading via configparser
# -------------------------------------------------------------------
DEFAULT_CONFIG = {
'todo': {
'todo_file': '~/sync/todo/todo.txt',
'archive_file': '~/sync/todo/todo-archive.txt',
'default_priority': 'B'
},
'tag_colors': {
'@jira': 'blue',
'@me': 'magenta',
'@work': 'green'
},
'priority_labels': {
'A': 'High',
'B': 'Med',
'C': 'Low'
},
'priority_styles': {
'A': 'bold red',
'B': 'yellow',
'C': 'green'
}
}
def load_config():
cfg = configparser.ConfigParser()
cfg.optionxform = str
config_path = Path.home() / '.config' / 'todo' / 'config.ini'
for section, opts in DEFAULT_CONFIG.items():
if not cfg.has_section(section):
cfg[section] = {}
for k, v in opts.items():
cfg[section].setdefault(k, str(v))
if config_path.exists():
cfg.read(config_path)
return {
'todo_file': Path(cfg['todo']['todo_file']).expanduser(),
'archive_file': Path(cfg['todo']['archive_file']).expanduser(),
'default_priority': cfg['todo']['default_priority'],
'tag_colors': dict(cfg['tag_colors']),
'priority_labels': dict(cfg['priority_labels']),
'priority_styles': dict(cfg['priority_styles']),
}
CFG = load_config()
TODO_FILE_PATH = CFG['todo_file']
ARCHIVE_FILE_PATH = CFG['archive_file']
DEFAULT_PRIORITY = CFG['default_priority']
TAG_COLOR_MAP = CFG['tag_colors']
PRIORITY_LABELS = CFG['priority_labels']
PRIORITY_STYLE_MAP= CFG['priority_styles']
DATE_FORMAT = '%Y-%m-%d'
console = Console()
# -------------------------------------------------------------------
# Task class with completion-date support
# -------------------------------------------------------------------
LINE_RE = re.compile(
r'^(?:x \((?P<completed>\d{4}-\d{2}-\d{2})\)\s*)?'
r'(?:\[#(?P<priority>[ABC])\]\s*)?'
r'\((?P<created>\d{4}-\d{2}-\d{2})\)\s*'
r'(?P<description>.+)$'
)
class Task:
def __init__(self, completed, priority, created, description, tags):
self.completed = completed
self.priority = priority
self.created = created
self.description = description
self.tags = tags
@property
def done(self):
return self.completed is not None
@classmethod
def from_line(cls, line):
m = LINE_RE.match(line)
if not m:
return None
gd = m.groupdict()
completed = None
if gd.get('completed'):
completed = datetime.strptime(gd['completed'], DATE_FORMAT).date()
prio = gd.get('priority') or DEFAULT_PRIORITY
created = datetime.strptime(gd['created'], DATE_FORMAT).date()
parts = gd['description'].split()
tags = [w for w in parts if w.startswith('@')]
desc = ' '.join(w for w in parts if not w.startswith('@'))
return cls(completed, prio, created, desc, tags)
def to_line(self):
parts = []
if self.done:
parts.append(f"x ({self.completed.strftime(DATE_FORMAT)}) ")
parts.append(f"[#{self.priority}] ")
parts.append(f"({self.created.strftime(DATE_FORMAT)}) ")
parts.append(self.description)
if self.tags:
parts.append(' ' + ' '.join(self.tags))
return ''.join(parts)
def mark_done(self):
return Task(date.today(), self.priority, self.created, self.description, self.tags)
# -------------------------------------------------------------------
# I/O
# -------------------------------------------------------------------
def read_tasks():
if not TODO_FILE_PATH.exists():
return []
lines = TODO_FILE_PATH.read_text().splitlines()
tasks = []
for l in lines:
t = Task.from_line(l)
if t:
tasks.append(t)
return tasks
def write_tasks(tasks):
TODO_FILE_PATH.parent.mkdir(parents=True, exist_ok=True)
lines = [t.to_line() for t in tasks]
TODO_FILE_PATH.write_text("\n".join(lines) + "\n")
# -------------------------------------------------------------------
# Display & Sorting
# -------------------------------------------------------------------
def display_tasks(tasks, show_all, sort_by):
display = tasks if show_all else [t for t in tasks if not t.done]
if sort_by == 'created':
display.sort(key=lambda t: t.created)
elif sort_by == 'priority':
display.sort(key=lambda t: t.priority)
elif sort_by and sort_by.startswith('tag:'):
tag = sort_by.split(':',1)[1]
display.sort(key=lambda t: tag in t.tags, reverse=True)
cols = ['#','Created','Pri','Description','Tags']
if show_all:
cols.insert(2, 'Completed')
cols.insert(4, 'Done')
table = Table(title='TODOs (all)' if show_all else 'TODOs')
for c in cols:
table.add_column(c, justify='right' if c=='#' else None)
for idx, t in enumerate(display, start=1):
pri_lbl = PRIORITY_LABELS.get(t.priority, t.priority)
pri_cell = Text(pri_lbl, style=PRIORITY_STYLE_MAP.get(t.priority,''))
tag_cell = Text()
for tag in t.tags:
tag_cell.append(tag, TAG_COLOR_MAP.get(tag,''))
tag_cell.append(' ')
row = [str(idx), t.created.strftime(DATE_FORMAT)]
if show_all:
comp = t.completed.strftime(DATE_FORMAT) if t.completed else ''
row.append(comp)
row.append(pri_cell)
if show_all:
row.append('✔' if t.done else '')
row.append(t.description)
row.append(tag_cell)
table.add_row(*row)
console.print(table)
# -------------------------------------------------------------------
# Commands
# -------------------------------------------------------------------
def cmd_ls(args):
display_tasks(read_tasks(), False, args.sort)
def cmd_lsa(args):
display_tasks(read_tasks(), True, args.sort)
def cmd_add(args):
if args.text:
entry = ' '.join(args.text)
if not entry.startswith('[#'):
console.print('[yellow]No priority; defaulting to Med (B).[/]')
today = date.today().strftime(DATE_FORMAT)
entry = f"[#{DEFAULT_PRIORITY}] ({today}) {entry}"
if '@' not in entry:
console.print('[yellow]No tag; defaulting to @misc.[/]')
entry += ' @misc'
t = Task.from_line(entry)
tasks = read_tasks()
if t:
tasks.append(t)
write_tasks(tasks)
console.print(f'[green]Added:[/] {t.description}')
else:
console.print(f'[red]Failed to parse task line:[/] {entry}')
else:
desc = Prompt.ask('Task description')
prio = Prompt.ask('Priority (A=High,B=Med,C=Low)', choices=['A','B','C'], default=DEFAULT_PRIORITY)
tag = Prompt.ask('Tag (e.g. @work,@me,@jira)', default='@misc')
t = Task(None, prio, date.today(), desc, [tag])
tasks = read_tasks()
tasks.append(t)
write_tasks(tasks)
console.print(f'[green]Added:[/] {desc}')
def cmd_done(args):
all_tasks = read_tasks()
active_idxs = [i for i,t in enumerate(all_tasks) if not t.done]
try:
n = int(args.number)
if not (1 <= n <= len(active_idxs)):
raise IndexError
idx = active_idxs[n-1]
all_tasks[idx] = all_tasks[idx].mark_done()
write_tasks(all_tasks)
console.print(f"[green]Completed:[/] {all_tasks[idx].description}")
cmd_ls(argparse.Namespace(sort=None))
except:
console.print('[red]Invalid task number[/]')
def cmd_donei(args):
all_tasks = read_tasks()
active = [(i,t) for i,t in enumerate(all_tasks) if not t.done]
if not active:
console.print('[yellow]No active tasks.[/]')
return
for disp,(i,t) in enumerate(active, start=1):
console.print(f"{disp}: {t.description}")
choice = IntPrompt.ask('Complete task #')
cmd_done(argparse.Namespace(number=str(choice)))
def cmd_archive(args):
tasks = read_tasks()
done = [t for t in tasks if t.done]
if not done:
console.print('[yellow]No tasks to archive[/]')
return
ARCHIVE_FILE_PATH.parent.mkdir(parents=True, exist_ok=True)
with ARCHIVE_FILE_PATH.open('a') as f:
for t in done:
f.write(t.to_line() + "\n")
remaining = [t for t in tasks if not t.done]
write_tasks(remaining)
console.print(f'[green]Archived {len(done)}[/]')
def cmd_tags(args):
tasks = [t for t in read_tasks() if args.tag in t.tags and not t.done]
if not tasks:
console.print(f'[yellow]No active tasks with tag {args.tag}[/]')
else:
display_tasks(tasks, False, None)
def cmd_edit(args):
editor = os.getenv('EDITOR','nano')
os.execvp(editor, [editor, str(TODO_FILE_PATH)])
def cmd_jira(args):
jira_token = os.getenv('JIRA_TOKEN')
if not jira_token:
console.print('[red]Missing JIRA_TOKEN environment variable[/]')
return
base_url = 'https://jira.atg-corp.com'
jql = (
f'project="{args.project}" '
f'AND assignee=currentUser() '
f'AND status in ("Open","In Progress") '
f'ORDER BY created DESC'
)
url = f'{base_url}/rest/api/2/search?jql={urllib.parse.quote(jql)}'
console.print(f'[cyan]Requesting URL:[/] {url}')
req = urllib.request.Request(url)
req.add_header('Authorization', f'Bearer {jira_token}')
req.add_header('Accept', 'application/json')
req.add_header('Content-Type', 'application/json')
try:
with urllib.request.urlopen(req) as resp:
data = json.load(resp)
except urllib.error.HTTPError as e:
body = e.read().decode(errors='ignore')
console.print(f'[red]HTTP Error {e.code}: {e.reason}[/]')
console.print('[yellow]Response body:[/]')
console.print(body)
return
except Exception as e:
console.print(f'[red]Failed to fetch JIRA issues:[/] {e}')
return
issues = data.get('issues', [])
if not issues:
console.print('[yellow]No JIRA issues found.[/]')
return
tasks = read_tasks()
added = 0
for issue in issues:
key = issue['key']
summary = issue['fields']['summary']
date_str = issue['fields']['created'][:10]
desc = f'[{key}] {summary}'
# skip duplicates by key
if any(t.description.startswith(f'[{key}]') for t in tasks):
continue
t = Task(
None,
'B',
datetime.strptime(date_str, DATE_FORMAT).date(),
desc,
['@jira']
)
tasks.append(t)
added += 1
write_tasks(tasks)
console.print(f'[green]Imported {added} JIRA tasks from {args.project} assigned to you.[/]')
# -------------------------------------------------------------------
# CLI dispatch
# -------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(prog='todo')
sub = parser.add_subparsers(dest='cmd', required=True)
p_ls = sub.add_parser('ls', help='List active tasks')
p_ls.add_argument('--sort', choices=['created','priority','tag:@jira','tag:@work','tag:@me'])
p_lsa = sub.add_parser('lsa', help='List all tasks')
p_lsa.add_argument('--sort', choices=['created','priority','tag:@jira','tag:@work','tag:@me'])
sub.add_parser('archive', help='Archive completed tasks')
p_add = sub.add_parser('add', help='Add a task')
p_add.add_argument('text', nargs=argparse.REMAINDER)
p_done = sub.add_parser('done', help='Mark a task done')
p_done.add_argument('number')
sub.add_parser('donei', help='Interactive completion')
p_tags = sub.add_parser('tags', help='Filter by tag')
p_tags.add_argument('tag')
sub.add_parser('edit', help='Open todo file in editor')
p_jira = sub.add_parser('jira', help='Import JIRA issues')
p_jira.add_argument('--project', default='IS', help='JIRA project key (defaults to IS)')
args = parser.parse_args()
{
'ls': cmd_ls,
'lsa': cmd_lsa,
'add': cmd_add,
'done': cmd_done,
'donei': cmd_donei,
'archive': cmd_archive,
'tags': cmd_tags,
'edit': cmd_edit,
'jira': cmd_jira,
}[args.cmd](args)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
console.print('\n[red]^C Aborted[/]')

36
.local/bin/unimenu Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/sh
MENU="📚 Dictionary\n🌍 Translate\n📖 Man Page\n🔐 Passwords\n📝 Notes\n🖼 Emoji Picker"
choice=$(printf "$MENU" | \
bemenu -p "Choose:" -l 10 -c -M 500 \
--fn 'Monospace 14' \
--tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' \
--cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' \
--hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' \
--ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98')
case "$choice" in
"📚 Dictionary")
word=$(bemenu -p "Define:")
[ -n "$word" ] && alacritty -e sdcv "$word"
;;
"🌍 Translate")
phrase=$(bemenu -p "Translate:")
[ -n "$phrase" ] && alacritty -e trans ":en" "$phrase"
;;
"📖 Man Page")
~/.local/bin/man.sh
;;
"🔐 Passwords")
passmenu # or gopass fzf if you're using gopass
;;
"📝 Notes")
note=$(bemenu-run -p "Note:")
[ -n "$note" ] && echo "- $(date): $note" >> ~/notes/quick.md
;;
"🖼 Emoji Picker")
wtype $(awk '{print $1, $0}' ~/.local/share/chars/emojis* | bemenu -p Emoji: -l 25 -c -M 500 --fn 'Noto Color Emoji,Monospace 14' --tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' --cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' --hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' --ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98' | awk '{print $1}')
;;
esac

61
.local/bin/vault Executable file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# vault — mount/dismount VeraCrypt containers with automatic mountpoint creation and cleanup
# now suppresses PIM, keyfile, and hiddenvolume prompts by default
# Usage: vault {open|close} /full/path/to/container.hc
set -euo pipefail
usage() {
echo "Usage: $0 {open|close} /full/path/to/container.hc"
exit 1
}
[[ $# -eq 2 ]] || usage
action=$1
rawpath=$2
container=$(eval echo "$rawpath")
[[ -f "$container" ]] || { echo "Container not found: $container"; exit 1; }
# derive mountpoint
base=$(basename "$container")
name="${base%.*}"
mountpoint="/mnt/$name"
require_sudo() {
if (( EUID != 0 )); then
exec sudo bash "$0" "$action" "$rawpath"
fi
}
case "$action" in
open)
if mountpoint -q "$mountpoint"; then
echo "Already mounted at $mountpoint"
exit 0
fi
require_sudo
mkdir -p "$mountpoint"
veracrypt -t \
--keyfiles="" \
--pim=0 \
--protect-hidden=no \
--mount "$container" "$mountpoint"
echo "Mounted $container → $mountpoint"
;;
close)
require_sudo
# dismount and suppress warnings
veracrypt -t --dismount "$mountpoint" || true
# cleanup empty dir
if [[ -d "$mountpoint" ]]; then
rmdir "$mountpoint" && echo "Removed mountpoint $mountpoint"
fi
;;
*)
usage
;;
esac

20
.local/bin/yt2rss Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/sh
url="$1"
if [ -z "$url" ]; then
echo "Usage: yt2rss.sh <youtube_url>" >&2
exit 1
fi
html=$(curl -Ls "$url")
channel_id=$(printf '%s\n' "$html" | grep -oE 'https://www.youtube.com/channel/UC[[:alnum:]_-]+' | head -n1 | sed 's|.*/||')
if [ -z "$channel_id" ]; then
echo "Could not find channel ID." >&2
exit 1
fi
echo "https://www.youtube.com/feeds/videos.xml?channel_id=$channel_id"

22
.local/bin/zmenu Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/sh
# ~/.local/bin/readmenu.sh
DOC_DIR="$HOME/docs/books"
choice=$(
find "$DOC_DIR" -type f \
\( -iname '*.pdf' -o -iname '*.epub' -o -iname '*.djvu' -o -iname '*.cbz' -o -iname '*.ps' \) \
-printf '%f\n' | \
bemenu -p "Read:" -l 10 -c -M 500 \
--fn 'Monospace 14' \
--tb '#1d2021' --tf '#d8a657' --fb '#1d2021' --ff '#d4be98' \
--cb '#7daea3' --cf '#1d2021' --nb '#1d2021' --nf '#d4be98' \
--hb '#7daea3' --hf '#1d2021' --sb '#7daea3' --sf '#1d2021' \
--ab '#1b1b1b' --af '#d4be98' --scb '#1d2021' --scf '#d4be98'
)
if [ -n "$choice" ]; then
full=$(find "$DOC_DIR" -type f -name "$choice" -print -quit)
[ -n "$full" ] && zathura "$full"
fi

60
archive/nvim/init.lua Normal file
View File

@@ -0,0 +1,60 @@
require("config.lazy")
vim.opt.title = true
vim.opt.background = 'dark'
vim.opt.guicursor = ''
vim.opt.mouse = 'a'
vim.opt.hlsearch = false
vim.opt.clipboard:append('unnamedplus')
vim.opt.showmode = false
vim.opt.ruler = false
vim.opt.laststatus = 0
vim.opt.showcmd = false
vim.cmd('highlight Normal ctermbg=NONE guibg=NONE')
-- Some basics:
vim.api.nvim_set_keymap('n', 'c', '"_c', { noremap = true })
vim.opt.compatible = false
vim.cmd('filetype plugin on')
vim.cmd('syntax on')
vim.opt.encoding = 'utf-8'
vim.opt.number = true
vim.opt.relativenumber = true
-- Enable autocompletion:
vim.opt.wildmode = { 'longest', 'list', 'full' }
-- Disables automatic commenting on newline:
vim.api.nvim_exec([[
autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o
]], false)
-- Perform dot commands over visual blocks:
vim.api.nvim_set_keymap('v', '.', ':normal .<CR>', { noremap = true })
-- Goyo plugin makes text more readable when writing prose:
vim.api.nvim_set_keymap('n', '<leader>f', ':Goyo | set bg=light | set linebreak<CR>', { noremap = true })
-- Spell-check set to <leader>o, 'o' for 'orthography':
vim.api.nvim_set_keymap('n', '<leader>o', ':setlocal spell! spelllang=en_us<CR>', { noremap = true })
-- Splits open at the bottom and right, which is non-retarded, unlike vim defaults.
vim.opt.splitbelow = true
vim.opt.splitright = true
-- Shortcutting split navigation, saving a keypress:
vim.api.nvim_set_keymap('n', '<C-h>', '<C-w>h', { noremap = true })
vim.api.nvim_set_keymap('n', '<C-j>', '<C-w>j', { noremap = true })
vim.api.nvim_set_keymap('n', '<C-k>', '<C-w>k', { noremap = true })
vim.api.nvim_set_keymap('n', '<C-l>', '<C-w>l', { noremap = true })
vim.o.background = "dark" -- or "light" for light mode
require("solarizedDark").setup({
transparent_mode = true,
})
vim.cmd([[colorscheme solarizedDark]])

View File

@@ -25,23 +25,7 @@ vim.g.maplocalleader = "\\"
require("lazy").setup({
spec = {
-- import your plugins
-- add the Gruvbox plugin
{
"ellisonleao/gruvbox.nvim",
priority = 1000,
config = function()
require("gruvbox").setup({
contrast = "hard", -- can be "soft", "medium" or "hard"
palette_overrides = {
bright_green = "#a9b665",
},
overrides = {
SignColumn = { bg = "#1e2021" },
},
transparent_mode = true,
})
end
},
{ "nxstynate/solarizedDark.nvim", priority = 1000 },
},
-- Configure any other settings here. See the documentation for more details.
-- colorscheme that will be used when installing plugins.

View File

27
archive/nyxt/config.lisp Normal file
View File

@@ -0,0 +1,27 @@
;; vi keybindings
(define-configuration buffer
((default-modes
(pushnew 'nyxt/mode/vi:vi-normal-mode %slot-value%))))
;; Vi-insert mode for prompt-buffer (minibuffer)
(define-configuration prompt-buffer
((default-modes (append '(vi-insert-mode) %slot-default%))))
(defvar *my-search-engines*
(list
'("ddg" "https://duckduckgo.com/?q=~a" "https://duckduckgo.com"))
"List of search engines.")
(define-configuration context-buffer
"Set DuckDuckGo as the default search engine."
((search-engines
(append %slot-default%
(mapcar
(lambda (engine) (apply 'make-search-engine engine))
*my-search-engines*)))))
(define-configuration (web-buffer)
((default-modes (pushnew 'nyxt/mode/blocker:blocker-mode %slot-value%))))
(defmethod customize-instance ((document-buffer document-buffer) &key)
(setf (slot-value document-buffer 'zoom-ratio-default) 1.1))

View File

@@ -0,0 +1,196 @@
# If a config.py file exists, this file is ignored unless it's explicitly loaded
# via config.load_autoconfig(). For more information, see:
# https://github.com/qutebrowser/qutebrowser/blob/main/doc/help/configuring.asciidoc#loading-autoconfigyml
# DO NOT edit this file by hand, qutebrowser will overwrite it.
# Instead, create a config.py - see :help for details.
config_version: 2
settings:
content.blocking.method:
global: both
content.javascript.clipboard:
https://chatgpt.com: access-paste
https://img.opal.sh: access-paste
https://teams.microsoft.com: access-paste
content.javascript.enabled:
'*://*.01.emailinboundprocessing.eu/*': true
'*://*.127.0.0.1/*': true
'*://*.4chanlit.fandom.com/*': true
'*://*.account.proton.me/*': true
'*://*.account.protonvpn.com/*': true
'*://*.ancientdead.com/*': true
'*://*.app.netdata.cloud/*': true
'*://*.app.simplelogin.io/*': true
'*://*.askubuntu.com/*': true
'*://*.babeground.com/*': true
'*://*.babeground.net/*': true
'*://*.babegrounds.live/*': true
'*://*.bandcamp.com/*': true
'*://*.chmodcommand.com/*': true
'*://*.codeberg.org/*': true
'*://*.confluence.atg-corp.com/*': false
'*://*.crontab.guru/*': true
'*://*.customer.xfinity.com/*': true
'*://*.demo.uptime.kuma.pet/*': true
'*://*.docs.google.com/*': true
'*://*.drop.download/*': true
'*://*.duckduckgo.com/*': true
'*://*.features.jellyfin.org/*': true
'*://*.flathub.org/*': true
'*://*.fleet.linuxserver.io/*': true
'*://*.fmovies.to/*': true
'*://*.framatube.org/*': true
'*://*.get.adobe.com/*': true
'*://*.github.com/*': true
'*://*.gitlab.com/*': true
'*://*.goauthentik.io/*': true
'*://*.greyzone.com/*': true
'*://*.heretic.camp/*': true
'*://*.html.duckduckgo.com/*': true
'*://*.hub.docker.com/*': true
'*://*.id.atlassian.com/*': true
'*://*.idcs-3359adb31e35415e8c1729c5c8098c6d.identity.oraclecloud.com/*': true
'*://*.imgflip.com/*': true
'*://*.inv.odyssey346.dev/*': true
'*://*.jf.opal.sh/*': true
'*://*.jira.atg-corp.com/*': true
'*://*.layoffs.fyi/*': true
'*://*.learningnetwork.cisco.com/*': true
'*://*.listen.20buckspin.com/*': true
'*://*.localhost/*': true
'*://*.login.seattle.gov/*': true
'*://*.login.xfinity.com/*': true
'*://*.looking-glass.io/*': true
'*://*.lotrproject.com/*': true
'*://*.mail.proton.me/*': true
'*://*.main.realsecure.flyingcroc.net/*': true
'*://*.metalodyssey.8merch.com/*': true
'*://*.my.uscis.gov/*': true
'*://*.my.vultr.com/*': true
'*://*.myaccount.standingstonegames.com/*': true
'*://*.myutilities.seattle.gov/*': true
'*://*.nagios.realsecure.flyingcroc.net/*': true
'*://*.netbox.realsecure.flyingcroc.net/*': true
'*://*.online.adp.com/*': true
'*://*.onlinebanking.becu.org/*': true
'*://*.onyxboox.com/*': true
'*://*.openscrobbler.com/*': true
'*://*.payments.xfinity.com/*': true
'*://*.portainer.opal.sh/*': true
'*://*.protesilaos.com/*': true
'*://*.proton.me/*': true
'*://*.rateyourmusic.com/*': true
'*://*.register.be.xfinity.com/*': false
'*://*.reverb.com/*': true
'*://*.sack.realsecure.flyingcroc.net/*': true
'*://*.search.brave.com/*': true
'*://*.seattle.bibliocommons.com/*': true
'*://*.seattle.craigslist.org/*': true
'*://*.shop.bulletproof.com/*': true
'*://*.spl.overdrive.com/*': true
'*://*.stackoverflow.com/*': true
'*://*.stash.atg-corp.com/*': true
'*://*.superuser.com/*': true
'*://*.support-acquia.force.com/*': true
'*://*.thecirclemusic.gr/*': true
'*://*.thegrayzone.com/*': true
'*://*.thuleanperspective.com/*': true
'*://*.translate.google.com/*': true
'*://*.twitter.com/*': true
'*://*.unix.stackexchange.com/*': true
'*://*.uploadev.org/*': true
'*://*.utilities-self-service.ebill.seattle.gov/*': true
'*://*.veganmenshoes.com/*': true
'*://*.vid.puffyan.us/*': true
'*://*.wooddove.fciis.net/*': true
'*://*.www.20buckspin.com/*': true
'*://*.www.airplane.dev/*': true
'*://*.www.amazon.com/*': true
'*://*.www.astound.com/*': true
'*://*.www.budgetbytes.com/*': true
'*://*.www.calculator.net/*': true
'*://*.www.carhartt.com/*': true
'*://*.www.dancarlin.com/*': true
'*://*.www.drmartens.com/*': true
'*://*.www.duluthtrading.com/*': true
'*://*.www.easyime.com/*': true
'*://*.www.ebay.com/*': true
'*://*.www.filson.com/*': true
'*://*.www.foodnetwork.com/*': true
'*://*.www.geoguessr.com/*': true
'*://*.www.goodreads.com/*': true
'*://*.www.google.com/*': true
'*://*.www.harddrivesdirect.com/*': true
'*://*.www.knoll.com/*': true
'*://*.www.kobo.com/*': true
'*://*.www.last.fm/*': true
'*://*.www.lastpodcastontheleft.com/*': true
'*://*.www.lotro.com/*': true
'*://*.www.metal-archives.com/*': true
'*://*.www.mmorpg.com/*': true
'*://*.www.moddb.com/*': true
'*://*.www.netaddictionrecovery.com/*': true
'*://*.www.nightshiftmerch.com/*': true
'*://*.www.openstreetmap.org/*': true
'*://*.www.patagonia.com/*': true
'*://*.www.paypal.com/*': true
'*://*.www.raspberrypi.com/*': true
'*://*.www.reddit.com/*': true
'*://*.www.seattle.gov/*': true
'*://*.www.startpage.com/*': true
'*://*.www.thisisclassicalguitar.com/*': true
'*://*.www.vegetarian-shoes.co.uk/*': true
'*://*.www.vultr.com/*': true
'*://*.www.wills-vegan-store.com/*': true
'*://*.www.xfinity.com/*': true
'*://*.www.youtube.com/*': true
'*://*.www.zillow.com/*': true
'*://account.venmo.com/*': true
'*://accounts.google.com/*': true
'*://api.us-west.punchh.com/*': true
'*://archive.org/*': true
'*://auth.openai.com/*': true
'*://chatgpt.com/*': true
'*://copr.fedorainfracloud.org/*': true
'*://damonacy.bandcamp.com/*': true
'*://digital.fidelity.com/*': true
'*://distrowatch.com/*': true
'*://gethomepage.dev/*': true
'*://git.opal.sh/*': true
'*://hessianfirm.bigcartel.com/*': true
'*://id.venmo.com/*': true
'*://img.opal.sh/*': true
'*://irc.opal.sh/*': true
'*://jenkins.atg-corp.com/*': true
'*://jf.opal.sh/*': true
'*://jsonformatter.curiousconcept.com/*': true
'*://login.becu.org/*': true
'*://login.microsoftonline.com/*': true
'*://mega.nz/*': true
'*://myaccounts.capitalone.com/*': true
'*://navi.opal.sh/*': true
'*://openai.com/*': true
'*://order.tacotimenw.com/*': true
'*://pypi.org/*': true
'*://rateyourmusic.com/*': true
'*://revelationofdoom.com/*': true
'*://shop-hellsheadbangers.com/*': true
'*://statics.teams.cdn.office.net/*': true
'*://teams.microsoft.com/*': true
'*://verified.capitalone.com/*': true
'*://www.bardomethodology.com/*': true
'*://www.discogs.com/*': true
'*://www.duplicati.com/*': true
'*://www.fidelity.com/*': true
'*://www.google.com/*': true
'*://www.hybridcalisthenics.com/*': true
'*://www.instagram.com/*': true
'*://www.newegg.com/*': true
'*://www.usharbors.com/*': true
'*://www.vitamix.com/*': true
'*://www.youtube.com/*': true
'*://www.zsa.io/*': true
content.notifications.enabled:
https://jf.opal.sh: false
content.register_protocol_handler:
https://mail.proton.me#mailto=%25s: false

View File

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env python3
from qutebrowser.api import interceptor
# Load existing settings made via :set
config.load_autoconfig()
c.qt.highdpi = True
c.fonts.default_size = "15pt"
c.fonts.tabs.selected = "13pt default_family"
c.fonts.tabs.unselected = "13pt default_family"
c.zoom.default = "130%"
c.content.javascript.enabled = False
c.downloads.location.directory = "~/dls"
c.editor.command = ["alacritty", "-e", "nvim", "{}"]
c.editor.encoding = "utf-8"
c.auto_save.session = True
c.colors.webpage.preferred_color_scheme = "dark"
# privacy
c.content.cookies.accept = "no-3rdparty"
c.content.webrtc_ip_handling_policy = "default-public-interface-only"
c.content.site_specific_quirks.enabled = False
config.bind("j", "scroll-px 0 100")
config.bind("k", "scroll-px 0 -100")
config.bind("K", "tab-next")
config.bind("J", "tab-prev")
c.url.searchengines = {
"DEFAULT": "https://duckduckgo.com/?q={}",
}
c.url.start_pages = ["https://start.duckduckgo.com"]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
[FileDialog]
history=file:///home/opal/pictures
lastVisited=file:///home/opal/pictures
qtVersion=6.8.2
shortcuts=file:, file:///home/opal
sidebarWidth=87
treeViewHeader="@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\x3\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1\xd1\0\0\0\x4\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\0\xf5\0\0\0\x1\0\0\0\0\0\0\0\x39\0\0\0\x1\0\0\0\0\0\0\0=\0\0\0\x1\0\0\0\0\0\0\0\x66\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\xff\xff\xff\xff\0\0\0\0)"
viewMode=Detail

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,343 @@
#!/usr/bin/env python3
#!/usr/bin/env python3
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2021 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2018 Claude (longneck) <longneck@scratchbook.ch>
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
"""Tool to import data from other browsers.
Currently importing bookmarks from Netscape HTML Bookmark files, Chrome
profiles, and Mozilla profiles is supported.
"""
import argparse
import textwrap
import sqlite3
import os
import urllib.parse
import json
import string
def main():
args = get_args()
bookmark_types = []
output_format = None
input_format = args.input_format
if args.search_output:
bookmark_types = ["search"]
if args.oldconfig:
output_format = "oldsearch"
else:
output_format = "search"
else:
if args.bookmark_output:
output_format = "bookmark"
elif args.quickmark_output:
output_format = "quickmark"
if args.import_bookmarks:
bookmark_types.append("bookmark")
if args.import_keywords:
bookmark_types.append("keyword")
if not bookmark_types:
bookmark_types = ["bookmark", "keyword"]
if not output_format:
output_format = "quickmark"
import_function = {
"html": import_html_bookmarks,
"mozilla": import_moz_places,
"chrome": import_chrome,
}
import_function[input_format](args.bookmarks, bookmark_types, output_format)
def get_args():
"""Get the argparse parser."""
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent(
"""
To import bookmarks, you'll need the path to your profile or an
exported HTML file from your browser's bookmark manager. Redirect
the output from this script to the appropriate file in your
qutebrowser config directory (listed in the output of :version),
usually done with the '>' operator; for example,
./importer.py -i mozilla your_profile_path > ~/.config/qutebrowser/quickmarks
Common browsers with native input format support:
chrome: Chrome, Chromium, Edge
mozilla: Firefox, SeaMonkey, Pale Moon
"""
),
)
parser.add_argument(
"-i",
"--input-format",
help="Which input format? Defaults to html",
choices=["html", "mozilla", "chrome"],
default="html",
required=False,
)
parser.add_argument(
"-b",
"--bookmark-output",
help="Output in bookmark format.",
action="store_true",
default=False,
required=False,
)
parser.add_argument(
"-q",
"--quickmark-output",
help="Output in quickmark format (default).",
action="store_true",
default=False,
required=False,
)
parser.add_argument(
"-s",
"--search-output",
help="Output config.py search engine format (negates -B and -K)",
action="store_true",
default=False,
required=False,
)
parser.add_argument(
"--oldconfig",
help="Output search engine format for old qutebrowser.conf format",
default=False,
action="store_true",
required=False,
)
parser.add_argument(
"-B",
"--import-bookmarks",
help="Import plain bookmarks (can be combiend with -K)",
action="store_true",
default=False,
required=False,
)
parser.add_argument(
"-K",
"--import-keywords",
help="Import keywords (can be combined with -B)",
action="store_true",
default=False,
required=False,
)
parser.add_argument(
"bookmarks",
help="Bookmarks file (html format) or " "profile folder (Mozilla format)",
)
args = parser.parse_args()
return args
def search_escape(url):
"""Escape URLs such that preexisting { and } are handled properly.
Will obviously trash a properly-formatted qutebrowser URL.
"""
return url.replace("{", "{{").replace("}", "}}")
def opensearch_convert(url):
"""Convert a basic OpenSearch URL into something qutebrowser can use.
Exceptions:
KeyError:
An unknown and required parameter is present in the URL. This
usually means there's browser/addon specific functionality needed
to build the URL (I'm looking at you and your browser, Google) that
obviously won't be present here.
"""
subst = {
"searchTerms": "%s", # for proper escaping later
"language": "*",
"inputEncoding": "UTF-8",
"outputEncoding": "UTF-8",
}
# remove optional parameters (even those we don't support)
for param in string.Formatter().parse(url):
if param[1]:
if param[1].endswith("?"):
url = url.replace("{" + param[1] + "}", "")
elif param[2] and param[2].endswith("?"):
url = url.replace("{" + param[1] + ":" + param[2] + "}", "")
return search_escape(url.format(**subst)).replace("%s", "{}")
def import_html_bookmarks(bookmarks_file, bookmark_types, output_format):
"""Import bookmarks from a NETSCAPE-Bookmark-file v1.
Generated by Chromium, Firefox, IE and possibly more browsers. Not all
export all possible bookmark types:
- Firefox mostly works with everything
- Chrome doesn't support keywords at all; searches are a separate
database
"""
import bs4
with open(bookmarks_file, encoding="utf-8") as f:
soup = bs4.BeautifulSoup(f, "html.parser")
bookmark_query = {
"search": lambda tag: (
(tag.name == "a") and ("shortcuturl" in tag.attrs) and ("%s" in tag["href"])
),
"keyword": lambda tag: (
(tag.name == "a")
and ("shortcuturl" in tag.attrs)
and ("%s" not in tag["href"])
),
"bookmark": lambda tag: (
(tag.name == "a") and ("shortcuturl" not in tag.attrs) and (tag.string)
),
}
output_template = {
"search": {
"search": "c.url.searchengines['{tag[shortcuturl]}'] = "
"'{tag[href]}' #{tag.string}"
},
"oldsearch": {
"search": "{tag[shortcuturl]} = {tag[href]} #{tag.string}",
},
"bookmark": {
"bookmark": "{tag[href]} {tag.string}",
"keyword": "{tag[href]} {tag.string}",
},
"quickmark": {
"bookmark": "{tag.string} {tag[href]}",
"keyword": "{tag[shortcuturl]} {tag[href]}",
},
}
bookmarks = []
for typ in bookmark_types:
tags = soup.findAll(bookmark_query[typ])
for tag in tags:
if typ == "search":
tag["href"] = search_escape(tag["href"]).replace("%s", "{}")
if tag["href"] not in bookmarks:
bookmarks.append(output_template[output_format][typ].format(tag=tag))
for bookmark in bookmarks:
print(bookmark)
def import_moz_places(profile, bookmark_types, output_format):
"""Import bookmarks from a Mozilla profile's places.sqlite database."""
place_query = {
"bookmark": (
"SELECT DISTINCT moz_bookmarks.title,moz_places.url "
"FROM moz_bookmarks,moz_places "
"WHERE moz_places.id=moz_bookmarks.fk "
"AND moz_places.id NOT IN (SELECT place_id FROM moz_keywords) "
"AND moz_places.url NOT LIKE 'place:%';"
), # Bookmarks with no keywords assigned
"keyword": (
"SELECT moz_keywords.keyword,moz_places.url "
"FROM moz_keywords,moz_places,moz_bookmarks "
"WHERE moz_places.id=moz_bookmarks.fk "
"AND moz_places.id=moz_keywords.place_id "
"AND moz_places.url NOT LIKE '%!%s%' ESCAPE '!';"
), # Bookmarks with keywords assigned but no %s substitution
"search": (
"SELECT moz_keywords.keyword, "
" moz_bookmarks.title, "
" search_conv(moz_places.url) AS url "
"FROM moz_keywords,moz_places,moz_bookmarks "
"WHERE moz_places.id=moz_bookmarks.fk "
"AND moz_places.id=moz_keywords.place_id "
"AND moz_places.url LIKE '%!%s%' ESCAPE '!';"
), # bookmarks with keyword and %s substitution
}
out_template = {
"bookmark": {"bookmark": "{url} {title}", "keyword": "{url} {keyword}"},
"quickmark": {"bookmark": "{title} {url}", "keyword": "{keyword} {url}"},
"oldsearch": {"search": "{keyword} {url} #{title}"},
"search": {"search": "c.url.searchengines['{keyword}'] = '{url}' #{title}"},
}
def search_conv(url):
return search_escape(url).replace("%s", "{}")
places = sqlite3.connect(os.path.join(profile, "places.sqlite"))
places.create_function("search_conv", 1, search_conv)
places.row_factory = sqlite3.Row
c = places.cursor()
for typ in bookmark_types:
c.execute(place_query[typ])
for row in c:
print(out_template[output_format][typ].format(**row))
def import_chrome(profile, bookmark_types, output_format):
"""Import bookmarks and search keywords from Chrome-type profiles.
On Chrome, keywords and search engines are the same thing and handled in
their own database table; bookmarks cannot have associated keywords. This
is why the dictionary lookups here are much simpler.
"""
out_template = {
"bookmark": "{url} {name}",
"quickmark": "{name} {url}",
"search": "c.url.searchengines['{keyword}'] = '{url}'",
"oldsearch": "{keyword} {url}",
}
if "search" in bookmark_types:
webdata = sqlite3.connect(os.path.join(profile, "Web Data"))
c = webdata.cursor()
c.execute("SELECT keyword,url FROM keywords;")
for keyword, url in c:
try:
url = opensearch_convert(url)
print(out_template[output_format].format(keyword=keyword, url=url))
except KeyError:
print(
"# Unsupported parameter in url for {}; skipping....".format(
keyword
)
)
else:
with open(os.path.join(profile, "Bookmarks"), encoding="utf-8") as f:
bookmarks = json.load(f)
def bm_tree_walk(bm, template):
"""Recursive function to walk through bookmarks."""
if not isinstance(bm, dict):
return
assert "type" in bm, bm
if bm["type"] == "url":
if urllib.parse.urlparse(bm["url"]).scheme != "chrome":
print(template.format(**bm))
elif bm["type"] == "folder":
for child in bm["children"]:
bm_tree_walk(child, template)
for root in bookmarks["roots"].values():
bm_tree_walk(root, out_template[output_format])
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,356 @@
#!/usr/bin/env python3
# Copyright 2017 Chris Braun (cryzed) <cryzed@googlemail.com>
# Adapted for Bitwarden by Jonathan Haylett (JonnyHaystack) <jonathan@haylett.dev>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
"""
Insert login information using Bitwarden CLI and a dmenu-compatible application
(e.g. dmenu, rofi -dmenu, ...).
"""
USAGE = """The domain of the site has to be in the name of the Bitwarden entry, for example: "github.com/cryzed" or
"websites/github.com". The login information is inserted by emulating key events using qutebrowser's fake-key command in this manner:
[USERNAME]<Tab>[PASSWORD], which is compatible with almost all login forms.
If enabled, with the `--totp` flag, it will also move the TOTP code to the
clipboard, much like the Firefox add-on.
You must log into Bitwarden CLI using `bw login` prior to use of this script.
The session key will be stored using keyctl for the number of seconds passed to
the --auto-lock option.
To use in qutebrowser, run: `spawn --userscript qute-bitwarden`
"""
EPILOG = """Dependencies: tldextract (Python 3 module), pyperclip (optional
Python module, used for TOTP codes), Bitwarden CLI (1.7.4 is known to work
but older versions may well also work)
WARNING: The login details are viewable as plaintext in qutebrowser's debug log
(qute://log) and might be shared if you decide to submit a crash report!"""
import argparse
import enum
import functools
import os
import shlex
import subprocess
import sys
import json
import tldextract
argument_parser = argparse.ArgumentParser(
description=__doc__,
usage=USAGE,
epilog=EPILOG,
)
argument_parser.add_argument("url", nargs="?", default=os.getenv("QUTE_URL"))
argument_parser.add_argument(
"--dmenu-invocation",
"-d",
default="bemenu -x -b --prompt=Pass",
help="Invocation used to execute a dmenu-provider",
)
argument_parser.add_argument(
"--password-prompt-invocation",
"-p",
default='bemenu -x -b -p "Master Password"',
help="Invocation used to prompt the user for their Bitwarden password",
)
argument_parser.add_argument(
"--no-insert-mode",
"-n",
dest="insert_mode",
action="store_false",
help="Don't automatically enter insert mode",
)
argument_parser.add_argument(
"--totp", "-t", action="store_true", help="Copy TOTP key to clipboard"
)
argument_parser.add_argument(
"--io-encoding",
"-i",
default="UTF-8",
help="Encoding used to communicate with subprocesses",
)
argument_parser.add_argument(
"--merge-candidates",
"-m",
action="store_true",
help="Merge pass candidates for fully-qualified and registered domain name",
)
argument_parser.add_argument(
"--auto-lock",
type=int,
default=900,
help="Automatically lock the vault after this many seconds",
)
group = argument_parser.add_mutually_exclusive_group()
group.add_argument(
"--username-only", "-e", action="store_true", help="Only insert username"
)
group.add_argument(
"--password-only", "-w", action="store_true", help="Only insert password"
)
group.add_argument(
"--totp-only", "-T", action="store_true", help="Only insert totp code"
)
stderr = functools.partial(print, file=sys.stderr)
class ExitCodes(enum.IntEnum):
SUCCESS = 0
FAILURE = 1
# 1 is automatically used if Python throws an exception
NO_PASS_CANDIDATES = 2
COULD_NOT_MATCH_USERNAME = 3
COULD_NOT_MATCH_PASSWORD = 4
def qute_command(command):
with open(os.environ["QUTE_FIFO"], "w") as fifo:
fifo.write(command + "\n")
fifo.flush()
def ask_password(password_prompt_invocation):
process = subprocess.run(
shlex.split(password_prompt_invocation),
text=True,
stdout=subprocess.PIPE,
)
if process.returncode > 0:
raise Exception("Could not unlock vault")
master_pass = process.stdout.strip()
return subprocess.check_output(
["bw", "unlock", "--raw", master_pass],
text=True,
).strip()
def get_session_key(auto_lock, password_prompt_invocation):
if auto_lock == 0:
subprocess.call(["keyctl", "purge", "user", "bw_session"])
return ask_password(password_prompt_invocation)
else:
process = subprocess.run(
["keyctl", "request", "user", "bw_session"],
text=True,
stdout=subprocess.PIPE,
)
key_id = process.stdout.strip()
if process.returncode > 0:
session = ask_password(password_prompt_invocation)
if not session:
raise Exception("Could not unlock vault")
key_id = subprocess.check_output(
["keyctl", "add", "user", "bw_session", session, "@u"],
text=True,
).strip()
if auto_lock > 0:
subprocess.call(["keyctl", "timeout", str(key_id), str(auto_lock)])
return subprocess.check_output(
["keyctl", "pipe", str(key_id)],
text=True,
).strip()
def pass_(domain, encoding, auto_lock, password_prompt_invocation):
session_key = get_session_key(auto_lock, password_prompt_invocation)
process = subprocess.run(
["bw", "list", "items", "--session", session_key, "--url", domain],
capture_output=True,
)
err = process.stderr.decode(encoding).strip()
if err:
msg = "Bitwarden CLI returned for {:s} - {:s}".format(domain, err)
stderr(msg)
if process.returncode:
return "[]"
out = process.stdout.decode(encoding).strip()
return out
def get_totp_code(
selection_id, domain_name, encoding, auto_lock, password_prompt_invocation
):
session_key = get_session_key(auto_lock, password_prompt_invocation)
process = subprocess.run(
["bw", "get", "totp", "--session", session_key, selection_id],
capture_output=True,
)
err = process.stderr.decode(encoding).strip()
if err:
# domain_name instead of selection_id to make it more user-friendly
msg = "Bitwarden CLI returned for {:s} - {:s}".format(domain_name, err)
stderr(msg)
if process.returncode:
return "[]"
out = process.stdout.decode(encoding).strip()
return out
def dmenu(items, invocation, encoding):
command = shlex.split(invocation)
process = subprocess.run(
command, input="\n".join(items).encode(encoding), stdout=subprocess.PIPE
)
return process.stdout.decode(encoding).strip()
def fake_key_raw(text):
for character in text:
# Escape all characters by default, space requires special handling
sequence = '" "' if character == " " else r"\{}".format(character)
qute_command("fake-key {}".format(sequence))
def main(arguments):
if not arguments.url:
argument_parser.print_help()
return ExitCodes.FAILURE
extract_result = tldextract.extract(arguments.url)
# Try to find candidates using targets in the following order: fully-qualified domain name (includes subdomains),
# the registered domain name and finally: the IPv4 address if that's what
# the URL represents
candidates = []
for target in filter(
None,
[
extract_result.fqdn,
extract_result.registered_domain,
extract_result.subdomain + "." + extract_result.domain,
extract_result.domain,
extract_result.ipv4,
],
):
target_candidates = json.loads(
pass_(
target,
arguments.io_encoding,
arguments.auto_lock,
arguments.password_prompt_invocation,
)
)
if not target_candidates:
continue
candidates = candidates + target_candidates
if not arguments.merge_candidates:
break
else:
if not candidates:
stderr("No pass candidates for URL {!r} found!".format(arguments.url))
return ExitCodes.NO_PASS_CANDIDATES
if len(candidates) == 1:
selection = candidates.pop()
else:
choices = []
for c in candidates:
if c["login"]["username"] is None:
c["login"]["username"] = ""
choices.append("{:s} | {:s}".format(c["name"], c["login"]["username"]))
# choices = [
# "{:s} | {:s}".format(c["name"], c["login"]["username"]) for c in candidates
# ]
choice = dmenu(choices, arguments.dmenu_invocation, arguments.io_encoding)
choice_tokens = choice.split("|")
choice_name = choice_tokens[0].strip()
choice_username = choice_tokens[1].strip()
selection = next(
(
c
for (i, c) in enumerate(candidates)
if c["name"] == choice_name
and c["login"]["username"] == choice_username
),
None,
)
# Nothing was selected, simply return
if not selection:
return ExitCodes.SUCCESS
username = selection["login"]["username"]
password = selection["login"]["password"]
totp = selection["login"]["totp"]
if arguments.username_only:
fake_key_raw(username)
elif arguments.password_only:
fake_key_raw(password)
elif arguments.totp_only:
# No point in moving it to the clipboard in this case
fake_key_raw(
get_totp_code(
selection["id"],
selection["name"],
arguments.io_encoding,
arguments.auto_lock,
arguments.password_prompt_invocation,
)
)
else:
# Enter username and password using fake-key and <Tab> (which seems to work almost universally), then switch
# back into insert-mode, so the form can be directly submitted by
# hitting enter afterwards
fake_key_raw(username)
qute_command("fake-key <Tab>")
fake_key_raw(password)
if arguments.insert_mode:
qute_command("mode-enter insert")
# If it finds a TOTP code, it copies it to the clipboard,
# which is the same behavior as the Firefox add-on.
if not arguments.totp_only and totp and arguments.totp:
# The import is done here, to make pyperclip an optional dependency
import pyperclip
pyperclip.copy(
get_totp_code(
selection["id"],
selection["name"],
arguments.io_encoding,
arguments.auto_lock,
arguments.password_prompt_invocation,
)
)
return ExitCodes.SUCCESS
if __name__ == "__main__":
arguments = argument_parser.parse_args()
sys.exit(main(arguments))

1
archive/waybar Symbolic link
View File

@@ -0,0 +1 @@
../code/opalfiles/.config/waybar