예제 #1
0
        /// <summary>
        /// Searches the given file for the given search text.
        /// </summary>
        /// <param name="file">FileInfo object</param>
        /// <param name="searchSpec">ISearchSpec interface value</param>
        /// <param name="ex">Exception holder if error occurs</param>
        /// <returns>Hitobject containing grep results, null if on error</returns>
        /// <history>
        /// [Curtis_Beard]      07/28/2006  Created
        /// [Curtis_Beard]      05/25/2007  ADD: support for Exception object
        /// [Curtis_Beard]      03/31/2015	CHG: rework Grep/Matches
        /// </history>
        public MatchResult Grep(FileInfo file, ISearchSpec searchSpec, ref Exception ex)
        {
            // initialize Exception object to null
             ex = null;

             if (IsAvailable && IsUsable)
             {
            try
            {
               if (file.Exists)
               {
                  //const int MARGINSIZE = 4;
                  int count = 0;
                  MatchResult match = null;
                  int prevLine = 0;
                  int prevPage = 0;
                  //string _spacer = new string(' ', MARGINSIZE);
                  //string _contextSpacer = string.Empty;

                  //if (searchSpec.ContextLines > 0)
                  //{
                  //   _contextSpacer = new string(' ', MARGINSIZE);
                  //   _spacer = _contextSpacer.Substring(_contextSpacer.Length - MARGINSIZE - 2) + "> ";
                  //}
                  //else
                  //   _spacer = new string(' ', MARGINSIZE);

                  // Open a given Word document as readonly
                  // Note: Word 2003+ requires write mode since reading mode doesn't allow use of home/end keys to select text)
                  object appversion = __WordApplication.GetType().InvokeMember("Version", BindingFlags.GetProperty, null, __WordApplication, null);
                  double version = 0;
                  double.TryParse(appversion.ToString(), out version);
                  bool useReadOnly = version >= 12.00 ? false : true;
                  object wordDocument = OpenDocument(file.FullName, useReadOnly);

                  // Get Selection Property
                  __WordSelection = __WordApplication.GetType().InvokeMember("Selection", BindingFlags.GetProperty,
                     null, __WordApplication, null);

                  // create range and find objects
                  object range = GetProperty(wordDocument, "Content");
                  object find = GetProperty(range, "Find");

                  // setup find
                  RunRoutine(find, "ClearFormatting", null);
                  SetProperty(find, "Forward", true);
                  SetProperty(find, "Text", searchSpec.SearchText);
                  SetProperty(find, "MatchWholeWord", searchSpec.UseWholeWordMatching);
                  SetProperty(find, "MatchCase", searchSpec.UseCaseSensitivity);

                  // start find
                  FindExecute(find);

                  // keep finding text
                  while ((bool)GetProperty(find, "Found") == true)
                  {
                     count += 1;

                     if (count == 1)
                     {
                        // create hit object
                        match = new MatchResult(file);
                     }

                     // since a hit was found and only displaying file names, quickly exit
                     if (searchSpec.ReturnOnlyFileNames)
                        break;

                     // retrieve find information
                     int start = (int)GetProperty(range, "Start");
                     int colNum = (int)Information(range, WdInformation.wdFirstCharacterColumnNumber);
                     int lineNum = (int)Information(range, WdInformation.wdFirstCharacterLineNumber);
                     int pageNum = (int)Information(range, WdInformation.wdActiveEndPageNumber);
                     string line = GetFindTextLine(start);

                     // don't add a hit if on same line
                     if (!(prevLine == lineNum && prevPage == pageNum))
                     {
                        // check for line numbers
                        //if (searchSpec.IncludeLineNumbers)
                        //{
                        //   // setup line header
                        //   _spacer = "(" + string.Format("{0},{1}", lineNum, pageNum);
                        //   if (_spacer.Length <= 5)
                        //   {
                        //      _spacer = _spacer + new string(' ', 6 - _spacer.Length);
                        //   }
                        //   _spacer = _spacer + ") ";
                        //   //_contextSpacer = "(" + new string(' ', _spacer.Length - 3) + ") ";
                        //}

                        //  remove any odd characters from the text
                        line = RemoveSpecialCharacters(line);

                        // add context lines before
                        // if (__contextLines > 0){
                        //    For i As int = __contextLines To 1 Step -1
                        //       SetProperty(__WordSelection, "Start", start)
                        //       SelectionMoveUp(WdUnits.wdLine, i, WdMovementType.wdMove)
                        //       Dim cxt As string = GetFindTextLine()
                        //       cxt = RemoveSpecialCharacters(cxt)

                        //       if (Not HitExists(cxt, hit)){
                        //          hit.Add(_contextSpacer & cxt & NEW_LINE, lineNum - i, 1)
                        //       End If
                        //    Next
                        // End If

                        // add line
                        MatchResultLine matchLine = new MatchResultLine()
                        {
                           HasMatch = true,
                           ColumnNumber = colNum,
                           LineNumber = lineNum,
                           Line = line
                        };
                        var lineMatches = libAstroGrep.Grep.RetrieveLineMatches(line, searchSpec);
                        match.SetHitCount(lineMatches.Count);
                        matchLine.Matches = lineMatches;
                        match.Matches.Add(matchLine);
                        //match.Add(_spacer, line, lineNum, colNum);

                        // add context lines after
                        // if (__contextLines > 0){
                        //    For i As int = 1 To __contextLines
                        //       SetProperty(__WordSelection, "Start", start)
                        //       SelectionMoveDown(WdUnits.wdLine, i, WdMovementType.wdMove)
                        //       Dim cxt As string = GetFindTextLine()
                        //       cxt = RemoveSpecialCharacters(cxt)

                        //       if (Not HitExists(cxt, hit)){
                        //          hit.Add(_contextSpacer & cxt & NEW_LINE, lineNum + i, 1)
                        //       End If
                        //    Next
                        // End If
                     }
                     //match.SetHitCount();

                     prevLine = lineNum;
                     prevPage = pageNum;

                     // find again
                     FindExecute(find);
                  }

                  ReleaseSelection();
                  CloseDocument(wordDocument);

                  return match;
               }
               else
               {
                  string msg = string.Format("File does not exist: {0}", file.FullName);
                  ex = new Exception(msg);
                  Trace(msg);
               }
            }
            catch (Exception mainEx)
            {
               ex = mainEx;
               Trace(mainEx.ToString());
            }
             }
             else
             {
            ex = new Exception("Plugin not available or usable.");
            Trace("Plugin not available or usable.");
             }

             return null;
        }
