public CommandResult <(List <(FileSystemPath source, FileSystemPath target)> items, FindCounts counts)> Mv( CommandEvaluationContext context, [Parameter("source: file/directory or several corresponding to a wildcarded path")] WildcardFilePath source, [Parameter(1, "destination: a file or a directory")] FileSystemPath dest, [Option("i", "prompt before overwrite")] bool interactive, [Option("v", "explain what is being done")] bool verbose ) { if (source.CheckExists()) { var counts = new FindCounts(); var items = FindItems(context, source.FullName, source.WildCardFileName ?? "*", true, true, false, true, false, null, false, counts, false, false); var sourceCount = items.Count; List <(FileSystemPath src, FileSystemPath tgt)> r = new List <(FileSystemPath src, FileSystemPath tgt)>(); if (sourceCount > 1) { if (dest.CheckExists()) { if (!dest.IsDirectory) { Errorln("dest must be a directory"); return(new CommandResult <(List <(FileSystemPath, FileSystemPath)> items, FindCounts counts)>( (new List <(FileSystemPath, FileSystemPath)> { (source, dest) }, counts), ReturnCode.Error )); } else { // move multiple source to dest foreach (var item in items) { var msg = $"move {item.GetPrintableName()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { if (source.IsFile) { var newdest = Path.Combine(dest.FullName, item.Name); r.Add((item, new FileSystemPath(newdest))); File.Move(item.FullName, newdest); } else { var newdest = Path.Combine(dest.FullName, item.Name); Directory.Move(item.FullName, newdest); r.Add((item, new DirectoryPath(newdest))); } if (verbose) { context.Out.Echoln(msg.Replace("move ", "moved ")); } } } } } } else { if (dest.CheckExists(false)) { if (dest.IsDirectory) { // move one source to dest var msg = $"move {source.GetPrintableNameWithWlidCard()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { if (source.IsFile) { var newdest = Path.Combine(dest.FullName, source.NameWithWildcard); File.Move(source.FullNameWithWildcard, newdest); r.Add((new FilePath(source.FullNameWithWildcard), new FilePath(newdest))); } else { var newdest = Path.Combine(dest.FullName, source.NameWithWildcard); Directory.Move(source.FullName, newdest); r.Add((source, new DirectoryPath(newdest))); } if (verbose) { context.Out.Echoln(msg.Replace("move ", "moved ")); } } } else { // rename source (file) to dest (overwrite dest) var msg = $"rename {source.GetPrintableNameWithWlidCard()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { dest.FileSystemInfo.Delete(); File.Move(source.FullNameWithWildcard, dest.FullName); r.Add((new FilePath(source.FullNameWithWildcard), dest)); if (verbose) { context.Out.Echoln(msg.Replace("rename ", "renamed ")); } } } } else { // rename source to dest var msg = $"rename {source.GetPrintableNameWithWlidCard()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { if (source.IsFile) { File.Move(source.FullNameWithWildcard, dest.FullName); r.Add((new FilePath(source.FullNameWithWildcard), dest)); } else { Directory.Move(source.FullName, dest.FullName); r.Add((source, dest)); } if (verbose) { context.Out.Echoln(msg.Replace("rename ", "renamed ")); } } } } return(new CommandResult <(List <(FileSystemPath source, FileSystemPath target)> items, FindCounts counts)> ((r, counts))); } else { return(new CommandResult <(List <(FileSystemPath, FileSystemPath)> items, FindCounts counts)> ((new List <(FileSystemPath, FileSystemPath)> { (source, null) }, new FindCounts()))); } }