Haha, I think I am worse than you, I mostly jump around between different projects, and of course, as I have no system in place to track progress, I sort of forget what I was doing the last time, and somewhat start again with the same project when I return. :D
Not that I mind though, I write big programs at work, I don't want to do that in my spare time as well. One job is enough. I use my spare time for writing small or interesting programs. I do spend time thinking why it happens and how I could change that behavior though.
As for the topic of avoiding pitfalls, I found several ways to avoid getting lost in the maze of arbitrary coding. For difficult problems I do a lot of thinking how to implement things. When I have a vision of how it should be done, I can code that without derailing into other subjects.
For simpler problems, focus on the end-result also tends to work for me, even when the implementation is not fully clear. You need some kind of global path what to implement in which order though, but that is not too hard. Distractions from the goal then end up as comment “// XXX Enhance this by implementing blah blah bla” for future decision (most likely never, but writing that line gets it out of my head).
For an editor experiment I used a feature list like below. Just a text file with lines and a “[ ]” prefix in front. Near the bottom you add new features to do, you shuffle features roughly in implementation order, and when done, change “[ ]” to “[x]” .
[x] (v1) Display some static text with a cursor.
[x] Move cursor vertically
[x] (v3) Move cursor horizontally
// Horizontally, cursor jumps due to different character widths.
[x] Replace list of lines with gapbuffer.
[x] Add 'change' concept
[x] Add edit stack
[x] Add letter
[x] Remove letter
[x] Join lines with delete/backspace
[x] enter key
(v4) cursor arrow movement, insert letter, enter, backspace, delete
[x] position cursor with mouse
[ ] Implement jumpy movement (DocumentView.moveCursorHorizontal function)
Use tokens for jumping.
[x] block selections with ctrl+cursor
[ ] block selections with double click
[ ] block selections with drag
[ ] block paste https://docs.oracle.com/javafx/2/api/javafx/scene/input/Clipboard.html
[ ] block delete https://docs.oracle.com/javafx/2/api/javafx/scene/input/Clipboard.html
[x] Add tokenizing of line
[x] Add notion of language
[x] Add scanner support
[ ] loading files with tab
[ ] indent-size setting
[ ] tab-size setting
[ ] tab
[ ] indent (tab)
[ ] dedent (shift-tab)
[ ] auto-indent
It did work quite nicely, especially when the features are small, so you could perhaps break a big feature into several sub-features. Didn't try that though. I did do some thinking beforehand about main data structures though.
[Off-topic, but while building that editor, I aimed for a simple way to implement the features, that is, nothing smart, nothing special case. What amazed me is that it started to behave like much of the editors we use daily. One of the result for me was thus that we have a world to gain on editor implementation.]
Your post did make me think why the above things work, and it made me remind the book “Freedom From Stress - How to Take Control of Your Life” by David Gamow. One of the things he explains is why we can give advice to others but not to ourselves. The reason for that is being emotionally involved according to the book. You need some distance from the subject to make proper decisions about it. Perhaps this “focus” thing of me is one way to create such distance. Likely there are many more ways to create it.