Recreating Ulysses with VIM

I like to work on a variety of computers. Only one of them is a non-Apple product. It’s a cheapo Lenovo laptop I got three years ago at Black Friday sale for $300. The original Windows 8 didn’t last much longer than the first battery charge. Now it runs Xubuntu Linux off of a small solid-state drive I installed. Overall, its 11″ screen and poor battery life make it a mostly pathetic specimen soon to relegated to the scrapheap.

But for some reason I enjoy using it. Maybe it’s because of Linux and the availability of software. Or maybe it’s just a small, light machine that is easy to carry. Regardless, I plan to keep it around for a while longer. It may even outlast my MacBook. I also think one of the reasons for my fondness is because of how cheap it was. I don’t have a lot invested so any use I get out of it is a win. Other than the dreadfully short battery life (at best two hours) it’s my go-to machine for when I want to get out of the house.

But doing this also causes a break in my workflow. Since Ulysses is Mac/iOS only I can’t use it on the Lenovo. It’s not a huge burden. Text files swap back-and-forth easily. The major hangup is the aesthetics of the writing environment that Ulysses provides. If you haven’t used it, you are missing out. The simplicity of the layout coupled with the integrated writing goals and built-in file organization make it difficult to be away from. Each time returning to Ulysses I feel a little spoiled at just how nice it feels to have an all-in-one place to do my writing.

As with most things, the convenience comes with a price. And that price is baked into the cost of the Apple hardware. Granted, a low-end iPad Mini can be had for about the price of a cheap laptop and will do 90% of what Ulysses on Mac will do. The rub comes when you need that other 10% for things like working on the guts of a ePub file, or any sort of file conversion (KindleGen, I’m looking at you!). For an independent writer responsible for a farm-to-table writing process, it means at some point you’ll need a laptop/desktop computer to pickup the slack from the iPad. Given a house-fire situation, a cheap laptop and an iPad Mini would be my preferred choice of replacements.

So with that in mind, I set out to see if there was any way I could at least partially replicate the Ulysses experience on Linux. I also want to avoid any “odd” software that might not be actively maintained. I’ve also been a VIM user for a very long time. I know it’s an extremely customizable program, and there are a multitude of plugins to add functionality to it. Because of this my search started with VIM and ended with a set of plugins that make it into a reasonable facsimile of Ulysses.

Before going too deep into details, here’s a list of the plugins I used.

  • VIM (in case you’re unfamiliar with it)
  • Goyo, the writing room plugin
  • Limelight, a paragraph highlighting plugin
  • Vim-markdown, an updated markdown syntax highlighter
  • Fountain.vim, a syntax highlighter for .fountain script files
  • NerdTree, a sidebar file browser
  • Seoul256, one of my favorite themes
  • Vim-fugitive, a plugin that integrates Git into VIM
  • Vim-Plug, an easy-to-use plugin manager

The most amazing part of this is how there’s not really much needed in the way of configuration. All of the plugins have sane defaults, and any tweaking of their settings is just for personal taste.

Initial Setup

If you’ve never used VIM, this might not be the best place to start. There’s a lot of great resources on the web to ease people past the shock of a sitting down with a keyboard-driven text editor like VIM. This one is focused on using VIM for NaNoWriMo, and is a good place to start.

One of the most important files you’ll edit while writing with VIM is the .vimrc settings file (the name means “VIM resource”). This is the file that lives in your home folder and controls all aspects of how VIM behaves. It’s also a source of contention between some VIM users who like to argue about the best configuration. In the interest of avoiding all that, I’ll only list a few general settings that should be used when writing prose rather than code.

.vimrc basics

The following are in no particular order, I’m just going down my .vimrc and pulling examples. These are also some of the more overlooked settings.

set spellsuggest=15

This keeps the spell suggestion window from taking over the whole screen and shows the top fifteen options.

set linebreak

Makes sure lines break on whole words, not in the middle of a word when it meets the screen edge.

