Here are a few of the key code formatting patterns we use. The names and some of the examples are from Kent’s book.

Inline Message Pattern

The message pattern at the beginning of the method is always formatted on one line, never indented.

Indented Control Flow

Zero or one argument messages go on the same line as their receiver:

foo isNil.

2 + 3.

a < b ifTrue: [...]

Messages with two or more keywords have each keyword-argument pair on its own line, indented one tab under the receiver.

size > 0
    ifTrue: [ ... ]
    ifFalse: [ ... ]

array
    at: 5
    put: #abc

aCollection
    copyFrom: 1
    to: aString size
    with: aString
    startingAt: 1

Blocks are made rectangular, with the starting bracket as the upper left corner, and the ending bracket as the lower right. Use one-line blocks if other rules permit. All other rules apply inside blocks.

ifTrue: [self recomputeAngle]

ifTrue: [^angle*90 + 270 degreesToRadians]

ifTrue:
    [self clearCaches.
    self recomputeAngle]

ifTrue:
    [self
        at: each
        put: 0]

Use cascades if a bunch of zero- or one-argument messages are being sent to the same object.

self listPane parent
    color: Color black;
    height: 17;
    width: 11

Do not use cascades with multiple-argument messages. They are hard to read. For example, if height:width: is a single message, do NOT write:

self listPane parent
    color: Color black;
    height: 17
    width: 11

Instead write:

self listPane parent color: Color black.
self listPane parent
    height: 17
    width: 11

or, better:

| parent |
parent := self listPane parent.
parent color: Color black.
parent
    height: 17
    width: 11

If these rules result in code that looks ugly, chances are that what is really needed is to refactor the method. Don’t question your formatting rules: question the code. Here’s an example:

removeStep
    | stepToRemove |
    stepToRemove := self list selection.
    stepToRemove isNil ifFalse: [stepToRemove isExecutable ifTrue:
        [self list remove: stepToRemove.
        steps remove: stepToRemove]]

The above code is correctly formatted. However, it is ugly. We could try adding extra returns and tabs, in violation of our formatting rules:

removeStep
    | stepToRemove |
    stepToRemove := self list selection.
    stepToRemove isNil ifFalse:
        [stepToRemove isExecutable ifTrue:
            [self list remove: stepToRemove.
            steps remove: stepToRemove]]

Let’s face it, it’s still ugly. A better solution is to refactor, for example:

removeStep
    self removeStep: self list selection

removeStep: aStep
    aStep isNil ifTrue: [^self].
    aStep isExecutable ifFalse: [^self].
    self list remove: aStep.
    steps remove: aStep

When we feel like breaking the formatting rules to make a method look better, we get better code by refactoring, in almost all cases. Give it a try.