Example #1
0
        public static void ListMatches(ref Statistics statistics, ThreadData threadData, bool simple, WaitHandle cancelEvent)
        {
            if (threadData.Exception != null)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"Read error of file: {threadData.Filename}");
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine($"Exception: {threadData.Exception.Message}");
                return;
            }

            if (threadData.Matches.Count == 0)
            {
                return;
            }

            Console.WriteLine();

            ++statistics.Files;
            statistics.TotalMatches += threadData.Matches.Count;

            Console.BackgroundColor = ConsoleColor.DarkBlue;
            int x = Console.CursorLeft;
            int y = Console.CursorTop;

            for (int i = 0; i < Console.BufferWidth - 1; ++i)
            {
                Console.Write(' ');
            }

            Console.SetCursorPosition(x, y);

            Console.ForegroundColor = ConsoleColor.White;
            Console.Write($" {threadData.Filename}");
            Console.ForegroundColor = ConsoleColor.Gray;

            var results_str = $"{threadData.Matches.Count} result{(threadData.Matches.Count == 1 ? "" : "s")} ";

            Console.Write(results_str.PadLeft(Console.BufferWidth - threadData.Filename.Length - 1));
            Console.BackgroundColor = ConsoleColor.Black;

            //Console.WriteLine();
            Console.WriteLine();

            int MaxPrintLength = Console.BufferWidth - 12;

            var printed_lines_hash = new HashSet <int>();
            var match_lines        = new HashSet <int>();

            foreach (var match in threadData.Matches)
            {
                var i = match.Line - 1;
                match_lines.Add(i);
            }

            int previous_line = -1;

            foreach (var match in threadData.Matches)
            {
                if (cancelEvent.WaitOne(0))
                {
                    break;
                }

                var i = match.Line - 1;

                if (!simple)
                {
                    if (previous_line != -1 &&
                        previous_line != i)
                    {
                        Console.ForegroundColor = ConsoleColor.DarkGray;
                        for (int j = 0; j < Console.BufferWidth - 1; ++j)
                        {
                            Console.Write('=');
                        }
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine();
                    }

                    for (int j = Math.Max(0, i - 5); j < i; ++j)
                    {
                        if (match_lines.Contains(j))
                        {
                            continue;
                        }

                        if (printed_lines_hash.Contains(j))
                        {
                            continue;
                        }

                        printed_lines_hash.Add(j);

                        Console.Write($"{(j + 1).ToString().PadLeft(6)}: ");
                        var part = threadData.Lines[j];
                        if (part.Length > MaxPrintLength - 3)
                        {
                            part = part.Substring(0, MaxPrintLength - 3) + "...";
                        }
                        Console.WriteLine(part);
                        previous_line = j + 1;
                    }
                }

                Console.Write($"{(i + 1).ToString().PadLeft(6)}: ");
                previous_line = i + 1;

                var chunk_before = threadData.Lines[i].Substring(0, match.Offset);
                var chunk        = threadData.Lines[i].Substring(match.Offset, match.Length);
                var chunk_after  = threadData.Lines[i].Substring(match.Offset + match.Length);

                var print_len = MaxPrintLength;
                print_len -= chunk.Length;
                if (print_len > 0)
                {
                    var len = Math.Min(print_len, chunk_before.Length + 3);
                    print_len -= len;

                    if (chunk_before.Length > len)
                    {
                        chunk_before = "..." + chunk_before.Substring(chunk_before.Length - Math.Max(0, (len - 3)));
                    }

                    if (chunk_after.Length > print_len)
                    {
                        chunk_after = chunk_after.Substring(0, Math.Max(0, print_len - 3)) + "...";
                    }
                }
                else
                {
                    chunk_before = "";
                    chunk_after  = "";
                }

                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write(chunk_before);
                Console.BackgroundColor = ConsoleColor.DarkMagenta;
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(chunk);
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(chunk_after);
                Console.ForegroundColor = ConsoleColor.Gray;

                if (!simple)
                {
                    for (int j = i + 1; j < Math.Min(threadData.Lines.Length, i + 6); ++j)
                    {
                        if (match_lines.Contains(j))
                        {
                            break;
                        }

                        if (printed_lines_hash.Contains(j))
                        {
                            continue;
                        }

                        printed_lines_hash.Add(j);

                        Console.Write($"{(j + 1).ToString().PadLeft(6)}: ");
                        var part = threadData.Lines[j];
                        if (part.Length > MaxPrintLength - 3)
                        {
                            part = part.Substring(0, MaxPrintLength - 3) + "...";
                        }
                        Console.WriteLine(part);

                        previous_line = j + 1;
                    }
                }
            }
        }
Example #2
0
        static int Main(string[] args)
        {
            var searchRegex   = string.Empty;
            var ignoreCase    = false;
            var includeHidden = false;
            var simple        = false;
            var dirs          = new List <string>()
            {
                ""
            };
            var findFilesMode = false;

            for (int i = 0; i < args.Length; ++i)
            {
                if (args[i] == "-v" ||
                    args[i] == "--version")
                {
                    Console.WriteLine($"QFind Version {Version}");
                    return(0);
                }

                if (args[i] == "-i")
                {
                    ignoreCase = true;
                }
                else if (args[i] == "-a")
                {
                    includeHidden = true;
                }
                else if (args[i] == "-s")
                {
                    simple = true;
                }
                else if (args[i] == "--ext")
                {
                    if (i + 1 >= args.Length)
                    {
                        Console.WriteLine("--ext requires an argument that contains a list of comma separated file extensions.");
                        return(1);
                    }

                    var arg = args[++i];
                    if (arg != "*")
                    {
                        var extensions = Utilities.ReadExtensionsList(arg);
                        Finder.ExtensionRegex = new Regex($"\\.({string.Join("|", extensions)})$", RegexOptions.IgnoreCase);
                    }
                    else
                    {
                        Finder.ExtensionRegex = new Regex(@"\.");
                    }
                }
                else if (args[i] == "--exc")
                {
                    if (i + 1 >= args.Length)
                    {
                        Console.WriteLine("--exc requires an argument that contains a list of comma separated file extensions to exclude.");
                        return(1);
                    }

                    var extensions = Utilities.ReadExtensionsList(args[++i]);
                    Finder.ExtensionExcludeRegex = new Regex($"\\.({string.Join("|", extensions)})$", RegexOptions.IgnoreCase);
                }
                else if (args[i] == "--dirs")
                {
                    if (i + 1 >= args.Length)
                    {
                        Console.WriteLine("--dirs requires an argument that contains a list of comma separated directories to scan.");
                        return(1);
                    }

                    dirs.Clear();
                    dirs.AddRange(args[++i].Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries));
                }
                else if (args[i] == "-f")
                {
                    findFilesMode = true;
                }
                else
                {
                    searchRegex = args[i];
                }
            }

            using (var cancelEvent = new ManualResetEvent(false))
            {
                Console.CancelKeyPress += (sender, e) =>
                {
                    e.Cancel = true;
                    cancelEvent.Set();
                };

                if (string.IsNullOrEmpty(searchRegex))
                {
                    Console.Write("Find regex> ");
                    searchRegex = Console.ReadLine();
                }

                if (cancelEvent.WaitOne(0) ||
                    searchRegex == null)
                {
                    return(0);
                }

                var stopwatch = Stopwatch.StartNew();

                var options = RegexOptions.None;
                if (ignoreCase)
                {
                    options |= RegexOptions.IgnoreCase;
                }

                Finder.SearchRegex = new Regex(searchRegex, options);

                var statistics = new Statistics();

                if (findFilesMode)
                {
                    // find files
                    foreach (var dir in dirs)
                    {
                        foreach (var match in FileFinder.Scan(cancelEvent, dir, Finder.SearchRegex, ref statistics))
                        {
                            if (match.Start > 0)
                            {
                                Console.Write(match.Fullpath.Substring(0, match.Start));
                            }

                            Console.ForegroundColor = ConsoleColor.Magenta;
                            Console.Write(match.Filename.Substring(0, match.Length));
                            Console.ForegroundColor = ConsoleColor.Gray;

                            if (match.Start + match.Length < match.Fullpath.Length)
                            {
                                Console.Write(match.Fullpath.Substring(match.Start + match.Length));
                            }

                            Console.WriteLine();
                        }
                    }
                }
                else
                {
                    // scan inside files
                    var numberOfThreads = Environment.ProcessorCount;
                    var backlog         = new ThreadData[numberOfThreads];
                    var backlog_threads = new Thread[numberOfThreads];
                    int backlog_count   = 0;

                    for (int i = 0; i < backlog.Length; ++i)
                    {
                        backlog[i] = new ThreadData(cancelEvent);
                    }

                    foreach (var dir in dirs)
                    {
                        Finder.RecursiveFind(cancelEvent, dir, includeHidden, filename =>
                        {
                            statistics.TotalFilesScanned++;

                            backlog[backlog_count].Reset(filename);
                            (backlog_threads[backlog_count] = new Thread(Finder.ProcessFileThread)).Start(backlog[backlog_count]);
                            if (++backlog_count == backlog.Length)
                            {
                                for (int i = 0; i < backlog_count; ++i)
                                {
                                    backlog_threads[i].Join();
                                    if (!cancelEvent.WaitOne(0))
                                    {
                                        Finder.ListMatches(ref statistics, backlog[i], simple, cancelEvent);
                                    }
                                }

                                backlog_count = 0;
                            }
                        });
                    }

                    for (int i = 0; i < backlog_count; ++i)
                    {
                        backlog_threads[i].Join();
                        if (!cancelEvent.WaitOne(0))
                        {
                            Finder.ListMatches(ref statistics, backlog[i], simple, cancelEvent);
                        }
                    }
                }

                stopwatch.Stop();

                var str = "";

                var canceled = cancelEvent.WaitOne(0);

                Console.ForegroundColor = ConsoleColor.White;

                if (statistics.TotalMatches != 0)
                {
                    Console.WriteLine();

                    Console.BackgroundColor = canceled ? ConsoleColor.DarkYellow : ConsoleColor.DarkGreen;
                    if (findFilesMode)
                    {
                        str = $" {statistics.TotalMatches} matches found";
                    }
                    else
                    {
                        str = $" {statistics.TotalMatches} matches found in {statistics.Files} files";
                    }
                }
                else
                {
                    Console.BackgroundColor = ConsoleColor.DarkRed;
                    str = $" No matches found";
                }

                str += $" ({statistics.TotalFilesScanned} files scanned - {stopwatch.Elapsed})";

                Console.Write(str.PadRight(Console.BufferWidth - 2) + "# ");
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine();

                if (canceled)
                {
                    Console.WriteLine();
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("<Operation was canceled prematurely>");
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
            }

            if (Debugger.IsAttached)
            {
                Console.ReadKey(true);
            }

            return(0);
        }