Vim macro recording is really nice

This is probably a big "duh" for anyone who's used it before, but Vim's macro recording is pretty handy.  It's one of those things I've been vaguely aware of for a long time, but never actually used before.  Until now, I really only ever recorded a macro by accident.

But the other night I was playing around with my attempt to learn Go by writing a NES emulator.  I'm working from a demo of writing one in Rust, which recommends having highly comprehensive unit tests, so that's what I'm trying to do.  The problem I'm running into is that this results in lots of repetitive test cases.  The individual test cases are short, usually six to ten lines, and take the form of a struct defining the processor state and expectations.  The thing is, there are a lot of them.  By that, I mean that so far I've implemented 20 of around 150 opcodes and my unit test file is already pushing 1000 lines, compared to about 250 lines of production code.

Now, a 4:1 test to prod ratio isn't necessarily a bad thing, but it does seem a little high.  And the tests are all very similar, so they're kind of hard to read and navigate - unless you know the exact term to search for, they all just blend together.  So I really wanted to condense them down, preferably to one line per test case.  So I finally decided to make a few functions to extract the common stuff into a template so that I can condense all those structs down into one-liners.  Great!  But I already have 1000 lines of code to update.  Not so great.

Enter the Vim macro reorder.  For each opcode, a wrote a function to create the test template.  Now I had to take the existing structs and convert those into function calls.  Unfortunately, this was too complex for a simple substitution and it was just too tedious to do that many by hand.  However, the exact same series of steps could be repeated for each test case, so I decided to look up that macro recorder that I've been accidentally turning on for years.

Turns out it's super simple.  You just start recording by using "q" with a register name (e.g. "qa") in command mode, do a bunch of stuff, and then run "q" again to stop.  Then you can execute the macro with "@" and the name, e.g. "@a" and repeat that with "@@".  By itself, this is not terribly remarkable.  But with Vim movements and actions, it's really easy to make a macro that performs a complex manipulation on structurally identical blocks of text.  So I was literally able to start recording, just do the manipulation like I normally would, and then stop recording, leaving me with a macro that works perfectly with basically zero extra work.

Like I said, nothing really new or ground-breaking here.  Just discovering one of those handy features that I've never really used before.  But now I know how to take advantage of that for future use.

Non-standard project setup with CoC and Pyright

Here's a quick little thing that I'll probably need to remember and might be useful to other.

At work, we have a PHP project that has automated integration tests written in Python.  The top-level directory of the Git repo is the normal PHP stuff, but the tests/integration/ directory is a Python sub-project that uses Poetry and Pytest.

Now, I use Vim as my editor and CoC with Intelliphense and Pyright for my PHp and Pythong language servers.  Since the main repo is PHP, Intelliphense works just fine.  Hwoever, Pyright needs a little help.  In particular, it didn't find the third-party dependencies or the integration test framework packages because it didn't know where to look.

Fortunately, this is easily fixed by creating a pyrightconfig.json file.  I was able to create one of those in the top-level directory of the project and add an "execution environment" to tell Pyright where to find the root of the Python project.  I set it to the "tests" directory because, while the main dir is tests/integration/,  that directory is also a Python module, so using "tests" lets Pyright find the "integration" module.

My particular file looks like this:

{
    "venvPath": "tests/integration",
    "venv": ".venv",
    "executionEnvironments": [
        {
            "root": "tests
        }
    ]
}

CoC for Vim

