belav / csharpier

CSharpier is an opinionated code formatter for c#.
https://csharpier.com
MIT License
1.41k stars 98 forks source link

Usings order #1246

Open ghost opened 6 months ago

ghost commented 6 months ago

Is it possible to define custom usings order? For example, I have an extension CSharpFormatUsings which formats a usings for me the way I want. It may remove unnecessary "using" clauses and even insert an empty line between using groups. CSharpier does format "using" as well but does it in its own way without the possibility of applying my own format. For example, I want "using UnityEngine" to go before my own namespace Galactical. It doesn't happen, and the UnityEngine namespace always goes to the last position. I also want to be able to split "using" groups.

But even more annoying, is that I cannot turn it off and use another extension to format using clauses! It always conflicts with CSharpier.

Input:

using System;
using System.Collections.Generic; // unused using!
using Galactical.CharacterController.Interfaces;
using UnityEngine;
using FSM.States
using FSM;
using Galactical.CharacterController.States;

Output:

using System;
using System.Collections.Generic; // unused using!
using FSM;
using FSM.States
using Galactical.CharacterController.Interfaces;
using Galactical.CharacterController.States;
using UnityEngine;

Expected behavior:

using System;

using UnityEngine;

using FSM;
using FSM.States

using Galactical.CharacterController.Interfaces;
using Galactical.CharacterController.States;

Config sample:

{
    "printWidth": 100,
    "useTabs": true,
    "tabWidth": 4,
    "endOfLine": "auto",
    "usingsOrder": ["System", "UnityEngine", "FSM", "Galactical"],
    "splitUsingGroups": true,
    "removeUnusedUsings": true
}
belav commented 6 months ago

Regarding options -

CSharpier provides a few basic options that affect formatting and has no plans to add more. It follows the Option Philosophy of prettier.

I had intended to keep blank lines between some groups of usings but getting the logic working correctly when usings were moving was difficult and didn't seem worth the effort.

ghost commented 6 months ago

Regarding options -

CSharpier provides a few basic options that affect formatting and has no plans to add more. It follows the Option Philosophy of prettier.

I had intended to keep blank lines between some groups of usings but getting the logic working correctly when usings were moving was difficult and didn't seem worth the effort.

Prettier has a plugin prettier-plugin-sort-imports which does what I want - it sorts imports according to the importOrder config option. Maybe, it's possible to develop something similar for CSharpier? I am ready to put an effort into this thing.

belav commented 6 months ago

I'm not opposed to a plugin system, but I don't know of a good way to deal with it currently in a dotnet tool. There is this open issue proposing that microsoft add plugin support to dotnet tools. I have csproj/xml formatting mostly done in a branch and was hoping I could make that system extensible. So that other formatters could be added to csharpier.

It looks like the prettier plugin works as a preprocessor, which I assume does the sorting on the syntax tree first and then prettier does the formatting. The CSharpier using sorting happens at the same time as the formatting. That would need to go away for a preprocessor plugin to be able to sort the usings.

Another potential option is a postprocessor plugin, which modifies the syntax tree after csharpier is done with it.