changeset 20:370213df9449

misc: start rewrite in C++
author David Demelier <markand@malikania.fr>
date Thu, 26 Apr 2018 13:23:44 +0200
parents ea81d5b2c72e
children 38d927bed5c3
files .hgignore CMakeLists.txt INSTALL.md Makefile TODO.md bin/dmenu_bg bin/dmenu_filesel bin/dmenu_mpc bin/dmenu_power bin/dmenu_ssh dmenu-background/CMakeLists.txt dmenu-background/main.cpp doc/dmenu_bg.md doc/dmenu_filesel.md doc/dmenu_mpc.md doc/dmenu_power.md doc/dmenu_ssh.md doc/dmenutools.md libdmenutools/CMakeLists.txt libdmenutools/dmenu/dmenu.cpp libdmenutools/dmenu/dmenu.hpp libdmenutools/dmenu/ini.cpp libdmenutools/dmenu/ini.hpp libdmenutools/dmenu/xdg.hpp libexec/dmenutools/dmenu.subr
diffstat 25 files changed, 1674 insertions(+), 1031 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Jan 02 13:27:42 2018 +0100
+++ b/.hgignore	Thu Apr 26 13:23:44 2018 +0200
@@ -1,6 +1,13 @@
-# ctags & vim.
-tags
+# Build directory used in lots of documentation.
+^build
+
+# Qt Creator creates CMakeLists.txt.user.
+^CMakeLists\.txt\.user$
+
+# vim/emacs specific.
+^tags$
 \.swp$
+\.swo$
 
-# manuals.
-\.1$
+# macOS specific.
+\.DS_Store$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CMakeLists.txt	Thu Apr 26 13:23:44 2018 +0200
@@ -0,0 +1,28 @@
+#
+# CMakeLists.txt -- CMake build system for dmenutools
+#
+# Copyright (c) 2018 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+cmake_minimum_required(VERSION 3.5)
+project(dmenutools)
+
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED On)
+
+find_package(Boost REQUIRED COMPONENTS filesystem system)
+
+add_subdirectory(libdmenutools)
+add_subdirectory(dmenu-background)
--- a/INSTALL.md	Tue Jan 02 13:27:42 2018 +0100
+++ b/INSTALL.md	Thu Apr 26 13:23:44 2018 +0200
@@ -6,19 +6,20 @@
 Requirements
 ------------
 
-  - POSIX compatible shell,
-  - Pandoc for the documentation.
+  - Boost,
+  - CMake.
+
+For `dmenu-background`:
+
+  - feh (by default, can be changed)
 
 Basic installation
 ------------------
 