A few weeks ago, I was looking into Typescript a bit.  I've heard lots of good things about it, but never had a chance to play with it.  However, I got tasked with some updates to my company's portal site.  (While not technically my team's responsibility, the portal team was swamped, so I agreed to make the required updates to support a  back-end feature my team added.)  And, of course, the portal team uses Typescript.

Naturally, most of the editing recommendations for Typescript are focused on Visual Studio Code.  But I like Vim, so I did a quick search and found this article, which led me to CoC (which I choose to pronounce "coke", like the soda), which stands for the slightly ungrammatical "Conquer of Completion".  It's a plugin for NeoVim and Vim that essentially does Intellisense (code completion, context popups, etc.) using language servers.

If you're not familiar, the Language Server Protocol (abbreviated LSP, though that always makes me think of the Liskov Substitution Principle) was developed by Microsoft for VS Code.  It's essentially a way to make Intellisense work without the editor having to implement support for each language.  It does this by defining a protocol that "clients" like an editor can use to communicate with a "language server".  The language server is a stand-alone program that can provide code intelligence for a particular language, but is not directly tied to any particular editor.  The server can then be called by any client that implements the protocol, which means that the editor itself doesn't actually have to know anything about the language to implement advanced editing features - which is huge.

Anyway, CoC is an LSP client for Vim.  And I have to say, it's awesome!  I've messed with a few code completion and LSP plugins in the past, but I never really got them to work right.  They were either difficult to configure, or required Vim to be built with particular non-standard options.  But CoC was dead-simple to set up.  The only catch is that you have to install the language servers separately, but it turns out that's super-simple as well.  (The ones I've used so far can all be installed through NPM.)

I'm still getting used to it, but having CoC is a game changer for Vim.  I'd given up on having this level of intelligence in my editor.  I mean, for something that supports as many languages as Vim, building it the old-fashioned way just isn't feasible.  But when you can use the same language servers as more modern editors to do the heavy lifting, suddenly it's no longer crazy.

The next step is to look into the available commands and customizations for CoC and see what I can come up with to optimize my experience.  So far it's a pretty cool tool and it definitely makes the development experience nicer.  I want to see what else I can do with it.

 

Docblocks in Vim

As you may or may not know, I've become an avid Vim user.  I use it for work and home, having given up on PHPStorm a couple of years ago.

But one of the things that PHPStorm did automatically, which was quite handy, was to add PHPDoc comments to functions automatically.  This is kinda nice because, let's face it, unless you're writing a long description, most of a docblock is just typing.  You duplicate the parameters and return signature and, if the names and types are pretty obvious (which they should be), then there's not really much to say.  But having them is part of the coding standard, so you can't just skip them, even though they don't add much.

Fortunately, Vim has a plugin for that, known as PDV.  It will read the declaration of a function (or class, or a few other things) and auto-generate a docblock for you.  This is nice, but the extension was a little out of date - it hadn't been updated to support return type annotations.  There was a pending pull request to add that, but it hadn't been merged.  I'm not sure why - apparently that repo is dead.

So I decided to just create my own fork and merge the outstanding pull requests.  Now I have a version that supports modern type annotations, which is nice.  While I was at it, I also added an alternative set of templates for NaturalDocs doc comments.  I use NaturalDocs for LnBlog, so I figured it would be nice to be able to auto-generate my docblocks there too.  All I needed to do as add a line to my Sauce config to change the PDV template path.

Stupid Vim tricks - putting the time on the status line

The other week I realized that I was often moving my mouse for no reason while coding.  Well, not no reason - I wanted to see what time it was.  You see, I have Windows set to hide the taskbar because I use 13" laptops and want to maximize my vertical screen space.  But that means that I have to hit the Windows key or move the mouse down to bring up the clock.

I don't have this problem when browsing the web, because Vivaldi has a setting to put a clock in the lower-right corner of the window.  So I thought to myself, "Self, do you think Vim can do that same thing?"

Well, it turns out it can!  In fact, there's even an article on it.  Of course, that's for putting it in the plain-old status line.  I'm using the airline plugin, so I had to tweak it a little.  Still, I was able to get the passable looking image above by putting the following in my .vimrc:

" Put the current date and time in the status line and keep it updated
let g:airline_section_z='%p%% %#__accent_bold#%{g:airline_symbols.linenr}%l%#__restore__#%#__accent_bold#/%L%{g:airline_symbols.maxlinenr}%#__restore__#:%v %{strftime("%b %d %I:%M:%S%p")}'
let status_update_timer = timer_start(1000, 'UpdateStatusBar',{'repeat':-1})
function! UpdateStatusBar(timer)
  execute 'let &ro = &ro'
endfunction