예제 #2
0
파일: Grep.cs 프로젝트: joshball/astrogrep
        /// <summary>
        /// Search the given file.
        /// </summary>
        /// <param name="SourceFile">FileInfo object to be searched</param>
        private void SearchFile(FileInfo SourceFile)
        {
            try
             {
            // skip any files that are filtered out
            FilterItem filterItem = null;
            string filterValue = string.Empty;
            if (ShouldFilterOut(SourceFile, FileFilterSpec, out filterItem, out filterValue))
            {
               OnFileFiltered(SourceFile, filterItem, filterValue);
            }
            else if (string.IsNullOrEmpty(SearchSpec.SearchText))
            {
               // return a 'file hit' if the search text is empty
               var match = new MatchResult(SourceFile) { Index = MatchResults.Count };
               var matchLine = new MatchResultLine();
               match.Matches.Add(matchLine);
               MatchResults.Add(match);

               OnFileHit(SourceFile, match.Index);
            }
            else
            {
               SearchFileContents(SourceFile);
            }
             }
             catch (ThreadAbortException)
             {
            UnloadPlugins();
             }
             catch (Exception ex)
             {
            OnSearchError(SourceFile, ex);
             }
        }
예제 #3
0
파일: Grep.cs 프로젝트: joshball/astrogrep
        /// <summary>
        /// Search a given file for the searchText.
        /// </summary>
        /// <param name="file">FileInfo object for file to search for searchText</param>
        /// <history>
        /// [Curtis_Beard]		09/08/2005	Created
        /// [Curtis_Beard]		11/21/2005	ADD: update hit count when actual line added
        /// [Curtis_Beard]		12/02/2005	CHG: use SearchingFile instead of StatusMessage
        /// [Curtis_Beard]		04/21/2006	CHG: use a regular expression match collection to get
        ///											correct count of hits in a line when using RegEx
        /// [Curtis_Beard]		07/03/2006	FIX: 1500174, use a FileStream to open the files readonly
        /// [Curtis_Beard]		07/07/2006	FIX: 1512029, RegEx use Case Sensitivity and WholeWords,
        ///											also use different whole word matching regex
        /// [Curtis_Beard]		07/26/2006	ADD: 1512026, column position
        /// [Curtis_Beard]		07/26/2006	FIX: 1530023, retrieve file with correct encoding
        /// [Curtis_Beard]		09/12/2006	CHG: Converted to C#
        /// [Curtis_Beard]		09/28/2006	FIX: check for any plugins before looping through them
        /// [Curtis_Beard]		05/18/2006	FIX: 1723815, use correct whole word matching regex
        /// [Curtis_Beard]		06/26/2007	FIX: correctly detect plugin extension support
        /// [Curtis_Beard]		06/26/2007	FIX: 1779270, increase array size holding context lines
        /// [Curtis_Beard]		10/09/2012	FIX: don't overwrite position when getting context lines
        /// [Curtis_Beard]		10/12/2012	FIX: get correct position when using whole word option
        /// [Curtis_Beard]		10/12/2012	CHG: 32, implement a hit count filter
        /// [Curtis_Beard]		10/31/2012	CHG: renamed to SearchFileContents, remove parameter searchText
        /// [Curtis_Beard]		08/19/2014	FIX: 57, escape search text when whole word is enabled but not regular expressions
        /// [Curtis_Beard]      10/27/2014	CHG: 85, remove leading white space, remove use of newline so each line is in hit object
        /// [Curtis_Beard]      02/09/2015	CHG: 92, support for specific file encodings
        /// [Curtis_Beard]		03/05/2015	FIX: 64/35, if whole word doesn't pass our check but does pass regex, make it fail.  Code cleanup.
        /// [Curtis_Beard]		04/02/2015	CHG: remove line number logic and always include line number in MatchResultLine.
        /// [Curtis_Beard]		05/18/2015	FIX: 72, don't grab file sample when detect encoding option is turned off.
        /// [Curtis_Beard]		05/18/2015	FIX: 69, use same stream to detect encoding and grep contents
        /// [Curtis_Beard]	   05/26/2015	FIX: 69, add performance setting for file detection
        /// [Curtis_Beard]		06/02/2015	FIX: 75, use sample size from performance setting
        /// [theblackbunny]		06/25/2015	FIX: 39, remove context lines that intersect with each other in different MatchResults
        /// </history>
        private void SearchFileContents(FileInfo file)
        {
            // Raise SearchFile Event
             OnSearchingFile(file);

             FileStream _stream = null;
             StreamReader _reader = null;
             int _lineNumber = 0;
             MatchResult match = null;
             Regex _regularExp;
             MatchCollection _regularExpCol = null;
             bool _hitOccurred = false;
             bool _fileNameDisplayed = false;
             int _maxContextLines = 0;
             var _context = new string[11];
             int _contextIndex = -1;
             int _lastHit = 0;
             int userFilterCount = 0;

             try
             {
            #region Plugin Processing

            if (Plugins != null)
            {
               for (int i = 0; i < Plugins.Count; i++)
               {
                  // find a valid plugin for this file type
                  if (Plugins[i].Enabled && Plugins[i].Plugin.IsAvailable)
                  {
                     // detect if plugin supports extension
                     bool isFound = Plugins[i].Plugin.IsFileSupported(file);

                     // if extension not supported try another plugin
                     if (!isFound)
                        continue;

                     Exception pluginEx = null;

                     // load plugin and perform grep
                     if (Plugins[i].Plugin.Load())
                     {
                        OnSearchingFileByPlugin(Plugins[i].Plugin.Name);
                        match = Plugins[i].Plugin.Grep(file, SearchSpec, ref pluginEx);
                     }
                     else
                     {
                        OnSearchError(file, new Exception(string.Format("Plugin {0} failed to load.", Plugins[i].Plugin.Name)));
                     }

                     Plugins[i].Plugin.Unload();

                     // if the plugin processed successfully
                     if (pluginEx == null)
                     {
                        // check for a hit
                        if (match != null)
                        {
                           match.FromPlugin = true;

                           // only perform is not using negation
                           if (!SearchSpec.UseNegation)
                           {
                              if (DoesPassHitCountCheck(match))
                              {
                                 match.Index = MatchResults.Count;
                                 MatchResults.Add(match);
                                 OnFileHit(file, match.Index);

                                 if (SearchSpec.ReturnOnlyFileNames)
                                    match.SetHitCount();

                                 OnLineHit(match, match.Index);
                              }
                           }
                        }
                        else if (SearchSpec.UseNegation)
                        {
                           // no hit but using negation so create one
                           match = new MatchResult(file) { Index = MatchResults.Count, FromPlugin = true };
                           MatchResults.Add(match);
                           OnFileHit(file, match.Index);
                        }
                     }
                     else
                     {
                        // the plugin had an error
                        OnSearchError(file, pluginEx);
                     }

                     return;
                  }
               }
            }
            #endregion

            // open stream to file to use in encoding detection if enabled and in grep logic
            _stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            #region Encoding Detection

            string usedEncoder = string.Empty;
            System.Text.Encoding encoding = null;

            //
            // User specified file encoding
            //
            FileEncoding fileEncoding = SearchSpec.FileEncodings != null && SearchSpec.FileEncodings.Count > 0 ?
               (from f in SearchSpec.FileEncodings where f.FilePath.Equals(file.FullName, StringComparison.InvariantCultureIgnoreCase) && f.Enabled select f).ToList().FirstOrDefault()
               :  null;
            if (fileEncoding != null)
            {
               usedEncoder = "User";
               encoding = fileEncoding.Encoding;
            }
            else
            {
               //
               // Detect file encoding if enabled
               //
               if (SearchSpec.EncodingDetectionOptions.DetectFileEncoding)
               {
                  // encoding cache check
                  var key = file.FullName;
                  if (SearchSpec.EncodingDetectionOptions.UseEncodingCache &&
                     EncodingCache.Instance.ContainsKey(key))
                  {
                     var value = EncodingCache.Instance.GetItem(key);

                     usedEncoder = value.DetectorName;
                     encoding = System.Text.Encoding.GetEncoding(value.CodePage);
                  }
                  else
                  {
                     byte[] sampleBytes;

                     //Check if can read first
                     try
                     {
                        int sampleSize = EncodingOptions.GetSampleSizeByPerformance(SearchSpec.EncodingDetectionOptions != null ? SearchSpec.EncodingDetectionOptions.PerformanceSetting : EncodingOptions.Performance.Default);
                        sampleBytes = EncodingTools.ReadFileContentSample(_stream, sampleSize);
                     }
                     catch (Exception ex)
                     {
                        // can't read file for sample bytes
                        OnSearchError(file, ex);
                        return;
                     }

                     // detect encoding based on user set performance level that determines what detectors are used
                     encoding = EncodingDetector.Detect(sampleBytes,
                        out usedEncoder,
                        EncodingOptions.GetEncodingDetectorOptionsByPerformance(SearchSpec.EncodingDetectionOptions != null ? SearchSpec.EncodingDetectionOptions.PerformanceSetting : EncodingOptions.Performance.Default),
                        System.Text.Encoding.Default);

                     // add to cache if enabled
                     if (encoding != null && SearchSpec.EncodingDetectionOptions.UseEncodingCache)
                     {
                        var value = new EncodingCacheItem() { CodePage = encoding.CodePage, DetectorName = usedEncoder };
                        EncodingCache.Instance.SetItem(key, value);
                     }
                  }
               }
               else
               {
                  // Use original encoding method before detect encoding option availalbe
                  usedEncoder = "Default";
                  encoding = System.Text.Encoding.Default;
               }
            }

            if (encoding == null)
            {
               // Could not detect file encoding
               OnSearchError(file, new Exception("Could not detect file encoding."));
               return;
            }

            OnFileEncodingDetected(file, encoding, usedEncoder);

            // process all encoding detectors and display results to output window
            //var values = EncodingDetector.DetectAll(sampleBytes);
            //if (values.Count > 0)
            //{
            //   System.Diagnostics.Debug.WriteLine(string.Format("File: {0}", file.FullName));
            //   foreach (var value in values)
            //   {
            //      System.Diagnostics.Debug.WriteLine(string.Format("Encoding: {0} ({1})", value.Encoding != null ? value.Encoding.EncodingName : "None", value.Option.ToString()));
            //   }
            //   System.Diagnostics.Debug.WriteLine(Environment.NewLine);
            //}

            #endregion

            // could have read some data for the encoding check, seek back to start of file
            if (_stream.CanSeek)
            {
               _stream.Seek(0, SeekOrigin.Begin);
            }
            _reader = new StreamReader(_stream, encoding);

            _maxContextLines = SearchSpec.ContextLines + 1;
            do
            {
               string textLine = _reader.ReadLine();

               if (textLine == null)
                  break;
               else
               {
                  _lineNumber += 1;

                  int _posInStr = -1;
                  if (SearchSpec.UseRegularExpressions)
                  {
                     if (textLine.Length > 0)
                     {
                        string pattern = string.Format("{0}{1}{0}", SearchSpec.UseWholeWordMatching ? "\\b" : string.Empty, SearchSpec.SearchText);
                        RegexOptions options = SearchSpec.UseCaseSensitivity ? RegexOptions.None : RegexOptions.IgnoreCase;
                        _regularExp = new Regex(pattern, options);
                        _regularExpCol = _regularExp.Matches(textLine);

                        if (_regularExpCol.Count > 0)
                        {
                           if (SearchSpec.UseNegation)
                           {
                              _hitOccurred = true;
                           }

                           _posInStr = 1;
                        }
                     }
                  }
                  else
                  {
                     // If we are looking for whole worlds only, perform the check.
                     if (SearchSpec.UseWholeWordMatching)
                     {
                        _regularExp = new Regex("\\b" + Regex.Escape(SearchSpec.SearchText) + "\\b", SearchSpec.UseCaseSensitivity ? RegexOptions.None : RegexOptions.IgnoreCase);

                        // if match is found, also check against our internal line hit count method to be sure they are in sync
                        Match mtc = _regularExp.Match(textLine);
                        if (mtc != null && mtc.Success && RetrieveLineMatches(textLine, SearchSpec).Count > 0)
                        {
                           if (SearchSpec.UseNegation)
                           {
                              _hitOccurred = true;
                           }

                           _posInStr = mtc.Index;
                        }
                     }
                     else
                     {
                        _posInStr = textLine.IndexOf(SearchSpec.SearchText, SearchSpec.UseCaseSensitivity ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);

                        if (SearchSpec.UseNegation && _posInStr > -1)
                        {
                           _hitOccurred = true;
                        }
                     }
                  }

                  //*******************************************
                  // We found an occurrence of our search text.
                  //*******************************************
                  if (_posInStr > -1)
                  {
                     //since we have a hit, check to see if negation is checked
                     if (SearchSpec.UseNegation)
                        break;

                     // create new hit and add to collection
                     if (match == null)
                     {
                        match = new MatchResult(file) { Index = MatchResults.Count, DetectedEncoding = encoding };
                        MatchResults.Add(match);
                     }

                     // don't show until passes count check
                     if (!_fileNameDisplayed && DoesPassHitCountCheck(match))
                     {
                        OnFileHit(file, match.Index);

                        _fileNameDisplayed = true;
                     }

                     // If we are only showing filenames, go to the next file.
                     if (SearchSpec.ReturnOnlyFileNames)
                     {
                        if (!_fileNameDisplayed)
                        {
                           OnFileHit(file, match.Index);

                           _fileNameDisplayed = true;
                        }

                        //notify that at least 1 hit is in file
                        match.SetHitCount();
                        OnLineHit(match, match.Index);

                        break;
                     }

                     // Display context lines if applicable.
                     if (SearchSpec.ContextLines > 0 && _lastHit <= 0)
                     {
                        if (match.Matches.Count > 0 && _lastHit < -_maxContextLines)
                        {
                           // Insert a blank space before the context lines.
                           var matchLine = new MatchResultLine() { Line = string.Empty, LineNumber = -1 };
                           match.Matches.Add(matchLine);
                           int _pos = match.Matches.Count - 1;

                           if (DoesPassHitCountCheck(match))
                           {
                              OnLineHit(match, _pos);
                           }
                        }

                        // Display preceding n context lines before the hit.
                        int tempContextLines = SearchSpec.ContextLines;
                        // But only output the context lines which are not part of the previous context
                        if(_lastHit >= -_maxContextLines)
                        {
                           tempContextLines = -_lastHit;
                        }
                        // Roll back the context index to get the first context line that needs to be displayed
                        _contextIndex = _contextIndex - tempContextLines;
                        if(_contextIndex < 0)
                        {
                           _contextIndex += _maxContextLines;
                        }
                        for (int tempPosInStr = tempContextLines; tempPosInStr >= 1; tempPosInStr--)
                        {
                           _contextIndex = _contextIndex + 1;
                           if (_contextIndex >= _maxContextLines)
                              _contextIndex = 0;

                           // If there is a match in the first one or two lines,
                           // the entire preceeding context may not be available.
                           if (_lineNumber > tempPosInStr)
                           {
                              // Add the context line.
                              var matchLine = new MatchResultLine() { Line = _context[_contextIndex], LineNumber = _lineNumber - tempPosInStr };
                              match.Matches.Add(matchLine);
                              int _pos = match.Matches.Count - 1;

                              if (DoesPassHitCountCheck(match))
                              {
                                 OnLineHit(match, _pos);
                              }
                           }
                        }
                     }

                     _lastHit = SearchSpec.ContextLines;

                     //
                     // Add the actual "hit".
                     //
                     var matchLineFound = new MatchResultLine() { Line = textLine, LineNumber = _lineNumber, HasMatch = true };

                     if (SearchSpec.UseRegularExpressions)
                     {
                        _posInStr = _regularExpCol[0].Index;
                        match.SetHitCount(_regularExpCol.Count);

                        foreach (Match regExMatch in _regularExpCol)
                        {
                           matchLineFound.Matches.Add(new MatchResultLineMatch(regExMatch.Index, regExMatch.Length));
                        }
                     }
                     else
                     {
                        var lineMatches = RetrieveLineMatches(textLine, SearchSpec);
                        match.SetHitCount(lineMatches.Count);
                        matchLineFound.Matches = lineMatches;
                     }
                     matchLineFound.ColumnNumber = _posInStr + 1;
                     match.Matches.Add(matchLineFound);
                     int _index = match.Matches.Count - 1;

                     if (DoesPassHitCountCheck(match))
                     {
                        OnLineHit(match, _index);
                     }
                  }
                  else if (SearchSpec.ContextLines > 0)
                  {
                     if(_lastHit > 0)
                     {
                        //***************************************************
                        // We didn't find a hit, but since lastHit is > 0, we
                        // need to display this context line.
                        //***************************************************
                        var matchLine = new MatchResultLine() { Line = textLine, LineNumber = _lineNumber };
                        match.Matches.Add(matchLine);
                        int _index = match.Matches.Count - 1;

                        if (DoesPassHitCountCheck(match))
                        {
                           OnLineHit(match, _index);
                        }
                     }
                     if(_lastHit >= -_maxContextLines)
                     {
                        //*****************************************************
                        // We continue keeping track of the number of potential
                        // context lines since the last displayed context line
                        // until we pass (-_maxContextLines).
                        //*****************************************************
                        _lastHit -= 1;
                     }

                  } // Found a hit or not.

                  // If we are showing context lines, keep the last n+1 lines.
                  if (SearchSpec.ContextLines > 0)
                  {
                     _contextIndex += 1;
                     if (_contextIndex >= _maxContextLines)
                        _contextIndex = 0;

                     _context[_contextIndex] = textLine;
                  }
               }
            }
            while (true);

            // send event file/line hit if we haven't yet but it should be
            if (!_fileNameDisplayed && match != null && DoesPassHitCountCheck(match))
            {
               // need to display it
               OnFileHit(file, match.Index);
               OnLineHit(match, match.Index);
            }

            // send event for file filtered if it fails the file hit count filter
            if (!SearchSpec.UseNegation && !SearchSpec.ReturnOnlyFileNames && match != null && !DoesPassHitCountCheck(match))
            {
               // remove from grep collection only if
               // not negation
               // not filenames only
               // actually have a hit
               // doesn't pass the hit count filter
               MatchResults.RemoveAt(MatchResults.Count - 1);

               string filterValue = match.HitCount.ToString();
               FilterItem filterItem = new FilterItem(new FilterType(FilterType.Categories.File, FilterType.SubCategories.MinimumHitCount), userFilterCount.ToString(), FilterType.ValueOptions.None, false, true);
               OnFileFiltered(file, filterItem, filterValue);
            }

            //
            // Check for no hits through out the file
            //
            if (SearchSpec.UseNegation && _hitOccurred == false)
            {
               //add the file to the hit list
               if (!_fileNameDisplayed)
               {
                  match = new MatchResult(file) { Index = MatchResults.Count, DetectedEncoding = encoding };
                  MatchResults.Add(match);
                  OnFileHit(file, match.Index);
               }
            }
             }
             finally
             {
            if (_reader != null)
               _reader.Close();

            if (_stream != null)
               _stream.Close();
             }
        }
