aboutsummaryrefslogtreecommitdiff
path: root/sel
blob: 5d057e888f6832c077b4c7286d9bb61c3def218e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/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.

# Another TODO: add by filename does not work when globbing filenames with
# space. E.g. sel add "a file.txt" works, but sel add *.txt does not.
# Why does this happen?

# 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

Generated with cgit - Back to sebastiano.tronto.net