#!/bin/sh # Allow bulk operations on a list of selected files. # Usage: sel [-m menu] [command] # If no command is specified, shows the list of selected files # Commands: # add [files...]: add files to selection # addall: add all files in the current folder to selection # clear: clear selection # cp: copy to current dir, possbily after editing filenames # edit: open selection in editor # mv: move to current dir, possbily after editing filenames # open: open files using open-file # rm: remove selected files and clear selection # Requires: dmenu (or similar), trash (optional), open-file (for open only) # TODO: The usage of paste(1) is a bit of a hack, and for example it does # not work if filenames contain tab characters. Fix this. # Kinda bug, but it's fine: when using glob expressions, the expression must # be quoted when it matches filenames with spaces. For example # sel add * # works fine only if the are no filenames with spaces in the current folder; # on the other hand # sel add "*" # always works. # Bug (probably not fixing this, use virename): moving a file to # itself gives an error and rm is not run. file="$XDG_DATA_HOME/selectedfiles" menu="" # default uses dmenu-filepicker default editor=${EDITOR:-vi} rm="trash rm" # replace with rm -r if you don't use trash while getopts "m:" opt; do case "$opt" in m) menu="$OPTARG" ;; esac done shift `expr $OPTIND - 1` add() { shift 1 if [ -z "$1" ]; then if [ -n "$menu" ]; then dmenu-filepicker -m "$menu" >> "$file" else dmenu-filepicker >> "$file" fi else for i in "$@"; do realpath "$i" >> "$file"; done fi sort -u -o "$file" "$file" } clear() { cat /dev/null > "$file" } cphere() { file2=$(mktemp) sed 's/^.*\///' "$file" > "$file2" $editor "$file2" if [ "$(wc -l $file | awk '{print $1}')" != \ "$(wc -l $file2 | awk '{print $1}')" ]; then echo "Error reading new file names" return 1 else paste "$file" "$file2" | while read f; do fold=$(echo "$f" | sed 's/\t.*//') fnew=$(echo "$f" | sed 's/.*\t//') cp -R "$fold" ./"$fnew" || return 1 done fi } open() { while read f; do open-file "$f" done < "$file" } remove() { while read f; do $rm "$f" done < "$file" } if [ -z "$1" ]; then cat "$file" else case "$1" in add) add $@ ;; addall) add * ;; clear) clear ;; cp) cphere && clear ;; edit) $editor "$file" ;; mv) cphere && (remove; clear) ;; open) open ;; rm) remove && clear ;; *) echo "$1: not a valid sel command" ;; esac fi