PuTTY configuration

PuTTY is a terminal emulator with a free software license, including an SSH client. While it has cross-platform ports, it’s used most frequently on Windows systems, because they otherwise lack a built-in terminal emulator that interoperates well with Unix-style TTY systems.

While it’s very popular and useful, PuTTY’s defaults are quite old, and are chosen for compatibility reasons rather than to take advantage of all the features of a more complete terminal emulator. For new users, this is likely an advantage as it can avoid confusion, but more advanced users who need to use a Windows client to connect to a modern GNU/Linux system may find the defaults frustrating, particularly when connecting to a more capable and custom-configured server.

Here are a few of the problems with the default configuration:

  • It identifies itself as an xterm(1), when terminfo(5) definitions are available named putty and putty-256color, which more precisely define what the terminal can and cannot do, and their various custom escape sequences.
  • It only allows 16 colors, where most modern terminals are capable of using 256; this is partly tied into the terminal type definition.
  • It doesn’t use UTF-8 by default, which should be used whenever possible for reasons of interoperability and compatibility, and is well-supported by modern locale definitions on GNU/Linux.
  • It uses Courier New, a workable but rather harsh monospace font, which should be swapped out for something more modern if available.
  • It uses audible terminal bells, which tend to be annoying.
  • Its default palette based on xterm(1) is rather garish and harsh; softer colors are more pleasant to read.

All of these things are fixable.

Terminal type

Usually the most important thing in getting a terminal working smoothly is to make sure it identifies itself correctly to the machine to which it’s connecting, using an appropriate $TERM string. By default, PuTTY identifies itself as an xterm(1) terminal emulator, which most systems will support.

However, there’s a terminfo(5) definition for putty and putty-256color available as part of ncurses, and if you have it available on your system then you should use it, as it slightly more precisely describes the features available to PuTTY as a terminal emulator.

You can check that you have the appropriate terminfo(5) definition installed by looking in /usr/share/terminfo/p:

$ ls -1 /usr/share/terminfo/p/putty*
/usr/share/terminfo/p/putty  
/usr/share/terminfo/p/putty-256color  
/usr/share/terminfo/p/putty-sco  
/usr/share/terminfo/p/putty-vt100

On Debian and Ubuntu systems, these files can be installed with:

# apt-get install ncurses-term

If you can’t install the files via your system’s package manager, you can also keep a private repository of terminfo(5) files in your home directory, in a directory called .terminfo:

$ ls -1 $HOME/.terminfo/p
putty
putty-256color

Once you have this definition installed, you can instruct PuTTY to identify with that $TERM string in the Connection > Data section:

Correct terminal definition in PuTTY

Here, I’ve used putty-256color; if you don’t need or want a 256 color terminal you could just use putty.

Once connected, make sure that your $TERM string matches what you specified, and hasn’t been mangled by any of your shell or terminal configurations:

$ echo $TERM
putty-256color

Color space

Certain command line applications like Vim and Tmux can take advantage of a full 256 colors in the terminal. If you’d like to use this, set PuTTY’s $TERM string to putty-256color as outlined above, and select Allow terminal to use xterm 256-colour mode in Window > Colours:

256 colours in PuTTY

You can test this is working by using a 256 color application, or by trying out the terminal colours directly in your shell using tput:

$ for ((color = 0; color <= 255; color++)); do
> tput setaf "$color"
> printf "test"
> done

If you see the word test in many different colors, then things are probably working. Type reset to fix your terminal after this:

$ reset

Using UTF-8

If you’re connecting to a modern GNU/Linux system, it’s likely that you’re using a UTF-8 locale. You can check which one by typing locale. In my case, I’m using the en_NZ locale with UTF-8 character encoding:

$ locale
LANG=en_NZ.UTF-8
LANGUAGE=en_NZ:en
LC_CTYPE="en_NZ.UTF-8"
LC_NUMERIC="en_NZ.UTF-8"
LC_TIME="en_NZ.UTF-8"
LC_COLLATE="en_NZ.UTF-8"
LC_MONETARY="en_NZ.UTF-8"
LC_MESSAGES="en_NZ.UTF-8"
LC_PAPER="en_NZ.UTF-8"
LC_NAME="en_NZ.UTF-8"
LC_ADDRESS="en_NZ.UTF-8"
LC_TELEPHONE="en_NZ.UTF-8"
LC_MEASUREMENT="en_NZ.UTF-8"
LC_IDENTIFICATION="en_NZ.UTF-8"
LC_ALL=

If the output of locale does show you’re using a UTF-8 character encoding, then you should configure PuTTY to interpret terminal output using that character set; it can’t detect it automatically (which isn’t PuTTY’s fault; it’s a known hard problem). You do this in the Window > Translation section:

Using UTF-8 encoding in PuTTY

While you’re in this section, it’s best to choose the Use Unicode line drawing code points option as well. Line-drawing characters are most likely to work properly with this setting for UTF-8 locales and modern fonts:

Using Unicode line-drawing points in PuTTY

If Unicode and its various encodings is new to you, I highly recommend Joel Spolsky’s classic article about what programmers should know about both.

Fonts

Courier New is a workable monospace font, but modern Windows systems include Consolas, a much nicer terminal font. You can change this in the Window > Appearance section:

Using Consolas font in PuTTY

There’s no reason you can’t use another favourite Bitmap or TrueType font instead once it’s installed on your system; DejaVu Sans Mono, Inconsolata, and Terminus are popular alternatives. I personally favor Ubuntu Mono.

