Theming Bash
Pages: 1, 2
Sensitive Completion
Another functionality I like to have in my themes is sensitive filename completion. Usually, I work on a Subversion working copy where there are many temporary or backup files that gvim leaves, as well as the .svn directories for Subversion meta-files. In that case, trying to use the default Bash filename completion with gvim is quite daunting, because my completion often finds files in which I have no interest.
To resolve this, I wrote another Bash function:
__gvim_completion()
{
local cur
cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(compgen -f -X '*~' -- "$cur" |
grep -vE '(^|/)\.(svn|[^/]+\.swp)($|/)' )
)
}
complete -o filenames -F __gvim_completion gvim
The complete command instructs the shell to use the __gvim_completion() function for the completion of filenames for the arguments following the gvim command. __gvim_completion in turn throws away all of the undesired files. You can refer to the meaning of the various commands and variables from the Bash man page--I won't explain them here. I should just note that it took a lot of experimentation to get it right (some of it, right before I wrote this article).
Useful Theme-Specific Commands
Running ./Build disttest in a Module::Build-based Perl module prepares a fresh distribution and tests it using its defined tests. I discovered that it also tends to leave a directory behind with the tested distribution inside of it. To remedy this, I use:
__dist_name()
{
(cd "$this" &&
cat META.yml | grep "^name:" | sed 's/^name: //'
)
}
__version()
{
(cd "$this" &&
cat META.yml | grep "^version:" | sed 's/^version: //'
)
}
__test_distribution()
{
(
cd "$this"
./Build disttest
rm -fr "$(__dist_name)-$(__version)"
)
}
The function __dist_name() retrieves the name of the distribution from the META.yml file. A proper and more failsafe way to do it would probably be to use Perl and the YAML module, but this way also works. __version() does the same for the version number. These two functions may be useful to other functions as well.
Finally, the __test_distribution() function does the test and then deletes the temporary distribution directory.
Use, Abuse, and the Future of Shell Themes
There are plenty of other uses of themes. Here are ideas I haven't tried much yet!
Reducing .bashrc Bloat
Ian McDonald's Bash Completion source is 8,313 lines and 192,606 bytes long, as of November 25th, 2005. As you can imagine, it takes quite a long time to source it from your .bashrc file. Using Bash themes, however, you can assign completions to the necessary commands within the theme, and avoid the cost of the rest of the completion commands.
I believe the shell initialization file of many command-line users has many common functions, shell variables, and environment variables that only a small number of projects use. You can put them in the appropriate themes and avoid bloating your shell initialization file. It's more maintainable that way, too!
Whence a Theme?
It's probably not worth the trouble to define a new shell theme, if a project you're working on is temporary, or such that you only update it extremely rarely. I'm also sometimes too lazy to define themes for such projects. For example, I did not define a theme for working on this article.
Individual themes and the theme collection as a whole require some maintenance. However, I still believe the time spent on maintaining themes is worth the convenience of having them. Constructing a new tool for convenience is a long-term investment that pays off with a lot of saved time and frustration in the long run--and customizing your working environment is fun and rewarding.
The History and Future of Shell Themes
I first came up with the idea of shell themes a few years ago, and quickly ended up implementing them. At first, most of them were a relatively rudimentary declaration of some variable directory paths and a cd $this command. Shell themes really took off for me when I needed to write a theme for my work on Subversion, and ended up writing many functions for it. Later themes, like the one for work on HTML::Widgets::NavMenu also incorporated some new facilities.
Nevertheless, I still have a feeling that I've only scratched the surface in regards to shell themes. There must be plenty of other exciting features to add. Here I pass the ball to your court and ask you to come up with more exciting shell customizations for your own themes.
For example, one problem I encountered just before preparing this article was that I couldn't pack a certain theme I created for working on a project for a client in the themes distribution, out of confidentiality. I ended up removing it altogether, but I realized that I would like to have several directories in which to search for themes. I haven't implemented it yet.
Happy theming!
Thanks
Thanks to Joshua Varner and chromatic for going over early drafts of this article and giving useful comments and corrections.
is a software professional, who has been experimenting with programming since 1987 and with various UNIX technologies since 1996. He graduated from the Technion with a B.Sc. in Electrical Engineering, and has been heavily involved as a Linux and open source user, developer, and advocate.
His most successful project so far was Freecell Solver, but he also headed several other projects, and contributed to other projects such as Perl 5, Subversion, and the GIMP.
Return to ONLamp.com.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 5 of 5.
-
Script broken for BASH 2.05
2006-02-04 11:37:56 notchewie [Reply | View]
You use $BASH_SOURCE as a variable to set the themes base directory. This is only available in BASH v3.0 or greater. To use the script in BASH < 3.0, just manually set the __themes_dir variable in the Source_Me.bash file.
Otherwise, nice little system.
-
Put the CVS branch name in your prompt
2006-02-03 15:38:22 Matt Doar |
[Reply | View]
If you sometimes forget which branch your current sandbox of checked-out code was taken from, you can have the name of the branch appear in your shell prompt.
export PS1="[\u@\h\$(if [ -d CVS ]; then if [ -e CVS/Tag ]; then cat CVS/Tag | sed -e 's/^T/ /' | sed -e 's/^N/ /' | sed -e 's/^D/ Date /' | sed -e 's/_BRANCH/\[\033]12;blue\007\]/'; else echo ' \[\033]12;black\007\]MAIN' ; fi; else echo '\[\033]12;black\007\]' ;fi) \W]\\$ "
Change "_BRANCH" to some string that matches your local convention for CVS branches. I'm not sure how the line breaks will be handled when this appears, but the original text is also in my O'Reilly book "Practical Development Environments".
~Matt







Interesting article. I'm sure there's lots more than can be done to make the shell an even more productive working environment.
I've written a Bash script that adds colour to shell output, cycling through colours one per command. I find this really useful when I run something like "make" and it generates loads of output. If you want to scroll back to the start of this command's output normally it's hard to spot where this command started, but with colours it's easy. You can get the script here: http://chezphil.org/colourshell/ (US readers note the spelling!).
There must be lots of other stuff like this out there in peoples' ~/bin directories that could be useful to others - please share!
--Phil.