|
Softpanorama |
May the source be with you, but remember the KISS principle ;-)
|
| Advanced navigation | ||||
| ksh completion | Bash completion modes | bash programmable completion package | Shell History | Etc |
One of the most powerful (and typically underused) features of many shells (ksh, bash, zsh) is filename completion facility, inspired by similar features in the C shell, and (originally) the old DEC TOPS-20 operating system.
The idea behind filename completion is that when you need to type a filename, you should not have to type more than is necessary to identify the file unambiguously. This is an excellent idea although it is limited by absence of visual feedback (compare with OFM filename completion). Still in moderate dozes it can save you some quite a bit of typing.
The most primitive completion is when instead of typing in the arguments/options following a command, the user presses TAB and the shell automatically inserts (or gives you the option of inserting) new text based on which bit of the full command you're editing. For example, say you want to extract files from a UNIX tape archive (.tar or .tar.gz file) of the Linux kernel source tree, which you just downloaded to the /tmp directory. You type:
/tmp % tar -zxvf l[press TAB] /tmp % tar -zxvf linux-2.0.38.tar.gz
If you had chosen -xvf instead, it would complete on files ending in .tar. Say there was also a file called allmail.tar in tmp:
/tmp % tar -xvf [press TAB] /tmp % tar -xvf allmail.tar
This is where things get really nifty. Say you only want to extract the file zsh-3.1.6-pws-11/Completion/User/_perl_builtin_funcs from zsh-3.1.6-pws-11.tar.gz. No need to type in all of that massive filename. Instead, going through the process step by step:
/tmp % tar zxf z[press TAB] /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz [press TAB again] /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/ /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/C[TAB] ChangeLog ChangeLog.3.0 Completion/ Config/ /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Com[TAB] /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Completion/ /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Completion/U[TAB] /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Completion/User/ /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Completion/User/_pe[TAB] _perl_basepods _perl_builtin_funcs _perl_modules _perldoc /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Completion/User/_perl[TAB] /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Completion/User/_perl_basepods[TAB again] /tmp % tar zxf zsh-3.1.6-pws-11.tar.gz zsh-3.1.6-pws-11/Completion/User/_perl_builtin_funcs
Using completion in this way, you can use the completion system as a way of browsing around directory structures. Note that this applies equally outside compressed archives, if you were intending to view or edit a file but didn't know exactly where it was, for example.
Bash supports several completion modes (via readline). Only few first have practical importance and return on investment for other modes might in general be negative:
complete (TAB) possible-completions (M-?) insert-completions (M-*) possible-completions.
menu-complete () complete, but replaces the word to be completed
with a single match from the list of possible completions. Repeated
execution of menu-complete steps through the list of possible
completions, inserting each match in turn. At the end of the list of
completions, the bell is rung (subject to the setting of bell-style)
and the original text is restored. An argument of n moves n
positions forward in the list of matches; a negative argument may be used to
move backward through the list. This command is intended to be bound to
TAB, but is unbound by default. delete-char-or-list () delete-char). If at the end of the line, behaves
identically to possible-completions. This command is unbound by
default. complete-filename (M-/) possible-filename-completions (C-x /) complete-username (M-~) possible-username-completions (C-x ~) complete-variable (M-$) possible-variable-completions (C-x $) complete-hostname (M-@) possible-hostname-completions (C-x @) complete-command (M-!) possible-command-completions (C-x !) dynamic-complete-history (M-TAB) complete-into-braces (M-{)
Backslash (\) is the command that tells the Korn shell to do filename completion in vi-mode. If you type in a word, type ESC to enter control mode, and then type \, one of four things will happen:
If there is no file whose name begins with the word, the shell will beep and nothing further will happen.
If there is exactly one way to complete the filename and the file is a regular file, the shell will type the rest of the filename, followed by a space in case you want to type in more command arguments.
If there is exactly one way to complete the filename and the file is a directory, the shell will complete the filename, followed by a slash.
If there is more than one way to complete the filename, the shell will complete out to the longest common prefix among the available choices.
A related command is *. It behaves
similarly to ESC \, but if there is more than one
completion possibility (number four in the list above), it lists all of them and
allows you to type further. Thus, it resembles the *
shell wildcard character.
The command = does the same kind of
filename expansion as the * shell wildcard, but in
a different way. Instead of expanding the filenames onto the command line, it
prints them in a numbered list with one filename on each line. Then it gives you
your shell prompt back and retypes whatever was on your command line before you
typed =. You can select the filename you which and
put it on the command line using the middle button of the mouse.
[esc] [=]
Display list of pathnames that result from expanding the word under the cursor.[esc] [esc]
Append characters to the word under the cursor to complete the pathname of an existing file.[esc] [*]
Replace words under the cursor with the list of pathnames that result from expanding the word.2.7. Command completion -- vi mode
[=]
Display list of pathnames that result from expanding the word under the cursor.[\]
Append characters to the word under the cursor to complete the pathname of an existing file.[*]
Replace words under the cursor with the list of pathnames that result from expanding the word.
| = | Pathname listing. Causes the current word on the command line to be expanded to a list of pathnames. For example, |
$ls m<ESC>=
1) myfile
2) myhome
$
| \ | Pathname completion. Causes the current word on the command line to be expanded to a filename or directory. If it is a directory then a / is added. For example, |
$ echo my<Esc>\
| would expand to myfile. | |
| @letter | Searches your list of aliases for one named _letter. If an alias is defined, its value is inserted as keystrokes. For example, |
alias _Q='LBi"^V<Esc>Ea"^V<Esc>'
| now if you are editing a command and type <Esc>@Q the current word you are on would be quoted. | |
| # | Insert a # (comment marker) at the beginning of a command. |
Another interesting feature is incremental searching, usually bound to C-r (Control R). This is a sort of cross between the other two: press it, and start typing a word which exists somewhere in the history. By the time you've typed enough of it to uniquely identify it, you've plucked the whole of that line out of the history. This is available in bash (C-r by default), tcsh (not bound by default) and zsh (C-r by default).
Completion is when you can press a key (often TAB) and the shell automatically cleverly completes the rest of the word you are typing, based on the context you are typing it in. bash offers basic filename, hostname and command completion. Only tcsh and zsh offer fully programmable context-sensitive completion of many different types with zsh functionality clearly superior.
Another nice examples of the zsh extended completion system are: the ytalk, finger and ssh commands, which complete on usernames and hostnames (automatically appending an @ symbol in between); the find command, which has different completions for each option (e.g. completes file/directory names for the initial parameter(s), users for -user, groups for -group ... zsh is even able to treat the arguments to -exec as a whole new command line!). The rpm, cvs, and gcc completions are even more fiendish.
You certainly get "hardcore hacker" points for fully grokking the internals of the zsh completion system. However, you can rejoice in the knowledge that you won't ever need to in order to enjoy this sophisticated time-saver, since the latest development versions come with a complete, `out of the box' pre-configured completions system.
|
Re: command completion
> I was wondering if anyone knows if there is software (or built in > functionality) for the korn shell in UWin which allows for the following two > functions available in the Unix Cshell: > > 1.)the ability to complete the path/filename from the first few letters > typed Yes, ksh supports both command and filename completion. In emacs mode use, <ESC><ESC> to complete a command or pathname up to the point of uniqueness. If the complete the first word on the line, then this indicates command completion and it will uses functions, builtins, and path search to complete the argument. You can use <ESC>= to get the matching list. In vi-mode use <ESC> to go to control mode and then \ to complete or = to list. U/WIN provides functions emacs_keybind and vi_keybind to allow the tab key to be used for completion, but there is a bug in the emacs_keybind function in which a $ is missing in front of the '\E\E". > 2.)the ability to use the arguments of previous commands (in the history) In vi-mode you can use _ from control mode to get the last argument of the previous command, or n_ to get the n-th argument of the pervious command. With emacs you can use <ESC>_ or <ESC>. > > David Korn research!dgk dgk@research.att.com
freshmeat.net Project details for bash programmable completion
Please allow user to revert to standard bash completion at any time (a
must-have).
by
Stéphane Gourichon - Oct 4th 2004
07:59:13
Currently, the arguably interesting features of
bash_completion actually interfere with some completion
patterns that bash had for years, (for example completing
a path stopping at cursor, when the cursor is in the middle
of the line, but there are other cases in previous
comments).
Generally, until it can be proven that a change makes the
situation better at all times without any (even minor)
downside, the change should be reversible and never
imposed.
So, any user should be able to turn it off. The simplest
idea is to unset the involved environment variables.
But BASH_COMPLETION and BASH_COMPLETION_DIR
are declared as read-only. Why ?
This prevents a particular user to turn it off... :-(
On a system with many users, there's currently no other
choice than to ask the administrator to remove the
package for all users (or make it not activated by default,
which is not what we need either).
Is it currently possible for a user to revert to standard
bash completion ? If not, please consider changing
something in the package (even something as simple as
checking for some ~/.bash_completionrc for a hint should
be fine).
The risk is that, on any big site, new users don't even
know what comes from your package or even that it
exists, but people that used normal bash completion
completion in ways *you* don't use will dislike the package
(becauses it causes less efficient work) and have it
removed for all users.
A last suggestion : use savannah.nongnu.org or
sourceforge.net to have real forums. Freshmeat comments
aren't structured enough so that contributors can make a
good job of checking if a request was already issued
before. User feedback quality depends on this.
Regards,
--
"J'y gagne, répondit le renard, à cause de la couleur du blé."
[»] Re: Please allow user to revert to
standard bash completion at any time (a must-have).
by
Ian Macdonald - Oct 8th 2004 17:20:08
> So, any user should be able to turn it
> off. The simplest
> idea is to unset the involved
> environment variables.
>
> But BASH_COMPLETION and
> BASH_COMPLETION_DIR
> are declared as read-only. Why ?
> This prevents a particular user to turn
> it off... :-(
These are set read-only, because it's bad to change them once they've been set.
They are used later on and it's important that the value doesn't change. They
can be set before the bash_completion script is run, however, and the original
value will be honoured.
> On a system with many users, there's
> currently no other
> choice than to ask the administrator to
> remove the
> package for all users (or make it not
> activated by default,
> which is not what we need either).
>
> Is it currently possible for a user to
> revert to standard
> bash completion ?
Yes, just run 'complete -r' and all completions will be removed, leaving just
the default. However, I agree that this isn't the most useful way of achieving
this, so I will consider the implementation of a better mechanism.
> A last suggestion : use
> savannah.nongnu.org or
> sourceforge.net to have real forums.
> Freshmeat comments
> aren't structured enough so that
> contributors can make a
> good job of checking if a request was
> already issued
> before. User feedback quality depends on
> this.
Well, e-mail works well, too. I agree that this forum isn't very efficient or
convenient, so just e-mail me your comments instead. It would be nice to have a
real mailing list, though. I'll consider setting one up.
[»] Wonderful... but...
by
GaelicWizard - Oct 5th 2003
02:14:11
I LOVE bash_completion, but I think that it is growing
just a tad too big... and a little unmanageable.
Spesific gripes:
1) If $UNAME isn't tested explicitly for an OS that
doesn't return xyz then feature abc which worx, is not
completed upon. I'm not sure how this is fixable, its just
a comment. :-)
2) some of the functions and completions seem to be
slightly more complex than neccessary. What I mean is
that I don't see the need to redefine the builtin
completions if the builtin ones work.
3) It seems to be very linux spesific, although almost all
worx on freeBSD it checks vigorously for linux in
$UNAME.
Thanx, keep up the good work!
[»] Re: Automatic change directory
by
Ian Macdonald - Apr 18th 2003 18:37:42
> Would it be possible to add the
> automatic change directory feature to
> Bash Completion?
>
> If a directory called /usr/local/lib/foo
> exists and the command line is:
> $ /usr/local/lib/foo <return>
>
> Then the action is to change to that
> directory instead of reporting that
> "/usr/local/lib/foo" is a
> directory.
>
> I've used this feature in other shells.
> Can this be done at the command
> completion level or does it call for a
> more fundamental change in bash
> itself?
>
bash can't really do this, since it has no pre-execution hook for you to tap
into with code.
Nevertheless, to my surprise, I managed to botch together the following hack:
trap '{ d=$_; [ -d "$d" ] && cd $d; unset d; }' ERR
This does what you want, but won't stop the attempt to run a directory from
displaying an error before changing to the directory.
Bash Reference Manual - Commands For Completion
Working more productively with bash 2.x by Ian Macdonald . See below his bash programmable completion package
Bash Reference Manual Command Line Editing
Advanced Bash-Scripting HOWTO - A guide to shell scripting, using Bash
freshmeat.net Project details for bash programmable completion project by Ian Macdonald You generally need bash 2.05a or later to use the package.
Since v2.04, bash has allowed you to intelligently program and extend its standard completion behavior to achieve complex command lines with just a few keystrokes. Imagine typing ssh [Tab] and being able to complete on hosts from your ~/.ssh/known_hosts files. Or typing man 3 str [Tab] and getting a list of all string handling functions in the UNIX manual. mount system: [Tab] would complete on all exported file-systems from the host called system, while make [Tab] would complete on all targets in Makefile. This project was conceived to produce programmable completion routines for the most common Linux/UNIX commands, reducing the amount of typing sysadmins and programmers need to do on a daily basis.
Copyright © 1996-2007 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. Submit comments This document is an industrial compilation designed and created exclusively for educational use and is placed under the copyright of the Open Content License(OPL). Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
Standard disclaimer: The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.
Last modified: March 15, 2008