aboutsummaryrefslogtreecommitdiff
path: root/wmutils/bin/groups.sh
blob: 486c5a7e25f5e3e9b77e231ad829720ae03a1c27 (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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/bin/sh
#
# Copyright (c) 2015 Greduan <me@greduan.com>, licensed under the WTFPL
# Adds group-like capabilities, sorta like those you find in CWM and such WMs

usage() {
    cat << EOF
usage: $(basename $0) [-hCU] [-c wid] [-s wid group] [-tmMu group]
       -h shows this help
       -c cleans WID from group files (and makes it visible)
       -C runs cleanup routine
       -s sets WID's group
       -t toggle group visibility state
       -m maps (shows) group
       -M maps group and unmaps all other groups
       -u unmaps (hides) group
       -U unmaps all the groups
EOF

    exit 1
}

# test for no arguments
test $# -eq 0 && usage

# I suggest it's under /tmp or somewhere that gets cleaned up at reboot or gets
# cleaned up after X stops running
FSDIR=${FSDIR:-/tmp/groups.sh}

# define our functions

# clean WID ($1) from group files
clean_wid() {
    # TODO: make POSIX compatible, -i is a GNU-ism
    sed -i "/$1/d" $FSDIR/group.*
}

# cleans group ($1) from (in)active files
clean_status() {
    # TODO: make POSIX compatible, -i is a GNU-ism
    sed -i "/$1/d" $FSDIR/active
    sed -i "/$1/d" $FSDIR/inactive
}

# shows all the windows in group ($1)
map_group() {
    # safety
    if ! grep -q $1 < $FSDIR/all; then
        echo "Group doesn't exist"
        exit 1
    fi

    # clean statuses
    clean_status $1
    # add to active
    echo $1 >> $FSDIR/active

    # loop through group and map windows
    while read line; do
        mapw -m $line
    done < $FSDIR/group.$1
}

# hides all the windows in group ($1)
unmap_group() {
    # safety
    if ! grep -q $1 < $FSDIR/all; then
        echo "Group doesn't exist"
        exit 1
    fi

    # clean statuses
    clean_status $1
    # add to inactive
    echo $1 >> $FSDIR/inactive

    # loop through group and unmap windows
    while read line; do
        mapw -u $line
    done < $FSDIR/group.$1
}

# assigns WID ($1) to the group ($2)
set_group() {
    # make sure we've no duplicates
    clean_wid $1
    clean_status $2

    # insert WID into new group if not already there
    grep -q $1 < $FSDIR/group.$2 || \
    echo $1 >> $FSDIR/group.$2

    # if we can't find the group add it to groups and make it active
    grep -q $2 < $FSDIR/all || \
    echo $2 >> $FSDIR/all && \
    echo $2 >> $FSDIR/active

    # map WID if group is active
    grep -q $2 < $FSDIR/active && \
    mapw -m $1

    # unmap WID if group is inactive
    grep -q $2 < $FSDIR/inactive && \
    mapw -u $1
}

# toggles visibility state of all the windows in group ($1)
toggle_group() {
    # safety
    if ! grep -q $1 < $FSDIR/all; then
        echo "Group doesn't exist"
        return
    fi

    # search through active groups first
    grep -q $1 < $FSDIR/active && \
    unmap_group $1 && \
    return

    # search through inactive groups next
    grep -q $1 < $FSDIR/inactive && \
    map_group $1 && \
    return
}

# removes all the unexistent WIDs from groups
# removes all group files that don't exist
# removes from 'all' file all groups that don't exist
cleanup_everything() {
    # clean WIDs that don't exist
    # using `cat` instead of `<` because error suppression
    cat $FSDIR/group.* 2>/dev/null | while read wid; do
        wattr $wid || \
        clean_wid $wid
    done

    # clean group files that are empty
    for file in $FSDIR/group.*; do
        # is the group empty?
        if [ ! -s $file ]; then
            rm -f $file
        fi
    done

    # remove groups that don't exist from 'all'
    while read line; do
        if [ ! -f $FSDIR/group.$line ]; then
            # TODO: make POSIX compatible, -i is a GNU-ism
            sed -i "/$line/d" $FSDIR/all
            clean_status $line
        fi
    done < $FSDIR/all
}

# actual run logic (including arguments and such)

# check $FSDIR exists
test -d $FSDIR || mkdir -p $FSDIR

# touch all the files
test -f $FSDIR/active || :> $FSDIR/active
test -f $FSDIR/inactive || :> $FSDIR/inactive
test -f $FSDIR/all || :> $FSDIR/all

cleanup_everything

# getopts yo
while getopts "hc:Cs:t:m:M:u:U" opt; do
    case $opt in
        h)
            usage
            ;;
        c)
            clean_wid $OPTARG
            mapw -m $OPTARG
            break
            ;;
        C)
            cleanup_everything
            break
            ;;
        s)
            set_group $OPTARG $(eval echo "\$$OPTIND")
            break
            ;;
        t)
            toggle_group $OPTARG
            break
            ;;
        m)
            map_group $OPTARG
            break
            ;;
        M)
            for file in $FSDIR/group.*; do
                group=${file##*.}
                unmap_group $group
            done
            map_group $OPTARG
            break
            ;;
        u)
            unmap_group $OPTARG
            break
            ;;
        U)
            for file in $FSDIR/group.*; do
                group=${file##*.}
                unmap_group $group
            done
            break
            ;;
    esac
done