Bells

Terminal bells by default in PuTTY emit the system alert sound. Most people find this annoying; some sort of visual bell tends to be much better if you want to use the bell at all. Configure this in Terminal > Bell:

Using taskbar bell in PuTTY

Given the purpose of the alert is to draw attention to the window, I find that using a flashing taskbar icon works well; I use this to draw my attention to my prompt being displayed after a long task completes, or if someone mentions my name or directly messages me in irssi(1).

Another option is using the Visual bell (flash window) option, but I personally find this even worse than the audible bell.

Default palette

The default colours for PuTTY are rather like those used in xterm(1), and hence rather harsh, particularly if you’re used to the slightly more subdued colorscheme of terminal emulators like gnome-terminal(1), or have customized your palette to something like Solarized.

If you have decimal RGB values for the colours you’d prefer to use, you can enter those in the Window > Colours section, making sure that Use system colours and Attempt to use logical palettes are unchecked:

Defining colorschemes in PuTTY

There are a few other default annoyances in PuTTY, but the above are the ones that seem to annoy advanced users most frequently. Dag Wieers has a similar post with a few more defaults to fix.

Terminal colour tolerance

Using 256 colour terminals with applications like Vim and tmux is pretty much a no-brainer; it’s been well-supported on most GUI terminal emulators for ages, including Windows emulators like PuTTY, and gives you a much wider spectrum of colour with which to work and to apply useful features like syntax highlighting and contextual colours for shell prompts.

The problem is that not all terminals are created equal. Occasionally, you’ll find yourself needing to use a console, perhaps with the linux type, when your X server doesn’t start or you’re using a KVM. Following the principles of graceful degradation, it’s a good idea to arrange your terminal configuration and any other applications that normally take advantage of the wider 256 colour spectrum to start up normally with no errors, and to use sensible values instead as supported by the terminal.

Bash

You can check the number of colours supported by your $TERM setting using the tput command:

$ tput colors
256

On systems using termcap, the syntax is slightly different:

$ tput Co
256

This provides you with an accessible way to set up graceful degradation for any colours that you use in your .bashrc file or other startup scripts. By way of example, in my .bashrc file I include the following stanza that adjusts the colour of my prompt depending on whether I have root privileges:

if ((EUID == 0)); then
    PS1=${color_root}${PS1}${color_undo}
else
    PS1=${color_user}${PS1}${color_undo}
fi

The variables contain the terminal escape codes used to start painting text in appropriate colours for the terminal type. I set these earlier on in the file by checking the output of tput colors:

colors=$(tput colors)

# Terminal supports 256 colours
if ((colors >= 256)); then
    color_root='\[\e[38;5;9m\]'
    color_user='\[\e[38;5;10m\]'
    color_undo='\[\e[0m\]'

# Terminal supports only eight colours
elif ((colors >= 8)); then
    color_root='\[\e[1;31m\]'
    color_user='\[\e[1;32m\]'
    color_undo='\[\e[0m\]'

# Terminal may not support colour at all
else
    color_root=
    color_user=
    color_undo=
fi

The above conditional restricts the colour space to conform to what the terminal explicitly specifies is supported. If no colours at all are supported, the variables are empty, and the prompt is simply printed with no colour at all.

Vim

A familiar structure from a lot of Vim colorscheme definition files is:

if has("gui_running") || &t_Co >= 256
    ...
endif

This has the effect of checking that either gVim is running, or that the terminal is capable of printing 256 colours. You can therefore use this and similar structures to delineate different sections of the file to apply based on the number of colours supported by the terminal.

if has("gui_running") || &t_Co >= 256
    ...
elseif &t_Co >= 88
    ...
elseif &t_Co >= 8
    ...
endif

It’s not really a good idea to define this sort of stuff in your .vimrc file; colour information should go into your colour scheme file.

Tmux

Things are a little tricker in tmux. Conditionals based on shell output are supported in recent versions. If you have a particular line of your configuration that will only work on terminals that support a certain number of colours, you can prefix that line with an #if-shell call:

if-shell 'test $(tput colors) -ge 256' 'set-option -g default-terminal "screen-256color"'

The above will only set the default terminal to screen-256color for new sessions if the test call returns a result greater than or equal to 256. Note that you need to wrap both the shell test and the configuration to run in quotes for this to work.

You can preface every applicable line with this test, or if you’d prefer to only run one test for efficiency reasons, you could arrange to load a separate local configuration file only if a single test passes:

if-shell 'test "$(tput colors)" -ge 256' 'source-file ~/.tmux.256.conf'

Unfortunately, there’s a race condition in tmux that means that the first shell can be established before the default-terminal configuration item is actually applied, meaning that the default $TERM of screen is used for the first window, but subsequent windows are correctly created with the screen-256color setting for $TERM. One possible workaround for this is to preserve the old terminal’s name in an environment variable:

containing_term=$TERM
if-shell 'test "$(tput colors)" -ge 256' 'set-option -g default-terminal "screen-256color"'

You can then check this variable’s value in your .bashrc file to see if it’s a terminal known to support 256 colours, and if it is, force the screen-256color terminal type for the shell:

case $containing_term in
    *256color) 
        TERM=screen-256color
        unset containing_term
        ;;
esac

This problem may well be fixed in future versions of tmux, but it still seems to be an issue even in the developing 1.7 version.

All of the above goes a long way to making your personal set of dotfiles more robust, so that when you need to bust them out on some older machine or less capable terminal, they’re more likely to work properly.