The timer update the time every second (obviously you can do longer if you want).  That's because, otherwise, the time won't update until you do something in the editor window.  This way it stays current, even if I'm not actively editing.

Vim emulation in Komodo

Authors note: Here's yet another installment of "From the Archives".  Clearly I haven't really felt like coming up with new ideas lately.  I blame the pandemic.  Seriously - I'm not going to be back in the office until at least next summer.  Even though restrictions have eased (at least for the time being), lock-down fatigue has definitely long since set in.

At any rate, this is another one on using Komodo with Vim emulation.  This was written on April 16, 2014, just a few days after the last one on the same topic.  These days I'm using Vim all the time, so none of this is relevant to me anymore.  However, it is a nice example of how it's possible to extend a good IDE to customize your workflow.

In this case Komodo is (or was) customizable using JavaScript, which is nice - lots of people know JavaScript.  The down side is that, to do actually useful thing, you also it also used XUL and SciMoz, the Mozilla Scintilla binding.  These are less commonly known, to put it mildly.

To be fair, Vim isn't much better on this score.  While it supports multiple scripting languages, the primary one is, of course, VimScript, which is...not a great language.  However, it's also quite old, quite well documented, and there are lots of examples of how to use it.  The VimScript API is also pretty stable, as opposed to Komodo, which was in the process of moving away from the XUL-based stuff when I stopped using it.  And really, a little VimScript will actually take you farther than you think.

In any event, I guess the idea is that it's good to know how to customize your editor, at least a little.  You know, sharpening the saw, knowing your tools, and all that.  Good stuff.  Enjoy!


Since upgrading to Komodo IDE, I've been looking a little more at customizing my development environment.  This is actually made somewhat easier by Komodo's "sync" feature, which will synchronize things like color schemes, key bindings, etc. between IDE instances via ActiveState's cloud.

Anyway, as part of this I've also been looking more at the Vim keybindings.  I've been a casual Vim user for a very long time, but I was never hard-core enough to do things like stop using the arrow keys or give up using ctrl+C and ctrl+V for copy and paste.  So now I'm trying to do just that.

Of course, Komodo's VI emulation mode is a pale imitation of what's available in Vim.  However, even that pale imitation is actually pretty good.  In fact, its even better than Komodo's documentation would lead you to believe.  In addition to the basic modal editing stuff, Komodo supports a decent range of movement commands, variants of change and delete commands, etc.  Basically, it supports everything I already knew about plus a lot more.  So now I'm trying to get that extra stuff into my muscle memory.

In the course of looking at some Vim command guides, I naturally came across some handy looking commands that Komodo didn't support.  So I'm going to try to fix that.

The first one is the reg command.  Vim's registers were something I hadn't really worked with before, but it turns out that they're not only pretty cool, but that Komodo actually has some support for them.  I only know this because the documentation mentions the key binding for the "set register" command.  However, it doesn't implement the reg command, so you can't actually see what's in any of those registers.

So, long story short, I fixed that with a macro.  Just create a new macro named "reg" in your "Vi Commands" folder in your toolbox and add the following code (this requires another macro, executed at start-up, containing the "append_to_command_output_window" function lifted from here):

var viCommandDetails = Components.classes['@activestate.com/koViCommandDetail;1'].
                                getService(Components.interfaces.koIViCommandDetail);
var count = new Object();
var args = viCommandDetails.getArguments(count);

append_to_command_output_window('');
append_to_command_output_window("--- Registers ---");

for (item in gVimController._registers) {
    if (args.length > 0 && args.indexOf(item) < 0) {
        continue;
    }
    if (typeof gVimController._registers[item] !== 'undefined') {
        append_to_command_output_window('"' + item + '   ' + gVimController._registers[item].trimRight());
    }
}

This allows you to type ":reg" and get a list of the current registers in the "command output" window in the bottom pane.

Another good one:

var scimoz = ko.views.manager.currentView.scimoz;
if (scimoz.selText.length == 0) {
    ko.commands.doCommand('cmd_vim_cancel');
} else {
    ko.commands.doCommand('cmd_copy');
}

