Category Archives: tools

Easy Data Transform

I have been furiously coding a new product. Easy Data Transform. It is a Windows and Mac tool for transforming table and list data from one form to another. Joining, splitting, reformatting, filtering, sorting etc.

easydatatransform

I have been thinking about this product idea for years. In fact I threw together a janky prototype back in 2008. It allows you to perform various operations on a pair of lists.

list-weaver

I used this prototype for jobs such as creating a list of emails of people who had bought Perfect Table Plan v5, but hadn’t upgraded to v6 yet. It worked. But it wasn’t very good. The biggest annoyance was that each operation obliterated everything that came before. Which made it very easy to lose track of where you had got to. And there was no repeatability. It was also limited to lists and it became clear that I really needed something that could also handle tabular data. I never released it.

But the idea has been running as a background process in my brain for 11 years since. And I think I have come up with a much better design in that time. Finally I had mature, stable versions of my Perfect Table Plan and Hyper Plan products out, so I decided to go for it. I am really pleased with how it has turned out so far.

If you aren’t embarrassed by v1.0 you didn’t release it early enough. And so I have cut lots of corners to get this first public version out. The documentation is only part written. I created the application icon myself  in 10 minutes. There is no licensing. The GUI is lacking polish. The website would make a designer cry. But the software seems fairly robust. My 13 year old son wasn’t able to crash it after 10 minutes of trying, despite financial incentives to do so.

I did some market research and spoke to some people who knew a bit about this market. But I deliberately didn’t look closely at any competing products, as I didn’t want to be mentally restricted by what others have done. For better or worse, I want to blaze my own trail. Copying other people’s stuff is a zero-sum game with no net benefit to society.

Most of the things that Easy Data Transform you can do, you can also do in Excel or SQL. My claim is that it is much quicker, easier and less error prone to do in Easy Data Transform. No programming or scripting required. I am hoping that people will be able to start using it within a couple of minutes of downloading it (I plan to do lots of usability testing). Will people pay for that? I hope so. I’m not aiming it at programmers. Perish the thought.

Naming is hard. I came up with some 70 names. Things like ‘Data Hero’, ‘Transform Flow’, ‘Transmogrify’ and ‘Data Rapture’. But the domains were taken, people I asked hated them or there was an existing service or product with that name. So I ended up with Easy Data Transform. It does what it says on the tin.

Why desktop? Surely no-one is writing new desktop apps in 2019? I believe a desktop solution has some real advantages in this market. The biggest ones are:

  • You don’t need to load your (potentially highly sensitive) data on to a third party server.
  • Not having to upload and download (potentially very large) data sets makes it much more responsive.

Easy Data Transform is currently free for anyone to use. You can get it from the super-minimalist easydatatransform.com website. The current 0.9.0 version expires on the 4th August 2019. You will then be able to get another free version. Once the product is mature enough, and if I am convinced there is enough demand, I will release a paid version. The free beta will probably last several months. Please try it and let me know how you get on. I am particularly interested to get feedback from anyone using it for real day-to-day tasks.

Of course the real challenge is always marketing. How to get noticed amongst many competing products. As well as helping to improve the product I am hoping that this extended beta will also help me to get some traction and better understand the market. For example, what price to charge and what trial model to use. Watch this space.

Bloviate

I wondered what it would look like if you took a body of text and then used it to generate new text, using Markov chains of different lengths. So I knocked up  quick program to try it.  ‘Bloviate’.

bloviate

Bloviate analyses your source text to find every sequence of N characters and then works out the frequency of characters that come next.

For example, if you set N=3 and your source text contains the following character sequences staring with ‘the’:

‘the ‘, ‘then’, ‘they’, ‘the ‘

Then ‘the’ should be followed 50% of the time by a space, 25% of the time by an ‘n’ and 25% of the time by a ‘y’.

Bloviate then creates output text, starting with the first N characters of the source text and filling in the rest randomly using the same sequence frequencies as the source text.

Note that a character is a character to Bloviate. It treats upper and lower case as different characters, makes no attempt to differentiate between letters, punctuation and white space and does not attempt to clean up the source text. Which also means it works on any language.

Bloviate also tells you the average number of different characters following each unique sequence of N, which I will call F here. As F approaches 1.0 the output text becomes closer and closer to the input text.

Using ‘Goldilocks and the 3 bears’ as input:

If N=1 (F=7.05) the output is garbage. Albeit garbage with the same character pair frequency as the original.

