vimclippy

There used to be a nifty Mac utility called QuickCursor. It set up a global hotkey you could use whenever you were editing text in any app. When invoked, it would open up a copy of your chosen text editor1 passing the text into it. You could then edit away using the FULL POWER of your editing setup, and when you saved the file the text would be copied back into the app where it came from.

It was pretty rad.

Unfortunately, changes to the Mac App Store and sandboxing rules meant it could no longer be sold there, so it’s no longer under development. 😫

But do not despair! I present to you the next best thing. viz. a shell command that will open a copy of Vim with a buffer containing the contents of your clipboard, and AUTOMATICALLY copy the edited text back into the clipboard when you :write the buffer with e.g.:wq.

vim +'silent pu!+' +'$d _' +'1' +'set nomodified' +'au BufWriteCmd vimclippy %y+ | set nomodified' vimclippy
Note
For this to work your copy of Vim must be compiled with +clipboard support.

If you change your mind halfway through and want to leave your clipboard the heck alone, just exit without saving::q!.

Installing it

I see you are ASTONISHED and CLAMOURING to find out how you can set up a shortcut to allow INSTANT access. I got your back!

Add this to your .bashrc or .zshrc:

vimclippy() {
  vim +'silent pu!+' +'$d _' +'1' +'set nomodified' +'au BufWriteCmd vimclippy %y+ | set nomodified' vimclippy
}

Or for fish, run funced vimclippy, enter the following, save, and then run funcsave vimclippy to make it persistent.

function vimclippy
  vim +'silent pu!+' +'$d _' +'1' +'set nomodified' +'au BufWriteCmd vimclippy %y+ | set nomodified' vimclippy
end

Users of the venerable Windows Command Prompt will want to drop a file named vimclippy.bat somewhere in their %PATH% with the contents:

vim +"silent pu!+" +"$d _" +"1" +"set nomodified" +"au BufWriteCmd vimclippy %%y+ | set nomodified" vimclippy

Now you can just run vimclippy whenever you need to tamper with your clipboard contents!

If you use ksh or csh or something then I’m afraid you are on your own but I’m sure you will figure it out I have faith in you.

How does it work?

When you run Vim, you can pass in commands to be executed on startup with a + flag. We pass in five of these:

silent pu!+
Mildly scatalogical overtones aside2, this uses the :put command to insert the contents of the clipboard via the + register at the start of the buffer. We use :silent to prevent Vim displaying a message to say that it’s done so.
$d _
Before we :put the clipboard contents, there was an empty line in the buffer. This is now at the end of the buffer, so we remove it by passing the $ range and the _ black hole register to the :delete command.
1
But now the cursor is at the end of the buffer, which could be DISORIENTING. :1 will move it back to the first line.
set nomodified
Tell Vim that the buffer hasn’t been modified. This allows you to quit immediately with:qif you decide you don’t want to make any changes.3
au BufWriteCmd vimclippy %y+ | set nomodified
This is the CRUX of the tool we are creating.

au BufWriteCmd vimclippy sets up an autocommand that, when editing a file named vimclippy, replaces the normal file-saving mechanism with the commands that follow.

%y+ uses a % range to :yank the entire contents of the buffer into the + register.

| allows you to include multiple commands in a single autocommand.

Finally, set nomodified marks the buffer as not having any unsaved changes (so we can :quit), and informs our BufWriteCmd that the “write” operation was successful.

Pretty keen, n’est ce pas?

Shouts out to reddit user u/Hauleth who came up with the original version of this that I’ve tweaked slightly.

See also

If you’re looking for a more ROBUST solution, you might like to check out vim-anywhere. I’ve never tried it, but I presume there are EDGE cases that my solution doesn’t quite cover.

Update 2023-05-23

If you use the iOS app iVim, and would like to know how to set up an iVimClippy shortcut, tap here to find out how!


  1. i.e. Vim ↩︎

  2. If like me you have the mind of a twelve-year-old boy, feel free to use the full version of the command in order to prevent sniggering: silent put!+ ↩︎

  3. Thanks to @tt345 for requesting this. ↩︎