importsort-d

Sort and format imports in DLang
Log | Files | Refs | README

commit 6c5da795541523f1fadd6f5182b9b4768ea4c403
parent baea7b0cfb7ad786fe3a9f8c14d9096449f2cbc0
Author: Friedel Schön <[email protected]>
Date:   Fri, 22 Dec 2023 21:03:35 +0100

trailing arguments are inputs

Diffstat:
MREADME.md | 4++--
Msrc/main.d | 58+++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/sort.d | 50+++-----------------------------------------------
3 files changed, 56 insertions(+), 56 deletions(-)

diff --git a/README.md b/README.md @@ -61,7 +61,7 @@ Look at the documentation at [`dpldocs.info`](https://importsort-d.dpldocs.info/ "emeraldwalk.runonsave": { "commands": [ { - "cmd": "importsort-d --inplace --inputs=${file}", + "cmd": "importsort-d --inplace ${file}", "match": "\\.d$" } ] @@ -72,7 +72,7 @@ Look at the documentation at [`dpldocs.info`](https://importsort-d.dpldocs.info/ ### How to add `importsort-d` to VIM/NeoVIM? > Just add this to your `.vimrc` or `init.vim` ```vim -:autocmd BufWritePost * silent !importsort-d --inplace --inputs=<afile> +:autocmd BufWritePost * silent !importsort-d --inplace <afile> ``` ### Are cats cool? diff --git a/src/main.d b/src/main.d @@ -1,17 +1,61 @@ // (c) 2022 Friedel Schon <[email protected]> module importsort.main; -import importsort.sort : SortConfig; -import argparse : CLI; + +import argparse; import core.stdc.stdlib : exit; import importsort.sort : Import, sortImports; import std.array : replace; import std.file : DirEntry, SpanMode, dirEntries, exists, isDir, isFile; import std.functional : unaryFun; -import std.stdio : File, stderr, stdin, stdout; import std.range : empty; +import std.stdio : File, stderr, stdin, stdout; import std.string : endsWith; +/// current version (and something I always forget to update oops) +enum VERSION = "0.3.0"; + +/// configuration for sorting imports +@(Command("importsort-d").Description("Sorts dlang imports").Epilog("Version: v" ~ VERSION)) +struct SortConfig { + @(ArgumentGroup("Input/Output arguments") + .Description( + "Define in- and output behavior. Trailing arguments are considered input-files.")) { + @(NamedArgument(["recursive", "r"]).Description("recursively search in directories")) + bool recursive = false; + + @(NamedArgument(["inplace", "i"]).Description("writes to the input")) + bool inplace = false; + + @(NamedArgument(["output", "o"]).Description("writes to `path` instead of stdout")) + string output; + } + + @(ArgumentGroup("Sorting arguments").Description("Tune import sorting algorithms")) { + /// won't format the line, keep it as-is + @(NamedArgument(["keep", "k"]).Description("keeps the line as-is instead of formatting")) + bool keepLine = false; + + @(NamedArgument(["attribute", "a"]).Description("public and static imports first")) + /// sort by attributes (public/static first) + bool byAttribute = false; + + @(NamedArgument(["binding", "b"]).Description("sorts by binding rather then the original")) + /// sort by binding instead of the original + bool byBinding = false; + + @(NamedArgument(["merge", "m"]).Description("merge imports which uses same file")) + /// merges imports of the same source + bool merge = false; + + /// ignore case when sorting + @(NamedArgument(["ignore-case", "c"]).Description("ignore case when comparing elements")) + bool ignoreCase = false; + } + + string[] inputs; +} + /// list entries (`ls`) from all arguments DirEntry[] listEntries(alias F = "true")(string[] input, bool recursive) { alias filterFunc = unaryFun!F; @@ -42,7 +86,9 @@ DirEntry[] listEntries(alias F = "true")(string[] input, bool recursive) { return entries; } -int _main(SortConfig config) { +mixin CLI!(SortConfig).main!((config, unparsed) { + config.inputs = unparsed; + if (config.recursive && config.inputs.empty) { stderr.writeln("error: cannot use '--recursive' and specify no input"); exit(1); @@ -64,6 +110,4 @@ int _main(SortConfig config) { listEntries(config.inputs, config.recursive).sortImports(config); } return 0; -} - -mixin CLI!(SortConfig).main!((config) { return _main(config); }); +}); diff --git a/src/sort.d b/src/sort.d @@ -1,7 +1,10 @@ module importsort.sort; +import argparse; +import importsort.main : SortConfig; import std.algorithm : findSplit, remove, sort; import std.array : split; +import std.conv : to; import std.file : DirEntry, rename; import std.functional : unaryFun; import std.range : ElementType; @@ -10,54 +13,7 @@ import std.stdio : File, stderr; import std.string : strip, stripLeft; import std.traits : isIterable; import std.typecons : Yes; -import std.conv : to; import std.uni : asLowerCase; -import argparse; - -/// current version (and something I always forget to update oops) -enum VERSION = "0.3.0"; - -/// configuration for sorting imports -@(Command("importsort-d").Description("Sorts dlang imports").Epilog("Version: v" ~ VERSION)) -struct SortConfig { - @(ArgumentGroup("Input/Output arguments").Description("Define in- and output behavior")) { - @(NamedArgument(["recursive", "r"]).Description("recursively search in directories")) - bool recursive = false; - - @(NamedArgument(["inplace", "i"]).Description("writes to the input")) - bool inplace = false; - - @(NamedArgument(["output", "o"]).Description("writes to `path` instead of stdout")) - string output; - - @(NamedArgument(["inputs", "in"]) - .Description("input files or directories, can be set to '-' to read from stdin")) - string[] inputs; - } - - @(ArgumentGroup("Sorting arguments").Description("Tune import sorting algorithms")) { - /// won't format the line, keep it as-is - @(NamedArgument(["keep", "k"]).Description("keeps the line as-is instead of formatting")) - bool keepLine = false; - - @(NamedArgument(["attribute", "a"]).Description("public and static imports first")) - /// sort by attributes (public/static first) - bool byAttribute = false; - - @(NamedArgument(["binding", "b"]).Description("sorts by binding rather then the original")) - /// sort by binding instead of the original - bool byBinding = false; - - @(NamedArgument(["merge", "m"]).Description("merge imports which uses same file")) - /// merges imports of the same source - bool merge = false; - - /// ignore case when sorting - @(NamedArgument(["ignoreCase", "c"]).Description("ignore case when comparing elements")) - bool ignoreCase = false; - } - -} /// the pattern to determinate a line is an import or not enum PATTERN = ctRegex!`^(\s*)(?:(public|static)\s+)?import\s+(?:(\w+)\s*=\s*)?([a-zA-Z._]+)\s*(:\s*\w+(?:\s*=\s*\w+)?(?:\s*,\s*\w+(?:\s*=\s*\w+)?)*)?\s*;[ \t]*([\n\r]*)$`;