Rewrite dotsmenu script

General improvements to the quality of the code.  The script's
functionality has remained unchanged.
This commit is contained in:
Protesilaos Stavrou 2019-04-29 11:42:56 +03:00
parent 08a8d1fbae
commit 923e07b838
No known key found for this signature in database
GPG key ID: 99BD6459CD5CA3EA

View file

@ -13,72 +13,111 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Dotsmenu: a dmenu script to edit configuration files that are stored
# in a "dotfiles" directory of arbitrary depth. Opens a new terminal
# running the EDITOR on the selected file. This script is part of my
# dotfiles: https://gitlab.com/protesilaos/dotfiles.
# Dotsmenu: a dmenu script to quickly edit configuration files that are
# stored in a "dotfiles" directory. Opens a {,new }terminal running the
# EDITOR on the selected file, else defaults to the VISUAL.
#
# Part of my dotfiles: https://gitlab.com/protesilaos/dotfiles.
#
# Debian Buster dependencies:
# apt install suckless-tools fd-find
# apt install suckless-tools
#
# TODO improve documentation
# TODO review code
# TODO add feedback messages
# Optional dependencies:
# apt install fd-find notify-send libnotify-bin
# NOTE this would not work with the Xresources, Xdefaults, etc., though
# I do not use them…
if [ -d "$HOME/dotfiles" ]; then
my_dots="$HOME/dotfiles"
else
echo "ERROR"
echo "Your dotfiles are not available"
echo "ERROR: Your dotfiles are not available"
echo "Aborting"
exit 1
fi
# NOTE this would not work with the Xresources, Xdefaults, etc.. It is
# trivial to add them, though I do not use any of them…
my_configs() {
# TODO use `fdfind` as an optional dependency
# TODO use parameter expansion instead of `sed`
fdfind -H -t f '.*rc$|.*\.conf|config$' "$my_dots" | \
sed "s,$my_dots/,,g"
local my_conf
# fdfind is just easier to write, but you do not really need it
if [ "$(command -v fdfind 2> /dev/null)" ]; then
my_conf="$(fdfind -H -t f '.*rc$|.*\.conf|config$' $my_dots)"
else
# HELP can this be simplified further?
my_conf="$(find "$my_dots" -type d -name '.git' -prune -o -type f -regex ".*\(rc\|\.conf\|config\)$" -print)"
fi
# Use parameter expansion to exclude $HOME/dotfiles/ from the results
# (no need to invoke `sed`).
echo "${my_conf//$my_dots\//}" | sort
}
# Custom dmenu command. Accepts the line height as an argument.
my_dmenu() {
# Pass custom colours to dmenu command
source "$HOME/.local/share/my_colours/active-tempus-theme.sh"
local my_colours my_font menu_height
# Get the system-wide custom font, for use in dmenu
source "$HOME/.local/share/my_custom_ui_font.sh"
my_colours="$HOME/.local/share/my_colours/active-tempus-theme.sh"
my_font="$HOME/.local/share/my_custom_ui_font.sh"
source_file() {
if [ -f "$1" ]; then
source "$1"
else
echo "ERROR: Could not find active $2"
echo "Aborting"
exit 1
fi
}
source_file "$my_colours" 'Tempus theme'
source_file "$my_font" 'UI font'
if [ -n "$1" ]; then
local height="$1"
menu_height="$1"
else
local height="8"
menu_height="8"
fi
dmenu -i -p 'Edit selected file' \
-nb "$background" -nf "$foreground" -sb "$color5" \
-sf "$background" -fn "$my_custom_ui_font" -l "$height"
dmenu -i -p 'Edit selected dotfile' \
-nb "$background" -nf "$foreground" -sb "$color13" \
-sf "$background" -fn "$my_custom_ui_font" -l "$menu_height"
}
# Will send a desktop notification if the necessary command is present.
# This function accepts a single argument with the notification message.
my_notify() {
# TODO test the "$#" condition and feedback
if [ "$#" == 1 ]; then
if [ "$(command -v notify-send 2> /dev/null)" ]; then
notify-send -i applications-system "Dotsmenu" "$1"
fi
echo "$1"
else
echo "ERROR. my_notify() cannot accept multiple arguments"
echo "You passed $# arguments"
echo "Aborting"
exit 1
fi
}
# Capture the dmenu output
dotsmenu_interaction="$(my_configs | my_dmenu)"
dotsmenu_interaction="$(my_configs | my_dmenu 12)"
dotsmenu_selection="$my_dots/$dotsmenu_interaction"
# Open the selected file in the editor, else exit.
# TODO add echo messages and notify-send actions. The latter require an
# extra dependency. Add it to the description.
if [ -n "$dotsmenu_interaction" ]; then
# TODO can these be turned into a case statement or something more
# elegant?
if [ -n "$EDITOR" ]; then
"$EDITOR" "$dotsmenu_selection"
elif [ -n "$VISUAL" ]; then
my_notify "Opening selection in a separate window, using $VISUAL"
"$VISUAL" "$dotsmenu_selection"
elif [ "$(command -v gvim 2> /dev/null)" ]; then
my_notify "Opening selection in GUI Vim"
gvim "$dotsmenu_selection"
else
my_notify "Opening selection using the MIME default"
xdg-open "$dotsmenu_selection"
fi
else