On cre She sl s ramy raked cheais Bus ore than s sherd up m. ged. bend staireomest p!”Sof ckstirigrorr a ry ps.

” f waine tind s aso Sowa t antthee aime bupis stht stooomed pie k is beche p!

At N=3 (F=1.44) it looks close to English, but jibberish:

Once up and been sight,” she this timed. Pretty so soon, she second soft. She screame up and she screame hot!” cried the Mama bed the Papa been sleeping in the Papa bear

“Someone’s bear growl.

At N=5 (F=1.14) it starts to look like proper English, but semantically weird:

Once upon a time, so she went for a walked right,” she lay down into the kitchen, Goldilocks sat in the porridge from the three chair,” growled, “Someone’s been sitting my porridge and she tasted the door, and ran down the bedroom. Goldilocks woke up and she second bowl.

And it comes out with occasional gems such as:

“Someone’s been sitting my porridge,” said the bedroom.

At N=10 (F=1.03) it starts to become reasonably coherent:

Once upon a time, there was a little tired. So, she walked into the forest. Pretty soon, she came upon a house. She knocked and, when no one answered, she walked right in.

At the table in the kitchen, there were three bowls of porridge.

At N=15 (F=1.01) it starts to get pretty close to the original text, but doesn’t follow quite the same order:

Once upon a time, there was a little girl named Goldilocks. She went for a walk in the forest. Pretty soon, she came upon a house. She knocked and, when no one answered, she walked right in.

At the table in the kitchen, there were three bowls of porridge. Goldilocks was very tired by this time, so she went upstairs to the bedroom. She lay down in the first bed, but it was too hard. Then she lay down in the third bed and it was just right. Goldilocks fell asleep.

At N=12 (F=1.07) the whole 680k characters of ‘Pride and prejudice’ produces:

It is a truth universally contradict it. Besides, there was a motive within her of goodwill which could not help saying:

“Oh, that my dear mother had more command over herself! She can have her own way.”

As she spoke she observed him looking at her earnest desire for their folly or their vice. He was fond of them.”

Obviously the source text is important. The Bohemian Rhapsody lyrics make nearly as much (or as little sense) at N=5 (F=1.08) as the original:

Is this to me, for me, to me

Mama, just a poor boy from this to me

Any way the truth

Mama, life? Is this time tomorrow

Carry on as if nothing all behind and face the truth

Mama, ooh, didn’t mean to me, baby!

Just gotta leave me and lightning, very fright out, just killed a man

Put a gun against his head

Pulled my time to die?

At N=12 (F=1.05) 160k characters of Trump election speeches produces:

Hillary brought death and disaster to Iraq, Syria and Libya, she empowered Iran, and she unleashed ISIS. Now she wants to raise your taxes very substantially. Highest taxed nation in the world is a tenant of mine in Manhattan, so many great people. These are people that have been stolen, stolen by either very stupid politicians ask me the question, how are you going to get rid of all the emails?” “Yes, ma’am, they’re gonna stay in this country blind. My contract with the American voter begins with a plan to end government that will not protect its people is a government corruption at the State Department of Justice is trying as hard as they can to protect religious liberty;

Supply your own joke.

I knocked together Bloviate in C++/Qt in a couple of hours, so it is far from commercial quality. But it is fairly robust, runs on Windows and Mac and can rewrite the whole of ‘Pride and prejudice’ in a few seconds. The core of Bloviate is just a map of the frequency of characters mapped to the character sequence they follow:

QMap< QString, QMap< QChar, int > >

You can get the Windows binaries here (~8MB, should work from Windows 7 onwards).

You can get the Mac binaries here (~11MB, should work from macOS 10.12 onwards).

Note that the Bloviate executable is tiny compared to the Qt library files. I could have tried to reduce the size of the downloads, but I didn’t.

To use Bloviate just:

  1. paste your source text in the left pane
  2. set the sequence length
  3. press the ‘Go >’ button

I included some source text files in the downloads.

You can get the source for Bloviate here (~1MB).

It should build on Qt 4 or 5 and is licensed as creative commons. If you modify it, just give me an attribution and send me a link to anything interesting you come up with.

Qt is broken on macOS right now

Let me say up front that I am a big fan of the Qt framework. I have been working with it continuously since the late 90s. Both of my commercial products (PerfectTablePlan and Hyper Plan) are written on top of Qt. But Qt is quite broken on macOS right now. In fact I struggled to find a version of Qt 5 that supported recent versions of macOS and didn’t have a showstopper bug. I must have wasted a couple of weeks grappling with these issues. I am putting my notes here in the hope that they help someone else.

