How I set up my Ubuntu Laptop

By anders pearson 14 Aug 2011

I finally got around to putting an SSD drive in my laptop this weekend. I have a nice Lenovo Thinkpad T500 that I’ve used for the last year and a half or so. It’s pretty much just a sit on the couch and code or browse the web machine. I don’t use it for anything really heavy duty or media related so I don’t actually use much storage. That meant I could get away with putting a cheap 60GB SSD in it, which is more than enough storage for my needs on that machine.

First of all, yes, I think the SSD was a worthwhile improvement. For general web browsing and coding, it’s not really noticeably faster. The bottleneck for web stuff is still the speed of the internet connection. Compiling is a little faster, but not by a lot. Starting applications is a little faster, but really, I tend to just leave applications open all the time so it’s not saving me a lot there. Where the SSD is noticeable is booting and waking the laptop up from sleep. Waking it from sleep is now completely instantaneous. Booting takes 12 seconds to go from pushing the power button to having a usable desktop. I didn’t measure it pre-SSD, but it used to be well over a minute. It’s not a life changing improvement, but it does make me smile every time. If I traveled more with my laptop, I’d probably appreciate it even more.

Since switching to the SSD involved doing a completely fresh Ubuntu installation, this time around I took care to document everything I did to convert the laptop from a default Ubuntu 11.04 to how I prefer to have it set up. I thought it might be interesting to share my setup here.

I use the wonderful XMonad tiling window manager instead of Gnome or Unity. I’ve been using a tiling window manager of some sort since 2001 or so and I doubt I’ll ever go back. Once you get over the learning curve, tiling window managers just get out of your way and feel far more efficient to use. Previously, I’d set up XMonad to work alongside Ubuntu’s Gnome. So gnome-panel was running and it was a proper Gnome session, but XMonad replaced Metacity as the window manager. When Ubuntu 11.04 came out and they switched to Unity, it pretty much broke that setup. I actually gave Unity a try for a couple months since it seemed to be trying to take on some of the usability advantages of tiling window managers. It wasn’t terrible, but it was far from great. When I put in the SSD, I decided to give up on the Unity experiment and just go to a full XMonad setup, using xmobar and trayer to handle the things that gnome-panel used to do for me.

I’ve also been taking advantage of Ubuntu One to keep my various config files synchronized between machines. I’ve played around with putting my config files in Git and had some experiences with that, but at the moment I’m liking the automatic synchronization approach of Ubuntu One better. I rolled my own version with lsyncd for a while, which worked fine, but since Ubuntu One comes set up by default, it seems like the easiest approach now. I’m sure you could do the same thing with Dropbox, if you prefer, but Ubuntu One has worked well enough for me that I haven’t bothered looking into that. In the future, I’ll probably work out some hybrid solution with Ubuntu One and git so I can have things automatically synchronized and versioned, but I’m keeping it simple for now.

First of all, once the basic Ubuntu 11.04 desktop install is complete, I install the packages I need. This is a matter of opening up a terminal and running:

$ sudo apt-get install aptitude thunderbird xmonad emacs xmobar trayer dwm-tools htop keychain chromium-browser git-core magit python-setuptools erlang-mode postgresql
$ sudo apt-get build-dep python-psycopg2

Then I log in to Ubuntu One by running

$ u1sdtool -c

It prompts me for my username/password, which I’ve set up before and then syncs everything I have in my account to an “Ubuntu One” directory. This takes a little while, but when it’s finished, the important stuff in there are directories called ‘configs’ and ‘emacs’. The ‘emacs’ directory contains all my emacs libraries. I’m not going to include any of that here since many volumes of blog posts and articles have been written about how to set up emacs. My setup has built up over many years and is very personal to my usage. In ‘configs’ I have:

bashrc  
emacs
gitconfig   
Xmodmap
xmobarrc  
xmonad.desktop  
xmonad.hs  
xmonad.start

These config files are the core of my configuration. They live in Ubuntu One but I symlink them out to their proper locations. It’s important to note that these are just config files and don’t contain anything sensitive like passwords or ssh keys. I’ll go through them.

First, Xmodmap gets symlinked to ~/.Xmodmap. It has one simple, but very important purpose: erase the stupidity of most keyboards placing a useless CapsLock key in one of the most convenient spots. We simply replace it with a Control (essential for an emacs user):

