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
|
#!/bin/bash
# udt-folders - rofi script mode: bookmarked and home folders, opened in pcmanfm-qt
# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# Run by rofi as a mode, "-modi 'Folders:udt-folders'". Without an argument it
# lists the folders; called again with the pick, it opens that folder and
# prints nothing, which closes rofi. The path travels in the entry's info
# field (ROFI_INFO), so labels can repeat or differ from the directory name.
if [[ -n ${ROFI_INFO:-} ]]; then
setsid -f pcmanfm-qt "$ROFI_INFO" >/dev/null 2>&1
exit 0
fi
declare -A seen
entry() { # label path
[[ -d $2 && -z ${seen[$2]:-} ]] || return
seen[$2]=1
local icon=folder
case $2 in
"$HOME") icon=user-home ;;
"$HOME/Desktop") icon=user-desktop ;;
"$HOME/Documents") icon=folder-documents ;;
"$HOME/Downloads") icon=folder-download ;;
"$HOME/Music") icon=folder-music ;;
"$HOME/Pictures") icon=folder-pictures ;;
"$HOME/Videos") icon=folder-videos ;;
"$HOME/Templates") icon=folder-templates ;;
"$HOME/Public") icon=folder-publicshare ;;
esac
printf '%s\0icon\x1f%s\x1finfo\x1f%s\n' "$1" "$icon" "$2"
}
entry Home "$HOME"
# GTK bookmarks, which pcmanfm-qt shares: "file:///path label", %-encoded.
# ponytail: local file:// bookmarks only; sftp:// and the like are skipped.
while read -r uri label; do
[[ $uri == file://* ]] || continue
path=${uri#file://}
path=$(printf '%b' "${path//%/\\x}")
entry "${label:-${path##*/}}" "$path"
done < "${XDG_CONFIG_HOME:-$HOME/.config}/gtk-3.0/bookmarks"
for d in "$HOME"/*/; do
d=${d%/}
entry "${d##*/}" "$d"
done
|