Will Neovim rock on Windows?

Gvim on Windows 8

I have been using Vim on Windows since I switched to 64-bit and edit.com stopped working. Originally I just used the console version inside of PowerShell or the standard command line. In the last three years I’ve been favouring Gvim as my go-to text editor for smaller scripts and utilities.

I know for a fact I’m not using everything Gvim or Vim has to offer, but I’m quite happy with the way it works. For example, I have line numbers turned off, but I can turn them on very easily using a quick :set nu.

Very powerful, very fast.

There are some things I absolutely hate though. For starters, what’s this horrible border on the inside of the window, and how can I make it disappear without hacking the whole application and recompiling it? This isn’t Windows 95.

Ugly Border

I’ve looked for some time but I haven’t found a solution. But hey, I found out that people can make it look pretty on Ubuntu (handy!)

Enter Neovim

Neovim promises to be a refactoring (and reimagining) of the Vim text editor using more modern techniques. The plan is to have the core Vim functionality moved into a new library, which will allow the interfaces to be separated out in a modular way.

The thing that got me really interested? When they mentioned Windows:

Modern GUIs written in high-level programming languages that integrate better with the operating system. We can have GUIs written using C#/WPF on Windows or Ruby/Cocoa on OS X, for example.

True they’re not saying they will write a GUI using C# & WPF, but someone can. And I like the sound of that. Of course, it’ll be open source – and I’ll be able to edit the XAML to have no borders at all, if I like.

Also, here’s hoping we get better PowerShell integration out of this too.

It could be huge.

So, will Neovim rock on Windows? I sure hope so.

Update

I always keep an eye on the Neovim project and recently I though I’d try out the Neovim-QT frontend which actually builds for Windows. Purely from an aesthetic point of view, I think it’s awesome already. But even now (over a year after this original post) there is a long way to go.

Neovim-QT

Querying TFS with TFPT.EXE and PowerShell

At Branded3 we use Team Foundation Server for source control, task managment, and various other tracking purposes. One of the benefits of this is being able to run queries with WIQL to pull off reports.

As is usually the case with me, I have set up a couple of PowerShell scripts that use TFPT.EXE from the Team Foundation Server Power Tools to make life a little simpler for myself…

Viewing Open WorkItems

$TFSSERVER   = "hq-tfs08-01.branded3.net"

Function Get-WorkItem
{
    $query = "SELECT [System.Id], [System.Title] FROM WorkItems " +
             "WHERE [System.AssignedTo] = 'Julian Kay' " +
             "AND [System.State] <> 'Closed' " +
             "AND [System.State] <> 'Resolved' " +
             "ORDER BY [System.Id]"

    tfpt query /collection:$TFSSERVER /wiql:$query /include:data
}

This little script gets a list of WorkItems which are not closed or resolved from TFS. I find this much faster than opening a copy of Visual Studio to find out which tasks I have assigned to me. True you could run this kind of script by using a batch file, but I like the fact I can use this in conjunction with the various Outlook scripts I use for PowerShell with simple one-liners like foreach ($workItem in Get-WorkItem) { Add-OutlookTask "$workItem" }

Getting Work Hours

Function Get-WorkItemHours
{
    $month = (Get-Date).ToString("MMMM")
    $year  = (Get-Date).Year
    $query = "SELECT [Completed Work] FROM WorkItems " +
             "WHERE [System.AssignedTo] = 'Julian Kay' " +
             "AND [Assigned Month] = '$month' " +
             "AND [Assigned Year] = '$year'"

    $hours = tfpt query /collection:$TFSSERVER /wiql:$query /include:data
    $total = 0.0
    foreach ($hour in $hours)
    {
       $total += $hour
    }
    $total
}

We also have custom fields which help us keep track of the hours we’ve spent on a project, and as shown above, we can even see how many hours have been spent in a month. By running this simple script I can be sure that all my time is correctly recorded to enable us to both bill correctly, and keep track of how long things really take.

Naturally, everyone has their own requirements for scripts like this, but PowerShell gives me the flexibility to create these simple utilities with very little development work.

Outlook Tasks in PowerShell and Vim

Getting Outlook Tasks in PowerShell is actually pretty easy. All you need to do is use the Office Interop to get access to the default tasks folder, then iterate through the items that are returned.

