Skip to content

Commit

Permalink
Code restructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoplaitano committed Jan 5, 2024
1 parent 228305d commit ad17261
Showing 1 changed file with 119 additions and 147 deletions.
266 changes: 119 additions & 147 deletions evemenu
Original file line number Diff line number Diff line change
Expand Up @@ -3,217 +3,189 @@
# File: evemenu
# Author: Marco Plaitano https://github.com/marcoplaitano
# Date: 01 Aug 2022
# Brief: Let the user launch anything via dmenu.
#
# Copyright (c) 2023 Marco Plaitano
# Brief: This script lets you interact with a custom actions menu
# based on dmenu.


##################################################
# DMENU APPEARANCE #
##################################################
################################################################################
### APPEARANCE
################################################################################

font="monospace-12"
nb="#262626" # Normal Background
nf="#AAAAAA" # Normal Foreground
sb="#447375" # Selected Background
sf="#FFFFFF" # Selected Foreground

# Background.
nb="#262626"
# Foreground.
nf="#aaaaaa"
# Selected item background.
sb="#447375"
# Selected item foreground.
sf="#ffffff"



##################################################
# ACTIONS #
##################################################

_WEBBROWSER=${WEBBROWSER:=firefox}
_CALCULATOR=${CALCULATOR:=mate-calc}
################################################################################
### ACTIONS
################################################################################

# Key-Value pairs in which:
# Key = name of the action.
# Value = command to perform.
# Key = name of the action
# Value = routine to perform
declare -A actions=(
[all]="_ask_dmenu -p run:" # Launch regular instance of dmenu.
[amazon]="$_WEBBROWSER amazon.com"
[appearance]="xfce4-appearance-settings"
[calculator]="$CALCULATOR"
[code]="_choose_code_dir"
# Open links in web browser
[amazon]="firefox amazon.com"
[github]="firefox github.com"
[gmail]="firefox mail.google.com/mail/u/0/#inbox"
[lofi]="firefox youtube.com/watch?v=jfKfPfyJRdk"
[netflix]="firefox netflix.com/browse"
[speedtest]="firefox speedtest.net/run"
[youtube]="firefox youtube.com"
[whatsapp]="firefox web.whatsapp.com"

# Launch GUI applications.
[discord]="discord"
[drive]="_choose_google_account drive.google.com/drive my-drive"
[firefox]="firefox"
[github]="$_WEBBROWSER github.com"
[instagram]="$_WEBBROWSER instagram.com"
[kill]="_choose_kill_process"
[lofi]="$_WEBBROWSER https://www.youtube.com/watch?v=jfKfPfyJRdk"
[logout]="xfce4-session-logout"
[mail]="_choose_google_account mail.google.com/mail \#inbox"
[mousepad]="mousepad"
[netflix]="$_WEBBROWSER netflix.com/browse"
[nightmode]="night_mode.sh --now"
[notion]="$_WEBBROWSER notion.so"
[poweroff]="poweroff"
[redshift]="redshift -x && redshift"
[screenshot]="xfce4-screenshooter"
[search]="_search_online"
[session]="xfce4-session-settings"
[settings]="xfce4-settings-manager"
[screenrecorder]="simplescreenrecorder"
[speedtest]="$_WEBBROWSER speedtest.net/run"
[spotify]="spotify"
[telegram]="Telegram"
[youtube]="$_WEBBROWSER youtube.com"
[whatsapp]="$_WEBBROWSER https://web.whatsapp.com"
)
[screenshot]="xfce4-screenshooter"
[settings]="xfce4-settings-manager"

# Control system.
[logout]="xfce4-session-logout --logout --fast"
[nightmode]="night_mode.sh --on" # Custom script.
[poweroff]="poweroff"
[reboot]="reboot"
[suspend]="systemctl suspend"

# Custom routines (defined below).
[code]="_choose_code_dir"
[dock]="_plank_dock"
[kill]="_choose_kill_process"
[search]="_search_online"
)

##################################################
# FUNCTIONS #
##################################################

################################################################################
### FUNCTIONS
################################################################################

# Show error message and stop the execution of the script.
_die() {
[[ -n $1 ]] && error_msg="$1" || error_msg="Error in $(basename "$0")."
if [[ $TERM != dumb ]]; then
echo "$error_msg" >&2
else
notify-send "Error in $(basename "$0")" "$error_msg"
local msg
msg="$1"
echo "$msg" >&2
if [[ $TERM == dumb ]]; then
notify-send "evemenu error" "$msg"
fi
exit 1
}

# Make sure that the script won't be executed more than once at a time.
_check_pid() {
local pidfile
pidfile="/tmp/evemenu.pid"
if [[ -f "$pidfile" ]]; then
pid=$(cat "$pidfile")
# Process found, script already running, do not execute this.
ps -p "$pid" &>/dev/null && _die "Script already running."
fi
# Script wasn't running, write its pid.
echo $$ > "$pidfile"
}

# Run dmenu with the given options and list of choices.
_ask_dmenu() {
local prompt list multiple_lines accept_all lines
local prompt list accept_all
# Parse function's arguments.
while [[ -n $1 ]]; do
case "$1" in
# Prompt to display.
-p | --prompt)
prompt="$2" ; shift ; shift ;;
prompt="$2" ; shift ;;
# List of choices.
-l | --list)
list="$2" ; shift ; shift ;;
# Display each choice on a new line.
--multiple-lines)
multiple_lines=true ; shift ;;
# Accept any user input, without presenting a list of choices.
list="$2" ; shift ;;
# Flag to accept any user input, without list of choices.
--accept-all)
accept_all=true ; shift ;;
accept_all=1 ;;
# Discard any other argument.
*)
shift ;;
*) ;;
esac
shift
done