This can be bound to ctrl+C and allow you to keep the default "copy text" behavior when there is text selected, and still work for Vim's "back to normal mode" when nothing is selected.

Komodo and Vim

Author's Note: We're back with another installment of "From the Archives", the blog show where I declare writing bankruptcy and just post an old, half-finished article that's been sitting in my drafts for years.  This entry is from April 9, 2014.  This was in the midst of my long stint as a Komodo IDE user. 

One of my favorite things about Komodo was that it had pretty good Vim emulation.  I started using that because a few years before I'd spent a lot of time going back and forth between a Windows PC and a Macbook Pro.  The Macbook keyboard had that weird Apple layout going and it routinely messed with me, so I eventually gave up and decided to use Vim-mode because that's the same on both platforms.

Of course, things have changed since then.  I've become a full-time Vim user, and have all the fancy faux-IDE stuff set up.  I actually like it so much that I stopped using PHPStorm for work and switched to doing all my development in Vim.  So this post is no longer relevant to me, but it at least has a few handy links, so enjoy!


I've been a Vim user more or less since I started using Linux.  Mind you, I was never really a hard core Vim user.  I still use the arrow keys, for instance, and manage to get by on maybe a couple dozen keybindings and commands.  I have no clue how Vim's scripting or configuration systems work.  All I know about ctags is that they're a thing that exists.  So really, I'm more of a dabbler.

The other part of this is that I like at least a small amount of IDE in my normal working-day editor.  I kind of like having some sort of "project view" of my files, a code hierarchy viewer, some form of Intellisense, etc.  And while you can get most of the stuff I like in Vim, they're not there out of the box.  And even if you can get them, you can't count on having an obvious graphical way to manipulate them.  Typically, you just have to read the documentation to find out what the key bindings are to trigger everything.

So the upshot of this is that I use Komodo IDE with the Vi emulation setting.  This essentially turns on a Vim emulation mode that makes the editor modal and enables a lot of the standard Vim keybindings as well as a small subset of common commands.  So I get Vim goodness with all the convenience of a full IDE.  I had never really looked closely at just how much of Vim Komodo would emulate, though - I just knew it supported everything I commonly used.

Well, I had some extra time after finishing all my bug fixes the other day, and since really learning Vim has been on my list of things to do for, er, over 10 years, I decided to look up some Vim reference sheets and see how many of the commands and keybindings actually worked in Komodo.  Turns out it was a pretty decent amount.  (Note from the future: I didn't write down the details at the time and don't care enough to catalog now that I no longer use Komodo.  Suffice it do say that Komodo's Vi emulation was actually pretty good.  Maybe not as good as IdeaVim, but pretty good.)

Vim and ctags

Today's post is random Vim trivia, featuring ctags!

If you've used Vim casually or been around the UNIX world for a bit, you may have heard of ctags, but not really been sure what it was good for.  Well, ctags is a code indexing tool.  It scans a bunch of source code and creates an index of it.  The goal is the same as creating a  database index - to allow you to look up specific things quickly.

That's straight-forward enough, right?  But what the heck do you do with the index once you create it?  Well...nothing.  At least, not directly.  Sure, you can manually create and query the tag index from the command line, but you wouldn't really want to.  Following the UNIX way, ctags is really just one part of the pipeline.  It creates the index and it's your editor that queries it and does stuff with the result.

If you want to use Vim for any non-trivial development, then you really want to be using ctags.  It provides you with a handy way to jump between definitions of classes, functions, and so forth, much like you get with Visual Studio or PHPStorm.  It makes your life significantly easier.

The only problem is that there's a little setup that needs to be done.  Reading the ctags index doesn't require anything special if you're using the default "tags" files for the index.  However, generating that file takes a little more effort.  You can do it manually, but really you want it to happen automatically in the background.  Luckily, there's a plugin for that - Gutentags.  This plugin will basically just update your tags file in the background at appropriate intervals.  Although it has some options available, there's not really anything you need to configure for it - it just works out of the box.

Once you've got your tags file auto-updating, the next thing is to figure out how you want to browse tags.  The workflow that works best depends on your preferences, and I can't claim to have mastered it.  This page gives a good overview of the different commands and default keybindings that are available for tag browsing.  As with everything else in Vim, there are a lot of options available, but you can get by with just a few to start.  Personally, I find that just ctrl+] and :tselect work for 80% of my needs, but your mileage may vary.

