diff --git a/.local/bin/i3cmds/cabl b/.local/bin/i3cmds/cabl new file mode 100755 index 0000000..b5b1b3f --- /dev/null +++ b/.local/bin/i3cmds/cabl @@ -0,0 +1,26 @@ +#!/bin/bash +# Dependencies are xclip and xorg-xprop. +# qrencode required for qrcode generation. +# groff/zathura required for man pages. +prim="$(xclip -o)"; [ -z "$prim" ] && exit + +PID=$(xprop -id "$(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}')" | grep -m 1 PID | cut -d " " -f 3) +PID=$(echo "$(pstree -lpA "$PID" | tail -n 1)" | awk -F'---' '{print $NF}' | sed -re 's/[^0-9]//g') +cd "$(readlink /proc/"$PID"/cwd)" +[ -f "$prim" ] && xdg-open "$prim" && exit +[ -d "$prim" ] && "$TERMINAL" "$prim" && exit + +websearch() { "$BROWSER" "https://duckduckgo.com/?q=$@" ;} +wikipedia() { "$BROWSER" "https://en.wikipedia.org/wiki/$@" ;} +wiktionary() { "$BROWSER" "https://en.wiktionary.org/wiki/$@" ;} +maps() { "$BROWSER" "https://www.openstreetmap.org/search?query=$@" ;} +ebay() { "$BROWSER" "https://www.ebay.com/sch/$@" ;} + +echo "$prim" | grep "^.*\.[A-Za-z]\+.*" >/dev/null && gotourl() { "$BROWSER" "$@" ;} +echo "$prim" | grep "^.*@.*\.[A-Za-z]\+$" >/dev/null && email() { xdg-email "$@" ;} +command -v qrencode >/dev/null && qrcode() { qrencode "$@" -s 10 -o /tmp/qr.png && xdg-open /tmp/qr.png ;} +man -k "^$prim$" >/dev/null && manual() { man -Tpdf "$prim" | zathura - ;} + +func="$(declare -F | awk '{print $3}' | dmenu -p "Plumb \"$(echo "$prim" | cut -c -30)\" to?" -i -l 15)" + +[ -z "$func" ] || "$func" "$prim" diff --git a/.local/bin/i3cmds/camtoggle b/.local/bin/i3cmds/camtoggle new file mode 100755 index 0000000..05679c0 --- /dev/null +++ b/.local/bin/i3cmds/camtoggle @@ -0,0 +1,2 @@ +#!/bin/sh +pkill -f /dev/video || mpv --no-osc --no-input-default-bindings --input-conf=/dev/null --geometry=-0-0 --autofit=30% --title="mpvfloat" /dev/video0 diff --git a/.local/bin/i3cmds/ddspawn b/.local/bin/i3cmds/ddspawn new file mode 100755 index 0000000..d4a4034 --- /dev/null +++ b/.local/bin/i3cmds/ddspawn @@ -0,0 +1,19 @@ +#!/bin/sh + +# Toggle floating dropdown terminal in i3, or start if non-existing. +# $1 is the script run in the terminal. +# All other args are terminal settings. +# Terminal names are in dropdown_* to allow easily setting i3 settings. + +[ -z "$1" ] && exit + +script=$1 +shift +if xwininfo -tree -root | grep "(\"dropdown_$script\" "; +then + echo "Window detected." + i3 "[instance=\"dropdown_$script\"] scratchpad show; [instance=\"dropdown_$script\"] move position center" +else + echo "Window not detected... spawning." + i3 "exec --no-startup-id $TERMINAL -n dropdown_$script $@ -e $script" +fi diff --git a/.local/bin/i3cmds/displayselect b/.local/bin/i3cmds/displayselect new file mode 100755 index 0000000..e526014 --- /dev/null +++ b/.local/bin/i3cmds/displayselect @@ -0,0 +1,73 @@ +#!/bin/sh + +# A UI for detecting and selecting all displays. +# Probes xrandr for connected displays and lets user select one to use. +# User may also select "manual selection" which opens arandr. +# I plan on adding a routine from multi-monitor setups later. + +twoscreen() { # If multi-monitor is selected and there are two screens. + + mirror=$(printf "no\\nyes" | dmenu -i -p "Mirror displays?") + # Mirror displays using native resolution of external display and a scaled + # version for the internal display + if [ "$mirror" = "yes" ]; then + external=$(echo "$screens" | dmenu -i -p "Optimize resolution for:") + internal=$(echo "$screens" | grep -v "$external") + + res_external=$(xrandr --query | sed -n "/^$external/,/\+/p" | \ + tail -n 1 | awk '{print $1}') + res_internal=$(xrandr --query | sed -n "/^$internal/,/\+/p" | \ + tail -n 1 | awk '{print $1}') + + res_ext_x=$(echo $res_external | sed 's/x.*//') + res_ext_y=$(echo $res_external | sed 's/.*x//') + res_int_x=$(echo $res_internal | sed 's/x.*//') + res_int_y=$(echo $res_internal | sed 's/.*x//') + + scale_x=$(echo "$res_ext_x / $res_int_x" | bc -l) + scale_y=$(echo "$res_ext_y / $res_int_y" | bc -l) + + xrandr --output "$external" --auto --scale 1.0x1.0 \ + --output "$internal" --auto --same-as "$external" \ + --scale "$scale_x"x"$scale_y" + else + + primary=$(echo "$screens" | dmenu -i -p "Select primary display:") + secondary=$(echo "$screens" | grep -v "$primary") + direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?") + xrandr --output "$primary" --auto --scale 1.0x1.0 --output "$secondary" --"$direction"-of "$primary" --auto --scale 1.0x1.0 + fi + } + +morescreen() { # If multi-monitor is selected and there are more than two screens. + primary=$(echo "$screens" | dmenu -i -p "Select primary display:") + secondary=$(echo "$screens" | grep -v "$primary" | dmenu -i -p "Select secondary display:") + direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?") + tertiary=$(echo "$screens" | grep -v "$primary" | grep -v "$secondary" | dmenu -i -p "Select third display:") + xrandr --output "$primary" --auto --output "$secondary" --"$direction"-of "$primary" --auto --output "$tertiary" --"$(printf "left\\nright" | grep -v "$direction")"-of "$primary" --auto + } + +multimon() { # Multi-monitor handler. + case "$(echo "$screens" | wc -l)" in + 1) xrandr $(echo "$allposs" | grep -v "$screens" | awk '{print "--output", $1, "--off"}' | tr '\n' ' ') ;; + 2) twoscreen ;; + *) morescreen ;; + esac ;} + +# Get all possible displays +allposs=$(xrandr -q | grep "connected") + +# Get all connected screens. +screens=$(echo "$allposs" | grep " connected" | awk '{print $1}') + +# Get user choice including multi-monitor and manual selection: +chosen=$(printf "%s\\nmulti-monitor\\nmanual selection" "$screens" | dmenu -i -p "Select display arangement:") && +case "$chosen" in + "manual selection") arandr ; exit ;; + "multi-monitor") multimon ;; + *) xrandr --output "$chosen" --auto --scale 1.0x1.0 $(echo "$allposs" | grep -v "$chosen" | awk '{print "--output", $1, "--off"}' | tr '\n' ' ') ;; +esac + +setbg # Fix background if screen size/arangement has changed. +remaps # Re-remap keys if keyboard added (for laptop bases) +pgrep -x dunst >/dev/null && killall dunst && setsid dunst & # Restart dunst to ensure proper location on screen diff --git a/.local/bin/i3cmds/dmenumount b/.local/bin/i3cmds/dmenumount new file mode 100755 index 0000000..0de5f0f --- /dev/null +++ b/.local/bin/i3cmds/dmenumount @@ -0,0 +1,59 @@ +#!/bin/sh +# Gives a dmenu prompt to mount unmounted drives. +# 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 + mp="$(find $1 2>/dev/null | dmenu -i -p "Type in mount point.")" + [ "$mp" = "" ] && exit 1 + 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 + } + +mountusb() { \ + chosen="$(echo "$usbdrives" | dmenu -i -p "Mount which drive?" | 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 '$2=="part"&&$3!~/\/boot|\/home$|SWAP/&&length($3)>1{printf "-not \\( -path *%s -prune \\) \\ \n",$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;; + *) 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." + } + +mountandroid() { \ + chosen=$(echo "$anddrives" | dmenu -i -p "Which Android device?" | cut -d : -f 1) + getmount "$HOME -maxdepth 3 -type d" + simple-mtpfs --device "$chosen" "$mp" + notify-send "πŸ€– Android Mounting" "Android device mounted to $mp." + } + +asktype() { \ + case $(printf "USB\\nAndroid" | dmenu -i -p "Mount a USB drive or Android device?") in + USB) mountusb ;; + Android) mountandroid ;; + esac + } + +anddrives=$(simple-mtpfs -l 2>/dev/null) +usbdrives="$(lsblk -rpo "name,type,size,mountpoint" | awk '$2=="part"&&$4==""{printf "%s (%s)\n",$1,$3}')" + +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/i3cmds/dmenurecord b/.local/bin/i3cmds/dmenurecord new file mode 100755 index 0000000..6af25a9 --- /dev/null +++ b/.local/bin/i3cmds/dmenurecord @@ -0,0 +1,105 @@ +#!/bin/sh + +# Usage: +# `record`: Ask for recording type via dmenu +# `record screencast`: Record both audio and screen +# `record video`: Record only screen +# `record audio`: Record only audio +# `record kill`: Kill existing recording +# +# If there is already a running instance, user will be prompted to end it. + +updateicon() { \ + echo "$1" > /tmp/recordingicon + pkill -RTMIN+9 i3blocks + } + +killrecording() { + recpid="$(cat /tmp/recordingpid)" + # kill with SIGTERM, allowing finishing touches. + kill -15 "$recpid" + rm -f /tmp/recordingpid + updateicon "" + pkill -RTMIN+9 i3blocks + # 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 | grep dimensions | awk '{print $2;}') \ + -i $DISPLAY \ + -f alsa -i default \ + -r 30 \ + -c:v libx264rgb -crf 0 -preset ultrafast -c:a flac \ + "$HOME/screencast-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "βΊοΈπŸŽ™οΈ" + } + +video() { ffmpeg \ + -f x11grab \ + -s $(xdpyinfo | grep dimensions | awk '{print $2;}') \ + -i $DISPLAY \ + -c:v libx264 -qp 0 -r 30 \ + "$HOME/video-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "⏺️" + } + +webcamhidef() { ffmpeg \ + -f v4l2 \ + -i /dev/video0 \ + -video_size 1920x1080 \ + "$HOME/webcam-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "πŸŽ₯" + } + +webcam() { ffmpeg \ + -f v4l2 \ + -i /dev/video0 \ + -video_size 640x480 \ + "$HOME/webcam-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "πŸŽ₯" + } + + +audio() { \ + ffmpeg \ + -f alsa -i default \ + -c:a flac \ + "$HOME/audio-$(date '+%y%m%d-%H%M-%S').flac" & + echo $! > /tmp/recordingpid + updateicon "πŸŽ™οΈ" + } + +askrecording() { \ + choice=$(printf "screencast\\nvideo\\naudio\\nwebcam\\nwebcam (hi-def)" | dmenu -i -p "Select recording style:") + case "$choice" in + screencast) screencast;; + audio) audio;; + video) video;; + webcam) webcam;; + "webcam (hi-def)") webcamhidef;; + esac + } + +asktoend() { \ + response=$(printf "No\\nYes" | dmenu -i -p "Recording still active. End recording?") && + [ "$response" = "Yes" ] && killrecording + } + + +case "$1" in + screencast) screencast;; + audio) audio;; + video) video;; + kill) killrecording;; + *) ([ -f /tmp/recordingpid ] && asktoend && exit) || askrecording;; +esac diff --git a/.local/bin/i3cmds/dmenuumount b/.local/bin/i3cmds/dmenuumount new file mode 100755 index 0000000..dee53e7 --- /dev/null +++ b/.local/bin/i3cmds/dmenuumount @@ -0,0 +1,41 @@ +#!/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. + +unmountusb() { + [ -z "$drives" ] && exit + chosen=$(echo "$drives" | dmenu -i -p "Unmount which drive?" | awk '{print $1}') + [ -z "$chosen" ] && exit + sudo -A umount "$chosen" && notify-send "πŸ’» USB unmounting" "$chosen unmounted." + } + +unmountandroid() { \ + chosen=$(awk '/simple-mtpfs/ {print $2}' /etc/mtab | dmenu -i -p "Unmount which device?") + [ -z "$chosen" ] && exit + sudo -A umount -l "$chosen" && notify-send "πŸ€– Android unmounting" "$chosen unmounted." + } + +asktype() { \ + case "$(printf "USB\\nAndroid" | dmenu -i -p "Unmount a USB drive or Android device?")" in + USB) unmountusb ;; + Android) unmountandroid ;; + esac + } + +drives=$(lsblk -nrpo "name,type,size,mountpoint" | awk '$2=="part"&&$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "%s (%s)\n",$4,$3}') + +if ! grep simple-mtpfs /etc/mtab; then + [ -z "$drives" ] && echo "No drives to unmount." && exit + echo "Unmountable USB drive detected." + unmountusb +else + if [ -z "$drives" ] + then + echo "Unmountable Android device detected." + unmountandroid + else + echo "Unmountable USB drive(s) and Android device(s) detected." + asktype + fi +fi diff --git a/.local/bin/i3cmds/dmenuunicode b/.local/bin/i3cmds/dmenuunicode new file mode 100755 index 0000000..429e41e --- /dev/null +++ b/.local/bin/i3cmds/dmenuunicode @@ -0,0 +1,22 @@ +#!/bin/sh +# Give dmenu list of all unicode characters to copy. +# Shows the selected character in dunst if running. + +# Must have xclip installed to even show menu. +xclip -h >/dev/null || exit + +if [ -e ~/.config/fontawesome ]; then + chosen=$(grep -v "#" -h ~/.config/emoji ~/.config/fontawesome | dmenu -i -l 20 -fn Monospace-18) +else + chosen=$(grep -v "#" ~/.config/emoji | dmenu -i -l 20 -fn Monospace-18) +fi + +[ "$chosen" != "" ] || exit + +c=$(echo "$chosen" | sed "s/ .*//") +echo "$c" | tr -d '\n' | xclip -selection clipboard +notify-send "'$c' copied to clipboard." & + +s=$(echo "$chosen" | sed "s/.*; //" | awk '{print $1}') +echo "$s" | tr -d '\n' | xclip +notify-send "'$s' copied to primary." & diff --git a/.local/bin/i3cmds/dropdowncalc b/.local/bin/i3cmds/dropdowncalc new file mode 100755 index 0000000..4d41f88 --- /dev/null +++ b/.local/bin/i3cmds/dropdowncalc @@ -0,0 +1,2 @@ +#!/bin/sh +ifinstalled bc && echo "Welcome to the Calculator." && bc -lq diff --git a/.local/bin/i3cmds/ducksearch b/.local/bin/i3cmds/ducksearch new file mode 100755 index 0000000..7b5bca6 --- /dev/null +++ b/.local/bin/i3cmds/ducksearch @@ -0,0 +1,20 @@ +#!/bin/sh +# Gives a dmenu prompt to search DuckDuckGo. +# Without input, will open DuckDuckGo.com. +# URLs will be directly handed to the browser. +# Anything else, it search it. +browser=${BROWSER:-firefox} + +pgrep -x dmenu && exit + +choice=$(echo "πŸ¦†" | dmenu -i -p "Search DuckDuckGo:") || exit 1 + +if [ "$choice" = "πŸ¦†" ]; then + $browser "https://duckduckgo.com" +else + if echo "$choice" | grep "^(http:\/\/|https:\/\/)?[a-zA-Z0-9]+\.[a-zA-Z]+(/)?.*$"; then + $browser "$choice" + else + $browser "https://duckduckgo.com/?q=$choice&t=ffab&atb=v1-1" + fi +fi diff --git a/.local/bin/i3cmds/hover b/.local/bin/i3cmds/hover new file mode 100755 index 0000000..8d03a99 --- /dev/null +++ b/.local/bin/i3cmds/hover @@ -0,0 +1,14 @@ +#!/bin/sh +[ -z "$1" ] && exit # If $1 is left, hovers in the bottom left, if right, the bottom right +current=$(xdotool getwindowfocus) +newwidth=$(($(xdotool getdisplaygeometry | awk '{print $2}') / 3)) +newheight=$(($(xdotool getdisplaygeometry | awk '{print $1}') / 3)) +xdotool windowsize "$current" $newheight $newwidth +newsize=$(xdotool getwindowgeometry "$current" | grep Geometry | sed -e 's/x/ /g' | awk '{print $3}') +newwidth=$(xdotool getwindowgeometry "$current" | grep Geometry | grep -o " [0-9]*") + +case "$1" in + left) horizontal=0; vertical=$(($(xdotool getdisplaygeometry | awk '{print $2}') - newsize)) ;; + right) horizontal=$(($(xdotool getdisplaygeometry | awk '{print $1}') - newwidth)) ; vertical=$(($(xdotool getdisplaygeometry | awk '{print $2}') - newsize)) ;; +esac +xdotool windowmove "$current" $horizontal $vertical diff --git a/.local/bin/i3cmds/i3resize b/.local/bin/i3cmds/i3resize new file mode 100755 index 0000000..11b0992 --- /dev/null +++ b/.local/bin/i3cmds/i3resize @@ -0,0 +1,27 @@ +#!/bin/sh +# This script was made by `goferito` on Github. +# Some cleanup by Luke. + +[ -z "$1" ] && echo "No direction provided" && exit 1 +distanceStr="2 px or 2 ppt" + +moveChoice() { + i3-msg resize "$1" "$2" "$distanceStr" | grep '"success":true' || \ + i3-msg resize "$3" "$4" "$distanceStr" +} + +case $1 in + up) + moveChoice grow up shrink down + ;; + down) + moveChoice shrink up grow down + ;; + left) + moveChoice shrink right grow left + ;; + right) + moveChoice grow right shrink left + ;; +esac + diff --git a/.local/bin/i3cmds/killrecording b/.local/bin/i3cmds/killrecording new file mode 100755 index 0000000..ec9a698 --- /dev/null +++ b/.local/bin/i3cmds/killrecording @@ -0,0 +1,7 @@ +#!/bin/sh + +kill -9 "$(cat ~/.recordingpid)" + +# Update i3bar. +echo "" > ~/.recordingicon +pkill -RTMIN+9 i3blocks diff --git a/.local/bin/i3cmds/maimpick b/.local/bin/i3cmds/maimpick new file mode 100755 index 0000000..07d032f --- /dev/null +++ b/.local/bin/i3cmds/maimpick @@ -0,0 +1,9 @@ +#!/bin/sh +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-"$(date '+%y%m%d-%H%M-%S').png" ;; + "current window") maim -i "$(xdotool getactivewindow)" pic-window-"$(date '+%y%m%d-%H%M-%S').png" ;; + "full screen") maim pic-full-"$(date '+%y%m%d-%H%M-%S').png" ;; + "a selected area (copy)") maim -s | xclip -selection clipboard -t image/png ;; + "current window (copy)") maim -i "$(xdotool getactivewindow)" | xclip -selection clipboard -t image/png ;; + "full screen (copy)") maim | xclip -selection clipboard -t image/png ;; +esac diff --git a/.local/bin/i3cmds/prompt b/.local/bin/i3cmds/prompt new file mode 100755 index 0000000..56de2f8 --- /dev/null +++ b/.local/bin/i3cmds/prompt @@ -0,0 +1,7 @@ +#!/bin/sh +# A dmenu binary prompt script. +# Gives a dmenu prompt labeled with $1 to perform command $2. +# For example: +# `./prompt "Do you want to shutdown?" "shutdown -h now"` + +[ "$(printf "No\\nYes" | dmenu -i -p "$1" -nb darkred -sb red -sf white -nf gray )" = "Yes" ] && $2 diff --git a/.local/bin/i3cmds/samedir b/.local/bin/i3cmds/samedir new file mode 100755 index 0000000..88845fc --- /dev/null +++ b/.local/bin/i3cmds/samedir @@ -0,0 +1,5 @@ +#!/bin/sh +PID=$(xprop -id "$(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}')" | grep -m 1 PID | cut -d " " -f 3) +PID=$(echo "$(pstree -lpA "$PID" | tail -n 1)" | awk -F'---' '{print $NF}' | sed -re 's/[^0-9]//g') +cd "$(readlink /proc/"$PID"/cwd)" +"$TERMINAL" diff --git a/.local/bin/i3cmds/showclip b/.local/bin/i3cmds/showclip new file mode 100755 index 0000000..d2faff8 --- /dev/null +++ b/.local/bin/i3cmds/showclip @@ -0,0 +1,10 @@ +#!/bin/sh + +# Display contents of selection via dunst if running. +# Separate script for i3. + +clip=$(xclip -o -selection clipboard) +prim=$(xclip -o -selection primary) + +[ -n "$clip" ] && notify-send "Clipboard:" "$clip" +[ -n "$prim" ] && notify-send "Primary:" "$prim" diff --git a/.local/bin/i3cmds/td-toggle b/.local/bin/i3cmds/td-toggle new file mode 100755 index 0000000..dc727b9 --- /dev/null +++ b/.local/bin/i3cmds/td-toggle @@ -0,0 +1,10 @@ +#!/bin/sh +# If transmission-daemon is running, will ask to kill, else will ask to start. +if pgrep -x transmission-da >/dev/null ; +then + [ "$(printf "No\\nYes" | dmenu -i -p "Kill transmission-daemon?")" = "Yes" ] && killall transmission-da && notify-send "transmission-daemon killed." +else + ifinstalled transmission-cli || exit + [ "$(printf "No\\nYes" | dmenu -i -p "Start transmission daemon?")" = "Yes" ] && transmission-daemon && notify-send "tranmission-daemon started." +fi +sleep 3 && pkill -RTMIN+7 i3blocks diff --git a/.local/bin/i3cmds/tmuxdd b/.local/bin/i3cmds/tmuxdd new file mode 100755 index 0000000..c194ff1 --- /dev/null +++ b/.local/bin/i3cmds/tmuxdd @@ -0,0 +1,4 @@ +#!/bin/sh +# This is the script that i3 runs to either start tmux in +# the dropdown terminal or log into a previous session. +tmux a || tmux diff --git a/.local/bin/i3cmds/toggletouchpad b/.local/bin/i3cmds/toggletouchpad new file mode 100755 index 0000000..6d8c9c8 --- /dev/null +++ b/.local/bin/i3cmds/toggletouchpad @@ -0,0 +1,4 @@ +#!/bin/sh +# Toggle touchpad. Requires xf86-input-synaptics. +(synclient | grep "TouchpadOff.*1" && synclient TouchpadOff=0)>/dev/null && echo "TouchPad reactivated." && exit +synclient TouchpadOff=1 && echo "TouchPad deactivated." diff --git a/.local/bin/i3cmds/torwrap b/.local/bin/i3cmds/torwrap new file mode 100755 index 0000000..04e7a51 --- /dev/null +++ b/.local/bin/i3cmds/torwrap @@ -0,0 +1,6 @@ +#!/bin/sh +ifinstalled transmission-remote-cli transmission-cli || exit + +! pgrep -x transmission-da >/dev/null && transmission-daemon && notify-send "Starting torrent daemon..." && sleep 3 && pkill -RTMIN+7 i3blocks + +$TERMINAL -e transmission-remote-cli diff --git a/.local/bin/i3cmds/tutorialvids b/.local/bin/i3cmds/tutorialvids new file mode 100755 index 0000000..f1357eb --- /dev/null +++ b/.local/bin/i3cmds/tutorialvids @@ -0,0 +1,18 @@ +#!/bin/sh +vidlist=" +status bar https://www.youtube.com/watch?v=gKumet6b-WY +sxiv (image viewer) https://www.youtube.com/watch?v=GYW9i_u5PYs +st (terminal) https://www.youtube.com/watch?v=9H75enWM22k +i3 (window manager) https://www.youtube.com/watch?v=GKviflL9XeI +pacman (installing/managing programs) https://www.youtube.com/watch?v=-dEuXTMzRKs +mutt (email) https://www.youtube.com/watch?v=2U3vRbF7v5A +ncmpcpp (music player) https://www.youtube.com/watch?v=sZIEdI9TS2U +newsboat (RSS reader) https://www.youtube.com/watch?v=dUFCRqs822w +zathura (pdf viewer) https://www.youtube.com/watch?v=V_Iz4zdyRM4 +gpg keys https://www.youtube.com/watch?v=DMGIlj7u7Eo +calcurse (calendar) https://www.youtube.com/watch?v=hvc-pHjbhdE +urlview https://www.youtube.com/watch?v=IgzpAjFgbCw +colorschemes with pywal https://www.youtube.com/watch?v=Es79N_9BblE +vi mode in shell https://www.youtube.com/watch?v=GqoJQft5R2E +" +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/i3cmds/winresize b/.local/bin/i3cmds/winresize new file mode 100755 index 0000000..090bbf3 --- /dev/null +++ b/.local/bin/i3cmds/winresize @@ -0,0 +1,2 @@ +#!/bin/sh +echo "πŸ“" | dmenu -p "Give width and height:" | xargs xdotool windowsize "$(xdotool getwindowfocus)" diff --git a/.local/bin/statusbar/battery b/.local/bin/statusbar/battery new file mode 100755 index 0000000..25c9269 --- /dev/null +++ b/.local/bin/statusbar/battery @@ -0,0 +1,32 @@ +#!/bin/sh +# Give a battery name (e.g. BAT0) as an argument. + +case $BLOCK_BUTTON in + 3) pgrep -x dunst >/dev/null && notify-send "πŸ”‹ Battery module" "πŸ”‹: discharging +πŸ›‘: not charging +β™»: stagnant charge +πŸ”Œ: charging +⚑: charged +❗: battery very low! +- Text color reflects charge left" ;; +esac + +capacity=$(cat /sys/class/power_supply/"$1"/capacity) || exit +status=$(cat /sys/class/power_supply/"$1"/status) + +if [ "$capacity" -ge 75 ]; then + color="#00ff00" +elif [ "$capacity" -ge 50 ]; then + color="#ffffff" +elif [ "$capacity" -ge 25 ]; then + color="#ffff00" +else + color="#ff0000" + warn="❗" +fi + +[ -z $warn ] && warn=" " + +[ "$status" = "Charging" ] && color="#ffffff" + +printf "%s%s%s" "$color" "$(echo "$status" | sed -e "s/,//;s/Discharging/πŸ”‹/;s/Not Charging/πŸ›‘/;s/Charging/πŸ”Œ/;s/Unknown/♻️/;s/Full/⚑/;s/ 0*/ /g;s/ :/ /g")" "$warn" "$(echo "$capacity" | sed -e 's/$/%/')" diff --git a/.local/bin/statusbar/clock b/.local/bin/statusbar/clock new file mode 100755 index 0000000..d6d54ef --- /dev/null +++ b/.local/bin/statusbar/clock @@ -0,0 +1,10 @@ +#!/bin/sh + +date '+%Y %b %d (%a) %I:%M%p' + +case $BLOCK_BUTTON in + 1) pgrep -x dunst >/dev/null && notify-send "This Month" "$(cal --color=always | sed "s/..7m//;s/..27m/<\/span><\/b>/")" && notify-send "Appointments" "$(calcurse -D ~/.config/calcurse -d3)" ;; + 2) "$TERMINAL" -e calcurse -D ~/.config/calcurse ;; + 3) pgrep -x dunst >/dev/null && notify-send "πŸ“… Time/date module" "\- Left click to show upcoming appointments for the next three days via \`calcurse -d3\` and show the month via \`cal\` +- Middle click opens calcurse if installed" ;; +esac diff --git a/.local/bin/statusbar/cpu b/.local/bin/statusbar/cpu new file mode 100755 index 0000000..3b1394a --- /dev/null +++ b/.local/bin/statusbar/cpu @@ -0,0 +1,10 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) notify-send "πŸ–₯ CPU hogs" "$(ps axch -o cmd:15,%cpu --sort=-%cpu | head)" ;; + 3) notify-send "πŸ–₯ CPU module " "\- Shows CPU temperature. +- Click to show intensive processes. +- % is of single core." ;; +esac + +sensors | awk '/Core 0/ {print $3}' diff --git a/.local/bin/statusbar/disk b/.local/bin/statusbar/disk new file mode 100755 index 0000000..d3dd07d --- /dev/null +++ b/.local/bin/statusbar/disk @@ -0,0 +1,18 @@ +#!/bin/sh + +# Status bar module for disk space +# $1 should be drive mountpoint +# $2 is optional icon, otherwise mountpoint will displayed + +[ -z "$1" ] && exit + +icon="$2" +[ -z "$2" ] && icon="$1" + +case $BLOCK_BUTTON in + 1) pgrep -x dunst >/dev/null && notify-send "πŸ’½ Disk space" "$(df -h --output=target,used,size)" ;; + 3) pgrep -x dunst >/dev/null && notify-send "πŸ’½ Disk module" "\- Shows used hard drive space. +- Click to show all disk info." ;; +esac + +printf "%s: %s" "$icon" "$(df -h "$1" | awk ' /[0-9]/ {print $3 "/" $2}')" diff --git a/.local/bin/statusbar/help b/.local/bin/statusbar/help new file mode 100755 index 0000000..4916d5c --- /dev/null +++ b/.local/bin/statusbar/help @@ -0,0 +1,7 @@ +#!/bin/sh +case $BLOCK_BUTTON in + 1) groff -mom ~/.local/share/larbs/readme.mom -Tpdf | zathura - ;; + 2) i3 restart ;; + 3) pgrep -x dunst >/dev/null && notify-send "❓ Help module" "\- Left click to open LARBS guide. +- Middle click to refresh i3.";; +esac; echo "❓" diff --git a/.local/bin/statusbar/internet b/.local/bin/statusbar/internet new file mode 100755 index 0000000..1d2f2e8 --- /dev/null +++ b/.local/bin/statusbar/internet @@ -0,0 +1,17 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) $TERMINAL -e nmtui ;; + 3) pgrep -x dunst >/dev/null && notify-send "🌐 Internet module" "\- Click to connect +πŸ“‘: no wifi connection +πŸ“Ά: wifi connection with quality +❎: no ethernet +🌐: ethernet working +" ;; +esac + +[ "$(cat /sys/class/net/w*/operstate)" = 'down' ] && wifiicon="πŸ“‘" + +[ ! -n "${wifiicon+var}" ] && wifiicon=$(grep "^\s*w" /proc/net/wireless | awk '{ print "πŸ“Ά", int($3 * 100 / 70) "%" }') + +printf "%s %s" "$wifiicon" "$(cat /sys/class/net/e*/operstate | sed "s/down/❎/;s/up/🌐/")" diff --git a/.local/bin/statusbar/iplocate b/.local/bin/statusbar/iplocate new file mode 100755 index 0000000..4ca4f10 --- /dev/null +++ b/.local/bin/statusbar/iplocate @@ -0,0 +1,9 @@ +#!/bin/sh + +# Gets your public ip address checks which country you are in and +# displays that information in the statusbar +# +# https://www.maketecheasier.com/ip-address-geolocation-lookups-linux/ +ifinstalled "geoiplookup" || exit +addr="$(curl ifconfig.me 2>/dev/null)" || exit +grep "flag: " ~/.config/emoji | grep "$(geoiplookup $addr | sed 's/.*, //')" | sed "s/flag: //;s/;.*//" diff --git a/.local/bin/statusbar/mailbox b/.local/bin/statusbar/mailbox new file mode 100755 index 0000000..21c85ab --- /dev/null +++ b/.local/bin/statusbar/mailbox @@ -0,0 +1,16 @@ +#!/bin/sh + +# i3blocks mail module. +# Displays number of unread mail and an loading icon if updating. +# When clicked, brings up `neomutt`. + +case $BLOCK_BUTTON in + 1) "$TERMINAL" -e neomutt ;; + 2) setsid mailsync >/dev/null & ;; + 3) pgrep -x dunst >/dev/null && notify-send "πŸ“¬ Mail module" "\- Shows unread mail +- Shows πŸ”ƒ if syncing mail +- Left click opens neomutt +- Middle click syncs mail" ;; +esac + +echo "$(du -a ~/.local/share/mail/*/INBOX/new/* 2>/dev/null | sed -n '$=')$(cat /tmp/imapsyncicon_$USER 2>/dev/null)" diff --git a/.local/bin/statusbar/memory b/.local/bin/statusbar/memory new file mode 100755 index 0000000..dfd3d7b --- /dev/null +++ b/.local/bin/statusbar/memory @@ -0,0 +1,9 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) notify-send "🧠 Memory hogs" "$(ps axch -o cmd:15,%mem --sort=-%mem | head)" ;; + 3) notify-send "🧠 Memory module" "\- Shows Memory Used/Total. +- Click to show memory hogs." ;; +esac + +free -h | awk '/^Mem:/ {print $3 "/" $2}' diff --git a/.local/bin/statusbar/mpdupdate b/.local/bin/statusbar/mpdupdate new file mode 100755 index 0000000..afe11bb --- /dev/null +++ b/.local/bin/statusbar/mpdupdate @@ -0,0 +1,8 @@ +#!/bin/sh +# Whenever the mpd state changes, update the mpd i3 module. +kill -0 "$(cat /tmp/mpdupdate)" 2>/dev/null && exit || echo $$ > /tmp/mpdupdate + +sleep 5 && while : ; do + pkill -RTMIN+11 i3blocks + mpc idle >/dev/null || exit +done diff --git a/.local/bin/statusbar/music b/.local/bin/statusbar/music new file mode 100755 index 0000000..93c2c9c --- /dev/null +++ b/.local/bin/statusbar/music @@ -0,0 +1,18 @@ +#!/bin/sh + +filter() { + sed "/^volume:/d" | tac | sed -e "s/\\&/&/g;s/\\[paused\\].*//g;s/\\[playing\\].*//g" | tr -d '\n' | sed -e "s/$/<\\/span>/g" + } + +case $BLOCK_BUTTON in + 1) mpc status | filter && setsid "$TERMINAL" -e ncmpcpp & ;; # right click, pause/unpause + 2) mpc toggle | filter ;; # right click, pause/unpause + 3) mpc status | filter && pgrep -x dunst >/dev/null && notify-send "🎡 Music module" "\- Shows mpd song playing. +- Italic when paused. +- Left click opens ncmpcpp. +- Middle click pauses. +- Scroll changes track.";; # right click, pause/unpause + 4) mpc prev | filter ;; # scroll up, previous + 5) mpc next | filter ;; # scroll down, next + *) mpc status | filter ;; +esac; exit diff --git a/.local/bin/statusbar/news b/.local/bin/statusbar/news new file mode 100755 index 0000000..b7ca1a7 --- /dev/null +++ b/.local/bin/statusbar/news @@ -0,0 +1,17 @@ +#!/bin/sh + +# i3blocks newsboat module. +# Displays number of unread news items and an loading icon if updating. +# When clicked, brings up `newsboat`. + +case $BLOCK_BUTTON in + 1) setsid "$TERMINAL" -e newsboat ;; + 2) setsid newsup >/dev/null & exit ;; + 3) pgrep -x dunst >/dev/null && notify-send "πŸ“° News module" "\- Shows unread news items +- Shows πŸ”ƒ if updating with \`newsup\` +- Left click opens newsboat +- Middle click syncs RSS feeds +Note: Only one instance of newsboat (including updates) may be running at a time." ;; +esac + + cat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ print $1}' | sed s/^0$//g)$(cat ~/.config/newsboat/.update 2>/dev/null)" diff --git a/.local/bin/statusbar/pacpackages b/.local/bin/statusbar/pacpackages new file mode 100755 index 0000000..418bc2d --- /dev/null +++ b/.local/bin/statusbar/pacpackages @@ -0,0 +1,18 @@ +#!/bin/sh + +# i3blocks module for pacman upgrades. +# Displays number of upgradeable packages. +# For this to work, have a `pacman -Sy` command run in the background as a +# cronjob every so often as root. This script will then read those packages. +# When clicked, it will run an upgrade via pacman. + +case $BLOCK_BUTTON in + 1) $TERMINAL -e popupgrade ;; + 2) notify-send "$(/usr/bin/pacman -Qu)" ;; + 3) pgrep -x dunst >/dev/null && notify-send "Upgrade module" "πŸ“¦: number of upgradable packages +- Left click to upgrade packages +- Middle click to show upgradable packages" ;; +esac + + +pacman -Qu | grep -v "\[ignored\]" | wc -l | sed -e "s/^0$//g" diff --git a/.local/bin/statusbar/popupgrade b/.local/bin/statusbar/popupgrade new file mode 100755 index 0000000..83035c3 --- /dev/null +++ b/.local/bin/statusbar/popupgrade @@ -0,0 +1,9 @@ +#!/bin/sh + +printf "Beginning upgrade.\\n" + +yay -Syu +pkill -RTMIN+8 i3blocks + +printf "\\nUpgrade complete.\\nPress to exit window.\\n\\n" +read -r diff --git a/.local/bin/statusbar/torrent b/.local/bin/statusbar/torrent new file mode 100755 index 0000000..0ab811c --- /dev/null +++ b/.local/bin/statusbar/torrent @@ -0,0 +1,28 @@ +#!/bin/sh + +transmission-remote -l | grep % | + sed " # This first sed command is to ensure a desirable order with sort + s/.*Stopped.*/A/g; + s/.*Seeding.*/Z/g; + s/.*100%.*/N/g; + s/.*Idle.*/B/g; + s/.*Uploading.*/L/g; + s/.*%.*/M/g" | + sort -h | uniq -c | sed " # Now we replace the standin letters with icons. + s/A/πŸ›‘/g; + s/B/βŒ›οΈ/g; + s/L/πŸ”Ό/g; + s/M/πŸ”½/g; + s/N/βœ…/g; + s/Z/🌱/g" | awk '{print $2, $1}' | tr '\n' ' ' | sed -e "s/ $//g" + +case $BLOCK_BUTTON in + 1) $TERMINAL -e transmission-remote-cli ;; + 3) pgrep -x dunst >/dev/null && notify-send "Torrent module" "πŸ›‘: paused +⏳: idle (seeds needed) +πŸ”Ό: uploading (unfinished) +πŸ”½: downloading +βœ…: done +🌱: done and seeding" ;; +esac + diff --git a/.local/bin/statusbar/volume b/.local/bin/statusbar/volume new file mode 100755 index 0000000..3bbb32b --- /dev/null +++ b/.local/bin/statusbar/volume @@ -0,0 +1,25 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) setsid "$TERMINAL" -e pulsemixer & ;; + 2) pulsemixer --toggle-mute ;; + 4) pulsemixer --change-volume +5 ;; + 5) pulsemixer --change-volume -5 ;; + 3) pgrep -x dunst >/dev/null && notify-send "πŸ“’ Volume module" "\- Shows volume πŸ”Š, πŸ”‡ if muted. +- Middle click to mute. +- Scroll to change." +esac + +[ "$(pulsemixer --get-mute)" = "1" ] && printf "πŸ”‡\\n" && exit + +vol=$(pulsemixer --get-volume | awk '{print $1}') + +if [ "$vol" -gt "70" ]; then + icon="πŸ”Š" +elif [ "$vol" -lt "30" ]; then + icon="πŸ”ˆ" +else + icon="πŸ”‰" +fi + +printf "%s %s%%\\n" "$icon" "$vol" diff --git a/.local/bin/statusbar/weather b/.local/bin/statusbar/weather new file mode 100755 index 0000000..e4de680 --- /dev/null +++ b/.local/bin/statusbar/weather @@ -0,0 +1,23 @@ +#!/bin/sh +location="$1"; [ -z "$location" ] || { location="$location+" && rm -f "$HOME/.local/share/weatherreport" ;} + +getforecast() { ping -q -c 1 1.1.1.1 >/dev/null || exit 1 +curl -s "wttr.in/$location" > "$HOME/.local/share/weatherreport" || exit 1 ;} + +showweather() { printf "%s" "$(sed '16q;d' "$HOME/.local/share/weatherreport" | grep -wo "[0-9]*%" | sort -n | sed -e '$!d' | sed -e "s/^/β˜” /g" | tr -d '\n')" +sed '13q;d' "$HOME/.local/share/weatherreport" | grep -o "m\\(-\\)*[0-9]\\+" | sort -n -t 'm' -k 2n | sed -e 1b -e '$!d' | tr '\n|m' ' ' | awk '{print " ❄️",$1 "Β°","🌞",$2 "Β°"}' ;} + +case $BLOCK_BUTTON in + 1) $TERMINAL -e less -S "$HOME/.local/share/weatherreport" ;; + 2) getforecast && showweather ;; + 3) pgrep -x dunst >/dev/null && notify-send "🌈 Weather module" "\- Left click for full forecast. +- Middle click to update forecast. +β˜”: Chance of rain/snow +❄: Daily low +🌞: Daily high" ;; +esac + +if [ "$(stat -c %y "$HOME/.local/share/weatherreport" >/dev/null 2>&1 | awk '{print $1}')" != "$(date '+%Y-%m-%d')" ] + then getforecast && showweather + else showweather +fi diff --git a/.local/bin/unix b/.local/bin/unix new file mode 100755 index 0000000..14d7ef0 --- /dev/null +++ b/.local/bin/unix @@ -0,0 +1,25 @@ +#!/bin/sh +#original artwork by http://www.sanderfocus.nl/#/portfolio/tech-heroes +#converted to shell by #nixers @ irc.unix.chat + +cat << 'eof' + ,_ ,_==β–„β–‚ + , β–‚β–ƒβ–„β–„β–…β–…β–…β–‚β–…ΒΎ. / / + β–„β–†<Β΄ "Β»β–“β–“β–“%\ / / / / + ,β–…7" Β΄>β–“β–“β–“% / / > / >/% + ▐ΒΆβ–“ ,Β»β–“β–“ΒΎΒ΄ /> %/%// / / + β–“β–ƒβ–…β–…β–…β–ƒ,,β–„β–…β–…β–…Γ†\// ///>// />/ / + V║«¼.;β†’ β•‘<Β«.,`=// />//%/% / / + //β• <Β΄ -Β²,)(β–“~"-╝/ΒΎ/ %/>/ /> + / / / ▐% -./β–„β–ƒβ–„β–…▐, /7//;//% / / + / ////`β–Œ▐ %zWv xXβ–“β–‡β–Œ//&;% / / + / / / %//%/ΒΎΒ½Β΄β–Œβ–ƒβ–„β–„β–„β–„β–ƒβ–ƒ▐ΒΆ\/& / + </ /)VY>7; \_ UNIX IS VERY SIMPLE IT JUST NEEDS A + / /</ //<///<_/%\β–“ V%W%Β£)XY _/%β€Ύ\_, GENIUS TO UNDERSTAND ITS SIMPLICITY + / / //%/_,=--^/%/%%\ΒΎ%ΒΆ%%} /%%%%%%;\, + %/< /_/ %%%%%;X%%\%%;, _/%%%;, \ + / / %%%%%%;, \%%l%%;// _/%;, dmr + / %%%;, <;\-=-/ / + ;, l +eof \ No newline at end of file