added various util scripts and herbst config from desktop

This commit is contained in:
Rudis Muiznieks 2022-04-09 08:13:45 -05:00
parent a4b7e8c815
commit 3340f1629e
Signed by: rudism
GPG Key ID: CABF2F86EF7884F9
16 changed files with 1294 additions and 25 deletions

25
bin/audio-output-swap Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
bluecard=$(pactl list cards | grep 'Name: bluez_card' | awk '{ print $2 }')
if [ "$1" = "fixbt" ] && [ -n "$bluecard" ]; then
pactl set-card-profile "$bluecard" a2dp-sink
exit
fi
hdmisink=$(pactl list sinks | grep 'Name: ' | grep hdmi | awk '{ print $2 }')
bluesink=$(pactl list sinks | grep 'Name: ' | grep bluez | awk '{ print $2 }')
analogsink=$(pactl list sinks | grep 'Name: ' | grep analog | awk '{ print $2 }')
currentsink=$(pactl get-default-sink)
case "$currentsink" in
"$hdmisink") nextsink="${bluesink:-$analogsink}";;
*) nextsink="$hdmisink";;
esac
pactl set-default-sink "$nextsink"
if [ "$nextsink" = "$bluesink" ]; then
pactl set-card-profile "$bluecard" a2dp-sink
fi

24
bin/quake-term Executable file
View File

@ -0,0 +1,24 @@
#!/usr/bin/env bash
winid=$(xdotool search --classname QuakeConsole)
mongeom=$(herbstclient attr monitors.focus.geometry)
monw=${mongeom%x*}
monw=$(( monw - 4 ))
curtag=$(herbstclient attr tags.focus.name)
if [ -z "$winid" ]; then
(
rules=( floating=on floating_geometry="${monw}x512+1+1" )
herbstclient rule once pid=$BASHPID maxage=10 "${rules[@]}"
exec st -c QuakeConsole -n QuakeConsole -t QuakeConsole
) &
else
hcid=$(printf "0x%x" "$winid")
visible=$(herbstclient attr clients."$hcid".visible)
wintag=$(herbstclient attr clients."$hcid".tag)
if [ "$visible" = "false" ] || [ "$wintag" != "$curtag" ]; then
herbstclient chain , lock , set_attr clients."$hcid".floating_geometry "${monw}x512+1+1" , bring "$winid" , unlock
else
herbstclient set_attr clients."$hcid".minimized true
fi
fi

73
bin/stickyctl Executable file
View File

@ -0,0 +1,73 @@
#!/usr/bin/env sh
VERSION="0.0.2"
usage() {
echo 'stickyctl'
echo
echo "Version: $VERSION"
echo
echo 'stickyctl is a script to manage making windows (floating'
echo 'or tiled) sticky in herbstluftwm so it is visible on any'
echo 'tag.'
echo
echo 'Herbstluftwm autostart requirements:'
echo 'The following attributes need to be defined in the'
echo 'autostart file. This holds the window ID of the sticky'
echo 'window. It should be of type string'
echo ' my_sticky'
echo
echo 'Usage:'
echo ' stick Makes the focused window sticky.'
echo
echo ' unstick Clears the window ID and un-stick the'
echo ' window.'
echo
echo ' get-sticky Called when switching tags and gets'
echo ' the sticky window and pulls it to the'
echo ' current tag.'
echo
echo ' status Shows if a window is sticky. Use with'
echo ' status bars.'
echo
echo ' locate Focuses the sticky window.'
echo
echo ' reset Resets the my_sticky attribute in case'
echo ' the sticky window is closed without'
echo ' un-sticking it.'
exit 0
}
hc() {
herbstclient "$@"
}
case "$@" in
stick)
hc set_attr my_sticky $(hc attr clients.focus.winid)
notify-send -u normal "Sticky" "Window is <b><span foreground=\"#c0f83e\">STICKY</span></b>"
;;
unstick)
hc set_attr my_sticky ''
notify-send -u normal "Sticky" "Window is <b><span foreground=\"#c0f83e\">NOT STICKY</span></b>"
;;
get-sticky)
focused=$(hc get_attr clients.focus.winid)
hc bring $(hc attr my_sticky)
hc jumpto $focused
;;
status)
[[ -n $(hc attr my_sticky) ]] && echo "%{F#ffff52} %{F-} |" || echo ""
;;
locate)
hc jumpto "$(hc attr my_sticky)"
;;
reset)
hc set_attr my_sticky ''
notify-send -u critical -t 5000 "Sticky" "Sticky-Control is <b><span foreground=\"#ff4a52\">RESET</span></b>"
;;
*)
usage
;;
esac

166
herbstluftwm/autostart Executable file
View File

@ -0,0 +1,166 @@
#!/usr/bin/env bash
# this is a simple config for herbstluftwm
hc() {
herbstclient "$@"
}
hc new_attr string my_sticky
refresh_panel="pgrep -f 'bash.*panel\.sh' | xargs -n1 kill -s USR1"
hc emit_hook reload
if hc silent new_attr bool my_picom_is_running; then
picom -b
fi
xsetroot -solid "#080808" -cursor_name left_ptr &
feh --bg-fill ~/.config/herbstluftwm/wallpaper.jpg
xobpipe="$XDG_RUNTIME_DIR/xobpipe"
# remove all existing keybindings
hc keyunbind --all
hc set default_frame_layout horizontal
hc set_layout horizontal
# keybindings
Mod=Mod4 # Use the super key as the main modifier
hc keybind $Mod-Shift-q quit
hc keybind $Mod-Control-r reload
hc keybind $Mod-Shift-c close
hc keybind $Mod-Return spawn st
hc keybind $Mod-grave spawn quake-term
hc keybind $Mod-Control-Return spawn flatpak run org.qutebrowser.qutebrowser
hc keybind Print spawn flameshot gui
hc keybind $Mod-d spawn rofi -show drun -show-icons
hc keybind $Mod-r spawn rofi -show run
hc keybind $Mod-F1 spawn sh -c 'CM_LAUNCHER=rofi clipmenu'
hc keybind $Mod-F2 spawn rofi -show calc -modi calc -no-show-match -no-sort
hc keybind $Mod-F3 spawn sh -c 'clipctl disable; bwmenu; clipctl enable'
hc keybind XF86AudioPlay spawn playerctl play-pause
hc keybind XF86AudioPause spawn playerctl pause-pause
hc keybind XF86AudioRaiseVolume spawn sh -c "pamixer -i 5; pamixer --get-volume >> \"$xobpipe\"; $refresh_panel"
hc keybind XF86AudioLowerVolume spawn sh -c "pamixer -d 5; pamixer --get-volume >> \"$xobpipe\"; $refresh_panel"
hc keybind XF86AudioMute spawn sh -c "pamixer -t; pamixer --get-volume-human | sed 's/muted/0/' >> \"$xobpipe\"; $refresh_panel"
hc keybind $Mod-a spawn sh -c "audio-output-swap; $refresh_panel"
hc keybind XF86Launch7 spawn sh -c "sleep 0.15 && xdotool keydown ctrl key w keyup ctrl"
# basic movement in tiling and floating mode
# focusing clients
hc keybind $Mod-Left focus left
hc keybind $Mod-Down focus down
hc keybind $Mod-Up focus up
hc keybind $Mod-Right focus right
# moving clients in tiling and floating mode
hc keybind $Mod-Shift-Left shift left
hc keybind $Mod-Shift-Down shift down
hc keybind $Mod-Shift-Up shift up
hc keybind $Mod-Shift-Right shift right
hc keybind $Mod-j spawn stickyctl stick
hc keybind $Mod-Shift-j spawn stickyctl unstick
# tags
tag_names=( {1..9} 0 )
tag_keys=( {1..9} 0 )
hc rename default "${tag_names[0]}" || true
for i in "${!tag_names[@]}" ; do
hc add "${tag_names[$i]}"
key="${tag_keys[$i]}"
if ! [ -z "$key" ] ; then
hc keybind "$Mod-$key" chain , lock , use_index "$i" , spawn stickyctl get-sticky , unlock
hc keybind "$Mod-Shift-$key" move_index "$i"
fi
done
# cycle through tags
hc keybind $Mod-Control-Right use_index +1 --skip-visible
hc keybind $Mod-Control-Left use_index -1 --skip-visible
# layouting
hc keybind $Mod-f fullscreen toggle
hc keybind $Mod-Shift-f set_attr clients.focus.floating toggle
# The following cycles through the available layouts within a frame, but skips
# layouts, if the layout change wouldn't affect the actual window positions.
# I.e. if there are two windows within a frame, the grid layout is skipped.
hc keybind $Mod-space or , and . compare tags.focus.curframe_wcount = 2 . cycle_layout +1 vertical horizontal max vertical grid , cycle_layout +1
# mouse
hc mouseunbind --all
hc set focus_follows_mouse true
hc set focus_follows_monitor_boundaries true
hc mousebind $Mod-Button1 move
hc mousebind $Mod-Button3 resize
# focus
hc keybind $Mod-BackSpace cycle_monitor
hc keybind $Mod-Tab cycle_all +1
hc keybind $Mod-Shift-Tab cycle_all -1
hc keybind $Mod-Alt-Tab jumpto urgent
# theme
hc attr theme.tiling.reset 1
hc attr theme.floating.reset 1
hc set always_show_frame on
hc set frame_bg_transparent off
hc attr theme.active.color '#95e454'
hc attr theme.normal.color '#88b8f6'
hc attr theme.urgent.color '#e5796d'
hc attr theme.inner_color black
hc attr theme.border_width 1
hc attr theme.floating.border_width 2
hc attr theme.floating.outer_width 1
hc attr theme.floating.outer_color black
hc attr theme.background_color '#080808'
hc set window_gap 0
hc set frame_padding 0
hc set smart_window_surroundings on
hc set smart_frame_surroundings on
hc set mouse_recenter_gap 0
hc set frame_active_opacity 1
hc set frame_normal_opacity 1
hc set frame_bg_active_color '#0000000000'
hc set snap_distance 0
hc set snap_gap 0
# rules
hc unrule -F
#hc rule class=XTerm tag=3 # move all xterms to tag 3
hc rule focus=on # normally focus new clients
hc rule floatplacement=smart
#hc rule focus=off # normally do not focus new clients
# give focus to most common terminals
#hc rule class~'(.*[Rr]xvt.*|.*[Tt]erm|Konsole)' focus=on
hc rule windowtype~'_NET_WM_WINDOW_TYPE_(DIALOG|UTILITY|SPLASH)' floating=on
hc rule windowtype='_NET_WM_WINDOW_TYPE_DIALOG' focus=on
hc rule windowtype~'_NET_WM_WINDOW_TYPE_(NOTIFICATION|DOCK|DESKTOP)' manage=off
hc rule class='mpv' floating=on
hc set tree_style '╾│ ├└╼─┐'
# unlock, just to be sure
hc unlock
# do multi monitor setup here, e.g.:
# hc set_monitors 1280x1024+0+0 1280x1024+1280+0
# or simply:
hc detect_monitors
# restart panel
~/.config/herbstluftwm/killpanel.sh
{ exec ~/.config/herbstluftwm/panel.sh; } &
# restart xob
pgrep xob | xargs -n1 kill -9
if [ ! -p "$xobpipe" ]; then
mkfifo "$xobpipe"
fi
{ tail -f "$xobpipe" | xob; } &

