refactor(dotfiles): separate desktop configuration
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
hyprctl activeworkspace -j | jq -r '@text "Workspace \(.id)"'
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
if [[ ! -x /usr/bin/awww ]]; then
|
||||
echo "required awww please install with yay -S awww" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# setting paths
|
||||
offset=0
|
||||
[[ "$1" =~ [1-9][0-9]*$ ]] && offset=$1
|
||||
|
||||
BACKGROUNDS_DIR="$HOME/Sync/Shared/wallpapers"
|
||||
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
|
||||
|
||||
url_preffix="http://www.bing.com"
|
||||
xml_url="https://cn.bing.com/HPImageArchive.aspx?format=xml&idx=$offset&n=10&nc=1612409408851&pid=hp&FORM=BEHPTB&uhd=1&uhdwidth=3840&uhdheight=2160"
|
||||
[ -d $BACKGROUNDS_DIR ] || mkdir -p $BACKGROUNDS_DIR
|
||||
|
||||
# actual script
|
||||
url_suffix=$(curl --no-progress-meter $xml_url | xmllint --xpath "string(//url)" -) && \
|
||||
url="$url_preffix$url_suffix"
|
||||
|
||||
if [[ ! -z "$url_suffix" ]]; then
|
||||
name=$(echo $url_suffix | awk -F'&' '{print $1}' | awk -F'=' '{print $2}')
|
||||
if [ ! -z "$name" ]; then
|
||||
file_path="$BACKGROUNDS_DIR/$name"
|
||||
echo "Wallpaper name: $name"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$file_path" || -z "$url" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$file_path" ]]; then
|
||||
if curl "$url" -o "$file_path" 2>/dev/null; then
|
||||
echo "Downloaded"
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
ln -nsf $file_path $CURRENT_BACKGROUND_LINK && \
|
||||
setsid uwsm app -- awww img $CURRENT_BACKGROUND_LINK && \
|
||||
exit 0
|
||||
|
||||
# return exitcode if above crashed
|
||||
exit 1
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
hyprctl activeworkspace -j | jq -r '@text "Workspace \(.id)"'
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
chooser="rofi -i -dmenu -display-columns 1"
|
||||
selected=$(hyprctl clients -j | jq -r 'to_entries | .[] | select(.value.hidden == false) | "\(.value.title)\t\(.value.class)::\(.value.address)"' | $chooser -p 'Client to Fetch')
|
||||
address=$(echo "$selected" | awk -F '::' '{print $NF}')
|
||||
if [ -z "$address" ]; then
|
||||
notify-send "No client selected"
|
||||
exit 1
|
||||
fi
|
||||
hyprctl dispatch "fetch_or_launch({ match = '$address', field = 'address', cmd = 'notify-send \"$selected not found\"'})"
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
#chooser="walker -d"
|
||||
chooser="rofi -i -dmenu -display-columns 1"
|
||||
selected=$(hyprctl clients -j | jq -r 'to_entries | .[] | select(.value.hidden == false) | "\(.value.title) \t\(.value.class)::\(.value.address)"' | $chooser -p 'Client to Focus')
|
||||
address=$(echo $selected | awk -F'::' '{print $NF}')
|
||||
if [ -z "$address" ]; then
|
||||
notify-send "No client selected"
|
||||
exit 1
|
||||
fi
|
||||
hyprctl dispatch "focus_or_launch({ match = '$address', field = 'address', cmd = 'notify-send \"$selected not found\"'})"
|
||||
@@ -1,91 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# A script to display Hyprland keybindings defined in your configuration
|
||||
#
|
||||
# original script from omarchy
|
||||
|
||||
# Fetch dynamic keybindings from Hyprland
|
||||
#
|
||||
# Also do some pre-processing:
|
||||
# - Remove standard Omarchy bin path prefix
|
||||
# - Remove uwsm prefix
|
||||
# - Map numeric modifier key mask to a textual rendition
|
||||
# - Output comma-separated values that the parser can understand
|
||||
dynamic_bindings() {
|
||||
hyprctl -j binds | \
|
||||
jq -r '.[] | {modmask, key, keycode, description, dispatcher, arg, submap} | "\(.modmask),\(.key)@\(.keycode),\(.description),\(.dispatcher),\(.arg),\(.submap)"' | \
|
||||
sed -E \
|
||||
-e 's/null//' \
|
||||
-e 's,uwsm app -- ,,' \
|
||||
-e 's|exec,.*/([^/]*)|exec,\1|' \
|
||||
-e 's/@0//' \
|
||||
-e 's/,@/,code:/' \
|
||||
-e 's/^0,/,/' \
|
||||
-e 's/^1,/SHIFT,/' \
|
||||
-e 's/^4,/CTRL,/' \
|
||||
-e 's/^5,/SHIFT CTRL,/' \
|
||||
-e 's/^8,/ALT,/' \
|
||||
-e 's/^9,/SHIFT ALT,/' \
|
||||
-e 's/^12,/CTRL ALT,/' \
|
||||
-e 's/^13,/SHIFT CTRL ALT,/' \
|
||||
-e 's/^64,/SUPER,/' \
|
||||
-e 's/^65,/SUPER SHIFT,/' \
|
||||
-e 's/^68,/SUPER CTRL,/' \
|
||||
-e 's/^69,/SUPER SHIFT CTRL,/' \
|
||||
-e 's/^72,/SUPER ALT,/' \
|
||||
-e 's/^73,/SUPER SHIFT ALT,/' \
|
||||
-e 's/^77,/HYPR,/'
|
||||
}
|
||||
|
||||
# Parse and format keybindings
|
||||
#
|
||||
# `awk` does the heavy lifting:
|
||||
# - Set the field separator to a comma ','.
|
||||
# - Joins the key combination (e.g., "SUPER + Q").
|
||||
# - Joins the command that the key executes.
|
||||
# - Prints everything in a nicely aligned format.
|
||||
parse_bindings() {
|
||||
awk -F, '
|
||||
{
|
||||
# Combine the modifier and key (first two fields)
|
||||
key_combo = $1 " + " $2;
|
||||
|
||||
# Clean up: strip leading "+" if present, trim spaces
|
||||
gsub(/^[ \t]*\+?[ \t]*/, "", key_combo);
|
||||
gsub(/[ \t]+$/, "", key_combo);
|
||||
|
||||
# Use description, if set
|
||||
action = $3;
|
||||
submenu = $NF;
|
||||
|
||||
if (action == "") {
|
||||
# Reconstruct the command from the remaining fields
|
||||
for (i = 4; i <= NF - 1; i++) {
|
||||
action = action $i (i < NF ? "," : "");
|
||||
}
|
||||
|
||||
# Clean up trailing commas, remove leading "exec, ", and trim
|
||||
sub(/,$/, "", action);
|
||||
gsub(/(^|,)[[:space:]]*exec[[:space:]]*,?/, "", action);
|
||||
gsub(/^[ \t]+|[ \t]+$/, "", action);
|
||||
gsub(/[ \t]+/, " ", key_combo); # Collapse multiple spaces to one
|
||||
|
||||
# Escape XML entities
|
||||
gsub(/&/, "\\&", action);
|
||||
gsub(/</, "\\<", action);
|
||||
gsub(/>/, "\\>", action);
|
||||
gsub(/"/, "\\"", action);
|
||||
gsub(/'"'"'/, "\\'", action);
|
||||
}
|
||||
|
||||
if (action != "") {
|
||||
if (submenu != "") {
|
||||
printf "%-10s | %-22s → %s\n", submenu, key_combo, action;
|
||||
} else {
|
||||
printf "%-35s → %s\n", key_combo, action;
|
||||
}
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
dynamic_bindings | parse_bindings | sort -u
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
#sessions="$(tmux list-sessions -F '#S' 2>/dev/null || true)"
|
||||
sessions="$(tmux list-windows -a -F '#S #W::#S:#I' 2>/dev/null || true)"
|
||||
|
||||
[ -n "${sessions}" ] || exit 0
|
||||
|
||||
walker_pick_session() {
|
||||
if command -v walker >/dev/null 2>&1; then
|
||||
walker -d -p 'tmux sessions:'
|
||||
fi
|
||||
}
|
||||
|
||||
rofi_pick_session() {
|
||||
if command -v rofi >/dev/null 2>&1; then
|
||||
rofi -i -dmenu -display-columns 1 -display-column-separator '::' -p 'tmux sessions:'
|
||||
fi
|
||||
}
|
||||
|
||||
chosen="$(printf '%s\n' "$sessions" | rofi_pick_session | awk -F'::' 'NR==1{print $NF}')"
|
||||
|
||||
[ -n "$chosen" ] || exit 0
|
||||
|
||||
if [ "${TMUX-}" ]; then
|
||||
exec tmux switch-client -t "${chosen}"
|
||||
fi
|
||||
|
||||
session_name="${chosen%%:*}"
|
||||
tmux select-window -t $chosen && hyprctl dispatch "focus_or_launch({match = \"$session_name\", field = \"title\", cmd = \"foot -e tmux attach-session -t $chosen\"})"
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
monitor=$1
|
||||
state=$(hyprctl monitors all -j | jq -r ".[] | select(.name == \"$monitor\") | .disabled")
|
||||
if [ $state == "true" ]; then
|
||||
hyprctl keyword monitor $monitor,preferred
|
||||
else
|
||||
hyprctl keyword monitor $monitor,disable
|
||||
fi
|
||||
@@ -1,993 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# rofi-pass
|
||||
# (c) 2015 Rasmus Steinke <rasi@xssn.at>
|
||||
basecommand="$0"
|
||||
|
||||
# set default settings
|
||||
_rofi () {
|
||||
rofi -no-auto-select -i "$@"
|
||||
}
|
||||
|
||||
_pwgen () {
|
||||
pwgen -y "$@"
|
||||
}
|
||||
|
||||
_image_viewer () {
|
||||
feh -
|
||||
}
|
||||
|
||||
config_dir=${XDG_CONFIG_HOME:-$HOME/.config}
|
||||
cache_dir=${XDG_CACHE_HOME:-$HOME/.cache}
|
||||
|
||||
# We expect to find these fields in pass(1)'s output
|
||||
URL_field='url'
|
||||
USERNAME_field='user'
|
||||
AUTOTYPE_field='autotype'
|
||||
OTPmethod_field='otp_method'
|
||||
|
||||
default_autotype="user :tab pass"
|
||||
delay=2
|
||||
wait=0.2
|
||||
type_delay=12
|
||||
default_do='menu' # menu, copyPass, typeUser, typePass, copyUser, copyUrl, viewEntry, typeMenu, actionMenu, copyMenu, openUrl
|
||||
auto_enter='false'
|
||||
notify='false'
|
||||
help_color=""
|
||||
clip=primary
|
||||
clip_clear=45
|
||||
default_user="${ROFI_PASS_DEFAULT_USER-$(whoami)}"
|
||||
default_user2=john_doe
|
||||
password_length=12
|
||||
fix_layout=false
|
||||
|
||||
# default shortcuts
|
||||
autotype="Alt+1"
|
||||
type_user="Alt+2"
|
||||
type_pass="Alt+3"
|
||||
open_url="Alt+4"
|
||||
copy_name="Alt+u"
|
||||
copy_url="Alt+l"
|
||||
copy_pass="Alt+p"
|
||||
show="Alt+o"
|
||||
copy_menu="Alt+c"
|
||||
action_menu="Alt+a"
|
||||
type_menu="Alt+t"
|
||||
help="Alt+h"
|
||||
switch="Alt+x"
|
||||
insert_pass="Alt+n"
|
||||
qrcode="Alt+q"
|
||||
previous_root="Shift+Left"
|
||||
next_root="Shift+Right"
|
||||
clipboard_backend=${ROFI_PASS_CLIPBOARD_BACKEND:-xclip}
|
||||
backend=${ROFI_PASS_BACKEND:-xdotool}
|
||||
|
||||
case "$clipboard_backend" in
|
||||
"xclip");;
|
||||
"wl-clipboard");;
|
||||
*)
|
||||
>&2 echo "Invalid clipboard backend '$clipboard_backend', falling back to xclip"
|
||||
clipboard_backend=xclip
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$backend" in
|
||||
"xdotool");;
|
||||
"wtype");;
|
||||
*)
|
||||
>&2 echo "Invalid backend '$backend', falling back to xdotool"
|
||||
backend=xdotool
|
||||
;;
|
||||
esac
|
||||
|
||||
# Safe permissions
|
||||
umask 077
|
||||
|
||||
# Backends for clipboard manipulation
|
||||
_clip_in_primary_wl-clipboard() {
|
||||
wl-copy -p
|
||||
}
|
||||
|
||||
_clip_in_clipboard_wl-clipboard() {
|
||||
wl-copy
|
||||
}
|
||||
|
||||
_clip_out_primary_wl-clipboard() {
|
||||
wl-paste -p
|
||||
}
|
||||
|
||||
_clip_out_clipboard_wl-clipboard() {
|
||||
wl-paste
|
||||
}
|
||||
|
||||
_clip_in_primary_xclip() {
|
||||
xclip
|
||||
}
|
||||
|
||||
_clip_in_clipboard_xclip() {
|
||||
xclip -selection clipboard
|
||||
}
|
||||
|
||||
_clip_out_primary_xclip() {
|
||||
xclip -o
|
||||
}
|
||||
|
||||
_clip_out_clipboard_xclip() {
|
||||
xclip --selection clipboard -o
|
||||
}
|
||||
|
||||
# Backends for typing what's in stdin
|
||||
_do_type_xdotool() {
|
||||
xdotool type --delay ${type_delay} --clearmodifiers --file -
|
||||
}
|
||||
|
||||
_do_type_wtype() {
|
||||
wtype -d ${type_delay} -
|
||||
}
|
||||
|
||||
# Backends for pressing the key specified by the first argument ($1)
|
||||
_do_press_key_xdotool() {
|
||||
xdotool key "$1"
|
||||
}
|
||||
|
||||
_do_press_key_wtype() {
|
||||
wtype -P "$1" -p "$1"
|
||||
}
|
||||
|
||||
has_qrencode() {
|
||||
command -v qrencode >/dev/null 2>&1
|
||||
}
|
||||
|
||||
listgpg () {
|
||||
mapfile -d '' pw_list < <(find -L . -name '*.gpg' -print0)
|
||||
pw_list=("${pw_list[@]#./}")
|
||||
printf '%s\n' "${pw_list[@]}" | sort -n
|
||||
}
|
||||
|
||||
# get all password files and output as newline-delimited text
|
||||
list_passwords() {
|
||||
cd "${root}" || exit
|
||||
mapfile -t pw_list < <(listgpg)
|
||||
printf '%s\n' "${pw_list[@]%.gpg}" | sort -n
|
||||
}
|
||||
|
||||
doClip () {
|
||||
case "$clip" in
|
||||
"primary") ${clip_in_primary} ;;
|
||||
"clipboard") ${clip_in_clipboard} ;;
|
||||
"both") ${clip_in_primary}; ${clip_out_primary} | ${clip_in_clipboard};;
|
||||
esac
|
||||
}
|
||||
|
||||
checkIfPass () {
|
||||
printf '%s\n' "${root}: $selected_password" >| "$cache_dir/rofi-pass/last_used"
|
||||
}
|
||||
|
||||
|
||||
autopass () {
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
|
||||
xset r off
|
||||
fi
|
||||
|
||||
rm -f "$cache_dir/rofi-pass/last_used"
|
||||
printf '%s\n' "${root}: $selected_password" > "$cache_dir/rofi-pass/last_used"
|
||||
for word in ${stuff["$AUTOTYPE_field"]}; do
|
||||
case "$word" in
|
||||
":tab") ${do_press_key} Tab;;
|
||||
":space") ${do_press_key} space;;
|
||||
":delay") sleep "${delay}";;
|
||||
":enter") ${do_press_key} Return;;
|
||||
":otp") printf '%s' "$(generateOTP)" | ${do_type};;
|
||||
"pass") printf '%s' "${password}" | ${do_type};;
|
||||
"path") printf '%s' "${selected_password}" | rev | cut -d'/' -f1 | rev | ${do_type};;
|
||||
*) printf '%s' "${stuff[${word}]}" | ${do_type};;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ${auto_enter} == "true" ]]; then
|
||||
${do_press_key} Return
|
||||
fi
|
||||
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
xset r "$x_repeat_enabled"
|
||||
unset x_repeat_enabled
|
||||
fi
|
||||
|
||||
clearUp
|
||||
}
|
||||
|
||||
generateQrCode() {
|
||||
has_qrencode
|
||||
|
||||
if [[ $? -eq "1" ]]; then
|
||||
printf '%s\n' "qrencode not found" | _rofi -dmenu
|
||||
exit_code=$?
|
||||
if [[ $exit_code -eq "1" ]]; then
|
||||
exit
|
||||
else
|
||||
"${basecommand}"
|
||||
fi
|
||||
fi
|
||||
|
||||
checkIfPass
|
||||
pass "$selected_password" | head -n 1 | qrencode -d 300 -v 8 -l H -o - | _image_viewer
|
||||
if [[ $? -eq "1" ]]; then
|
||||
printf '%s\n' "" | _rofi -dmenu -mesg "Image viewer not defined or cannot read from pipe"
|
||||
exit_value=$?
|
||||
if [[ $exit_value -eq "1" ]]; then
|
||||
exit
|
||||
else
|
||||
"${basecommand}"
|
||||
fi
|
||||
fi
|
||||
clearUp
|
||||
}
|
||||
|
||||
openURL () {
|
||||
checkIfPass
|
||||
$BROWSER "$(PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep "${URL_field}: " | gawk '{sub(/:/,"")}{print $2}1' | head -1)"; exit;
|
||||
clearUp
|
||||
}
|
||||
|
||||
typeUser () {
|
||||
checkIfPass
|
||||
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
|
||||
xset r off
|
||||
fi
|
||||
|
||||
printf '%s' "${stuff[${USERNAME_field}]}" | ${do_type}
|
||||
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
xset r "$x_repeat_enabled"
|
||||
unset x_repeat_enabled
|
||||
fi
|
||||
|
||||
clearUp
|
||||
}
|
||||
|
||||
typePass () {
|
||||
checkIfPass
|
||||
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
|
||||
xset r off
|
||||
fi
|
||||
|
||||
printf '%s' "${password}" | ${do_type}
|
||||
|
||||
if [[ $notify == "true" ]]; then
|
||||
if [[ "${stuff[notify]}" == "false" ]]; then
|
||||
:
|
||||
else
|
||||
notify-send "rofi-pass" "finished typing password";
|
||||
fi
|
||||
elif [[ $notify == "false" ]]; then
|
||||
if [[ "${stuff[notify]}" == "true" ]]; then
|
||||
notify-send "rofi-pass" "finished typing password";
|
||||
else
|
||||
:
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
xset r "$x_repeat_enabled"
|
||||
unset x_repeat_enabled
|
||||
fi
|
||||
|
||||
clearUp
|
||||
}
|
||||
|
||||
typeField () {
|
||||
checkIfPass
|
||||
local to_type
|
||||
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
|
||||
xset r off
|
||||
fi
|
||||
|
||||
case $typefield in
|
||||
"OTP") to_type="$(generateOTP)" ;;
|
||||
*) to_type="${stuff[${typefield}]}" ;;
|
||||
esac
|
||||
|
||||
printf '%s' "$to_type" | ${do_type}
|
||||
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
xset r "$x_repeat_enabled"
|
||||
unset x_repeat_enabled
|
||||
fi
|
||||
|
||||
unset to_type
|
||||
|
||||
clearUp
|
||||
}
|
||||
|
||||
generateOTP () {
|
||||
checkIfPass
|
||||
|
||||
# First, we check if there is a non-conventional OTP command in the pass file
|
||||
if PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep -q "${OTPmethod_field}: "; then
|
||||
# We execute the commands after otp_method: AS-IS
|
||||
bash -c "$(PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep "${OTPmethod_field}: " | cut -d' ' -f2-)"
|
||||
else
|
||||
# If there is no method defined, fallback to pass-otp
|
||||
PASSWORD_STORE_DIR="${root}" pass otp "$selected_password"
|
||||
fi
|
||||
|
||||
clearUp
|
||||
}
|
||||
|
||||
copyUser () {
|
||||
checkIfPass
|
||||
printf '%s' "${stuff[${USERNAME_field}]}" | doClip
|
||||
clearUp
|
||||
}
|
||||
|
||||
copyField () {
|
||||
checkIfPass
|
||||
printf '%s' "${stuff[${copyfield}]}" | doClip
|
||||
clearUp
|
||||
}
|
||||
|
||||
copyURL () {
|
||||
checkIfPass
|
||||
printf '%s' "${stuff[${URL_field}]}" | doClip
|
||||
clearUp
|
||||
}
|
||||
|
||||
copyPass () {
|
||||
checkIfPass
|
||||
printf '%s' "$password" | doClip
|
||||
if [[ $notify == "true" ]]; then
|
||||
notify-send "rofi-pass" "Copied Password\\nClearing in $clip_clear seconds"
|
||||
fi
|
||||
|
||||
if [[ $notify == "true" ]]; then
|
||||
(sleep $clip_clear; printf '%s' "" | ${clip_in_primary}; printf '%s' "" | ${clip_in_clipboard} | notify-send "rofi-pass" "Clipboard cleared") &
|
||||
elif [[ $notify == "false" ]]; then
|
||||
(sleep $clip_clear; printf '%s' "" | ${clip_in_primary}; printf '%s' "" | ${clip_in_clipboard}) &
|
||||
fi
|
||||
}
|
||||
|
||||
viewEntry () {
|
||||
checkIfPass
|
||||
showEntry "${selected_password}"
|
||||
}
|
||||
|
||||
generatePass () {
|
||||
askmenu_content=(
|
||||
"Yes"
|
||||
"No"
|
||||
)
|
||||
|
||||
askGenMenu=$(printf '%s\n' "${askmenu_content[@]}" | _rofi -dmenu -p "Generate new Password for ${selected_password}? > ")
|
||||
askgen_exit=$?
|
||||
|
||||
if [[ $askgen_exit -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
if [[ $askGenMenu == "Yes" ]]; then
|
||||
true
|
||||
elif [[ $askGenMenu == "No" ]]; then
|
||||
actionMenu
|
||||
fi
|
||||
|
||||
checkIfPass
|
||||
|
||||
symbols_content=(
|
||||
"0 Cancel"
|
||||
"1 Yes"
|
||||
"2 No"
|
||||
)
|
||||
|
||||
symbols=$(printf '%s\n' "${symbols_content[@]}" | _rofi -dmenu -p "Use Symbols? > ")
|
||||
symbols_val=$?
|
||||
|
||||
if [[ $symbols_val -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
if [[ $symbols == "0 Cancel" ]]; then
|
||||
mainMenu;
|
||||
elif [[ $symbols == "1 Yes" ]]; then
|
||||
symbols="";
|
||||
elif [[ $symbols == "2 No" ]]; then
|
||||
symbols="-n";
|
||||
fi
|
||||
|
||||
HELP="<span$help_color_attribute>Enter Number or hit Enter to use default length</span>"
|
||||
length=$(printf '%s' "" | _rofi -dmenu -mesg "${HELP}" -p "Password length? (Default: ${password_length}) > ")
|
||||
length_exit=$?
|
||||
|
||||
if [[ $length_exit -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
if [[ $length == "" ]]; then
|
||||
PASSWORD_STORE_DIR="${root}" pass generate ${symbols} -i "$selected_password" "${password_length}" > /dev/null;
|
||||
else
|
||||
PASSWORD_STORE_DIR="${root}" pass generate ${symbols} -i "$selected_password" "${length}" > /dev/null;
|
||||
fi
|
||||
}
|
||||
|
||||
# main Menu
|
||||
mainMenu () {
|
||||
if [[ $1 == "--bmarks" ]]; then
|
||||
selected_password="$(list_passwords 2>/dev/null \
|
||||
| _rofi -mesg "Bookmarks Mode. ${switch} to switch" \
|
||||
-dmenu \
|
||||
-kb-custom-10 "${switch}" \
|
||||
-select "$entry" \
|
||||
-p "rofi-pass > ")"
|
||||
|
||||
rofi_exit=$?
|
||||
|
||||
if [[ $rofi_exit -eq 1 ]]; then
|
||||
exit
|
||||
elif [[ $rofi_exit -eq 19 ]]; then
|
||||
${basecommand}
|
||||
elif [[ $rofi_exit -eq 0 ]]; then
|
||||
openURL
|
||||
fi
|
||||
else
|
||||
unset selected_password
|
||||
|
||||
args=( -dmenu
|
||||
-kb-custom-1 "${autotype}"
|
||||
-kb-custom-2 "${type_user}"
|
||||
-kb-custom-3 "${type_pass}"
|
||||
-kb-custom-4 "${open_url}"
|
||||
-kb-custom-5 "${copy_name}"
|
||||
-kb-custom-6 "${copy_pass}"
|
||||
-kb-custom-7 "${show}"
|
||||
-kb-custom-8 "${copy_url}"
|
||||
-kb-custom-9 "${type_menu}"
|
||||
-kb-custom-10 "${previous_root}"
|
||||
-kb-custom-11 "${next_root}"
|
||||
-kb-custom-14 "${action_menu}"
|
||||
-kb-custom-15 "${copy_menu}"
|
||||
-kb-custom-16 "${help}"
|
||||
-kb-custom-17 "${switch}"
|
||||
-kb-custom-18 "${insert_pass}"
|
||||
-kb-custom-19 "${qrcode}"
|
||||
)
|
||||
args+=( -kb-mode-previous "" # These keyboard shortcut options are needed, because
|
||||
-kb-mode-next "" # Shift+<Left|Right> are otherwise taken by rofi.
|
||||
-select "$entry"
|
||||
-p "> " )
|
||||
|
||||
if [[ ${#roots[@]} -gt "1" || $custom_root == "true" ]]; then
|
||||
args+=(-mesg "PW Store: ${root}")
|
||||
fi
|
||||
|
||||
selected_password="$(list_passwords 2>/dev/null | _rofi "${args[@]}")"
|
||||
|
||||
rofi_exit=$?
|
||||
if [[ $rofi_exit -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
# Actions based on exit code, which do not need the entry.
|
||||
# The exit code for -kb-custom-X is X+9.
|
||||
case "${rofi_exit}" in
|
||||
19) roots_index=$(( (roots_index-1+roots_length) % roots_length)); root=${roots[$roots_index]}; mainMenu; return;;
|
||||
20) roots_index=$(( (roots_index+1) % roots_length)); root=${roots[$roots_index]}; mainMenu; return;;
|
||||
25) helpMenu; return;;
|
||||
26) ${basecommand} --bmarks; return;;
|
||||
esac
|
||||
|
||||
mapfile -t password_temp < <(PASSWORD_STORE_DIR="${root}" pass show "$selected_password")
|
||||
password=${password_temp[0]}
|
||||
|
||||
if [[ ${password} == "#FILE="* ]]; then
|
||||
pass_file="${password#*=}"
|
||||
mapfile -t password_temp2 < <(PASSWORD_STORE_DIR="${root}" pass show "${pass_file}")
|
||||
password=${password_temp2[0]}
|
||||
fi
|
||||
|
||||
fields=$(printf '%s\n' "${password_temp[@]:1}" | awk '$1 ~ /:$/ || /otpauth:\/\// {$1=$1;print}')
|
||||
declare -A stuff
|
||||
stuff["pass"]=${password}
|
||||
|
||||
if [[ -n $fields ]]; then
|
||||
while read -r LINE; do
|
||||
unset _id _val
|
||||
case "$LINE" in
|
||||
"otpauth://"*|"${OTPmethod_field}"*)
|
||||
_id="OTP"
|
||||
_val=""
|
||||
;;
|
||||
*)
|
||||
_id="${LINE%%: *}"
|
||||
_val="${LINE#* }"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ -n "$_id" ]]; then
|
||||
stuff["${_id}"]=${_val}
|
||||
fi
|
||||
done < <(printf '%s\n' "${fields}")
|
||||
|
||||
if test "${stuff['autotype']+autotype}"; then
|
||||
:
|
||||
else
|
||||
stuff["autotype"]="${USERNAME_field} :tab pass"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "${stuff["${AUTOTYPE_field}"]}" ]]; then
|
||||
if [[ -n $default_autotype ]]; then
|
||||
stuff["${AUTOTYPE_field}"]="${default_autotype}"
|
||||
fi
|
||||
fi
|
||||
if [[ -z "${stuff["${USERNAME_field}"]}" ]]; then
|
||||
if [[ -n $default_user ]]; then
|
||||
if [[ "$default_user" == ":filename" ]]; then
|
||||
stuff["${USERNAME_field}"]="$(basename "$selected_password")"
|
||||
else
|
||||
stuff["${USERNAME_field}"]="${default_user}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
pass_content="$(for key in "${!stuff[@]}"; do printf '%s\n' "${key}: ${stuff[$key]}"; done)"
|
||||
|
||||
# actions based on keypresses
|
||||
# The exit code for -kb-custom-X is X+9.
|
||||
case "${rofi_exit}" in
|
||||
0) typeMenu;;
|
||||
10) sleep $wait; autopass;;
|
||||
11) sleep $wait; typeUser;;
|
||||
12) sleep $wait; typePass;;
|
||||
13) openURL;;
|
||||
14) copyUser;;
|
||||
15) copyPass;;
|
||||
16) viewEntry;;
|
||||
17) copyURL;;
|
||||
18) default_do="menu" typeMenu;;
|
||||
23) actionMenu;;
|
||||
24) copyMenu;;
|
||||
27) insertPass;;
|
||||
28) generateQrCode;;
|
||||
esac
|
||||
clearUp
|
||||
}
|
||||
|
||||
|
||||
clearUp () {
|
||||
password=''
|
||||
selected_password=''
|
||||
unset stuff
|
||||
unset password
|
||||
unset selected_password
|
||||
unset password_temp
|
||||
unset stuff
|
||||
}
|
||||
|
||||
helpMenu () {
|
||||
_rofi -dmenu -mesg "Hint: All hotkeys are configurable in config file" -p "Help > " <<- EOM
|
||||
${autotype}: Autotype
|
||||
${type_user}: Type Username
|
||||
${type_pass}: Type Password
|
||||
${qrcode}: Generate and display qrcode
|
||||
---
|
||||
${copy_name}: Copy Username
|
||||
${copy_pass}: Copy Password
|
||||
${copy_url}: Copy URL
|
||||
${open_url}: Open URL
|
||||
${copy_menu}: Copy Custom Field
|
||||
---
|
||||
${action_menu}: Edit, Move, Delete, Re-generate Submenu
|
||||
${show}: Show Password File
|
||||
${insert_pass}: Insert new Pass Entry
|
||||
${switch}: Switch Pass/Bookmark Mode
|
||||
---
|
||||
${previous_root}: Switch to previous password store (--root)
|
||||
${next_root}: Switch to next password store (--root)
|
||||
EOM
|
||||
help_val=$?
|
||||
|
||||
if [[ $help_val -eq 1 ]]; then
|
||||
exit;
|
||||
else
|
||||
unset helptext; mainMenu;
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
typeMenu () {
|
||||
if [[ -n $default_do ]]; then
|
||||
if [[ $default_do == "menu" ]]; then
|
||||
checkIfPass
|
||||
local -a keys=("${!stuff[@]}")
|
||||
keys=("${keys[@]/$AUTOTYPE_field}")
|
||||
typefield=$({ printf '%s' "${AUTOTYPE_field}" ; printf '%s\n' "${keys[@]}" | sort; } | _rofi -dmenu -p "Choose Field to type > ")
|
||||
typefield_exit=$?
|
||||
if [[ $typefield_exit -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
case "$typefield" in
|
||||
'') exit;;
|
||||
'pass') sleep $wait; typePass;;
|
||||
"${AUTOTYPE_field}") sleep $wait; autopass;;
|
||||
*) sleep $wait; typeField
|
||||
esac
|
||||
clearUp
|
||||
elif [[ $default_do == "${AUTOTYPE_field}" ]]; then
|
||||
sleep $wait; autopass
|
||||
else
|
||||
${default_do}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
copyMenu () {
|
||||
checkIfPass
|
||||
copyfield=$(printf '%s\n' "${!stuff[@]}" | sort | _rofi -dmenu -p "Choose Field to copy > ")
|
||||
val=$?
|
||||
if [[ $val -eq 1 ]]; then
|
||||
exit;
|
||||
fi
|
||||
if [[ $copyfield == "pass" ]]; then
|
||||
copyPass;
|
||||
else
|
||||
copyField
|
||||
fi
|
||||
clearUp
|
||||
}
|
||||
|
||||
actionMenu () {
|
||||
checkIfPass
|
||||
action_content=("< Return"
|
||||
"---"
|
||||
"1 Move Password File"
|
||||
"2 Copy Password File"
|
||||
"3 Delete Password File"
|
||||
"4 Edit Password File"
|
||||
"5 Generate New Password"
|
||||
)
|
||||
|
||||
action=$(printf '%s\n' "${action_content[@]}" | _rofi -dmenu -p "Choose Action > ")
|
||||
if [[ ${action} == "1 Move Password File" ]]; then
|
||||
manageEntry move;
|
||||
elif [[ ${action} == "3 Delete Password File" ]]; then
|
||||
manageEntry delete;
|
||||
elif [[ ${action} == "2 Copy Password File" ]]; then
|
||||
manageEntry copy;
|
||||
elif [[ ${action} == "4 Edit Password File" ]]; then
|
||||
manageEntry edit;
|
||||
elif [[ ${action} == "5 Generate New Password" ]]; then
|
||||
generatePass;
|
||||
elif [[ ${action} == "< Return" ]]; then
|
||||
mainMenu;
|
||||
elif [[ ${action} == "" ]]; then
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
showEntry () {
|
||||
if [[ -z $pass_content ]]; then
|
||||
pass_temp=$(PASSWORD_STORE_DIR="${root}" pass show "$selected_password")
|
||||
password="${pass_temp%%$'\n'*}"
|
||||
pass_key_value=$(printf '%s\n' "${pass_temp}" | tail -n+2 | grep ': ')
|
||||
declare -A stuff
|
||||
|
||||
while read -r LINE; do
|
||||
_id="${LINE%%: *}"
|
||||
_val="${LINE#* }"
|
||||
stuff["${_id}"]=${_val}
|
||||
done < <(printf '%s\n' "${pass_key_value}")
|
||||
|
||||
stuff["pass"]=${password}
|
||||
|
||||
if test "${stuff['autotype']+autotype}"; then
|
||||
:
|
||||
else
|
||||
stuff["autotype"]="${USERNAME_field} :tab pass"
|
||||
fi
|
||||
|
||||
pass_content="$(for key in "${!stuff[@]}"; do printf '%s\n' "${key}: ${stuff[$key]}"; done)"
|
||||
fi
|
||||
|
||||
bla_content=("< Return"
|
||||
"${pass_content}"
|
||||
)
|
||||
|
||||
bla=$(printf '%s\n' "${bla_content[@]}" | _rofi -dmenu -mesg "Enter: Copy entry to clipboard" -p "> ")
|
||||
rofi_exit=$?
|
||||
|
||||
word=$(printf '%s' "$bla" | gawk -F': ' '{print $1}')
|
||||
|
||||
if [[ ${rofi_exit} -eq 1 ]]; then
|
||||
exit
|
||||
elif [[ ${rofi_exit} -eq 0 ]]; then
|
||||
if [[ ${bla} == "< Return" ]]; then
|
||||
mainMenu
|
||||
else
|
||||
if [[ -z $(printf '%s' "${stuff[${word}]}") ]]; then
|
||||
printf '%s' "$word" | doClip
|
||||
else
|
||||
printf '%s' "${stuff[${word}]}" | doClip
|
||||
fi
|
||||
if [[ $notify == "true" ]]; then
|
||||
notify-send "rofi-pass" "Copied Password\\nClearing in $clip_clear seconds"
|
||||
fi
|
||||
if [[ $notify == "true" ]]; then
|
||||
(sleep $clip_clear; printf '%s' "" | ${clip_in_primary}; printf '%s' "" | ${clip_in_clipboard} | notify-send "rofi-pass" "Clipboard cleared") &
|
||||
elif [[ $notify == "false" ]]; then
|
||||
(sleep $clip_clear; printf '%s' "" | ${clip_in_primary}; printf '%s' "" | ${clip_in_clipboard}) &
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
exit
|
||||
unset stuff
|
||||
unset password
|
||||
unset selected_password
|
||||
unset password_temp
|
||||
unset stuff
|
||||
exit
|
||||
}
|
||||
|
||||
manageEntry () {
|
||||
if [[ "$1" == "edit" ]]; then
|
||||
EDITOR=$EDITOR PASSWORD_STORE_DIR="${root}" pass edit "${selected_password}"
|
||||
mainMenu
|
||||
elif [[ $1 == "move" ]]; then
|
||||
cd "${root}" || exit
|
||||
group_array=(*/)
|
||||
group=$(printf '%s\n' "${group_array[@]%/}" | _rofi -dmenu -p "Choose Group > ")
|
||||
if [[ $group == "" ]]; then
|
||||
exit
|
||||
fi
|
||||
PASSWORD_STORE_DIR="${root}" pass mv "$selected_password" "${group}"
|
||||
mainMenu
|
||||
elif [[ $1 == "copy" ]]; then
|
||||
cd "${root}" || exit
|
||||
group_array=(*/)
|
||||
group=$(printf '%s\n' "${group_array[@]%/}" | _rofi -dmenu -p "Choose Group > ")
|
||||
if [[ $group == "" ]]; then
|
||||
exit
|
||||
else
|
||||
new_name="$(listgpg | _rofi -dmenu -format 'f' -mesg "Copying to same Group. Please enter a name for the new entry" -p "> ")"
|
||||
fi
|
||||
PASSWORD_STORE_DIR="${root}" pass cp "$selected_password" "${group}/${new_name}"
|
||||
mainMenu
|
||||
elif [[ "$1" == "delete" ]]; then
|
||||
HELP="<span$help_color_attribute>Selected entry: ${selected_password}</span>"
|
||||
ask_content=("Yes"
|
||||
"No"
|
||||
)
|
||||
ask=$(printf '%s\n' "${ask_content[@]}" | _rofi -mesg "${HELP}" -dmenu -p "Are You Sure? > ")
|
||||
if [[ "$ask" == "Yes" ]]; then
|
||||
PASSWORD_STORE_DIR="${root}" pass rm --force "${selected_password}"
|
||||
elif [[ "$ask" == "No" ]]; then
|
||||
mainMenu
|
||||
elif [[ -z "$ask" ]]; then
|
||||
exit
|
||||
fi
|
||||
else
|
||||
mainMenu
|
||||
fi
|
||||
}
|
||||
|
||||
edit_pass() {
|
||||
if [[ $edit_new_pass == "true" ]]; then
|
||||
PASSWORD_STORE_DIR="${root}" pass edit "${1}"
|
||||
fi
|
||||
}
|
||||
|
||||
insertPass () {
|
||||
url=$(${clip_out_clipboard})
|
||||
|
||||
if [[ "${url:0:4}" == "http" ]]; then
|
||||
domain_name="$(printf '%s\n' "${url}" | awk -F / '{l=split($3,a,"."); print (a[l-1]=="com"?a[l-2] OFS:X) a[l-1] OFS a[l]}' OFS=".")"
|
||||
help_content="Domain: ${domain_name}
|
||||
Type name, make sure it is unique"
|
||||
else
|
||||
help_content="Hint: Copy URL to clipboard before calling this menu.
|
||||
Type name, make sure it is unique"
|
||||
fi
|
||||
|
||||
cd "${root}" || exit
|
||||
group_array=(*/)
|
||||
grouplist=$(printf '%s\n' "${group_array[@]%/}")
|
||||
name="$(listgpg | _rofi -dmenu -format 'f' -filter "${domain_name}" -mesg "${help_content}" -p "> ")"
|
||||
val=$?
|
||||
|
||||
if [[ $val -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
user_content=("${default_user2}"
|
||||
"${USER}"
|
||||
"${default_user}"
|
||||
)
|
||||
|
||||
user=$(printf '%s\n' "${user_content[@]}" | _rofi -dmenu -mesg "Chose Username or type" -p "> ")
|
||||
val=$?
|
||||
|
||||
if [[ $val -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
group_content=("No Group"
|
||||
"---"
|
||||
"${grouplist}"
|
||||
)
|
||||
|
||||
group=$(printf '%s\n' "${group_content[@]}" | _rofi -dmenu -p "Choose Group > ")
|
||||
val=$?
|
||||
|
||||
if [[ $val -eq 1 ]]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
pw=$(printf '%s' "Generate" | _rofi -dmenu -password -p "Password > " -mesg "Type Password or hit Enter to generate one")
|
||||
|
||||
if [[ $pw == "Generate" ]]; then
|
||||
pw=$(_pwgen "${password_length}")
|
||||
fi
|
||||
|
||||
clear
|
||||
|
||||
if [[ "$group" == "No Group" ]]; then
|
||||
if [[ $url == http* ]]; then
|
||||
pass_content=("${pw}"
|
||||
"---"
|
||||
"${USERNAME_field}: ${user}"
|
||||
"${URL_field}: ${url}"
|
||||
)
|
||||
printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${name}" > /dev/null && edit_pass "${name}"
|
||||
else
|
||||
pass_content=("${pw}"
|
||||
"---"
|
||||
"${USERNAME_field}: ${user}"
|
||||
)
|
||||
printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${name}" > /dev/null && edit_pass "${name}"
|
||||
fi
|
||||
else
|
||||
if [[ $url == http* ]]; then
|
||||
pass_content=("${pw}"
|
||||
"---"
|
||||
"${USERNAME_field}: ${user}"
|
||||
"${URL_field}: ${url}"
|
||||
)
|
||||
printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${group}/${name}" > /dev/null && edit_pass "${group}/${name}"
|
||||
else
|
||||
pass_content=("${pw}"
|
||||
"---"
|
||||
"${USERNAME_field}: ${user}"
|
||||
)
|
||||
printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${group}/${name}" > /dev/null && edit_pass "${group}/${name}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
help_msg () {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
rofi-pass [command]
|
||||
|
||||
Commands:
|
||||
--insert insert new entry to password store
|
||||
--root set custom root directories (colon separated)
|
||||
--last-used highlight last used item
|
||||
--show-last show details of last used Entry
|
||||
--bmarks start in bookmarks mode
|
||||
|
||||
rofi-pass version 1.5.3
|
||||
EOF
|
||||
}
|
||||
|
||||
get_config_file () {
|
||||
configs=("$ROFI_PASS_CONFIG"
|
||||
"$config_dir/rofi-pass/config"
|
||||
"/etc/rofi-pass.conf")
|
||||
|
||||
# return the first config file with a valid path
|
||||
for config in "${configs[@]}"; do
|
||||
# '-n' is needed in case ROFI_PASS_CONFIG is not set
|
||||
if [[ -n "${config}" && -f "${config}" ]]; then
|
||||
printf "%s" "$config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main () {
|
||||
# load config file
|
||||
config_file="$(get_config_file)"
|
||||
[[ -n "$config_file" ]] && source "$config_file"
|
||||
|
||||
# create tmp dir
|
||||
if [[ ! -d "$cache_dir/rofi-pass" ]]; then
|
||||
mkdir -p "$cache_dir/rofi-pass"
|
||||
fi
|
||||
|
||||
# set backends
|
||||
clip_in_primary=_clip_in_primary_${clipboard_backend}
|
||||
clip_in_clipboard=_clip_in_clipboard_${clipboard_backend}
|
||||
clip_out_primary=_clip_out_primary_${clipboard_backend}
|
||||
clip_out_clipboard=_clip_out_clipboard_${clipboard_backend}
|
||||
|
||||
do_type=_do_type_${backend}
|
||||
do_press_key=_do_press_key_${backend}
|
||||
|
||||
# backwards compat
|
||||
if [[ -n "$xdotool_delay" ]]; then
|
||||
>&2 echo "Setting 'xdotool_delay' is deprecated. Please update your configuration to use 'type_delay' instead"
|
||||
type_delay=${xdotool_delay}
|
||||
fi
|
||||
|
||||
# Only valid for the xdotool backend
|
||||
if [[ $backend == "xdotool" ]]; then
|
||||
# fix keyboard layout if enabled in config
|
||||
if [[ $fix_layout == "true" ]]; then
|
||||
layout_cmd
|
||||
fi
|
||||
fi
|
||||
|
||||
# set help color
|
||||
if [[ $help_color == "" ]]; then
|
||||
help_color_attribute=""
|
||||
else
|
||||
help_color_attribute=" color='$help_color'"
|
||||
fi
|
||||
|
||||
# check for BROWSER variable, use xdg-open as fallback
|
||||
if [[ -z $BROWSER ]]; then
|
||||
export BROWSER=xdg-open
|
||||
fi
|
||||
|
||||
# check if alternative root directory was given on commandline
|
||||
if [[ -r "$cache_dir/rofi-pass/last_used" ]] && [[ $1 == "--last-used" || $1 == "--show-last" ]]; then
|
||||
roots=("$(awk -F ': ' '{ print $1 }' "$cache_dir/rofi-pass/last_used")")
|
||||
elif [[ -n "$2" && "$1" == "--root" ]]; then
|
||||
custom_root=true; IFS=: read -r -a roots <<< "$2"
|
||||
elif [[ -n $root ]]; then
|
||||
custom_root=true; IFS=: read -r -a roots <<< "${root}"
|
||||
elif [[ -n ${PASSWORD_STORE_DIR} ]]; then
|
||||
roots=("${PASSWORD_STORE_DIR}")
|
||||
else
|
||||
roots=("$HOME/.password-store")
|
||||
fi
|
||||
roots_index=0
|
||||
roots_length=${#roots[@]}
|
||||
export root=${roots[$roots_index]}
|
||||
export PASSWORD_STORE_DIR="${root}"
|
||||
case $1 in
|
||||
--insert)
|
||||
insertPass
|
||||
;;
|
||||
--root)
|
||||
mainMenu
|
||||
;;
|
||||
--help)
|
||||
help_msg
|
||||
;;
|
||||
--last-used)
|
||||
if [[ -r "$cache_dir/rofi-pass/last_used" ]]; then
|
||||
entry="$(awk -F ': ' '{ print $2 }' "$cache_dir/rofi-pass/last_used")"
|
||||
fi
|
||||
mainMenu
|
||||
;;
|
||||
--show-last)
|
||||
if [[ -r "$cache_dir/rofi-pass/last_used" ]]; then
|
||||
selected_password="$(awk -F ': ' '{ print $2 }' "$cache_dir/rofi-pass/last_used")" viewEntry
|
||||
else
|
||||
mainMenu
|
||||
fi
|
||||
;;
|
||||
--bmarks)
|
||||
mainMenu --bmarks;
|
||||
;;
|
||||
*)
|
||||
mainMenu
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,83 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
LOG_FILE=$([[ ${DEBUG_SCREENRECORDER:-false} == "true" ]] && echo "/tmp/screenrecord.log" || echo "/dev/null")
|
||||
|
||||
usage() {
|
||||
echo "Usage: screen-recorder stop | screen-recorder [-a] [-m region|monitor|window] -o <output_filename>" >&2
|
||||
}
|
||||
|
||||
if [ "$#" -eq 1 ] && [ "$1" = stop ]; then
|
||||
pkill -SIGINT -f "gpu-screen-recorder"
|
||||
|
||||
count=0
|
||||
while pgrep -f "gpu-screen-recorder" >/dev/null && ((count < 50)); do
|
||||
sleep 0.1
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
if pgrep -f "gpu-screen-recorder" >/dev/null; then
|
||||
pkill -9 -f "gpu-screen-recorder"
|
||||
fi
|
||||
notify-send "Screen Recorder" "Recording stopped" -t 2000
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if pgrep -f "gpu-screen-recorder" >/dev/null; then
|
||||
notify-send "Screen Recorder" "Recording is already in progress" -t 2000
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mode=monitor
|
||||
output_filename="/tmp/output.mp4"
|
||||
audio_args=()
|
||||
while getopts ":am:o:h" opt; do
|
||||
case "$opt" in
|
||||
a) audio_args=(-a default_input -ac aac) ;;
|
||||
m) mode=$OPTARG ;;
|
||||
o) output_filename=$OPTARG ;;
|
||||
h) usage; exit 0 ;;
|
||||
:) usage; exit 1 ;;
|
||||
\?) usage; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ "$#" -ne 0 ] || [ -z "$output_filename" ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
recorder=$(PATH=$(printf '%s' "$PATH" | awk -v RS=: -v ORS=: -v script_dir="$script_dir" '$0 != script_dir') command -v gpu-screen-recorder)
|
||||
if [ -z "$recorder" ]; then
|
||||
echo "gpu-screen-recorder executable not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
capture_args=()
|
||||
case "$mode" in
|
||||
monitor)
|
||||
target=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name')
|
||||
[ -n "$target" ] || exit 1
|
||||
capture_args=(-w "$target")
|
||||
;;
|
||||
region)
|
||||
target=$(slurp -f '%wx%h+%x+%y') || exit 1
|
||||
[ -n "$target" ] || exit 1
|
||||
capture_args=(-w region -region "$target")
|
||||
;;
|
||||
window)
|
||||
target=$(hyprctl clients -j |
|
||||
jq -r '.[] | select(.mapped == true and .hidden == false and .at != null and .size != null) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1]) \((.title // .class // "window") | gsub("[\\r\\n]"; " "))"' |
|
||||
slurp -r) || exit 1
|
||||
[ -n "$target" ] || exit 1
|
||||
capture_args=(-w region -region "$target")
|
||||
;;
|
||||
*)
|
||||
echo "Invalid mode: $mode" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exec "$recorder" "${capture_args[@]}" "${audio_args[@]}" -k auto -f 60 -fm cfr -fallback-cpu-encoding yes -o "$output_filename" 2>>"$LOG_FILE" &
|
||||
@@ -1,53 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Wrapper around wallpaper-fetcher: downloads a random new wallpaper from
|
||||
# backiee.com and sets it as the desktop background via awww.
|
||||
#
|
||||
# Usage: set-wallpaper.sh [backiee-path] [-r WxH]
|
||||
#
|
||||
# backiee-path Path segment on backiee.com (default: latest)
|
||||
# -r WxH Max resolution (e.g. "1920x1080") — passed through to wallpaper-fetcher
|
||||
|
||||
BACKIEE_PATH="${1:-latest}"
|
||||
|
||||
# Check for -r flag (may be first or second arg)
|
||||
RES_ARGS=""
|
||||
if [[ "$1" == "-r" ]]; then
|
||||
RES_ARGS="-r $2"
|
||||
elif [[ "$2" == "-r" ]]; then
|
||||
RES_ARGS="-r $3"
|
||||
fi
|
||||
|
||||
if [[ ! -x /usr/bin/awww ]]; then
|
||||
echo "required awww — please install with yay -S awww" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Paths
|
||||
BACKGROUNDS_DIR="$HOME/Sync/Shared/wallpapers"
|
||||
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
|
||||
|
||||
[ -d "$BACKGROUNDS_DIR" ] || mkdir -p "$BACKGROUNDS_DIR"
|
||||
|
||||
# Run wallpaper-fetcher (stdout = bare filename, stderr = log output)
|
||||
FILENAME=$(~/.local/bin/wallpaper-fetcher "$BACKIEE_PATH" --output "$BACKGROUNDS_DIR" $RES_ARGS 2>/dev/null)
|
||||
|
||||
if [[ -z "$FILENAME" ]]; then
|
||||
echo "wallpaper-fetcher failed — no image downloaded" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILE_PATH="$BACKGROUNDS_DIR/$FILENAME"
|
||||
|
||||
echo "Wallpaper: $FILENAME"
|
||||
|
||||
if [[ ! -f "$FILE_PATH" ]]; then
|
||||
echo "File not found: $FILE_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ln -nsf "$FILE_PATH" "$CURRENT_BACKGROUND_LINK" &&
|
||||
setsid uwsm app -- awww img "$CURRENT_BACKGROUND_LINK" &&
|
||||
exit 0
|
||||
|
||||
exit 1
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
get_file_extension() {
|
||||
local url="$1"
|
||||
|
||||
# Remove query parameters and fragments
|
||||
local clean_url="${url%%\?*}"
|
||||
clean_url="${clean_url%%\#*}"
|
||||
|
||||
# Get the filename part
|
||||
local filename="${clean_url##*/}"
|
||||
|
||||
# Check if there's a dot in the filename
|
||||
if [[ "$filename" == *.* ]]; then
|
||||
echo "${filename##*.}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo -e "\e[32mLet's create a new web app you can start with the app launcher.\n\e[0m"
|
||||
APP_NAME=$(gum input --prompt "Name> " --placeholder "My favorite web app")
|
||||
APP_URL=$(gum input --prompt "URL> " --placeholder "https://example.com")
|
||||
ICON_URL=$(gum input --prompt "Icon URL> " --placeholder "See https://dashboardicons.com (must use PNG!)")
|
||||
else
|
||||
APP_NAME="$1"
|
||||
APP_URL="$2"
|
||||
ICON_URL="$3"
|
||||
fi
|
||||
|
||||
if [[ -z "$APP_NAME" || -z "$APP_URL" || -z "$ICON_URL" ]]; then
|
||||
echo "You must set app name, app URL, and icon URL!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ICON_EXT=$(get_file_extension "$ICON_URL")
|
||||
ICON_DIR="$HOME/.local/share/icons"
|
||||
DESKTOP_FILE="$HOME/.local/share/applications/$APP_NAME.desktop"
|
||||
ICON_PATH="$ICON_DIR/$APP_NAME.$ICON_EXT"
|
||||
|
||||
mkdir -p "$ICON_DIR"
|
||||
|
||||
if ! curl -sL -o "$ICON_PATH" "$ICON_URL"; then
|
||||
echo "Error: Failed to download icon."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat >"$DESKTOP_FILE" <<EOF
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=$APP_NAME
|
||||
Comment=$APP_NAME
|
||||
Exec=chromium --new-window --ozone-platform=wayland --app="$APP_URL" --name="$APP_NAME" --class="$APP_NAME"
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=$APP_NAME
|
||||
StartupNotify=true
|
||||
EOF
|
||||
|
||||
chmod +x "$DESKTOP_FILE"
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo -e "You can now find $APP_NAME using the app launcher (SUPER + SPACE)\n"
|
||||
fi
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo export SSH_AUTH_SOCK=$(fd 's.*sshd*' ~/.ssh)
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
class=$1
|
||||
cmd=$2
|
||||
hyprctl dispatch "focus_or_launch({ match = '$class', cmd = 'footclient -a $class -T $class $cmd'})"
|
||||
Reference in New Issue
Block a user