Here are the 4 bugs in macOS version of Qt that have causing me the most headaches:

Qt Version
bug v5.9.6 v5.10.1 v5.11.0 v5.11.1 v5.11.2
QFontDialog broken (link) ok ok ok ss ss
QStaticText::size() returns wrong value for rich text
with line breaks
ss ss ok ok ok
widgets such as QTableWidget do not repaint correctly (link) ok cwa cwa cwa cwa
default QComboBox size is incorrect (link)
ok ok cwa ok ok

Where:

ok = bug not present.

cwa = bug present, but can workaround.

ss= bug present, making release unusable for me (showstopper).

Consequently Qt 5.11.0 is the only usable release on macOS for me and I have to kludge my way around two quite nasty bugs. While the QStaticText issue is fairly obscure (but important for me), how in the hell did QFontDialog get completely broken without anyone noticing? And then not get fixed for two whole releases?! I also know other developers who are having to stick with earlier versions of Qt due to the bugginess of the recent versions of Qt on macOS. This isn’t good enough.

Thankfully the recent versions of Qt are much more solid on Windows.

** Feb-2019 Update: Qt 5.12.0 seems to be a big improvement. **

** Mar-2019 Update: I had to revert PerfectTablePlan to Qt 5.11.0 because versions built with 5.12.0 and 5.12.1 kept crashing deep in Qt. **

** Sep-2019 Update: I had to revert PerfectTablePlan to Qt 5.11.0  again because versions built with 5.12.4 kept crashing deep in Qt. **

** Oct-2019 Update: Qt 5.12.5 fixes all the bugs above and doesn’t seem to introduce any major new bugs that I care about. **

Getting Qt 5.9 working on Windows (eventually)

I have had Qt 5.5 and 5.6 installed on my development machines for some time. Now that I have purchased a new Mac development box (an iMac with a lickably beautiful 27″ screen) I thought it was a good time to update to a more recent version of Qt. I went for Qt 5.9, rather than Qt 5.10, as 5.9 has been designated as an LTS (long term support) release. Upgrading turned into a real chore. I am quickly writing it up here in the hope that it helps someone else, and as a reminder to myself a few years down the line.

I like to build Qt from source. Because then I know it was built using the same compiler, headers, SDK etc as I am using to build my product. And I have more control over how Qt is configured. Also I can patch the source and rebuild it, if I need to. But I have had problems building Qt on Mac before. So I decided to install the pre-built binaries on my new Mac. I installed the latest version of XCode and then the Q5.9.4 binaries. This was a couple of big downloads, but it all went pretty smoothly.

I successfully built Qt 5.5 from source on my Windows machine previously, so I decided to try that for Qt 5.9. I have Visual Studio 2010 installed. This isn’t supported for Qt 5.9.4, so I downloaded Visual Studio 2017. I unzipped the Qt source into C:\Qt\5.9.4, ran ‘x86 native tools command prompt for VS 2017’, made sure Python and Perl were in the path and then:

cd C:\Qt\5.9.4

set QTDIR=C:\Qt\5.9.4\qtbase

set PATH=%QTDIR%\bin;%PATH%

configure -opensource -confirm-license -opengl desktop -nomake tests -nomake examples -no-plugin-manifests -debug-and-release -platform win32-msvc -verbose

nmake

Note that you are told by the nmake script to do nmake install at the end of this. But it tells you somewhere in the Qt Windows documentation not to do this, unless you have set the prefix argument (confusing, I know)

The build failed part way through making qtwebengine. Something to do with a path being too long for Perl or Python (I forget). It seems to be a known problem. Odd as the root path was just C:\Qt\5.9.4. I don’t need qtwebengine at present, so I deleted everything and tried again with -skip qtwebengine:

configure -opensource -confirm-license -opengl desktop -skip qtwebengine -nomake tests -nomake examples -no-plugin-manifests -debug-and-release -platform win32-msvc -verbose

nmake

It seemed to complete ok this time. But using this version of Qt to build Hyper Plan I got an error:

Unknown module(s) in QT:svg

On further examination the SVG DLL  had been built, but hadn’t been copied to the C:\Qt\5.9.4\qtbase\bin folder. Similarly for a lot of the other Qt DLLs. I couldn’t find any obvious reason for this looking through logs, Stackoverflow and Googling. I could possibly do without the SVG functionality, but I wasn’t sure what else was broken. So I decided to give up on bulding from source on Windows as well.