7
herbstluftwm/killpanel.sh Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
pgrep -f 'panel_text' | xargs -n1 kill -9
pgrep -f 'lemonbar' | xargs -n1 kill -9
pgrep -f 'xobpipe' | xargs -n1 kill -9
pgrep -f 'trayer' | xargs -n1 kill -9
pgrep -f 'bash.*panel\.sh' | xargs -n1 kill -9

419
herbstluftwm/panel.sh Executable file
View File

@ -0,0 +1,419 @@
#!/usr/bin/env bash
hostname=$(hostname)
hc() { herbstclient "$@" ;}
panel_height=20
for monitor in $(hc list_monitors | cut -d: -f1); do
hc pad "$monitor" "$panel_height" 0 0 0
done
{ sleep 1; exec trayer --SetPartialStrut false --edge top --height 20 --widthtype request --align right --tint 0x080808 --transparent true --alpha 0; } &
fggreen='%{F#95e454}'
fgblue='%{F#88b8f6}'
fgred='%{F#e5796d}'
fgdark='%{F#080808}'
fgend='%{F-}'
bggreen='%{B#95e454}'
bgblue='%{B#88b8f6}'
bgred='%{B#e5796d}'
bglight='%{B#333333}'
bgend='%{B-}'
ulblue='%{U#88b8f6+u}'
ulend='%{-u}'
handle_signal() {
FORCE_REFRESH=1
}
handle_kill() {
kill 0
rm "$fifo"
exit 0
}
trap handle_signal SIGUSR1
trap handle_kill SIGINT
fifo="/tmp/panel_text"
if [ ! -p "$fifo" ]; then
mkfifo "$fifo"
fi
msgfifo="/tmp/panel_msg"
if [ ! -p "$msgfifo" ]; then
mkfifo "$msgfifo"
fi
# process to handle lemonbar clicks
{
while IFS= read -r line; do
IFS="-" read -r -a command <<< "$line"
if [ "${command[0]}" = "tag" ]; then
# not sure how to specify a monitor, but probably don't need to anyway
monitor="${command[1]}"
index=$(( "${command[2]}" - 1 ))
if [ "$index" -eq -1 ]; then
index=9
fi
herbstclient chain , lock , focus_monitor "$monitor" , use_index "$index" , spawn stickyctl get-sticky , unlock
fi
done < "$msgfifo"
} &
tail -f "$fifo" | stdbuf -oL lemonbar -d -p -a 100 -g "x${panel_height}" -f "Drafting* Mono:pixelsize=18:antialias=true" -f "Unifont:pixelsize=18:antialias=true" -B "#080808" -F "#e3e0d7" > "$msgfifo" &
append_segment() {
local seconds=$1
local name=$2
local param=$3
shift
local now=$SECONDS
local escparam
segment_text=''
escparam="${param//\//_}"
eval "local lastrun=\$${name}${escparam}_lastrun"
if [ -z "$lastrun" ]; then
lastrun=0
fi
if [ -n "$FORCE_REFRESH" ] || [ "$lastrun" -eq 0 ] || (( SECONDS - lastrun >= seconds )); then
"$@"
eval "${name}${escparam}_lastrun=\$now"
eval "${name}${escparam}_lastoutput=\"$segment_text\""
panel_text="$panel_text$segment_text"
else
eval "panel_text=\"\$panel_text\$${name}${escparam}_lastoutput\""
fi
}
append_separator() {
panel_text="$panel_text "
}
append_percent_icon() {
local pct=$1
segment_text="$segment_text$bglight"
if (( pct < 12 )); then
segment_text="$segment_text"
elif (( pct < 25 )); then
segment_text="$segment_text"
elif (( pct < 38 )); then
segment_text="$segment_text"
elif (( pct < 51 )); then
segment_text="$segment_text"
elif (( pct < 64 )); then
segment_text="$segment_text"
elif (( pct < 77 )); then
segment_text="$segment_text"
elif (( pct < 90 )); then
segment_text="$segment_text"
else
segment_text="$segment_text"
fi
segment_text="$segment_text$bgend%{O5}"
}
segment_tags() {
local monitor=$1
local tags
local prefix
local tagclass
IFS=$'\t' read -ra tags <<< "$(hc tag_status "$monitor")"
segment_text=''
for i in "${tags[@]}"; do
prefix=${i:0:1}
case $prefix in
'.') tagclass=$fgend$bgend ;;
'+') tagclass=$bgblue$fgdark ;;
'#') tagclass=$bggreen$fgdark ;;
'!') tagclass=$bgred$fgdark ;;
'-') tagclass=$ulblue$bglight$fgblue ;;
'%') tagclass=$ulblue$bglight$fgblue ;;
*) tagclass=$bglight ;;
esac
segment_text="$segment_text%{A:tag-$monitor-${i:1}:}$tagclass%{O8}${i:1}%{O8}%{A}$fgend$bgend$ulend"
done
}
segment_timew() {
local curday
local active
local twclass
local twicon
if hash timew 2>/dev/null; then
active=$(timew get dom.active)
if [ "$active" = "1" ]; then
twicon=""
twclass=$fggreen
else
twicon=""
twclass=$fgred
fi
curday=$(timew summary | tail -n2 | head -n1 | awk '{ print $1 }')
if [ "$curday" = "No" ]; then
curday='0:00'
else
curday="${curday%:*}"
fi
segment_text="${twclass}${twicon}${fgend}%{O5}$curday"
fi
}
segment_keyboard() {
local kblayout
local kbclass
local kbicon
kblayout=$(setxkbmap -query | grep variant | awk '{ print $2 }' | tr -d ',')
if [ "$kblayout" = "dvorak" ]; then
kbclass=$fgred
kbicon=""
else
kbclass=$fggreen
kbicon=""
fi
segment_text="$kbclass$kbicon$fgend"
}
segment_network() {
local net
local neticon
local btpower
local btconn
local bticon
local nasavpn
local nasaicon
# network device
net=$(ip route get 1.1.1.1 | grep -Po '(?<=dev\s)\w+' | cut -f1 -d ' ')
if ! [ "$net" ]; then
neticon="%{O3}$fgred$fgend"
else
neticon="%{O3}$fggreenﯱ$fgend"
fi
if hash bluetoothctl 2>/dev/null; then
# bluetooth status
btpower=$(bluetoothctl show | grep Powered | awk '{ print $2 }')
if [ "$btpower" = "yes" ]; then
btconn=$(bluetoothctl devices | cut -f2 -d' ' | while read uuid; do bluetoothctl info $uuid; done | grep "Connected: yes")
if [ -z "$btconn" ]; then
bticon="${fggreen}$fgend"
else
bticon="${fgblue}$fgend"
fi
else
bticon="${fgred}$fgend"
fi
fi
if hash docker 2>/dev/null; then
nasavpn=$(docker ps --format "{{.Names}}" | grep nasavpn)
if [ -n "$nasavpn" ]; then
nasaicon="%{O3}${fggreen}$fgend"
else
nasaicon="%{O3}${fgred}$fgend"
fi
fi
segment_text="$bticon$nasaicon$neticon"
}
segment_memory() {
local mempct
local memclass
mempct=$(free | grep Mem | awk '{ print int($3/$2 * 100.0 + 0.5) }')
if [ "$mempct" -gt 75 ]; then
memclass=$fgred
elif [ "$mempct" -gt 50 ]; then
memclass=$fgblue
else
memclass=$fggreen
fi
segment_text=$memclass
append_percent_icon "$mempct"
segment_text="${segment_text}$fgend"
}
segment_disk() {
local dpath=$1
local diskpct
local diskclass
local diskicon
if [ "$dpath" = "/" ]; then
diskicon=""
else
diskicon=""
fi
diskpct=$(df --output=pcent "$dpath" | sed 1d | sed 's/^[ \t]*//' | sed 's/%.*//')
if [ "$diskpct" -gt 90 ]; then
diskclass=$fgred
elif [ "$diskpct" -gt 75 ]; then
diskclass=$fgblue
else
diskclass=$fggreen
fi
segment_text=$diskclass
append_percent_icon "$diskpct"
segment_text="${segment_text}$diskicon$fgend"
}
segment_cpu() {
local cpupct
local cpuclass
cpupct=$(awk '{u=$2+$4; t=$2+$4+$5; if (NR==1){u1=u; t1=t;} else print ($2+$4-u1) * 100 / (t-t1); }' <(grep 'cpu ' /proc/stat) <(sleep 1;grep 'cpu ' /proc/stat) | awk '{print int($1+0.5)}')
if [ "$cpupct" -gt 90 ]; then
cpuclass=$fgred
elif [ "$cpupct" -gt 25 ]; then
cpuclass=$fgblue
else
cpuclass=$fggreen
fi
segment_text=$cpuclass
append_percent_icon "$cpupct"
segment_text="${segment_text}$fgend"
}
segment_audio() {
local audiohdmi
local audiobt
local audicon
local volpct
if hash pactl 2>/dev/null; then
# audio output device (hdmi/analog)
audiohdmi=$(pactl get-default-sink | grep hdmi)
audiobt=$(pactl get-default-sink | grep bluez)
fi
if [ -n "$audiobt" ]; then
audclass=$fgblue
audicon='﫽'
else
audclass=$fggreen
if [ "$hostname" != "ellison" ]; then
if [ -z "$audiohdmi" ]; then
audicon=''
else
audicon='蓼'
fi
else
audicon='蓼'
fi
fi
if hash pamixer 2>/dev/null; then
volpct=$(pamixer --get-volume-human | sed 's/%//')
if [ "$volpct" = "muted" ]; then
audclass=$fgred
volpct="0"
fi
fi
segment_text=$audclass
append_percent_icon "$volpct"
segment_text="$segment_text$audicon$fgend"
}
segment_battery() {
local battpct
local batstat
local baticon
local batclass
if hash upower 2>/dev/null; then
# battery charge percent
battpct="$(upower --show-info $(upower --enumerate | grep -i 'BAT') | grep -E "percentage" | awk '{print $2}')"
battpct="${battpct%\%}"
# battery status (charging/charged/etc)
batstat="$(upower --show-info $(upower --enumerate | grep -i 'BAT') | grep -E "state" | awk '{print $2}')"
baticon='B'
if (( battpct > 80 )); then
batclass=$fggreen
elif (( battpct < 20 )); then
batclass=$fgred
else
batclass=$fgblue
fi
if [ "$batstat" = "fully-charged" ]; then
baticon="${baticon}%{O3}⇈"
elif [ "$batstat" = "discharging" ]; then
baticon="${baticon}%{O3}↓";
else
baticon="${baticon}%{O3}↑";
fi
segment_text="$batclass"
append_percent_icon "$battpct"
segment_text="$segment_text$baticon$fgend"
else
segment_text="$fggreenﮣ$fgend"
fi
}
segment_date() {
segment_text="$(date +$'%a %b %d') $fgblue$(date +$'%H:%M')$fgend"
}
last_text=''
while true; do
{
full_text=''
for monitor in $(herbstclient list_monitors | cut -d: -f1); do
panel_text="%{S$monitor}%{l}"
append_segment 0 segment_tags "$monitor"
panel_text="$panel_text%{l}%{r}"
append_segment 60 segment_timew
append_separator
append_segment 60 segment_keyboard
append_separator
append_segment 10 segment_network
append_separator
panel_text="$panel_text%{A:conky:}"
append_segment 10 segment_memory
append_separator
append_segment 60 segment_disk "/"
append_separator
if [ "$hostname" != "ellison" ]; then
append_segment 60 segment_disk "/home"
append_separator
fi
append_segment 5 segment_cpu
append_separator
append_segment 60 segment_audio
append_separator
append_segment 30 segment_battery
panel_text="$panel_text%{A}"
append_separator
append_segment 60 segment_date
if [ "$monitor" -eq 0 ]; then
tray_width=$(xdotool search --classname panel | xargs -n1 xprop -id | grep 'program specified minimum size' | cut -d ' ' -f 5)
tray_width=$(( tray_width + 5 ))
panel_text="$panel_text%{O$tray_width}"
fi
panel_text="$panel_text%{r}"
full_text="$full_text$panel_text"
done
if [ "$full_text" != "$last_text" ]; then
echo -e "$full_text"
last_text="$full_text"
fi
} >> "$fifo"
unset FORCE_REFRESH
sleep 1
done

