README.md |
Intro
I recently switched from fedora 41 to arch linux and found formatting in C# with my current configuration not working properly anymore
More precisely:
-
Formatting with omnisharp doesn't apply .editorconfig although properly configured +
-
When setting up csharpier as formatter for
.cs
files, Conform can't executedotnet-csharpier
anymore (as opposed to my fedora setup) due to:ConformInfo
reporting No frameworks were found
If you encounter similar issues on whatever system you're on, this article might just be what you need.
Scenario
Let's say we use the omnisharp LSP for formatting our .cs
files and we have an .editorconfig in our project path:
.
├── bin
├── .editorconfig
├── MyConsole.csproj
├── obj
└── Program.cs
The .editorconfig in our project path to define formatting rules looks like this:
root = true
# All files
[*]
charset = utf-8-bom
max_line_length = 20
# ...
The trained eye immediately spots the ridiculous max_line_length
value of 20
.
Given we have a ~/.omnisharp/omnisharp.json
file configured, as mentioned above, to make omnisharp use the project's .editorconfig for it's formatting, ..
// ~/.omnisharp/omnisharp.json
// ...
"FormattingOptions": {
"enableEditorConfigSupport": true
}
// ...
.. I would now expect any formatted file to look ridiculous:
Console.WriteLine(
"Hello, World!"
);
Console.WriteLine(
"Hello, World!"
);
Console.WriteLine(
"Hello, World!"
);
Console.WriteLine(
"Hello, World!"
);
Console.WriteLine(
"Hello, World!"
);
Console.WriteLine(
"Hello, World!"
);
The Problem
Interestingly max_line_length
does not seem to be regarded by omnisharp - whether that is a bug or a feature, I don't know. Either way, when I use <leader>fm
inside neovim nothing happens.
Running dotnet format
in the terminal magically also doesn't do the expected formatting either.
The Solution: Preparation
Arch Linux based docker test container
In order to reproduce the arch-linux specifc scenario, we create the following Dockerfile
FROM archlinux:latest
# Install required packages
RUN pacman -Sy --noconfirm \
ansible-core ansible \
sudo \
curl \
gcc \
git \
neovim \
ripgrep \
unzip \
npm \
wget \
dotnet-sdk-8.0 && \
ansible-config init --disabled > /ansible.cfg && \
pacman -Scc --noconfirm
# Create a new user 'ramboe' and give sudo access
RUN useradd -m -s /bin/bash ramboe && \
echo "ramboe ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# Switch to the new user and set up home
USER ramboe
WORKDIR /home/ramboe
RUN mkdir Downloads Documents
RUN cd Documents
RUN dotnet new console -n MyConsole
CMD ["/bin/bash"]
then we build it with
docker build -t arch-dotnet-ramboe .
And finally run the container with
docker run -it --name my-arch-dotnet-container arch-dotnet-ramboe
you can start a exited container with
docker start -i my-arch-dotnet-container
[Docker Container] Ramboe nvim configuration
https://git.ramboe.io/configuration/dotfiles contains is the exact C# neovim configuration that ist already shown here
To install it, simply follow the instructions in the README.md
[Docker Container] Omnisharp Configuration
In case it doesn't already exist, create a omnisharp.json
file inside the ~/.omnisharp
directory like so
touch ~/.omnisharp/omnisharp.json
and make sure it configures omnisharp to enable .editorconfig
support:
// ~/.omnisharp/omnisharp.json
{
"RoslynExtensionsOptions": {
"enableAnalyzersSupport": false
},
"FormattingOptions": {
"enableEditorConfigSupport": true
}
}
The Solution
Options to solve the problem
In essence we have two options to choose from
- Use a different LSP instead of omnisharp that (hopefully) applies .editorconfig properly
- Use csharpier for formatting - with csharpier the .editorconfig is applied properly as well.
We go for option 2, csharpier, since we cannot only use it locally during development but also in a CI/CD pipeline and still expect consistent results.
In order to use csharpier with neovim, we use a plugin called Conform.
Conform - A Brief Introduction
NvChad makes it easy for us to deal with formatting since it ships already with conform pre-installed and pre-configured.
Within the default nvchad installation, we find a file ~/.config/nvim/lua/configs/conform.lua
that contains the formatting configuration for each file type:
-- ~/.config/nvim/lua/configs/conform.lua
local opts = {
formatters_by_ft = {
cs = { "csharpier" }, -- go into the 'formatters' section below and use whatever executable you find defined in the 'csharpier' block to format .cs files
-- ...
},
formatters = {
-- ...
csharpier = {
command = "dotnet-csharpier",
args = { "--write-stdout" },
},
},
}
require("conform").setup(opts)
formatters_by_ft
means "formatters by file type"
Essentially conform is a wrapper that automatically assigns the correct formatting executable (prettier, xmlformat, ..) to whatever file type we have in the current buffer. Formatting is done by the executable, not by conform itself.
Setup Conform to use csharpier for .cs files
Make sure to have csharpier configured in your conform configuration, found in ~/.config/nvim/lua/configs/conform.lua
:
[Arch Linux] The Problem with Csharpier
In order to do so conform needs to be able to load the executable correctly.
Mason Installation
Last time we installed csharpier with Mason
Which effectively installs the dotnet-csharpier executable on our system, in a way that neovim can use it. But does it?
But does it?
After the installation with Mason, although available for neovim, we are still not able to do a dotnet-csharpier
in the terminal, at least on arch:
Which might be fixable if we add csharpier to the ENV variable which still not guarantees that it is going to work properly when hitting <leader>fm
.
Conform is not amused
Although we installed the latest version of dotnet 8 with
sudo pacman -S dotnet-sdk-8.0
and are able to build, debug and run dotnet 8 applications, csharpier, as defined in '' is unhappy because :ConformInfo
says No frameworks were found:
This is because the version of csharpier
that is installed with Mason needs the specific version 8.0.100, which we have to install separately next to the latest version that comes with sudo pacman -S dotnet-sdk-8.0
[Arch Linux] Making Conform Happy again
When we go to the arch linux dotnet documentation we find the script to install multiple versions side by side, along with the instructions on how to run it in the terminal:
We download the script and make it executable with
sudo chmod +x ./dotnet-install.sh
We also make slight adjustments to the terminal command, so we use the csharpier friendly version 8.0.100
and life time support:
sudo ./dotnet-install.sh --install-dir /usr/share/dotnet -channel LTS -version 8.0.100
make sure to run as sudo to avoid permisson errors
After that is done csharpier should work just fine the next time you open neovim and whatever .editorconfig shall be applied perfectly.