Compare commits
57 Commits
workstatio
...
92a464415c
| Author | SHA1 | Date | |
|---|---|---|---|
| 92a464415c | |||
| 89f628fbb2 | |||
| 674f083980 | |||
| 989b4d473b | |||
| ba2b5e286c | |||
| 005589be05 | |||
| aaa45d6009 | |||
| e5b720af93 | |||
| 4818c27b93 | |||
| 25ad40f68b | |||
| f9d22072a6 | |||
| db0d98c0d9 | |||
| 22a4db35f5 | |||
| 6a4a6a8c3e | |||
| b8e6598a7f | |||
| 5b00715c4b | |||
| dbca282194 | |||
| f08e29bbd9 | |||
| 35ed3e1343 | |||
| 739e3f8837 | |||
|
|
330b094069 | ||
| 9e424589de | |||
| 23f53a5ac4 | |||
| b3911b0f36 | |||
| 35d7d0ae23 | |||
| 20ce61bedb | |||
| 3ab067c35e | |||
| f6997c69cc | |||
| b1ebde8e27 | |||
| 7e09920f02 | |||
| ecc289897c | |||
| 625b61a4cc | |||
| 327d13992e | |||
| 19e1e133e3 | |||
| c7fe0235bf | |||
| dab8e342aa | |||
| 897490b10b | |||
| cb2490baae | |||
| 7c9c25f09d | |||
| 064d6f6a3b | |||
| 64d731775f | |||
| 943ad74f4a | |||
| 2f4b1b8fed | |||
| a4484f61e7 | |||
| 11deb87570 | |||
| fe4cf2905a | |||
| ebf47c763d | |||
| 1c284fc34b | |||
| 8bfb4d86bf | |||
| ba5e462587 | |||
| 304d81bf4b | |||
| d1f2ecbc14 | |||
| 23d686908d | |||
| e9c0ca90a6 | |||
| 24737b5d6e | |||
| 53917e3ddb | |||
| 753ef8d1e6 |
@@ -6,17 +6,14 @@ export XDG_CONFIG_HOME=~/.config
|
||||
export XDG_CACHE_HOME=~/.cache
|
||||
export XDG_DATA_HOME=~/.local/share
|
||||
export BROWSER=/usr/bin/brave-browser
|
||||
export VISUAL=nvim
|
||||
export VISUAL=nvim
|
||||
export EDITOR=nvim
|
||||
export QT_QPA_PLATFORMTHEME=qt5ct
|
||||
export DESKTOP_SESSION=sway
|
||||
export GOPATH="$HOME"/go
|
||||
|
||||
# Scripts Path
|
||||
PATH=$PATH:~/.local/bin
|
||||
PATH=$PATH:~/bin
|
||||
PATH=$PATH:/usr/local/go/bin
|
||||
PATH=$PATH:$HOME/go/bin
|
||||
PATH=$PATH:~/scripts
|
||||
|
||||
# Doom Path
|
||||
PATH=$PATH:~/.config/emacs/bin/
|
||||
|
||||
@@ -4,4 +4,4 @@ if [ -f ~/.bash_env ]; then
|
||||
. "$HOME"/.bash_env
|
||||
fi
|
||||
|
||||
[ "$(tty)" = "/dev/tty1" ] && exec sway
|
||||
# [ "$(tty)" = "/dev/tty1" ] && exec sway
|
||||
|
||||
56
.bashrc
@@ -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 df='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,6 +138,19 @@ 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='vim ~/sync/workout/workout.txt'
|
||||
|
||||
|
||||
#######################################################
|
||||
# WORK
|
||||
@@ -147,10 +160,6 @@ alias tbr='trans :pt-BR'
|
||||
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)'
|
||||
|
||||
|
||||
#######################################################
|
||||
# SPECIAL FUNCTIONS
|
||||
#######################################################
|
||||
@@ -171,9 +180,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 +195,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
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import = ["/home/opal/.config/alacritty/theme.toml"]
|
||||
|
||||
[env]
|
||||
TERM = "alacritty"
|
||||
TERM = "xterm-256color"
|
||||
|
||||
[font]
|
||||
size = 18
|
||||
size = 16
|
||||
|
||||
[font.normal]
|
||||
family = "Terminus"
|
||||
family = "Monospace"
|
||||
style = "Regular"
|
||||
|
||||
[font.offset]
|
||||
@@ -16,3 +15,6 @@ y = 0
|
||||
|
||||
[window]
|
||||
opacity = 0.9
|
||||
|
||||
[general]
|
||||
import = ["/home/opal/.config/alacritty/theme.toml"]
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# Dracula theme for Alacritty
|
||||
# https://draculatheme.com/alacritty
|
||||
#
|
||||
# Color palette
|
||||
# https://spec.draculatheme.com
|
||||
#
|
||||
# Template
|
||||
# https://github.com/alacritty/alacritty/blob/master/alacritty.yml
|
||||
|
||||
colors:
|
||||
primary:
|
||||
background: "#282a36"
|
||||
foreground: "#f8f8f2"
|
||||
bright_foreground: "#ffffff"
|
||||
cursor:
|
||||
text: CellBackground
|
||||
cursor: CellForeground
|
||||
vi_mode_cursor:
|
||||
text: CellBackground
|
||||
cursor: CellForeground
|
||||
search:
|
||||
matches:
|
||||
foreground: "#44475a"
|
||||
background: "#50fa7b"
|
||||
focused_match:
|
||||
foreground: "#44475a"
|
||||
background: "#ffb86c"
|
||||
footer_bar:
|
||||
background: "#282a36"
|
||||
foreground: "#f8f8f2"
|
||||
hints:
|
||||
start:
|
||||
foreground: "#282a36"
|
||||
background: "#f1fa8c"
|
||||
end:
|
||||
foreground: "#f1fa8c"
|
||||
background: "#282a36"
|
||||
line_indicator:
|
||||
foreground: None
|
||||
background: None
|
||||
selection:
|
||||
text: CellForeground
|
||||
background: "#44475a"
|
||||
normal:
|
||||
black: "#21222c"
|
||||
red: "#ff5555"
|
||||
green: "#50fa7b"
|
||||
yellow: "#f1fa8c"
|
||||
blue: "#bd93f9"
|
||||
magenta: "#ff79c6"
|
||||
cyan: "#8be9fd"
|
||||
white: "#f8f8f2"
|
||||
bright:
|
||||
black: "#6272a4"
|
||||
red: "#ff6e6e"
|
||||
green: "#69ff94"
|
||||
yellow: "#ffffa5"
|
||||
blue: "#d6acff"
|
||||
magenta: "#ff92df"
|
||||
cyan: "#a4ffff"
|
||||
white: "#ffffff"
|
||||
30
.config/alacritty/gruvbox-light.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Colors (Gruvbox light)
|
||||
|
||||
# Default colors
|
||||
[colors.primary]
|
||||
# hard contrast background = = '#f9f5d7'
|
||||
background = '#E8D8B0'
|
||||
# soft contrast background = = '#f2e5bc'
|
||||
foreground = '#3c3836'
|
||||
|
||||
# Normal colors
|
||||
[colors.normal]
|
||||
black = '#fbf1c7'
|
||||
red = '#cc241d'
|
||||
green = '#98971a'
|
||||
yellow = '#d79921'
|
||||
blue = '#458588'
|
||||
magenta = '#b16286'
|
||||
cyan = '#689d6a'
|
||||
white = '#7c6f64'
|
||||
|
||||
# Bright colors
|
||||
[colors.bright]
|
||||
black = '#928374'
|
||||
red = '#9d0006'
|
||||
green = '#79740e'
|
||||
yellow = '#b57614'
|
||||
blue = '#076678'
|
||||
magenta = '#8f3f71'
|
||||
cyan = '#427b58'
|
||||
white = '#3c3836'
|
||||
@@ -1,30 +0,0 @@
|
||||
# Colors (Gruvbox dark)
|
||||
|
||||
# Default colors
|
||||
[colors.primary]
|
||||
# hard contrast background = = '#1d2021'
|
||||
background = '#282828'
|
||||
# soft contrast background = = '#32302f'
|
||||
foreground = '#ebdbb2'
|
||||
|
||||
# Normal colors
|
||||
[colors.normal]
|
||||
black = '#282828'
|
||||
red = '#cc241d'
|
||||
green = '#98971a'
|
||||
yellow = '#d79921'
|
||||
blue = '#458588'
|
||||
magenta = '#b16286'
|
||||
cyan = '#689d6a'
|
||||
white = '#a89984'
|
||||
|
||||
# Bright colors
|
||||
[colors.bright]
|
||||
black = '#928374'
|
||||
red = '#fb4934'
|
||||
green = '#b8bb26'
|
||||
yellow = '#fabd2f'
|
||||
blue = '#83a598'
|
||||
magenta = '#d3869b'
|
||||
cyan = '#8ec07c'
|
||||
white = '#ebdbb2'
|
||||
26
.config/alacritty/manegarm-theme.toml
Normal 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
|
||||
@@ -1,60 +0,0 @@
|
||||
[colors.bright]
|
||||
black = "#1c1f24"
|
||||
blue = "#dbc077"
|
||||
cyan = "#dbc077"
|
||||
green = "#7cb518"
|
||||
magenta = "#d72638"
|
||||
red = "#ff7000"
|
||||
white = "#dfdfdf"
|
||||
yellow = "#ffbf00"
|
||||
|
||||
[colors.cursor]
|
||||
cursor = "CellForeground"
|
||||
text = "CellBackground"
|
||||
|
||||
[colors.footer_bar]
|
||||
background = "#1c1408"
|
||||
foreground = "#7cb518"
|
||||
|
||||
[colors.hints.end]
|
||||
background = "#1c1408"
|
||||
foreground = "#ffbf00"
|
||||
|
||||
[colors.hints.start]
|
||||
background = "#ffbf00"
|
||||
foreground = "#1c1408"
|
||||
|
||||
[colors.line_indicator]
|
||||
background = "None"
|
||||
foreground = "None"
|
||||
|
||||
[colors.normal]
|
||||
black = "#1B2229"
|
||||
blue = "#dbc077"
|
||||
cyan = "#dbc077"
|
||||
green = "#7cb518"
|
||||
magenta = "#d72638"
|
||||
red = "#ff4e00"
|
||||
white = "#dfdfdf"
|
||||
yellow = "#ffbf00"
|
||||
|
||||
[colors.primary]
|
||||
background = "#1c1408"
|
||||
bright_foreground = "#dfdfdf"
|
||||
foreground = "#7cb518"
|
||||
|
||||
[colors.search.focused_match]
|
||||
background = "#ffbf00"
|
||||
foreground = "#3f444a"
|
||||
|
||||
[colors.search.matches]
|
||||
background = "#7cb518"
|
||||
foreground = "#3f444a"
|
||||
|
||||
[colors.selection]
|
||||
background = "#3f444a"
|
||||
text = "CellForeground"
|
||||
|
||||
[colors.vi_mode_cursor]
|
||||
cursor = "CellForeground"
|
||||
text = "CellBackground"
|
||||
@@ -1,52 +0,0 @@
|
||||
colors:
|
||||
primary:
|
||||
background: "#1c1408" # -bg
|
||||
foreground: "#7cb518" # green, adjusted for better visibility
|
||||
bright_foreground: "#dfdfdf" # base8
|
||||
cursor:
|
||||
text: CellBackground
|
||||
cursor: CellForeground
|
||||
vi_mode_cursor:
|
||||
text: CellBackground
|
||||
cursor: CellForeground
|
||||
search:
|
||||
matches:
|
||||
foreground: "#3f444a" # base4
|
||||
background: "#7cb518" # green
|
||||
focused_match:
|
||||
foreground: "#3f444a" # base4
|
||||
background: "#ffbf00" # yellow
|
||||
footer_bar:
|
||||
background: "#1c1408" # -bg
|
||||
foreground: "#7cb518" # green
|
||||
hints:
|
||||
start:
|
||||
foreground: "#1c1408" # -bg
|
||||
background: "#ffbf00" # yellow
|
||||
end:
|
||||
foreground: "#ffbf00" # yellow
|
||||
background: "#1c1408" # -bg
|
||||
line_indicator:
|
||||
foreground: None
|
||||
background: None
|
||||
selection:
|
||||
text: CellForeground
|
||||
background: "#3f444a" # base4
|
||||
normal:
|
||||
black: "#1B2229" # base0
|
||||
red: "#ff4e00" # red
|
||||
green: "#7cb518" # green
|
||||
yellow: "#ffbf00" # yellow
|
||||
blue: "#dbc077" # teal, lightened umber
|
||||
magenta: "#d72638" # magenta
|
||||
cyan: "#dbc077" # teal (sand/beige)
|
||||
white: "#dfdfdf" # base8
|
||||
bright:
|
||||
black: "#1c1f24" # base1
|
||||
red: "#ff7000" # orange
|
||||
green: "#7cb518" # green
|
||||
yellow: "#ffbf00" # yellow
|
||||
blue: "#dbc077" # teal, lightened umber
|
||||
magenta: "#d72638" # magenta
|
||||
cyan: "#dbc077" # teal (sand/beige)
|
||||
white: "#dfdfdf" # base8
|
||||
28
.config/alacritty/solarized-dark.toml
Normal 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'
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,175 +0,0 @@
|
||||
(setq fancy-splash-image "~/.config/doom/splash.png")
|
||||
|
||||
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu)
|
||||
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-footer)
|
||||
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-loaded)
|
||||
(add-hook! '+doom-dashboard-mode-hook (hide-mode-line-mode 1) (hl-line-mode -1))
|
||||
(setq-hook! '+doom-dashboard-mode-hook evil-normal-state-cursor (list nil))
|
||||
|
||||
(setq user-full-name "opal"
|
||||
user-mail-address "ry.orlando@proton.me")
|
||||
|
||||
;; (setq doom-theme 'doom-dracula)
|
||||
(load-theme 'doom-gruvbox t)
|
||||
;;(define-key global-map (kbd "<f5>") #'modus-themes-toggle)
|
||||
|
||||
(dolist (mode '(org-mode-hook
|
||||
term-mode-hook
|
||||
shell-mode-hook
|
||||
eshell-mode-hook))
|
||||
(add-hook mode (lambda () (display-line-numbers-mode 0))))
|
||||
|
||||
(setq browse-url-browser-function 'browse-url-generic
|
||||
browse-url-generic-program "qutebrowser")
|
||||
|
||||
(set-face-attribute 'default nil :font "Terminus" :height 130 :weight 'regular)
|
||||
(set-face-attribute 'fixed-pitch nil :font "Terminus" :height 1.0 :weight 'regular)
|
||||
(set-face-attribute 'variable-pitch nil :font "Terminus" :height 1.0 :weight 'bold)
|
||||
|
||||
(defun opal/org-font-setup ()
|
||||
;; Replace list hyphen with dot
|
||||
(font-lock-add-keywords 'org-mode
|
||||
'(("^ *\\([-]\\) "
|
||||
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1)
|
||||
"•"))))))
|
||||
|
||||
;; Set faces for heading levels
|
||||
(dolist (face '((org-level-1 . 1.2)
|
||||
(org-level-2 . 1.1)
|
||||
(org-level-3 . 1.05)
|
||||
(org-level-4 . 1.0)
|
||||
(org-level-5 . 1.1)
|
||||
(org-level-6 . 1.1)
|
||||
(org-level-7 . 1.1)
|
||||
(org-level-8 . 1.1)))
|
||||
(set-face-attribute (car face) nil :font "Terminus" :weight 'regular :height (cdr face)))
|
||||
|
||||
;; Ensure that anything that should be fixed-pitch in Org files appears that way
|
||||
(set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'org-formula nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
|
||||
(set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
|
||||
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
|
||||
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
|
||||
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
|
||||
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'line-number nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'line-number-current-line nil :inherit 'fixed-pitch))
|
||||
|
||||
|
||||
(defun opal/org-mode-setup ()
|
||||
(org-indent-mode)
|
||||
(variable-pitch-mode 1)
|
||||
(visual-line-mode 1))
|
||||
|
||||
(use-package org
|
||||
:commands (org-capture org-agenda)
|
||||
:hook (org-mode . opal/org-mode-setup)
|
||||
:config
|
||||
(setq org-ellipsis " ▾")
|
||||
(setq org-agenda-start-with-log-mode t)
|
||||
(setq org-log-done 'time)
|
||||
(setq org-log-into-drawer t)
|
||||
(setq org-startup-folded t)
|
||||
(setq org-agenda-files
|
||||
'("~/work/work.org"))
|
||||
|
||||
(require 'org-habit)
|
||||
(add-to-list 'org-modules 'org-habit)
|
||||
(setq org-habit-graph-column 60)
|
||||
|
||||
(setq org-todo-keywords
|
||||
'((sequence "NEXT(n)" "TODO(t)" "|" "DONE(d!)")
|
||||
(sequence "ACTIVE(a)" "PROJ(p)" "READY(r)" "WAIT(w@/!)" "HOLD(h)" "BACKLOG(b)" "DOC(u)" "|" "COMPLETED(c)" "CANC(k@)")))
|
||||
|
||||
(setq org-todo-keyword-faces
|
||||
'(("NEXT" . "red") ("TODO" . "orange") ("WAIT" . "yellow") ("DONE" . "green")))
|
||||
|
||||
(setq org-refile-targets
|
||||
'(("archive.org" :maxlevel . 1)
|
||||
("planner.org" :maxlevel . 1)))
|
||||
|
||||
;; Save Org buffers after refiling!
|
||||
(advice-add 'org-refile :after 'org-save-all-org-buffers)
|
||||
|
||||
(add-hook 'org-mode-hook #'org-make-toc-mode)
|
||||
|
||||
;; Configure custom agenda views
|
||||
(setq org-agenda-custom-commands
|
||||
'(("d" "Dashboard"
|
||||
((agenda "" ((org-deadline-warning-days 7)))
|
||||
(todo "NEXT"
|
||||
((org-agenda-overriding-header "Next Tasks")))
|
||||
(tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))
|
||||
|
||||
("n" "Next Tasks"
|
||||
((todo "NEXT"
|
||||
((org-agenda-overriding-header "Next Tasks")))))
|
||||
|
||||
;; Low-effort next actions
|
||||
("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
|
||||
((org-agenda-overriding-header "Low Effort Tasks")
|
||||
(org-agenda-max-todos 20)
|
||||
(org-agenda-files org-agenda-files)))))
|
||||
|
||||
;; Create capture templates
|
||||
(setq org-capture-templates
|
||||
`(("t" "Tasks")
|
||||
("tt" "Task" entry (file+olp "~/work/work.org" "Inbox")
|
||||
"* TODO %?\n %U\n %a\n %i" :empty-lines 1)))
|
||||
|
||||
;; Tell Org to stop indenting inside of org source blocks.
|
||||
(setq org-edit-src-content-indentation 0)
|
||||
|
||||
;; Set org agenda dir
|
||||
(setq org-directory "~/org/")
|
||||
|
||||
;; Open links in browser
|
||||
(setq browse-url-browser-function 'browse-url-generic
|
||||
browse-url-generic-program "firefox")
|
||||
|
||||
;; Init org font setup
|
||||
(opal/org-font-setup))
|
||||
|
||||
(use-package org-bullets
|
||||
:after org
|
||||
:hook (org-mode . org-bullets-mode)
|
||||
:custom
|
||||
(org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
|
||||
|
||||
(defun opal/org-mode-visual-fill ()
|
||||
(setq visual-fill-column-width 150
|
||||
visual-fill-column-center-text t)
|
||||
(visual-fill-column-mode 1))
|
||||
|
||||
(use-package visual-fill-column
|
||||
:hook (org-mode . opal/org-mode-visual-fill))
|
||||
|
||||
;; Load languages for babel code blocks.
|
||||
(with-eval-after-load 'org
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((emacs-lisp . t)
|
||||
(lisp . t)
|
||||
(python . t)
|
||||
(sql . t)
|
||||
(clojure . t)))
|
||||
|
||||
(push '("conf-unix" . conf-unix) org-src-lang-modes))
|
||||
|
||||
(with-eval-after-load 'org
|
||||
(require 'org-tempo)
|
||||
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
|
||||
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
|
||||
(add-to-list 'org-structure-template-alist '("cl" . "src lisp"))
|
||||
(add-to-list 'org-structure-template-alist '("sql" . "src sql"))
|
||||
(add-to-list 'org-structure-template-alist '("py" . "src python"))
|
||||
(add-to-list 'org-structure-template-alist '("clj" . "src clojure")))
|
||||
|
||||
(setq rmh-elfeed-org-files (list "~/sync/elfeed/feeds.org"))
|
||||
(add-hook! 'elfeed-search-mode-hook 'elfeed-update)
|
||||
(after! elfeed
|
||||
(setq elfeed-search-filter "@1-month-ago +unread"))
|
||||
|
||||
(setq create-lockfiles nil)
|
||||
@@ -1,53 +0,0 @@
|
||||
(custom-set-variables
|
||||
;; custom-set-variables was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(ansi-color-names-vector
|
||||
["#282c34" "#ff6c6b" "#98be65" "#ECBE7B" "#51afef" "#c678dd" "#46D9FF" "#bbc2cf"])
|
||||
'(auth-source-save-behavior nil)
|
||||
'(custom-safe-themes
|
||||
'("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
|
||||
((("#333a38" "#99bb66" "green")
|
||||
. 0)
|
||||
(("#2b3d48" "#46D9FF" "brightcyan")
|
||||
. 20)))
|
||||
'(jdee-db-active-breakpoint-face-colors (cons "#1B2229" "#51afef"))
|
||||
'(jdee-db-requested-breakpoint-face-colors (cons "#1B2229" "#98be65"))
|
||||
'(jdee-db-spec-breakpoint-face-colors (cons "#1B2229" "#3f444a"))
|
||||
'(objed-cursor-color "#ff6c6b")
|
||||
'(package-selected-packages '(quelpa-use-package use-package bind-key quelpa))
|
||||
'(pdf-view-midnight-colors (cons "#bbc2cf" "#282c34"))
|
||||
'(rustic-ansi-faces
|
||||
["#282c34" "#ff6c6b" "#98be65" "#ECBE7B" "#51afef" "#c678dd" "#46D9FF" "#bbc2cf"])
|
||||
'(vc-annotate-background "#282c34")
|
||||
'(vc-annotate-color-map
|
||||
(list
|
||||
(cons 20 "#98be65")
|
||||
(cons 40 "#b4be6c")
|
||||
(cons 60 "#d0be73")
|
||||
(cons 80 "#ECBE7B")
|
||||
(cons 100 "#e6ab6a")
|
||||
(cons 120 "#e09859")
|
||||
(cons 140 "#da8548")
|
||||
(cons 160 "#d38079")
|
||||
(cons 180 "#cc7cab")
|
||||
(cons 200 "#c678dd")
|
||||
(cons 220 "#d974b7")
|
||||
(cons 240 "#ec7091")
|
||||
(cons 260 "#ff6c6b")
|
||||
(cons 280 "#cf6162")
|
||||
(cons 300 "#9f585a")
|
||||
(cons 320 "#6f4e52")
|
||||
(cons 340 "#5B6268")
|
||||
(cons 360 "#5B6268")))
|
||||
'(vc-annotate-very-old-color nil))
|
||||
(custom-set-faces
|
||||
;; custom-set-faces was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
)
|
||||
@@ -1,6 +0,0 @@
|
||||
(package! org-bullets)
|
||||
(package! visual-fill-column)
|
||||
(package! org-make-toc)
|
||||
(package! modus-themes)
|
||||
(package! ef-themes)
|
||||
(package! dirvish :disable t)
|
||||
4
.config/eww/eww.yuck
Normal 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
@@ -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;
|
||||
}
|
||||
@@ -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=brave-browser.desktop
|
||||
application/xhtml+xml=brave-browser.desktop
|
||||
application/xml=brave-browser.desktop
|
||||
text/xml=brave-browser.desktop
|
||||
text/xsl=brave-browser.desktop
|
||||
application/rss+xml=brave-browser.desktop
|
||||
application/atom+xml=brave-browser.desktop
|
||||
x-scheme-handler/http=brave-browser.desktop
|
||||
x-scheme-handler/https=brave-browser.desktop
|
||||
x-scheme-handler/ftp=brave-browser.desktop
|
||||
x-scheme-handler/chrome=brave-browser.desktop
|
||||
x-scheme-handler/about=brave-browser.desktop
|
||||
x-scheme-handler/mailto=brave-browser.desktop
|
||||
text/html=/usr/bin/brave-browser
|
||||
application/xhtml+xml=/usr/bin/brave-browser
|
||||
application/xml=/usr/bin/brave-browser
|
||||
text/xml=/usr/bin/brave-browser
|
||||
text/xsl=/usr/bin/brave-browser
|
||||
application/rss+xml=/usr/bin/brave-browser
|
||||
application/atom+xml=/usr/bin/brave-browser
|
||||
x-scheme-handler/http=/usr/bin/brave-browser
|
||||
x-scheme-handler/https=/usr/bin/brave-browser
|
||||
x-scheme-handler/ftp=/usr/bin/brave-browser
|
||||
x-scheme-handler/chrome=/usr/bin/brave-browser
|
||||
x-scheme-handler/about=/usr/bin/brave-browser
|
||||
x-scheme-handler/mailto=/usr/bin/brave-browser
|
||||
|
||||
14
.config/mpd/mpd.conf
Normal 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
@@ -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
@@ -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"
|
||||
|
||||
@@ -40,7 +40,7 @@ highlight article ":.*\\(link\\)$" cyan default
|
||||
highlight article ":.*\\(image\\)$" blue default
|
||||
highlight article ":.*\\(embedded flash\\)$" magenta default
|
||||
|
||||
urls-source "ttrss"
|
||||
ttrss-url "https://rss.opal.sh/tt-rss/"
|
||||
ttrss-login "ryan"
|
||||
ttrss-passwordeval "gopass show -o self-hosted/rss.opal.sh"
|
||||
#urls-source "ttrss"
|
||||
#ttrss-url "https://rss.opal.sh/tt-rss/"
|
||||
#ttrss-login "ryan"
|
||||
#ttrss-passwordeval "gopass show -o self-hosted/rss.opal.sh"
|
||||
|
||||
@@ -1,16 +1,41 @@
|
||||
"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://feeds.arstechnica.com/arstechnica/index "~Ars Technica"
|
||||
https://www.theverge.com/rss/index.xml "~The Verge"
|
||||
https://www.linuxlinks.com/feed/ "~LinuxLinks"
|
||||
https://itsfoss.com/feed/ "~It's FOSS"
|
||||
https://kmandla.wordpress.com/feed/ "~K.Mandla"
|
||||
https://distrowatch.com/news/dw.xml "~DistroWatch"
|
||||
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"
|
||||
|
||||
---Stores---
|
||||
https://www.darkdescentrecords.com/shop/shop/rss
|
||||
|
||||
@@ -1,51 +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 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 [[highlight Normal guibg=NONE ctermbg=NONE]]
|
||||
vim.cmd [[highlight NormalNC guibg=NONE ctermbg=NONE]]
|
||||
vim.cmd [[highlight EndOfBuffer guibg=NONE ctermbg=NONE]]
|
||||
|
||||
vim.api.nvim_create_autocmd("BufRead", {
|
||||
pattern = "*",
|
||||
callback = function()
|
||||
if vim.fn.getline(1):match("^#!.*/python") then
|
||||
vim.bo.filetype = "python"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
@@ -1,34 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
from qutebrowser.api import interceptor
|
||||
#import dracula.draw
|
||||
|
||||
# Load existing settings made via :set
|
||||
config.load_autoconfig()
|
||||
#dracula.draw.blood(c, {"spacing": {"vertical": 6, "horizontal": 8}})
|
||||
|
||||
|
||||
# def intercept(info: interceptor.Request):
|
||||
# if info.request_url.host() == "youtube.com":
|
||||
# new_url = QUrl(info.request_url)
|
||||
# new_url.setHost("vid.puffyan.us")
|
||||
# try:
|
||||
# info.redirect(new_url)
|
||||
# except interceptor.interceptors.RedirectException:
|
||||
# pass
|
||||
|
||||
|
||||
# interceptor.register(intercept)
|
||||
|
||||
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 = "~/downloads"
|
||||
c.editor.command = ["alacritty", "-e", "vim", "{}"]
|
||||
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"
|
||||
@@ -37,7 +22,6 @@ c.colors.webpage.preferred_color_scheme = "dark"
|
||||
c.content.cookies.accept = "no-3rdparty"
|
||||
c.content.webrtc_ip_handling_policy = "default-public-interface-only"
|
||||
c.content.site_specific_quirks.enabled = False
|
||||
c.content.headers.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.79 Safari/537.36"
|
||||
|
||||
config.bind("j", "scroll-px 0 100")
|
||||
config.bind("k", "scroll-px 0 -100")
|
||||
@@ -48,20 +32,5 @@ c.url.searchengines = {
|
||||
"DEFAULT": "https://duckduckgo.com/?q={}",
|
||||
}
|
||||
|
||||
c.url.start_pages = ["http://localhost:80"]
|
||||
c.url.start_pages = ["https://start.duckduckgo.com"]
|
||||
|
||||
# Bitwarden Password Management
|
||||
config.bind(
|
||||
",p",
|
||||
"spawn --userscript qute-bitwarden --dmenu-invocation 'bemenu -b -x --prompt=Pass'",
|
||||
)
|
||||
|
||||
config.bind(
|
||||
",u",
|
||||
"spawn --userscript qute-bitwarden -e --dmenu-invocation 'bemenu -b -p 'Username Only''",
|
||||
)
|
||||
|
||||
config.bind(
|
||||
",P",
|
||||
"spawn --userscript qute-bitwarden --dmenu-invocation 'bemenu -b -x -p 'Password Only''",
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[FileDialog]
|
||||
history=file:///home/opal/pictures
|
||||
lastVisited=file:///home/opal/pictures
|
||||
qtVersion=5.15.6
|
||||
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\0\0\0\0\0\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)"
|
||||
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
|
||||
|
||||
@@ -14,8 +14,9 @@ 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 -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
|
||||
@@ -41,18 +42,13 @@ floating_modifier $mod normal
|
||||
bindsym $mod+Shift+c reload
|
||||
|
||||
# Exit sway (logs you out of your Wayland session)
|
||||
#bindsym $mod+Shift+x exec swaymsg -r exit
|
||||
# bindsym $mod+Shift+x exec swaymsg -r exit
|
||||
|
||||
## Volume
|
||||
bindsym XF86AudioRaiseVolume exec pactl set-sink-volume @DEFAULT_SINK@ +2%
|
||||
bindsym XF86AudioLowerVolume exec pactl set-sink-volume @DEFAULT_SINK@ -2%
|
||||
bindsym XF86AudioMute exec pactl set-sink-mute @DEFAULT_SINK@ toggle
|
||||
|
||||
## Volume for non-media button keyboards
|
||||
#bindsym $mod+Shift+n exec pactl set-sink-volume @DEFAULT_SINK@ +5%
|
||||
#bindsym $mod+Shift+b exec pactl set-sink-volume @DEFAULT_SINK@ -5%
|
||||
#bindsym $mod+Shift+m exec pactl set-sink-mute @DEFAULT_SINK@ toggle
|
||||
|
||||
# Media playerctl
|
||||
bindsym XF86AudioNext exec playerctl next
|
||||
bindsym XF86AudioPrev exec playerctl previous
|
||||
@@ -168,147 +164,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 '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}')
|
||||
|
||||
|
||||
#######################
|
||||
# EXECS
|
||||
#######################
|
||||
# Set GTK/icon theme
|
||||
exec_always {
|
||||
gsettings set org.gnome.desktop.interface gtk-theme 'Arc-Darker'
|
||||
gsettings set org.gnome.desktop.interface icon-theme 'Papirus-Dark'
|
||||
}
|
||||
|
||||
|
||||
# Notifications
|
||||
exec_always dunst
|
||||
|
||||
# Wlsunset (Night Light)
|
||||
exec wlsunset -l 47.6 -L -122.3 -t 3000 -T 3500
|
||||
|
||||
# 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
|
||||
#######################
|
||||
|
||||
# Window Borders
|
||||
default_border pixel 3
|
||||
default_floating_border none
|
||||
client.focused "#38761d" "#38761d" "#ffffff" "#38761d"
|
||||
|
||||
set $opacity 0.90
|
||||
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
|
||||
|
||||
# Gaps
|
||||
smart_gaps on
|
||||
gaps inner 5
|
||||
gaps outer 2
|
||||
|
||||
#######################
|
||||
# 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"
|
||||
}
|
||||
|
||||
# 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/exterminator.png 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 number "1"
|
||||
set $ws2 number "2"
|
||||
set $ws3 number "3"
|
||||
set $ws4 number "4"
|
||||
set $ws5 number "5"
|
||||
set $ws6 number "6"
|
||||
set $ws7 number "0"
|
||||
|
||||
# Switch to workspace
|
||||
bindsym $mod+1 workspace $ws1
|
||||
bindsym $mod+2 workspace $ws2
|
||||
@@ -327,6 +200,185 @@ 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/man.sh
|
||||
# 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 <command>
|
||||
# bindsym $mod+x exec <command>
|
||||
# bindsym $mod+y exec <command>
|
||||
# bindsym $mod+z exec <command>
|
||||
# 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.sh
|
||||
# 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 <command>
|
||||
# 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
|
||||
#######################
|
||||
|
||||
# Notifications
|
||||
exec_always sh -c 'pgrep -x dunst > /dev/null || dunst'
|
||||
|
||||
# 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
|
||||
|
||||
# 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="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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Image
|
||||
image=~/.config/wallpapers/exterminator.png
|
||||
image=~/.config/wallpapers/wall.jpg
|
||||
scaling=fill
|
||||
|
||||
# Indicator
|
||||
|
||||
@@ -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/"
|
||||
|
||||
BIN
.config/wallpapers/berries.jpg
Normal file
|
After Width: | Height: | Size: 566 KiB |
BIN
.config/wallpapers/buddha1.jpg
Normal file
|
After Width: | Height: | Size: 758 KiB |
BIN
.config/wallpapers/buddha2.jpg
Normal file
|
After Width: | Height: | Size: 774 KiB |
BIN
.config/wallpapers/foggy-forest.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
.config/wallpapers/greek-ruins.jpg
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
.config/wallpapers/pine.jpg
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
.config/wallpapers/swallowed.jpg
Normal file
|
After Width: | Height: | Size: 445 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
BIN
.config/wallpapers/wall.jpg
Normal file
|
After Width: | Height: | Size: 6.3 MiB |
@@ -4,13 +4,12 @@
|
||||
"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","custom/wlsunset","custom/padd", "tray","custom/power","custom/padd"],
|
||||
"modules-right": ["custom/l_end","custom/music","custom/padd","pulseaudio","custom/padd","network", "custom/padd","battery","custom/padd", "tray","custom/power","custom/padd"],
|
||||
"sway/workspaces": {
|
||||
"disable-scroll": true,
|
||||
"all-outputs": true,
|
||||
"format": "<span size='large'>{icon}</span>",
|
||||
"format": "{name}",
|
||||
},
|
||||
|
||||
"sway/mode": {
|
||||
"format": "<span style='italic'>{}</span>"
|
||||
},
|
||||
@@ -21,11 +20,11 @@
|
||||
},
|
||||
|
||||
"clock": {
|
||||
"format": " {:%H:%M %a %B %d}",
|
||||
"format": " {:%H:%M %D}",
|
||||
"tooltip-format": "<tt><big>{calendar}</big></tt>"
|
||||
},
|
||||
"custom/music": {
|
||||
"exec": "~/.config/waybar/scripts/music.py",
|
||||
"exec": "~/.config/waybar/scripts/music.scm",
|
||||
"interval": 3,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -43,9 +42,9 @@
|
||||
},
|
||||
"full-at": "99",
|
||||
"format": "{icon} {capacity}%",
|
||||
"format-icons": ["","", "","", ""],
|
||||
"format-good": " {capacity}%", // An empty format will hide the module
|
||||
"format-full": " Full",
|
||||
"format-icons": [" ","", "","", ""],
|
||||
"format-good": " %", // An empty format will hide the module
|
||||
"format-full": "",
|
||||
"format-charging": " {capacity}% "
|
||||
},
|
||||
"custom/wlsunset": {
|
||||
@@ -55,8 +54,8 @@
|
||||
},
|
||||
"network": {
|
||||
"interval": 5,
|
||||
"format-wifi": " {essid}",
|
||||
"format-ethernet": " {ifname}",
|
||||
"format-wifi": "",
|
||||
"format-ethernet": "",
|
||||
"format-disconnected": " ",
|
||||
"tooltip-format-wifi": "{essid}:{signalStrength}\nSpeed:{bandwidthDownBits} \n{ipaddr}",
|
||||
"on-click": "alacritty -e nmtui"
|
||||
@@ -77,7 +76,7 @@
|
||||
},
|
||||
|
||||
"custom/power": {
|
||||
"format": "{}",
|
||||
"format": "",
|
||||
//"exec": "echo ; echo logout",
|
||||
"on-click": "wlogout -p layer-shell",
|
||||
"interval" : 86400, // once every day
|
||||
|
||||
36
.config/waybar/scripts/music.scm
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/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 "")))
|
||||
@@ -21,8 +21,9 @@ def get_weather_icon(description):
|
||||
"overcast clouds": "☁️",
|
||||
"shower rain": "🌦️",
|
||||
"light rain": "🌧️",
|
||||
"rain": "🌧️",
|
||||
"light intensity drizzle": "🌧️",
|
||||
"moderate rain": "🌧️",
|
||||
"rain": "🌧️",
|
||||
"thunderstorm": "⛈️",
|
||||
"snow": "❄️",
|
||||
"mist": "🌫️",
|
||||
@@ -42,7 +43,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)
|
||||
|
||||
86
.config/waybar/scripts/weather.scm
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/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)
|
||||
@@ -2,15 +2,15 @@
|
||||
* {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
font-family: "Terminus", "Font Awesome 6 Free";
|
||||
font-size: 15px;
|
||||
font-family: "ETBembo", "Font Awesome 6 Free";
|
||||
font-size: 20px;
|
||||
min-height: 0;
|
||||
color: #bebebe;
|
||||
}
|
||||
|
||||
window#waybar {
|
||||
opacity: 0.7;
|
||||
background: #000000;
|
||||
opacity: 1;
|
||||
background: #0D0703;
|
||||
}
|
||||
|
||||
/* Specific module styles */
|
||||
@@ -32,7 +32,6 @@ window#waybar {
|
||||
}
|
||||
|
||||
#mode {
|
||||
font-family: "Terminus";
|
||||
color: black;
|
||||
background: white;
|
||||
}
|
||||
@@ -72,20 +71,13 @@ window#waybar {
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#clock {
|
||||
font-family: Terminus;
|
||||
}
|
||||
#clock {}
|
||||
|
||||
#custom-weather {
|
||||
font-family: Terminus;
|
||||
}
|
||||
#custom-weather {}
|
||||
|
||||
#custom-music {
|
||||
font-family: Terminus;
|
||||
}
|
||||
#custom-music {}
|
||||
|
||||
#custom-wlsunset {}
|
||||
|
||||
#pulseaudio {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
6
.gitignore
vendored
@@ -1,5 +1,11 @@
|
||||
.config/qutebrowser/quickmarks
|
||||
.config/qutebrowser/qsettings/*
|
||||
.config/qutebrowser/autoconfig.yml
|
||||
.config/borgmatic/config.yaml
|
||||
.config/beets/beets-library.db
|
||||
.config/beets/state.pickle
|
||||
*.swp
|
||||
lazy-lock.json
|
||||
*.sync-conflict*
|
||||
.stfolder
|
||||
flycheck-packages.el
|
||||
|
||||
22
.local/bin/battery_alert.sh
Executable 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/man.sh
Executable 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}')"
|
||||
22
.local/bin/pass_autofill
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/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"
|
||||
wtype -k Tab
|
||||
wtype "$password"
|
||||
wtype -k Return
|
||||
fi
|
||||
8
.local/bin/pass_copy
Executable 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
@@ -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
|
||||
350
.local/bin/todo
Executable file
@@ -0,0 +1,350 @@
|
||||
#!/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 sys
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
import configparser
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import json
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, date
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
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'
|
||||
# Initialize defaults
|
||||
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))
|
||||
# Read user overrides
|
||||
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*)?' # optional done with date
|
||||
r'(?:\[#(?P<priority>[ABC])\]\s*)?' # optional priority
|
||||
r'\((?P<created>\d{4}-\d{2}-\d{2})\)\s*' # created date
|
||||
r'(?P<description>.+)$' # description+tags
|
||||
)
|
||||
|
||||
@dataclass
|
||||
class Task:
|
||||
completed: Optional[date]
|
||||
priority: str
|
||||
created: date
|
||||
description: str
|
||||
tags: List[str]
|
||||
|
||||
@property
|
||||
def done(self) -> bool:
|
||||
return self.completed is not None
|
||||
|
||||
@classmethod
|
||||
def from_line(cls, line: str) -> Optional['Task']:
|
||||
m = LINE_RE.match(line)
|
||||
if not m:
|
||||
return None
|
||||
gd = m.groupdict()
|
||||
# Parse dates
|
||||
completed = None
|
||||
if gd.get('completed'):
|
||||
completed = datetime.strptime(gd['completed'], DATE_FORMAT).date()
|
||||
prio = gd['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=completed,
|
||||
priority=prio,
|
||||
created=created,
|
||||
description=desc,
|
||||
tags=tags)
|
||||
|
||||
def to_line(self) -> str:
|
||||
parts = []
|
||||
if self.done:
|
||||
parts.append(f"x ({self.completed.strftime(DATE_FORMAT)}) ")
|
||||
parts.append(f"[#%s] " % 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) -> 'Task':
|
||||
return Task(completed=date.today(),
|
||||
priority=self.priority,
|
||||
created=self.created,
|
||||
description=self.description,
|
||||
tags=self.tags)
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# I/O
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
def read_tasks() -> List[Task]:
|
||||
if not TODO_FILE_PATH.exists():
|
||||
return []
|
||||
lines = TODO_FILE_PATH.read_text().splitlines()
|
||||
return [t for t in (Task.from_line(l) for l in lines) if t]
|
||||
|
||||
|
||||
def write_tasks(tasks: List[Task]):
|
||||
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: List[Task], show_all: bool, sort_by: Optional[str]):
|
||||
# filter
|
||||
display = tasks if show_all else [t for t in tasks if not t.done]
|
||||
# sort
|
||||
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)
|
||||
|
||||
# columns order
|
||||
if show_all:
|
||||
cols = ['#','Created','Completed','Pri','Done','Description','Tags']
|
||||
else:
|
||||
cols = ['#','Created','Pri','Description','Tags']
|
||||
|
||||
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(' ')
|
||||
# cells
|
||||
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(), show_all=False, sort_by=args.sort)
|
||||
|
||||
def cmd_lsa(args):
|
||||
display_tasks(read_tasks(), show_all=True, sort_by=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).[/]')
|
||||
entry = '[#B] ' + entry
|
||||
if '@' not in entry:
|
||||
console.print('[yellow]No tag; defaulting to @misc.[/]')
|
||||
entry += ' @misc'
|
||||
t = Task.from_line(entry)
|
||||
tasks = read_tasks() + ([t] if t else [])
|
||||
write_tasks(tasks)
|
||||
console.print(f'[green]Added:[/] {t.description if t else 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(completed=None, priority=prio, created=date.today(), description=desc, tags=[tag])
|
||||
tasks = read_tasks() + [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}")
|
||||
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 in enumerate(active, start=1):
|
||||
console.print(f"{disp}: {i[1].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')
|
||||
write_tasks([t for t in tasks if not t.done])
|
||||
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, show_all=False, sort_by=None)
|
||||
|
||||
def cmd_edit(args):
|
||||
editor = os.getenv('EDITOR','nano')
|
||||
os.execvp(editor, [editor, str(TODO_FILE_PATH)])
|
||||
|
||||
def cmd_jira(args):
|
||||
console.print('[italic]JIRA import not yet implemented[/]')
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 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=p_ls.get_default('sort') and p_ls.choices or None)
|
||||
|
||||
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', required=True)
|
||||
p_jira.add_argument('--status','-s',action='append',default=['Open','In Progress'])
|
||||
p_jira.add_argument('--assignee','-a',default='currentUser()')
|
||||
p_jira.add_argument('--board','-b',type=int)
|
||||
|
||||
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.sh
Executable 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
|
||||
|
||||
50
.local/bin/vault
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
|
||||
CONTAINER=${2:-"$HOME/vault.hc"}
|
||||
|
||||
BASENAME=$(basename "$CONTAINER")
|
||||
MAPPER_NAME="${BASENAME%.*}"
|
||||
MOUNT_POINT="/mnt/$MAPPER_NAME"
|
||||
|
||||
case "$1" in
|
||||
open)
|
||||
if [ ! -f "$CONTAINER" ]; then
|
||||
echo "Container not found: $CONTAINER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -e "/dev/mapper/$MAPPER_NAME" ]; then
|
||||
echo "Already opened at /dev/mapper/$MAPPER_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$MOUNT_POINT" || exit 1
|
||||
|
||||
if sudo cryptsetup open --type tcrypt "$CONTAINER" "$MAPPER_NAME"; then
|
||||
sudo mount "/dev/mapper/$MAPPER_NAME" "$MOUNT_POINT" &&
|
||||
echo "Mounted at $MOUNT_POINT"
|
||||
else
|
||||
echo "Failed to open container."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
close)
|
||||
if mountpoint -q "$MOUNT_POINT"; then
|
||||
sudo umount "$MOUNT_POINT"
|
||||
fi
|
||||
|
||||
if [ -e "/dev/mapper/$MAPPER_NAME" ]; then
|
||||
sudo cryptsetup close "$MAPPER_NAME"
|
||||
echo "Closed and unmounted $MOUNT_POINT."
|
||||
else
|
||||
echo "Container is not open."
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 {open|close} [path/to/container.hc]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
316
archive/doom/config.el
Normal file
@@ -0,0 +1,316 @@
|
||||
;;(setq fancy-splash-image "~/.config/doom/splash.png")
|
||||
|
||||
;; Clean up starting screen
|
||||
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu)
|
||||
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-banner)
|
||||
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-footer)
|
||||
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-loaded)
|
||||
(add-hook! '+doom-dashboard-mode-hook (hide-mode-line-mode 1) (hl-line-mode -1))
|
||||
(setq-hook! '+doom-dashboard-mode-hook evil-normal-state-cursor (list nil))
|
||||
|
||||
;; Set name & e-mail
|
||||
(setq user-full-name "opal"
|
||||
user-mail-address "ry.orlando@proton.me")
|
||||
|
||||
;; Theme & background color
|
||||
(load-theme 'doom-solarized-dark t)
|
||||
;;(set-face-background 'default "#E8D8B0")
|
||||
|
||||
;; Lockfiles
|
||||
(setq create-lockfiles nil)
|
||||
|
||||
;; Remove line numbers from specific modes
|
||||
(dolist (mode '(org-mode-hook
|
||||
term-mode-hook
|
||||
shell-mode-hook
|
||||
eshell-mode-hook))
|
||||
(add-hook mode (lambda () (display-line-numbers-mode 0))))
|
||||
|
||||
;; Font configuration
|
||||
(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
|
||||
(font-lock-add-keywords 'org-mode
|
||||
'(("^ *\\([-]\\) "
|
||||
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1)
|
||||
"•"))))))
|
||||
|
||||
;; Set faces for heading levels
|
||||
(dolist (face '((org-level-1 . 1.2)
|
||||
(org-level-2 . 1.1)
|
||||
(org-level-3 . 1.05)
|
||||
(org-level-4 . 1.0)
|
||||
(org-level-5 . 1.1)
|
||||
(org-level-6 . 1.1)
|
||||
(org-level-7 . 1.1)
|
||||
(org-level-8 . 1.1)))
|
||||
(set-face-attribute (car face) nil :font "ETBembo" :weight 'regular :height (cdr face)))
|
||||
|
||||
;; Set properties and scheduling faces to inherit variable-pitch and be smaller
|
||||
;; Comment out these lines because mixed-pitch-mode will handle these.
|
||||
(set-face-attribute 'org-property-value nil :inherit 'variable-pitch :height 150)
|
||||
(set-face-attribute 'org-special-keyword nil :inherit 'variable-pitch :height 150)
|
||||
(set-face-attribute 'org-scheduled-today nil :inherit 'variable-pitch :height 150)
|
||||
(set-face-attribute 'org-drawer nil :inherit 'variable-pitch :height 150)
|
||||
(set-face-attribute 'org-date nil :inherit 'variable-pitch :height 150)
|
||||
|
||||
;; Ensure that all agenda items use fixed-pitch font
|
||||
(custom-set-faces
|
||||
'(org-agenda-date-today ((t (:inherit fixed-pitch :weight bold))))
|
||||
'(org-agenda-date ((t (:inherit fixed-pitch))))
|
||||
'(org-agenda-date-weekend ((t (:inherit fixed-pitch :weight bold))))
|
||||
'(org-agenda-done ((t (:inherit fixed-pitch :strike-through t))))
|
||||
'(org-agenda-dimmed-todo-face ((t (:inherit fixed-pitch))))
|
||||
'(org-agenda-structure ((t (:inherit fixed-pitch))))
|
||||
'(org-scheduled ((t (:inherit fixed-pitch))))
|
||||
'(org-scheduled-today ((t (:inherit fixed-pitch))))
|
||||
'(org-scheduled-previously ((t (:inherit fixed-pitch))))
|
||||
'(org-upcoming-deadline ((t (:inherit fixed-pitch))))
|
||||
'(org-deadline-announce ((t (:inherit fixed-pitch))))
|
||||
'(org-time-grid ((t (:inherit fixed-pitch)))))
|
||||
)
|
||||
|
||||
(defun opal/org-mode-setup ()
|
||||
(org-indent-mode)
|
||||
(visual-line-mode 1)
|
||||
(mixed-pitch-mode 1))
|
||||
|
||||
(use-package org
|
||||
:commands (org-capture org-agenda)
|
||||
:hook (org-mode . opal/org-mode-setup)
|
||||
:config
|
||||
(setq org-ellipsis " ▾")
|
||||
(setq org-agenda-start-with-log-mode t)
|
||||
(setq org-log-done 'time)
|
||||
(setq org-log-into-drawer t)
|
||||
(setq org-startup-folded t)
|
||||
(setq org-indent-indentation-per-level 2)
|
||||
(setq org-hide-emphasis-markers t)
|
||||
(setq org-agenda-files
|
||||
'("~/documents/org/agenda/todo.org"))
|
||||
|
||||
(require 'org-habit)
|
||||
(add-to-list 'org-modules 'org-habit)
|
||||
(setq org-habit-graph-column 60)
|
||||
|
||||
(setq org-todo-keywords
|
||||
'((sequence "NEXT(n)" "TODO(t)" "|" "DONE(d!)")
|
||||
(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")))
|
||||
|
||||
(setq org-refile-targets
|
||||
'(("archive.org" :maxlevel . 1)
|
||||
("planner.org" :maxlevel . 1)))
|
||||
|
||||
;; Save Org buffers after refiling!
|
||||
(advice-add 'org-refile :after 'org-save-all-org-buffers)
|
||||
|
||||
(add-hook 'org-mode-hook #'org-make-toc-mode)
|
||||
|
||||
(setq org-agenda-custom-commands
|
||||
'(("d" "Custom Dashboard"
|
||||
;; NEXT items for today
|
||||
((tags "+TODO=\"NEXT\"+SCHEDULED=\"<+0d>\"|+DEADLINE=\"<+0d>\""
|
||||
((org-agenda-overriding-header "\nNEXT Items for Today\n"))) ; Show NEXT items scheduled or due today
|
||||
;; TODO items for today
|
||||
(tags "+TODO=\"TODO\"+SCHEDULED=\"<+0d>\"|+DEADLINE=\"<+0d>\""
|
||||
((org-agenda-overriding-header "\nTODO Items for Today\n"))) ; Show TODO items scheduled or due today
|
||||
;; DONE items for today
|
||||
(tags "+TODO=\"DONE\"+CLOSED>=\"<-3d>\""
|
||||
((org-agenda-overriding-header "\nDone Items for Today\n"))) ; Show DONE items closed today
|
||||
;; Agenda for today
|
||||
(agenda ""
|
||||
((org-agenda-span 1) ; Show only today
|
||||
(org-agenda-start-day "0d") ; Start from today
|
||||
(org-agenda-show-all-dates t) ; Ensure all dates are shown
|
||||
(org-agenda-overriding-header "\nAgenda (Today)\n")))
|
||||
;; Agenda for next 3 days (no time grid)
|
||||
(agenda ""
|
||||
((org-agenda-span 3) ; Show the next 3 days
|
||||
(org-agenda-start-day "+1d") ; Start from tomorrow
|
||||
(org-agenda-overriding-header "\nAgenda (Next 3 Days)\n")
|
||||
(org-agenda-time-grid nil))))))) ; Remove time grid
|
||||
|
||||
;; Create capture templates
|
||||
(setq org-capture-templates
|
||||
`(("t" "Tasks")
|
||||
("tw" "Work Task" entry (file+headline "~/documents/org/agenda/todo.org" "Work")
|
||||
"* TODO %?\n %U\n %i" :empty-lines 1)
|
||||
("tp" "Personal Task" entry (file+headline "~/documents/org/agenda/todo.org" "Personal")
|
||||
"* 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)))
|
||||
|
||||
;; Tell Org to stop indenting inside of org source blocks.
|
||||
(setq org-edit-src-content-indentation 0)
|
||||
|
||||
;; Set org agenda dir
|
||||
(setq org-directory "~/documents/org/")
|
||||
|
||||
;; Init org font setup
|
||||
(opal/org-font-setup))
|
||||
|
||||
(use-package org-bullets
|
||||
:after org
|
||||
:hook (org-mode . org-bullets-mode)
|
||||
:custom
|
||||
(org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
|
||||
|
||||
(defun opal/org-mode-visual-fill ()
|
||||
(setq visual-fill-column-width 150
|
||||
visual-fill-column-center-text t)
|
||||
(visual-fill-column-mode 1))
|
||||
|
||||
(use-package visual-fill-column
|
||||
:hook (org-mode . opal/org-mode-visual-fill))
|
||||
|
||||
;; Load languages for babel code blocks.
|
||||
(with-eval-after-load 'org
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((emacs-lisp . t)
|
||||
(lisp . t)
|
||||
(python . t)
|
||||
(sql . t)))
|
||||
|
||||
(push '("conf-unix" . conf-unix) org-src-lang-modes))
|
||||
|
||||
(with-eval-after-load 'org
|
||||
(require 'org-tempo)
|
||||
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
|
||||
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
|
||||
(add-to-list 'org-structure-template-alist '("cl" . "src lisp"))
|
||||
(add-to-list 'org-structure-template-alist '("sql" . "src sql"))
|
||||
(add-to-list 'org-structure-template-alist '("py" . "src python")))
|
||||
|
||||
;; Programming
|
||||
(setq geiser-guile-binary "/usr/bin/guile3.0")
|
||||
|
||||
;; Playing youtube videos via mpv/yt-dlp/emms
|
||||
(defun opal/play-yt-url-at-point ()
|
||||
"Play YT link under point with EMMS/MPV/yt-dlp."
|
||||
(interactive)
|
||||
(let ((url (thing-at-point 'url t)))
|
||||
(if url
|
||||
(emms-play-url url)
|
||||
(message "No URL found at point."))))
|
||||
|
||||
(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)
|
||||
(let ((link (elfeed-entry-link (elfeed-search-selected :single))))
|
||||
(if link
|
||||
(eww-browse-url link)
|
||||
(message "No link to open."))))
|
||||
|
||||
(defun opal/elfeed-mark-all-read ()
|
||||
"Marks all feeds in *elfeed-search* as read."
|
||||
(interactive)
|
||||
(elfeed-untag elfeed-search-entries 'unread)
|
||||
(elfeed-search-update :force)) ; redraw
|
||||
|
||||
(use-package elfeed
|
||||
:bind
|
||||
(("C-c e" . elfeed))
|
||||
:config
|
||||
;; Ensure faces are set after elfeed has loaded
|
||||
(with-eval-after-load 'elfeed
|
||||
(set-face-attribute 'elfeed-search-filter-face nil :inherit 'variable-pitch :height 200)
|
||||
;; Monospace fonts are necessary for text/column alignment in the *elfeed-search* buffer
|
||||
(set-face-attribute 'elfeed-search-title-face nil :inherit 'fixed-pitch :height 200)
|
||||
(set-face-attribute 'elfeed-search-feed-face nil :inherit 'fixed-pitch :height 200))
|
||||
|
||||
;; Set variable-pitch face for article fonts in the *elfeed-entry* buffer
|
||||
(add-hook 'elfeed-show-mode-hook
|
||||
(lambda () (buffer-face-set 'variable-pitch)))
|
||||
|
||||
;; Set default search filter
|
||||
(setq elfeed-search-filter "@2-weeks-ago +unread")
|
||||
|
||||
;; Update feeds automatically when entering Elfeed search mode
|
||||
(add-hook 'elfeed-search-mode-hook 'elfeed-update)
|
||||
|
||||
;; 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
|
||||
|
||||
(setq create-lockfiles nil)
|
||||
|
||||
;; Make sure eww opens in it's own buffer
|
||||
(after! eww
|
||||
(set-popup-rule! "^\\*eww\\*" :ignore t))
|
||||
|
||||
(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))
|
||||
|
||||
(use-package eww
|
||||
:config
|
||||
(setq browse-url-browser-function 'eww-browse-url)
|
||||
|
||||
;; Set eww webpage title in the modeline bar instead of just *eww*
|
||||
(setq eww-auto-rename-buffer 'title)
|
||||
|
||||
;; Set privacy respecting proxies
|
||||
(setq reddit-proxy "https://eddrit.com")
|
||||
|
||||
;; Redirect reddit links to privacy respecting frontends.
|
||||
(setq eww-url-transformers '(eww-remove-tracking opal/eww-reddit-redirect))
|
||||
|
||||
;; Make sure eww opens in it's own buffer
|
||||
(after! eww
|
||||
(set-popup-rule! "^\\*eww\\*" :ignore t)))
|
||||
|
||||
;; Since I sometimes write notes in two languages, guess-language will allow for multiple language
|
||||
;; spelling checks to be done in a single buffer.
|
||||
(use-package guess-language
|
||||
:defer t
|
||||
:init (add-hook 'text-mode-hook #'guess-language-mode)
|
||||
:config
|
||||
(setq guess-language-langcodes '((en . ("en_US" "English"))
|
||||
(pt_BR . ("pt_BR" "Brazilian Portuguese")))
|
||||
guess-language-languages '(en pt_BR)
|
||||
guess-language-min-paragraph-length 45)
|
||||
:diminish guess-language-mode)
|
||||
|
||||
(setq geiser-guile-binary "/usr/bin/guile3.0")
|
||||
|
||||
(defun opal/nov-mode-setup ()
|
||||
"Configure fonts for nov.el."
|
||||
(variable-pitch-mode 1) ; Enable variable-pitch-mode
|
||||
(visual-line-mode 1) ; Enable line wrapping at word boundaries
|
||||
(setq visual-fill-column-width 150
|
||||
visual-fill-column-center-text t
|
||||
line-spacing 0.2)
|
||||
(visual-fill-column-mode 1))
|
||||
|
||||
(add-hook 'nov-mode-hook 'opal/nov-mode-setup)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
|
||||
|
||||
(setq +lookup-dictionary-prefer-offline t)
|
||||
(setq dictionary-server "dict.org")
|
||||
65
archive/doom/custom.el
Normal file
@@ -0,0 +1,65 @@
|
||||
(custom-set-variables
|
||||
;; custom-set-variables was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(ansi-color-names-vector
|
||||
["#282c34" "#ff6c6b" "#98be65" "#ECBE7B" "#51afef" "#c678dd" "#46D9FF" "#bbc2cf"])
|
||||
'(auth-source-save-behavior nil)
|
||||
'(custom-safe-themes
|
||||
'("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
|
||||
((("#333a38" "#99bb66" "green")
|
||||
. 0)
|
||||
(("#2b3d48" "#46D9FF" "brightcyan")
|
||||
. 20)))
|
||||
'(jdee-db-active-breakpoint-face-colors (cons "#1B2229" "#51afef"))
|
||||
'(jdee-db-requested-breakpoint-face-colors (cons "#1B2229" "#98be65"))
|
||||
'(jdee-db-spec-breakpoint-face-colors (cons "#1B2229" "#3f444a"))
|
||||
'(objed-cursor-color "#ff6c6b")
|
||||
'(package-selected-packages '(quelpa-use-package use-package bind-key quelpa))
|
||||
'(pdf-view-midnight-colors (cons "#bbc2cf" "#282c34"))
|
||||
'(rustic-ansi-faces
|
||||
["#282c34" "#ff6c6b" "#98be65" "#ECBE7B" "#51afef" "#c678dd" "#46D9FF" "#bbc2cf"])
|
||||
'(vc-annotate-background "#282c34")
|
||||
'(vc-annotate-color-map
|
||||
(list
|
||||
(cons 20 "#98be65")
|
||||
(cons 40 "#b4be6c")
|
||||
(cons 60 "#d0be73")
|
||||
(cons 80 "#ECBE7B")
|
||||
(cons 100 "#e6ab6a")
|
||||
(cons 120 "#e09859")
|
||||
(cons 140 "#da8548")
|
||||
(cons 160 "#d38079")
|
||||
(cons 180 "#cc7cab")
|
||||
(cons 200 "#c678dd")
|
||||
(cons 220 "#d974b7")
|
||||
(cons 240 "#ec7091")
|
||||
(cons 260 "#ff6c6b")
|
||||
(cons 280 "#cf6162")
|
||||
(cons 300 "#9f585a")
|
||||
(cons 320 "#6f4e52")
|
||||
(cons 340 "#5B6268")
|
||||
(cons 360 "#5B6268")))
|
||||
'(vc-annotate-very-old-color nil))
|
||||
(custom-set-faces
|
||||
;; custom-set-faces was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(org-agenda-date ((t (:inherit fixed-pitch))))
|
||||
'(org-agenda-date-today ((t (:inherit fixed-pitch :weight bold))))
|
||||
'(org-agenda-date-weekend ((t (:inherit fixed-pitch :weight bold))))
|
||||
'(org-agenda-dimmed-todo-face ((t (:inherit fixed-pitch))))
|
||||
'(org-agenda-done ((t (:inherit fixed-pitch :strike-through t))))
|
||||
'(org-agenda-structure ((t (:inherit fixed-pitch))))
|
||||
'(org-deadline-announce ((t (:inherit fixed-pitch))))
|
||||
'(org-scheduled ((t (:inherit fixed-pitch))))
|
||||
'(org-scheduled-previously ((t (:inherit fixed-pitch))))
|
||||
'(org-scheduled-today ((t (:inherit fixed-pitch))))
|
||||
'(org-time-grid ((t (:inherit fixed-pitch))))
|
||||
'(org-upcoming-deadline ((t (:inherit fixed-pitch))))
|
||||
'(variable-pitch ((t (:slant normal :weight regular :height 200 :width normal :foundry "PfEd" :family "ETBembo")))))
|
||||
@@ -34,7 +34,7 @@
|
||||
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||||
tabs ; a tab bar for Emacs
|
||||
;;treemacs ; a project drawer, like neotree but cooler
|
||||
unicode ; extended unicode support for various languages
|
||||
;;unicode ; extended unicode support for various languages
|
||||
vc-gutter ; vcs diff in the fringe
|
||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||
;;window-select ; visually switch windows
|
||||
@@ -83,7 +83,7 @@
|
||||
;;ein ; tame Jupyter notebooks with emacs
|
||||
(eval +overlay) ; run code, run (also, repls)
|
||||
;;gist ; interacting with github gists
|
||||
lookup ; navigate your code and its documentation
|
||||
(lookup +dictionary) ; navigate your code and its documentation
|
||||
lsp ; M-x vscode
|
||||
magit ; a git porcelain for Emacs
|
||||
;;make ; run make tasks from Emacs
|
||||
@@ -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...
|
||||
@@ -125,7 +125,7 @@
|
||||
;;fsharp ; ML stands for Microsoft's Language
|
||||
;;fstar ; (dependent) types and (monadic) effects and Z3
|
||||
;;gdscript ; the language you waited for
|
||||
(go +lsp) ; the hipster dialect
|
||||
;;(go +lsp) ; the hipster dialect
|
||||
;;(haskell +lsp) ; a language that's lazier than I am
|
||||
;;hy ; readability of scheme w/ speed of python
|
||||
;;idris ; a language you can depend on
|
||||
@@ -155,7 +155,7 @@
|
||||
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||
;;rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||
;;scala ; java, but good
|
||||
;;(scheme +guile) ; a fully conniving family of lisps
|
||||
(scheme +guile) ; a fully conniving family of lisps
|
||||
sh ; she sells {ba,z,fi}sh shells on the C xor
|
||||
;;sml
|
||||
;;solidity ; do you need a blockchain? No.
|
||||
@@ -171,11 +171,11 @@
|
||||
;;(wanderlust +gmail)
|
||||
|
||||
:app
|
||||
;;calendar
|
||||
;;emms
|
||||
calendar
|
||||
emms
|
||||
;;everywhere ; *leave* Emacs!? You must be joking
|
||||
;;irc ; how neckbeards socialize
|
||||
;;(rss +org) ; emacs as an RSS reader
|
||||
irc ; how neckbeards socialize
|
||||
(rss +org) ; emacs as an RSS reader
|
||||
;;twitter ; twitter client https://twitter.com/vnought
|
||||
|
||||
:config
|
||||
15
archive/doom/packages.el
Normal file
@@ -0,0 +1,15 @@
|
||||
;; Include
|
||||
(package! org-bullets)
|
||||
(package! visual-fill-column)
|
||||
(package! org-make-toc)
|
||||
(package! ef-themes)
|
||||
(package! org-drill)
|
||||
(package! pomm)
|
||||
(package! mixed-pitch)
|
||||
(package! guess-language)
|
||||
(package! sicp)
|
||||
(package! nov)
|
||||
(package! osm)
|
||||
|
||||
;; Remove
|
||||
(package! dirvish :disable t)
|
||||
|
Before Width: | Height: | Size: 416 KiB After Width: | Height: | Size: 416 KiB |
31
archive/elfeed/elfeed.org
Normal file
@@ -0,0 +1,31 @@
|
||||
* Feeds
|
||||
** Emacs
|
||||
*** https://sachachua.com/blog/feed/index.xml :tech: :emacs:
|
||||
*** https://protesilaos.com/master.xml :tech: :emacs: :philosophy:
|
||||
*** https://systemcrafters.net/rss/news.xml :tech: :emacs:
|
||||
|
||||
** Reddit
|
||||
*** https://www.reddit.com/r/stupidpol/.rss :reddit: :politics:
|
||||
|
||||
** News
|
||||
*** https://thegrayzone.com/rss :news: :politics:
|
||||
*** https://multipolarista.com/rss :news: :politics:
|
||||
*** https://www.telesurenglish.net/feed/ :news: :politics:
|
||||
*** https://theintercept.com/feed/ :news: :politics:
|
||||
*** https://www.dropsitenews.com/feed :news: :politics:
|
||||
|
||||
** Tech
|
||||
*** https://landchad.net/rss.xml :tech:
|
||||
*** https://videos.lukesmith.xyz/feeds/videos.xml?videoChannelId=2 :tech: :linux:
|
||||
*** https://pluralistic.net/feed/ :tech: :privacy:
|
||||
*** https://blog.privacyguides.org/feed_rss_created.xml :tech: :privacy:
|
||||
|
||||
** Podcasts
|
||||
*** https://feeds.simplecast.com/dCXMIpJz :podcast: :history:
|
||||
*** http://feeds.soundcloud.com/users/soundcloud:users:572119410/sounds.rss :podcast: :music:
|
||||
*** https://feeds.feedburner.com/dancarlin/history?format=xml :podcast: :history:
|
||||
|
||||
** Youtube
|
||||
*** https://www.youtube.com/channel/UC_bOcLgDdfE1whPDIwx3M_g :youtube: :travel:
|
||||
*** https://www.youtube.com/feeds/videos.xml?channel_id=UC8uT9cgJorJPWu7ITLGo9Ww :youtube: :tech: :retro:
|
||||
*** https://www.youtube.com/feeds/videos.xml?channel_id=UC0aanx5rpr7D1M7KCFYzrLQ :youtube: :commentary: :politics:
|
||||
60
archive/nvim/init.lua
Normal 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]])
|
||||
@@ -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" },
|
||||
},
|
||||
})
|
||||
vim.cmd("colorscheme gruvbox")
|
||||
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.
|
||||
@@ -1,7 +1,7 @@
|
||||
;; vi keybindings
|
||||
(define-configuration buffer
|
||||
((default-modes
|
||||
(pushnew 'nyxt/mode/vi:vi-normal-mode %slot-value%))))
|
||||
(pushnew 'nyxt/mode/vi:vi-normal-mode %slot-value%))))
|
||||
|
||||
;; Vi-insert mode for prompt-buffer (minibuffer)
|
||||
(define-configuration prompt-buffer
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
(defvar *my-search-engines*
|
||||
(list
|
||||
'("ddg" "https://duckduckgo.com/search?q=~a" "https://duckduckgo.com"))
|
||||
'("ddg" "https://duckduckgo.com/?q=~a" "https://duckduckgo.com"))
|
||||
"List of search engines.")
|
||||
|
||||
(define-configuration context-buffer
|
||||
"Set DuckDuckGo as the default search engine."
|
||||
"Set DuckDuckGo as the default search engine."
|
||||
((search-engines
|
||||
(append %slot-default%
|
||||
(mapcar
|
||||
0
archive/qutebrowser/bookmarks/urls
Normal file
67
archive/qutebrowser/config.py
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
from qutebrowser.api import interceptor
|
||||
#import dracula.draw
|
||||
|
||||
# Load existing settings made via :set
|
||||
config.load_autoconfig()
|
||||
#dracula.draw.blood(c, {"spacing": {"vertical": 6, "horizontal": 8}})
|
||||
|
||||
|
||||
# def intercept(info: interceptor.Request):
|
||||
# if info.request_url.host() == "youtube.com":
|
||||
# new_url = QUrl(info.request_url)
|
||||
# new_url.setHost("vid.puffyan.us")
|
||||
# try:
|
||||
# info.redirect(new_url)
|
||||
# except interceptor.interceptors.RedirectException:
|
||||
# pass
|
||||
|
||||
|
||||
# interceptor.register(intercept)
|
||||
|
||||
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 = "~/downloads"
|
||||
c.editor.command = ["alacritty", "-e", "vim", "{}"]
|
||||
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
|
||||
c.content.headers.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.79 Safari/537.36"
|
||||
|
||||
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 = ["http://localhost:80"]
|
||||
|
||||
# Bitwarden Password Management
|
||||
config.bind(
|
||||
",p",
|
||||
"spawn --userscript qute-bitwarden --dmenu-invocation 'bemenu -b -x --prompt=Pass'",
|
||||
)
|
||||
|
||||
config.bind(
|
||||
",u",
|
||||
"spawn --userscript qute-bitwarden -e --dmenu-invocation 'bemenu -b -p 'Username Only''",
|
||||
)
|
||||
|
||||
config.bind(
|
||||
",P",
|
||||
"spawn --userscript qute-bitwarden --dmenu-invocation 'bemenu -b -x -p 'Password Only''",
|
||||
)
|
||||
1712
archive/qutebrowser/old-stylesheet.css
Normal file
8
archive/qutebrowser/qsettings/QtProject.conf
Normal file
@@ -0,0 +1,8 @@
|
||||
[FileDialog]
|
||||
history=file:///home/opal/pictures
|
||||
lastVisited=file:///home/opal/pictures
|
||||
qtVersion=5.15.6
|
||||
shortcuts=file:, file:///home/opal
|
||||
sidebarWidth=87
|
||||
treeViewHeader="@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\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)"
|
||||
viewMode=Detail
|
||||
1712
archive/qutebrowser/stylesheet.css
Normal file
343
archive/qutebrowser/userscripts/importer.py
Executable 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()
|
||||
356
archive/qutebrowser/userscripts/qute-bitwarden
Executable 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))
|
||||