More Vim-as-IDE pointers

A while back I came upon this article on using Vim as a PHP IDE.  It's got some very good pointers, although the author may have gone a little over the top on trying to mimic the behavior of PHPStorm.  I haven't tried all of those plugins, but quite a few of them are in my Vim config.

If nothing else, the article gives you a good sense for just how powerful Vim is when it comes to extending its behavior.  It's actually pretty impressive.

Cover art for The Pragmatic ProgrammerEarlier this year,  finally read through The Pragmatic Programmer.  It's been sitting on my bookshelf for...at least 15 years now.  I'd read parts of it before, but never went through the whole thing.  Anyway, it contains a section on choosing an editor, and one of the things they stress is extension.  You need to be able to customize your editor to extend its functionality to suit your workflow.  The idea is that the editor is one of your primary tools of code-craft and you need to make it truly yours.  You need to learn to use it well and completely, to make it an extension of your hand.

So far I'm finding Vim to be a pretty good choice in that regard.  Partly this is due to its raw power, but to a large extent it's also due to its age and the ecosystem around it.  Vim is a very old tool and it's very mature and stable.  This is a very good thing, because it means that there are lots of examples and documentation for how to use and customize it.  If you want do do something new with Vim, there's a good change that someone already wrote a plugin to do it.  And if not, there are plenty of plugins out there that you can use as examples. 

Being mature and stable also means that things are unlikely to change out from underneath you.  Sure, new features are still being added, but the basic functionality has been largely unchanged for a while.  This is what you want from a good tool.  If you're going to invest a lot of time and effort to get good at using a tool, you want that investment to retain its value.  You don't want to spend three months every couple of years re-learning because the tool vendor decided to re-architect their product or switch to the latest trendy programming language.

So while Vim may be old and boring, there's something to be said for being old and boring.  When was the last time you saw an old, boring person on The Jerry Springer Show?  Doesn't happen.  New and interesting may be exciting, but there's a reason why telling someone "may you live in interesting times" is supposed to be a curse.

On the state of my Vim-as-IDE

Last year I posted about adopting Vim as my default editor.  I've been leveling up my Vim knowledge since then, so I thought I'd write a summary of the current state of my ad hoc Vim IDE configuration.

First, let's start with some sources of information and inspiration.  I found Ben McCormick's Learning Vim in 2014 series to be very useful.  The Vim as Language post in particular offers an eye-opening perspective on the beauty of using Vim.  I've also been working my way through Steve Losh's Learn Vimscript the Hard Way, which is a great source for information on customizing your Vim configuration.  And if you want a little inspiration to give Vim a try, here is Roy Osherove's "Vim for Victory" talk from GOTO 2013.

So how has my Vim adoption gone?  Pretty well, actually.  When I look back at my original post on looking for a new editor, it's pretty clear that a sufficiently customized Vim meets all my criteria.  However, to be fair, it did take a while to get it sufficiently customized.  The customization I've done wasn't actually that hard, but it took some time to figure out what I needed, what I could do, and then Google how to do it.  But paradoxically, that's one of the strengths of Vim - it's been around long enough that pretty much everything that you might want to do either has a plugin available or has been documented someplace on the web, so you rarely need to write any original code.

My Plugins

These days there are actually quite a few plugin managers available for Vim.  The nice thing about this is that they all support the same plugin format, i.e. GitHub repositories laid out in the standard ~/.vim directory format.  I'm currently using Plug because it provides an easy mechanism for selective or deferred plugin loading (in the case where you have a plugin that's not always needed and slows down Vim startup).

