Exploring the Nature of Software Delivery

My understanding of the nature of software development is undergoing change as I continue to investigate the works of such diverse thinkers as Karl Popper, Alan Turing, Dedre Gentner, David Easton and many others. This series of articles reflects on what I have learned. It is a work in progress. Your feedback is welcome. You can reach me via twitter @logosity or through my professional online prescence: Agnomia.

Unix is my IDE

Last Update: April 6th, 2017


"What Integrated Development Environment (IDE) do you use for [language X]?"

I get this question a lot. Regardless of language1, my answer is typically something like: "None." or perhaps, "Vim plus some other stuff." But really, the answer should be: "Unix." Here's what that currently looks like:

My current Toolchain:

  1. vim. Editors are personal decisions. There are many valid alternatives. Everyone should use what they like. I like vim. Color files allow you to customize the look (I'm currently using blackboard.vim ) and there are syntax files for every language that I use, providing indenting and highlighting that integrates with my chosen color file. These either are already bundled with vim or are available via plugins.

  2. vim plugins. There are lots to choose from. These play a large role in my everyday development.

    • ctrlp - file browsing.
    • vim-slime - code evaluation. Allows me to eval arbitrary code snippets in a repl or even a bare shell (locally or remotely), with a couple of keystrokes.
    • vim-snipmate & vim-snippets - language-specific code expansion. I don't use these as often as I should. They can be real time savers. And you can write your own.
    • There are also others that provide language-specific bells & whistles that I have installed, but don't currently use much.
  3. BASH. Another way to look at "Unix is my IDE" is that I've been steadily applying the unix way to both my systems and my development environment. Each of my projects (and my home directory) has a bin directory full of little bash scripts that automate my development. There are certainly other shells. Use whatever you like. I like bash. These scripts lever all kinds of tools to automate little bits of my work flow - an exhaustive list would be long, but a few tools and ideas crop up a lot, such as the usual suspects: awk, sed, grep, find, tr, cut, and curl. Others that show up less often (but importantly) are: process substitution, parallel, htop, and pstree. The following are especially useful for IDE-like behavior:

    • tmux. I used to use screen, but I like tmux better because it plays better with vim-slime (and now I'm used to it). Screen is fine. I like tmux. I use tmux for all sorts of things, but IDE-wise my main use is as a target for vim-slime. By running tmux in a shell (I usually have at least two shells open while coding, when it gets above six I start paring them down!), I can hit ctrl-c, ctrl-c from within vim and the lines under the curose show up in the tmux session. Whatever happens to be running there (e.g. a repl, or even the bare shell) evals the lines.

      Another important way I use tmux in development is to extend my visible screen real-estate. I open an ssh session from another computer (e.g my laptop, or even a tablet) and start my tests running in a tmux session. I then position it just at the edge of my vision. As long as it stays green, I know my tests are passing (see entr below for how the tests run with each file change).

    • jq. unix tools are typically pipelined together with text as the input and output. Since a lot of the code I write uses json as a marshalling and IPC format, having an easy way to parse and manipulate json is an important part of my scripting. jq makes this very easy to do. If it didn't exist, I'd have to write some lame version of it to get my job done, so I'm glad it exists.

    • entr. A simple yet powerful tool. Give it a list of files and/or directories and each time they change, it will run a command that you specify. Two places this shows up in my development stack all the time is auto-building web pages and continuous testing] scripts. The latter is especially key: Each save triggers the tests to run, so long as the tests are FIRE proof the run almost at the blink of an eye. I used to use guard for this, but unless I'm working in ruby (I haven't been doing so lately) I don't really like having to include it into my projects. I don't have this problem with entr.
  4. Python. I use straight shell scripting for most of my integration, but I do also use python a fair bit (when things move away from general tool, file system and process integration). Two items in particular show up in my web development setups:

    • 'python -m SimpleHTTPServer' this starts a basic webserver in whatever directory it's called on. By default, the port is 8000 but it takes the port as a parameter. I use this from everything to serving web-based testing tools (e.g jasmine) to viewing markup as I edit it, to sharing documentation.
    • livereload. I use chrome for just about everything and I prefer Chrome-hosted front-ends for UI work whenever possible. I use this module to auto-reload the page. For example, to write this entry, I have entr watching the markdown files for this page. When they change, it runs a script that generates the page's html and livereload refreshes the browser.
  5. aliases. I use them for all kinds of things - any script or common version of a frequently used command lines. Here's a couple examples:

    • alias gs='git status -s'
    • alias webshare='python -m SimpleHTTPServer' for the python snippet above.
    • alias work-test='ssh workstation -t tmux new -A -s tests this is how I connect to run my tests from my laptop. It will either reconnect or start a new tmux session.
  6. Build tools. Nearly every language out there (and all the ones I use) have command-line tools for compiling/packaging/bundling an application for deployment. Here's two that see a lot of use in my scripts these days:

    • Make. I use make mostly for simple process automation (single page files), but from the POV of integration it's just another call from an entr or specific bash script. For exampnle, I've been expirimenting with it for integrating pandoc-based toolchains to generate pdf and html versions of the same source data.
    • Leiningen. Most clojure programmers use leiningen, I'm guessing. But I call it out because it's a good example of a language-specific tool that is woven into my dev tool Chain. I also have a vim plugin installed for it, but I don't use it much.

