Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 134 lines (109 sloc) 2.59 KB
#!/bin/bash
readonly CONFIG="$HOME/.config/mimi/mime.conf"
find_in_config() {
[[ -f "$CONFIG" ]] || return
grep -m 1 "^$1: " "$CONFIG" | cut -d ' ' -f 2-
}
need_terminal() {
grep -m 1 -q '^Terminal=true$'
}
find_exec_in_desktop_file() {
awk -F '[= ]' '$1 == "Exec" {print $2; exit}'
}
find_desktop_file_by() {
local path=(/usr/share/applications/)
[[ -d "$HOME/.local/share/applications" ]] && path+=("$HOME/.local/share/applications")
grep -m 1 "^$1=.*$2" -R "${path[@]}" | awk -F : -v pat="$2" '{ print index($2, pat), length($2), $1 }' | sort -t ' ' -k1,1n -k2,2nr | awk '{ print $3; exit }'
}
url_decode() {
echo -e "$(sed 's/%\([a-f0-9A-F]\{2\}\)/\\x\1/g')"
}
fork_run() {
echo "$*"
"$@" &>/dev/null &
exit 0
}
exist() {
type "$@" &>/dev/null
}
usage() {
cat <<-EOF
Usage: xdg-open [file|directory|protocol]
It opens a file according to the extension
To setup the extension, create $CONFIG
mimi :)
EOF
exit 1
}
# config
# 1. ext
# 2. protocol
# 3. mime
# 4. general mime
# .desktop (mime and general mime)
# 5. ask
[[ ! "$*" ]] && usage
arg="$*"
ext=''
protocol=''
mime=''
general_mime=''
# fix file://
if [[ "$arg" =~ ^file://(.*)$ ]]; then
# strip file://
arg="$(url_decode <<<"${BASH_REMATCH[1]}")"
protocol=file
fi
if [[ -e "$arg" ]]; then
# file or dir
mime="$(file -ib "$arg" | cut -d';' -f1)"
if [[ -f "$arg" ]]; then
ext="$(tr '[:upper:]' '[:lower:]' <<< "${arg##*.}")"
fi
fi
# protocol to mime ext
if [[ "$arg" =~ ^([a-zA-Z-]+): ]]; then
# use protocol to guess mime ext
protocol="${BASH_REMATCH[1]}"
case "$protocol" in
http|https)
mime=text/html
ext=html
;;
magnet)
mime=application/x-bittorrent
ext=torrent
;;
irc)
mime=x-scheme-handler/irc
;;
esac
fi
# application mime is specific
[[ "$mime" =~ ^(audio|image|text|video)/ ]] && general_mime="${BASH_REMATCH[1]}/"
exist "$TERM" || TERM="$(find_in_config TERM)"
# config
for search in $ext $protocol $mime $general_mime; do
app=($(find_in_config "$search"))
[[ "${app[0]}" == TERM ]] && exist "$TERM" && app[0]="$TERM"
[[ "${app[*]}" ]] && fork_run "${app[@]}" "$arg"
done
# .desktop
for search in $mime $general_mime; do
desktop="$(find_desktop_file_by MimeType "$search")"
if [[ "$desktop" ]]; then
echo "$desktop"
app=($(find_exec_in_desktop_file <"$desktop"))
if need_terminal <"$desktop"; then
echo "term: $TERM"
exist "$TERM" && fork_run "$TERM" -e "${app[@]}" "$arg"
else
fork_run "${app[@]}" "$arg"
fi
fi
done
# ask
if exist dmenu; then
app=($(IFS=: stest -flx $PATH | sort -u | dmenu -p "how to open $arg"))
[[ "${app[*]}" ]] && fork_run "${app[@]}" "$arg"
fi