lines=0
# If requested, calculate the number of lines in the list string.
if [[ $multiple_lines == true ]]; then
lines=$(echo -e "$list" | wc -l)
fi

# Ask for any input.
if [[ $accept_all == true ]]; then
# Ask for any user input, without presenting a list of choices.
if [[ $accept_all == 1 ]]; then
echo $(dmenu -p "$prompt" -i -fn $font -nb $nb -nf $nf -sb $sb -sf $sf)
# Launch regular dmenu (with a list of all system applications).
elif [[ -z $list ]]; then
echo $(dmenu_run -p "$prompt" -i -fn $font -nb $nb -nf $nf -sb $sb -sf $sf)
# Ask for a choice from the list.
else
echo $(echo -e "$list" | dmenu -p "$prompt" -l $lines -i -fn $font -nb $nb -nf $nf -sb $sb -sf $sf)
echo $(echo -e "$list" | \
dmenu -p "$prompt" -i -fn $font -nb $nb -nf $nf -sb $sb -sf $sf)
fi
}


################################################################################
### ROUTINES
################################################################################

##################################################
# ROUTINES #
##################################################

### CALLED BY ACTION "code"
# Choose a directory to open in a new VS Code window.
_choose_code_dir() {
local dirs_string dir _CODE_ROOT_DIR
_CODE_ROOT_DIR="$HOME/Desktop" # Were to look for projects to open.

# Append all possible directories to one string.
dirs_string="default\nempty"
for dir in $(find "$_CODE_ROOT_DIR" -maxdepth 1 -type d); do
[[ "$dir" == "$_CODE_ROOT_DIR" ]] && continue
dirs_string+="\n"$(basename "$dir")
done

# Ask which directory to open.
dir=$(_ask_dmenu -p "directory:" -l "$dirs_string" --multiple-lines)
[[ -z $dir ]] && exit

# Open an empty window.
if [[ "$dir" == "empty" ]]; then
code -n
# "default" will open a window with last active workspace.
elif [[ "$dir" == "default" ]]; then
code
elif [[ -d "$_CODE_ROOT_DIR"/"$dir" ]]; then
code "$_CODE_ROOT_DIR"/"$dir"
fi
### CALLED BY ACTION "dock"
# Relaunch plank dock.
_plank_dock() {
killall plank
plank &>/dev/null
}

### CALLED BY ACTION "kill"
# Choose a process to kill.
_choose_kill_process() {
local processes process
# Ask for a process to kill. It can be any value, even one not listed here.
processes="firefox\nplank\nredshift\nspotify"
processes="firefox\nplank\nredshift\nspotify\nvlc"
process=$(_ask_dmenu -p "which process?" -l $processes)
killall "$process"
}
[[ -z $process ]] && return

### CALLED BY ACTIONS "drive", "mail"
# Choose which account to open the given Google's site with.
# When multiple accounts are active in the same browser, Google will assign
# a number to each one, going from 0 to N-1
_choose_google_account() {
local accounts account num
accounts="personal\nwork"
account=$(_ask_dmenu -p "which account?" -l $accounts)
[[ -z $account ]] && exit
# Argument $1 is the site to open (either gmail, Drive, Photos, ...) and,
# eventually, $2 is the specific page view in the site.
case $account in
personal) num=0 ;;
work) num=1 ;;
esac
$_WEBBROWSER "https://$1/u/$num/$2"
killall "$process"
}

### CALLED BY ACTION "search"
# Google something.
_search_online() {
local query url domains
local query
query=$(_ask_dmenu -p "search for?" --accept-all)
[[ -z $query ]] && exit
url="https://www.google.com/search?q=${query// /+}"
domains=("com" "it" "gov" "en" "org")
for domain in "${domains[@]}"; do
if [[ $query == *.$domain ]]; then
url="https://$query"
break
fi
[[ -z $query ]] && return

firefox "https://www.google.com/search?q=${query// /+}"
}

### CALLED BY ACTION "code"
# Choose a directory to open in a new VS Code window.
_choose_code_dir() {
local root_dir dirs_string dir
root_dir="$HOME/Desktop" # Where to look for directories to open.

# Append all possible directories to one string.
dirs_string="default\nempty"
for dir in $(find "$root_dir" -mindepth 1 -maxdepth 1 -type d); do
dirs_string+="\n"$(basename "$dir")
done
$_WEBBROWSER "$url"
# Ask which directory to open.
dir=$(_ask_dmenu -p "directory:" -l "$dirs_string")
[[ -z $dir ]] && return

if [[ "$dir" == "empty" ]]; then
code -n # Open an empty window.
elif [[ "$dir" == "default" ]]; then
code # Open last active workspace.
elif [[ -d "$root_dir"/"$dir" ]]; then
code "$root_dir"/"$dir" # Open chosen directory.
fi
}


################################################################################
### MAIN
################################################################################

##################################################
# MAIN #
##################################################
# Make sure that the script won't be executed more than once at a time.
_check_pid

# Sort the keys in alphabetical order and create one long string, separating
# them with a '\n'.
# Sort the dictionary keys in alphabetical order and create one long string,
# separating them with '\n'
keys=( $( echo ${!actions[@]} | tr ' ' $'\n' | sort ) )
for k in "${keys[@]}"; do
choices+="$k\n"
Expand All @@ -222,10 +194,10 @@ done
choices=${choices::-2}

# The user chooses the action to perform via dmenu.
selected=$(_ask_dmenu -p "run:" -l "$choices")
selected=$(_ask_dmenu --prompt "run:" --list "$choices")
[[ -z $selected ]] && exit

# Execute the chosen action.
# Execute the selected action.
if [[ -v actions[$selected] ]]; then
${actions[$selected]} & exit
else
Expand Down

0 comments on commit ad17261

Please sign in to comment.