Add more dmenu scripts
This commit is contained in:
76
dotfiles/.local/bin/dmenu-bookmarks
Executable file
76
dotfiles/.local/bin/dmenu-bookmarks
Executable file
@@ -0,0 +1,76 @@
|
||||
#! /bin/bash
|
||||
|
||||
# set prefered launcher
|
||||
PREFERED_LAUNCHER=dmenu
|
||||
# set path where urls will be stored
|
||||
URL_FILE_PATH=$HOME/dotfiles/bookmarks
|
||||
# name of file urls will be stored in
|
||||
URL_FILE_NAME=urls
|
||||
|
||||
show_usage() {
|
||||
printf "bmks: unix bookmark management that sucks less
|
||||
|
||||
usage:
|
||||
bmks help
|
||||
show this help message
|
||||
bmks add <url>
|
||||
add a new bookmark
|
||||
bmks del
|
||||
remove a bookmark
|
||||
bmks ls
|
||||
show all bookmarks
|
||||
bmks dmenu
|
||||
manual switch for displaying bookmarks in dmenu
|
||||
bmks fzf
|
||||
manual switch for displaying bookmarks in fzf
|
||||
|
||||
Configuration is done by directly editing the script. Two launchers are available (dmenu and fzf). You can specify which one to use by adding to the PREFERED_LAUNCHER variable directly in the script. Both will display a menu that will allow you to choose a bookmark and open it in your default browser.
|
||||
|
||||
If you would prefer to have your bookmarks stored in alternate location there are also variables that can be changed for that. The default is /home/user/.bmks/urls\n"
|
||||
}
|
||||
|
||||
bmks_add() {
|
||||
[ -z "$url" ] && printf "Error: url must be provided\n\n" && show_usage && exit 0
|
||||
printf "Description: "
|
||||
read description
|
||||
[ -z "$description" ] && echo "$url" >> $URL_FILE_PATH/$URL_FILE_NAME
|
||||
[ -n "$description" ] && echo "$description - $url" >> $URL_FILE_PATH/$URL_FILE_NAME
|
||||
}
|
||||
|
||||
bmks_ls() {
|
||||
bmks_check
|
||||
cat $URL_FILE_PATH/$URL_FILE_NAME | sort
|
||||
}
|
||||
|
||||
bmks_del() {
|
||||
bmks_check
|
||||
case $PREFERED_LAUNCHER in
|
||||
dmenu) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -l $(cat $URL_FILE_PATH/$URL_FILE_NAME | wc -l))/d" $URL_FILE_PATH/$URL_FILE_NAME ;;
|
||||
fzf) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf)/d" $URL_FILE_PATH/$URL_FILE_NAME ;;
|
||||
esac
|
||||
}
|
||||
|
||||
bmks_display() {
|
||||
bmks_check
|
||||
case $PREFERED_LAUNCHER in
|
||||
dmenu) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -l $(cat $URL_FILE_PATH/$URL_FILE_NAME | wc -l) | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;;
|
||||
fzf) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;;
|
||||
esac
|
||||
}
|
||||
|
||||
bmks_check() {
|
||||
[ ! -s $URL_FILE_PATH/$URL_FILE_NAME ] && printf "Error: No bookmarks found to display. Try adding some!\n\n" && show_usage && exit 0
|
||||
}
|
||||
|
||||
[ ! -d $URL_FILE_PATH ] && mkdir $URL_FILE_PATH
|
||||
[ ! -f $URL_FILE_PATH/$URL_FILE_NAME ] && touch $URL_FILE_PATH/$URL_FILE_NAME
|
||||
|
||||
case "$1" in
|
||||
"help") show_usage ;;
|
||||
"add") url=$2; bmks_add ;;
|
||||
"del") bmks_del ;;
|
||||
"ls") bmks_ls ;;
|
||||
"dmenu") PREFERED_LAUNCHER=$1; bmks_display ;;
|
||||
"fzf") PREFERED_LAUNCHER=$1; bmks_display ;;
|
||||
*) bmks_display ;;
|
||||
esac
|
||||
324
dotfiles/.local/bin/dmenu-fm
Executable file
324
dotfiles/.local/bin/dmenu-fm
Executable file
@@ -0,0 +1,324 @@
|
||||
#!/bin/sh
|
||||
|
||||
PROGRAM_NAME=$(basename $0) # This will be used in a few messages
|
||||
|
||||
main() {
|
||||
parse_opts "$@"
|
||||
[ -z "$mode" ] && mode=open # The default mode
|
||||
|
||||
if [ -n "$copy" -a "$copy" != false -a "$cat" = true ]; then
|
||||
prompt_copy_contents "$@"
|
||||
elif [ "$open" = true ]; then
|
||||
prompt_open "$@"
|
||||
elif [ "$cat" = true ]; then
|
||||
prompt_print_contents "$@"
|
||||
elif [ "$print" = true ]; then
|
||||
prompt_print "$@"
|
||||
elif [ -n "$copy" -a "$copy" != false ]; then
|
||||
prompt_copy "$@"
|
||||
else
|
||||
prompt_$mode "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_base() {
|
||||
[ -z "$length" ] && length=10
|
||||
|
||||
if [ "$case_sensitivity" = sensitive ]; then
|
||||
backtrack() { sed 's|\(.*/'$sel'[^/]*\).*|\1|'; }
|
||||
s=+i
|
||||
else
|
||||
backtrack() { perl -pe 's|(.*/'$sel'[^/]*).*|$1|i'; }
|
||||
i=-i
|
||||
fi
|
||||
|
||||
[ -z "$menu" ] && menu="dmenu"
|
||||
if [ "$menu" = dmenu ]; then menu() { $menu $i -l $length -p "$@"; }
|
||||
elif [ "$menu" = fzf ]; then menu() { $menu $s $i --header="$@"; }
|
||||
else menu() { $menu; }; fi
|
||||
|
||||
if [ "$path" = "full" ]; then prompt() { p="$target"; }
|
||||
else prompt() { p="$(printf '%s' "$target" | sed 's|^'"$HOME"'|~|')"; }; fi
|
||||
|
||||
# Only GNU `ls` supports `--group-directories-first`
|
||||
if [ "$(ls --version | head -1 | cut -d " " -f 2-3)" = "(GNU coreutils)" ]
|
||||
then
|
||||
list() { ls --group-directories-first "$@"; }
|
||||
else
|
||||
list() {
|
||||
(ls -l "$@" | grep "^d"
|
||||
ls -l "$@" | grep -vE "^d|^total") | tr -s " " | cut -d " " -f 9-
|
||||
}
|
||||
fi
|
||||
|
||||
# Commonly used functions in DFM
|
||||
truepath() { sh -c "realpath -s "$sel""; }
|
||||
slash() { printf '%s' "$target/$sel" | rev | cut -b 1-2; }
|
||||
check() { file -E "$@" | grep "(No such file or directory)$"; }
|
||||
fullcmd() {
|
||||
printf '%s\n' "$PWD" > "$cache_file"
|
||||
printf '%s' "$target" | sed -e "s/'/'\\\\''/g;s/\(.*\)/'\1'/" | cmd
|
||||
}
|
||||
|
||||
while true; do
|
||||
p="$prompt" # Reset the prompt to have it update
|
||||
[ -z "$p" ] && prompt # Make the prompt if it does not exist
|
||||
|
||||
# This is where the file manager actually first opens.
|
||||
sel="$(printf '%s' "$(list "$target"; list -A "$target" | grep '^\.')" |
|
||||
menu "$p")"
|
||||
|
||||
# Exit if the user presses Escape, Control-C, etc.
|
||||
exit_code=$?
|
||||
if [ "$exit_code" -ne 0 ]; then
|
||||
printf '%s\n' "$target" > "$cache_file"
|
||||
exit $exit_code
|
||||
fi
|
||||
|
||||
if [ $(printf '%s' "$sel" | wc -l) -eq 0 ]; then
|
||||
# If the input box is empty, go to the parent directory
|
||||
if [ "$sel" = "" ]; then
|
||||
newt="$(realpath -s "$target/..")"
|
||||
# Relative directories
|
||||
elif [ -e "$target/$sel" -a "$(slash)" != // ]; then
|
||||
newt="$(realpath -s "$target/$sel")"
|
||||
elif [ ! -e "$target/$sel" -a $(printf '%s' "$target" |
|
||||
grep $i "$(sh -c "printf '%s' "$sel"")" | wc -l) -eq 1 ]
|
||||
then
|
||||
# Go to a lower directory using the input box
|
||||
if [ ! -e "$(truepath)" ]; then
|
||||
newt="$(printf '%s' "$target" | backtrack)"
|
||||
# Go to certain directories like `~` `$HOME`, etc.
|
||||
else
|
||||
newt="$(truepath)"
|
||||
fi
|
||||
# Go to a directory when the input box begins with `/`
|
||||
elif [ -e "$(truepath)" ] &&
|
||||
[ ! -e "$target/$sel" -o "$(slash)" = "//" ]
|
||||
then
|
||||
newt="$(truepath)"
|
||||
else
|
||||
# This applies to wildcards
|
||||
newt="$(realpath -s "$target/$sel")"
|
||||
fi
|
||||
else
|
||||
newt="$sel"
|
||||
fi
|
||||
|
||||
# If the current working directory is not empty
|
||||
if [ $(ls | wc -l) -ge 1 ]; then
|
||||
target="$newt"
|
||||
if [ ! -d "$target" ]; then
|
||||
# Check if the user used a wildcard
|
||||
if [ $(printf '%s' "$target" | grep "*" | wc -l) -ge 1 -a\
|
||||
$(check "$target" | wc -l) -eq 1 ]
|
||||
then
|
||||
IFS= # Needed to make wildcards work
|
||||
ls "$PWD"/$sel 1> /dev/null 2>& 1
|
||||
# Target is a file or directory
|
||||
if [ $? -ne 0 ]; then
|
||||
target="$PWD"
|
||||
# Target is a wildcard
|
||||
else
|
||||
target=$(ls -d "$PWD"/$sel) fullcmd
|
||||
exit 0
|
||||
fi
|
||||
# No such file or directory
|
||||
elif [ $(printf '%s' "$target" | wc -l) -eq 0 -a\
|
||||
$(check "$target" | wc -l) -eq 1 ]
|
||||
then
|
||||
target="$PWD"
|
||||
# More than one selection
|
||||
elif [ $(printf '%s' "$target" | wc -l) -gt 0 ]; then
|
||||
target=$(printf '%s' "$target" | sed 's|^|'"$PWD"/'|')
|
||||
fullcmd
|
||||
exit
|
||||
# Exactly one selection
|
||||
else
|
||||
fullcmd
|
||||
exit
|
||||
fi
|
||||
# Target is a directory
|
||||
else
|
||||
PWD="$target"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
prompt_print() {
|
||||
cmd () { xargs ls -d; }
|
||||
prompt_base "$@"
|
||||
}
|
||||
|
||||
prompt_print_contents() {
|
||||
cmd() { xargs cat; }
|
||||
prompt_base "$@"
|
||||
}
|
||||
|
||||
prompt_open() {
|
||||
if [ -x "$(command -v sesame)" ]; then cmd() { xargs sesame; }
|
||||
else cmd() { xargs xdg-open; }; fi
|
||||
prompt_base "$@"
|
||||
}
|
||||
|
||||
prompt_copy() {
|
||||
cmd() { tr '\n' ' ' | xclip -r -i -selection $copy; }
|
||||
prompt_base "$@"
|
||||
}
|
||||
|
||||
prompt_copy_contents() {
|
||||
if [ "$(file -b "$target" | cut -d " " -f2)" = "image" ]; then
|
||||
cmd() { xargs xclip -i -selection $copy -t image/png; }
|
||||
else
|
||||
cmd() { xargs xclip -r -i -selection $copy; }
|
||||
fi
|
||||
prompt_base "$@"
|
||||
}
|
||||
|
||||
help() {
|
||||
printf "Usage:\t$0 [options] [target] [prompt]
|
||||
|
||||
Options:
|
||||
|
||||
Modes:
|
||||
-p|--print │ Print the output of the selection
|
||||
-o|--open │ Open the appropriate program for the selection (default)
|
||||
|
||||
--cat │ Concatenate the selections before using a mode
|
||||
-c|--copy=[CLIPBOARD] │ Copy the output of the selection
|
||||
--no-copy │ Do not copy (always overrides \`--copy\`)
|
||||
│
|
||||
-r|--restore │ Start from the previous path restored from the last run
|
||||
-s|--sensitive │ Use case-sensitive matching
|
||||
-i|--insensitive │ Use case-insensitive matching (default)
|
||||
-m|--menu=MENU │ Choose which menu program to use (default: dmenu)
|
||||
-l|--length=LENGTH │ Specify the length of dmenu (default: 10)
|
||||
│
|
||||
-f|--full │ Use the full path for the prompt
|
||||
-a|--abbreviated │ Use the abbreviated path for the prompt (default)
|
||||
│
|
||||
-h|--help │ Print this help message and exit
|
||||
"; }
|
||||
|
||||
parse_opts() {
|
||||
: "${config_dir:=${XDG_CONFIG_HOME:-$HOME/.config}/$PROGRAM_NAME}"
|
||||
: "${config_file:=$config_dir/$PROGRAM_NAME.conf}"
|
||||
[ -f "$config_file" ] && . "$config_file"
|
||||
|
||||
: "${cache_dir:=${XDG_CACHE_DIR:-$HOME/.cache}/$PROGRAM_NAME}"
|
||||
: "${cache_file:=$cache_dir/path}"
|
||||
# Create the cache file if it doesn't exist
|
||||
if [ ! -f "$cache_file" ]; then
|
||||
mkdir -p "$(dirname "$cache_file")" &&
|
||||
touch "$cache_file"
|
||||
fi
|
||||
|
||||
needs_arg() {
|
||||
if [ -z "$OPTARG" ]; then
|
||||
printf '%s\n' "No arg for --$OPT option" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
while getopts hpcosim:l:far-: OPT; do
|
||||
# Support long options: https://stackoverflow.com/a/28466267/519360
|
||||
if [ "$OPT" = "-" ]; then
|
||||
OPT="${OPTARG%%=*}"
|
||||
OPTARG="${OPTARG#$OPT}"
|
||||
OPTARG="${OPTARG#=}"
|
||||
fi
|
||||
case "$OPT" in
|
||||
h|help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
p|print)
|
||||
print=true
|
||||
;;
|
||||
c|copy)
|
||||
shift
|
||||
[ $(printf '%s' "$OPT" | wc -c) -eq 1 ] && OPTARG="$1"
|
||||
case "$OPTARG" in
|
||||
primary|secondary|clipboard|buffer-cut)
|
||||
copy="$OPTARG"
|
||||
;;
|
||||
*)
|
||||
copy=clipboard
|
||||
;;
|
||||
esac
|
||||
[ -n "$1" -a "$OPTARG" = "$1" -a "$copy" = "$OPTARG" ] && shift
|
||||
;;
|
||||
no-copy)
|
||||
copy=false
|
||||
;;
|
||||
cat)
|
||||
cat=true
|
||||
;;
|
||||
o|open)
|
||||
open=true
|
||||
;;
|
||||
s|sensitive)
|
||||
case_sensitivity="sensitive"
|
||||
;;
|
||||
i|insensitive)
|
||||
case_sensitivity="insensitive"
|
||||
;;
|
||||
m|menu)
|
||||
needs_arg
|
||||
menu="$OPTARG"
|
||||
;;
|
||||
l|length)
|
||||
needs_arg
|
||||
length=$OPTARG
|
||||
;;
|
||||
f|full)
|
||||
path="full"
|
||||
;;
|
||||
a|abbreviated)
|
||||
path="abbreviated"
|
||||
;;
|
||||
r|restore)
|
||||
restore=true
|
||||
;;
|
||||
??*)
|
||||
printf '%s\n' "Illegal option --$OPT" >&2
|
||||
exit 2
|
||||
;;
|
||||
?) # Error reported via `getopts`
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1)) # Remove option arguments from the argument list
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
target="$1"
|
||||
elif [ -z "$target" ]; then
|
||||
if [ "$restore" = true -a -s "$cache_file" ]; then
|
||||
target="$(cat "$cache_file")"
|
||||
else
|
||||
target="$PWD"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$target" ]; then
|
||||
target="$(realpath -s "$target")"
|
||||
PWD="$target"
|
||||
else
|
||||
# Zero out cache file.
|
||||
[ "$restore" = true -a -s "$cache_file" ] && > "$cache_file"
|
||||
printf '%s\n' "$PROGRAM_NAME: \`$target\` is not a directory." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
[ -n "$2" ] && prompt="$2"
|
||||
# If the prompt is the same as the target, uset the prompt so that it can
|
||||
# update. This is useful if you set a prompt in your configuration file but
|
||||
# want to use the default prompt
|
||||
if [ -n "$prompt" ] && [ "$(realpath -s "$prompt")" = "$target" ]; then
|
||||
unset prompt
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
script_path="$HOME/.local/bin"
|
||||
|
||||
prompt="-p Menus:"
|
||||
|
||||
# list only executable non-binay files
|
||||
|
||||
run_dmenu="$(find $script_path/dmenu-* -maxdepth 1 -type f -executable \
|
||||
-exec grep -Iq . {} \; -print \
|
||||
| sed 's|^'$script_path/'||' \
|
||||
| sort \
|
||||
| dmenu $prompt)"
|
||||
|
||||
eval "$script_path/$run_dmenu"
|
||||
|
||||
exit 0
|
||||
76
dotfiles/.local/bin/dmenu-mpdmenu
Executable file
76
dotfiles/.local/bin/dmenu-mpdmenu
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
all_name='[ALL]'
|
||||
mode=library
|
||||
|
||||
d_artist() {
|
||||
mpc list artist | sort -f | dmenu -p artist "${dmenu_args[@]}"
|
||||
}
|
||||
|
||||
d_album() {
|
||||
local artist="$1"
|
||||
local albums
|
||||
|
||||
mapfile -t albums < <(mpc list album artist "$artist")
|
||||
if (( ${#albums[@]} > 1 )) ; then
|
||||
{
|
||||
printf '%s\n' "$all_name"
|
||||
printf '%s\n' "${albums[@]}" | sort -f
|
||||
} | dmenu -p album "${dmenu_args[@]}"
|
||||
else
|
||||
# We only have one album, so just use that.
|
||||
printf '%s\n' "${albums[0]}"
|
||||
fi
|
||||
}
|
||||
|
||||
d_playlist() {
|
||||
local format="%position% %title%"
|
||||
local extra_format="(%artist% - %album%)"
|
||||
local track
|
||||
local num_extras
|
||||
|
||||
# If all tracks are from the same artist and album, no need to display that
|
||||
num_extras=$(mpc playlist -f "$extra_format" | sort | uniq | wc -l)
|
||||
(( num_extras == 1 )) || format+=" $extra_format"
|
||||
|
||||
track=$(mpc playlist -f "$format" | dmenu -p track "${dmenu_args[@]}")
|
||||
printf '%s' "${track%% *}"
|
||||
}
|
||||
|
||||
i=2
|
||||
|
||||
for arg do
|
||||
if [[ $arg == :: ]]; then
|
||||
dmenu_args=( "${@:$i}" )
|
||||
break
|
||||
fi
|
||||
|
||||
case "$arg" in
|
||||
-l) mode=library ;;
|
||||
-p) mode=playlist ;;
|
||||
esac
|
||||
|
||||
let i++
|
||||
done
|
||||
|
||||
case "$mode" in
|
||||
library)
|
||||
artist=$(d_artist)
|
||||
[[ $artist ]] || exit 1
|
||||
|
||||
album=$(d_album "$artist")
|
||||
[[ $album ]] || exit 2
|
||||
|
||||
mpc clear
|
||||
if [[ $album == "$all_name" ]]; then
|
||||
mpc find artist "$artist" | sort | mpc add
|
||||
else
|
||||
mpc find artist "$artist" album "$album" | sort | mpc add
|
||||
fi
|
||||
|
||||
mpc play >/dev/null
|
||||
;;
|
||||
playlist)
|
||||
mpc play "$(d_playlist)" >/dev/null
|
||||
;;
|
||||
esac
|
||||
60
dotfiles/.local/bin/dmenu-pass
Executable file
60
dotfiles/.local/bin/dmenu-pass
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
shopt -s nullglob globstar
|
||||
|
||||
typeit=0
|
||||
if [[ $1 == "--type" ]]; then
|
||||
typeit=1
|
||||
shift
|
||||
fi
|
||||
|
||||
|
||||
STARTDIR=${PASSWORD_STORE_DIR-~/.password-store}
|
||||
BASEDIR=$STARTDIR
|
||||
DONE=0
|
||||
LEVEL=0
|
||||
PREVSELECTION=""
|
||||
SELECTION=""
|
||||
|
||||
while [ "$DONE" -eq 0 ] ; do
|
||||
password_files=( "$STARTDIR"/* )
|
||||
password_files=( "${password_files[@]#"$STARTDIR"/}" )
|
||||
password_files=( "${password_files[@]%.gpg}" )
|
||||
|
||||
if [ "$LEVEL" -ne 0 ] ; then
|
||||
password_files=(".." "${password_files[@]}")
|
||||
fi
|
||||
entry=$(printf '%s\n' "${password_files[@]}" | dmenu "$@" -l 15)
|
||||
|
||||
echo "entry: $entry"
|
||||
if [ -z "$entry" ] ; then
|
||||
DONE=1
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$entry" != ".." ] ; then
|
||||
PREVSELECTION=$SELECTION
|
||||
SELECTION="$SELECTION/$entry"
|
||||
|
||||
# check if another dir
|
||||
if [ -d "$STARTDIR/$entry" ] ; then
|
||||
STARTDIR="$STARTDIR/$entry"
|
||||
LEVEL=$((LEVEL+1))
|
||||
else
|
||||
# not a directory so it must be a real password entry
|
||||
|
||||
if [[ $typeit -eq 0 ]]; then
|
||||
pass show -c "$SELECTION" 2>/dev/null
|
||||
else
|
||||
xdotool - <<<"type --clearmodifiers -- $(pass show "$SELECTION" | head -n 1)"
|
||||
fi
|
||||
DONE=1
|
||||
fi
|
||||
|
||||
else
|
||||
LEVEL=$((LEVEL-1))
|
||||
SELECTION=$PREVSELECTION
|
||||
STARTDIR="$BASEDIR/$SELECTION"
|
||||
fi
|
||||
done
|
||||
|
||||
28
dotfiles/.local/bin/dmenu-todo
Executable file
28
dotfiles/.local/bin/dmenu-todo
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Write/remove a task to do later.
|
||||
#
|
||||
# Select an existing entry to remove it from the file, or type a new entry to
|
||||
# add it.
|
||||
#
|
||||
|
||||
file="$HOME/.todo"
|
||||
touch "$file"
|
||||
height=$(wc -l "$file" | awk '{print $1}')
|
||||
prompt="Add/delete a task: "
|
||||
|
||||
cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file")
|
||||
while [ -n "$cmd" ]; do
|
||||
if grep -q "^$cmd\$" "$file"; then
|
||||
grep -v "^$cmd\$" "$file" > "$file.$$"
|
||||
mv "$file.$$" "$file"
|
||||
height=$(( height - 1 ))
|
||||
else
|
||||
echo "$cmd" >> "$file"
|
||||
height=$(( height + 1 ))
|
||||
fi
|
||||
|
||||
cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file")
|
||||
done
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user