Wednesday, January 11, 2006

Better Bashing

Bash is a big part of my life. I spend a huge part of my day interacting with my shell at the command prompt. For years now, Bash has been my shell of choice. That's not to say it's perfect, however. There have been a few nagging deficiencies in Bash that I have been meaning to remedy, and I finally got around to doing just that today. (Relevant config file contents are at the bottom of this post.)

One thing that's long annoyed me in Bash is that history searches only show the next match (whether forward or reverse, incremental or not). I want to be able to scroll back through all commands in my history that match a search. It turns out that there are a couple readline builtins that accomplish this: history-search-forward and history-search-backward. (See 'bind -l' for a list of readline commands, by the way.) They are not incremental, but they work well if you know the first few characters of the command, which is the common case for me. I bound these two commands to my up and down arrows using my .inputrc and now the arrow keys scroll through commands in my history that match the first few characters I type at the prompt. It's pretty handy.

The next feature I've always wanted in my shell is the equivalent of Ctrl-o and Ctrl-i in vim. Basically it's like the Back and Forward buttons on your web browser. Now, I know most of you are thinking that pushd and popd already get me there, but those commands behave somewhat differently. Read the Bash manual for details. What I want is to use cd to change directories, then use Ctrl-o and Ctrl-i to jump back and forward along my directory navigation history. I was going to somehow build this on top of pushd and popd, but I decided to just write my own system instead using a couple of arrays for the stacks. Here is the code, which I've included in my .bash_profile:

forward_size=0
back_size=0
declare -a back_dirs
declare -a forward_dirs

back_dir()
{
    if [ $back_size = 0 ]; then
        return;
    fi
    back_size=$((back_size-1));
    forward_dirs[$forward_size]=`pwd`;
    forward_size=$((forward_size+1));
    builtin cd ${back_dirs[$back_size]};
}

forward_dir()
{
    if [ $forward_size = 0 ]; then
        return;
    fi
    forward_size=$((forward_size-1));
    back_dirs[$back_size]=`pwd`;
    back_size=$((back_size+1));
    builtin cd ${forward_dirs[$forward_size]};
}

cd()
{
    wd=`pwd`;
    builtin cd "$@";
    if [ $? = "0" ]; then
        back_dirs[$back_size]=$wd;
        back_size=$((back_size+1));
        forward_size=0;
    fi
}

Using my new version of cd and binding my new functions back_dir and forward_dir to some keys (I ended up using Ctrl-f and Ctrl-b, also vi-inspired) I now have the behavior I was looking for. Here are the contents of my .inputrc:

$include /etc/inputrc
"\M-[B":   history-search-forward
"\M-[A":   history-search-backward
"\C-b":    "back_dir^M"
"\C-f":    "forward_dir^M"
"\M-i":    kill-whole-line

Note that I also bound Meta-i to kill-whole-line, which is too useful of a command to be unbound (yet it is unbound by default). There is probably a much simpler way of doing this, but this was easy enough and it works great. Try it out and let me know what you think.

posted by David Shoemaker @ 6:38 PM   8 comments

8 Comments:

At Sat Jan 28, 08:14:00 AM PST,
      Anonymous Anonymous said...

Doesn't ctrl-c kill the whole line?

 
At Fri Mar 24, 07:42:00 PM PST,
      Anonymous Anonymous said...

Hey David,

I have been looking for something similar for awhile now (and too lazy to write it since bash isn't my thing).

On my setup I have to put the code into ~/.bashrc instead of ~/.bash_profile (even though .bash_profile calls .bashrc??).

I also had to delete the ^M characters at the end of back_dir and forward_dir to get things working. DOS newline??

Anyways, thanks for the code.

Thanks,
Wilson

 
At Tue May 16, 02:37:00 PM PDT,
      Blogger David Shoemaker said...

anonymous - AFAIK, ctrl-c does not kill the whole line with default bash key bindings. Instead it seems to cancel input and start a new line, which is similar and accomplishes the same thing, really.
Wilson - the ^M characters probably won't copy correctly from the web browser. That is actually one character (ctrl-M), not two. ctrl-M is usually the equivatlent of carriage return, which is what I'm using it for here. I don't want to have to press 'Enter' to execute my forward_dir and back_dir commands.

 
At Fri Aug 04, 02:21:00 PM PDT,
      Anonymous Anonymous said...

I'm posting this comment from Jamie's new motorola q phone. Pretty sweet, eh?

 
At Fri Dec 18, 02:33:00 PM PST,
      Anonymous Anonymous said...

Good day !.
You re, I guess , probably very interested to know how one can reach 2000 per day of income .
There is no need to invest much at first. You may commense to receive yields with as small sum of money as 20-100 dollars.

AimTrust is what you thought of all the time
The firm incorporates an offshore structure with advanced asset management technologies in production and delivery of pipes for oil and gas.

Its head office is in Panama with structures around the world.
Do you want to become really rich in short time?
That`s your chance That`s what you desire!

I feel good, I began to take up income with the help of this company,
and I invite you to do the same. It`s all about how to select a proper partner utilizes your savings in a right way - that`s AimTrust!.
I make 2G daily, and my first deposit was 1 grand only!
It`s easy to get involved , just click this link http://kyhyxata.freecities.com/colaci.html
and go! Let`s take our chance together to get rid of nastiness of the life

 
At Sun Jan 10, 07:51:00 AM PST,
      Anonymous Anonymous said...

Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now keep it up!

 
At Wed Jul 28, 01:07:00 AM PDT,
      Anonymous Anonymous said...

thanks for your share ,and got useful information from your post.http://www.shopbigbig.com

 
At Sun Jan 09, 04:38:00 AM PST,
      Anonymous Anonymous said...

Well-paying, they coerce to be taught that filing lawsuits is not the movement of dis to be the provenience to a court piracy. As an substitute, it's to yacht something build than piracy. Like contain of use. It's main part a the as a customs supplies easier to necessity iTunes than to search the Internet with omen of malware and then crappy magnificence, but if people are expected to a gull loads and dally on owing ages, it's not profit to work. They at most realize a indelicate on sooner ahead people fallacy up software and Take captive sites that amount to it ridiculously broad-minded to infringer, and up the quality. If that happens, then there disambiguate be no stopping piracy. But they're too sensible and horrified of losing. Risks recompense over the amplitude of to be bewitched!

flight tickets to china

 

Post a Comment

%%%SIDEBAR%%%

Recent Blog Entries

Powered by Blogger