I download the Qt 5.9.4 binaries for Visual Studio 2017. This seemed to go ok, but then I discovered that I could only build a 64-bit application from these. No 32-bit version was available for Visual Studio 2017. Many of my customers are still on 32 bit versions of Windows. So I need to be able to ship my product as a 32 bit executable + DLLs[1].

So I uninstalled Visual Studio 2017 and installed Visual Studio 2015. I then got an error message about Visual Studio 2017 redistributables that I hadn’t uninstalled. So I had to uninstall those and run a repair install on Visual Studio 2015. That seemed to work ok. So then I download the 32-bit Qt 5.9.4 binaries for Visual Studio 2015. I had to download these into a different top level folder (C:\Qtb), so as not to risk wiping existing Qt installs that I had previously managed to build from source.

Eventually I managed to build Hyper Plan and PerfectTablePlan on Mac and Windows. What a palaver though! Qt is an amazing framework and I am very grateful for everyone who works on it. But I wish they would make it a bit easier to install and upgrade! Has anyone actually managed to get Qt 5.9 built from source on Windows?

[1] I don’t bother shipping a 64-bit executable on Windows as the 32-bit executable works fine on 64-bit versions of Windows (my software doesn’t require excessive amounts of memory). I only ship a 64-bit executable on macOS as almost no-one uses 32-bit versions of macOS now.

Tracking your sales pipeline

The purpose of marketing is to generate prospects. People who are interested in your product and might buy it. The purpose of sales is to try to convert these prospects into customers. The key difference between these activities is that marketing is one-to-many and sales is one-to-one. Each sales prospect is going to have different questions depending on their requirements, timescales and budgets.

For low cost products there is generally very little selling. You simply can’t afford to spend significant amounts of time engaging with someone who may or may not buy a product with a $30 lifetime value. But for higher price products (typically B2B), sales becomes more important. Sales activities might take the form of answering questions by email or phone, video conferences, quotes, online demonstrations and perhaps even site visits.

Many of my customers purchase from my website without any active selling. But organizations who wish to buy more expensive licences typically have questions about licensing, pricing, functionality, upgrading etc before purchasing. I characterise the stages of selling to these companies as:

  • Enquiry – Someone has expressed an interest in one of my products and typically has questions about functionality, licensing and/or pricing. Initial contact is usually by email.
  • Qualification – I answer the prospect’s questions. If my product isn’t a good fit for their requirements I let them know, as I don’t want to waste my time or theirs or end up with unhappy customers.
  • Quoted – If the prospect looks like a good fit and is still interested I send them a quote.
  • Verbal agreement – The prospect expresses an interest in buying the product. There may be some negotiation over number of licenses, discounts, payment methods, tax etc.
  • Won/Lost/Cold – I either win or lose the sale, or the prospect stops responding (goes cold).

This step-by-step process is known as a ‘sales pipeline’ or ‘sales funnel’.  Different companies use different terminology and a high-value enterprise sale would probably have more stages. But the process is the same in principal – your marketing (SEO, PPC, word of mouth etc) feeds people into the pipeline at one end and a certain proportion will drop out at each stage. Some will end up as customers.

You can take a very ‘hands-off’ approach to sales and only respond to communications that the prospect initiates. But this is not going to get you the best conversion rate from prospect to customer. People are busy and have lots of conflicting demands on their time. One of your response emails might get lost. Their initial contact might leave the company. It seems a pity to let a prospect slip away, just because you can’t be bothered to send a few follow-up emails.

I don’t really want to do a 30 minute online demo if I think I am only going to sell $50 of software (unless I think the feedback might be particularly valuable). But the more a sale is likely to be worth, the more effort I am prepared to put into it. I have found that I can make a pretty good guess at how much a sale is likely to be worth based on the organization they belong to and the initial questions they ask. And these guesses becomes more accurate as they travel along the pipeline.

Note that I am not trying to cajole or pressure the prospect into buying. I am simply trying to provide them with the information they need so they can make the right choice. If I don’t hear anything for a while I will email them something along the lines of:

Did you make a decision regarding purchasing ? Please let us know if you need any further information. We would be happy to call if you would prefer to discuss it on the phone.

If they reply that they aren’t interested or don’t reply after 2 or 3 emails from me, then I stop chasing them. No need to be an asshole about it.

