Browse Source

create new search using Rx

pull/23/head
Siegfried Pammer 14 years ago
parent
commit
e0f184d63e
  1. 72
      src/AddIns/Misc/SearchAndReplace/Project/Commands/SearchMainMenuCommands.cs
  2. 124
      src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/AllOpenDocumentIterator.cs
  3. 63
      src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/CurrentDocumentIterator.cs
  4. 100
      src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/DirectoryDocumentIterator.cs
  5. 91
      src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/IDocumentIterator.cs
  6. 99
      src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/WholeProjectDocumentIterator.cs
  7. 101
      src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/WholeSolutionDocumentIterator.cs
  8. 13
      src/AddIns/Misc/SearchAndReplace/Project/Engine/Enums.cs
  9. 159
      src/AddIns/Misc/SearchAndReplace/Project/Engine/Search.cs
  10. 132
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchManager.cs
  11. 89
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchReplaceInFilesManager.cs
  12. 393
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchReplaceManager.cs
  13. 112
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchReplaceUtilities.cs
  14. 128
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/BoyerMooreSearchStrategy.cs
  15. 91
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/BruteForceSearchStrategy.cs
  16. 35
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/ISearchStrategy.cs
  17. 78
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/KMPSearchStrategy.cs
  18. 103
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/RegExSearchStrategy.cs
  19. 190
      src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/WildcardSearchStrategy.cs
  20. 163
      src/AddIns/Misc/SearchAndReplace/Project/Engine/TextIterator/ForwardTextIterator.cs
  21. 18
      src/AddIns/Misc/SearchAndReplace/Project/Engine/TextIterator/ForwardTextIteratorBuilder.cs
  22. 69
      src/AddIns/Misc/SearchAndReplace/Project/Engine/TextIterator/ITextIterator.cs
  23. 45
      src/AddIns/Misc/SearchAndReplace/Project/Engine/TextSelection.cs
  24. 66
      src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs
  25. 133
      src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplacePanel.cs
  26. 26
      src/AddIns/Misc/SearchAndReplace/Project/SearchAndReplace.csproj
  27. 17
      src/AddIns/Misc/SearchAndReplace/Project/SearchOptions.cs
  28. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs
  29. 5
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/RegexSearchStrategy.cs
  30. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs
  31. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchStrategyFactory.cs
  32. 2
      src/Main/Base/Project/Src/Editor/Search/ISearchResultFactory.cs
  33. 20
      src/Main/Base/Project/Src/Editor/Search/SearchResultsPad.cs
  34. 39
      src/Main/Base/Project/Src/Services/MimeTypeDetection.cs

72
src/AddIns/Misc/SearchAndReplace/Project/Commands/SearchMainMenuCommands.cs

@ -12,13 +12,13 @@ namespace SearchAndReplace @@ -12,13 +12,13 @@ namespace SearchAndReplace
public static void SetSearchPattern()
{
// Get Highlighted value and set it to FindDialog.searchPattern
ITextEditor textArea = SearchReplaceUtilities.GetActiveTextEditor();
if (textArea != null) {
string selectedText = textArea.SelectedText;
if (selectedText != null && selectedText.Length > 0 && !IsMultipleLines(selectedText)) {
SearchOptions.CurrentFindPattern = selectedText;
}
}
// ITextEditor textArea = SearchReplaceUtilities.GetActiveTextEditor();
// if (textArea != null) {
// string selectedText = textArea.SelectedText;
// if (selectedText != null && selectedText.Length > 0 && !IsMultipleLines(selectedText)) {
// SearchOptions.CurrentFindPattern = selectedText;
// }
// }
}
public override void Run()
@ -38,7 +38,7 @@ namespace SearchAndReplace @@ -38,7 +38,7 @@ namespace SearchAndReplace
public override void Run()
{
if (SearchOptions.CurrentFindPattern.Length > 0) {
SearchReplaceManager.FindNext(null);
// SearchReplaceManager.FindNext(null);
} else {
Find find = new Find();
find.Run();
@ -65,34 +65,34 @@ namespace SearchAndReplace @@ -65,34 +65,34 @@ namespace SearchAndReplace
{
public override void Run()
{
ITextEditor textArea = SearchReplaceUtilities.GetActiveTextEditor();
if (textArea == null) {
return;
}
// Determine what text we should search for.
string textToFind;
string selectedText = textArea.SelectedText;
if (selectedText.Length > 0) {
if (Find.IsMultipleLines(selectedText)) {
// Locate the nearest word at the selection start.
textToFind = textArea.Document.GetWordAt(textArea.SelectionStart);
} else {
// Search for selected text.
textToFind = selectedText;
}
} else {
textToFind = textArea.Document.GetWordAt(textArea.Caret.Offset);
}
if (textToFind != null && textToFind.Length > 0) {
SearchOptions.CurrentFindPattern = textToFind;
if (SearchOptions.DocumentIteratorType == DocumentIteratorType.CurrentSelection) {
SearchOptions.DocumentIteratorType = DocumentIteratorType.CurrentDocument;
}
SearchReplaceManager.FindNext(null);
}
// ITextEditor textArea = SearchReplaceUtilities.GetActiveTextEditor();
// if (textArea == null) {
// return;
// }
//
// // Determine what text we should search for.
// string textToFind;
//
// string selectedText = textArea.SelectedText;
// if (selectedText.Length > 0) {
// if (Find.IsMultipleLines(selectedText)) {
// // Locate the nearest word at the selection start.
// textToFind = textArea.Document.GetWordAt(textArea.SelectionStart);
// } else {
// // Search for selected text.
// textToFind = selectedText;
// }
// } else {
// textToFind = textArea.Document.GetWordAt(textArea.Caret.Offset);
// }
//
// if (textToFind != null && textToFind.Length > 0) {
// SearchOptions.CurrentFindPattern = textToFind;
// if (SearchOptions.DocumentIteratorType == SearchMode.CurrentSelection) {
// SearchOptions.DocumentIteratorType = SearchMode.CurrentDocument;
// }
// SearchReplaceManager.FindNext(null);
// }
}
}

124
src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/AllOpenDocumentIterator.cs

@ -1,124 +0,0 @@ @@ -1,124 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor;
using System;
using System.Linq;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Refactoring;
namespace SearchAndReplace
{
public class AllOpenDocumentIterator : IDocumentIterator
{
int startIndex = -1;
int curIndex = -1;
bool resetted = true;
public AllOpenDocumentIterator()
{
Reset();
}
public string CurrentFileName {
get {
IViewContent viewContent = GetCurrentTextEditorViewContent();
if (viewContent != null) {
return viewContent.PrimaryFileName;
}
return null;
}
}
IViewContent GetCurrentTextEditorViewContent()
{
GetCurIndex();
if (curIndex >= 0) {
IViewContent viewContent = WorkbenchSingleton.Workbench.ViewContentCollection.ToList()[curIndex];
if (viewContent is ITextEditorProvider) {
return viewContent;
}
}
return null;
}
public ProvidedDocumentInformation Current {
get {
IViewContent viewContent = GetCurrentTextEditorViewContent();
if (viewContent != null) {
ITextEditor textEditor = (((ITextEditorProvider)viewContent).TextEditor);
return new ProvidedDocumentInformation(textEditor.Document,
CurrentFileName,
textEditor);
}
return null;
}
}
void GetCurIndex()
{
IViewContent[] viewContentCollection = WorkbenchSingleton.Workbench.ViewContentCollection.ToArray();
int viewCount = WorkbenchSingleton.Workbench.ViewContentCollection.Count;
if (curIndex == -1 || curIndex >= viewCount) {
for (int i = 0; i < viewCount; ++i) {
if (WorkbenchSingleton.Workbench.ActiveViewContent == viewContentCollection[i]) {
curIndex = i;
return;
}
}
curIndex = -1;
}
}
public bool MoveForward()
{
GetCurIndex();
if (curIndex < 0) {
return false;
}
if (resetted) {
resetted = false;
return true;
}
curIndex = (curIndex + 1) % WorkbenchSingleton.Workbench.ViewContentCollection.Count;
if (curIndex == startIndex) {
return false;
}
return true;
}
public bool MoveBackward()
{
GetCurIndex();
if (curIndex < 0) {
return false;
}
if (resetted) {
resetted = false;
return true;
}
if (curIndex == 0) {
curIndex = WorkbenchSingleton.Workbench.ViewContentCollection.Count - 1;
}
if (curIndex > 0) {
--curIndex;
return true;
}
return false;
}
public void Reset()
{
curIndex = -1;
GetCurIndex();
startIndex = curIndex;
resetted = true;
}
}
}

63
src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/CurrentDocumentIterator.cs

@ -1,63 +0,0 @@ @@ -1,63 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor;
using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
namespace SearchAndReplace
{
public class CurrentDocumentIterator : IDocumentIterator
{
bool didRead = false;
public CurrentDocumentIterator()
{
Reset();
}
public string CurrentFileName {
get {
if (!SearchReplaceUtilities.IsTextAreaSelected) {
return null;
}
return WorkbenchSingleton.Workbench.ActiveViewContent.PrimaryFileName;
}
}
public ProvidedDocumentInformation Current {
get {
ITextEditor textEditor = SearchReplaceUtilities.GetActiveTextEditor();
if (textEditor != null)
return new ProvidedDocumentInformation(textEditor.Document, CurrentFileName, textEditor);
else
return null;
}
}
public bool MoveForward()
{
if (!SearchReplaceUtilities.IsTextAreaSelected) {
return false;
}
if (didRead) {
return false;
}
didRead = true;
return true;
}
public bool MoveBackward()
{
return MoveForward();
}
public void Reset()
{
didRead = false;
}
}
}

100
src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/DirectoryDocumentIterator.cs

@ -1,100 +0,0 @@ @@ -1,100 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop;
using System;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Refactoring;
namespace SearchAndReplace
{
public class DirectoryDocumentIterator : IDocumentIterator
{
string searchDirectory;
string fileMask;
bool searchSubdirectories;
List<string> files = null;
int curIndex = -1;
public DirectoryDocumentIterator(string searchDirectory, string fileMask, bool searchSubdirectories)
{
this.searchDirectory = searchDirectory;
this.fileMask = fileMask;
this.searchSubdirectories = searchSubdirectories;
Reset();
}
public string CurrentFileName {
get {
if (curIndex < 0 || curIndex >= files.Count) {
return null;
}
return files[curIndex].ToString();;
}
}
public ProvidedDocumentInformation Current {
get {
if (curIndex < 0 || curIndex >= files.Count) {
return null;
}
string fileName = files[curIndex].ToString();
if (!File.Exists(fileName) || !SearchReplaceUtilities.IsSearchable(fileName)) {
++curIndex;
return Current;
}
IDocument document;
foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) {
if (content.PrimaryFileName != null &&
FileUtility.IsEqualFileName(content.PrimaryFileName, fileName) &&
content is ITextEditorProvider) {
document = ((ITextEditorProvider)content).TextEditor.Document;
return new ProvidedDocumentInformation(document,
fileName,
0);
}
}
ITextBuffer fileContent;
try {
fileContent = ParserService.GetParseableFileContent(fileName);
} catch (Exception) {
return null;
}
return new ProvidedDocumentInformation(fileContent,
fileName,
0);
}
}
public bool MoveForward()
{
if (curIndex == -1) {
files = FileUtility.SearchDirectory(this.searchDirectory, this.fileMask, this.searchSubdirectories);
}
return ++curIndex < files.Count;
}
public bool MoveBackward()
{
if (curIndex == -1) {
curIndex = files.Count - 1;
return true;
}
return --curIndex >= -1;
}
public void Reset()
{
curIndex = -1;
}
}
}

91
src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/IDocumentIterator.cs

@ -1,91 +0,0 @@ @@ -1,91 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
namespace SearchAndReplace
{
public enum DocumentIteratorType {
CurrentDocument,
CurrentSelection,
AllOpenFiles,
WholeProject,
WholeSolution,
Directory // only used for search in files
}
/// <summary>
/// Represents a bi-directional iterator which could move froward/backward
/// in a document queue. Note that after move forward is called
/// move backward needn't to function correctly either move forward or move
/// backward is called but they're not mixed. After a reset the move operation
/// can be switched.
/// </summary>
public interface IDocumentIterator
{
/// <value>
/// Returns the current ProvidedDocumentInformation. This method
/// usually creates a new ProvidedDocumentInformation object which can
/// be time consuming
/// </value>
ProvidedDocumentInformation Current {
get;
}
/// <value>
/// Returns the file name of the current provided document information. This
/// property usually is not time consuming
/// </value>
string CurrentFileName {
get;
}
/// <remarks>
/// Moves the iterator one document forward.
/// </remarks>
bool MoveForward();
/// <remarks>
/// Moves the iterator one document backward.
/// </remarks>
bool MoveBackward();
/// <remarks>
/// Resets the iterator to the start position.
/// </remarks>
void Reset();
}
/// <summary>
/// A document iterator which never returns any results.
/// </summary>
public sealed class DummyDocumentIterator : IDocumentIterator
{
public ProvidedDocumentInformation Current {
get {
return null;
}
}
public string CurrentFileName {
get {
return null;
}
}
public bool MoveForward()
{
return false;
}
public bool MoveBackward()
{
return false;
}
public void Reset()
{
}
}
}

99
src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/WholeProjectDocumentIterator.cs

@ -1,99 +0,0 @@ @@ -1,99 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop;
using System;
using System.Collections;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Refactoring;
namespace SearchAndReplace
{
public class WholeProjectDocumentIterator : IDocumentIterator
{
ArrayList files = new ArrayList();
int curIndex = -1;
public WholeProjectDocumentIterator()
{
Reset();
}
public string CurrentFileName {
get {
if (curIndex < 0 || curIndex >= files.Count) {
return null;
}
return files[curIndex].ToString();;
}
}
public ProvidedDocumentInformation Current {
get {
if (curIndex < 0 || curIndex >= files.Count) {
return null;
}
if (!File.Exists(files[curIndex].ToString())) {
++curIndex;
return Current;
}
IDocument document;
string fileName = files[curIndex].ToString();
foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) {
if (content.PrimaryFileName != null &&
FileUtility.IsEqualFileName(content.PrimaryFileName, fileName) &&
content is ITextEditorProvider)
{
document = (((ITextEditorProvider)content).TextEditor).Document;
return new ProvidedDocumentInformation(document,
fileName,
0);
}
}
ITextBuffer fileContent;
try {
fileContent = ParserService.GetParseableFileContent(fileName);
} catch (Exception) {
return null;
}
return new ProvidedDocumentInformation(fileContent,
fileName,
0);
}
}
public bool MoveForward()
{
return ++curIndex < files.Count;
}
public bool MoveBackward()
{
if (curIndex == -1) {
curIndex = files.Count - 1;
return true;
}
return --curIndex >= -1;
}
public void Reset()
{
files.Clear();
if (ProjectService.CurrentProject != null) {
foreach (ProjectItem item in ProjectService.CurrentProject.Items) {
if (item is FileProjectItem && SearchReplaceUtilities.IsSearchable(item.FileName)) {
files.Add(item.FileName);
}
}
}
curIndex = -1;
}
}
}

