Part 2: No Visual Studio

In part one of this series I got my newly-Linux laptop set up with everything needed to run ASP.NET 5 web and console applications. The next job is to create an environment in which I can actually create and edit these applications.

In the olden days, I used to write Informix ESQL/C code in vi on a Wyse 50, remembering syntax and commands and entire libraries, all in my head. Now, as I enter my early dotage, years of IDE abuse have all but robbed me of my near-eidetic faculties, and I cannot get from the start of a line to the semi-colon without at least IntelliSenseā„¢, to say nothing of ReSharper.

Sadly, Microsoft have not yet open-sourced Visual Studio 2015 Ultimate Edition (something to do with the MIT license being incompatible with $10K price tags), so I must look elsewhere for my hand-holding editor requirements.

Enter OmniSharp

OmniSharp is one of those things that's been on my radar since it appeared a couple of years ago, but because I was safely reclining on Windows with Visual Studio, and it was a Vim plug-in, I never really paid it much attention. Now, with Microsoft's new-found enthusiasm for all things *nixy, OmniSharp finds itself with lots of new friends and contributors, including, as of last night, me.

OmniSharp works with Vim, Emacs, SublimeText, Brackets and Atom. I'm not going to pass judgement on any of these editors, because I don't want the comments section to descend into flaming-poo-flinging anarchy, but my personal preference is SublimeText.

You can install the OmniSharp package using Sublime's marvellous Package Control, and I did, but something was awry. The package did not like ASP.NET 5 projects. It sort of worked, when you were using classes from the BCL as provided by Mono, but it choked when using things from packages. Like, for example, Microsoft.AspNet.Mvc.

More hackery

I raised GitHub issues, and waxed wroth upon the OmniSharp Jabbr room. I was told that yes, this was true, and that there was a version 2 of OmniSharp being worked upon which used the Roslyn language services instead of NRefactory, and that would play nicely with ASP.NET 5 projects, but that it had not been made to work with the Sublime package because Jonathan Channon was a lazy little toe-rag who had abjectly failed in his duty to pre-cognitively cater to my every whim. Or he wasn't feeling well. I forget which.

So I forked omnisharp-sublime, grabbed omnisharp-roslyn, and commenced to hacking the two together.

The OmniSharp server is a separate process; it runs a little web server (using Nancy self-hosting in version 1, and MVC + Kestrel in Roslyn-driven version 2), and the various editor plug-ins communicate with it using whatever they use for doing HTTP. In the case of SublimeText 3, plug-ins are written in Python 3.

And so it was that I spent many hours (five) battling the dark forces of Python's urllib2, trying to get it to talk to the new OmniSharp v2 server. Eventually, I discovered that you can bundle Python libraries into your plug-in, so I switched to using urllib3, which is related to urllib2 by the first six letters of its name only. There are more optimizations to be had using that library, around pooling and reusing connections, but for now it's working and that's the main thing.

A few more tweaks here and there (I really, really hate SublimeText's plug-in system), and I finally had this:

Which is basically amazing. I am in awe of OmniSharp and the clever brains behind it.

If you want to use this version of the OmniSharp plug-in, open up a Terminal and clone the repo directly to your Sublime Packages folder, like this:

cd ~/.config/sublime-text-3/Packages
git clone -b roslyn https://github.com/omnisharp/omnisharp-sublime OmniSharp

(If there are any Mac users reading, please give this a try. I've been mucking about with shell scripts and I haven't got a Mac to test them on. (If somebody wants to help out by buying me a Mac, this one will do nicely.))

Jam tomorrow...

The original v1 of OmniSharp Sublime, based on NRefactory, actually does a lot of ReSharper-style things like code corrections and refactorings. The Roslyn version is going to do these things too, but it's waiting on the Roslyn team to remove the dreaded internal word from all their language service refactoring classes and such. But it will be awesome when they do :)

Kulture

The other plug-in for Sublime is Kulture, which adds a bunch of commands and stuff to the editor, including Run K Commands, which reads your project.json file and adds the commands in in to the choices in Sublime:

kmon

You might notice an unfamiliar command in that screenshot: k mon. That's a very handy utility that watches all your .cs files and, if any of them change, restarts the server, forcing a recompile. It's something that VS2015 does automatically, and it's an absolute godssend*.

To use it, you need to have the nodemon NPM package installed (sudo npm install -g nodemon). Then you add kmon to your dependencies, and add the mon command, in your project.json:

{
    "webroot": "wwwroot",
    "exclude": "wwwroot/**/*.*",
    "dependencies": {
        "Microsoft.AspNet.Hosting": "1.0.0-beta2",
        "Kestrel": "1.0.0-beta2",
        "kmon": "0.3.0"
    },
    "commands": {
        "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004",
        "mon" : "kmon --ext cs,json,js --server kestrel"
    },
    "frameworks": {
        "aspnet50": { }
    }
}

You can also run that from the command line using k mon.

* Not a typo :)

Brackets

While I've been hanging around the OmniSharp Jabbr room, I've also seen a lot of chat around the Brackets extension, so I decided to have a play with that as well. It had a tiny bug where it was trying to use the omnisharp.cmd script on non-Windows platforms, but hopefully they'll merge my PR to fix that soon and you can use it. Because Brackets is all HTML/CSS/JS, they've been able to come up with something really rather nice looking. If Brackets' vi emulation were better, I could see myself using it over Sublime.

End of Part 2

So, now I have a pretty good editing environment set up, and I'm building and running my ASP.NET 5 application on my Linux laptop. It's all going splendidly well. In Part 3, I'll talk about pushing applications into production, using wonderful open-sourcey things like Nginx, Docker and supervisord.