예제 #4
0
파일: Grep.cs 프로젝트: joshball/astrogrep
 /// <summary>
 /// Raise line hit event.
 /// </summary>
 /// <param name="match">MatchResult containing line hit</param>
 /// <param name="index">Index to line</param>
 /// <history>
 /// [Curtis_Beard]      05/25/2007  Created
 /// </history>
 protected virtual void OnLineHit(MatchResult match, int index)
 {
     if (LineHit != null)
      {
     LineHit(match, index);
      }
 }
예제 #5
0
파일: Grep.cs 프로젝트: joshball/astrogrep
        /// <summary>
        /// Determines if current match count passes the file hit count filter.
        /// </summary>
        /// <param name="hit">Current MatchResult</param>
        /// <returns>true if match count valid, false if not</returns>
        /// <history>
        /// [Curtis_Beard]      10/12/2012  Created: 32, implement file hit count
        /// </history>
        private bool DoesPassHitCountCheck(MatchResult match)
        {
            if (userFilterCount <= 0)
            return true;

             if (userFilterCount > 0 && (match != null && match.HitCount >= userFilterCount))
            return true;

             return false;
        }
예제 #6
0
 /// <summary>
 /// A line has been detected to contain the searching text
 /// </summary>
 /// <param name="match">The MatchResult that contains the line</param>
 /// <param name="index">The position in the HitObject's line collection</param>
 /// <history>
 /// [Curtis_Beard]		11/04/2005   Created
 /// </history>
 private void ReceiveLineHit(MatchResult match, int index)
 {
     UpdateHitCount(match);
      CalculateTotalCount();
 }
