I’m a long-time Ulysses user, and I appreciate it since it’s a great Mac citizen, but I’m moving towards more open formats and possibly keeping more of my raw source files in Git.
I started using iA Writer a couple of months ago for my Zettelkasten writing, and having it as a backbone of my Jekyll site turned out to be great. On the other hand, I still kept my writing workflow in Ulysses, especially for long-form writings. I just wrote about how I use Ulysses projects in my writing workflow.
I wonder if having iA Writer as my only writing app is beneficial. I start to think it is, so I’ll discuss that in this post.
Keeping my writings in a Git repository
Git should be used by more people, not only by developers. It is a powerful system for keeping track of changes in a project, and it’s easy try out new ideas by creating new branches.
Git is made for text, so keeping writings in a repository is a natural workflow. For me, it’s new, though; I always used some form of library-based app for managing my writings where you can export the final product, but the raw material is usually kept in a proprietary database or file format.
iA Writer, on the other hand, uses standard text files – specifically Markdown files – and keeps them in the file system, so we can store our files in Git repositories, which can be edited directly as folders in iA Writer. I use Tower on the Mac and Working Copy on the iPad to manage all my Git repositories and to commit my changes.
The beauty of keeping my writings as simple text files is that I can work on them using multiple apps (even in Ulysses). I like the idea that I can write in iA Writer and edit my documents later in MacVim/ iVim or BBEdit. Different text editors are made for various purposes so that I can use the best one for the task. There is no one-size-fits-all.
Keeping my Markdown files simply in the filesystem, I can also capitalize on other tools like Tmux for managing Vim sessions; using it, I can even write in the Terminal (the original distraction-free writing environment) and have access to multiple panes.
Git is also an open system so I can push changes to any standard Unix-based server over SSH. Keeping my writings up-to-date between devices is not automatic but pretty straightforward to do.
Using Git for marking milestones
In Ulysses, I had this milestones-based workflow where the main writing group in the project got manually duplicated.
- I kept groups where all sections were sheets, then duplicated these groups before significant edits and assigned version numbers for each group, like v1, v2, etc. These names had no meaning other than having a version number for the group.
- The triggers for duplicating groups were the following:
- Collected and sorted my Zettelkasten notes.
- Finished the first draft.
- Checked the grammar with Grammarly (which is just another form of editing).
- The final version before publishing the post.
Since I can use Git directly with iA Writer, I no longer need to duplicate groups manually. I can use Git to keep the history and mark important milestones.
Keeping history in Git is pretty straightforward: I can commit my changes and have a version history on every file. I can create branches for each writing project, so my main
branch only includes finished and published content. This is not that important since all of my posts are siloed into separate folders, but I still keep pull requests open for each article to comment on and see the history of changes in a nice interface.
Pull requests also mark a project’s start and end at the point of opening and merging. This is more of a psychological benefit I like to have: I feel a sense of accomplishment when I finish a project and merge it into the main
branch.
Managing milestones is done through Git as well: I commit in Git that I "Published XYZ v1" or "Published XYZ v2", and then optionally, I tag these commits to mark the end of a milestone.
iA Writer can also publish my writings directly to my blog; this can be used as a marker when I reach a writing milestone. There is no need to duplicate anything locally, but I can export a manual version and keep it published as a hidden post on my blog if I want to return to a previous idea I removed.
I call these posts seedlings, and they aren’t visible in any listing, but they have a direct link, which I can use to preview how the final post will look on my blog.
I created seedlings as a tool primarily for gathering feedback from others on a document. It is my homegrown collaboration feature, which uses my site, where I’m entirely in control of my content. I can publish a hidden post, and then people can leave comments as feedback so we can collaborate without external tools.
But most of the time, I "collaborate" with myself, so I’m leaving comments on my seedlings as notes, which can be migrated back to the actual draft.
Creating pull requests for writings
GitHub pull requests are powerful tools, not just for coding but for writing, too. As I develop my writings, I can keep track of them in separate branches and associated pull requests in my Writings repository.
Pull requests allow me to annotate my text files with comments, which can serve as a built-in to-do system for my writing projects. There is a similar feature is built into Ulysses, where I can have annotations and notes on a sheet, which is one of the benefits of having a library-based app backing my raw content.
On the other hand, using open formats makes using different tools for different jobs on the same content possible. So, in this case, pull requests can be used as an annotation and journaling system around the post I’m writing. When I’m done, I can merge the PR into the main
branch as I do in my software development workflow, then publish the final article on my blog.
Writing in the Terminal
Using Vim in the Terminal for writing is a new experience for me. I usually work all day in the Terminal, but I have yet to consider it a writing environment. Technically, it is the original "distraction-free writing app."
My primary text editor is Vim; next to iA Writer, I started using Tmux to keep my writing sessions open with Vim inside. It is my favorite place to do development work and works well for writing projects, too.
The beauty of plain text is immediately apparent in the Terminal. My eyes love the nice Gruvbox Dark theme, and more importantly, all of my CLI tools are just a couple of keyboard shortcuts away.
I’ve started to use my Mac more for writing-related projects lately. It is one of the most flexible environments (alongside my iPad) for managing my blog and my Zettelkasten. I spent a lot of time optimizing my Terminal environment for development, so having it available for writing is beneficial since the command line is the best place to work on any plain-text project – the two just pair really well since the UI is also text-based.
I can also jump into a running Tmux session from my iPad using Blink and continue my writing session from where I left off.
Section-based writing
In Ulysses, I used sheets for every section. I don’t have sections in iA Writer, but I can have separate Markdown files and include them as content blocks. Content blocks are not a standard Markdown feature, but they are so easy to work with that I’m fine if other apps don’t support them.
Sections are numbered and represent a sequence. When I want to create a new section, I add a unique number in the sequence. I name my sections 001.md
, 002.md
, 003.md
etc. This workflow is similar to how Stephen Wolfram manages his notebooks in project folders: he creates a new file in the folder and starts writing.
I have a bunch of other conventions too. When I’m doing designs, I’ll typically keep my notes in files with names like
Notes–01.nb
orSWNotes–01.nb
. It’s like my principle of not having too many file categories: I don’t tend to try to categorize different parts of the design. I just sequentially number my files, because typically it’ll be the most recent–or most recent few–that are the most relevant when I continue with a particular design. And if the files are just numbered sequentially, it’s easy to find them; one’s not trying to remember what name one happened to give to some particular direction or idea.A long time ago I started always naming my sequential files
file–01
,file–02
, etc. That way pretty much any sorting scheme will sort the files in sequence. And, yes, I do often get tofile–10
, etc. But in all these years I have yet to get even close tofile–99
.
I see this workflow being similar since writing projects can contain other types of assets, not just Markdown. Markdown files in iA Writer can also include code blocks, which can be stored as separate files. Think about that for a second.
Separate code snippets mean I can run these files directly in the Terminal using Ruby, Swift, or any other CLI tool. This gives me an interactive thinking space for code, like outlining, journaling, or mind-mapping. We have interactive notebooks in different environments, but I can make my writing projects similar with automation. It can be a great way to test and document code.
Let’s say I’m working on a new software project: I can have a docs
folder that contains Markdown files linking to external sources in the actual code. Additionally, I can use iA Writer to embed source files as content blocks. When exporting the final version, source files are converted to Markdown code blocks in the output document.
Section-based writing also allows me to work on any part of the text at any time. This is a more natural bottom-up approach that is better than trying to fit my writing into a linear flow, where I start my post with the intro and then write the rest from top to bottom. Writing is the act of trying to fit random ideas together into a final story arc.
Using iA Writer Authorship for marking Zettelkasten notes
One of the main reasons I want to keep all my writing in iA Writer is their new Authorship feature.
It was intended to mark content pasted from other authors or generated by AI, but I want to hack around its intended purpose by marking text that was added from my Zettelkasten differently.
Since I mainly edit my Zettelkasten notes in iA Writer, using the same app as an end-to-end workflow for my final writing projects makes sense. I can switch between my notes and writings and copy and paste text into my drafts. Here’s where the Authorship feature comes into the picture. Since I can paste my Zettelkasten notes as text acquired from other sources, iA Writer would mark these paragraphs in a different style. I actually like this since edits are clearly visible over my original Zettelkasten text.
I have a global Authorship setup in my iA Writer settings, where my Zettelkasten is marked as "Other." This feature was intended for text copied from text-related AI apps, but if you think about it, my Zettelkasten is a "thinking partner," according to Luhmann, so in that sense, marking it as authored by "Other" sources makes sense.
Zettelkasten provides a system that, much like GTD, outlines the necessary physical steps for learning about something, generates new ideas from that knowledge, and links concepts to write a cohesive long-form text.
Creating a story is like developing a skeleton. We will add our precise thoughts on top of this skeleton. These thoughts can come from our heads, or if we use an active note-taking system, our notes can serve as a basis for them.
When we use these notes, we still have to form them in a way that makes sense in the context of the current story. The Authorship feature lets me highlight the differences between a piece of text that is just a source of a draft and the actual text I edited.
Since most of my articles contain notes developed in my Zettelkasten, I want to see these differences. Visually getting a difference between the original note and the edited version makes sense. It lets me visualize the differences between texts from other sources or texts I’m actively writing.
Using iA Writer as an end-to-end writing app
As I mentioned, I’m editing my Zettelkasten in iA Writer. I’m also editing my writings in iA Writer. How about including AI in the same app as well?
I developed a tool a few months ago called RubyGPT, a Ruby gem that lets me use ChatGPT in the Terminal. I also integrated it into iA Writer using Apple Script so I can have an ongoing ChatGPT chat session saved into a Markdown file. These chat sessions are stored in my ~/Documents/Chats
folder, which is also added to my iA Writer library. Sadly, this tool only works in macOS, although I can export ChatGPT chat sessions from Drafts, too, where I’m using this action to have a similar workflow.
All my writing-related plain text lives inside iA Writer, so I consider the app an end-to-end tool for all my writing needs. In theory, I can do this with Ulysses, too, which can also work on external files, but iA Writer doesn’t hide the Markdown syntax, so I can see the original text as John Gruber intended.
With the Authorship feature, I can also see the changes I made to externally generated text, regardless of whether it’s coming from an AI source or my Zettelkasten. I still have to do the work and edit this text into a proper post.
I love this integrated workflow of starting with reading, having highlights processed into notes, getting these notes under control, and then using them as the building blocks of my posts. This workflow lets me naturally develop ideas and use them in places where they make sense.
No need to force anything.
I can write about whatever I feel like at the moment.
I want to use iA end to end as well. However, I don’t know how to configure things so that it can edit files directly in a GitHub repo on my phone. On my laptop this isn’t a problem, since the repo is local. But I don’t maintain a local repo on my phone. Any idea how to config iA to edit GitHub hosted MD files?
I use the Working Copy app on iOS.