34 changed files with 384 additions and 2407 deletions
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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() |
|
||||||
{ |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,16 +1,17 @@ |
|||||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
// 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)
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||||
|
|
||||||
using ICSharpCode.SharpDevelop.Editor.Search; |
|
||||||
using System; |
using System; |
||||||
|
|
||||||
namespace SearchAndReplace |
namespace SearchAndReplace |
||||||
{ |
{ |
||||||
/// <summary>
|
public enum SearchTarget |
||||||
/// Builds a text iterator object.
|
|
||||||
/// </summary>
|
|
||||||
public interface ITextIteratorBuilder |
|
||||||
{ |
{ |
||||||
ITextIterator BuildTextIterator(ProvidedDocumentInformation info); |
CurrentDocument, |
||||||
|
CurrentSelection, |
||||||
|
AllOpenFiles, |
||||||
|
WholeProject, |
||||||
|
WholeSolution, |
||||||
|
Directory |
||||||
} |
} |
||||||
} |
} |
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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); |
|
||||||
} |
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue