Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Source Code Super Search

, 10 Mar 2009 CPOL
A simple solution for searching source code directories
BSCodeGrep.zip
BSCodeGrep
branches
0.9 VS Add-In
BSCodeGrep
Classes
folder_explore copy.ico
Forms
icons
add.png
application_form.png
arrow_right.png
delete.png
find.png
folder.png
folder_explore copy.ico
folder_explore.png
folder_page.png
information.png
lightning.png
magnifier.png
note_edit.png
package_system.png
star.png
Properties
Settings.settings
CodeSearchAddIn
CodeSearchAddIn.AddIn
CodeSearchAddIn.csproj.user
tags
trunk
BSCodeGrep
bin
Classes
folder_explore copy.ico
Forms
icons
add.png
application_form.png
arrow_right.png
delete.png
find.png
folder.png
folder_explore copy.ico
folder_explore.png
folder_page.png
information.png
lightning.png
magnifier.png
note_edit.png
package_system.png
script_go.png
star.png
Properties
Settings.settings
BSCodeGrep_src.zip
Properties
Settings.settings
BSCodeGrep.csproj.user
folder_explore copy.ico
Classes
Forms
icons
add.png
application_form.png
arrow_right.png
BSLogo.jpg
delete.png
exclamation.png
find.png
folder.png
folder_explore copy.ico
folder_explore.png
folder_page.png
information.png
lightning.png
magnifier.png
note_edit.png
package_system.png
page_save.png
script_go.png
star.png
VS2008_Add-In.zip
BSCodeGrep.pdb
CodeSearchAddIn.AddIn
CodeSearchAddIn.dll
BSCodeGrep.exe
// BaileySoft Super Code Search
// Copyright (c) 2008, BSLTD
// nealbailey@hotmail.com - All rights reserved.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace BSCodeGrep
{
    public class IOWorker
    {
        #region Public Enums

        public enum RegExSearchScope
        {
            SINGLE_LINE,
            MULTI_LINE
        }
        #endregion

        #region Public Properties

        /// <summary>
        /// The amount of items searched through
        /// </summary>
        public int SearchedCount
        {
            get
            { return m_SearchedCount; }
        }

        /// <summary>
        /// Returns the results of the search
        /// </summary>
        public List<SearchResult> GetSearchResults
        {
            get
            { return m_results; }
        }

        /// <summary>
        /// User Defined Search Options
        /// </summary>
        public SearchSettings UserSearchOptions
        {
            get { return m_uso; }
            set { m_uso = value; }
        }

        /// <summary>
        /// The Files Index
        /// </summary>
        public List<string> Index
        {
            get { return m_idx; }
            set { m_idx = value; }
        }
        #endregion

        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        public IOWorker(SearchSettings uso, Form1 form)
        {
            m_idx = new List<string>();
            m_results = new List<SearchResult>();
            m_uso = uso;
            m_frm1 = form;
        }
        #endregion
       
        #region Public Methdods

        /// <summary>
        /// Creates the index of the user defined root path
        /// </summary>
        public void CreateIdx()
        {
            foreach (string f in m_uso.SearchFilters)
            {
                m_frm1.LabelPg.Invoke(new UpdateUiCallback(this.UpdateUi),
                   new object[] { String.Format("Generating {0} files index", f) });
                try
                {
                    m_idx.AddRange(Directory.GetFiles(
                        m_uso.SearchPath, "*" + f,
                        SearchOption.AllDirectories));
                }
                catch (UnauthorizedAccessException e)
                {
                    System.Diagnostics.Debug.WriteLine(e);
                }
            }
            //m_idx.Reverse();
            m_SearchedCount = m_idx.Count;
            SearchResults(m_uso.SearchPattern);
        }

        public void ExecuteReplace()
        {
            for (int i = 0; i < m_idx.Count; i++)
            {
                m_frm1.LabelPg.Invoke(new UpdateUiCallback(this.UpdateUi),
                    new object[] { String.Format("Modifying File: {0}", Path.GetFileName(m_idx[i])) });

                Regex rx = GetRegEx();
                File.Copy(m_idx[i], m_idx[i] + ".orig", true);
                List<string> lines = new List<string>();

                switch (m_uso.Scope)
                {
                    case RegExSearchScope.SINGLE_LINE:
                        try
                        {
                            using (StreamReader sr = new StreamReader(m_idx[i]))
                            {
                                string line = string.Empty;
                                while ((line = sr.ReadLine()) != null)
                                {
                                    string nline = rx.Replace(line, m_uso.Replacement);
                                    lines.Add(nline);
                                }
                            }
                        }
                        catch { }
                        break;
                    case RegExSearchScope.MULTI_LINE:
                        try
                        {
                            using (StreamReader sr = new StreamReader(m_idx[i]))
                            {
                                string line = sr.ReadToEnd();
                                string nline = rx.Replace(line, m_uso.Replacement);
                                lines.Add(nline);
                            }
                        }
                        catch { }
                        break;
                    default:
                        break;
                }

                //Write replacement file
                StreamWriter sw = File.CreateText(m_idx[i]);
                foreach (string d in lines)
                {
                    sw.WriteLine(d);
                }
                sw.Close();

                m_frm1.LabelPg.Invoke(new UpdateUiCallback(this.UpdateUi),
                    new object[] { "" });
            }
        }

        public void UndoReplace()
        {
            for (int i = 0; i < m_idx.Count; i++)
            {
                if (File.Exists(m_idx[i] + ".orig"))
                {
                    m_frm1.LabelPg.Invoke(new UpdateUiCallback(this.UpdateUi),
                   new object[] { String.Format("Restoring File: {0}", Path.GetFileName(m_idx[i])) });

                    File.Delete(m_idx[i]);
                    File.Move(m_idx[i] + ".orig", m_idx[i]);
                }

                m_frm1.LabelPg.Invoke(new UpdateUiCallback(this.UpdateUi),
                    new object[] { "" });
            }
        }
        #endregion

        #region Private Methods

        //Asynch UI update - main form
        private void UpdateUi(string text)
        {
            m_frm1.LabelPg.Text = text;
        }

        private void SearchResults(string searchPattern)
        {
            for (int i = 0; i < m_idx.Count; i++)
            {
                m_frm1.LabelPg.Invoke(new UpdateUiCallback(this.UpdateUi),
                    new object[] { String.Format("Searching File: {0}", Path.GetFileName(m_idx[i])) });

                SearchResult sri = new SearchResult();
                Regex rx = GetRegEx();

                if (!m_uso.NamesOnly) //search inside files
                {
                    switch (m_uso.Scope)
                    {
                        case RegExSearchScope.SINGLE_LINE: //search each line on its own
                            {
                                try
                                {
                                    using (StreamReader sr = new StreamReader(m_idx[i]))
                                    {
                                        String line;
                                        int p = 0;

                                        while ((line = sr.ReadLine()) != null)
                                        {
                                            p++;
                                            if (rx.IsMatch(line))
                                            {
                                                sri.FilePath = m_idx[i];
                                                sri.Lines.Add(Convert.ToString(p) + ": " + line.TrimStart());
                                            }
                                        }
                                        if (sri.Lines.Count > 0)
                                            m_results.Add(sri);
                                    }
                                }
                                catch (SystemException e)
                                {
                                    sri.FilePath = m_idx[i];
                                    sri.Error = e;
                                }
                                break;
                            }

                        case RegExSearchScope.MULTI_LINE: //search spans multiple lines
                            {
                                try
                                {
                                    using (StreamReader sr = new StreamReader(m_idx[i]))
                                    {
                                        string line = sr.ReadToEnd();
                                        MatchCollection mc = rx.Matches(line);

                                        for (int f = 0; f < mc.Count; f++)
                                        {
                                            Match m = mc[f];
                                            sri.FilePath = m_idx[i];
                                            sri.Lines.Add(String.Format("Match {0}: {1} ", f + 1, m.Value));
                                        }

                                        if (sri.Lines.Count > 0)
                                        {
                                            m_results.Add(sri);
                                        }
                                    }
                                }
                                catch (SystemException e)
                                {
                                    sri.FilePath = m_idx[i];
                                    sri.Error = e;
                                }
                                break;
                            }
                    }
                }
                else //search file names only
                {
                    if (rx.IsMatch(m_idx[i]))
                    {
                        sri.FilePath = m_idx[i];
                        m_results.Add(sri);
                    }
                }
            }
        }

        private Regex GetRegEx()
        {
            Regex rx = null;

            if (m_uso.CaseInsensative)
                rx = new Regex(m_uso.SearchPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            else
                rx = new Regex(m_uso.SearchPattern, RegexOptions.Singleline);

            return rx;
        }
        #endregion

        #region Private Fields

        private int m_SearchedCount;
        private delegate void UpdateUiCallback(string text);
        private List<string> m_idx;
        private List<SearchResult> m_results;
        private SearchSettings m_uso;
        private Form1 m_frm1;
        #endregion
        
        #region depreciated cli methods
        //public void CreateIdx()
        //{
        //    StreamWriter sw = File.CreateText(m_cmd);
        //    StreamWriter swr = File.CreateText(m_idx);

        //    foreach (string f in m_uso.filters)
        //    {
        //        sw.WriteLine("{0} \"{1}\" >> {2}",
        //                     "dir /B /S",
        //                     m_uso.path + "\\*" + f,
        //                     m_idx);
        //    }
        //    sw.Flush();
        //    sw.Close();
        //    swr.Flush();
        //    swr.Close();

        //    CommandLine cli = new CommandLine(ExecutionType.SHELL_EXECUTE_HIDDEN);
        //    cli.ExecuteCommand(m_cmd, "", null);
        //    PopulateIdx();
        //    SearchResults(m_uso.pattern);
        //}

        //private void PopulateIdx()
        //{
        //    using (StreamReader sr = new StreamReader(m_idx))
        //    {
        //        String line;
        //        while ((line = sr.ReadLine()) != null)
        //        {
        //            p_idx.Add(line);
        //        }
        //    }
        //    m_SearchedCount = p_idx.Count;
        //}

        #endregion

        /// <summary>
        /// User Defined Search Parameters
        /// </summary>
        public struct SearchSettings
        {
            /// <summary>
            /// Starting search path
            /// </summary>
            public string SearchPath;

            /// <summary>
            /// The file extensions to search
            /// </summary>
            public string[] SearchFilters;

            /// <summary>
            /// The pattern to match in the file name or in the file
            /// </summary>
            public string SearchPattern;

            /// <summary>
            /// The string to replace the matched string
            /// </summary>
            public string Replacement;
            /// <summary>
            /// Search file names only {bool)
            /// </summary>
            public bool NamesOnly;

            /// <summary>
            /// Search not based on exact casing
            /// </summary>
            public bool CaseInsensative;

            /// <summary>
            /// Regular Expressions Settings
            /// </summary>
            public RegExSearchScope Scope;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

thund3rstruck
Software Developer
United States United States
I'm a typical 30 year old generation X guy that likes video games, NFL football, and comic style art. I have an insatiable passion for programming and doing what ever it takes to become a better programmer.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 10 Mar 2009
Article Copyright 2008 by thund3rstruck
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid