Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider adding empty lines between groups of using statements, or respect existing empty lines. #988

Open
belav opened this issue Nov 7, 2023 · 3 comments
Milestone

Comments

@belav
Copy link
Owner

belav commented Nov 7, 2023

The initial version of sorting usings (#661) did not retain existing empty lines.

If we try to retain existing empty lines then

  1. What happens when usings are moved?
  2. Can the user easily correct any misplaced empty lines?

If we add empty lines automatically

  1. Should they only appear between groups that are sorted? Or between the first part of the namespace?
// between sorted groups
using System.IO.Abstractions;
using System.Text.Json;
using System.Text.Json.Serialization;

using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

// by first part of namespace
using System.IO.Abstractions;
using System.Text.Json;
using System.Text.Json.Serialization;

using Microsoft.Extensions.Logging;

using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
@belav belav added this to the 0.27.0 milestone Nov 7, 2023
@parched
Copy link
Contributor

parched commented Nov 7, 2023

I'd be happy if it worked like this:

  1. Record which pairs of imports have a space between them.
  2. Sort as is currently done.
  3. For any of the pairs that still exist in the sorted output, reinsert the space between them.

@parched
Copy link
Contributor

parched commented Nov 7, 2023

Or, perhaps,

  1. Group by first part of the namespace
  2. Put System first
  3. Put the group that matches the namespace used in the file last
  4. Sort the rest alphabetically.

@Jackenmen
Copy link

Personally, I'm a fan of the following import groups separated by one empty line each:

  • standard library (System imports)
  • third-party (non-System imports)
  • first-party (imports from the same parent namespace as the one used by the file)

I'm not sure if there's a precedent for this in how existing C# code bases are formatted but this is similar to how import sorting works in Python formatters such as isort or ruff.

To extend this to all the supported types of using syntaxes (global/static modifiers, using alias) in C#, I propose:

// global usings at the top since they affect every source file
// split in groups in the same way as non-global imports
global using System.Timers;
global using static System.Math;

global using NonSystemA;
global using NonSystemB;

global using MyProject.Utils;

// System imports - sorted within specific `using` syntaxes
using System.Collections;
using System.Timers;
using static System.Console;
using static System.Math;
using NameB = System.Collections.Dictionary;  // sort by import name vs alias name - up for debate
using NameA = System.Collections.List;

// Non-System imports, same rules as above
using NonSystemA;
using NonSystemB;
using static NonSystemA.X;
using static NonSystemB.Y;
using NonSystemAlias = NonSystem.SomeClass;

// Same-namespace imports
using MyProject.ViewModel;
using static MyProject.Collections.Generic;

#if DEBUG // finally any usings in #if's
// use the same heuristics as outside (or continue not sorting as is the case with the released version)
#endif

namespace MyProject.View;  // or namespace MyProject.View { ... }

// actual code

@belav belav modified the milestones: 0.27.0, Planned Jan 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants