From 9e48b48173a2c06443fd4ec58225cb1eaac27895 Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 3 Nov 2024 16:49:29 +0100 Subject: [PATCH] initial commmit --- COPYING.txt | 1 + LICENSE.txt | 17 +++++ README.md | 44 +++++++++++++ xdg-desktop-search | 153 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+) create mode 100644 COPYING.txt create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100755 xdg-desktop-search diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 0000000..d35e58c --- /dev/null +++ b/COPYING.txt @@ -0,0 +1 @@ +Copyright © 2024 Tilman Kranz diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..aaf5888 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9318a32 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ + + +## Usage + +``` +xdg-desktop-search [ OPTIONS ] SEARCH ... +``` + +## Arguments + +- `SEARCH`: Search .desktop files with search directives containing this + string. The searched directives are "Name" and "Exec" by default but can be + overridden using the -s option (see below). + +## Options + +- `-h`, `--help`: Print this message and exit. + +- `-v`, `--verbose`: Print directives in found .desktop files. + +- `-d STRING`, `--show-directive STRING`: Instead of printing all directives + when searching in verbose mode, print only this directive (e.g. "Name"). + Option can be repeated to print multiple directives. + +- `-s STRING`, `--search-directive STRING`: Instead of searching directives + "Name" and "Exec" for strings containing SEARCH, search the given directive + instead (e.g. "Comment"). Option can be repeated to search in multiple directives. + + +## Return Values + +The command returns 0 if .desktop files were found that match the specified +criteria, 1 on usage error and 2 if no matching .desktop files were found. + +## Example + +Search for the string "firefox" in all .desktop files found in the path +specified by `XDG_DATA_DIRS`. To match, the string "firefox" must be contained +in either the "Exec" or the "Comment" directive. List the matching files, also +show the "Exec" and "TryExec" directives in each found file. + +```shell +xdg-desktop-search -s Exec -s Comment -v -d Exec -d TryExec firefox +``` diff --git a/xdg-desktop-search b/xdg-desktop-search new file mode 100755 index 0000000..11bf318 --- /dev/null +++ b/xdg-desktop-search @@ -0,0 +1,153 @@ +#!/bin/bash +# Summary: Search for .desktop files with directives that match certain search strings. +# License: MIT +# Author: Tilman Kranz + +## +# Configuration + +name=$(basename "$(readlink -f "$0")") +IFS=":" +xdg_data_dirs=${XDG_DATA_DIRS:-/usr/share/gnome:$HOME/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share} +search_regex=.* +help=false +verbose=false +show_directives_regex=.* +search_directives_regex="(Name|Exec)" + +## +# Functions + +usage() { + cat << EOF +Usage: $name [ OPTIONS ] SEARCH ... + +Arguments: + + SEARCH: Search .desktop files with search directives + containing this string. The searched directives + are "Name" and "Exec" by default but can be + overridden using the -s option (see below). + +Options: + + -h | --help Print this message and exit. + -v | --verbose Print directives in found .desktop files. + -d STRING | --show-directive STRING + Instead of printing all directives when + searching in verbose mode, print only + this directive (e.g. "Name"). Option can + be repeated to print multiple directives. + -s STRING | --search-directive STRING + Instead of searching directives "Name" and + "Exec" for strings containing SEARCH, + search the given diretcive instead + (e.g. "Comment"). Option can be repeated + to search in multiple directives. + +Return Values: + + The command returns 0 if .desktop files were found that + match the specified criteria, 1 on usage error and 2 if + no matching .desktop files were found. + +Example: + + Search for the string "firefox" in all .desktop files found + in the path specified by XDG_DATA_DIRS. To match, the string + "firefox" must be contained in either the "Exec" or the + "Comment" directive. List the matching files, also show the + "Exec" and "TryExec" directives in each found file. + + $name -s Exec -s Comment -v -d Exec -d TryExec firefox +EOF +} + +join() { + local IFS="$1" + shift + echo "$*" +} + +parse_options() { + local search=() + local search_directives=() + local show_directives=() + local argc=$# + local counter=1 + + while true ; do + [[ $counter -gt $argc ]] && break + argument=$1 + shift + (( counter++ )) + + case "$argument" in + -h|--help) + help=true + ;; + -v|--verbose) + verbose=true + ;; + -d|--show-directive) + [[ $counter -gt $argc ]] && { + echo "ERROR: Missing argument for option -d; aborted." >&2 ; + exit 1 ; + } + show_directives+=( "$1" ) + shift + (( counter++ )) + ;; + -s|--search-directive) + [[ $counter -gt $argc ]] && { + echo "ERROR: Missing argument for option -s; aborted." >&2 ; + exit 1 ; + } + search_directives+=( "$1" ) + shift + (( counter++ )) + ;; + + *) + search+=( "$argument" ) + ;; + esac + done + + [[ "${#search_directives[@]}" -gt 0 ]] && search_directives_regex="($(join "|" ${search_directives[@]}))" + [[ "${#show_directives[@]}" -gt 0 ]] && show_directives_regex="^($(join "|" ${show_directives[@]}))=" + [[ "${#search[@]}" -gt 0 ]] && search_regex="^$search_directives_regex=.*($(join "|" ${search[@]}))" +} + +## +# Main Program + +parse_options $@ + +"$help" && { usage ; exit 0 ; } + +found=0 + +for data_dir in $xdg_data_dirs ; do + applications="$data_dir/applications" + + [[ -d $applications ]] && for desktop in "$applications"/*.desktop ; do + grep -Eiq "$search_regex" "$desktop" && { + (( found++ )) + if "$verbose" ; then + echo "# $desktop" + grep -Ei "$show_directives_regex" "$desktop" + else + echo "$desktop" + fi + } + done +done + +if [[ $found -gt 0 ]] ; then + exit 0 +else + exit 2 +fi + +# vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab: