From: Henning Bekel Date: 2009-10-06T06:10:09+09:00 Subject: Re: method_missing for command shell? Roger Pack wrote: > I'm wondering if anybody knows of a shell that can be programmed > to "guess" what you meant when you type in a command errantly, > like (kind of a bad example, but...) > > $ git dif > > (it runs git dif, fails, then, in method_missing style, I can > tell it "oh what I always means when I run git dif is git diff" > so it correct its for me and runs it). > > Any pointers on where to go there? Well, kind of. You might use PROMPT_COMMAND in bash to react if the last command failed (as in the above case of a misspelled second argument). Or you could use a command_not_found_handle function (new in bash 4.0, see the manual) as a hook for a misspelled binary name, and go from there. Maybe both. Here's something I hacked together using the first method. It works a bit different from your suggestion in that it uses compgen to guess the possible corrections for the second argument (checking first if there is a completion function for this command), then uses the builtin select command to query the user for a correction, and then runs the corrected command. So it will ask you if you meant "git diff" or "git difftool" in the case of "git dif" failing. (Note that git's completion already asks a "did you mean" question, so it's a little redundant here...) Not exactly what you asked for (still fails for "git dfif"), and probably not perfect, but maybe it's a pointer to start from ;) So, here's the code to source into bash: last_commandline () { # fetch the last commandline from the history local histtimeformat=$HISTTIMEFORMAT unset HISTTIMEFORMAT [[ $(history 1) =~ \ +[0-9]+?\ +(.+?) ]] local commandline=${BASH_REMATCH[1]} if [[ "$histtimeformat" != "" ]]; then HISTTIMEFORMAT=$histtimeformat fi echo "$commandline" } correct () { args=($*) rest="${args[@]:2}" # third to last arg if type -t "_$1" &>/dev/null; then # there's a completion function for this command # get possible completions for the incomplete second argument comps=($(compgen -W "$(compgen -F _$1 2>/dev/null)" -- $2)) # let the user choose, then run the corrected command select choice in ${comps[@]}; do echo "running corrected command: $1 $choice $rest"; $1 $choice $rest break; done fi } # we'll use the prompt command as a hook for failed commands PROMPT_COMMAND='[[ ! $? -eq 0 ]] && correct $(last_commandline)'