Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Simple Config Editor Program with Yad

I was given the opportunity to examine a cool update notifier and I was inspired to write a single-window config editor with yad.

The script

#!/usr/bin/env sh
set +e
CONFIG_FILE=~/config-editor.conf
test -e "${CONFIG_FILE}" && . "${CONFIG_FILE}" || {
   echo "File not found: ${CONFIG_FILE}. Will write a new one after making selections." 1>&2
   yad --title "File not found" --window-icon dialog-warning \
      --borders=5 --text="File not found: ${CONFIG_FILE}. \nWe will write a new one after making \nconfiguration selections in the following dialog." --center --skip-taskbar
   test $? -eq 1 && exit 0
}
config () {
   options='none!terminal!gui'
   # make the current choice the default for the drop-down listbox
   final_options="$( echo "${options}" | tr '!' '\n' | awk -v "chosen=${FRONTEND:-NONE_SELECTED}" "BEGIN{a=0} a==0 && \$0 ~ chosen{a=1;print \"^\"\$0;} \$0 "'!'"~ chosen{print} END{if(a==0 && chosen != \"NONE_SELECTED\")print \"^\"chosen;}" | tr '\n' '!' | sed -r -e 's/!$//;' )"
   results="$( yad --title="Settings" \
      --form --borders=5 \
      --window-icon=display \
      --field="Current settings\:
    Frontend\: ${FRONTEND}
    Interval\: ${INTERVAL}
Options for Front end\:
  none      Notify only.
  terminal  Do something with the terminal.
  gui       Do something with gui tool.
Interval is time to wait between notifications.
Examples: 8h for every 8 hours, 3d for every 3 days.:LBL" '' \
        --field="Front end:CB" "${final_options}" \
        --field="Interval" "${INTERVAL}" \
        --field="Additional settings are in ${CONFIG_FILE}.:LBL" '' )"
   ans="$?"
   results="$( echo "${results}" | sed -r -e "s:\|+:|:g" -e 's:^\|::' -e 's:\|$::' )"
   frontend="$( echo "${results}" | awk -F'|' '{print $1}' )"
   interval="$( echo "${results}" | awk -F'|' '{print $2}' )"
   if test "${ans}" = "1" ; then
      echo "Canceled."
      exit 0
   elif test "${FRONTEND}|${INTERVAL}" != "${frontend}|${interval}" ; then
      sed -i \
         -e "s/^FRONTEND=.*/FRONTEND=\"$frontend\"/" \
         -e "s/^INTERVAL=.*/INTERVAL=\"$interval\"/" "${CONFIG_FILE}"
      grep -qE "FRONTEND=" "${CONFIG_FILE}" 2>/dev/null || echo "FRONTEND=${frontend}" >> "${CONFIG_FILE}"
      grep -qE "INTERVAL=" "${CONFIG_FILE}" 2>/dev/null || echo "INTERVAL=${interval}" >> "${CONFIG_FILE}"
   else
      echo "No changes from current config."
   fi
}
config

Walkthrough

The config file is defined as a variable, and then it is dot-sourced into the current working environment. This will allow the values to be loaded and used by the dialog.

You can see from the two fields in the "Current settings" help text that this is a very simple config file. This program has all sorts of opportunities for expansion. And obviously the "options" being set to a specific hardcoded list of options could be parameterized or even loaded from declarative comments in the config file if you wanted to get really fancy!

The logic at the end (starting at line 41) compares the desired config with the current values. If they are different, it will make the changes and add each variable if not defined in the file already. If the desired config is already the configured values, it will not touch the file.

Additional reading

Comments