-Add the **bin/** directory to your path or you can install the scripts using
-`make install` target as root.
+Invoke CMake, make and make install.
 
-An additional variable `PREFIX` can be set to specify the installation
-directory.
-
-Examples:
-
-	make install			# install to /usr/local/bin
-	make install PREFIX=/	# install to /bin
+    mkdir build
+    cd build
+    cmake .. -DCMAKE\_BUILD\_TYPE=Release
+    make
+    sudo make install
--- a/Makefile	Tue Jan 02 13:27:42 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#
-# Copyright (c) 2017-2018 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-PREFIX=/usr/local
-MANDIR=share/man
-DOCSRC=	doc/dmenu_bg.md		\
-	doc/dmenu_filesel.md	\
-	doc/dmenu_mpc.md	\
-	doc/dmenu_power.md	\
-	doc/dmenu_ssh.md	\
-	doc/dmenutools.md
-DOCOBJ=	${DOCSRC:.md=.1}
-
-all: docs
-
-%.1: %.md
-	@echo "  MAN $@"
-	@pandoc -s -f markdown -t man $< -o $@
-
-docs: ${DOCOBJ}
-
-install: ${DOCOBJ}
-	@install -D -m 0644 doc/dmenutools.1 ${PREFIX}/${MANDIR}/man1
-	@install -D -m 0644 libexec/dmenutools/dmenu.subr ${PREFIX}/libexec/dmenutools/dmenu.subr
-	@echo "  INSTALL dmenu_bg"
-	@install -D -m 0755 bin/dmenu_bg ${PREFIX}/bin
-	@install -D -m 0644 doc/dmenu_bg.1 ${PREFIX}/${MANDIR}/man1
-	@echo "  INSTALL dmenu_filesel"
-	@install -D -m 0755 bin/dmenu_filesel ${PREFIX}/bin
-	@install -D -m 0644 doc/dmenu_filesel.1 ${PREFIX}/${MANDIR}/man1
-	@echo "  INSTALL dmenu_mpc"
-	@install -D -m 0755 bin/dmenu_mpc ${PREFIX}/bin
-	@install -D -m 0644 doc/dmenu_mpc.1 ${PREFIX}/${MANDIR}/man1
-	@echo "  INSTALL dmenu_power"
-	@install -D -m 0755 bin/dmenu_power ${PREFIX}/bin
-	@install -D -m 0644 doc/dmenu_power.1 ${PREFIX}/${MANDIR}/man1
-	@echo "  INSTALL dmenu_ssh"
-	@install -D -m 0755 bin/dmenu_ssh ${PREFIX}/bin
-	@install -D -m 0644 doc/dmenu_ssh.1 ${PREFIX}/${MANDIR}/man1
-
-
-clean:
-	@rm -f ${DOCOBJ}
--- a/TODO.md	Tue Jan 02 13:27:42 2018 +0100
+++ b/TODO.md	Thu Apr 26 13:23:44 2018 +0200
@@ -3,17 +3,12 @@
 
 List of things to improve or add.
 
-filesel
--------
+libdmenutools
+-------------
 
-  - Avoid using temporary files for listing if possible.
+  - Create convenient and powerful `dmenu::browse` API.
 
-mpc
----
-
-  - Remove temporary file for error reporting.
+New tools
+---------
 
-dmenu.subr
-----------
-
-  - Make dmt_fatal able to read from stdin.
+  - `dmenu-mpc`
--- a/bin/dmenu_bg	Tue Jan 02 13:27:42 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-#!/bin/sh
-#
-# dmenu_bg -- prompt for a background
-#
-# Copyright (c) 2017-2018 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="bg"
-TOP=$(dirname "$(readlink -f "$0")")
-
-dmt_bg_usage()
-{
-    echo "usage: dmenu_bg [directory]" 1>&2;
-    exit 1
-}
-
-. ${TOP}/../libexec/dmenutools/dmenu.subr
-
-# Check for an optional directory.
-if [ $# -ge 1 ]; then
-    directory="$1"
-elif [ -n "${bg_directory}" ]; then
-    directory="${bg_directory}"
-else
-    directory="${XDG_PICTURES_DIR:-${HOME}}"
-fi
-
-# Use user bg_cmd if defined, otherwise find one.
-if [ -z "${bg_cmd}" ]; then
-    if command -v feh > /dev/null 2>&1; then
-        bg_cmd="feh --bg-scale"
-    elif command -v hsetroot > /dev/null 2>&1; then
-        bg_cmd="hsetroot -fill"
-    elif command -v fbsetbg > /dev/null 2>&1; then
-        bg_cmd="fbsetbg"
-    else
-        dmt_fatal "no background manager found"
-        # NOTREACHED
-    fi
-fi
-
-# Optional lines.
-lines=${bg_lines:-16}
-
-file=$(${TOP}/dmenu_filesel -t f -l ${lines} -p "(jpe?g|png|gif)" ${directory})
-
-if [ -n "${file}" ]; then
-    ${bg_cmd} "${file}"
-fi
-
-# vim: syntax=sh:
--- a/bin/dmenu_filesel	Tue Jan 02 13:27:42 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-#!/bin/sh
-#
-# dmenu_filesel -- prompt for a file or directory
-#
-# Copyright (c) 2017-2018 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="filesel"
-TOP=$(dirname "$(readlink -f "$0")")
-
-dmt_filesel_usage()
-{
-    echo "usage: dmenu_filesel [-t file|directory]" 1>&2;
-    exit 1
-}
-
-dmt_filesel_list()
-{
-	list="/tmp/dmenutools-$(id -u).filesel_list.txt"
-	result="/tmp/dmenutools-$(id -u).filesel_result.txt"
-
-    # Allow '.' only if traget must be directory.
-    if [ "${ftype}" = "directory" ]; then
-		echo "." > ${result}
-    fi
-
-	echo ".." >> ${result}
-
-	# Avoid basename error in case of empty directories.
-    if [ -n "$(ls -A "${root}")" ]; then
-		find "${root}" -mindepth 1 -maxdepth 1 > ${list}
-
-		# Update the result list.
-		cat ${list} | while read n; do
-			keep=1
-
-			# Check for optional pattern
-			if [ -f "$n" ] && [ -n "${pattern}" ] && ! (echo $n | egrep -q "${pattern}"); then
-				keep=0
-			fi
-
-			if [ ${keep} -eq 1 ]; then
-				echo $(basename "$n") >> ${result}
-			fi
-		done
-    fi
-
-	cat ${result} | sort
-	rm -f ${result} ${list}
-}
-
-ftype="file"
-lines="16"
-
-while getopts "il:t:p:" opt; do
-    case ${opt} in
-    l)
-        lines=${OPTARG}
-        ;;
-	p)
-		pattern="${OPTARG}"
-		;;
-    t)
-        if [ "${OPTARG}" = "f" ] || [ "${OPTARG}" = "file" ]; then
-            ftype="file"
-        elif [ "${OPTARG}" = "d" ] || [ "${OPTARG}" = "directory" ]; then
-            ftype="directory"
-        fi
-        ;;
-    *)
-        dmt_filesel_usage
-        # NOTREACHED
-    esac
-done
-
-shift $((OPTIND - 1))
-
-# Start from here.
-if [ $# -ge 1 ]; then
-    root="${1}/"
-else
-    root="/"
-fi
-
-while [ -z "${selection}" ]; do
-    entry="$(dmt_filesel_list | dmenu -p "${root}" -l ${lines})"
-
-    # Abort on empty selection.
-    if [ -z "${entry}" ]; then
-        exit 1
-    fi
-
-    if [ "${entry}" = ".." ]; then
-        parent="$(dirname "${root}")"
-
-        if [ "${parent}" = "/" ]; then
-            root="/"
-        else
-            root="${parent}/"
-        fi
-
-        continue;
-    fi
-
-    # If directory, goes deeper.
-    path="${root}${entry}"
-
-    if [ -d "${path}" ]; then
-        if [ -r "${path}" ]; then
-            root="${path}/"
-        else
-            continue
-        fi
-    else
-        selection="${path}"
-    fi
-done
-
-echo "${selection}"
--- a/bin/dmenu_mpc	Tue Jan 02 13:27:42 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-#!/bin/sh
-#
-# dmenu_mpc -- convenient mpc module
-#
-# Copyright (c) 2017-2018 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="filesel"
-TOP=$(dirname "$(readlink -f "$0")")
-
-. ${TOP}/../libexec/dmenutools/dmenu.subr
-
-if [ -z "${MPD_HOST}" ] && [ -n "${mpc_host}" ]; then
-	export MPD_HOST="${mpc_host}"
-fi
-if [ -z "${MPD_PORT}" ] && [ -n "${mpc_port}" ]; then
-	export MPD_PORT="${mpc_port}"
-fi
-
-#
-# Get the list of files or directories.
-#
-# Arguments:
-#	- base, the optional base component path.
-#
-dmt_mpc_list()
-{
-	path="/tmp/dmenutools-$(id -u).mpc_list.txt"
-
-	echo "." > "${path}"
-
-	if [ -n "$1" ]; then
-		echo ".." >> "${path}"
-	fi
-
-	list=$(mpc ls "$1" >> "${path}" 2> /dev/null)
-
-	if [ $? -eq 0 ]; then
-		cat ${path} | while read n; do
-			basename "$n"
-		done
-	fi
-
-	rm -f "${path}" > /dev/null 2>&1
-}
-
-#
-# Select a file using dmt_mpc_list in successive dmenu calls.
-#
-dmt_mpc_select()
-{
-	while [ -z "${selection}" ]; do
-		entry="$(dmt_mpc_list "${root}" | dmenu -p "${root}" -l 16)"
-
-		# Abort on empty selection.
-		if [ -z "${entry}" ]; then
-			exit 1
-		fi
-
-		if [ "${entry}" = ".." ]; then
-			parent="$(dirname "${root}")"
-
-			if [ "${parent}" = "." ]; then
-				root=""
-			else
-				root="${parent}"
-			fi
-
-			continue;
-		elif [ "${entry}" = "." ]; then
-			selection="${root}"
-		else
-			#
-			# Selection, in that case we check if the selection is a directory
-			# or a file by checking if the mpc ls on the selection returns
-			# more than one row. This is not the best but I can't find a better
-			# solution at the moment.
-			#
-
-			# Convert to absolute.
-			if [ -n "${root}" ]; then
-				entry="${root}/${entry}"
-			fi
-
-			list=$(mpc ls "${entry}")
-
-			if [ "${entry}" != "${list}" ]; then
-				root="${entry}"
-			else
-				selection="${entry}"
-			fi
-		fi
-	done
-
-	echo "${selection}"
-}
-
-#
-# Wrap a mpc command and execute dmt_fatal in case of errors.
-#
-dmt_mpc_run()
-{
-	path="/tmp/dmenutools-$(id -u).err"
-
-	if ! mpc "$@" > /dev/null 2> "${path}"; then
-		dmt_fatal "$(cat ${path})"
-		exit 1
-	fi
-}
-
-#
-# Echo all menu entries.
-#
-dmt_mpc_menu()
-{
-	echo "add..."
-	echo ""
-	echo "previous"
-	echo "next"
-	echo ""
-	echo "play"
-	echo "pause"
-	echo "stop"
-	echo "clear"
-	echo ""
-	echo "toggle consume"
-	echo "toggle repeat"
-	echo "shuffle queue"
-	echo ""
-	echo "update database"
-}
-
-cmd=$(dmt_mpc_menu | dmenu -p mpd -l 16)
-
-case ${cmd} in
-add*)
-	select="$(dmt_mpc_select)"
-
-	if [ -n "${select}" ]; then
-		dmt_mpc_run add "${select}"
-	fi
-	;;
-previous)
-	dmt_mpc_run prev
-	;;
-next)
-	dmt_mpc_run next
-	;;
-play)
-	dmt_mpc_run play
-	;;
-pause)
-	dmt_mpc_run pause
-	;;
-stop)
-	dmt_mpc_run stop
-	;;
-clear)
-	dmt_mpc_run clear
-	;;
-"toggle consume")
-	dmt_mpc_run consume
-	;;
-"toggle repeat")
-	dmt_mpc_run repeat
-	;;
-shuffle*)
-	dmt_mpc_run shuffle
-	;;
-update*)
-	dmt_mpc_run update
-	;;
-esac
--- a/bin/dmenu_power	Tue Jan 02 13:27:42 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-#!/bin/sh
-#
-# dmenu_power -- dmenu prompt for system shutdown
-#
-# Copyright (c) 2017-2018 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-TOOL="power"
-TOP=$(dirname "$(readlink -f "$0")")
-
-. ${TOP}/../libexec/dmenutools/dmenu.subr
-
-# Default user values.
-: "${power_hibernate_enable:=1}"
-: "${power_reboot_enable:=1}"
-: "${power_shutdown_enable:=1}"
-: "${power_suspend_enable:=1}"
-
-os=$(uname -s)
-
-# Check for systemctl on Linux.
-if command -v systemctl > /dev/null 2>&1; then
-    has_systemctl=1
-fi
-
-#
-# Create a list of commands.
-# -------------------------------------------------------------------
-#
-dmt_power_list()
-{
-    for i in hibernate reboot shutdown suspend; do
-        eval enabled="\${power_${i}_enable}"
-
-        if [ ${enabled} -eq 1 ]; then
-            list="${list}$i\n"
-        fi
-    done
-
-    echo -e $(echo ${list} | sed -e s'/\\n$//')
-}
-
-#
-# Do hibernation
-# -------------------------------------------------------------------
-#
-# Supports: Linux, OpenBSD
-#
-dmt_power_hibernate()
-{
-    if [ -n "${power_hibernate_cmd}" ]; then
-        ${power_hibernate_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl hibernate
-    else
-        case "${os}" in
-        Linux)
-            echo 'disk' | sudo -A tee -a /sys/power/state
-            ;;
-        OpenBSD)
-            ZZZ
-            ;;
-        *)
-            dmt_fatal "hibernation not supported on this system"
-            ;;
-        esac
-    fi
-}
-
-#
-# Do reboot
-# -------------------------------------------------------------------
-#
-# Supports: all
-#
-dmt_power_reboot()
-{
-    if [ -n "${power_reboot_cmd}" ]; then
-        ${power_reboot_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl reboot
-    else
-        sudo -A shutdown -r now
-    fi
-}
-
-#
-# Do shutdown
-# -------------------------------------------------------------------
-#
-# Supports: all
-#
-dmt_power_shutdown()
-{
-    if [ -n "${power_shutdown_cmd}" ]; then
-        ${power_shutdown_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl poweroff
-    else
-        case ${os} in
-        Linux)
-            sudo -A shutdown -h now
-            ;;
-        *)
-            sudo -A shutdown -p now
-            ;;
-        esac
-    fi
-}
-
-#
-# Do suspend
-# -------------------------------------------------------------------
-#
-# Supports: Linux, OpenBSD, FreeBSD (if has not been broken in a new release).
-#
-dmt_power_suspend()
-{
-    if [ -n "${power_suspend_cmd}" ]; then
-        ${power_suspend_cmd}
-    elif [ "${has_systemctl}" -eq 1 ]; then
-        systemctl suspend
-    else
-        case "${os}" in
-        Linux)
-            echo 'mem' | sudo -A tee -a /sys/power/state
-            ;;
-        FreeBSD)
-            # Good luck.
-            sudo -A acpiconf -s 3
-            ;;
-        OpenBSD)
-            zzz
-            ;;
-        *)
-            dmt_fatal "suspend not supported on this system"
-            ;;
-        esac
-    fi
-}
-
-cmd=$(dmt_power_list | dmenu -p "power")
-
-# TODO: change this with a substitution.
-case "${cmd}" in
-hibernate)
-    dmt_power_hibernate
-    ;;
-reboot)
-    dmt_power_reboot
-    ;;
-shutdown)
-    dmt_power_shutdown
-    ;;
-suspend)
-    dmt_power_suspend</