예제 #7
0
        /// <summary>
        /// Updates the count column (Thread safe)
        /// </summary>
        /// <param name="match">MatchResult that contains updated information</param>
        /// <history>
        /// [Curtis_Beard]		11/21/2005  Created
        /// </history>
        private void UpdateHitCount(MatchResult match)
        {
            // Makes this a thread safe operation
             if (lstFileNames.InvokeRequired)
             {
            UpdateHitCountCallBack del = new UpdateHitCountCallBack(UpdateHitCount);
            lstFileNames.Invoke(del, new object[1] { match });
            return;
             }

             // find correct item to update
             foreach (ListViewItem item in lstFileNames.Items)
             {
            if (int.Parse(item.SubItems[Constants.COLUMN_INDEX_GREP_INDEX].Text) == match.Index)
            {
               item.SubItems[Constants.COLUMN_INDEX_COUNT].Text = match.HitCount.ToString();
               break;
            }
             }
        }
예제 #8
0
        /// <summary>
        /// Highlight the searched text in the results
        /// </summary>
        /// <param name="match">MatchResult containing results</param>
        /// <history>
        /// [Curtis_Beard]	   01/27/2005	Created
        /// [Curtis_Beard]	   04/12/2005	FIX: 1180741, Don't capitalize hit line
        /// [Curtis_Beard]	   11/18/2005	ADD: custom highlight colors
        /// [Curtis_Beard] 	   12/06/2005	CHG: call WholeWordOnly from Grep class
        /// [Curtis_Beard] 	   04/21/2006	CHG: highlight regular expression searches
        /// [Curtis_Beard] 	   09/28/2006	FIX: use grep object for settings instead of gui items
        /// [Ed_Jakubowski]	   05/20/2009   CHG: Skip highlight if hitCount = 0
        /// [Curtis_Beard]	   01/24/2012	CHG: allow back color use again since using .Net v2+
        /// [Curtis_Beard]      10/27/2014	CHG: 85, remove leading white space, add newline for display, fix windows sounds for empty text
        /// [Curtis_Beard]      11/26/2014	FIX: don't highlight found text that is part of the spacer text
        /// [Curtis_Beard]      02/24/2015	CHG: remove hit line restriction until proper fix for long loading
        /// [Curtis_Beard]      03/04/2015	CHG: move standard code to function to cleanup this function.
        /// [Curtis_Beard]      03/05/2015	FIX: 64/35, clear text field before anything to not have left over content.
        /// [Curtis_Beard]		04/08/2015  CHG: 61, change from RichTextBox to AvalonEdit
        /// [Curtis_Beard]		07/06/2015  FIX: 78, display empty preview area when result is null or no matches
        /// </history>
        private void ProcessMatchForDisplay(MatchResult match)
        {
            if (match == null || match.Matches.Count == 0)
             {
            txtHits.Clear();
            txtHits.SyntaxHighlighting = null;
            txtHits.LineNumbers = null;
            return;
             }

             txtHits.Clear();
             txtHits.SyntaxHighlighting = null;
             txtHits.ScrollToHome();

             for (int i = txtHits.TextArea.TextView.LineTransformers.Count - 1; i >= 0; i--)
             {
            if (txtHits.TextArea.TextView.LineTransformers[i] is ResultHighlighter)
               txtHits.TextArea.TextView.LineTransformers.RemoveAt(i);
            else if (txtHits.TextArea.TextView.LineTransformers[i] is AllResultHighlighter)
               txtHits.TextArea.TextView.LineTransformers.RemoveAt(i);
             }
             var foreground = Convertors.ConvertStringToSolidColorBrush(Core.GeneralSettings.HighlightForeColor);
             var background = Convertors.ConvertStringToSolidColorBrush(Core.GeneralSettings.HighlightBackColor);
             var nonForeground = Convertors.ConvertStringToSolidColorBrush(Core.GeneralSettings.ResultsContextForeColor);
             txtHits.TextArea.TextView.LineTransformers.Add(new ResultHighlighter(match, RemoveWhiteSpaceMenuItem.Checked)
             {
            MatchForeground = foreground,
            MatchBackground = background,
            NonMatchForeground = nonForeground
             });

             StringBuilder builder = new StringBuilder();
             var lineNumbers = new List<LineNumber>();
             var path = match.File.FullName;
             int max = match.Matches.Count;
             for (int i = 0; i < max; i++)
             {
            string line = match.Matches[i].Line;
            if (RemoveWhiteSpaceMenuItem.Checked)
            {
               line = line.TrimStart();
            }
            builder.AppendLine(line);
            lineNumbers.Add(new LineNumber()
            {
               Number = match.Matches[i].LineNumber,
               HasMatch = match.Matches[i].HasMatch,
               FileFullName = match.Matches[i].LineNumber > -1 || match.FromPlugin ? path : string.Empty,
               ColumnNumber = match.Matches[i].ColumnNumber
            });
             }

             // the last result will have a hanging newline, so remove it.
             if (builder.Length > 0)
             {
            builder.Remove(builder.Length - Environment.NewLine.Length, Environment.NewLine.Length);
             }

             txtHits.LineNumbers = lineNumbers;
             txtHits.Text = builder.ToString();
        }