101
src/AddIns/Misc/SearchAndReplace/Project/Engine/DocumentIterator/WholeSolutionDocumentIterator.cs

@ -1,101 +0,0 @@ @@ -1,101 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop;
using System;
using System.Collections;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Refactoring;
namespace SearchAndReplace
{
public class WholeSolutionDocumentIterator : IDocumentIterator
{
ArrayList files = new ArrayList();
int curIndex = -1;
public WholeSolutionDocumentIterator()
{
Reset();
}
public string CurrentFileName {
get {
if (curIndex < 0 || curIndex >= files.Count) {
return null;
}
return files[curIndex].ToString();;
}
}
public ProvidedDocumentInformation Current {
get {
if (curIndex < 0 || curIndex >= files.Count) {
return null;
}
if (!File.Exists(files[curIndex].ToString())) {
++curIndex;
return Current;
}
IDocument document;
string fileName = files[curIndex].ToString();
foreach (IViewContent content in WorkbenchSingleton.Workbench.ViewContentCollection) {
if (content.PrimaryFileName != null &&
FileUtility.IsEqualFileName(content.PrimaryFileName, fileName) &&
content is ITextEditorProvider)
{
document = (((ITextEditorProvider)content).TextEditor).Document;
return new ProvidedDocumentInformation(document,
fileName,
0);
}
}
ITextBuffer fileContent;
try {
fileContent = ParserService.GetParseableFileContent(fileName);
} catch (Exception) {
return null;
}
return new ProvidedDocumentInformation(fileContent,
fileName,
0);
}
}
public bool MoveForward()
{
return ++curIndex < files.Count;
}
public bool MoveBackward()
{
if (curIndex == -1) {
curIndex = files.Count - 1;
return true;
}
return --curIndex >= -1;
}
public void Reset()
{
files.Clear();
if (ProjectService.OpenSolution != null) {
foreach (IProject project in ProjectService.OpenSolution.Projects) {
foreach (ProjectItem item in project.Items) {
if (item is FileProjectItem && SearchReplaceUtilities.IsSearchable(item.FileName)) {
files.Add(item.FileName);
}
}
}
}
curIndex = -1;
}
}
}

13
src/AddIns/Misc/SearchAndReplace/Project/Engine/ITextIteratorBuilder.cs → src/AddIns/Misc/SearchAndReplace/Project/Engine/Enums.cs

@ -1,16 +1,17 @@ @@ -1,16 +1,17 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
namespace SearchAndReplace
{
/// <summary>
/// Builds a text iterator object.
/// </summary>
public interface ITextIteratorBuilder
public enum SearchTarget
{
ITextIterator BuildTextIterator(ProvidedDocumentInformation info);
CurrentDocument,
CurrentSelection,
AllOpenFiles,
WholeProject,
WholeSolution,
Directory
}
}

159
src/AddIns/Misc/SearchAndReplace/Project/Engine/Search.cs

@ -1,159 +0,0 @@ @@ -1,159 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using System.Diagnostics;
using ICSharpCode.SharpDevelop.Gui;
namespace SearchAndReplace
{
public class Search
{
ISearchStrategy searchStrategy = null;
IDocumentIterator documentIterator = null;
ITextIterator textIterator = null;
ITextIteratorBuilder textIteratorBuilder = null;
ProvidedDocumentInformation info = null;
public ProvidedDocumentInformation CurrentDocumentInformation {
get {
return info;
}
}
public ITextIteratorBuilder TextIteratorBuilder {
get {
return textIteratorBuilder;
}
set {
textIteratorBuilder = value;
}
}
public ITextIterator TextIterator {
get {
return textIterator;
}
}
public ISearchStrategy SearchStrategy {
get {
return searchStrategy;
}
set {
searchStrategy = value;
}
}
public IDocumentIterator DocumentIterator {
get {
return documentIterator;
}
set {
documentIterator = value;
}
}
SearchResultMatch CreateNamedSearchResult(SearchResultMatch pos)
{
if (info == null || pos == null) {
return null;
}
pos.ProvidedDocumentInformation = info;
return pos;
}
public void Reset()
{
documentIterator.Reset();
textIterator = null;
}
public void Replace(int offset, int length, string pattern)
{
if (CurrentDocumentInformation != null && TextIterator != null) {
CurrentDocumentInformation.Replace(offset, length, pattern);
TextIterator.InformReplace(offset, length, pattern.Length);
}
}
public SearchResultMatch FindNext(IProgressMonitor monitor)
{
// insanity check
Debug.Assert(searchStrategy != null);
Debug.Assert(documentIterator != null);
Debug.Assert(textIteratorBuilder != null);
if (monitor != null && monitor.CancellationToken.IsCancellationRequested)
return null;
if (info != null && textIterator != null && documentIterator.CurrentFileName != null) {
ProvidedDocumentInformation currentInfo = documentIterator.Current;
if (currentInfo != null) {
if (!info.Equals(currentInfo)) { // create new iterator, if document changed
info = currentInfo;
textIterator = textIteratorBuilder.BuildTextIterator(info);
} else { // old document -> initialize iterator position to caret pos
textIterator.Position = info.CurrentOffset;
}
SearchResultMatch result = CreateNamedSearchResult(searchStrategy.FindNext(textIterator));
if (result != null) {
info.CurrentOffset = textIterator.Position;
return result;
}
}
}
// not found or first start -> move forward to the next document
if (documentIterator.MoveForward()) {
info = documentIterator.Current;
// document is valid for searching -> set iterator & fileName
if (info != null && info.EndOffset >= 0 && info.EndOffset <= info.Document.TextLength) {
textIterator = textIteratorBuilder.BuildTextIterator(info);
} else {
textIterator = null;
}
return FindNext(monitor);
}
return null;
}
public SearchResultMatch FindNext(int offset, int length)
{
if (info != null && textIterator != null && documentIterator.CurrentFileName != null) {
ProvidedDocumentInformation currentInfo = documentIterator.Current;
if (currentInfo != null) {
if (!info.Equals(currentInfo)) { // create new iterator, if document changed
info = currentInfo;
textIterator = textIteratorBuilder.BuildTextIterator(info);
} else { // old document -> initialize iterator position to caret pos
textIterator.Position = info.CurrentOffset;
}
SearchResultMatch result = CreateNamedSearchResult(searchStrategy.FindNext(textIterator, offset, length));
if (result != null) {
info.CurrentOffset = textIterator.Position;
return result;
}
}
}
// not found or first start -> move forward to the next document
if (documentIterator.MoveForward()) {
info = documentIterator.Current;
// document is valid for searching -> set iterator & fileName
if (info != null && info.EndOffset >= 0 && info.EndOffset <= info.Document.TextLength) {
textIterator = textIteratorBuilder.BuildTextIterator(info);
} else {
textIterator = null;
}
return FindNext(offset, length);
}
return null;
}
}
}