set scrolloff=3
set foldcolumn=1

These two work together to keep the cursor away from the edges of the screen. scrolloff keeps at least three lines visible at the top and bottom of the screen unless at the top or bottom of the file. foldcolumn adds one character space to the left edge of the screen. I find this is more pleasant to look at when using VIM normally.

Keybindings and Shortcuts

VIM is all about never having to reach for the mouse. By defining your own shortcuts, it’s infinitely customizable. But the first change you should make is to remap your caps lock key to control. This can be done in the system preferences on a Mac, click the Modifier Keys... button in the Keyboard panel.

In VIM capital letters are different commands than their lowercase brethren. Accidentally hitting caps lock will cause very unexpected results. Plus, on a MacBook the control key is in an awkward place. This change make it easier to reach, as most modifier key commands are based around it. The command key isn’t used.

map j gj
map k gk
map ; :
inoremap jj <esc>
map <space> <PageDown>
" Fix for Ctrl+Space sending NUL
map <NUL> <PageUp>

These are some simple navigation hacks I came up with. Adding the g before j and k makes sure vim moves to the next line on the screen, not just the next full line. Without this, navigating paragraphs of prose would be more trouble than it’s worth. Having ; act line : means there’s no need to press shift to enter command mode. Converting jj to escape avoids your fingers from leaving the home row to exit insert mode. Finally turning the space bar and control+space into page up and page down keys saves hand movement when scrolling.

map <leader>s :setlocal spell<cr>
map <F1> [s
map <F2> z=
map <F3> ]s
map <F4> zg
map <F5> zG

I personally have a hard time remembering the spell checker commands. This batch of shortcuts saves me from that. The <leader> in this case is either the default \ (backslash) or what ever you might have it remapped to. (Note: you don’t press and hold the leader key, just tap it and the tap the next key.) I use , instead, as it’s easier for me to reach. <leader>s starts the spell checker for the current window. Then the F-keys will let me quickly move through the document. F1 searches for the previous misspelling, F3 the next. In between, F2 will bring up the replacement list. F4 adds the word to my personal word list, while F5 adds the word to a temporary list that clears when VIM is closed. So now I can do most of my spell checking with only four keys.

Plugins and their settings

The first plugin I suggest installing is a plugin manager. There are several options, but if you’re not using one I suggest Vim-Plug. The configuration is simple and it can be self-installing, while also automatically install all of your plugins. Simply add the following to the top of your .vimrc:

if empty(glob('~/.vim/autoload/plug.vim'))
  silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
  autocmd VimEnter * PlugInstall | source $MYVIMRC

What it does: if there’s no ~/.vim/autoload/plug.vim file, it downloads the latest version then runs its install command to install the plugins you’ve specified in your .vimrc. This makes it easy to have a consistent VIM environment no matter what machine you happen to be working on.

As for the plugins you want to install, simply list them between call plug#begin('~/.vim/plugged') and call plug#end() lines. Again, it’s best to have this at the top of your .vimrc. See the Vim-Plug page for more instructions.


I use Vim-markdown to get the most updated Markdown syntax highlighting, because the version of VIM installed might not be the latest version. Markdown is natively supported in VIM, so if your version is up-to-date, don’t bother. Fountain.vim is for .fountain files, and as the original plugin hasn’t been updated, so I’m hosting it on my Github with pull requests applied.

Seoul256 is entirely optional. It just happens to be my favorite. It’s unique in that it will adjust its tones depending on the background setting. I use let g:seoul256_background=234 most of the time. Make sure to do that before you load the theme. Placing it on the line before colorscheme seoul256 is enough.

The Writer’s Room

The Goyo plugin does the heavy lifting of getting VIM to emulate Ulysses. Its job is to black-out the interface and present a writing area centered on the screen. It’s actually quite elegant.

The only change I made to the default setting was to narrow the sides in some. The default is 80%, I find 65% to match my taste better. So I added let g:goyo_width = 65 to my .vimrc.