keycode 66 = Control_L
clear Lock
add Control = Control_L

I set up ssh keys with:

$ ssh-keygen -t rsa

Distribute them to the machines I need to login to with

$ ssh-copy-id remote.machine

Then, so I don’t have to enter my passphrase every single time I ssh somewhere, at the end of my ~/.bashrc I add:

keychain --quiet --nolock ~/.ssh/id_rsa 2>/dev/null
. ~/.keychain/${HOSTNAME}-sh

An additional step that I can’t really automate, but that is still necessary for me for development is to copy the contents of my ~/.ssh/id_rsa.pub up to my github account.

My ~/.gitconfig just contains my full name and email address. It’s what gets set up when you run:

$ git config --global user.name "Name"
$ git config --global user.email "email@domain.com"

That pretty much gets my terminal working the way I want. The final major section is my XMonad setup, which is a bit trickier.

/usr/share/xsessions/xmonad.desktop gives me the option of logging in to an XMonad session instead of Unity/Gnome:

[Desktop Entry]
Encoding=UTF-8
Name=XMonad
Comment=Lightweight tiling window manager
Exec=xmonad.start
Icon=xmonad.png
Type=XSession

Logging in runs /usr/local/bin/xmonad.start, which sets up the xmobar panel, various utilities, and finally kicks off XMonad itself:

:::bash
#!/bin/bash
xrdb -merge .Xresources
trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand true --width 15 --height 12 --transparent true --tint 0x000000 &
gnome-screensaver 
gnome-settings-daemon
if [ -x /usr/bin/gnome-power-manager ] ; then
   sleep 1
   gnome-power-manager&
fi
if [ -x /usr/bin/nm-applet ] ; then
   nm-applet --sm-disable &
fi
exec xmonad

Xmobar gets its configuration from .xmobarrc:

Config { font = "-misc-fixed-*-*-*-*-13-*-*-*-*-*-*-*"
       , bgColor = "black"
       , fgColor = "grey"
       , position = TopW L 85
       , commands = [ Run Network "wlan0" ["-L","0","-H","32","--normal","green","--high","red"] 10
                    , Run Cpu ["-L","15","-H","50","--normal","green","--high","red"] 10
                    , Run Memory ["-t","Mem: %"] 10
                    , Run Swap [] 10
                    , Run Date "%a %b %_d %Y %H:%M:%S" "date" 10
                    , Run StdinReader
                    ]
       , sepChar = "%"
       , alignSep = "}{"
       , template = "%StdinReader% }{ %cpu% | %memory% * %swap% | %wlan0% | %date%"
       }

And XMonad itself is configured with a Haskell program in ~/.xmonad/xmonad.hs:

import XMonad
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Util.Run(spawnPipe)
import XMonad.Util.EZConfig(additionalKeys)
import System.IO

myManageHook = composeAll
    [ className =? "Gimp"      --> doFloat
    , className =? "Vncviewer" --> doFloat
    ]

main = do
    xmproc <- spawnPipe "xmobar"
    xmonad $ defaultConfig
        { manageHook = manageDocks <+> myManageHook -- make sure to include myManageHook definition from above
                        <+> manageHook defaultConfig
        , layoutHook = avoidStruts  $  layoutHook defaultConfig
        , logHook = dynamicLogWithPP $ xmobarPP
                        { ppOutput = hPutStrLn xmproc
                        , ppTitle = xmobarColor "green" "" . shorten 50
                        }
        , modMask = mod4Mask     -- Rebind Mod to the Windows key
        , terminal = "xterm -r"

        } `additionalKeys`
        [ ((controlMask, xK_Print), spawn "sleep 0.2; scrot -s")
        , ((0, xK_Print), spawn "scrot")
        , ((mod4Mask, xK_p), sendMessage NextLayout)
        , ((mod4Mask, xK_space), spawn "exe=`dmenu_path | dmenu` && eval \"exec $exe\"")
        ]

It’s a pretty minimal setup (I have a more complicated one I use on my desktops with dual-monitor setups). It switches the default mod key to the otherwise unused “Windows” key on the keyboard. It sets my default terminal to xterm with reverse video set (I prefer white text on black background for eye fatigue reasons). It also switches the default keybindings of Mod+Space and Mod+p, which is a personal preference.

That’s pretty much it. From there I can do everything I need to do on my laptop.

Tags: linux ubuntu