BIN
herbstluftwm/wallpaper.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

5
shell/bash_profile Normal file
View File

@ -0,0 +1,5 @@
#
# ~/.bash_profile
#
[[ -f ~/.bashrc ]] && . ~/.bashrc

View File

@ -5,12 +5,7 @@
# If not running interactively, don't do anything # If not running interactively, don't do anything
[[ $- != *i* ]] && return [[ $- != *i* ]] && return
# If x is available and we're not in it, start it
if [ -z "$DISPLAY" ] && [ -x "$(command -v startx)" ]; then
startx
else
# source shared config # source shared config
for shared in ~/skynet/shell/bashrc.d/*.sh; do for shared in ~/skynet/shell/bashrc.d/*.sh; do
source "$shared" source "$shared"
done done
fi

479
shell/bashrc.d/50-goto.sh Normal file
View File

@ -0,0 +1,479 @@
# shellcheck shell=bash
# shellcheck disable=SC2039
# SOURCE: https://github.com/iridakos/goto
# MIT License
#
# Copyright (c) 2018 Lazarus Lazaridis
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Changes to the given alias directory
# or executes a command based on the arguments.
goto()
{
local target
_goto_resolve_db
if [ -z "$1" ]; then
# display usage and exit when no args
_goto_usage
return
fi
subcommand="$1"
shift
case "$subcommand" in
-c|--cleanup)
_goto_cleanup "$@"
;;
-r|--register) # Register an alias
_goto_register_alias "$@"
;;
-u|--unregister) # Unregister an alias
_goto_unregister_alias "$@"
;;
-p|--push) # Push the current directory onto the pushd stack, then goto
_goto_directory_push "$@"
;;
-o|--pop) # Pop the top directory off of the pushd stack, then change that directory
_goto_directory_pop
;;
-l|--list)
_goto_list_aliases
;;
-x|--expand) # Expand an alias
_goto_expand_alias "$@"
;;
-h|--help)
_goto_usage
;;
-v|--version)
_goto_version
;;
*)
_goto_directory "$subcommand"
;;
esac
return $?
}
_goto_resolve_db()
{
local CONFIG_DEFAULT="${XDG_CONFIG_HOME:-$HOME/.config}/goto"
GOTO_DB="${GOTO_DB:-$CONFIG_DEFAULT}"
GOTO_DB_CONFIG_DIRNAME=$(dirname "$GOTO_DB")
if [[ ! -d "$GOTO_DB_CONFIG_DIRNAME" ]]; then
mkdir "$GOTO_DB_CONFIG_DIRNAME"
fi
touch -a "$GOTO_DB"
}
_goto_usage()
{
cat <<\USAGE
usage: goto [<option>] <alias> [<directory>]
default usage:
goto <alias> - changes to the directory registered for the given alias
OPTIONS:
-r, --register: registers an alias
goto -r|--register <alias> <directory>
-u, --unregister: unregisters an alias
goto -u|--unregister <alias>
-p, --push: pushes the current directory onto the stack, then performs goto
goto -p|--push <alias>
-o, --pop: pops the top directory from the stack, then changes to that directory
goto -o|--pop
-l, --list: lists aliases
goto -l|--list
-x, --expand: expands an alias
goto -x|--expand <alias>
-c, --cleanup: cleans up non existent directory aliases
goto -c|--cleanup
-h, --help: prints this help
goto -h|--help
-v, --version: displays the version of the goto script
goto -v|--version
USAGE
}
# Displays version
_goto_version()
{
echo "goto version 2.1.0"
}
# Expands directory.
# Helpful for ~, ., .. paths
_goto_expand_directory()
{
builtin cd "$1" 2>/dev/null && pwd
}
# Lists registered aliases.
_goto_list_aliases()
{
local IFS=$' '
if [ -f "$GOTO_DB" ]; then
local maxlength=0
while read -r name directory; do
local length=${#name}
if [[ $length -gt $maxlength ]]; then
local maxlength=$length
fi
done < "$GOTO_DB"
while read -r name directory; do
printf "\e[1;36m%${maxlength}s \e[0m%s\n" "$name" "$directory"
done < "$GOTO_DB"
else
echo "You haven't configured any directory aliases yet."
fi
}
# Expands a registered alias.
_goto_expand_alias()
{
if [ "$#" -ne "1" ]; then
_goto_error "usage: goto -x|--expand <alias>"
return
fi
local resolved
resolved=$(_goto_find_alias_directory "$1")
if [ -z "$resolved" ]; then
_goto_error "alias '$1' does not exist"
return
fi
echo "$resolved"
}
# Lists duplicate directory aliases
_goto_find_duplicate()
{
local duplicates=
duplicates=$(sed -n 's:[^ ]* '"$1"'$:&:p' "$GOTO_DB" 2>/dev/null)
echo "$duplicates"
}
# Registers and alias.
_goto_register_alias()
{
if [ "$#" -ne "2" ]; then
_goto_error "usage: goto -r|--register <alias> <directory>"
return 1
fi
if ! [[ $1 =~ ^[[:alnum:]]+[a-zA-Z0-9_-]*$ ]]; then
_goto_error "invalid alias - can start with letters or digits followed by letters, digits, hyphens or underscores"
return 1
fi
local resolved
resolved=$(_goto_find_alias_directory "$1")
if [ -n "$resolved" ]; then
_goto_error "alias '$1' exists"
return 1
fi
local directory
directory=$(_goto_expand_directory "$2")
if [ -z "$directory" ]; then
_goto_error "failed to register '$1' to '$2' - can't cd to directory"
return 1
fi
local duplicate
duplicate=$(_goto_find_duplicate "$directory")
if [ -n "$duplicate" ]; then
_goto_warning "duplicate alias(es) found: \\n$duplicate"
fi
# Append entry to file.
echo "$1 $directory" >> "$GOTO_DB"
echo "Alias '$1' registered successfully."
}
# Unregisters the given alias.
_goto_unregister_alias()
{
if [ "$#" -ne "1" ]; then
_goto_error "usage: goto -u|--unregister <alias>"
return 1
fi
local resolved
resolved=$(_goto_find_alias_directory "$1")
if [ -z "$resolved" ]; then
_goto_error "alias '$1' does not exist"
return 1
fi
# shellcheck disable=SC2034
local readonly GOTO_DB_TMP="$HOME/.goto_"
# Delete entry from file.
sed "/^$1 /d" "$GOTO_DB" > "$GOTO_DB_TMP" && mv "$GOTO_DB_TMP" "$GOTO_DB"
echo "Alias '$1' unregistered successfully."
}
# Pushes the current directory onto the stack, then goto
_goto_directory_push()
{
if [ "$#" -ne "1" ]; then
_goto_error "usage: goto -p|--push <alias>"
return
fi
{ pushd . || return; } 1>/dev/null 2>&1
_goto_directory "$@"
}
# Pops the top directory from the stack, then goto
_goto_directory_pop()
{
{ popd || return; } 1>/dev/null 2>&1
}
# Unregisters aliases whose directories no longer exist.
_goto_cleanup()
{
if ! [ -f "$GOTO_DB" ]; then
return
fi
while IFS= read -r i && [ -n "$i" ]; do
echo "Cleaning up: $i"
_goto_unregister_alias "$i"
done <<< "$(awk '{al=$1; $1=""; dir=substr($0,2);
system("[ ! -d \"" dir "\" ] && echo " al)}' "$GOTO_DB")"
}
# Changes to the given alias' directory
_goto_directory()
{
# directly goto the special name that is unable to be registered due to invalid alias, eg: ~
if ! [[ $1 =~ ^[[:alnum:]]+[a-zA-Z0-9_-]*$ ]]; then
{ builtin cd "$1" 2> /dev/null && return 0; } || \
{ _goto_error "Failed to goto '$1'" && return 1; }
fi
local target
target=$(_goto_resolve_alias "$1") || return 1
builtin cd "$target" 2> /dev/null || \
{ _goto_error "Failed to goto '$target'" && return 1; }
}
# Fetches the alias directory.
_goto_find_alias_directory()
{
local resolved
resolved=$(sed -n "s/^$1 \\(.*\\)/\\1/p" "$GOTO_DB" 2>/dev/null)
echo "$resolved"
}
# Displays the given error.
# Used for common error output.
_goto_error()
{
(>&2 echo -e "goto error: $1")
}
# Displays the given warning.
# Used for common warning output.
_goto_warning()
{
(>&2 echo -e "goto warning: $1")
}
# Displays entries with aliases starting as the given one.
_goto_print_similar()
{
local similar
similar=$(sed -n "/^$1[^ ]* .*/p" "$GOTO_DB" 2>/dev/null)
if [ -n "$similar" ]; then
(>&2 echo "Did you mean:")
(>&2 column -t <<< "$similar")
fi
}
# Fetches alias directory, errors if it doesn't exist.
_goto_resolve_alias()
{
local resolved
resolved=$(_goto_find_alias_directory "$1")
if [ -z "$resolved" ]; then
_goto_error "unregistered alias $1"
_goto_print_similar "$1"
return 1
else
echo "${resolved}"
fi
}
# Completes the goto function with the available commands
_complete_goto_commands()
{
local IFS=$' \t\n'
# shellcheck disable=SC2207
COMPREPLY=($(compgen -W "-r --register -u --unregister -p --push -o --pop -l --list -x --expand -c --cleanup -v --version" -- "$1"))
}
# Completes the goto function with the available aliases
_complete_goto_aliases()
{
local IFS=$'\n' matches
_goto_resolve_db
# shellcheck disable=SC2207
matches=($(sed -n "/^$1/p" "$GOTO_DB" 2>/dev/null))
if [ "${#matches[@]}" -eq "1" ]; then
# remove the filenames attribute from the completion method
compopt +o filenames 2>/dev/null
# if you find only one alias don't append the directory
COMPREPLY=("${matches[0]// *}")
else
for i in "${!matches[@]}"; do
# remove the filenames attribute from the completion method
compopt +o filenames 2>/dev/null
if ! [[ $(uname -s) =~ Darwin* ]]; then
matches[$i]=$(printf '%*s' "-$COLUMNS" "${matches[$i]}")
COMPREPLY+=("$(compgen -W "${matches[$i]}")")
else
COMPREPLY+=("${matches[$i]// */}")
fi
done
fi
}
# Bash programmable completion for the goto function
_complete_goto_bash()
{
local cur="${COMP_WORDS[$COMP_CWORD]}" prev
if [ "$COMP_CWORD" -eq "1" ]; then
# if we are on the first argument
if [[ $cur == -* ]]; then
# and starts like a command, prompt commands
_complete_goto_commands "$cur"
else
# and doesn't start as a command, prompt aliases
_complete_goto_aliases "$cur"
fi
elif [ "$COMP_CWORD" -eq "2" ]; then
# if we are on the second argument
prev="${COMP_WORDS[1]}"
if [[ $prev = "-u" ]] || [[ $prev = "--unregister" ]]; then
# prompt with aliases if user tries to unregister one
_complete_goto_aliases "$cur"
elif [[ $prev = "-x" ]] || [[ $prev = "--expand" ]]; then
# prompt with aliases if user tries to expand one
_complete_goto_aliases "$cur"
elif [[ $prev = "-p" ]] || [[ $prev = "--push" ]]; then
# prompt with aliases only if user tries to push
_complete_goto_aliases "$cur"
fi
elif [ "$COMP_CWORD" -eq "3" ]; then
# if we are on the third argument
prev="${COMP_WORDS[1]}"
if [[ $prev = "-r" ]] || [[ $prev = "--register" ]]; then
# prompt with directories only if user tries to register an alias
local IFS=$' \t\n'
# shellcheck disable=SC2207
COMPREPLY=($(compgen -d -- "$cur"))
fi
fi
}
# Zsh programmable completion for the goto function
_complete_goto_zsh()
{
local all_aliases=()
_goto_resolve_db
while IFS= read -r line; do
all_aliases+=("$line")
done <<< "$(sed -e 's/ /:/g' $GOTO_DB 2>/dev/null)"
local state
local -a options=(
'(1)'{-r,--register}'[registers an alias]:register:->register'
'(- 1 2)'{-u,--unregister}'[unregisters an alias]:unregister:->unregister'
'(: -)'{-l,--list}'[lists aliases]'
'(*)'{-c,--cleanup}'[cleans up non existent directory aliases]'
'(1 2)'{-x,--expand}'[expands an alias]:expand:->aliases'
'(1 2)'{-p,--push}'[pushes the current directory onto the stack, then performs goto]:push:->aliases'
'(*)'{-o,--pop}'[pops the top directory from stack, then changes to that directory]'
'(: -)'{-h,--help}'[prints this help]'
'(* -)'{-v,--version}'[displays the version of the goto script]'
)
_arguments -C \
"${options[@]}" \
'1:alias:->aliases' \
'2:dir:_files' \
&& ret=0
case ${state} in
(aliases)
_describe -t aliases 'goto aliases:' all_aliases && ret=0
;;
(unregister)
_describe -t aliases 'unregister alias:' all_aliases && ret=0
;;
esac
return $ret
}
goto_aliases=($(alias | sed -n "s/.*\s\(.*\)='goto'/\1/p"))
goto_aliases+=("goto")
for i in "${goto_aliases[@]}"
do
# Register the goto completions.
if [ -n "${BASH_VERSION}" ]; then
if ! [[ $(uname -s) =~ Darwin* ]]; then
complete -o filenames -F _complete_goto_bash $i
else
complete -F _complete_goto_bash $i
fi
elif [ -n "${ZSH_VERSION}" ]; then
compdef _complete_goto_zsh $i
else
echo "Unsupported shell."
exit 1
fi
done