One feature I really like about Ulysses is the line highlight option. This draws the eye to where the cursor is. A simple alternative in VIM is the Limelight plugin from the same author. This will darken the non-active paragraphs while leaving the current paragraph undisturbed. When drafting this is quite nice as the focus is completely on the new words. It works without much user intervention, except for the need to activate it each time. Since I only use it with Goyo, I added the following two lines to my .vimrc:

autocmd! User GoyoEnter Limelight0.7
autocmd! User GoyoLeave Limelight!

So when I activate Goyo with <leader>w Limelight switches on. It also switches off when I deactivate Goyo. This makes it pretty much invisible in day-to-day use.

The Sidebar

One of the main attractions of Ulysses is the way it stores your writing. The library keeps track of everything and there’s no need to manage individual files. They have a nice safe place to live and are automatically backed up to iCloud. Once outside of Ulysses, this really isn’t possible. Especially when using multiple operating systems.

One plugin, NerdTree, does offer a workable solution. It’s a sidebar file browser. I have it mapped to Ctrl-N with map <C-n> :NERDTreeToggle<CR> One of NerdTree’s nice features is to have a list of bookmarks for frequently used files and folders. Pressing Shift+b (or capital B) toggles the bookmark list. The command :Bookmark will save the highlighted file or folder to the bookmark list. Also note that the file doesn’t have to be opened, just selected in the NerdTree browser.

Of course, this means file management becomes something requiring thought again. So I’ve found it’s better to just recreate the Ulysses group structure with regular folders. It’s more work, but it is portable across operating systems.


Sometimes, it seems that the little things are what you miss the most. For me it’s Ulysses’ writing goals. I really enjoy seeing the little circle fill up. There’s not much that can recreate this, especially when you have to use multiple files. But there is a way to at least see the word count of the current document without having to use external tools.

I added a word count function to my .vimrc and have it shown in the status bar.

This is the function and some additional bits to make it work:

let g:word_count="<unknown>"
set updatetime=1000
augroup WordCounter
  au!  CursorHold,CursorHoldI * call UpdateWordCount()
augroup END
function WordCount()
  return g:word_count

function UpdateWordCount()
 let lnum = 1
 let n = 0
 while lnum <= line('$')
   let n = n + len(split(getline(lnum)))
   let lnum = lnum + 1
 let g:word_count = n

Now, I can use %{WordCount() in my status line. There’s a couple other parts that are needed for it to work. First the status lines needs to be shown. By default it’s not. By setting set laststatus=2 it will be. To show nothing but the word count you can set the statusline variable to something like:

set statusline=%=\ %{WordCount()}

Then you’ll have the word count in the bottom right of your screen. It’s not a writing goal, but it’s better than nothing.

Git for Writers

The replacement of Ulysses library and it’s iCloud/Dropbox syncing and version control can be replaced with Git and Dropbox. The Vim-fugitive plugin makes it possible to do most of the Git version control operation from inside VIM.

While a full discussion of Git & VIM is worth another article, here’s a brief overview.

I have a “bare“ git repository in my Dropbox folder. This is so I can push and pull from it anywhere Dropbox is installed. I would be possible to just work from the Dropbox folder, but I find it more convenient to have my working folder elsewhere. Plus, with Dropbox acting like a server, it’s possible to delete the working folder and not have it deleted from Dropbox. It’s an easy way to add a layer of accident protection to my day.

I also keep my .vimrc and other files in a Git repository, so I can have a consistent VIM environment across computers with a simple git pull.

Wrapping Up

Ulysses is an excellent writing app, with only one bad feature. It’s Apple only. This makes it hard to break away from the Apple-centric ecosystem and use other software. But with a few tweaks, VIM + Git can come close. It’s not a perfect solution, but I’m confident that I could get by with minimal interruption should I need to use commodity hardware.

MVW: The idea of the Minimum Viable Writer

With all of the changes that are happening in the world as we dive headfirst in to 2017 I’ve started to inventory my needs as a writer. My name for this project is the MVW or Minimum Viable Writer. This is a play on the idea of a “minimum viable product” that is popular in the culture of tech startups. It’s an idea rooted in the concept of doing as little as needed to launch a product or service. The goal is to let the market decide if it will be profitable before investing too much time and money into it.

With this in mind I started to think about what are the minimum resources needed to write and publish. So let’s start with some definitions.
This is how I define what makes up a MVW:
Continue reading “MVW: The idea of the Minimum Viable Writer”

Making an eBook with Ulysses: a complete guide

I’ve been working on this article for a while. Ever since I started experimenting with ePubs exported from Ulysses, I’ve been blogging my results. Now I’m ready to share a full eBook production process using Ulysses and my KBasic style.

After introducing my KBasic style, I found that I still wanted to make some adjustments to it. Actually it was more than just a few adjustments. I tried the style on several eReaders and found that I needed to change the text markup too.

I’m not going to bury the lede on this one. The sample eBook I made for this article looks damn good.

Continue reading “Making an eBook with Ulysses: a complete guide”

A Drag and Drop File Uploader for WordPress Blogs

This is a simple app that I built with Apple Automator that I’ve been using to upload files to this blog. Overall, WordPress’s web page uploader works well, but it requires a browser window be open. Sometimes I just want to send a file quickly and not bother with that. One of the reasons people like my Post to WordPress plugin for Ulysses is that it avoids having to open up WordPress to save a draft post.

Continue reading “A Drag and Drop File Uploader for WordPress Blogs”

Using Ulysses and Vellum for High-quality eBooks

The Ulysses app can do a lot besides writing. I’ve written a lot about how I abuse the poor thing. Its export options offer a variety of formats. One that was convenient was the RTF option. It meant I had one click export to a standard rich text format that’s usually requested by publishers.

The v2.1 Ulysses update replaced RTF with DOCX, the new Word 2007 format. These files aren’t usually accepted via email because of the chance that they carry a macro virus. (Have you noticed all the email spam that includes an “invoice”? Yep, those files come contain a DOCX file pre-loaded with a macro virus!) Even so, I was a bit miffed when the Ulysses developers made me resort to another app to deal with the Ulysses export.

But I also found that there’s a couple of ways this also helped me out.

Continue reading “Using Ulysses and Vellum for High-quality eBooks”

Post to WordPress from Ulysses update 5/20

I’ve made a significant update to my app Post to WordPress for Ulysses today.

I’ve improved it so that there’s no need to edit the Automator app or need two parts (app & code file) for everything to work. The blog information (user name, password, URL, and SSL preference) is now stored in a separate file. Also, all the posting code is now inside the app, and the user doesn’t need to create a ~/bin folder to keep the Ruby code file in.

The ReadMe file has all the updated information and the install will be much simpler.

Even though Ulysses is beta testing a WordPress posting feature, my solution will work with the current version. I’ve also tested it against the beta, and it works the same. The one thing I like most about my app is that it converts any links into ones that open in a new window. There’s no way for this to be done in Ulysses, and having to do it manually in WordPress is tedious at best.

I’ve also decided to quit fighting with WordPress about how it interprets timezones. Posts uploaded with the app will now be plain drafts instead of scheduled posts.

Continue reading “Post to WordPress from Ulysses update 5/20”

New Ulysses ePub Style

I just uploaded a style sheet for the Ulysses writing app that I’ve been working on to the Ulysses Style Exchange. It’s called KBasic and it’s meant to make creating ePub files easy.

I’ve been fighting with ePub formatting for a while now. It turns out I was trying to do too much. The eReaders (hardware & software) do a great job of displaying even unformatted text. I even experimented with using a blank stylesheet to see what would happen. The result was actually better than some styles available for download.

So I started from that blank page and built up the elements that I wanted, and let the defaults handle the rest.

Here’s the list of what I changed:

Continue reading “New Ulysses ePub Style”