132
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchManager.cs

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
/*
* Created by SharpDevelop.
* User: Siegfried
* Date: 06.10.2011
* Time: 21:33
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Search;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
namespace SearchAndReplace
{
/// <summary>
/// Description of SearchManager.
/// </summary>
public class SearchManager
{
static IEnumerable<FileName> GenerateFileList(SearchTarget target, string baseDirectory = null, string filter = "*.*", bool searchSubdirs = false)
{
List<FileName> files = new List<FileName>();
switch (target) {
case SearchTarget.CurrentDocument:
case SearchTarget.CurrentSelection:
ITextEditorProvider vc = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
if (vc != null)
files.Add(vc.TextEditor.FileName);
break;
case SearchTarget.AllOpenFiles:
foreach (ITextEditorProvider editor in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<ITextEditorProvider>())
files.Add(editor.TextEditor.FileName);
break;
case SearchTarget.WholeProject:
if (ProjectService.CurrentProject == null)
break;
foreach (FileProjectItem item in ProjectService.CurrentProject.Items.OfType<FileProjectItem>())
files.Add(new FileName(item.FileName));
break;
case SearchTarget.WholeSolution:
if (ProjectService.OpenSolution == null)
break;
foreach (var item in ProjectService.OpenSolution.SolutionFolderContainers.Select(f => f.SolutionItems).SelectMany(si => si.Items))
files.Add(new FileName(Path.Combine(ProjectService.OpenSolution.Directory, item.Location)));
foreach (var item in ProjectService.OpenSolution.Projects.SelectMany(p => p.Items).OfType<FileProjectItem>())
files.Add(new FileName(item.FileName));
break;
case SearchTarget.Directory:
if (!Directory.Exists(baseDirectory))
break;
foreach (var name in FileUtility.SearchDirectory(baseDirectory, filter, searchSubdirs))
files.Add(new FileName(name));
break;
default:
throw new Exception("Invalid value for FileListType");
}
return files.Distinct();
}
public static IObservable<SearchResultMatch> FindAll(string pattern, bool ignoreCase, bool matchWholeWords, SearchMode mode,
SearchTarget target, string baseDirectory = null, string filter = "*.*", bool searchSubdirs = false)
{
CancellationTokenSource cts = new CancellationTokenSource();
var monitor = WorkbenchSingleton.Workbench.StatusBar.CreateProgressMonitor(cts.Token);
monitor.TaskName = "Find All";
monitor.Status = OperationStatus.Normal;
var strategy = SearchStrategyFactory.Create(pattern, ignoreCase, matchWholeWords, mode);
ParseableFileContentFinder fileFinder = new ParseableFileContentFinder();
var fileList = GenerateFileList(target, baseDirectory, filter, searchSubdirs);
return new SearchRun(strategy, fileFinder, fileList, monitor, cts);
}
class SearchRun : IObservable<SearchResultMatch>, IDisposable
{
IObserver<SearchResultMatch> observer;
ISearchStrategy strategy;
ParseableFileContentFinder fileFinder;
IEnumerable<FileName> fileList;
IProgressMonitor monitor;
CancellationTokenSource cts;
public SearchRun(ISearchStrategy strategy, ParseableFileContentFinder fileFinder, IEnumerable<FileName> fileList, IProgressMonitor monitor, CancellationTokenSource cts)
{
this.strategy = strategy;
this.fileFinder = fileFinder;
this.fileList = fileList;
this.monitor = monitor;
this.cts = cts;
}
public IDisposable Subscribe(IObserver<SearchResultMatch> observer)
{
this.observer = observer;
new System.Threading.Tasks.Task(delegate { Parallel.ForEach(fileList, fileName => SearchFile(fileFinder.Create(fileName).CreateSnapshot(), strategy, monitor.CancellationToken)); }).Start();
return this;
}
public void Dispose()
{
if (!cts.IsCancellationRequested)
cts.Cancel();
monitor.Dispose();
}
void SearchFile(ITextBuffer buffer, ISearchStrategy strategy, CancellationToken ct)
{
if (!MimeTypeDetection.FindMimeType(buffer).StartsWith("text/"))
return;
var source = DocumentUtilitites.GetTextSource(buffer);
foreach(var result in strategy.FindAll(source)) {
ct.ThrowIfCancellationRequested();
observer.OnNext(new SearchResultMatch(result.Offset, result.Length));
}
lock (monitor)
monitor.Progress += 1 / fileList.Count();
}
}
}
}

89
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchReplaceInFilesManager.cs

@ -1,89 +0,0 @@ @@ -1,89 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using System.Collections.Generic;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
namespace SearchAndReplace
{
public static class SearchInFilesManager
{
static Search find = new Search();
static string currentFileName = String.Empty;
static SearchInFilesManager()
{
find.TextIteratorBuilder = new ForwardTextIteratorBuilder();
}
static void SetSearchOptions(IProgressMonitor monitor)
{
find.SearchStrategy = SearchReplaceUtilities.CreateSearchStrategy(SearchOptions.SearchStrategyType);
find.DocumentIterator = SearchReplaceUtilities.CreateDocumentIterator(SearchOptions.DocumentIteratorType, monitor);
}
static bool InitializeSearchInFiles(IProgressMonitor monitor)
{
SetSearchOptions(monitor);
find.Reset();
if (!find.SearchStrategy.CompilePattern(monitor))
return false;
currentFileName = String.Empty;
return true;
}
static void FinishSearchInFiles(List<SearchResultMatch> results)
{
ShowSearchResults(SearchOptions.FindPattern, results);
}
public static void ShowSearchResults(string pattern, List<SearchResultMatch> results)
{
string title = StringParser.Parse("${res:MainWindow.Windows.SearchResultPanel.OccurrencesOf}",
new StringTagPair("Pattern", pattern));
SearchResultsPad.Instance.ShowSearchResults(title, results);
SearchResultsPad.Instance.BringToFront();
}
public static void FindAll(IProgressMonitor monitor)
{
if (!InitializeSearchInFiles(monitor)) {
return;
}
List<SearchResultMatch> results = new List<SearchResultMatch>();
while (true) {
SearchResultMatch result = find.FindNext(monitor);
if (result == null) {
break;
}
results.Add(result);
}
FinishSearchInFiles(results);
}
public static void FindAll(int offset, int length, IProgressMonitor monitor)
{
if (!InitializeSearchInFiles(monitor)) {
return;
}
List<SearchResultMatch> results = new List<SearchResultMatch>();
while (true) {
SearchResultMatch result = find.FindNext(offset, length);
if (result == null) {
break;
}
results.Add(result);
}
FinishSearchInFiles(results);
}
}
}

393
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchReplaceManager.cs

@ -1,393 +0,0 @@ @@ -1,393 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Bookmarks;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
namespace SearchAndReplace
{
public class SearchReplaceManager
{
public static SearchAndReplaceDialog SearchAndReplaceDialog = null;
static Search find = new Search();
static SearchReplaceManager()
{
find.TextIteratorBuilder = new ForwardTextIteratorBuilder();
}
static void SetSearchOptions(IProgressMonitor monitor)
{
find.SearchStrategy = SearchReplaceUtilities.CreateSearchStrategy(SearchOptions.SearchStrategyType);
find.DocumentIterator = SearchReplaceUtilities.CreateDocumentIterator(SearchOptions.DocumentIteratorType, monitor);
}
public static void Replace(IProgressMonitor monitor)
{
SetSearchOptions(monitor);
if (lastResult != null) {
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
if (provider != null) {
ITextEditor textarea = provider.TextEditor;
if (textarea.SelectionStart == lastResult.Offset
&& textarea.SelectionLength == lastResult.Length
&& lastResult.FileName == textarea.FileName)
{
string replacePattern = lastResult.TransformReplacePattern(SearchOptions.ReplacePattern);
using (textarea.Document.OpenUndoGroup()) {
textarea.Document.Replace(lastResult.Offset, lastResult.Length, replacePattern);
textarea.Select(lastResult.Offset + replacePattern.Length, 0); // clear selection and set caret position
}
}
}
}
FindNext(monitor);
}
static TextSelection textSelection;
public static void ReplaceFirstInSelection(int offset, int length, IProgressMonitor monitor)
{
SetSearchOptions(monitor);
FindFirstInSelection(offset, length, monitor);
}
public static bool ReplaceNextInSelection(IProgressMonitor monitor)
{
if (lastResult != null) {
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
if (provider != null) {
ITextEditor textarea = provider.TextEditor;
if (textarea.SelectionStart == lastResult.Offset
&& textarea.SelectionLength == lastResult.Length
&& lastResult.FileName == textarea.FileName)
{
string replacePattern = lastResult.TransformReplacePattern(SearchOptions.ReplacePattern);
using (textarea.Document.OpenUndoGroup()) {
textarea.Document.Replace(lastResult.Offset, lastResult.Length, replacePattern);
textarea.Select(lastResult.Offset + replacePattern.Length, 0); // clear selection and set caret position
}
textSelection.Length -= lastResult.Length - replacePattern.Length;
}
}
}
return FindNextInSelection(monitor);
}
public static void MarkAll(IProgressMonitor monitor)
{
SetSearchOptions(monitor);
ClearSelection();
find.Reset();
if (!find.SearchStrategy.CompilePattern(monitor))
return;
List<ITextEditor> textAreas = new List<ITextEditor>();
int count;
for (count = 0;; count++) {
SearchResultMatch result = SearchReplaceManager.find.FindNext(monitor);
if (result == null) {
break;
} else {
MarkResult(textAreas, result);
}
}
find.Reset();
ShowMarkDoneMessage(count, monitor);
}
public static void MarkAll(int offset, int length, IProgressMonitor monitor)
{
SetSearchOptions(monitor);
find.Reset();
if (!find.SearchStrategy.CompilePattern(monitor))
return;
List<ITextEditor> textAreas = new List<ITextEditor>();
int count;
for (count = 0;; count++) {
SearchResultMatch result = find.FindNext(offset, length);
if (result == null) {
break;
} else {
MarkResult(textAreas, result);
}
}
find.Reset();
ShowMarkDoneMessage(count, monitor);
}
static void MarkResult(List<ITextEditor> textAreas, SearchResultMatch result)
{
ITextEditor textArea = OpenTextArea(result.FileName);
if (textArea != null) {
if (!textAreas.Contains(textArea)) {
textAreas.Add(textArea);
}
textArea.Caret.Offset = result.Offset;
IDocumentLine segment = textArea.Document.GetLineForOffset(result.Offset);
int lineNr = segment.LineNumber;
foreach (var bookmark in BookmarkManager.GetBookmarks(result.FileName)) {
if (bookmark.CanToggle && bookmark.LineNumber == lineNr) {
// bookmark or breakpoint already exists at that line
return;
}
}
BookmarkManager.AddMark(new Bookmark(result.FileName, textArea.Document.OffsetToPosition(result.Offset)));
}
}
static void ShowMarkDoneMessage(int count, IProgressMonitor monitor)
{
if (count == 0) {
ShowNotFoundMessage(monitor);
} else {
if (monitor != null) monitor.ShowingDialog = true;
MessageService.ShowMessage(StringParser.Parse("${res:ICSharpCode.TextEditor.Document.SearchReplaceManager.MarkAllDone}",new StringTagPair("Count", count.ToString())),
"${res:Global.FinishedCaptionText}");
if (monitor != null) monitor.ShowingDialog = false;
}
}
static void ShowReplaceDoneMessage(int count, IProgressMonitor monitor)
{
if (count == 0) {
ShowNotFoundMessage(monitor);
} else {
if (monitor != null) monitor.ShowingDialog = true;
MessageService.ShowMessage(
StringParser.Parse("${res:ICSharpCode.TextEditor.Document.SearchReplaceManager.ReplaceAllDone}",
new StringTagPair("Count", count.ToString())),
"${res:Global.FinishedCaptionText}");
if (monitor != null) monitor.ShowingDialog = false;
}
}
public static void ReplaceAll(IProgressMonitor monitor)
{
SetSearchOptions(monitor);
ClearSelection();
find.Reset();
if (!find.SearchStrategy.CompilePattern(monitor))
return;
List<ITextEditor> textAreas = new List<ITextEditor>();
ITextEditor textArea = null;
for (int count = 0;; count++) {
SearchResultMatch result = SearchReplaceManager.find.FindNext(monitor);
if (result == null) {
if (count != 0) {
foreach (ITextEditor ta in textAreas) {
ta.Document.EndUndoableAction();
}
}
ShowReplaceDoneMessage(count, monitor);
find.Reset();
return;
} else {
if (textArea == null || textArea.FileName != result.FileName) {
// we need to open another text area
textArea = OpenTextArea(result.FileName);
if (textArea != null) {
if (!textAreas.Contains(textArea)) {
textArea.Document.StartUndoableAction();
textArea.Select(textArea.SelectionStart, 0);
textAreas.Add(textArea);
}
}
}
if (textArea != null) {
string transformedPattern = result.TransformReplacePattern(SearchOptions.ReplacePattern);
find.Replace(result.Offset, result.Length, transformedPattern);
if (find.CurrentDocumentInformation.IsDocumentCreatedFromTextBuffer) {
textArea.Document.Replace(result.Offset, result.Length, transformedPattern);
}
} else {
count--;
}
}
}
}
public static void ReplaceAll(int offset, int length, IProgressMonitor monitor)
{
SetSearchOptions(monitor);
find.Reset();
if (!find.SearchStrategy.CompilePattern(monitor))
return;
for (int count = 0;; count++) {
SearchResultMatch result = find.FindNext(offset, length);
if (result == null) {
ShowReplaceDoneMessage(count, monitor);
return;
}
string replacement = result.TransformReplacePattern(SearchOptions.ReplacePattern);
find.Replace(result.Offset,
result.Length,
replacement);
length -= result.Length - replacement.Length;
// HACK - Move the cursor to the correct offset - the caret gets
// moved before the replace range if we replace a string with a
// single character. The ProvidedDocInfo.Replace method assumes that
// the current offset is at the end of the found text which it is not.
find.CurrentDocumentInformation.CurrentOffset = result.Offset + replacement.Length - 1;
}
}
static SearchResultMatch lastResult = null;
public static void FindNext(IProgressMonitor monitor)
{
SetSearchOptions(monitor);
if (find == null ||
SearchOptions.FindPattern == null ||
SearchOptions.FindPattern.Length == 0) {
return;
}
if (!find.SearchStrategy.CompilePattern(monitor)) {
find.Reset();
lastResult = null;
return;
}
ITextEditor textArea = null;
while (textArea == null) {
SearchResultMatch result = find.FindNext(monitor);
if (result == null) {
ShowNotFoundMessage(monitor);
find.Reset();
lastResult = null;
return;
} else {
textArea = OpenTextArea(result.FileName);
if (textArea != null) {
if (lastResult != null && lastResult.FileName == result.FileName &&
textArea.Caret.Offset != lastResult.Offset + lastResult.Length) {
find.Reset();
}
int startPos = Math.Min(textArea.Document.TextLength, Math.Max(0, result.Offset));
int endPos = Math.Min(textArea.Document.TextLength, startPos + result.Length);
textArea.Select(startPos, endPos - startPos);
lastResult = result;
}
}
}
}
static bool foundAtLeastOneItem = false;
public static void FindFirstInSelection(int offset, int length, IProgressMonitor monitor)
{
foundAtLeastOneItem = false;
textSelection = null;
SetSearchOptions(monitor);
if (find == null ||
SearchOptions.FindPattern == null ||
SearchOptions.FindPattern.Length == 0) {
return;
}
if (!find.SearchStrategy.CompilePattern(monitor)) {
find.Reset();
lastResult = null;
return;
}
textSelection = new TextSelection(offset, length);
FindNextInSelection(monitor);
}
public static bool FindNextInSelection(IProgressMonitor monitor)
{
ITextEditor textArea = null;
while (textArea == null) {
SearchResultMatch result = find.FindNext(textSelection.Offset, textSelection.Length);
if (result == null) {
if (!foundAtLeastOneItem) {
ShowNotFoundMessage(monitor);
}
find.Reset();
lastResult = null;
foundAtLeastOneItem = false;
return false;
} else {
textArea = OpenTextArea(result.FileName);
if (textArea != null) {
foundAtLeastOneItem = true;
if (lastResult != null && lastResult.FileName == result.FileName &&
textArea.Caret.Offset != lastResult.Offset + lastResult.Length) {
}
int startPos = Math.Min(textArea.Document.TextLength, Math.Max(0, result.Offset));
int endPos = Math.Min(textArea.Document.TextLength, startPos + result.Length);
textArea.Select(startPos, endPos - startPos);
lastResult = result;
}
}
}
return true;
}
static void ShowNotFoundMessage(IProgressMonitor monitor)
{
if (monitor != null && monitor.CancellationToken.IsCancellationRequested)
return;
if (monitor != null) monitor.ShowingDialog = true;
MessageBox.Show(WorkbenchSingleton.MainWin32Window,
ResourceService.GetString("Dialog.NewProject.SearchReplace.SearchStringNotFound"),
ResourceService.GetString("Dialog.NewProject.SearchReplace.SearchStringNotFound.Title"),
MessageBoxButtons.OK,
MessageBoxIcon.Information);
if (monitor != null) monitor.ShowingDialog = false;
}
static ITextEditor OpenTextArea(string fileName)
{
ITextEditorProvider textEditorProvider;
if (fileName != null) {
textEditorProvider = FileService.OpenFile(fileName) as ITextEditorProvider;
} else {
textEditorProvider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
}
if (textEditorProvider != null) {
return textEditorProvider.TextEditor;
}
return null;
}
static void ClearSelection()
{
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
if (provider != null) {
ITextEditor editor = provider.TextEditor;
if (editor.SelectionLength > 0)
editor.Select(editor.Caret.Offset, 0);
}
}
}
}

112
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchReplaceUtilities.cs

@ -1,112 +0,0 @@ @@ -1,112 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
namespace SearchAndReplace
{
public sealed class SearchReplaceUtilities
{
public static bool IsTextAreaSelected {
get {
return WorkbenchSingleton.Workbench.ActiveViewContent is ITextEditorProvider;
}
}
public static ITextEditor GetActiveTextEditor()
{
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
if (provider != null) {
return provider.TextEditor;
} else {
return null;
}
}
static bool IsWordPart(char c)
{
return char.IsLetterOrDigit(c) || c == '_';
}
public static bool IsWholeWordAt(IDocument document, int offset, int length)
{
return (offset - 1 < 0 || !IsWordPart(document.GetCharAt(offset - 1))) &&
(offset + length + 1 >= document.TextLength || !IsWordPart(document.GetCharAt(offset + length)));
}
public static ISearchStrategy CreateSearchStrategy(SearchStrategyType type)
{
switch (type) {
case SearchStrategyType.Normal:
return new BruteForceSearchStrategy(); // new KMPSearchStrategy();
case SearchStrategyType.RegEx:
return new RegExSearchStrategy();
case SearchStrategyType.Wildcard:
return new WildcardSearchStrategy();
default:
throw new System.NotImplementedException("CreateSearchStrategy for type " + type);
}
}
public static IDocumentIterator CreateDocumentIterator(DocumentIteratorType type, IProgressMonitor monitor)
{
switch (type) {
case DocumentIteratorType.CurrentDocument:
case DocumentIteratorType.CurrentSelection:
return new CurrentDocumentIterator();
case DocumentIteratorType.Directory:
try {
if (!Directory.Exists(SearchOptions.LookIn)) {
if (monitor != null) monitor.ShowingDialog = true;
MessageService.ShowMessageFormatted("${res:Dialog.NewProject.SearchReplace.SearchStringNotFound.Title}", "${res:Dialog.NewProject.SearchReplace.LookIn.DirectoryNotFound}", FileUtility.NormalizePath(SearchOptions.LookIn));
if (monitor != null) monitor.ShowingDialog = false;
return new DummyDocumentIterator();
}
} catch (Exception ex) {
if (monitor != null) monitor.ShowingDialog = true;
MessageService.ShowMessage(ex.Message);
if (monitor != null) monitor.ShowingDialog = false;
return new DummyDocumentIterator();
}
return new DirectoryDocumentIterator(SearchOptions.LookIn,
SearchOptions.LookInFiletypes,
SearchOptions.IncludeSubdirectories);
case DocumentIteratorType.AllOpenFiles:
return new AllOpenDocumentIterator();
case DocumentIteratorType.WholeProject:
return new WholeProjectDocumentIterator();
case DocumentIteratorType.WholeSolution:
return new WholeSolutionDocumentIterator();
default:
throw new System.NotImplementedException("CreateDocumentIterator for type " + type);
}
}
public static bool IsSearchable(string fileName)
{
const int BUFFER_LENGTH = 4 * 1024;
if (!File.Exists(fileName))
return false;
using (var stream = File.OpenRead(fileName)) {
string mime = "text/plain";
if (stream.Length > 0) {
stream.Position = 0;
mime = MimeTypeDetection.FindMimeType(new BinaryReader(stream).ReadBytes(BUFFER_LENGTH));
}
return mime.StartsWith("text/", StringComparison.OrdinalIgnoreCase);
}
}
}
}

128
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/BoyerMooreSearchStrategy.cs

@ -1,128 +0,0 @@ @@ -1,128 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using System.Collections.Generic;
namespace SearchAndReplace
{
/// <summary>
/// This interface is the basic interface which all
/// search algorithms must implement.
/// </summary>
public class BoyerMooreSearchStrategy
{
// Shift table for chars present in the pattern
Dictionary<char, int[]> patternCharShifts;
// Shifts for all other chars
int[] otherCharShifts;
// the patern to search
string searchPattern;
// Length of the search pattern
int patternLength;
/// <remarks>
/// Only with a call to this method the search strategy must
/// update their pattern information. This method will be called
/// before the FindNext function.
/// </remarks>
public void CompilePattern()
{
searchPattern = SearchOptions.MatchCase ? SearchOptions.FindPattern : SearchOptions.FindPattern.ToUpper();
// Building shift table
patternLength = searchPattern.Length;
int maxShift = patternLength;
patternCharShifts = new Dictionary<char, int[]>();
// Constructing the table where number
// of columns is equal to PatternLength
// and number of rows is equal to the
// number of distinct chars in the pattern
for (int i = 0; i < patternLength; ++i) {
if (!patternCharShifts.ContainsKey(searchPattern[i])) {
patternCharShifts.Add(searchPattern[i], new int[patternLength]);
}
}
otherCharShifts = new int[patternLength];
// Filling the last column of the
// table with maximum shifts (pattern length)
foreach(KeyValuePair<char, int[]> row in patternCharShifts) {
row.Value[patternLength - 1] = maxShift;
}
otherCharShifts[patternLength - 1] = maxShift;
// Calculating other shifts (filling each column
// from PatternLength - 2 to 0 (from right to left)
for (int i = patternLength - 1; i >= 0; --i)
{
// Suffix string contains the characters
// right to the character being processsed
string suffix = new String(searchPattern.ToCharArray(),
i + 1, patternLength - i - 1);
// if Pattern begins with Suffix
// the maximum shift is equal to i + 1
if (searchPattern.StartsWith(suffix)) {
maxShift = i + 1;
}
// Store shift for characters not present in the pattern
otherCharShifts[i] = maxShift;
// We shorten patter by one char in NewPattern.
string newPattern = new string(searchPattern.ToCharArray(),
0, searchPattern.Length -1);
if ((newPattern.LastIndexOf(suffix) > 0) || (suffix.Length == 0)) {
foreach(KeyValuePair<char, int[]> row in patternCharShifts)
{
string newSuffix = row.Key + suffix;
// Calculate shifts:
//Check if there are other occurences
//of the new suffix in the pattern
// If several occurences exist, we need the rightmost one
int newSuffixPos = newPattern.LastIndexOf(newSuffix);
if (newSuffixPos >= 0) {
row.Value[i] = i - newSuffixPos;
} else {
row.Value[i] = maxShift;
}
// Storing 0 if characters
// in a row and a columnt are the same
if (row.Key == searchPattern[i]) {
row.Value[i] = 0;
}
}
} else {
foreach(KeyValuePair<char, int[]> row in patternCharShifts)
{
// if Suffix doesn't occure in NewPattern
// we simply use previous shift value
row.Value[i] = maxShift;
if (row.Key == searchPattern[i]) {
row.Value[i] = 0;
}
}
}
}
}
int InternalFindNext(ITextIterator textIterator)
{
// while (textIterator.MoveAhead(1)) {
// if (SearchOptions.MatchCase ? MatchCaseSensitive(textIterator.TextBuffer, textIterator.Position, searchPattern) : MatchCaseInsensitive(textIterator.TextBuffer, textIterator.Position, searchPattern)) {
// if (!SearchOptions.MatchWholeWord || IsWholeWordAt(textIterator.TextBuffer, textIterator.Position, searchPattern.Length)) {
// return textIterator.Position;
// }
// }
// }
return -1;
}
/// <remarks>
/// The find next method should search the next occurrence of the
/// compiled pattern in the text using the textIterator and options.
/// </remarks>
public SearchResultMatch FindNext(ITextIterator textIterator)
{
int offset = InternalFindNext(textIterator);
return offset >= 0 ? new SearchResultMatch(offset, searchPattern.Length) : null;
}
}
}

91
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/BruteForceSearchStrategy.cs

@ -1,91 +0,0 @@ @@ -1,91 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using ICSharpCode.SharpDevelop.Editor;
namespace SearchAndReplace
{
/// <summary>
/// Only for fallback purposes.
/// </summary>
public class BruteForceSearchStrategy : ISearchStrategy
{
string searchPattern;
bool MatchCaseSensitive(IDocument document, int offset, string pattern)
{
for (int i = 0; i < pattern.Length; ++i) {
if (offset + i >= document.TextLength || document.GetCharAt(offset + i) != pattern[i]) {
return false;
}
}
return true;
}
bool MatchCaseInsensitive(IDocument document, int offset, string pattern)
{
for (int i = 0; i < pattern.Length; ++i) {
if (offset + i >= document.TextLength || Char.ToUpper(document.GetCharAt(offset + i)) != pattern[i]) {
return false;
}
}
return true;
}
int InternalFindNext(ITextIterator textIterator)
{
while (textIterator.MoveAhead(1)) {
if (SearchOptions.MatchCase ? MatchCaseSensitive(textIterator.Document, textIterator.Position, searchPattern) : MatchCaseInsensitive(textIterator.Document, textIterator.Position, searchPattern)) {
if (!SearchOptions.MatchWholeWord || SearchReplaceUtilities.IsWholeWordAt(textIterator.Document, textIterator.Position, searchPattern.Length)) {
return textIterator.Position;
}
}
}
return -1;
}
int InternalFindNext(ITextIterator textIterator, int offset, int length)
{
while (textIterator.MoveAhead(1)) {
if (textIterator.Position >= offset + length) {
textIterator.Position = offset;
}
if (SearchOptions.MatchCase ? MatchCaseSensitive(textIterator.Document, textIterator.Position, searchPattern) : MatchCaseInsensitive(textIterator.Document, textIterator.Position, searchPattern)) {
if (!SearchOptions.MatchWholeWord || SearchReplaceUtilities.IsWholeWordAt(textIterator.Document, textIterator.Position, searchPattern.Length)) {
if (TextSelection.IsInsideRange(textIterator.Position + searchPattern.Length - 1, offset, length)) {
return textIterator.Position;
} else {
return -1;
}
}
}
}
return -1;
}
public bool CompilePattern(ICSharpCode.SharpDevelop.Gui.IProgressMonitor monitor)
{
searchPattern = SearchOptions.MatchCase ? SearchOptions.FindPattern : SearchOptions.FindPattern.ToUpper();
return true;
}
public SearchResultMatch FindNext(ITextIterator textIterator)
{
int offset = InternalFindNext(textIterator);
return GetSearchResult(offset);
}
public SearchResultMatch FindNext(ITextIterator textIterator, int offset, int length)
{
int foundOffset = InternalFindNext(textIterator, offset, length);
return GetSearchResult(foundOffset);
}
SearchResultMatch GetSearchResult(int offset)
{
return offset >= 0 ? new SearchResultMatch(offset, searchPattern.Length) : null;
}
}
}

35
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/ISearchStrategy.cs

@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using ICSharpCode.SharpDevelop.Gui;
namespace SearchAndReplace
{
/// <summary>
/// This interface is the basic interface which all
/// search algorithms must implement.
/// </summary>
public interface ISearchStrategy
{
/// <remarks>
/// Only with a call to this method the search strategy must
/// update their pattern information. This method will be called
/// before the FindNext function.
/// The method might show a message box to the user if the pattern is invalid.
/// </remarks>
bool CompilePattern(IProgressMonitor monitor);
/// <remarks>
/// The find next method should search the next occurrence of the
/// compiled pattern in the text using the textIterator and options.
/// </remarks>
SearchResultMatch FindNext(ITextIterator textIterator);
/// <summary>
/// Find only in the specified range.
/// </summary>
SearchResultMatch FindNext(ITextIterator textIterator, int offset, int length);
}
}

78
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/KMPSearchStrategy.cs

@ -1,78 +0,0 @@ @@ -1,78 +0,0 @@
//// <file>
//// <copyright see="prj:///doc/copyright.txt"/>
//// <license see="prj:///doc/license.txt"/>
//// <owner name="Andrea Paatz" email="andrea@icsharpcode.net"/>
//// <version value="$version"/>
//// </file>
//
//using System;
//
//namespace SearchAndReplace
//{
// /// <summary>
// /// Implements the Knuth, Morris, Pratt searching algorithm.
// /// </summary>
// public class KMPSearchStrategy : ISearchStrategy
// {
// string searchPattern;
// int[] overlap;
//
// public void CompilePattern()
// {
// if (searchPattern != (options.IgnoreCase ? options.SearchPattern.ToUpper() : options.SearchPattern)) {
// searchPattern = options.IgnoreCase ? options.SearchPattern.ToUpper() : options.SearchPattern;
// overlap = new int[searchPattern.Length + 1];
// Preprocessing();
// }
// }
//
// void Preprocessing()
// {
// overlap[0] = -1;
// for (int i = 0, j = -1; i < searchPattern.Length;) {
// while (j >= 0 && searchPattern[i] != searchPattern[j]) {
// j = overlap[j];
// }
// ++i;
// ++j;
// overlap[i] = j;
// }
// }
//
// int InternalFindNext(ITextIterator textIterator)
// {
// int j = 0;
// if (!textIterator.MoveAhead(1)) {
// return -1;
// }
// while (true) { // until pattern found or Iterator finished
// while (j >= 0 && searchPattern[j] != (options.IgnoreCase ? Char.ToUpper(textIterator.GetCharRelative(j)) : textIterator.GetCharRelative(j))) {
// if (!textIterator.MoveAhead(j - overlap[j])) {
// return -1;
// }
// j = overlap[j];
// }
// if (++j >= searchPattern.Length) {
// if ((!options.SearchWholeWordOnly || SearchReplaceUtilities.IsWholeWordAt(textIterator.TextBuffer, textIterator.Position, searchPattern.Length))) {
// return textIterator.Position;
// }
// if (!textIterator.MoveAhead(j - overlap[j])) {
// return -1;
// }
// j = overlap[j];
// }
// }
// }
//
// public SearchResult FindNext(ITextIterator textIterator)
// {
// int offset = InternalFindNext(textIterator, options);
//
// if (offset + searchPattern.Length >= textIterator.TextBuffer.Length) {
// return FindNext(textIterator, options);
// }
//
// return offset >= 0 ? new SearchResult(offset, searchPattern.Length) : null;
// }
// }
//}

103
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/RegExSearchStrategy.cs

@ -1,103 +0,0 @@ @@ -1,103 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using System.Text.RegularExpressions;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace SearchAndReplace
{
public class RegExSearchStrategy : ISearchStrategy
{
Regex regex = null;
public bool CompilePattern(IProgressMonitor monitor)
{
RegexOptions regexOptions = RegexOptions.Compiled | RegexOptions.Multiline;
if (!SearchOptions.MatchCase) {
regexOptions |= RegexOptions.IgnoreCase;
}
try {
regex = new Regex(SearchOptions.FindPattern, regexOptions);
return true;
} catch (ArgumentException ex) {
if (monitor != null) monitor.ShowingDialog = true;
MessageService.ShowError("${res:Dialog.NewProject.SearchReplace.ErrorParsingRegex}\n" + ex.Message);
if (monitor != null) monitor.ShowingDialog = false;
return false;
}
}
public SearchResultMatch FindNext(ITextIterator textIterator)
{
string document = textIterator.Document.Text;
while (textIterator.MoveAhead(1)) {
Match m = regex.Match(document, textIterator.Position);
if (m == null || !m.Success) {
while (textIterator.Position < document.Length - 1) {
if (!textIterator.MoveAhead(1))
return null;
}
} else {
int delta = m.Index - textIterator.Position;
if (delta <= 0 || textIterator.MoveAhead(delta)) {
return new RegexSearchResult(m);
} else {
return null;
}
}
}
return null;
}
public SearchResultMatch FindNext(ITextIterator textIterator, int offset, int length)
{
string document = textIterator.Document.GetText(0, textIterator.Document.TextLength);
while (textIterator.MoveAhead(1)) {
if (textIterator.Position >= offset + length) {
textIterator.Position = offset;
}
Match m = regex.Match(document, textIterator.Position);
if (m == null || !m.Success) {
while (textIterator.Position < document.Length - 1) {
if (!textIterator.MoveAhead(1))
return null;
}
} else {
int delta = m.Index - textIterator.Position;
if (delta <= 0 || textIterator.MoveAhead(delta)) {
if (TextSelection.IsInsideRange(m.Index + m.Length - 1, offset, length)) {
return new RegexSearchResult(m);
} else {
return null;
}
} else {
return null;
}
}
}
return null;
}
private sealed class RegexSearchResult : SearchResultMatch
{
Match m;
internal RegexSearchResult(Match m) : base(m.Index, m.Length)
{
this.m = m;
}
public override string TransformReplacePattern(string pattern)
{
return m.Result(pattern);
}
}
}
}

190
src/AddIns/Misc/SearchAndReplace/Project/Engine/SearchStrategy/WildcardSearchStrategy.cs

@ -1,190 +0,0 @@ @@ -1,190 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using System.Collections;
using ICSharpCode.SharpDevelop.Editor;
namespace SearchAndReplace
{
/// <summary>
/// Implements a wildcard search strategy.
///
/// Wildcard search has following pattern code :
/// * = Zero or more of any character
/// ? = Any single character
/// # = Any single digit
/// [...] = Any one character in the set
/// [!...] = Any one character not in the set
/// </summary>
public class WildcardSearchStrategy : ISearchStrategy
{
enum CommandType {
Match,
AnyZeroOrMore,
AnySingle,
AnyDigit,
AnyInList,
NoneInList
}
class Command {
public CommandType CommandType = CommandType.Match;
public char SingleChar = '\0';
public string CharList = String.Empty;
}
ArrayList patternProgram = null;
int curMatchEndOffset = -1;
void CompilePattern(string pattern, bool ignoreCase)
{
patternProgram = new ArrayList();
for (int i = 0; i < pattern.Length; ++i) {
Command newCommand = new Command();
switch (pattern[i]) {
case '#':
newCommand.CommandType = CommandType.AnyDigit;
break;
case '*':
newCommand.CommandType = CommandType.AnyZeroOrMore;
break;
case '?':
newCommand.CommandType = CommandType.AnySingle;
break;
case '[':
int index = pattern.IndexOf(']', i);
if (index > 0) {
newCommand.CommandType = CommandType.AnyInList;
string list = pattern.Substring(i + 1, index - i - 1);
if (list[0] == '!') {
newCommand.CommandType = CommandType.NoneInList;
list = list.Substring(1);
}
newCommand.CharList = ignoreCase ? list.ToUpper() : list;
i = index;
} else {
goto default;
}
break;
default:
newCommand.CommandType = CommandType.Match;
newCommand.SingleChar = ignoreCase ? Char.ToUpper(pattern[i]) : pattern[i];
break;
}
patternProgram.Add(newCommand);
}
}
bool Match(IDocument document,
int offset,
bool ignoreCase,
int programStart)
{
int curOffset = offset;
curMatchEndOffset = -1;
for (int pc = programStart; pc < patternProgram.Count; ++pc) {
if (curOffset >= document.TextLength) {
return false;
}
char ch = ignoreCase ? Char.ToUpper(document.GetCharAt(curOffset)) : document.GetCharAt(curOffset);
Command cmd = (Command)patternProgram[pc];
switch (cmd.CommandType) {
case CommandType.Match:
if (ch != cmd.SingleChar) {
return false;
}
break;
case CommandType.AnyZeroOrMore:
if (ch == '\n') {
return false;
}
return Match(document, curOffset, ignoreCase, pc + 1) ||
Match(document, curOffset + 1, ignoreCase, pc);
case CommandType.AnySingle:
break;
case CommandType.AnyDigit:
if (!Char.IsDigit(ch) && ch != '#') {
return false;
}
break;
case CommandType.AnyInList:
if (cmd.CharList.IndexOf(ch) < 0) {
return false;
}
break;
case CommandType.NoneInList:
if (cmd.CharList.IndexOf(ch) >= 0) {
return false;
}
break;
}
++curOffset;
}
curMatchEndOffset = curOffset;
return true;
}
int InternalFindNext(ITextIterator textIterator)
{
while (textIterator.MoveAhead(1)) {
int position = textIterator.Position;
if (Match(textIterator.Document, position, !SearchOptions.MatchCase, 0)) {
if (!SearchOptions.MatchWholeWord || SearchReplaceUtilities.IsWholeWordAt(textIterator.Document, position, curMatchEndOffset - position)) {
textIterator.MoveAhead(curMatchEndOffset - position - 1);
return position;
}
}
}
return -1;
}
int InternalFindNext(ITextIterator textIterator, int offset, int length)
{
while (textIterator.MoveAhead(1)) {
if (textIterator.Position >= offset + length) {
textIterator.Position = offset;
}
int position = textIterator.Position;
if (Match(textIterator.Document, position, !SearchOptions.MatchCase, 0)) {
if (!SearchOptions.MatchWholeWord || SearchReplaceUtilities.IsWholeWordAt(textIterator.Document, position, curMatchEndOffset - position)) {
if (TextSelection.IsInsideRange(curMatchEndOffset - 1, offset, length)) {
textIterator.MoveAhead(curMatchEndOffset - position - 1);
return position;
} else {
return -1;
}
}
}
}
return -1;
}
public bool CompilePattern(ICSharpCode.SharpDevelop.Gui.IProgressMonitor monitor)
{
CompilePattern(SearchOptions.FindPattern, !SearchOptions.MatchCase);
return true;
}
public SearchResultMatch FindNext(ITextIterator textIterator)
{
int offset = InternalFindNext(textIterator);
return GetSearchResult(offset);
}
public SearchResultMatch FindNext(ITextIterator textIterator, int offset, int length)
{
int foundOffset = InternalFindNext(textIterator, offset, length);
return GetSearchResult(foundOffset);
}
SearchResultMatch GetSearchResult(int offset)
{
return offset >= 0 ? new SearchResultMatch(offset, curMatchEndOffset - offset) : null;
}
}
}

163
src/AddIns/Misc/SearchAndReplace/Project/Engine/TextIterator/ForwardTextIterator.cs

@ -1,163 +0,0 @@ @@ -1,163 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using System.Diagnostics;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using ICSharpCode.SharpDevelop.Editor;
namespace SearchAndReplace
{
public class ForwardTextIterator : ITextIterator
{
ProvidedDocumentInformation info;
enum TextIteratorState {
Resetted,
Iterating,
Done,
}
TextIteratorState state;
IDocument document;
int endOffset;
int oldOffset = -1;
public IDocument Document {
get {
return document;
}
}
public char Current {
get {
switch (state) {
case TextIteratorState.Resetted:
throw new System.InvalidOperationException("Call moveAhead first");
case TextIteratorState.Iterating:
return document.GetCharAt(Position);
case TextIteratorState.Done:
throw new System.InvalidOperationException("TextIterator is at the end");
default:
throw new System.InvalidOperationException("unknown text iterator state");
}
}
}
int position;
public int Position {
get {
return position;
}
set {
position = value;
}
}
public ForwardTextIterator(ProvidedDocumentInformation info)
{
if (info == null)
throw new ArgumentNullException("info");
this.info = info;
this.document = info.Document;
this.position = info.CurrentOffset;
this.endOffset = info.EndOffset;
Reset();
}
public char GetCharRelative(int offset)
{
if (state != TextIteratorState.Iterating) {
throw new System.InvalidOperationException();
}
int realOffset = (Position + (1 + Math.Abs(offset) / document.TextLength) * document.TextLength + offset) % document.TextLength;
return document.GetCharAt(realOffset);
}
public bool MoveAhead(int numChars)
{
Debug.Assert(numChars > 0);
// HACK : ignore files with length 1 (fixes SD-1815)
if (document.TextLength == 1) {
state = TextIteratorState.Done;
return false;
}
switch (state) {
case TextIteratorState.Resetted:
if (document.TextLength == 0) {
state = TextIteratorState.Done;
return false;
}
Position = endOffset;
state = TextIteratorState.Iterating;
return true;
case TextIteratorState.Done:
return false;
case TextIteratorState.Iterating:
if (oldOffset == -1 && document.TextLength == endOffset) {
// HACK: Take off one if the iterator start
// position is at the end of the text.
Position--;
}
if (oldOffset != -1 && Position == endOffset - 1 && document.TextLength == endOffset) {
state = TextIteratorState.Done;
return false;
}
Position = (Position + numChars) % document.TextLength;
bool finish = oldOffset != -1 && (oldOffset > Position || oldOffset < endOffset) && Position >= endOffset;
// HACK: Iterating is complete if Position == endOffset - 1
// when the iterator start position was initially at the
// end of the text.
if (oldOffset != -1 && oldOffset == endOffset - 1 && document.TextLength == endOffset) {
finish = true;
}
oldOffset = Position;
if (finish) {
state = TextIteratorState.Done;
return false;
}
return true;
default:
throw new Exception("Unknown text iterator state");
}
}
public void InformReplace(int offset, int length, int newLength)
{
if (offset <= endOffset) {
endOffset = endOffset - length + newLength;
}
if (offset <= Position) {
Position = Position - length + newLength;
}
if (offset <= oldOffset) {
oldOffset = oldOffset - length + newLength;
}
}
public void Reset()
{
state = TextIteratorState.Resetted;
Position = endOffset;
oldOffset = -1;
}
public override string ToString()
{
return String.Format("[ForwardTextIterator: Position={0}, endOffset={1}, state={2}]", Position, endOffset, state);
}
}
}

18
src/AddIns/Misc/SearchAndReplace/Project/Engine/TextIterator/ForwardTextIteratorBuilder.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor.Search;
using System;
using System.Diagnostics;
namespace SearchAndReplace
{
public class ForwardTextIteratorBuilder : ITextIteratorBuilder
{
public ITextIterator BuildTextIterator(ProvidedDocumentInformation info)
{
Debug.Assert(info != null);
return new ForwardTextIterator(info);
}
}
}

69
src/AddIns/Misc/SearchAndReplace/Project/Engine/TextIterator/ITextIterator.cs

@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Editor;
using System;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
namespace SearchAndReplace
{
/// <summary>
/// This iterator iterates on a text buffer strategy.
/// </summary>
public interface ITextIterator
{
/// <value>
/// The text buffer strategy
/// </value>
IDocument Document {
get;
}
/// <value>
/// Gets the current char this is the same as
/// GetCharRelative(0)
/// </value>
/// <exception cref="System.InvalidOperationException">
/// If this method is called before the first MoveAhead or after
/// MoveAhead or after MoveAhead returns false.
/// </exception>
char Current {
get;
}
/// <value>
/// The current position=offset of the text iterator cursor
/// </value>
int Position {
get;
set;
}
/// <remarks>
/// Gets a char relative to the current position (negative values
/// will work too).
/// </remarks>
/// <exception cref="System.InvalidOperationException">
/// If this method is called before the first MoveAhead or after
/// MoveAhead or after MoveAhead returns false.
/// </exception>
char GetCharRelative(int offset);
/// <remarks>
/// Moves the iterator position numChars
/// </remarks>
bool MoveAhead(int numChars);
/// <remarks>
/// Rests the iterator
/// </remarks>
void Reset();
/// <remarks>
/// The find object calls the InformReplace method to inform the text iterator
/// about the replace operation on the TextBuffer. The text iterator must update
/// all internal offsets to the new offsets (if neccessary)
/// </remarks>
void InformReplace(int offset, int length, int newLength);
}
}

45
src/AddIns/Misc/SearchAndReplace/Project/Engine/TextSelection.cs

@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
namespace SearchAndReplace
{
public class TextSelection
{
int offset;
int length;
public TextSelection(int offset, int length)
{
this.offset = offset;
this.length = length;
}
public int Length {
get {
return length;
}
set {
length = value;
}
}
public int Offset {
get {
return offset;
}
set {
offset = value;
}
}
/// <summary>
/// Checks whether a position is in a specified range.
/// </summary>
public static bool IsInsideRange(int position, int offset, int length)
{
return position >= offset && position < offset + length;
}
}
}

66
src/AddIns/Misc/SearchAndReplace/Project/Gui/DefaultSearchResult.cs

@ -8,6 +8,7 @@ using System.Linq; @@ -8,6 +8,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.Core;
using ICSharpCode.Core.Presentation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor.Search;
@ -118,5 +119,70 @@ namespace SearchAndReplace @@ -118,5 +119,70 @@ namespace SearchAndReplace
{
return new DefaultSearchResult(title, matches);
}
public ISearchResult CreateSearchResult(string title, IObservable<SearchResultMatch> matches)
{
var osr = new ObserverSearchResult(title);
osr.Registration = matches.Subscribe(osr);
return osr;
}
}
public class ObserverSearchResult : ISearchResult, IObserver<SearchResultMatch>
{
List<SearchResultMatch> matches;
Button stopButton;
SearchRootNode rootNode;
public ObserverSearchResult(string title)
{
Text = title;
matches = new List<SearchResultMatch>();
rootNode = new SearchRootNode(title, matches);
}
public string Text { get; private set; }
public IDisposable Registration { get; set; }
static ResultsTreeView resultsTreeViewInstance;
public object GetControl()
{
WorkbenchSingleton.AssertMainThread();
if (resultsTreeViewInstance == null)
resultsTreeViewInstance = new ResultsTreeView();
rootNode.GroupResultsByFile(ResultsTreeView.GroupResultsByFile);
resultsTreeViewInstance.ItemsSource = new object[] { rootNode };
return resultsTreeViewInstance;
}
public IList GetToolbarItems()
{
stopButton = new Button { Content = "Stop" };
stopButton.Click += delegate { if (Registration != null) Registration.Dispose(); };
return new ArrayList { stopButton };
}
void IObserver<SearchResultMatch>.OnNext(SearchResultMatch value)
{
matches.Add(value);
}
void IObserver<SearchResultMatch>.OnError(Exception error)
{
MessageService.ShowException(error);
OnCompleted();
}
void OnCompleted()
{
stopButton.Visibility = Visibility.Collapsed;
}
void IObserver<SearchResultMatch>.OnCompleted()
{
OnCompleted();
}
}
}

133
src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchAndReplacePanel.cs

@ -1,12 +1,14 @@ @@ -1,12 +1,14 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.AvalonEdit.Search;
using ICSharpCode.SharpDevelop.Editor;
using System;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.Core.WinForms;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor.Search;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.XmlForms;
@ -84,9 +86,9 @@ namespace SearchAndReplace @@ -84,9 +86,9 @@ namespace SearchAndReplace
base.Dispose(disposing);
}
public DocumentIteratorType DocumentIteratorType {
public SearchTarget SearchTarget {
get {
return (DocumentIteratorType)(Get<ComboBox>("lookIn").SelectedIndex);
return (SearchTarget)(Get<ComboBox>("lookIn").SelectedIndex);
}
set {
Get<ComboBox>("lookIn").SelectedIndex = (int)value;
@ -115,7 +117,7 @@ namespace SearchAndReplace @@ -115,7 +117,7 @@ namespace SearchAndReplace
using (AsynchronousWaitDialog monitor = AsynchronousWaitDialog.ShowWaitDialog("Search", true))
{
monitor.Progress = double.NaN; // progress not implemented, use indeterminate progress
SearchReplaceManager.FindNext(monitor);
// SearchReplaceManager.FindNext(monitor);
}
}
Focus();
@ -129,11 +131,8 @@ namespace SearchAndReplace @@ -129,11 +131,8 @@ namespace SearchAndReplace
RunAllInSelection(0);
}
} else {
using (AsynchronousWaitDialog monitor = AsynchronousWaitDialog.ShowWaitDialog("Search", true))
{
monitor.Progress = double.NaN; // progress not implemented, use indeterminate progress
SearchInFilesManager.FindAll(monitor);
}
var results = SearchManager.FindAll(SearchOptions.FindPattern, !SearchOptions.MatchCase, SearchOptions.MatchWholeWord, SearchOptions.SearchStrategyType, SearchOptions.DocumentIteratorType, SearchOptions.LookIn, SearchOptions.LookInFiletypes, SearchOptions.IncludeSubdirectories);
SearchResultsPad.Instance.ShowSearchResults("Search", results);
}
}
@ -148,7 +147,7 @@ namespace SearchAndReplace @@ -148,7 +147,7 @@ namespace SearchAndReplace
using (AsynchronousWaitDialog monitor = AsynchronousWaitDialog.ShowWaitDialog("Search", true))
{
monitor.Progress = double.NaN; // progress not implemented, use indeterminate progress
SearchReplaceManager.MarkAll(monitor);
// SearchReplaceManager.MarkAll(monitor);
}
}
}
@ -164,7 +163,7 @@ namespace SearchAndReplace @@ -164,7 +163,7 @@ namespace SearchAndReplace
using (AsynchronousWaitDialog monitor = AsynchronousWaitDialog.ShowWaitDialog("Search", true))
{
monitor.Progress = double.NaN; // progress not implemented, use indeterminate progress
SearchReplaceManager.ReplaceAll(monitor);
// SearchReplaceManager.ReplaceAll(monitor);
}
}
}
@ -180,7 +179,7 @@ namespace SearchAndReplace @@ -180,7 +179,7 @@ namespace SearchAndReplace
using (AsynchronousWaitDialog monitor = AsynchronousWaitDialog.ShowWaitDialog("Search", true))
{
monitor.Progress = double.NaN; // progress not implemented, use indeterminate progress
SearchReplaceManager.Replace(monitor);
// SearchReplaceManager.Replace(monitor);
}
}
Focus();
@ -202,11 +201,11 @@ namespace SearchAndReplace @@ -202,11 +201,11 @@ namespace SearchAndReplace
SearchOptions.MatchWholeWord = Get<CheckBox>("matchWholeWord").Checked;
SearchOptions.IncludeSubdirectories = Get<CheckBox>("includeSubFolder").Checked;
SearchOptions.SearchStrategyType = (SearchStrategyType)Get<ComboBox>("use").SelectedIndex;
SearchOptions.SearchStrategyType = (SearchMode)Get<ComboBox>("use").SelectedIndex;
if (Get<ComboBox>("lookIn").DropDownStyle == ComboBoxStyle.DropDown) {
SearchOptions.DocumentIteratorType = DocumentIteratorType.Directory;
SearchOptions.DocumentIteratorType = SearchTarget.Directory;
} else {
SearchOptions.DocumentIteratorType = (DocumentIteratorType)Get<ComboBox>("lookIn").SelectedIndex;
SearchOptions.DocumentIteratorType = (SearchTarget)Get<ComboBox>("lookIn").SelectedIndex;
}
}
@ -246,14 +245,14 @@ namespace SearchAndReplace @@ -246,14 +245,14 @@ namespace SearchAndReplace
Get<ComboBox>("lookIn").Items.Add(SearchOptions.LookIn);
Get<ComboBox>("lookIn").SelectedIndexChanged += new EventHandler(LookInSelectedIndexChanged);
if (IsMultipleLineSelection(SearchReplaceUtilities.GetActiveTextEditor())) {
DocumentIteratorType = DocumentIteratorType.CurrentSelection;
} else {
if (SearchOptions.DocumentIteratorType == DocumentIteratorType.CurrentSelection) {
SearchOptions.DocumentIteratorType = DocumentIteratorType.CurrentDocument;
}
DocumentIteratorType = SearchOptions.DocumentIteratorType;
}
// if (IsMultipleLineSelection(SearchReplaceUtilities.GetActiveTextEditor())) {
// SearchTarget = SearchTarget.CurrentSelection;
// } else {
// if (SearchOptions.DocumentIteratorType == SearchTarget.CurrentSelection) {
// SearchOptions.DocumentIteratorType = SearchTarget.CurrentDocument;
// }
// SearchTarget = SearchOptions.DocumentIteratorType;
// }
Get<ComboBox>("fileTypes").Text = SearchOptions.LookInFiletypes;
Get<CheckBox>("matchCase").Checked = SearchOptions.MatchCase;
@ -265,10 +264,10 @@ namespace SearchAndReplace @@ -265,10 +264,10 @@ namespace SearchAndReplace
Get<ComboBox>("use").Items.Add(StringParser.Parse("${res:Dialog.NewProject.SearchReplace.SearchStrategy.RegexSearch}"));
Get<ComboBox>("use").Items.Add(StringParser.Parse("${res:Dialog.NewProject.SearchReplace.SearchStrategy.WildcardSearch}"));
switch (SearchOptions.SearchStrategyType) {
case SearchStrategyType.RegEx:
case SearchMode.RegEx:
Get<ComboBox>("use").SelectedIndex = 1;
break;
case SearchStrategyType.Wildcard:
case SearchMode.Wildcard:
Get<ComboBox>("use").SelectedIndex = 2;
break;
default:
@ -299,7 +298,7 @@ namespace SearchAndReplace @@ -299,7 +298,7 @@ namespace SearchAndReplace
bool IsSelectionSearch {
get {
return DocumentIteratorType == DocumentIteratorType.CurrentSelection;
return SearchTarget == SearchTarget.CurrentSelection;
}
}
@ -327,9 +326,9 @@ namespace SearchAndReplace @@ -327,9 +326,9 @@ namespace SearchAndReplace
ignoreSelectionChanges = true;
if (findFirst) {
findFirst = false;
SearchReplaceManager.FindFirstInSelection(startOffset, endOffset - startOffset, null);
// SearchReplaceManager.FindFirstInSelection(startOffset, endOffset - startOffset, null);
} else {
findFirst = !SearchReplaceManager.FindNextInSelection(null);
// findFirst = !SearchReplaceManager.FindNextInSelection(null);
if (findFirst) {
textEditor.Select(startOffset, endOffset - startOffset);
}
@ -344,20 +343,20 @@ namespace SearchAndReplace @@ -344,20 +343,20 @@ namespace SearchAndReplace
/// </summary>
static StoredSelection GetCurrentTextSelection()
{
ITextEditor textArea = SearchReplaceUtilities.GetActiveTextEditor();
if (textArea != null) {
return new StoredSelection(textArea.SelectionStart, textArea.SelectionLength);
}
// ITextEditor textArea = SearchReplaceUtilities.GetActiveTextEditor();
// if (textArea != null) {
// return new StoredSelection(textArea.SelectionStart, textArea.SelectionLength);
// }
return null;
}
void WorkbenchActiveViewContentChanged(object source, EventArgs e)
{
ITextEditor activeTextEditorControl = SearchReplaceUtilities.GetActiveTextEditor();
if (activeTextEditorControl != this.textEditor) {
AddSelectionChangedHandler(activeTextEditorControl);
TextSelectionChanged(source, e);
}
// ITextEditor activeTextEditorControl = SearchReplaceUtilities.GetActiveTextEditor();
// if (activeTextEditorControl != this.textEditor) {
// AddSelectionChangedHandler(activeTextEditorControl);
// TextSelectionChanged(source, e);
// }
}
void AddSelectionChangedHandler(ITextEditor textEditor)
@ -402,7 +401,7 @@ namespace SearchAndReplace @@ -402,7 +401,7 @@ namespace SearchAndReplace
{
findFirst = true;
selection = GetCurrentTextSelection();
AddSelectionChangedHandler(SearchReplaceUtilities.GetActiveTextEditor());
// AddSelectionChangedHandler(SearchReplaceUtilities.GetActiveTextEditor());
WorkbenchSingleton.Workbench.ActiveViewContentChanged += WorkbenchActiveViewContentChanged;
}
@ -424,22 +423,22 @@ namespace SearchAndReplace @@ -424,22 +423,22 @@ namespace SearchAndReplace
textEditor.Select(startOffset, endOffset - startOffset);
try {
ignoreSelectionChanges = true;
if (action == 0) {
SearchInFilesManager.FindAll(startOffset, endOffset - startOffset, monitor);
} else if (action == 1) {
SearchReplaceManager.MarkAll(startOffset, endOffset - startOffset, monitor);
} else if (action == 2) {
// use anchor for endOffset because the replacement might change the text length
var anchor = textEditor.Document.CreateAnchor(endOffset);
SearchReplaceManager.ReplaceAll(startOffset, endOffset - startOffset, monitor);
endOffset = anchor.Offset;
}
textEditor.Select(startOffset, endOffset - startOffset);
} finally {
ignoreSelectionChanges = false;
}
// try {
// ignoreSelectionChanges = true;
// if (action == 0) {
// SearchInFilesManager.FindAll(startOffset, endOffset - startOffset, monitor);
// } else if (action == 1) {
// SearchReplaceManager.MarkAll(startOffset, endOffset - startOffset, monitor);
// } else if (action == 2) {
// // use anchor for endOffset because the replacement might change the text length
// var anchor = textEditor.Document.CreateAnchor(endOffset);
// SearchReplaceManager.ReplaceAll(startOffset, endOffset - startOffset, monitor);
// endOffset = anchor.Offset;
// }
// textEditor.Select(startOffset, endOffset - startOffset);
// } finally {
// ignoreSelectionChanges = false;
// }
}
void ReplaceInSelection()
@ -451,20 +450,20 @@ namespace SearchAndReplace @@ -451,20 +450,20 @@ namespace SearchAndReplace
textEditor.Caret.Offset = startOffset;
}
try {
ignoreSelectionChanges = true;
if (findFirst) {
findFirst = false;
SearchReplaceManager.ReplaceFirstInSelection(startOffset, endOffset - startOffset, null);
} else {
findFirst = !SearchReplaceManager.ReplaceNextInSelection(null);
if (findFirst) {
textEditor.Select(startOffset, endOffset - startOffset);
}
}
} finally {
ignoreSelectionChanges = false;
}
// try {
// ignoreSelectionChanges = true;
// if (findFirst) {
// findFirst = false;
// SearchReplaceManager.ReplaceFirstInSelection(startOffset, endOffset - startOffset, null);
// } else {
// findFirst = !SearchReplaceManager.ReplaceNextInSelection(null);
// if (findFirst) {
// textEditor.Select(startOffset, endOffset - startOffset);
// }
// }
// } finally {
// ignoreSelectionChanges = false;
// }
}
/// <summary>

26
src/AddIns/Misc/SearchAndReplace/Project/SearchAndReplace.csproj

@ -69,27 +69,8 @@ @@ -69,27 +69,8 @@
</Compile>
<Compile Include="Commands\SearchMainMenuCommands.cs" />
<Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="Engine\DocumentIterator\AllOpenDocumentIterator.cs" />
<Compile Include="Engine\DocumentIterator\CurrentDocumentIterator.cs" />
<Compile Include="Engine\DocumentIterator\DirectoryDocumentIterator.cs" />
<Compile Include="Engine\DocumentIterator\IDocumentIterator.cs" />
<Compile Include="Engine\DocumentIterator\WholeProjectDocumentIterator.cs" />
<Compile Include="Engine\DocumentIterator\WholeSolutionDocumentIterator.cs" />
<Compile Include="Engine\ITextIteratorBuilder.cs" />
<Compile Include="Engine\Search.cs" />
<Compile Include="Engine\SearchReplaceInFilesManager.cs" />
<Compile Include="Engine\SearchReplaceManager.cs" />
<Compile Include="Engine\SearchReplaceUtilities.cs" />
<Compile Include="Engine\SearchStrategy\BoyerMooreSearchStrategy.cs" />
<Compile Include="Engine\SearchStrategy\BruteForceSearchStrategy.cs" />
<Compile Include="Engine\SearchStrategy\ISearchStrategy.cs" />
<Compile Include="Engine\SearchStrategy\KMPSearchStrategy.cs" />
<Compile Include="Engine\SearchStrategy\RegExSearchStrategy.cs" />
<Compile Include="Engine\SearchStrategy\WildcardSearchStrategy.cs" />
<Compile Include="Engine\TextIterator\ForwardTextIterator.cs" />
<Compile Include="Engine\TextIterator\ForwardTextIteratorBuilder.cs" />
<Compile Include="Engine\TextIterator\ITextIterator.cs" />
<Compile Include="Engine\TextSelection.cs" />
<Compile Include="Engine\Enums.cs" />
<Compile Include="Engine\SearchManager.cs" />
<Compile Include="Gui\DefaultSearchResult.cs" />
<Compile Include="Gui\ResultsTreeView.cs">
<SubType>Code</SubType>
@ -106,9 +87,6 @@ @@ -106,9 +87,6 @@
<ItemGroup>
<Folder Include="Commands" />
<Folder Include="Engine" />
<Folder Include="Engine\DocumentIterator" />
<Folder Include="Engine\SearchStrategy" />
<Folder Include="Engine\TextIterator" />
<Folder Include="Gui" />
<Folder Include="Resources" />
<ProjectReference Include="..\..\..\..\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">

17
src/AddIns/Misc/SearchAndReplace/Project/SearchOptions.cs

@ -2,16 +2,11 @@ @@ -2,16 +2,11 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.AvalonEdit.Search;
using ICSharpCode.Core;
namespace SearchAndReplace
{
public enum SearchStrategyType {
Normal,
RegEx,
Wildcard
}
public static class SearchOptions
{
const string searchPropertyKey = "SearchAndReplaceProperties";
@ -141,20 +136,20 @@ namespace SearchAndReplace @@ -141,20 +136,20 @@ namespace SearchAndReplace
}
}
public static DocumentIteratorType DocumentIteratorType {
public static SearchTarget DocumentIteratorType {
get {
return properties.Get("DocumentIteratorType", DocumentIteratorType.CurrentDocument);
return properties.Get("DocumentIteratorType", SearchTarget.CurrentDocument);
}
set {
if (!Enum.IsDefined(typeof(DocumentIteratorType), value))
if (!Enum.IsDefined(typeof(SearchTarget), value))
throw new ArgumentException("invalid enum value");
properties.Set("DocumentIteratorType", value);
}
}
public static SearchStrategyType SearchStrategyType {
public static SearchMode SearchStrategyType {
get {
return properties.Get("SearchStrategyType", SearchStrategyType.Normal);
return properties.Get("SearchStrategyType", SearchMode.Normal);
}
set {
properties.Set("SearchStrategyType", value);

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/ISearchStrategy.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.AvalonEdit.Search @@ -18,7 +18,7 @@ namespace ICSharpCode.AvalonEdit.Search
/// Finds all matches for a predicate in the given ITextSource.
/// </summary>
/// <remarks>This method is thread-safe.</remarks>
IEnumerable<ISearchResult> FindAll(ITextSource document);
IEnumerable<ISearchResult> FindAll(ITextSource document, ISegment selection = null);
}
/// <summary>
@ -32,7 +32,7 @@ namespace ICSharpCode.AvalonEdit.Search @@ -32,7 +32,7 @@ namespace ICSharpCode.AvalonEdit.Search
/// <summary>
/// Defines supported search modes.
/// </summary>
public enum SearchType
public enum SearchMode
{
/// <summary>
/// Standard search

5
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/RegexSearchStrategy.cs

@ -18,10 +18,11 @@ namespace ICSharpCode.AvalonEdit.Search @@ -18,10 +18,11 @@ namespace ICSharpCode.AvalonEdit.Search
this.searchPattern = searchPattern;
}
public IEnumerable<ISearchResult> FindAll(ITextSource document)
public IEnumerable<ISearchResult> FindAll(ITextSource document, ISegment selection = null)
{
foreach (Match result in searchPattern.Matches(document.Text)) {
yield return new SearchResult { StartOffset = result.Index, Length = result.Length };
if (selection == null || (selection.Offset <= result.Index && selection.EndOffset >= (result.Index + result.Length)))
yield return new SearchResult { StartOffset = result.Index, Length = result.Length };
}
}
}

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.xaml.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.AvalonEdit.Search @@ -52,7 +52,7 @@ namespace ICSharpCode.AvalonEdit.Search
void UpdateSearch()
{
messageView.IsOpen = false;
strategy = SearchStrategyFactory.Create(searchPattern ?? "", !MatchCase, WholeWords, UseRegex ? SearchType.RegEx : SearchType.Normal);
strategy = SearchStrategyFactory.Create(searchPattern ?? "", !MatchCase, WholeWords, UseRegex ? SearchMode.RegEx : SearchMode.Normal);
DoSearch(true);
}

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchStrategyFactory.cs

@ -5,6 +5,7 @@ using System; @@ -5,6 +5,7 @@ using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Controls;
using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.AvalonEdit.Search
{
@ -16,7 +17,7 @@ namespace ICSharpCode.AvalonEdit.Search @@ -16,7 +17,7 @@ namespace ICSharpCode.AvalonEdit.Search
/// <summary>
/// Creates a default ISearchStrategy with the given parameters.
/// </summary>
public static ISearchStrategy Create(string searchPattern, bool ignoreCase, bool matchWholeWords, SearchType searchType)
public static ISearchStrategy Create(string searchPattern, bool ignoreCase, bool matchWholeWords, SearchMode mode)
{
if (searchPattern == null)
throw new ArgumentNullException("searchPattern");
@ -24,11 +25,11 @@ namespace ICSharpCode.AvalonEdit.Search @@ -24,11 +25,11 @@ namespace ICSharpCode.AvalonEdit.Search
if (ignoreCase)
options |= RegexOptions.IgnoreCase;
switch (searchType) {
case SearchType.Normal:
switch (mode) {
case SearchMode.Normal:
searchPattern = Regex.Escape(searchPattern);
break;
case SearchType.Wildcard:
case SearchMode.Wildcard:
searchPattern = ConvertWildcardsToRegex(searchPattern);
break;
}

2
src/Main/Base/Project/Src/Editor/Search/ISearchResultFactory.cs

@ -12,5 +12,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search @@ -12,5 +12,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
public interface ISearchResultFactory
{
ISearchResult CreateSearchResult(string title, IEnumerable<SearchResultMatch> matches);
ISearchResult CreateSearchResult(string title, IObservable<SearchResultMatch> matches);
}
}

20
src/Main/Base/Project/Src/Editor/Search/SearchResultsPad.cs

@ -104,6 +104,11 @@ namespace ICSharpCode.SharpDevelop.Editor.Search @@ -104,6 +104,11 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
ShowSearchResults(CreateSearchResult(title, matches));
}
public void ShowSearchResults(string title, IObservable<SearchResultMatch> matches)
{
ShowSearchResults(CreateSearchResult(title, matches));
}
public event EventHandler SearchResultsShown;
public static ISearchResult CreateSearchResult(string title, IEnumerable<SearchResultMatch> matches)
@ -120,6 +125,21 @@ namespace ICSharpCode.SharpDevelop.Editor.Search @@ -120,6 +125,21 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
return new DummySearchResult { Text = title };
}
public static ISearchResult CreateSearchResult(string title, IObservable<SearchResultMatch> matches)
{
if (title == null)
throw new ArgumentNullException("title");
if (matches == null)
throw new ArgumentNullException("matches");
foreach (ISearchResultFactory factory in AddInTree.BuildItems<ISearchResultFactory>("/SharpDevelop/Pads/SearchResultPad/Factories", null, false)) {
ISearchResult result = factory.CreateSearchResult(title, matches);
if (result != null)
return result;
}
return new DummySearchResult { Text = title };
}
sealed class DummySearchResult : ISearchResult
{
public string Text {

39
src/Main/Base/Project/Src/Services/MimeTypeDetection.cs

@ -2,12 +2,16 @@ @@ -2,12 +2,16 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace ICSharpCode.SharpDevelop
{
public static class MimeTypeDetection
{
const int BUFFER_SIZE = 4 * 1024;
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
static extern unsafe int FindMimeFromData(
IntPtr pBC,
@ -19,12 +23,15 @@ namespace ICSharpCode.SharpDevelop @@ -19,12 +23,15 @@ namespace ICSharpCode.SharpDevelop
out IntPtr ppwzMimeOut,
int dwReserved);
public static unsafe string FindMimeType(byte[] buffer)
static unsafe string FindMimeType(byte[] buffer, int offset, int length)
{
fixed (byte *b = buffer) {
if (buffer.Length == 0)
return "text/plain";
fixed (byte *b = &buffer[offset]) {
const int FMFD_ENABLEMIMESNIFFING = 0x00000002;
IntPtr mimeout;
int result = FindMimeFromData(IntPtr.Zero, null, b, buffer.Length, null, FMFD_ENABLEMIMESNIFFING, out mimeout, 0);
int result = FindMimeFromData(IntPtr.Zero, null, b, length, null, FMFD_ENABLEMIMESNIFFING, out mimeout, 0);
if (result != 0)
throw Marshal.GetExceptionForHR(result);
@ -33,5 +40,31 @@ namespace ICSharpCode.SharpDevelop @@ -33,5 +40,31 @@ namespace ICSharpCode.SharpDevelop
return mime;
}
}
public static string FindMimeType(byte[] buffer)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
return FindMimeType(buffer, 0, buffer.Length);
}
public static string FindMimeType(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
byte[] buffer = new byte[BUFFER_SIZE];
stream.Position = 0;
return FindMimeType(buffer, 0, stream.Read(buffer, 0, buffer.Length));
}
public static string FindMimeType(ITextBuffer buffer)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
// TODO USE PROPER ENCODING!
// Maybe use Encoding detection from AvalonEdit?
byte[] bytes = Encoding.Default.GetBytes(buffer.TextLength > BUFFER_SIZE ? buffer.GetText(0, BUFFER_SIZE) : buffer.Text);
return FindMimeType(bytes, 0, bytes.Length);
}
}
}

Loading…
Cancel
Save