Here are some of the goodies my Plug plugin list currently contains:

  • scrooloose/nerdtree - A nice file explorer plugin that provides some enhancements to Vim's native file browser.  Pretty much a must-have for every Vim setup.
  • ctrlpvim/ctrlp.vim - A fuzzy file finder that works on buffers and other stuff too.  Just press ctrl+p and start typing the name you want.
  • jlanzarotta/bufexplorer - A handy plugin to list and switch between the current buffers.  Think of it as like the tab strip at the top of other editors, but easier to deal with from the keyboard.
  • tpope/vim-dispatch - A nice plugin for running external programs asynchronously.  By default, external command execution blocks the rest of the UI until the command is done.  This is fine sometimes, but not others.  Dispatch integrates with other plugins and provides a way to run things in the background and get their output back into Vim.
  • tpope/vim-surround - Provides a Vim movement that helps you manipulate surrounding entities.  Good for things like changing quotes, HTML tags, etc.
  • Chiel92/vim-autoformat - Provides an interface to various code formatters.  I use it as a replacement for the JSON beautifying feature that I loved so much in Komodo.
  • mileszs/ack.vim - A quick and easy integration of the ack! text search tool.  Like the built-in grep, but better.
  • joonty/vim-sauce - Sauce is a handy little plugin for managing multiple configuration files.  It's also useful for adding the concept of a "project" to Vim.  I use it to create project-specific configurations that handle all the customization that would be done in the project file of a regular IDE.
  • janko-m/vim-test - A unit test runner plugin that handles many different tools.
  • vim-airline/vim-airline - An enhanced status line that's both pretty and displays some useful information.
  • w0rp/ale - The Asynchronous Lint Engine, this offers syntax and style checking with inline error notifications, just like in a regular IDE.
  • majutsushi/tagbar - A tool for displaying the tags in the current file, similar to the structure browsers found in IDEs.

Needless to say, I also made a number of other customizations to my Vim configuration.  My full work-in-progress Vim configuration is in this repo if you're interested.  I do not hold this up as a great example of how to configure Vim, but it's working for me so far and, as previously noted, it actually wasn't all that much work.

The IDE Functionality

So what functionality do I have with this setup?  Well, it turns out I actually get most of what I previously had with Komodo.  Of course, I need to integrate with a few external packages for this, the key ones being Exuberant CTags, which indexes identifiers in the code, and ack for text search.  I also need various external formatters and linters, though the specific programs depend on what language I'm coding in.  Nothing fancy, though - they're pretty much all command-line executables that you can just drop someplace in your path.

