On Thu, May 19, 2011 at 1:13 AM, Dave Reisner <d@falconindy.com> 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 <auguste@gmail.com> 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 <auguste@gmail.com> 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