View File

@ -1,10 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
if [ -z "$DISPLAY" ] && [ -x "$(command -v startx)" ]; then
# start x if it's available and we're not already in it
startx
else
if command -v tmux &> /dev/null && [ -n "$PS1" ] && [[ ! "$TERM" =~ screen ]] && [[ ! "$TERM" =~ linux ]] && [ -z "$TMUX" ]; then if command -v tmux &> /dev/null && [ -n "$PS1" ] && [[ ! "$TERM" =~ screen ]] && [[ ! "$TERM" =~ linux ]] && [ -z "$TMUX" ]; then
# otherwise start tmux if it's available and we're not already in it
exec tmux exec tmux
fi else
# otherwise robot quote
# robot quote
if [ -x "$(command -v botsay)" ]; then if [ -x "$(command -v botsay)" ]; then
len=1642 #$(jq '. | length' ~/skynet/quotes.json) len=1642 #$(jq '. | length' ~/skynet/quotes.json)
idx=$(( RANDOM % len)) idx=$(( RANDOM % len))
@ -18,3 +22,5 @@ if [ -x "$(command -v botsay)" ]; then
fi fi
echo "$quoteText" | botsay -c - echo "$quoteText" | botsay -c -
fi fi
fi
fi

42
xorg/Xresources Normal file
View File

