Esempio n. 1
0
        public CommandVoidResult ComParamColTest(
            CommandEvaluationContext context,
            [Option("A", "optiona", "option a", true, true)] DirSort A,
            [Option("b", "b", "option b", true, true)] List <string> b,
            [Option("c", "c", "option c", true, true)] List <int> c,
            [Parameter(1, "x", true)] DirSort B,
            [Parameter(2, "y", true)] List <DirSort> C
            )
        {
            int i = 0;
            var v = Enum.GetValues(typeof(DirSort));

            foreach (var s in Enum.GetNames(typeof(DirSort)))
            {
                context.Out.Echo($"s={s} n={(int)v.GetValue(i)}", true);
                i++;
            }

            context.Out.Echo("A="); context.Out.Echo(A, true);
            context.Out.Echo("b=");
            context.Out.Echo(b, true);
            context.Out.Echo("c="); context.Out.Echo(c, true);
            context.Out.Echo("B="); context.Out.Echo(B, true);
            context.Out.Echo("C="); context.Out.Echo(C, true);
            return(CommandVoidResult.Instance);
        }
        public CommandResult <(List <FileSystemPath> items, FindCounts counts)> Dir(
            CommandEvaluationContext context,
            [Parameter("path where to list files and folders. if not specified is set to the current directory. use wildcards * and ? to filter files and folders names", true)] WildcardFilePath path,
            [Option("n", "name", "names only: do not print file system attributes")] bool noattributes,
            [Option("r", "recurse", "also list files and folders in sub directories. force display files full path")] bool recurse,
            [Option("w", "wide", "displays file names on several columns so output fills console width (only if not recurse mode). disable print of attributes")] bool wide,
            [Option("f", "file", "filter list on files (exclude directories). avoid -d")] bool filesOnly,
            [Option("d", "dir", "filter list on directories (exclude files)")] bool dirsOnly,
            [Option("s", "sort", "sort list of files and folders. default is alphabetic, mixing files and folders", true, true)] DirSort sort = DirSort.dir | DirSort.name
            )
        {
            var r = new List <FileSystemPath>();

            path ??= new WildcardFilePath(Environment.CurrentDirectory);
            if (path.CheckExists(context))
            {
                var counts = new FindCounts();

                var items = FindItems(context, path.FullName, path.WildCardFileName ?? "*", !recurse, true, false, !noattributes, !recurse, null, false, counts, false, false);

                if (filesOnly)
                {
                    dirsOnly = false;
                }
                if (filesOnly)
                {
                    items = items.Where(x => x.IsFile).ToList();
                }
                if (dirsOnly)
                {
                    items = items.Where(x => x.IsDirectory).ToList();
                }

                // apply sorts - default (.net) is name (==DirSort.name==1) - possible DirSort.not_specified==0 == default sort by name
                if (sort != DirSort.not_specified && sort != DirSort.name)
                {
                    IEnumerable <IGrouping <string, FileSystemPath> > grp = null;

                    if (sort.HasFlag(DirSort.ext))
                    {
                        grp = items.GroupBy((x) => Path.GetExtension(x.FullName));
                    }
                    else if (sort.HasFlag(DirSort.file))
                    {
                        grp = items.GroupBy((x) => x.IsDirectory + "");
                    }
                    else if (sort.HasFlag(DirSort.dir))
                    {
                        grp = items.GroupBy((x) => x.IsFile + "");
                    }
                    else if (sort.HasFlag(DirSort.size))
                    {
                        grp = items.GroupBy((x) => !x.IsFile + "");
                    }

                    var lst = grp.ToList();
                    lst.Sort((x, y) => x.Key.CompareTo(y.Key)); // sort alpha
                    if (!sort.HasFlag(DirSort.file) && !sort.HasFlag(DirSort.dir) && !sort.HasFlag(DirSort.size) && sort.HasFlag(DirSort.rev))
                    {
                        lst.Reverse();
                    }

                    items.Clear();
                    foreach (var g in lst)
                    {
                        var glst = g.ToList();
                        if (!sort.HasFlag(DirSort.size))
                        {
                            glst.Sort((x, y) => x.FullName.CompareTo(y.FullName));    // sort alpha
                        }
                        else
                        {
                            glst.Sort((x, y) => x.Length.CompareTo(y.Length));    // sort size
                        }
                        if (sort.HasFlag(DirSort.rev))
                        {
                            glst.Reverse();
                        }
                        items.AddRange(glst);
                    }
                }

                var  f                       = DefaultForegroundCmd;
                long totFileSize             = 0;
                var  cancellationTokenSource = new CancellationTokenSource();
                if (wide)
                {
                    noattributes = true;
                }

                // here we self handle the console Cancel event so we can output a partial result even if the seek phasis has been broke. print can also be broke.
                // TODO: seems there is now a simple way to do this. Just use the context cancellation token (as in findItems) :
                // TODO: if (context.CommandLineProcessor.CancellationTokenSource.Token.IsCancellationRequested) // then cancel com

                void postCmd(object o, EventArgs e)
                {
                    sc.CancelKeyPress -= cancelCmd;
                    context.Out.Echoln($"{Tab}{context.ShellEnv.Colors.Numeric}{Plur("file", counts.FilesCount, f),-30}{HumanFormatOfSize(totFileSize, 2, " ", context.ShellEnv.Colors.Numeric.ToString(), f)}");
                    context.Out.Echoln($"{Tab}{context.ShellEnv.Colors.Numeric}{Plur("folder", counts.FoldersCount, f),-30}{Drives.GetDriveInfo(path.FileSystemInfo.FullName, false, context.ShellEnv.Colors.Numeric.ToString(), f, " ", 2)}");
                }

                void cancelCmd(object o, ConsoleCancelEventArgs e)
                {
                    e.Cancel = true;
                    cancellationTokenSource.Cancel();
                }

                int printResult()
                {
                    var i = 0;

                    int maxitlength = 0;

                    counts.FilesCount = counts.FoldersCount = 0;
                    foreach (var item in items)
                    {
                        if (item.IsFile)
                        {
                            totFileSize += ((FileInfo)item.FileSystemInfo).Length;
                            counts.FilesCount++;
                        }
                        else
                        {
                            counts.FoldersCount++;
                        }
                        maxitlength = Math.Max(item.Name.Length, maxitlength);
                    }
                    maxitlength += 4;
                    var(id, left, top, right, bottom) = DotNetConsole.ActualWorkArea();
                    var nbcols = Math.Floor((double)(right - left + 1) / (double)maxitlength);

                    int nocol = 0;

                    foreach (var item in items)
                    {
                        if (cancellationTokenSource.IsCancellationRequested)
                        {
                            return(i);
                        }

                        item.Echo(
                            new EchoEvaluationContext(
                                context.Out, context,
                                new FileSystemPathFormattingOptions(
                                    !noattributes,
                                    !recurse,
                                    "",
                                    ((!wide || recurse || nocol == nbcols - 1) ? Br : ""),
                                    (wide && !recurse) ? maxitlength : -1, "")));
                        i++;
                        nocol++;
                        if (nocol == nbcols)
                        {
                            nocol = 0;
                        }
                    }
                    if (!recurse && wide && nocol < nbcols && nocol > 0)
                    {
                        context.Out.Echoln();
                    }
                    return(i);
                }

                sc.CancelKeyPress += cancelCmd;
                var task = Task.Run <int>(() => printResult(),
                                          cancellationTokenSource.Token);
                try
                {
                    task.Wait(cancellationTokenSource.Token);
                }
                catch (OperationCanceledException)
                {
                    var res = task.Result;
                }
                postCmd(null, null);
                return(new CommandResult <(List <FileSystemPath>, FindCounts)>((items, counts)));
            }
            return(new CommandResult <(List <FileSystemPath>, FindCounts)>((r, new FindCounts()), ReturnCode.Error));
        }
Esempio n. 3
0
 public InLineSorter(DirSort dirsort)
 {
     this.dirSort = dirsort;
 }