Skip to content

Commit e0d4ef2

Browse files
committed
Merge pull request #1028 from fdorg/organize-imports-better-sort
Organize/insert imports better sort
2 parents fbb09ad + c0c6e1c commit e0d4ef2

File tree

3 files changed

+99
-17
lines changed

3 files changed

+99
-17
lines changed

External/Plugins/ASCompletion/Completion/ASGenerator.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,7 +4219,8 @@ public static int InsertImport(MemberModel member, bool fixScrolling)
42194219
string txt;
42204220
int indent = 0;
42214221
int skipIfDef = 0;
4222-
Match mImport;
4222+
Match mImport;
4223+
var importComparer = new CaseSensitiveImportComparer();
42234224
while (line < curLine)
42244225
{
42254226
txt = sci.GetLine(line++).TrimStart();
@@ -4236,15 +4237,14 @@ public static int InsertImport(MemberModel member, bool fixScrolling)
42364237
else continue;
42374238
}
42384239
// insert imports after a package declaration
4239-
else if (txt.StartsWith("import"))
4240+
else if (txt.Length > 6 && txt.StartsWith("import") && txt[6] <= 32)
42404241
{
42414242
packageLine = -1;
42424243
found = true;
42434244
indent = sci.GetLineIndentation(line - 1);
42444245
// insert in alphabetical order
42454246
mImport = ASFileParserRegexes.Import.Match(txt);
4246-
if (mImport.Success &&
4247-
String.Compare(mImport.Groups["package"].Value, fullPath) > 0)
4247+
if (mImport.Success && importComparer.Compare(mImport.Groups["package"].Value, fullPath) > 0)
42484248
{
42494249
line--;
42504250
break;

External/Plugins/ASCompletion/Model/MemberModel.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,4 +538,98 @@ public int Compare(MemberModel a, MemberModel b)
538538
}
539539

540540
}
541+
542+
/// <summary>
543+
/// Compare members based on import name
544+
/// </summary>
545+
public class CaseSensitiveImportComparer : IComparer<MemberModel>
546+
{
547+
static Int32 GetPackageTypeSeparation(string import)
548+
{
549+
var dot = import.IndexOf('.');
550+
var lastDot = -1;
551+
var max = import.Length - 1;
552+
while (dot > 0 && dot < max)
553+
{
554+
if (Char.IsUpper(import[dot + 1]))
555+
return dot;
556+
lastDot = dot;
557+
dot = import.IndexOf('.', dot + 1);
558+
}
559+
if (dot < 0 || dot >= max) return lastDot;
560+
else if (dot == 0) return -1;
561+
else return dot;
562+
}
563+
564+
public static Int32 CompareImports(string import1, string import2)
565+
{
566+
IComparer cmp = StringComparer.Ordinal;
567+
var d1 = GetPackageTypeSeparation(import1);
568+
var d2 = GetPackageTypeSeparation(import2);
569+
// one or both imports do not have a package
570+
if (d1 < 0)
571+
{
572+
if (d2 > 0) return -1;
573+
else return cmp.Compare(import1, import2);
574+
}
575+
else if (d2 < 0)
576+
{
577+
if (d1 > 0) return 1;
578+
else return cmp.Compare(import1, import2);
579+
}
580+
// compare package
581+
var pkg1 = import1.Substring(0, d1);
582+
var pkg2 = import2.Substring(0, d2);
583+
var res = cmp.Compare(pkg1, pkg2);
584+
if (res != 0) return res;
585+
// compare type
586+
var tp1 = import1.Substring(d1 + 1);
587+
var tp2 = import2.Substring(d2 + 1);
588+
res = cmp.Compare(tp1, tp2);
589+
return res;
590+
}
591+
592+
#if DEBUG
593+
static void Assert(int res, int expected)
594+
{
595+
System.Diagnostics.Debug.Assert(res == expected, res + " was not expected " + expected);
596+
}
597+
598+
static CaseSensitiveImportComparer()
599+
{
600+
// poor man's unit tests
601+
Assert(GetPackageTypeSeparation("a.b.C"), 3);
602+
Assert(GetPackageTypeSeparation("a.b.c"), 3);
603+
Assert(GetPackageTypeSeparation("a.b.C.D"), 3);
604+
Assert(GetPackageTypeSeparation("a"), -1);
605+
Assert(GetPackageTypeSeparation(".a"), -1);
606+
Assert(GetPackageTypeSeparation("a."), -1);
607+
Assert(GetPackageTypeSeparation("a.b.c."), 3);
608+
609+
Assert(CompareImports("a", "A"), 32);
610+
Assert(CompareImports("a", "b"), -1);
611+
Assert(CompareImports("b", "a"), 1);
612+
Assert(CompareImports("a", "a"), 0);
613+
Assert(CompareImports("a.A", "b"), 1);
614+
Assert(CompareImports("a", "b.B"), -1);
615+
Assert(CompareImports("a.A", "b.A"), -1);
616+
Assert(CompareImports("b.A", "a.A"), 1);
617+
Assert(CompareImports("a.A", "a.A"), 0);
618+
Assert(CompareImports("a.A", "a.B"), -1);
619+
Assert(CompareImports("b.A", "a.A"), 1);
620+
Assert(CompareImports("a.A", "a.a"), -32);
621+
Assert(CompareImports("a.MathReal", "a.Mathematics"), -19);
622+
}
623+
#endif
624+
625+
public Int32 Compare(string import1, string import2)
626+
{
627+
return CompareImports(import1, import2);
628+
}
629+
630+
public Int32 Compare(MemberModel item1, MemberModel item2)
631+
{
632+
return CompareImports(item1.Type, item2.Type);
633+
}
634+
}
541635
}

External/Plugins/CodeRefactor/Commands/OrganizeImports.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ private void InsertImports(List<MemberModel> imports, String searchInText, Scint
149149
{
150150
String eol = LineEndDetector.GetNewLineMarker(sci.EOLMode);
151151
Int32 line = imports[0].LineFrom - DeletedImportsCompensation;
152-
ImportsComparerType comparerType = new ImportsComparerType();
153-
imports.Sort(comparerType);
152+
imports.Sort(new CaseSensitiveImportComparer());
154153
sci.GotoLine(line);
155154
Int32 curLine = 0;
156155
List<String> uniques = this.GetUniqueImports(imports, searchInText, sci.FileName);
@@ -219,17 +218,6 @@ public override Boolean IsValid()
219218

220219
}
221220

222-
/// <summary>
223-
/// Compare import statements based on import name
224-
/// </summary>
225-
class ImportsComparerType : IComparer<MemberModel>
226-
{
227-
public Int32 Compare(MemberModel item1, MemberModel item2)
228-
{
229-
return new CaseInsensitiveComparer().Compare(item1.Type, item2.Type);
230-
}
231-
}
232-
233221
/// <summary>
234222
/// Compare import statements based on declaration line
235223
/// </summary>

0 commit comments

Comments
 (0)