@ -0,0 +1,42 @@
Xcursor.theme: Arc
*.foreground: #dedacf
*.background: #080808
*.cursorColor: #bbbbbb
!
! Black
*.color0: #080808
*.color8: #313131
!
! Red
*.color1: #ff615a
*.color9: #f58c80
!
! Green
*.color2: #b1e969
*.color10: #ddf88f
!
! Yellow
*.color3: #ebd99c
*.color11: #eee5b2
!
! Blue
*.color4: #5da9f6
*.color12: #a5c7ff
!
! Magenta
*.color5: #e86aff
*.color13: #ddaaff
!
! Cyan
*.color6: #82fff7
*.color14: #b7fff9
!
! White
*.color7: #dedacf
*.color15: #ffffff
!
! Bold, Italic, Underline
*.colorBD: #ffffff
!*.colorIT:
!*.colorUL:

1
xorg/gtk-3.0/bookmarks Normal file
View File

@ -0,0 +1 @@
file:///home/rudism/mri/_notes

View File

@ -0,0 +1,4 @@
[Settings]
gtk-icon-theme-name = Arc-Dark
gtk-theme-name = Arc-Dark
gtk-application-prefer-dark-theme = true

3
xorg/gtkrc-2.0 Normal file
View File

@ -0,0 +1,3 @@
gtk-theme-name="Arc-Dark"
gtk-icon-theme="Arc-Dark"
gtk-application-prefer-dark-theme="true"

20
xorg/xinitrc Normal file
View File

@ -0,0 +1,20 @@
#!/bin/sh
#. "$HOME/.profile"
userresources=$HOME/.Xresources
sysresources=/etc/X11/xinit/.Xresources
sysmodmap=/etc/X11/xinit/.Xmodmap
if [ -f $sysresources ]; then
xrdb -merge $sysresources
fi
if [ -f "$userresources" ]; then
xrdb -merge "$userresources"
fi
clipmenud &
pipewire &
pipewire-pulse &
exec dbus-run-session herbstluftwm