So here's what I get for my trouble:

  • Insanely powerful key bindings.  I mean sersiously powerful - I don't think there's anything you can do in Vim that can't be bound to a keystroke.  And it's usually pretty easy.  Just the other week I defined a couple of ad hoc key bindings to help me add translation keys to a web template.  It's really a beautiful thing.
  • Inline syntax and style checking.  Using ALE in conjunction with the appropriate external linters, I get the same kind of inline checking I can get in PHPStorm.
  • Navigating identifiers.  Using Vim's ctag support, it's possible to navigate uses and definitions of a particular, for example, much like the code browsing abilities of PHPStorm.  Of course, it's not perfect because ctags lack knowledge of the context of the identifier, but it's not bad.  (And to be fair, I've seen the code navigation in PHPStorm and Komodo fall over on more than one occasion.)
  • Searching.  Between CtrlP and Ack, I have some nice facilities for searching for or within files.  Again, very similar to what I had in Komodo or PHPStorm.
  • Project management.  Between NERDTree and Sauce, I have some decent support for the concept of project.  They give me a nice file tree navigation panel and the ability to define project-specific configuration.

Conclusion

The short version is that this Vim experiment is going pretty well.  Granted, it is somewhat more work than figuring out a traditional IDE.  But on the other hand, it's not that bad and actually isn't as much work as I thought it would be.

In terms of functionality, I find that I haven't actually given up very much.  In fact, if you're talking about multi-language IDEs, I'm not even sure I've given up anything I care about.  It turns out that Vim is remarkably capable and the plugin ecosystem is very large and deep.

Would I recommend this to someone who's never touched Vim before?  Probably not.  But if you're familiar with Vim and interested in trying a new way of working, it might be worth a shot.  At worst, you'll improve your Vim skills and enjoy using a nice, fast editor that doesn't eat up half a gigabyte of RAM when it's just sitting there doing nothing.

And the current editor is - Vim?

So, as I mentioned before, I'm looking for a new go-to text editor/IDE.  So far, I've taken cursory looks at a few of the options.  These include:

  1. PHPStorm.  As I mentioned in the last post, I use PHPStorm at work.  And while it's really good in a lot of ways, I'm not in love with it.  On the up side, it's got great code intelligence and the VI-mode plugin is actually quite good.  On the down side, it's a single-language IDE (well, not quite, but it's still got a limited set of supported languages).  I guess I could just buy the entire JetBrains IDE suite, but I'm not crazy about switching back and forth.  Also, PHPStorm is kinda heavy - like, Eclipse heavy - both in terms of memory footprint and, more important, conceptual weight of the UI.  So while I don't dislike it, I don't really have any enthusiasm for it.
  2. Visual Studio Code.  I initially liked the look of VS Code.  It's got the cool Visual Studio intellisense, which is nice, and it seems to have a lot of extensions available.  The Vim-emulation plugin seemed fairly good, but not great.  The most popular PHP plugin, however, didn't seem to work out of the box at all.  I'm not sure why, though it could be its wonky install process/implementation (apparently it's written in PHP).  At any rate, I didn't care enough to look into it, though it might be worth taking a closer look at VS Code at some point.
  3. Atom.  I liked the look of Atom.  I read a little about the philosophy behind it and I really wanted to like it.  But then I fired it up and tried opening one of my project directories and it didn't work.  And by "didn't work", I mean that Atom actually crashed, consistently, on this particular directory.  So that's a no-go.  A quick Google revealed that it might be a problem with the Git library, which could possibly be fixed by changing the index version on the repo, but frankly I don't care.  If I can't trust my editor to just open a directory, then I can't trust it at all.  I mean, I don't even care if my editor has Git support at all, so I'm certainly not going to accept crashing if it sees a repo it doesn't like.  
  4. Sublime Text.  I've heard good things about Sublime.  I used to work with several people who really liked it.  Then I fired it up and immediately said, "What the heck is this?"  The UI is pathologically minimal, except for a gajillion menu items and the stupid friggin' mini-map (which I didn't like in Komodo either).  Configuration is done by editing a JSON file, but what the heck is with the weird out-of-box-experience?  The UI is extremely minimal and customization is done by editing a JSON file, which is weird (to be fair, VS Code and Atom do that too, but it's more forgivable because they're free), and the plugin manager was immediately confusing.  Seemed like getting used to Sublime might be a steep learning curve.
  5. Vim.  Yes, you read that right - Vim.  I was surprised too.  Let me explain.

After trying out Sublime, my initial reaction was, "Geez, if I want something that complicated, why don't I just use Vim?"  And then I stopped.  And I said to myself, "Actually...why don't I use Vim?"  Good Vim emulation is one of my must-haves, and no plugin is ever gonna beat the real thing.  It's free, open-source, hugely customizable, has lots of available plugins, and is extremely well established.

The thing is, I knew Vim could be customized into a pseudo-IDE, but I'd never really thought of myself as a hard-core Vim user so I'd never tried it.  But the truth is that I've been a Vim user for a very long time, and for the last few years I've been actively trying to pick up more Vim tricks for use in Vim emulation plugins.  So while I didn't know an awful lot about customizing Vim, I'm very comfortable actually editing code in it.

And it turns out that actually customizing Vim isn't really that bad.  Heck, there are even package managers for Vim now!  There are also IDE-like configuration/plugin bundles you can install, such as spf13, but I quickly determined that those were too big and overwhelming.  However, they are good as a source of ideas and settings to copy into your own custom ~/.vimrc file.  That's actually part of the beauty of Vim - despite the fact that Vim script is a little weird and the configuration is in no way intuitive, there's enough information already out there that it doesn't really matter.

So over the course of a week or so, I pulled out some of the more interesting settings from the spf13 config, found a selection of plugins that I liked, and got myself a nice, functional Vim setup.  I even set up some symlinks and file syncing so that I can have my setup synchronized between home and work.  

Is it perfect?  No, but nothing ever is.  But so far, it's working pretty well.  And what's more, I actually enjoy using it.  It might not have the power of a specialized IDE when it comes to the more advanced features, but it's got a heck of a lot of power in general.  And the amount and types of customization you can do are amazing.  With a little effort, you can really shape the editor to your workflow, which is a thing of beauty.

VI makes so much more sense now

Thanks to this answer from StackOverflow, the key mappings in VI and Vim make soooo much more sense now.  It's all explained by this keyboard layout:

The keyboard layout that was used when VI was created.

The more I use Vim, or the Vim emulation in Komodo, the less sense it makes to use the "escape" key to switch out of insert mode.  I mean, you have to move your hand way away from the home row just to reach it, which is exactly the opposite of how things are supposed to work.  But if you're using this keyboard, then it seems like a completely obvious choice.

Incidentally, after far too many years of suffering with the escape key, I've switched to using the other choices for getting out of insert mode — Ctrl-C and Ctrl-[.  Both do the same thing as the escape key, but require significantly less hand movement and so are faster to type.  Especially Ctrl-C, as most of us are used to using that for copying text to the clipboard.

Incidentally, since I'm using the Vim emulation for Komodo IDE/Edit, I should probably mention that it does support Ctrl-[ out of the box, but not Ctrl-C — that is, naturally, reserved for the "copy" operation.  However, it's easy to change that.  Simply create a new macro with the following code and set the key binding for it to Ctrl-C (you may have to unbind the standard "copy" operation first):

var scimoz = ko.views.manager.currentView.scimoz;
if (scimoz && scimoz.selText.length == 0) {
    ko.commands.doCommand('cmd_vim_cancel');
} else {
    ko.commands.doCommand('cmd_copy');
}

This macro preserves the standard copy behavior by checking if you have any text selected when it executes.  If you do, it does a standard "copy to clipboard".  If you don't, it switches the editor from "insert" mode to "normal" mode.

Yes, VIM is good

I've been catching up on some of my back episodes of .NET Rocks the past couple of days. I'm currently about 3 months behind on my podcasts, so I've got plenty to listen to.

Anyway, I was listening to show 537 with James Kovacs at the gym this morning, and he mentioned something interesting toward the end. When asked what he's been into lately, he said he'd been playing with Vim. Imagine that - a hard-core Microsoft guy playing with Vim. That just gives me a good feeling.

I've always been frustrated by how people in the Windows world seem to think "text editor" equals "Windows Notepad". Even experienced people. You always hear them refer to opening something in Notepad, or typing things into Notepad, etc. This from people who've been in the business for 10, 15, or even 20 or more years! I mean, they must be aware that there are better editors out there. Is "notepad" just used as a generic term, a shorter version of "text editor"? I wish somebody would explain that to me.

But getting back to the topic, it was nice to see James mention Vim. Despite Carl's and Richard's comments about VI being an antique, Vim really is remarkably powerful. Granted, it takes some effort to learn, but once you've got it down, you can do some pretty complicated stuff in just a couple of keystrokes. It's always nice to see that MS A-listers can recognize the power of tools like Vim, and not just us transplanted UNIX geeks.

PowerShell highlighting in Vim

Well, I feel stupid. I just finally got syntax highlighting for PowerShell to work in Vim. I did a little Googling and found my solution in the PDF document linked form this article. Why you need an 8 page PDF to explain this is a completely different issue.

Turns out I was just missing some lines in my filetype.vim file. I already had the syntax, indent, and file type plugins, I just didn't think to add the code to activate them (for some reason I thought that stuff was loaded dynamically). However, page 6 of that PDF gave the answer:

" Powershell
au BufNewFile,BufRead *.ps1,*.psc1 setf ps1

I just added those lines to my filetype.vim, below the corresponding entries for Povray files, and voilĂ ! Syntax highlighting now works.