changeset 1:02f6f8603d94

filesel: initial import
author David Demelier <markand@malikania.fr>
date Mon, 06 Nov 2017 13:52:32 +0100
parents 4785806e8a85
children 28f19009cbc2
files README.md dmenu_filesel
diffstat 2 files changed, 114 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/README.md	Thu Aug 18 13:44:09 2016 +0200
+++ b/README.md	Mon Nov 06 13:52:32 2017 +0100
@@ -1,4 +1,4 @@
-dmenu-scripts
+dmenutools
 =====================================================================
 
 Some scripts using [dmenu][].
@@ -6,6 +6,11 @@
 Connect your window manager keybinds to these scripts. You can also use
 [xbindkeys][].
 
+dmenu_filesel
+=============
+
+Simple file or directory selector.
+
 dmenu_mpc
 =========
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmenu_filesel	Mon Nov 06 13:52:32 2017 +0100
@@ -0,0 +1,108 @@
+#!/bin/sh
+#
+# dmenu_filesel -- prompt for a file or directory
+#
+# Copyright (c) 2016-2017 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.
+#
+
+dmt_filesel_usage()
+{
+    echo "usage: dmenu_filesel [-t file|directory]" 1>&2;
+    exit 1
+}
+
+dmt_filesel_list()
+{
+    # Allow '.' only if traget must be directory.
+    if [ "${ftype}" = "directory" ]; then
+        list=".\n"
+    fi
+    list="${list}..\n"
+
+    if [ -n "$(ls -A ${root})" ]; then
+        # TODO: Add some filters.
+        for i in ${root}*; do
+            list="${list}$(basename ${i})\n"
+        done
+    fi
+
+    echo -e ${list} | sort
+}
+
+ftype="file"
+lines="16"
+
+while getopts "l:t:" opt; do
+    case ${opt} in
+    l)
+        lines=${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}"