All of lore.kernel.org
 help / color / mirror / Atom feed
From: Torstein Eide <torsteine+linux@gmail.com>
To: linux-mmc@vger.kernel.org
Subject: [PATCH v4 3/3] mmc-utils: Add bash completion
Date: Wed, 24 Jun 2026 20:48:24 +0200	[thread overview]
Message-ID: <20260624184824.2215718-4-torsteine+linux@gmail.com> (raw)
In-Reply-To: <20260624184824.2215718-1-torsteine+linux@gmail.com>

Add a bash completion script in completion/mmc that completes subcommands
and /dev/mmcblkN device paths for all mmc commands.

Subcommand completion is driven by parsing 'mmc help' output rather than
maintaining a parallel hardcoded verb list, so it stays in sync as
commands are added or removed.

The completion directory is named 'completion/' rather than
'bash-completion/' so shell-specific scripts for other shells (zsh,
fish, etc.) can be placed alongside it without renaming.

Add bashcompletiondir variable to the Makefile (defaulting to the
standard /usr/share/bash-completion/completions) and install the
script as part of 'make install'. The install path can be overridden
at build time with make bashcompletiondir=<path>.

Signed-off-by: Torstein Eide <torsteine+linux@gmail.com>
---
 Makefile       |  5 ++++-
 completion/mmc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
 docs/HOWTO.rst |  6 ++++++
 3 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 completion/mmc

diff --git a/Makefile b/Makefile
index bf8c006..607d372 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,8 @@ AM_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 \
 	    -DSD_IDS_PATH=\"$(idsdir)/sdcard.ids\" \
 	    -DMMC_IDS_PATH=\"$(idsdir)/multimediacard.ids\"
 CFLAGS ?= -g -O2
+idsdir = /usr/share/misc
+bashcompletiondir = /usr/share/bash-completion/completions
 objects = \
 	mmc.o \
 	mmc_cmds.o \
@@ -23,7 +25,6 @@ override CFLAGS := $(CHECKFLAGS) $(AM_CFLAGS) $(CFLAGS)
 INSTALL = install
 prefix ?= /usr/local
 bindir = $(prefix)/bin
-idsdir ?= /usr/share/misc
 LIBS=
 RESTORE_LIBS=
 mandir = /usr/share/man
@@ -63,6 +64,8 @@ install: $(progs)
 	$(INSTALL) -m755 -d $(DESTDIR)$(idsdir)
 	$(INSTALL) -m 644 sdcard.ids $(DESTDIR)$(idsdir)
 	$(INSTALL) -m 644 multimediacard.ids $(DESTDIR)$(idsdir)
+	$(INSTALL) -m755 -d $(DESTDIR)$(bashcompletiondir)
+	$(INSTALL) -m 644 completion/mmc $(DESTDIR)$(bashcompletiondir)/mmc
 
 -include $(foreach obj,$(objects), $(dir $(obj))/.$(notdir $(obj)).d)
 
diff --git a/completion/mmc b/completion/mmc
new file mode 100644
index 0000000..1924c15
--- /dev/null
+++ b/completion/mmc
@@ -0,0 +1,52 @@
+_mmc_complete() {
+	local cur prev words cword
+	_init_completion || return
+
+	local devices
+	devices=$(compgen -G "/dev/mmcblk*" 2>/dev/null | grep -E '^/dev/mmcblk[0-9]+$')
+
+	local mmcbin
+	mmcbin=$(type -P "${words[0]}") || return
+
+	# "mmc help" prints one "Usage for command\t<verb words...> <args...>"
+	# line per command. Argument placeholders always start with '<', so
+	# stripping from the first '<' onward leaves just the verb words.
+	local verbs
+	verbs=$("$mmcbin" help 2>/dev/null | sed -n 's/^Usage for command[[:space:]]*//p' | sed 's/<.*//')
+	[[ -z $verbs ]] && return
+
+	local -a typed=("${words[@]:1:cword-1}")
+	local -A next_words=()
+	local have_leaf=
+
+	local line i match
+	while IFS= read -r line; do
+		[[ -z $line ]] && continue
+		local -a w
+		read -ra w <<<"$line"
+		[[ ${#w[@]} -lt ${#typed[@]} ]] && continue
+
+		match=1
+		for ((i = 0; i < ${#typed[@]}; i++)); do
+			if [[ ${w[i]} != "${typed[i]}" ]]; then
+				match=0
+				break
+			fi
+		done
+		[[ $match -eq 0 ]] && continue
+
+		if [[ ${#w[@]} -gt ${#typed[@]} ]]; then
+			next_words[${w[${#typed[@]}]}]=1
+		else
+			have_leaf=1
+		fi
+	done <<<"$verbs"
+
+	if [[ ${#next_words[@]} -gt 0 ]]; then
+		COMPREPLY=($(compgen -W "${!next_words[*]}" -- "$cur"))
+	elif [[ -n $have_leaf ]]; then
+		COMPREPLY=($(compgen -W "$devices" -- "$cur"))
+	fi
+}
+
+complete -F _mmc_complete mmc
diff --git a/docs/HOWTO.rst b/docs/HOWTO.rst
index 0b486e4..3aba86f 100644
--- a/docs/HOWTO.rst
+++ b/docs/HOWTO.rst
@@ -2,6 +2,12 @@
 
 Running mmc-utils
 -----------------
+**Bash completion**
+    Source ``completion/mmc`` to enable tab-completion for all subcommands and
+    device paths. When installed via ``make install``, the file is placed in
+    ``$(bashcompletiondir)`` (default: ``/usr/share/bash-completion/completions/mmc``)
+    and loaded automatically by bash-completion.
+
 **Name**
     mmc - a tool for configuring MMC storage devices
 **Synopsis**
-- 
2.53.0


      parent reply	other threads:[~2026-06-24 18:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-24 18:48 [PATCH v4 0/3] mmc-utils: improve lsmmc usability Torstein Eide
2026-06-24 18:48 ` [PATCH v4 1/3] mmc-utils: lsmmc: Use external .ids files and accept /dev, /sys/block paths Torstein Eide
2026-06-24 18:48 ` [PATCH v4 2/3] mmc-utils: lsmmc: Add mmc list command Torstein Eide
2026-06-24 18:48 ` Torstein Eide [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260624184824.2215718-4-torsteine+linux@gmail.com \
    --to=torsteine+linux@gmail.com \
    --cc=linux-mmc@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.