The Copy/Paste Challenges of Living in vim
Okay, with that entry out of the way, I have my motivation and invigoration again. Look at precisely HOW you’re going to start publishing content like that. Is it Medium.com again? Finally into that?
:’<,’>w !cat > /dev/clipboard
Okay, this is a vim challenge, and the development of another super-ability, if I master it. At bare minimum, I want to be able to copy-and-paste from my “hard return” 80-character text-wrapped daily journal file that I type in vim (not gvim) on a Cygwin terminal (usually), but could to from any Unix-style text-only terminal. As massively powerful as vim is, this simple task is the sort of place it breaks down, and you need to “cast a magic spell”.
And so here, I develop that spell. The above line of code should show you where I start in my head tackling the problem. Or probably, it doesn’t. I assume too much, you newb! In the vim text editor, without a full background on the videogame-line environment it provides for controlling text, you can highlight text in visual blocks and “pipe” the text from that highlighted text into any external (native Linux/Unix) command line program. You can also return the output, which is how I do my journal timestamps, with:
[Esc]! date
…which produces:
Fri, Jul 21, 2017 10:48:04 AM
And so that above command is what you do to pipe the text from vim into the native operating system’s copy-buffer. It’s the same place things go when you press [Ctrl]c in most any app, and where stuff comes out of when you press [Ctrl]x in most any app. Problem solved, right? Oh no, because I like my text files, including this journal, to be easily viewed in a ready-formatted and highly controlled fashion for display by markdown interpreters, I use hard returns at the end of every line near the 80-column mark. I’m not religious about this, especially when I embed snippets of code, but it is how almost all my journaling “stream of consciousness” writing like you’re reading here is formatted. The paragraphs must be stripped, but without dev work (really) and with enough powerful control that I can be deliberate, yet quick about it.
The keyboard control vip will visually select a whole paragraph. Once selected, the command:
:’<,’>s/\n/
…will strip out all the hard returns. It’s important to point out that these characters are actually created with the following keystrokes:
vip:s/\n/
The funny pattern that vip: becomes is the vim representation of “the text you have highlighted”. So in vim-ease, that statement reads from left to right:
vip = Highlight the text of the paragraph my cursor is in as a visual block
: = Apply to that visual block the following ex command
This appears :’<,’>
s/ = Search and replace
\n = Carriage return
/ = replace with nothing (nothing appears after the slash)
…and do it instantly (no additional /gc parameter)
This is leading me down the path of a macro, where I’d format paragraph by paragraph, highlighting and reformatting each as I go. It’s sort of a pain in the ass, but still appears to be the best approach to the problem. It will combine well with macros I can put in my .vimrc. It’s a long way to go for what is really just a non-issue in other text editors, but… but this is actually such a big win and step forward in my vim-abilities, it’s totally worth it.
Okay the next step after that is to make it fast on a macro.
Okay, the next step after vip:s/\n/ is hitting the o
o = Insert line below
[Enter] = Insert another line in insert mode
I’m tempted to put a zero (0) at the beginning so that the cursor jumps to the beginning of the line before a line is inserted below, but inserting a line below functionally accomplishes the same thing, cutting out that step. So, we’re effectively building a macro here to “flatten” a paragraph into one long line and position the cursor below to do the next paragraph. And that will be:
[Esc]j
…because…
[Esc] = takes you out of insert mode
j = move cursor down one line in the right place for the macro to repeat
Articles like this with a lot of code where the hard returns should actually be preserved will be a bit more challenging, but that just means you (I) have to hit j a bunch of times to get down to the next paragraph flattening. And so, it will be an initializing @[some key] and then a bunch of @@’s to repeat the last macro, with the occasional jjjjj to skip over code blocks and get to the next paragraph beginning.
Jumping through all these loops is worth it, because it’s publishing to Medium.com from a vim markdown file I keep anyway, and is where the majority of my extractable for publishing daily thoughts reside.
This should be the start of something big.
Cutting the catapult ropes.
I’ve been building up to this for awhile.
Next steps will be python-isizing the process, so I don’t have to jump through hoops. I’ll just run a Python script from this same directory, and it will pop the latest article into Medium.com through it’s API in draft format. I did that once with WordPress from this journal years ago, but the endeavor piddled out.
Lessons?
Despite vim’s idiosyncrasies and shortcomings, of which there are plenty, it’s still worth it making it the primary place you capture and refine your thoughts, especially for me, and especially in reverse chronological blog-like form, private by default, kept in markdown, integrated life, one file for life, unable to be lost due to git and Github, and not so private that a leak would be disastrous. Just daily thought processing for career and daddy-hood.
Having succumbed to the allure of one text-editor for life that will take you as far as you want to go (until you’re ready for evil mode in emacs), there are some VERY basics that are VERY difficult in vim, and one of them is preventing me from efficiently extracting articles from here for medium.com, which is my next logical step in sharing my thoughts with you folks.
Ouch, the day is slipping away. But this is a worthy hail mary play. A major part of my life was taken away when I made this journal private again, and this just takes back an major and fundamental capability that I’m missing for amlost ridiculous self-imposed reasons imposed by virtue of preferring terminal-based text for text-based tasks (like this journal) and not wanting to rely on special versions of vim like gvim that simply make copy-and-paste easier, but still lack the line-return stripping. So even if I used gvim to eliminate the
:’<,’>w !cat > /dev/clipboard
…keystroke, I still need this macro. And so all together, it’:
vip:s/\n/o[Enter][Esc]j
…then once all the paragraphs are “flattened”, there’s one more visual select block that’s required before popping it into the copy-buffer, which I can handle without a macro. I think I’ll make one though for copying the visually selected text into the Windows OS copy-buffer, although a different one would be need for Mac, because they write to the pbcopy command instead of writing to the cat command and redirecting that to a device path, which is a very Unixy thing to do and not very Mac-like. So, all Mac’s have a pbcopy command anyone can write to to put stuff in the Mac OS copy-buffer:
:’<,’>w !pbcopy
So, jump to it! Edit your .vimrc! When I cd to ~/ and look at my invisible .vimrc file, this is what I see:
set runtimepath+=$HOME/vim
source $HOME/vim/.vimrc
Good me! I’m using a unified .vimrc across all my machines, thanks to Github.
Okay, I fixed a few mistakes in my macro, and the code that ends up finally in my .vimrc is:
let @p = ‘vip:s/\n/ ^Mo^[j’
…where the [Esc] presses are turned into blue ^[ by typing v[ while holding down the Control key. So you hold down the control key and while still holding it down, hit the v and then the [ key. Same for [Enter] key becoming ^M. You press down the Control key and while continuing to hold it down, tap the v and then the m key. You get the special control character needed for macros embedded into your .vimrc.
And while I’m at it, hit this puppy hope with this new macro in my vimrc to copy highlighted text into my windows copy buffer:
let @w = ‘vip:w !cat > /dev/clipboard’
Hello, Medium.com!
