* [PATCH] mmc-utils: Add bash completion
@ 2026-08-09 8:07 Torstein Eide
2026-08-10 6:22 ` Avri Altman
0 siblings, 1 reply; 2+ messages in thread
From: Torstein Eide @ 2026-08-09 8:07 UTC (permalink / raw)
To: linux-mmc; +Cc: Torstein Eide
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 | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
docs/HOWTO.rst | 6 ++++++
3 files changed, 63 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..0a93bb1
--- /dev/null
+++ b/completion/mmc
@@ -0,0 +1,53 @@
+_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
+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
^ permalink raw reply related [flat|nested] 2+ messages in thread
* RE: [PATCH] mmc-utils: Add bash completion
2026-08-09 8:07 [PATCH] mmc-utils: Add bash completion Torstein Eide
@ 2026-08-10 6:22 ` Avri Altman
0 siblings, 0 replies; 2+ messages in thread
From: Avri Altman @ 2026-08-10 6:22 UTC (permalink / raw)
To: Torstein Eide, linux-mmc@vger.kernel.org
> 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 | 53
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> docs/HOWTO.rst | 6 ++++++
> 3 files changed, 63 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\"
I guess you are assuming here that the lsmmc series is applied first - which is fine IMHO.
> CFLAGS ?= -g -O2
> +idsdir = /usr/share/misc
Ditto.
'?=' is perfectly fine. I would just leave it
> +bashcompletiondir = /usr/share/bash-completion/completions
better '?=' Here also
> 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..0a93bb1
> --- /dev/null
> +++ b/completion/mmc
> @@ -0,0 +1,53 @@
> +_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]+$')
I think you are excluding rpmb nodes such as /dev/mmcblk0rpmb.
Thanks,
Avri
> +
> + 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
> +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
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-10 6:24 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-09 8:07 [PATCH] mmc-utils: Add bash completion Torstein Eide
2026-08-10 6:22 ` Avri Altman
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.