Create a file called Get-OutlookTask.ps1 in your scripts folder, and paste the following code:

Add-Type -AssemblyName Microsoft.Office.Interop.Outlook
$folders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type]
$outlook = New-Object -ComObject outlook.application
$mapi = $outlook.GetNameSpace("mapi")
$tasks = $mapi.getDefaultFolder($folders::olFolderTasks)

foreach($task in $tasks.Items)
{
  if(!$task.complete)
  { 
    $task.subject 
  }
}

Naturally, you could customize this script to work any way you like – for example, you could sort by priorty or date, or you could show an extra column for category information. I have actually set up an alias to this script, so all I have to do is type tasks to see all my current tasks.

If you have set Vim to work with PowerShell, you can import your Outlook Tasks directly into the open document by using the Vim command:

:r! tasks

Pretty cool huh? If you’re looking to add Outlook Tasks in a similar way, you can check out this script by Lee Holmes. I use this one with the alias of nt to save on all that extra typing.

If you want to be able to add Outlook Tasks from Vim, I suggest you add the following function to your vimrc file:

function! Task(args)
  system("nt \\\"" . a:args . "\\\"")
endfunction

command! -nargs=1 Task :call Task('')

Now you just need to call :Task buy milk and it’ll get added – without switching to the shell itself.

Writing and Running F# Scripts with Vim

When I’m writing software for the .NET Framework I tend to have a copy of F# Interactive open. This lets me run commands directly like so…

This is fine for simple stuff, but if you’re writing something a little more complex it’s better to write a script. In the past I’ve done this by having another copy of Visual Studio open and running the script that way. This works really well, and includes colour coding, intellisense and all the other good stuff you expect.

However there are times that having yet another copy of Visual Studio is a little heavy for just keeping track of a script. Enter Vim, the de facto command line editor for Unix and other operating systems.

  1. Set up Vim to work with PowerShell
  2. Grab yourself a copy of the F# Syntax file
  3. Save it into your Vim plugins directory
  4. Add the following lines to your vimrc file…
au BufRead,BufNewFile *.fs set filetype=fs
au BufRead,BufNewFile *.fsx set filetype=fs

Now when you create a .fsx file, you can run it directly from F# Interactive by using Vim’s shell execution feature.

:!fsi %

This will run your script in F# Interactive and present you with the results. The :! Vim command is for running the external program, and the % represents the filename of the currently open document.

Note that you’ll need to have set up F# Interactive by either adding it to the path or setting an alias in PowerShell. If you haven’t done this already, you can do it by adding the following lines to your PowerShell profile:

$FSIPATH     = "C:\Program Files (x86)\Microsoft F#\v4.0\Fsi.exe"

Set-Alias fsi  $FSIPATH

Setting up Vim to work with PowerShell

As an avid console user, I like being able to edit text without opening an interface that requires a mouse. For me this text editor is Vim – the extremely well regarded editor that ships with a very large number of operating systems.

My command line of choice is PowerShell, and I set up any extra commands to live in a Scripts directory inside my Windows user directory. If you’d like to do this you need to download Vim to the Scripts directory, then edit your PowerShell profile to include an alias so you can access Vim from any directory you might be in, as well as a couple of commands to make editing common files even simpler.

# There's usually much more than this in my profile!
$SCRIPTPATH = "C:\Users\Julian\Scripts"
$VIMPATH    = $SCRIPTPATH + "\vim73\vim.exe"

Set-Alias vi   $VIMPATH
Set-Alias vim  $VIMPATH

# for editing your PowerShell profile
Function Edit-Profile
{
    vim $profile
}

# for editing your Vim settings
Function Edit-Vimrc
{
    vim $home\_vimrc
}

Then you need to set Vim up in the way you like it, there are lots of sites with suggestions for how to set your vimrc file, but for now I’m just going to suggest you add a link back to PowerShell by adding the following lines:

set shell=powershell
set shellcmdflag=-command

This means that when you run the :shell command in Vim, you will actually use PowerShell itself to run commands, including all the aliases you set in your profile. I find this especially handy for writing and running F# scripts, as well as task management with Outlook – both of which I’ll write about in posts this week, but you can test this out now by running :sh or :!get-childitem | more and seeing what happens!