That's the basic idea. The actual tools and integrations change from project to project (and over time, but hopefully that gets the idea across.

Why I like this

The only real justification for adopting this set up is that "I like it" - there's lot's of ways to do this thing we call development, and I'm not really keen on arguing about it. But, there are some reasons that occur to me, and I thought I'd share them.

...

Rationale

This section is for those skeptical that Unix constitutes an IDE (I was going to delete this, but since I wrote it I may as well share it) I suppose this hinges on one's definition. Well, as wikipedia defines it:

An integrated development environment (IDE) is a software application that provides comprehensive facilities to computer programmers for software development.

So, really any application that provides such "comprehensive facilities" should qualify. Including Unix2. And in fact, later in the same article there is direct mention of Unix in this capacity - including a reference:

"Unix programmers can combine command-line POSIX tools into a complete development environment, capable of developing large programs such as the Linux kernel and its environment.[4] In this sense, the entire Unix system functions as an IDE."

Unfortunately, the "reference" currently points to a two-line stub on the C2 wiki, so it's basically anonymous opinion. But, one I happen to agree with3.

For me, an IDE must provide two types of services to be useful. The first, is a development toolchain. The wikipedia article again seems to agree. Returning to the first paragraph:

An IDE normally consists of a source code editor, build automation tools and a debugger. Most modern IDEs have intelligent code completion. Some IDEs [...] contain a compiler, interpreter, or both; [...] Sometimes a version control system, or various tools to simplify the construction of a Graphical User Interface (GUI), are integrated. Many modern IDEs also have a class browser, an object browser, and a class hierarchy diagram, for use in object-oriented software development.

I also want that integration bit. Namely, some combination of convenience, context sharing (i.e. one can easily invoke the tools with information from one or more of the others) and repeatability (so I don't have to start from scratch every time I add a file or start a new project).

In conclusion.

So when I say unix is my IDE, I mean it supports my development toolchain and provides a means for integrating them. My rationale is that while the learning curve is a bit steeper than "language-specific tool X" that investment pays off in the amount of control I have, the relatively little change I need to make as I move between projects and/or languages and that the learning has applications beyond my IDE-related needs. That it blurs the distinction between using my computer in general, for development, for support, for troubleshooting, etc I consider a feature, not a bug. Whatever you decide works best for you, I hope you found this description useful and are convinced that "Unix" is a legitimate answer to the question "what is your IDE."


  1. Java is a partial exception to this rule, but I don't work in straight Java very often. Several years ago, Ben Rady convinced me that the structure of all but the simplest of Java projects, almost requires the use of a language-specific IDE. I like IntelliJ for this. Not suprisingly, I feel the same way about C# - I expect that I would still reach for Visual Studio if confronted with a Windows .NET project, though I haven't worked with that language (or platform) in almost a decade. 

  2. "Unix" as I am using the term here refers more to the philosphy of unix-like OS's than to any particular flavor. My current development OS's are ubuntu and Mac OS X, neither of which are "Unix" in the strict sense, but both of which are "unix-like" enough for the purposes of serving as an IDE. Feel free to substitute and/or refine these terms as your pedantry dictates. 

  3. I may even be quoting myself - I spent a fair bit of time on the C2 wiki back in the day.