Monday, December 10, 2007

Cygwin

It's been a long time since I last posted. I've been working on the Delphi compiler all the while, but with uninteresting bug fixes (usually too boring to talk about), learning more about the code base (not general enough to talk about) and working on new features (not public enough to talk about), it's been rare enough that I found something interesting enough to talk about. So, I've decided to take a different tack.

I've had the "opportunity" to set up a number of PCs and laptops recently for my personal use, general and development work. Quite a bit of customization is necessary before I'm comfortable with a system. Apart from the usual handful of utilities (Firefox with extensions, Winzip, Winamp, Forte Agent), there's one other thing that I can't really live without - Cygwin. The bash shell running in an rxvt terminal window is my main interface with Windows.

There's one big reason for this. The shell is very programmable, so any time I need to do work of a repetitive nature, I can write a script. Whenever I find myself doing similar things, I can refactor my work and write a new utility script containing the commonality. My life would be a lot harder without Cygwin. Sometimes I wonder why it isn't more popular than it is; but then, the default Cygwin setup isn't very appealing. I remember when I first installed it, and got to use the usual Unix utilities I was familiar with from Linux, only this time in Windows, but I was still using the crippled cmd.exe shell from NT, running in the crappy console that Windows provides by default. I'm going to write a series of posts on how I beautify my Cygwin environment.

Installation

The first step is to install Cygwin. I do this in a four-step process:

  1. Download setup.exe from cygwin.com.
  2. Run setup.exe, and tell it to download (but not install) everything to a local directory. I choose c:\cygwin\opt\var\cygwin-cache. I then rename the ugly directory name it generates (based on the mirror you chose) to something briefer.
  3. I then run setup.exe again (setup.exe normally resides in c:\cygwin\opt\var\cygwin-cache on my system), and perform an install, selecting those packages that I know I want and need. Those include:
    • All the programming languages, from clisp and SWI-Prolog through byacc and cocom to gcc and nasm.
    • The text editor joe and the rxvt terminal.
    • ImageMagick, Ghostscript, TeX - stuff I seldom use, but like to have available.
  4. Finally, I add the main binaries directory (c:\cygwin\bin by default) to my system path.

Actually, I'm lying. I don't normally use setup.exe to download the cygwin-cache directory, since I already have one. I actually use wget to download the cygwin packages directly from a mirror on a monthly basis, but that presents a bootstrapping problem: one wouldn't normally have wget without already having installed cygwin.

In any case, once I've gotten Cygwin installed, it's time for me to set up my home directory (the ~ directory in Unix parlance; defaults to c:\cygwin\home\<username>). This is created the first time you run a Cygwin login shell, such as from the shortcut the setup.exe program creates (or by running bash --login). All the stuff up until now is pretty regular Cygwin orthodoxy: people usually stumble along this far all on their own. I know I did the first time, but I found bash running in NT's command window pretty unpleasant to use. Here's where I make Cygwin usable, at least to me.

Beautifying

The main objective is to get bash running inside rxvt. This can be done pretty trivially:
  • Create a shortcut to c:\cygwin\bin\rxvt.exe (assuming one chose the default install directory)
  • Modify the shortcut and change the target so that it has a few extra arguments: "c:\cygwin\bin\rxvt.exe -e bash --login".
That tells rxvt to use bash rather than sh as the shell, and tells bash to run ~/.bash_profile (amongst others) as its startup script, rather than ~/.bashrc.

However, the default shell is still pretty unappealing: an ugly white window with black text. That's why I use some customizations. Rxvt reads in .Xdefaults from your home directory when it starts up, even though it's a Windows program, not an X one. .Xdefaults uses a pretty simple line-oriented file format. '!' starts a comment, which extends to the end of the line. Here are some lines I add to make things more suited to my preferences:

Rxvt*geometry:120x43

Rxvt*background:rgb:00/00/20
Rxvt*foreground:rgb:C0/C0/C0

Rxvt*color1:red
Rxvt*color2:rgb:72/A0/32
Rxvt*color4:skyblue

Rxvt*color3:yellow
Rxvt*color5:magenta
Rxvt*color6:rgb:20/C0/A0
Rxvt*color7:rgb:C0/C0/C0

Rxvt*color9:red
Rxvt*color10:rgb:72/A0/32
Rxvt*color12:skyblue

Rxvt*color11:yellow
Rxvt*color13:magenta
Rxvt*color14:rgb:20/C0/A0
Rxvt*color15:rgb:C0/C0/C0

Rxvt*colorBD:rgb:C0/C0/C0
This remaps the 16 console colours a little, inverting the colour scheme. I get the names for these variables (called resources in X parlance) from the rxvt manual page, available from "man rxvt". Here are some other relevant lines in my .Xdefaults:
Rxvt*jumpScroll:True

! I use Dina-9, from the font Dina, which I installed separately
!Rxvt*font:-*-lucidatypewriter-medium-*-*-*-12-*-*-*-*-*-*-*
Rxvt*font:Dina-9

! I have an ego
Rxvt*title:Barry's Bash

! Scrollbar on the left looks odd.
Rxvt*scrollBar_right:True

! In case I forget something; this is somewhat better than cmd.exe's usual limit
Rxvt*saveLines:30000

Rxvt*termName:rxvt

! This is the number of pixels between text rows; aesthetic issue, depends on font and size
Rxvt*lineSpace:1
After having done this, I have something I can live with.

1 comment:

Steve Trefethen said...

Hey Bary,
Good to have you back! Have you looked at Microsoft's PowerShell at all? I still use 4NT daily though I've been playing with PS but haven't quite gotten used to it yet.

Hmm, I see Google has changed how comments work and you can only link back to your own blog if you have a Google account. Strange, seems like it will thwart blog commenting to some degree.