Minimal March – Part 1: Getting Started with .NET and C# at the Command-line

I wrote this tweet roughly a week ago about the state of .NET development that I was seeing on Twitter:

I see ‘Minimal March’ as a developer challenge for me, I’m someone who has spent the majority of the last 15 years working in a version of Visual Studio and C#. Let’s take away those comfortable and productive tools and expose me to more operating systems and more ways that folks can write applications. In this post, I’m going to outline the parameters of this .NET development event and show my initial configuration on Linux. I built this configuration live on my Twitch stream on March 1, 2020.

Watch Minimal March begins! .NET and Blazor development with text editors and command-line tools. !coffee from csharpfritz on

The Parameters

This event is all about using the smallest, least expensive, and most customizable tools to build .NET applications that are NOT provided by Microsoft. To that end, I’m starting with the following configuration:

This configuration provides minimal ‘big productivity’ features out of the box, but allows us to build console and server applications easily with just a terminal window and a browser.

Snapshot of my configuration at the conclusion of this article

Installation Steps

I followed the instructions on the .NET website to install the .NET SDK v3.1.2 and command-line tools using a package manager on my fresh Linux VM. After adding the required Microsoft repository configuration from those linked directions, I was able to run the following command to install .NET:

sudo apt-get install dotnet-sdk-3.1

I love seeing a very Linux-friendly way to work with .NET, right from the start.

Next, I wanted to enable syntax highlighting and type-ahead for my *.cs source code in vim. Fortunately, there is the community-owned Omnisharp project that provides support for vim. BUT… its not as simple as an apt-get command to install.

Preparing vim

vim (not vi, I made that mistake) is EXTREMELY versatile and can do many things, including running plugins when a plugin-manager is installed. For my configuration, I was able to use the built-in package manager for vim and just clone some files into my local directory to activate these plugins. First up was adding the Omnisharp plugin with a simple command to fetch from GitHub:

git clone git:// ~/.vim/pack/plugins/start/omnisharp-vim

Next, I wanted a file-browser in vim. For this, I was recommended to try out NERDTree and installed that with this command:

git clone ~/.vim/pack/vendor/start/nerdtree

Finally, I wanted to add the ability to enforce my EditorConfig settings using the .editorconfig configuration from the project folder. Fortunately, there’s an editorconfig plugin to handle this too:

git clone ~/.vim/pack/local/start/editorconfig-vim

I created my first .vimrc file with the following entries to make it a little easier to get around:

set nocompatible
filetype indent plugin on

map <C-n> :NERDTreeToggle<CR>
set number                       " show line-numbers
set tabstop=2                    " tab width is 2 spaces

I can now use Ctrl+n to open and close my “file-explorer”, the NERDTree. I’ve also turned on line numbers and set my tab-width to my preferred two spaces so that I can fit more code on screen during screencasting.

On-screen keystrokes

I normally use Carnac on Windows to show my hotkeys and interactions with the Visual Studio editor while screencasting on Twitch or giving presentations. For my minimal approach on Linux, I added screenkey to handle this task for me:

sudo apt-get install screenkey

I tuned the configuration slightly, primarily to ensure that it only showed the keystrokes that included modifier keys like Ctrl, Shift, or the Windows key. This helps prevent me from showing the world my password as I type it in.

screenkey configuration on my machine

Git command-prompt

In Windows, I use the excellent posh-git to tell me the current start of my git repository when I’m working in a folder that has git-managed assets. For Linux, I installed the bash-git-prompt from magicmonty to improve the look of my terminal:

git clone ~/.bash-git-prompt --depth=1

I then added this entry to my ~/.bashrc configuration for the terminal:

if [ -f "$HOME/.bash-git-prompt/" ]; then
    source $HOME/.bash-git-prompt/

Done. Now I have my source code status at the command-line. It could look cooler, but for a default configuration it works for me.


Next, I started using tmux, the terminal multiplexer. This allows me to split my terminal window so that I can have multiple command-line experiences on-screen at once. I’m not too familiar with the configuration of tmux yet, and I know I can customize tmux to run the way that I want it to with the panels and colors tuned for me… but that’s a separate blog post.

To get started, I launched tmux with the tmux command and used the default configuration. I added two vertical panels to the right with the following keystrokes:

Ctrl+b %
Ctrl+b "

I then was able to shrink my right panel by hitting Ctrl+b and HOLDING the Ctrl key while I pressed the right-arrow key several times to make the panel the width I desired. See the image at the top of the article for the width I set mine to. This operation is tedious, and I really want to save it to a configuration file so that tmux just looks RIGHT to me when I start it next time.

I can move around the panels in tmux by using the Ctrl+b <arrow-key> keystrokes in the direction I want to move the cursor. Note that you do NOT hold the Ctrl key when you press the arrow keys when executing this gesture.

Panel Configurations

In my configuration, I set the larger left-panel for my code editing experience. The top-right panel will run my webserver with the dotnet watch run command so that I can see the logs and I can restart it without impacting the rest of my configuration.

The lower-right panel will run my unit-tests with the dotnet watch test command. This way, as I change my code in the left panel, my tests automatically re-run and I know if I broke anything.

I think I need some scripts to automate these panels and I may change their font-size as well as move them around a little to make it easier to see all of the logs.

Next Steps

I’ve got a serviceable configuration at this point. I can build and run .NET Core, Blazor, and ASP.NET Core applications in Linux all at the command line. There are so many things that I can configure to automate and make my development easier, but at this point I feel like I have assembled my very own “Command-Line Visual Studio”.

I want to archive the git commands that I used to fetch my vim plugins and store my .vimrc on GitHub so that I can fetch them on other machines that I want to replicate this experience on.

The color and font themes in my console are not the most appealing to me. I’d really like to install Cascadia Code, a fresh vim color theme, and get that tmux configuration under control. The command-line for git could look better and I’d like to see some other status information on the tmux status bar. But that… is another blog post and Twitch session.