diff --git a/.config/firefox/larbs.js b/.config/firefox/larbs.js new file mode 100644 index 00000000..8328357e --- /dev/null +++ b/.config/firefox/larbs.js @@ -0,0 +1,47 @@ +// These are changes made on top of the Arkenfox JS file to tweak it as +// desired. Any of these settings can be overridden by the user. + +// Disable the Twitter/R*ddit/Faceberg ads in the URL bar: +user_pref("browser.urlbar.quicksuggest.enabled", false); +user_pref("browser.urlbar.suggest.topsites", false); // [FF78+] + +// Do not suggest web history in the URL bar: +user_pref("browser.urlbar.suggest.history", false); + +// Do not prefil forms: +user_pref("signon.prefillForms", false); + +// Do not autocomplete in the URL bar: +user_pref("browser.urlbar.autoFill", false); + +// Enable the addition of search keywords: +user_pref("keyword.enabled", true); + +// Allow access to http (i.e. not https) sites: +user_pref("dom.security.https_only_mode", false); + +// Keep cookies until expiration or user deletion: +user_pref("network.cookie.lifetimePolicy", 0); + +user_pref("dom.webnotifications.serviceworker.enabled", false); + +// Disable push notifications: +user_pref("dom.push.enabled", false); + +// Disable the pocket antifeature: +user_pref("extensions.pocket.enabled", false); + +// Don't autodelete cookies on shutdown: +user_pref("privacy.clearOnShutdown.cookies", false); + +// Enable custom userChrome.js: +user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); + +// This could otherwise cause some issues on bank logins and other annoying sites: +user_pref("network.http.referer.XOriginPolicy", 0); + +// Disable Firefox sync and its menu entries +user_pref("identity.fxaccounts.enabled", false); + +// Fix the issue where right mouse button instantly clicks +user_pref("ui.context_menus.after_mouseup", true); diff --git a/.config/lf/icons b/.config/lf/icons index ac8f641c..aad068ce 100644 --- a/.config/lf/icons +++ b/.config/lf/icons @@ -9,6 +9,7 @@ ex 🎯 *.mom ✍ *.me ✍ *.ms ✍ +*.avif πŸ–Ό *.png πŸ–Ό *.webp πŸ–Ό *.ico πŸ–Ό diff --git a/.config/lf/lfrc b/.config/lf/lfrc index 222e24ca..7b38659c 100644 --- a/.config/lf/lfrc +++ b/.config/lf/lfrc @@ -31,18 +31,18 @@ cmd open ${{ case $(file --mime-type "$(readlink -f $f)" -b) in application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) localc $fx ;; image/vnd.djvu|application/pdf|application/octet-stream|application/postscript) setsid -f zathura $fx >/dev/null 2>&1 ;; - text/*|application/json|inode/x-empty) $EDITOR $fx;; + text/*|application/json|inode/x-empty|application/x-subrip) $EDITOR $fx;; image/x-xcf) setsid -f gimp $f >/dev/null 2>&1 ;; image/svg+xml) display -- $f ;; - image/*) rotdir $f | grep -i "\.\(png\|jpg\|jpeg\|gif\|webp\|tif\|ico\)\(_large\)*$" | + image/*) rotdir $f | grep -i "\.\(png\|jpg\|jpeg\|gif\|webp\|avif\|tif\|ico\)\(_large\)*$" | setsid -f sxiv -aio 2>/dev/null | while read -r file; do [ -z "$file" ] && continue lf -remote "send select \"$file\"" lf -remote "send toggle" done & ;; - audio/*) mpv --audio-display=no $f ;; - video/*|application/vnd.rn-realmedia) setsid -f mpv $f -quiet >/dev/null 2>&1 ;; + audio/*|video/x-ms-asf) mpv --audio-display=no $f ;; + video/*) setsid -f mpv $f -quiet >/dev/null 2>&1 ;; application/pdf|application/vnd.djvu|application/epub*) setsid -f zathura $fx >/dev/null 2>&1 ;; application/pgp-encrypted) $EDITOR $fx ;; application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.oasis.opendocument.text) setsid -f lowriter $fx >/dev/null 2>&1 ;; diff --git a/.config/lf/scope b/.config/lf/scope index 1d835275..87b560a0 100755 --- a/.config/lf/scope +++ b/.config/lf/scope @@ -22,6 +22,9 @@ ifub() { # be regenerated once seen. case "$(file --dereference --brief --mime-type -- "$1")" in + image/avif) CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)" + [ ! -f "$CACHE" ] && convert "$1" "$CACHE.jpg" + image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1" ;; image/*) image "$1" "$2" "$3" "$4" "$5" "$1" ;; text/html) lynx -width="$4" -display_charset=utf-8 -dump "$1" ;; text/troff) man ./ "$1" | col -b ;; diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim index d8aaf5e1..d9c6fe61 100644 --- a/.config/nvim/init.vim +++ b/.config/nvim/init.vim @@ -117,7 +117,6 @@ set noshowcmd autocmd BufWritePre * let currPos = getpos(".") autocmd BufWritePre * %s/\s\+$//e autocmd BufWritePre * %s/\n\+\%$//e - autocmd BufWritePre *.[ch] %s/\%$/\r/e autocmd BufWritePre * cal cursor(currPos[1], currPos[2]) " When shortcut files are updated, renew bash and ranger configs with new material: @@ -155,4 +154,4 @@ nnoremap h :call ToggleHiddenAll() " Here leader is ";". " So ":vs ;cfz" will expand into ":vs /home//.config/zsh/.zshrc" " if typed fast without the timeout. -source ~/.config/nvim/shortcuts.vim +silent! source ~/.config/nvim/shortcuts.vim diff --git a/.config/python/pythonrc b/.config/python/pythonrc new file mode 100644 index 00000000..b32e6b6f --- /dev/null +++ b/.config/python/pythonrc @@ -0,0 +1,2 @@ +import readline +readline.write_history_file = lambda *args: None diff --git a/.config/shell/aliasrc b/.config/shell/aliasrc index 0541d0f1..09f9a327 100644 --- a/.config/shell/aliasrc +++ b/.config/shell/aliasrc @@ -6,12 +6,17 @@ # Use $XINITRC variable if file exists. [ -f "$XINITRC" ] && alias startx="startx $XINITRC" +[ -f "$MBSYNCRC" ] && alias mbsync="mbsync -c $MBSYNCRC" + # sudo not required for some system commands for command in mount umount sv pacman updatedb su shutdown poweroff reboot ; do alias $command="sudo $command" done; unset command -se() { cd ~/.local/bin; $EDITOR $(fzf) ;} +se() { + choice="$(find ~/.local/bin -mindepth 1 -printf '%P\n' | fzf)" + [ -f "$HOME/.local/bin/$choice" ] && $EDITOR "$HOME/.local/bin/$choice" + ;} # Verbosity and settings that you pretty much just always are going to want. alias \ @@ -19,9 +24,11 @@ alias \ mv="mv -iv" \ rm="rm -vI" \ bc="bc -ql" \ + rsync="rsync -vrPlu" \ mkd="mkdir -pv" \ yt="yt-dlp --embed-metadata -i" \ yta="yt -x -f bestaudio/best" \ + ytt="yt --skip-download --write-thumbnail" \ ffmpeg="ffmpeg -hide_banner" # Colorize commands when possible. diff --git a/.config/shell/profile b/.config/shell/profile index 10763526..26f82415 100644 --- a/.config/shell/profile +++ b/.config/shell/profile @@ -13,6 +13,7 @@ unsetopt PROMPT_SP # Default programs: export EDITOR="nvim" export TERMINAL="st" +export TERMINAL_PROG="st" export BROWSER="librewolf" # ~/ Clean-up: @@ -39,6 +40,8 @@ export UNISON="$XDG_DATA_HOME/unison" export HISTFILE="$XDG_DATA_HOME/history" export MBSYNCRC="$XDG_CONFIG_HOME/mbsync/config" export ELECTRUMDIR="$XDG_DATA_HOME/electrum" +export PYTHONSTARTUP="$XDG_CONFIG_HOME/python/pythonrc" +export SQLITE_HISTORY="$XDG_DATA_HOME/sqlite_history" # Other program settings: export DICS="/usr/share/stardict/dic/" diff --git a/.config/sxiv/exec/key-handler b/.config/sxiv/exec/key-handler index 4a4f10a1..4c78f18b 100755 --- a/.config/sxiv/exec/key-handler +++ b/.config/sxiv/exec/key-handler @@ -28,6 +28,6 @@ do "d") [ "$(printf "No\\nYes" | dmenu -i -p "Really delete $file?")" = "Yes" ] && rm "$file" && notify-send "$file deleted." ;; "g") ifinstalled gimp && setsid -f gimp "$file" ;; - "i") notify-send "File information" "$(mediainfo "$file")" ;; + "i") notify-send "File information" "$(mediainfo "$file" | sed "s/[ ]\+:/:/g;s/: /: /;s/$/<\/b>/" | grep "")" ;; esac done diff --git a/.config/wal/templates/zathurarc b/.config/wal/templates/zathurarc index a12bbd3c..8f0b16fa 100644 --- a/.config/wal/templates/zathurarc +++ b/.config/wal/templates/zathurarc @@ -12,6 +12,7 @@ map K zoom in map J zoom out map i recolor map p print +map g goto top set default-bg "{background}" set default-fg "{foreground}" diff --git a/.config/x11/xprofile b/.config/x11/xprofile index 0e226282..1d63fd2d 100755 --- a/.config/x11/xprofile +++ b/.config/x11/xprofile @@ -6,9 +6,8 @@ xrandr --dpi 96 # Set DPI. User may want to use a larger number for larger screens. setbg & # set the background with the `setbg` script #xrdb ${XDG_CONFIG_HOME:-$HOME/.config}/x11/xresources & xrdbpid=$! # Uncomment to use Xresources colors/settings on startup -remaps & # run the remaps script, switching caps/esc and more; check it for more info -autostart="mpd xcompmgr dunst unclutter pipewire" +autostart="mpd xcompmgr dunst unclutter pipewire remapd" for program in $autostart; do pidof -s "$program" || "$program" & diff --git a/.local/bin/arkenfox-auto-update b/.local/bin/arkenfox-auto-update new file mode 100755 index 00000000..05f4ca7f --- /dev/null +++ b/.local/bin/arkenfox-auto-update @@ -0,0 +1,20 @@ +#!/bin/sh + +# A wrapper for the arkenfox-updater that runs it on all pre-existing Arkenfox +# user.js files on the machine. + +# On installation of LARBS, this file is copied to /usr/local/lib/ where it is +# run by a pacman hook set up. The user should not have to run this manually. + +# Search for all Firefox and Librewolf profiles using Arkenfox. +profiles="$(grep -sH "arkenfox user.js" \ + /home/*/.librewolf/*.default-release/user.js \ + /home/*/.mozilla/firefox/*.default-release/user.js)" + +IFS=' +' + +# Update each found profile. +for profile in $profiles; do + arkenfox-updater -p "${profile%%/user.js*}" -s +done diff --git a/.local/bin/compiler b/.local/bin/compiler index 6e28cd0d..8420e25f 100755 --- a/.local/bin/compiler +++ b/.local/bin/compiler @@ -39,9 +39,9 @@ case "$ext" in java) javac -d classes "$file" && java -cp classes "${1%.*}" ;; m) octave "$file" ;; md) if [ -x "$(command -v lowdown)" ]; then - lowdown --parse-no-intraemph "$file" -Tms | groff -mpdfmark -ms -kept > "$base".pdf + lowdown --parse-no-intraemph "$file" -Tms | groff -mpdfmark -ms -kept -T pdf > "$base".pdf elif [ -x "$(command -v groffdown)" ]; then - groffdown -i "$file" | groff > "$base.pdf" + groffdown -i "$file" | groff -T pdf > "$base".pdf else pandoc -t ms --highlight-style=kate -s -o "$base".pdf "$file" fi ; ;; @@ -51,7 +51,7 @@ case "$ext" in py) python "$file" ;; [rR]md) Rscript -e "rmarkdown::render('$file', quiet=TRUE)" ;; rs) cargo build ;; - sass) sassc -a "$file" "$base.css" ;; + sass) sassc -a "$file" "$base".css ;; scad) openscad -o "$base".stl "$file" ;; sent) setsid -f sent "$file" 2>/dev/null ;; tex) textype "$file" ;; diff --git a/.local/bin/displayselect b/.local/bin/displayselect index f9e80628..0227a32b 100755 --- a/.local/bin/displayselect +++ b/.local/bin/displayselect @@ -58,7 +58,6 @@ onescreen() { # If only one output available or chosen. postrun() { # Stuff to run to clean up. setbg # Fix background if screen size/arangement has changed. - remaps # Re-remap keys if keyboard added (for laptop bases) { killall dunst ; setsid -f dunst ;} >/dev/null 2>&1 # Restart dunst to ensure proper location on screen } diff --git a/.local/bin/dmenumount b/.local/bin/dmenumount deleted file mode 100755 index 8cf4a6b5..00000000 --- a/.local/bin/dmenumount +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -# Gives a dmenu prompt to mount unmounted drives and Android phones. If -# they're in /etc/fstab, they'll be mounted automatically. Otherwise, you'll -# be prompted to give a mountpoint from already existsing directories. If you -# input a novel directory, it will prompt you to create that directory. - -getmount() { \ - [ -z "$chosen" ] && exit 1 - # shellcheck disable=SC2086 - mp="$(find $1 2>/dev/null | dmenu -i -p "Type in mount point.")" || exit 1 - test -z "$mp" && exit 1 - if [ ! -d "$mp" ]; then - mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") || exit 1 - [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp") - fi - } - -mountusb() { \ - chosen="$(echo "$usbdrives" | dmenu -i -p "Mount which drive?")" || exit 1 - chosen="$(echo "$chosen" | awk '{print $1}')" - sudo -A mount "$chosen" 2>/dev/null && notify-send "πŸ’» USB mounting" "$chosen mounted." && exit 0 - alreadymounted=$(lsblk -nrpo "name,type,mountpoint" | awk '$3!~/\/boot|\/home$|SWAP/&&length($3)>1{printf "-not ( -path *%s -prune ) ",$3}') - getmount "/mnt /media /mount /home -maxdepth 5 -type d $alreadymounted" - partitiontype="$(lsblk -no "fstype" "$chosen")" - case "$partitiontype" in - "vfat") sudo -A mount -t vfat "$chosen" "$mp" -o rw,umask=0000;; - "exfat") sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)";; - *) sudo -A mount "$chosen" "$mp"; user="$(whoami)"; ug="$(groups | awk '{print $1}')"; sudo -A chown "$user":"$ug" "$mp";; - esac && notify-send "πŸ’» USB mounting" "$chosen mounted to $mp." || - notify-send "πŸ’» Drive failed to mount." "Probably a permissions issue or drive is already mounted." - } - -mountandroid() { \ - chosen="$(echo "$anddrives" | dmenu -i -p "Which Android device?")" || exit 1 - chosen="$(echo "$chosen" | cut -d : -f 1)" - getmount "$HOME -maxdepth 3 -type d" - echo "OK" | dmenu -i -p "Tap Allow on your phone if it asks for permission and then press enter" || exit 1 - simple-mtpfs --device "$chosen" "$mp" && - notify-send "πŸ€– Android Mounting" "Android device mounted to $mp." || - notify-send "πŸ€– Android failed mounting." "Probably a permissions issue or phone is already mounted." - } - -asktype() { \ - choice="$(printf "USB\\nAndroid" | dmenu -i -p "Mount a USB drive or Android device?")" || exit 1 - case $choice in - USB) mountusb ;; - Android) mountandroid ;; - esac - } - -anddrives=$(simple-mtpfs -l 2>/dev/null) -usbdrives="$(lsblk -rpo "name,type,size,label,mountpoint,fstype" | grep -v crypto_LUKS | grep 'part\|rom' | sed 's/ /:/g' | awk -F':' '$5==""{printf "%s (%s) %s\n",$1,$3,$4}')" - -if [ -z "$usbdrives" ]; then - [ -z "$anddrives" ] && echo "No USB drive or Android device detected" && exit - echo "Android device(s) detected." - mountandroid -else - if [ -z "$anddrives" ]; then - echo "USB drive(s) detected." - mountusb - else - echo "Mountable USB drive(s) and Android device(s) detected." - asktype - fi -fi diff --git a/.local/bin/dmenurecord b/.local/bin/dmenurecord index b83a7c52..990b7b3c 100755 --- a/.local/bin/dmenurecord +++ b/.local/bin/dmenurecord @@ -9,6 +9,8 @@ # # If there is already a running instance, user will be prompted to end it. +getdim() { xrandr | sed -n "s/\s*\([0-9]\+x[0-9]\+\).*\*.*/\1/p" ;} + updateicon() { \ echo "$1" > /tmp/recordingicon pkill -RTMIN+9 "${STATUSBAR:-dwmblocks}" @@ -16,26 +18,23 @@ updateicon() { \ killrecording() { recpid="$(cat /tmp/recordingpid)" - # kill with SIGTERM, allowing finishing touches. kill -15 "$recpid" rm -f /tmp/recordingpid updateicon "" pkill -RTMIN+9 "${STATUSBAR:-dwmblocks}" - # even after SIGTERM, ffmpeg may still run, so SIGKILL it. - sleep 3 - kill -9 "$recpid" - exit } screencast() { \ ffmpeg -y \ -f x11grab \ - -framerate 60 \ - -s "$(xdpyinfo | awk '/dimensions/ {print $2;}')" \ + -framerate 30 \ + -s "$(getdim)" \ -i "$DISPLAY" \ - -f alsa -i default \ - -r 30 \ - -c:v h264 -crf 0 -preset ultrafast -c:a aac \ + -r 24 \ + -use_wallclock_as_timestamps 1 \ + -f alsa -thread_queue_size 1024 -i default \ + -c:v h264 \ + -crf 0 -preset ultrafast -c:a aac \ "$HOME/screencast-$(date '+%y%m%d-%H%M-%S').mp4" & echo $! > /tmp/recordingpid updateicon "βΊοΈπŸŽ™οΈ" @@ -43,7 +42,8 @@ screencast() { \ video() { ffmpeg \ -f x11grab \ - -s "$(xdpyinfo | awk '/dimensions/ {print $2;}')" \ + -framerate 30 \ + -s "$(getdim)" \ -i "$DISPLAY" \ -c:v libx264 -qp 0 -r 30 \ "$HOME/video-$(date '+%y%m%d-%H%M-%S').mkv" & @@ -104,7 +104,7 @@ videoselected() ffmpeg \ -f x11grab \ - -framerate 60 \ + -framerate 30 \ -video_size "$W"x"$H" \ -i :0.0+"$X,$Y" \ -c:v libx264 -qp 0 -r 30 \ diff --git a/.local/bin/dmenuumount b/.local/bin/dmenuumount deleted file mode 100755 index 656d1f12..00000000 --- a/.local/bin/dmenuumount +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# A dmenu prompt to unmount drives. -# Provides you with mounted partitions, select one to unmount. -# Drives mounted at /, /boot and /home will not be options to unmount. - -drives="$(lsblk -nrpo "name,type,size,mountpoint,label" | awk -F':' '{gsub(/ /,":")}$4!~/\/boot|\/efi|\/home$|SWAP/&&length($4)>1{printf "%s (%s) %s\n",$4,$3,$5}'; awk '/simple-mtpfs/ { print "πŸ“±", $2; }' /etc/mtab)" - -chosen="$(echo "$drives" | dmenu -i -p "Unmount which drive?")" || exit 1 - -case "$chosen" in - πŸ“±*) - chosen="${chosen#πŸ“± }" - sudo -A umount -l "$chosen" - ;; - *) - chosen="${chosen% (*}" - sudo -A umount -l "$chosen" - ;; -esac && notify-send "πŸ–₯️ Drive unmounted." "$chosen successfully unmounted." || - notify-send "πŸ–₯️ Drive failed to unmount." "Possibly a permissions or I/O issue." diff --git a/.local/bin/maimpick b/.local/bin/maimpick index 8ea9f5ec..5de26c17 100755 --- a/.local/bin/maimpick +++ b/.local/bin/maimpick @@ -9,10 +9,10 @@ output="$(date '+%y%m%d-%H%M-%S').png" xclip_cmd="xclip -sel clip -t image/png" case "$(printf "a selected area\\ncurrent window\\nfull screen\\na selected area (copy)\\ncurrent window (copy)\\nfull screen (copy)" | dmenu -l 6 -i -p "Screenshot which area?")" in - "a selected area") maim -s pic-selected-"${output}" ;; + "a selected area") maim -u -s pic-selected-"${output}" ;; "current window") maim -q -d 0.2 -i "$(xdotool getactivewindow)" pic-window-"${output}" ;; "full screen") maim -q -d 0.2 pic-full-"${output}" ;; - "a selected area (copy)") maim -s | ${xclip_cmd} ;; + "a selected area (copy)") maim -u -s | ${xclip_cmd} ;; "current window (copy)") maim -q -d 0.2 -i "$(xdotool getactivewindow)" | ${xclip_cmd} ;; "full screen (copy)") maim -q -d 0.2 | ${xclip_cmd} ;; esac diff --git a/.local/bin/mounter b/.local/bin/mounter new file mode 100755 index 00000000..b532e08f --- /dev/null +++ b/.local/bin/mounter @@ -0,0 +1,114 @@ +#!/bin/bash + +# Mounts Android Phones and USB drives (encrypted or not). This script will +# replace the older `dmenumount` which had extra steps and couldn't handle +# encrypted drives. +# TODO: Try decrypt for drives in crtypttab +# TODO: Add some support for connecting iPhones (although they are annoying). + +IFS=' +' +# Function for escaping cell-phone names. +escape(){ echo "$@" | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed "s/-\+/-/g;s/\(^-\|-\$\)//g" ;} + +# Check for phones. +phones="$(simple-mtpfs -l 2>/dev/null | sed "s/^/πŸ“±/")" +mountedphones="$(grep "simple-mtpfs" /etc/mtab)" +# If there are already mounted phones, remove them from the list of mountables. +[ -n "$mountedphones" ] && phones="$(for phone in $phones; do + for mounted in $mountedphones; do + escphone="$(escape "$phone")" + [[ "$mounted" =~ "$escphone" ]] && break 1 + done && continue 1 + echo "$phone" +done)" + +# Check for drives. +lsblkoutput="$(lsblk -rpo "uuid,name,type,size,label,mountpoint,fstype")" +# Get all LUKS drives +allluks="$(echo "$lsblkoutput" | grep crypto_LUKS)" +# Get a list of the LUKS drive UUIDs already decrypted. +decrypted="$(find /dev/disk/by-id/dm-uuid-CRYPT-LUKS2-* | sed "s|.*LUKS2-||;s|-.*||")" +# Functioning for formatting drives correctly for dmenu: +filter() { sed "s/ /:/g" | awk -F':' '$7==""{printf "%s%s (%s) %s\n",$1,$3,$5,$6}' ; } + +# Get only LUKS drives that are not decrypted. +unopenedluks="$(for drive in $allluks; do + uuid="${drive%% *}" + uuid="${uuid//-}" # This is a bashism. + for open in $decrypted; do + [ "$uuid" = "$open" ] && break 1 + done && continue 1 + echo "πŸ”’ $drive" +done | filter)" + +# Get all normal, non-encrypted or decrypted partitions that are not mounted. +normalparts="$(echo "$lsblkoutput"| grep -v crypto_LUKS | grep 'part\|rom\|crypt' | sed "s/^/πŸ’Ύ /" | filter )" + +# Add all to one variable. If no mountable drives found, exit. +alldrives="$(echo "$phones +$unopenedluks +$normalparts" | sed "/^$/d;s/ *$//")" + +# Quit the script if a sequential command fails. +set -e + +test -n "$alldrives" + +# Feed all found drives to dmenu and get user choice. +chosen="$(echo "$alldrives" | dmenu -p "Mount which drive?" -i)" + +# Function for prompting user for a mountpoint. +getmount(){ + mp="$(find /mnt /media /mount /home -maxdepth 1 -type d 2>/dev/null | dmenu -i -p "Mount this drive where?")" + test -n "$mp" + if [ ! -d "$mp" ]; then + mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") + [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp") + fi +} + +attemptmount(){ + # Attempt to mount without a mountpoint, to see if drive is in fstab. + sudo -A mount "$chosen" || return 1 + notify-send "πŸ’ΎDrive Mounted." "$chosen mounted." + exit +} + +case "$chosen" in + πŸ’Ύ*) + chosen="${chosen%% *}" + chosen="${chosen:1}" # This is a bashism. + attemptmount || getmount + sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)" + notify-send "πŸ’ΎDrive Mounted." "$chosen mounted to $mp." + ;; + + πŸ”’*) + chosen="${chosen%% *}" + chosen="${chosen:1}" # This is a bashism. + # Number the drive. + while true; do + [ -f "/dev/mapper/usb$num" ] || break + num="$(printf "%02d" "$((num +1))")" + done + + # Decrypt in a terminal window + ${TERMINAL:-st} -n floatterm -g 60x1 -e sudo cryptsetup open "$chosen" "usb$num" + # Check if now decrypted. + test -b "/dev/mapper/usb$num" + + attemptmount || getmount + sudo -A mount "/dev/mapper/usb$num" "$mp" -o uid="$(id -u)",gid="$(id -g)" + notify-send "πŸ”“Decrypted drive Mounted." "$chosen decrypted and mounted to $mp." + ;; + + πŸ“±*) + notify-send "❗Note" "Remember to allow file access on your phone now." + getmount + number="${chosen%%:*}" + number="${chosen:1}" # This is a bashism. + sudo -A simple-mtpfs -o allow_other -o fsname="simple-mtpfs-$(escape "$chosen")" --device "$number" "$mp" + notify-send "πŸ€– Android Mounted." "Android device mounted to $mp." + ;; +esac diff --git a/.local/bin/remapd b/.local/bin/remapd new file mode 100755 index 00000000..ee4cf396 --- /dev/null +++ b/.local/bin/remapd @@ -0,0 +1,8 @@ +#!/bin/bash + +# Rerun the remaps script whenever a new input device is added. + +while :; do + remaps + grep -qP -m1 '[^un]bind.+\/[^:]+\(usb\)' <(udevadm monitor -u -t seat -s input -s usb) +done diff --git a/.local/bin/remaps b/.local/bin/remaps index c95ac841..6d7d54e9 100755 --- a/.local/bin/remaps +++ b/.local/bin/remaps @@ -8,4 +8,4 @@ setxkbmap -option caps:super,altwin:menu_win # When caps lock is pressed only once, treat it as escape. killall xcape 2>/dev/null ; xcape -e 'Super_L=Escape' # Turn off caps lock if on since there is no longer a key for it. -xset -q | grep "Caps Lock:\s*on" && xdotool key Caps_Lock +xset -q | grep -q "Caps Lock:\s*on" && xdotool key Caps_Lock diff --git a/.local/bin/sd b/.local/bin/sd index 8047d33b..a0ff84c2 100755 --- a/.local/bin/sd +++ b/.local/bin/sd @@ -2,8 +2,21 @@ # Open a terminal window in the same directory as the currently active window. -PID=$(xprop -id "$(xprop -root | sed -n "/_NET_ACTIVE_WINDOW/ s/^.*# // p")" | sed -n "/PID/ s/^.*= // p") -PID=$(pstree -lpATna "$PID" | grep -v '\-\(lf,[0-9]\+ -server\|(st-urlhandler,[0-9]\+)\|xclip,[0-9]\+\)' | sed '$s/.*,\([0-9]\+\).*/\1/;t;d') -cwd=$(readlink /proc/"$PID"/cwd) +windowPID=$(xprop -id "$(xprop -root | sed -n "/_NET_ACTIVE_WINDOW/ s/^.*# // p")" | sed -n "/PID/ s/^.*= // p") +PIDlist=$(pstree -lpATna "$windowPID" | sed -En 's/.*,([0-9]+).*/\1/p' | tac) +for PID in $PIDlist; do + cmdline=$(ps -o args= -p "$PID") + process_group_leader=$(ps -o comm= -p "$(ps -o pgid= -p "$PID" | tr -d ' ')") + cwd=$(readlink /proc/"$PID"/cwd) + # zsh and lf won't be ignored even if it shows ~ or / + case "$cmdline" in + 'lf -server') continue ;; + "${SHELL##*/}"|'lf'|'lf '*) break ;; + esac + # git (and its sub-processes) will show the root of a repository instead of the actual cwd, so they're ignored + [ "$process_group_leader" = 'git' ] || [ ! -d "$cwd" ] && continue + # This is to ignore programs that show ~ or / instead of the actual working directory + [ "$cwd" != "$HOME" ] && [ "$cwd" != '/' ] && break +done [ "$PWD" != "$cwd" ] && [ -d "$cwd" ] && { cd "$cwd" || exit 1; } "$TERMINAL" diff --git a/.local/bin/shortcuts b/.local/bin/shortcuts index 8fecea28..7d7a1904 100755 --- a/.local/bin/shortcuts +++ b/.local/bin/shortcuts @@ -22,9 +22,9 @@ printf "\" vim: filetype=vim\\n" > "$vifm_shortcuts" # Format the `directories` file in the correct syntax and sent it to all three configs. eval "echo \"$(cat "$bmdirs")\"" | \ awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\"); - printf(\"%s=\42cd %s && ls -a\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ; + printf(\"%s=\42cd %s && ls -A\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ; printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ; - printf(\"abbr %s \42cd %s; and ls -a\42\n\",\$1,\$2) >> \"$fish_shortcuts\" ; + printf(\"abbr %s \42cd %s; and ls -A\42\n\",\$1,\$2) >> \"$fish_shortcuts\" ; printf(\"map g%s :cd %s\nmap t%s :cd %s\nmap M%s :cd %s:mo\nmap Y%s :cd %s:co \n\",\$1,\$2, \$1, \$2, \$1, \$2, \$1, \$2) >> \"$vifm_shortcuts\" ; printf(\"config.bind(';%s', \42set downloads.location.directory %s ;; hint links download\42) \n\",\$1,\$2) >> \"$qute_shortcuts\" ; printf(\"map g%s cd %s\nmap t%s tab_new %s\nmap m%s shell mv -v %%s %s\nmap Y%s shell cp -rv %%s %s \n\",\$1,\$2,\$1,\$2, \$1, \$2, \$1, \$2) >> \"$ranger_shortcuts\" ; diff --git a/.local/bin/statusbar/sb-doppler b/.local/bin/statusbar/sb-doppler index 7573c98b..f58b744e 100755 --- a/.local/bin/statusbar/sb-doppler +++ b/.local/bin/statusbar/sb-doppler @@ -184,7 +184,7 @@ US: KVNX: Norman, OK US: KVBX: Vandenberg Afb: Orcutt, CA EU: Europe EU: GB: Great Brittain -EU: SCAN: Scandinavia +EU: SCAN: Scandinavia. Norway, Sweden And Denmark EU: ALPS: The Alps EU: NL: The Netherlands EU: DE: Germany diff --git a/.local/bin/statusbar/sb-forecast b/.local/bin/statusbar/sb-forecast index 9744ea42..2a6440be 100755 --- a/.local/bin/statusbar/sb-forecast +++ b/.local/bin/statusbar/sb-forecast @@ -1,20 +1,40 @@ #!/bin/sh -# Displays todays precipication chance (β˜”) and daily low (πŸ₯Ά) and high (🌞). +# Displays today's precipication chance (β˜”), and daily low (πŸ₯Ά) and high (🌞). # Usually intended for the statusbar. -# If we have internet, get a weather report from wttr.in and store it locally. -# You could set up a shell alias to view the full file in a pager in the -# terminal if desired. This function will only be run once a day when needed. weatherreport="${XDG_CACHE_HOME:-$HOME/.cache}/weatherreport" -getforecast() { curl -sf "wttr.in/$LOCATION" > "$weatherreport" || exit 1 ;} -# Some very particular and terse stream manipulation. We get the maximum -# precipitation chance and the daily high and low from the downloaded file and -# display them with coresponding emojis. -showweather() { printf "%s" "$(sed '16q;d' "$weatherreport" | - grep -wo "[0-9]*%" | sort -rn | sed "s/^/β˜”/g;1q" | tr -d '\n')" -sed '13q;d' "$weatherreport" | grep -o "m\\([-+]\\)*[0-9]\\+" | sed 's/+//g' | sort -n -t 'm' -k 2n | sed -e 1b -e '$!d' | tr '\n|m' ' ' | awk '{print " πŸ₯Ά" $1 "Β°","🌞" $2 "Β°"}' ;} +# Get a weather report from 'wttr.in' and save it locally. +getforecast() { curl -sf "wttr.in/$LOCATION" > "$weatherreport" || exit 1; } + +# Forecast should be updated only once a day. +checkforecast() { + [ -s "$weatherreport" ] && [ "$(stat -c %y "$weatherreport" 2>/dev/null | + cut -d' ' -f1)" = "$(date '+%Y-%m-%d')" ] +} + +getprecipchance() { + echo "$weatherdata" | sed '16q;d' | # Extract line 16 from file + grep -wo "[0-9]*%" | # Find a sequence of digits followed by '%' + sort -rn | # Sort in descending order + head -1q # Extract first line +} + +getdailyhighlow() { + echo "$weatherdata" | sed '13q;d' | # Extract line 13 from file + grep -o "m\\([-+]\\)*[0-9]\\+" | # Find temperatures in the format "m" + sed 's/[+m]//g' | # Remove '+' and 'm' + sort -g | # Sort in ascending order + sed -e 1b -e '$!d' # Extract the first and last lines +} + +readfile() { weatherdata="$(cat "$weatherreport")" ;} + +showweather() { + readfile + printf "β˜”%s πŸ₯Ά%sΒ° 🌞%sΒ°\n" "$(getprecipchance)" $(getdailyhighlow) +} case $BLOCK_BUTTON in 1) setsid -f "$TERMINAL" -e less -Srf "$weatherreport" ;; @@ -27,9 +47,6 @@ case $BLOCK_BUTTON in 6) "$TERMINAL" -e "$EDITOR" "$0" ;; esac -# The test if our forcecast is updated to the day. If it isn't download a new -# weather report from wttr.in with the above function. -[ -s "$weatherreport" ] && [ "$(stat -c %y "$weatherreport" 2>/dev/null | cut -d' ' -f1)" = "$(date '+%Y-%m-%d')" ] || - getforecast +checkforecast || getforecast showweather diff --git a/.local/bin/statusbar/sb-kbselect b/.local/bin/statusbar/sb-kbselect index f0c923f5..ab2140c3 100755 --- a/.local/bin/statusbar/sb-kbselect +++ b/.local/bin/statusbar/sb-kbselect @@ -5,6 +5,7 @@ kb="$(setxkbmap -query | grep -oP 'layout:\s*\K\w+')" || exit 1 case $BLOCK_BUTTON in 1) kb_choice="$(awk '/! layout/{flag=1; next} /! variant/{flag=0} flag {print $2, "- " $1}' /usr/share/X11/xkb/rules/base.lst | dmenu -l 15)" + [ -z "$kb_choice" ] && exit 0 kb="$(echo "$kb_choice" | awk '{print $3}')" setxkbmap "$kb" pkill -RTMIN+30 "${STATUSBAR:-dwmblocks}";; diff --git a/.local/bin/statusbar/sb-music b/.local/bin/statusbar/sb-music index 7ea70320..d164b4be 100755 --- a/.local/bin/statusbar/sb-music +++ b/.local/bin/statusbar/sb-music @@ -1,6 +1,6 @@ #!/bin/sh -filter() { mpc | sed "/^volume:/d;s/\\&/&/g;s/\\[paused\\].*/⏸/g;/\\[playing\\].*/d;/^ERROR/Q" | paste -sd ' ' -;} +filter() { sed "/^volume:/d;s/\\&/&/g;s/\\[paused\\].*/⏸/g;/\\[playing\\].*/d;/^ERROR/Q" | paste -sd ' ' -;} pidof -x sb-mpdup >/dev/null 2>&1 || sb-mpdup >/dev/null 2>&1 & diff --git a/.local/bin/statusbar/sb-volume b/.local/bin/statusbar/sb-volume index d17ce666..acdf7a9e 100755 --- a/.local/bin/statusbar/sb-volume +++ b/.local/bin/statusbar/sb-volume @@ -4,9 +4,9 @@ case $BLOCK_BUTTON in 1) setsid -f "$TERMINAL" -e pulsemixer ;; - 2) pamixer -t ;; - 4) pamixer --allow-boost -i 1 ;; - 5) pamixer --allow-boost -d 1 ;; + 2) wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle ;; + 4) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%+ ;; + 5) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%- ;; 3) notify-send "πŸ“’ Volume module" "\- Shows volume πŸ”Š, πŸ”‡ if muted. - Middle click to mute. - Scroll to change." ;; @@ -19,14 +19,15 @@ vol="$(wpctl get-volume @DEFAULT_AUDIO_SINK@)" [ "$vol" != "${vol%\[MUTED\]}" ] && echo πŸ”‡ && exit vol="${vol#Volume: }" + split() { # For ommiting the . without calling and external program. IFS=$2 set -- $1 printf '%s' "$@" } -vol="$(split "$vol" ".")" -vol="${vol##0}" + +vol="$(printf "%.0f" "$(split "$vol" ".")")" case 1 in $((vol >= 70)) ) icon="πŸ”Š" ;; diff --git a/.local/bin/tutorialvids b/.local/bin/tutorialvids index 6d4914bd..8d1dc471 100755 --- a/.local/bin/tutorialvids +++ b/.local/bin/tutorialvids @@ -6,21 +6,21 @@ vidlist=" dwm (window manager) https://videos.lukesmith.xyz/videos/watch/f6b78db7-b368-4647-bc64-28c08fff1988 +dwmblocks (status bar) https://videos.lukesmith.xyz/w/mmxHMbqZZEr5FManB57Yy1 pacman (installing/managing programs) https://videos.lukesmith.xyz/videos/watch/8e7cadb9-0fed-47ce-a2a8-6635fa48614b -status bar https://videos.lukesmith.xyz/videos/watch/a4d5326b-0aac-496e-bfc3-5acd5cee89f0 sxiv (image viewer) https://videos.lukesmith.xyz/videos/watch/ad4c8d85-90c3-4f3d-a1f3-89129e64a3c2 -st (terminal) https://videos.lukesmith.xyz/videos/watch/efddd39d-bac5-4599-b572-177beb4ce6e8 +st (terminal) https://videos.lukesmith.xyz/videos/watch/efddd39d-bac5-4599-b572-177beb4ce6e8 i3 (old window manager) https://videos.lukesmith.xyz/videos/watch/b861525c-7ada-40ee-a2bb-b5e1ffe0f48b neomutt (email) https://videos.lukesmith.xyz/videos/watch/83122e83-52d9-4278-ae1a-7d1beeb50c8e -ncmpcpp (music player) https://videos.lukesmith.xyz/videos/watch/b5ac6f0d-a220-4433-88e3-e98fc791dc0a +ncmpcpp (music player) https://videos.lukesmith.xyz/videos/watch/b5ac6f0d-a220-4433-88e3-e98fc791dc0a newsboat (RSS reader) https://videos.lukesmith.xyz/videos/watch/bd2c3fff-40fa-47ea-aa98-5b1ec0c903b6 lf (file manager) https://videos.lukesmith.xyz/w/rKeHsF5ZHDNDbR1buUKB1c -zathura (pdf viewer) https://videos.lukesmith.xyz/videos/watch/c780f75a-11f6-48a9-a191-d079ebc36ea4 -gpg keys https://videos.lukesmith.xyz/videos/watch/040f5530-4830-4583-9ddc-2080b421531b +zathura (pdf viewer) https://videos.lukesmith.xyz/videos/watch/c780f75a-11f6-48a9-a191-d079ebc36ea4 +gpg keys https://videos.lukesmith.xyz/videos/watch/040f5530-4830-4583-9ddc-2080b421531b calcurse (calendar) https://videos.lukesmith.xyz/videos/watch/4b937e8b-7654-46e3-8d01-79392ec5b3d1 -urlview https://videos.lukesmith.xyz/videos/watch/31a4918f-633b-4bd6-b08e-956ac75d0324 +urlview https://videos.lukesmith.xyz/videos/watch/31a4918f-633b-4bd6-b08e-956ac75d0324 colorschemes with pywal https://videos.lukesmith.xyz/videos/watch/1b476003-61b2-4609-ac4b-820c3d128643 vi mode in shell https://videos.lukesmith.xyz/videos/watch/228aa50c-836f-456f-9f0d-a45157fe4313 -pass (password manager) https://videos.lukesmith.xyz/videos/watch/432fc942-5e28-4682-9beb-f5cb237a1dd6 +pass (password manager) https://videos.lukesmith.xyz/videos/watch/432fc942-5e28-4682-9beb-f5cb237a1dd6 " echo "$vidlist" | grep -P "^$(echo "$vidlist" | grep "https:" | sed 's/\t.*//g' | dmenu -i -p "Learn about what? (ESC to cancel)" -l 20 | awk '{print $1}')\s" | sed 's/.*\t//' | xargs -r mpv diff --git a/.local/bin/unmounter b/.local/bin/unmounter new file mode 100755 index 00000000..7f1dbf5d --- /dev/null +++ b/.local/bin/unmounter @@ -0,0 +1,28 @@ +#!/bin/sh + +# Unmount USB drives or Android phones. Replaces the older `dmenuumount`. Fewer +# prompt and also de-decrypts LUKS drives that are unmounted. + +set -e + +mounteddroids="$(grep simple-mtpfs /etc/mtab | awk '{print "πŸ“±" $2}')" +lsblkoutput="$(lsblk -nrpo "name,type,size,mountpoint")" +mounteddrives="$(echo "$lsblkoutput" | awk '($2=="part"||$2="crypt")&&$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "πŸ’Ύ%s (%s)\n",$4,$3}')" + +allunmountable="$(echo "$mounteddroids +$mounteddrives" | sed "/^$/d;s/ *$//")" +test -n "$allunmountable" + +chosen="$(echo "$allunmountable" | dmenu -i -p "Unmount which drive?")" +chosen="${chosen%% *}" +test -n "$chosen" + +sudo -A umount -l "/${chosen#*/}" +notify-send "Device unmounted." "$chosen has been unmounted." + +# Close the chosen drive if decrypted. +cryptid="$(echo "$lsblkoutput" | grep "/${chosen#*/}$")" +cryptid="${cryptid%% *}" +test -b /dev/mapper/"${cryptid##*/}" +sudo -A cryptsetup close "$cryptid" +notify-send "πŸ”’Device dencryption closed." "Drive is now securely locked again." diff --git a/README.md b/README.md index 1594423b..135a8e49 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ curl -LO larbs.xyz/larbs.sh ``` or clone the repo files directly to your home directory and install the -[dependencies](https://github.com/LukeSmithxyz/LARBS/blob/master/progs.csv). +[dependencies](https://github.com/LukeSmithxyz/LARBS/blob/master/static/progs.csv). ## Default Desktop Artwork