On Thu, May 19, 2011 at 1:13 AM, Dave Reisner <[email protected]> wrote: > On Thu, May 19, 2011 at 12:53:13AM +0800, Auguste Pop wrote: >> i have made a small patch to initscripts to allow for a simple bash >> completion function. >> >> i am not familiar with git, i made the patch by git clone, git branch, >> git commit, and git show. >> >> the patch is at http://paste.pocoo.org/show/391299/ and also >> copy-pasted as follows: >> >> commit a430fcfb8fcd1e268609473c9a722e1cae1a66f0 >> Author: Auguste Pop <[email protected]> >> Date: Thu May 19 00:36:44 2011 +0800 >> >> add a simple bash completion file >> >> diff --git a/Makefile b/Makefile >> index 6923840..15df4cf 100644 >> --- a/Makefile >> +++ b/Makefile >> @@ -1,5 +1,5 @@ >> VER := $(shell git describe) >> -DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/cron.hourly /sbin >> +DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/cron.hourly >> /sbin /etc/bash_completion.d >> >> minilogd: minilogd.o >> >> @@ -13,6 +13,7 @@ install: minilogd installdirs >> install -m755 -t $(DESTDIR)/etc/cron.hourly adjtime >> install -m755 -t $(DESTDIR)/etc/rc.d functions hwclock network netfs >> install -m755 -t $(DESTDIR)/sbin minilogd rc.d >> + install -m644 bash_completion $(DESTDIR)/etc/bash_completion.d/rc.d >> >> clean: >> rm -f minilogd minilogd.o >> diff --git a/bash_completion b/bash_completion >> new file mode 100644 >> index 0000000..a3bd8ed >> --- /dev/null >> +++ b/bash_completion >> @@ -0,0 +1,55 @@ >> +#!/bin/bash >> + >> +_rc.d_getdaemons () >> +{ >> + /usr/bin/find "$1" -mindepth 1 -maxdepth 1 -type f -printf '%f\n' >> +} > > It would be nice to avoid the fork here. This can easily be accomplished > as: > > local -a files=("$1"/*) > printf '%s\n' "${files[@]##*/}" > > Also, please avoid using '.' in bash functions names. While bash will > allow you to set this, it's technically wrong, and unset will not allow > you to remove the function from your environment. > >> +_rc.d_arraydiff () >> +{ >> + local arr >> + declare -A arr >> + >> + for elem in "${!1}" >> + do >> + arr[$elem]=1 >> + done >> + for elem in "${!2}" >> + do >> + unset arr[$elem] >> + done >> + echo "${!arr[@]}" >> +} > > We use 'for i in group; do' and 'if commands; then' everywhere else > in our code. > >> + >> +_rc.d () >> +{ >> + local command commands available started >> + local cur words cword >> + >> + commands="list help start stop restart" >> + available=($(_rc.d_getdaemons /etc/rc.d)) >> + started=($(_rc.d_getdaemons /run/daemons)) >> + >> + _get_comp_words_by_ref -n =: cur words cword >> + [ $cword -gt 1 ] && command=${words[1]} >> + >> + if [ -z "$command" ] > > This is Bash, not posix. Please use [[. > >> + then >> + COMPREPLY=($(compgen -W "$commands" -- $cur)) >> + else >> + case "$command" in >> + start) >> + COMPREPLY=($(compgen -W "$(_rc.d_arraydiff \ >> + available[@] started[@])" -- $cur)) >> + ;; >> + stop|restart) >> + COMPREPLY=($(compgen -W "$(echo ${started[@]})" -- $cur)) >> + ;; >> + list|help|*) >> + COMPREPLY=() >> + ;; >> + esac >> + fi >> +} >> + >> +complete -F _rc.d rc.d >
here is the new patch that has changed find to simple glob, changed format according to arch convention, and subsituted all dots in function name into _. i originally used find to avoid selecting functions.d as a daemon. it's now simply excluded with functions by -X "functions*". here's the patch: commit 960641f72da1fae3183878f4752711d801b36fc9 Author: Auguste Pop <[email protected]> Date: Thu May 19 00:36:44 2011 +0800 add a simple bash completion file diff --git a/Makefile b/Makefile index 6923840..15df4cf 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ VER := $(shell git describe) -DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/cron.hourly /sbin +DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/cron.hourly /sbin /etc/bash_completion.d minilogd: minilogd.o @@ -13,6 +13,7 @@ install: minilogd installdirs install -m755 -t $(DESTDIR)/etc/cron.hourly adjtime install -m755 -t $(DESTDIR)/etc/rc.d functions hwclock network netfs install -m755 -t $(DESTDIR)/sbin minilogd rc.d + install -m644 bash_completion $(DESTDIR)/etc/bash_completion.d/rc.d clean: rm -f minilogd minilogd.o diff --git a/bash_completion b/bash_completion new file mode 100644 index 0000000..69b1983 --- /dev/null +++ b/bash_completion @@ -0,0 +1,52 @@ +#!/bin/bash + +_rc_d_getdaemons () +{ + local -a files=("$1"/*) + echo "${files[@]##*/}" +} + +_rc_d_arraydiff () +{ + local -A arr + + for elem in "${!1}"; do + arr[$elem]=1 + done + for elem in "${!2}"; do + unset arr[$elem] + done + echo "${!arr[@]}" +} + +_rc_d () +{ + local command commands available started + local cur words cword + + commands="list help start stop restart" + available=($(_rc_d_getdaemons /etc/rc.d)) + started=($(_rc_d_getdaemons /run/daemons)) + + _get_comp_words_by_ref -n =: cur words cword + [[ $cword -gt 1 ]] && command=${words[1]} + + if [[ -z "$command" ]]; then + COMPREPLY=($(compgen -W "$commands" -- $cur)) + else + case "$command" in + start) + COMPREPLY=($(compgen -W "$(_rc_d_arraydiff \ + available[@] started[@])" -X "functions*" -- $cur)) + ;; + stop|restart) + COMPREPLY=($(compgen -W "$(echo ${started[@]})" -- $cur)) + ;; + list|help|*) + COMPREPLY=() + ;; + esac + fi +} + +complete -F _rc_d rc.d