예제 #9
0
        /// <summary>
        /// Displays the entire selected file and uses a syntax highlighter when available for that file extension.
        /// </summary>
        /// <param name="match">Currently selected MatchResult</param>
        /// <history>
        /// [Curtis_Beard]		04/08/2015  CHG: 20/21, display entire file and use syntax highlighter
        /// [Curtis_Beard]		05/18/2015  FIX: 71, use language text for message.
        /// </history>
        private void ProcessFileForDisplay(MatchResult match)
        {
            if (match == null || match.Matches.Count == 0)
             {
            txtHits.Clear();
            txtHits.LineNumbers = null;
            return;
             }

             if ((match.File.Length > 1024000 || FilterItem.IsBinaryFile(match.File)) &&
            MessageBox.Show(this, Language.GetGenericText("ResultsPreviewLargeBinaryFile"), ProductInformation.ApplicationName, MessageBoxButtons.YesNo,
            MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.No)
             {
            ProcessMatchForDisplay(match); // display just the results then and not the whole file.
            return;
             }

             txtHits.Clear();
             txtHits.LineNumbers = null;
             txtHits.ScrollToHome();

             var def = ICSharpCode.AvalonEdit.Highlighting.HighlightingManager.Instance.GetDefinitionByExtension(match.File.Extension);
             txtHits.SyntaxHighlighting = def;

             for (int i = txtHits.TextArea.TextView.LineTransformers.Count - 1; i >= 0; i--)
             {
            if (txtHits.TextArea.TextView.LineTransformers[i] is ResultHighlighter)
               txtHits.TextArea.TextView.LineTransformers.RemoveAt(i);
            else if (txtHits.TextArea.TextView.LineTransformers[i] is AllResultHighlighter)
               txtHits.TextArea.TextView.LineTransformers.RemoveAt(i);
             }
             var foreground = Convertors.ConvertStringToSolidColorBrush(Core.GeneralSettings.HighlightForeColor);
             var background = Convertors.ConvertStringToSolidColorBrush(Core.GeneralSettings.HighlightBackColor);
             var nonForeground = Convertors.ConvertStringToSolidColorBrush(Core.GeneralSettings.ResultsContextForeColor);
             txtHits.TextArea.TextView.LineTransformers.Add(new ResultHighlighter(match, false, true)
             {
            MatchForeground = foreground,
            MatchBackground = background,
            NonMatchForeground = nonForeground
             });

             // convert MatchResultLine to LineNumber
             List<LineNumber> lineNumbers = new List<LineNumber>();
             foreach (MatchResultLine matchLine in match.Matches)
             {
            lineNumbers.Add(new LineNumber()
            {
               ColumnNumber = matchLine.ColumnNumber,
               Number = matchLine.LineNumber,
               HasMatch = matchLine.HasMatch,
               FileFullName = match.File.FullName
            });
             }

             txtHits.LineNumbers = lineNumbers;
             txtHits.Encoding = match.DetectedEncoding;
             txtHits.Load(match.File.FullName);
        }
예제 #10
0
 /// <summary>
 /// Creates an instance of this class.
 /// </summary>
 /// <param name="match">The current MatchResult</param>
 /// <param name="removeWhiteSpace">Determines if leading white space was removed</param>
 /// <param name="showingFullFile">Determines if showing full file contents or just matches</param>
 /// <history>
 /// [Curtis_Beard]	   04/08/2015	ADD: switch from Rich Text Box to AvalonEdit
 /// </history>
 public ResultHighlighter(MatchResult match, bool removeWhiteSpace, bool showingFullFile)
     : this(match, removeWhiteSpace)
 {
     this.showingFullFile = showingFullFile;
 }
예제 #11
0
 /// <summary>
 /// Creates an instance of this class.
 /// </summary>
 /// <param name="match">The current MatchResult</param>
 /// <param name="removeWhiteSpace">Determines if leading white space was removed</param>
 /// <history>
 /// [Curtis_Beard]	   04/08/2015	ADD: switch from Rich Text Box to AvalonEdit
 /// </history>
 public ResultHighlighter(MatchResult match, bool removeWhiteSpace)
 {
     this.match = match;
      this.removeWhiteSpace = removeWhiteSpace;
 }
예제 #12
0
        /// <summary>
        /// Searches the given file for the given search text.
        /// </summary>
        /// <param name="file">FileInfo object</param>
        /// <param name="searchSpec">ISearchSpec interface value</param>
        /// <param name="ex">Exception holder if error occurs</param>
        /// <returns>Hitobject containing grep results, null if on error</returns>
        /// <history>
        /// [Curtis_Beard]      10/17/2012  Created
        /// [Curtis_Beard]      03/31/2015	CHG: rework Grep/Matches
        /// </history>
        public MatchResult Grep(FileInfo file, ISearchSpec searchSpec, ref Exception ex)
        {
            // initialize Exception object to null
             ex = null;
             MatchResult match = null;

             if (Parser.IsParseable(file.FullName))
             {
            string fileContent = Parser.Parse(file.FullName);

            if (!string.IsNullOrEmpty(fileContent))
            {
               string[] lines = fileContent.Split(new char[] { '\n', '\r' });
               for (int i = 0; i < lines.Length; i++)
               {
                  string line = lines[i];

                  int posInStr = -1;
                  Regex reg = null;
                  MatchCollection regCol = null;

                  if (searchSpec.UseRegularExpressions)
                  {
                     string pattern = string.Format("{0}{1}{0}", searchSpec.UseWholeWordMatching ? "\\b" : string.Empty, searchSpec.SearchText);
                     RegexOptions options = searchSpec.UseCaseSensitivity ? RegexOptions.None : RegexOptions.IgnoreCase;
                     reg = new Regex(pattern, options);
                     regCol = reg.Matches(line);

                     if (regCol.Count > 0)
                     {
                        posInStr = 1;
                     }
                  }
                  else
                  {
                     // If we are looking for whole worlds only, perform the check.
                     if (searchSpec.UseWholeWordMatching)
                     {
                        reg = new Regex("\\b" + Regex.Escape(searchSpec.SearchText) + "\\b", searchSpec.UseCaseSensitivity ? RegexOptions.None : RegexOptions.IgnoreCase);

                        // if match is found, also check against our internal line hit count method to be sure they are in sync
                        Match mtc = reg.Match(line);
                        if (mtc != null && mtc.Success && libAstroGrep.Grep.RetrieveLineMatches(line, searchSpec).Count > 0)
                        {
                           posInStr = mtc.Index;
                        }
                     }
                     else
                     {
                        posInStr = line.IndexOf(searchSpec.SearchText, searchSpec.UseCaseSensitivity ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
                     }
                  }

                  if (posInStr > -1)
                  {
                     if (match == null)
                     {
                        match = new MatchResult(file);

                        // found hit in file so just return
                        if (searchSpec.ReturnOnlyFileNames)
                        {
                           break;
                        }
                     }

                     var matchLineFound = new MatchResultLine() { Line = line, LineNumber = -1, HasMatch = true };

                     if (searchSpec.UseRegularExpressions)
                     {
                        posInStr = regCol[0].Index;
                        match.SetHitCount(regCol.Count);

                        foreach (Match regExMatch in regCol)
                        {
                           matchLineFound.Matches.Add(new MatchResultLineMatch(regExMatch.Index, regExMatch.Length));
                        }
                     }
                     else
                     {
                        var lineMatches = libAstroGrep.Grep.RetrieveLineMatches(line, searchSpec);
                        match.SetHitCount(lineMatches.Count);
                        matchLineFound.Matches = lineMatches;
                     }
                     matchLineFound.ColumnNumber = 1;
                     match.Matches.Add(matchLineFound);
                  }
               }
            }
             }

             return match;
        }