I’m confident that I could increase my conversion rate by following up prospects by phone, instead of emailing them (most B2B prospects include contact details in their sig or are easy enough to Google). But that isn’t something I can summon up enthusiasm for, so I don’t do it. If I was less secure financially, I would be on the phone a lot more.

The issue is then, how to track the various sales prospects so you can follow them up as appropriate? Initially I just tracked sales by having a ‘prospects’ folder in my email client. I would put email from prospects in this folder. Occasionally I would go through the folder and email prospects who hadn’t replied in the last few weeks. If they didn’t reply to a few emails I would move them out of the ‘prospects’ folder. It wasn’t very efficient and there were all sorts of questions I couldn’t easily get answers to, including:

  • What stage was each prospect at?
  • How long was it since I last contacted a prospect?
  • Was there anyone I needed to follow up today?
  • How many prospects were there at each stage in the pipeline? What did I think those prospects might be worth?
  • How were the sales divided into industry sectors (e.g. businesses vs charities vs government)?
  • What proportion of sales was I winning and losing?
  • How did the sales breakdown between new customers and upgrades? Direct sales and resellers?

But it just so happens that my own Hyper Plan product is excellent as sales pipeline software.

I now add a card into Hyper Plan for each prospect that I think might realistically purchase $200 of software or more.

sales pipeline software crm

Store any data about your prospects in custom fields.

I can then very easily slice and dice the data in any number of different ways. For example:

sales pipeline software

Active prospects are automatically arranged by sales pipeline stage and coloured by estimated value. Won/Lost/Cold cards are hidden by a filter. The card with the red highlight is overdue a follow-up call.

sales pipeline visualization

Active prospects are automatically arranged by when we last contacted them (column), when they last responded (row) and coloured by sales pipeline stage.

sales pipeline chart software

Charting the number of prospects at each stage of the sales pipeline.

Sales pipeline statistics software

Charting the number of prospects at each stage of the pipeline, by sector.

This has given me a lot more insight into how I am doing at sales and made me a lot more organized at following up prospects.

A few random things I have learnt about sales over 13 years of running my own software business:

  • Some organizations will buy on the same day they first contact you. Other may take years. Generally the bigger and more famous the organization and the bigger the order, the longer it takes.
  • Organizations sometimes ask for changes to my licensing agreement. I always refuse as it just isn’t worth the expense and stress of getting a lawyer involved. They usually buy anyway.
  • Don’t give additional discounts to ‘value subtracted resellers’. It almost certainly won’t make any difference to whether they purchase or not.
  • Sometimes it is quicker and more effective to talk on the phone, rather than sending lots of emails. But I will generally ask if it is ok by email, before calling.
  • Trying to get video conferencing to work so you can demo your product can be a real headache. Every organization seems to have a different preferred video conferencing solution.
  • Once you are confident your product is the right one for a prospect ask for the sale (‘close’). ‘Would you like to talk about licensing?’ is a not-to-pushy way to move the conversation onto money.
  • You don’t have to be dishonest or pushy. Just give prospects the information so they can make the right decision.
  • Prospects generally won’t tell you that they aren’t interested. They just stop replying to emails.

Hyper Plan is available for Windows and Mac. The Home edition, which has everything you need for sales pipeline tracking, is just $40. Download the free trial and start tracking your sales pipeline.

Hammer For Mac static website generator

I prefer static websites to a CMS for simple product websites because:

  • Static websites are fast.
  • I have more low-level control over the HTML/CSS.
  • I don’t have to worry about the very-real threat of a CMS being hacked.

Obviously writing every page separately in raw HTML/CSS would go against one of the cardinal rules of development, Don’t Repeat Yourself. But you can avoid this using a static website generator such as Hammer for Mac.

hammer

Hammer uses a simple syntax embedded in HTML comments to ‘compile’ a website from source files. I have now used Hammer to create several static HTML/CSS websites, including my perfecttableplan.com and hyperplan.com websites.

I like the simple syntax of Hammer. For example:

I can put the HTML for a page header in an _header.html file and then each page just needs to start with:

<!-- @include _header.html -->

I can define and use variables:

<!-- $current_year 2016 -->
..
<p>Copyright <!-- $current_year -->.</p>

And I can let Hammer work out relative paths:

<img src="@path image.png" />

If Hammer can’t make sense of a source file (e.g. it can’t find the image file), it generates a compilation error.

Because everything is text based I can easily manage all the source in a version control system. Also, if I have to move away from Hammer, it should be relatively straightforward to change the syntax to another static generator (or even write a replacement for Hammer!).

Overall I like Hammer. But it does have a number of shortcomings:

1. The user interface is very limited. Hammer shows you a list of source files and you can click on a source file to see the compiled version or edit the source. But the source files are listed in the order they were edited and you can’t filter or sort the list. This seems such a simple and basic feature, that I can’t understand why the developers have omitted it.

2. Hammer takes a dumb, brute force approach to compilation. If you change any file in a source folder, it recompiles *everything*, without checking if other source files include that file. This is a pain if you have 100+ source files. Surely it wouldn’t be that hard to work out which files depend on which and only recompile the files that need recompiling?

3. You can’t nest variables. For example you can’t do this:

<!-- $current_year 2016 -->
<!-- $copyright_message Copyright <!-- $current_year --> -->

This might sound minor. But it limits the expressiveness of variables significantly.

4. The vendor doesn’t do email support. If you want to communicate with them you have to use Slack or Twitter. I am old fashioned, I like email.

5. It only runs on Mac OS X (the clue is in the name).

At one point Hammer looked like abandonware, but owner riothq.com sold it to beach.io and active development has resumed.

Currently Hammer is priced at £15.39 (and presumably some round number of US dollars). That seems way too cheap. I wish they would price it a bit higher and fix some of the issues above.

 

Pretty printing C++ with Clang-Format

I use some of the code generation and refactoring tools in QtCreator. These save a lot of time, but they don’t format C++ code how I like it. For example they produce C++ code like this:

void MyClass::foo(int *x)

But I like my code formatted like this:

void MyClass::foo( int* x )

The differences may seem minor, but they are a source of significant irritation to me. I like my code how I like it, goddammit! And consistent formatting enhances readability. However re-formatting it by hand is time-consuming and tedious.

What I need is a tool that can enforce consistent formatting in the style that I like, or something close. I have tried to use automatic C++ formatting (pretty printing) tools in the past, but I couldn’t get them to produce a format that was close enough to what I wanted. But I have finally found the tool for the job. Clang-Format.

Clang-Format is part of the LLVM family of tools. It is a free, command-line tool that reformats C++, Objective-C or C according to the settings in a config file. As with many free tools, it isn’t terribly well documented. Some of the documentation on the web is out of date and some of it is incomplete. But I have managed to find out enough to configure it how I like it.

To run it you just need to place your options in a .clang-format file, make sure the clang-format executable is in the path and then run it:

clang-format.exe -i -style=file <C++ file>

Here are the settings I am currently using in my .clang-format file:

Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
  AfterClass:      true
  AfterControlStatement: true
  AfterEnum:       true
  AfterFunction:   true
  AfterNamespace:  true
  AfterObjCDeclaration: true
  AfterStruct:     true
  AfterUnion:      false
  BeforeCatch:     true
  BeforeElse:      true
  IndentBraces:    false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
PenaltyBreakBeforeFirstCallParameter: 100
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 10000
PointerAlignment: Left
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: true
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: true
SpacesInParentheses: true
SpacesInSquareBrackets: true
Standard: Cpp11
TabWidth: 4
UseTab: Never

It took me a few hours of fiddling with the settings to find the best combination. It would be really useful if someone could write a tool that would analyze your C++ code and create a .clang-format file for you. You would probably only want to do this once though, so I don’t think it has much potential as a commercial product.

There are only two things I couldn’t get quite right in the formatting:

  1. I couldn’t get it to add a blank line after public, protected and private declarations. I fixed this with a quick Perl hack (see below).
  2. I couldn’t get it to indent continuation lines how I would like (ideally indented 1 or 2 spaces from the first line). It is a small price to pay and I am just putting up with it for now.

Perhaps there are options to do these and I just didn’t find them.

Here is the Windows .bat script I used to format all the C++ files in a folder.

for %%f in (*.h *.cpp *.inl) do (
clang-format.exe -i -style=file %%f
)

for %%f in (*.h) do (
clang-format.exe -i -style=file %%f
perl -p -i.bak -e "s/public:/public:\n/g" %%f
perl -p -i.bak -e "s/protected:/protected:\n/g" %%f
perl -p -i.bak -e "s/private:/private:\n/g" %%f
perl -p -i.bak -e "s/    Q_OBJECT/Q_OBJECT/g" %%f
)

del *.bak
del *.tmp

No doubt there is a more elegant way to do the Perl, but it works.

I now just run this batch periodically to keep my code beautiful and consistent.