|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe "Search and Replace" and "Search in files" in VS.NET support Regular Expression, but the kind of Regular Expression is weak and wired. For instance, it uses some strange symbols like :z, :Lu, and doesn't support position-match like ?!>, ?=. Standard Regular Expression Searcher Add-in has the same functions with "Search and Replace" and "Search in files", and support standard Regular Expression, so by using it, you can take advantage of the power of standard Regular Expression and the convenient usability of VS.NET, and it provides some functions that VS.NET has not, for example, show the context of matched content. BackgroundIn The Code Project, there are a lot of articles involving how to write VS.NET add-ins, so we don't repeat it. We just use Using the Add-inAfter installing the add-in, You can find a menu item in Tools that is named SearcherAddin, and click it, and then write Regular Expression into the text box for Search. Click "Replace" button, you can write Regular Expression for replacing to the textbox for Replace. In "Search Scope", if you select "Active Document" or "All of opened files", the add-in works like "Find and Replace" of VS.NET; if you select "Current project" or "Whole solution" or click Browse button, it works like "Find in files", and executes the command once and closes, and then shows the results into If you input "Font Lines" and "Back Lines", the add-in will show the context front and back lines of the matched text in How to show the results to WindowPaneThe "Find in Files" of VS.NET uses public class OutputWindowPaneWrapper
{
private OutputWindowPane pane;
private DTE dte;
...
We named the private void getWindowPane (string title) {
Window winItem = this.dte.Windows.Item (Constants.vsWindowKindOutput);
OutputWindow window = (OutputWindow) winItem.Object;
try {
this.pane = window.OutputWindowPanes.Item (title);
}
catch(System.ArgumentException) {
this.pane = window.OutputWindowPanes.Add (title);
}
}
In order to show public void Activate ()
{
dte.Windows.Item(Constants.vsWindowKindOutput).Activate();
this.pane.Activate();
}
Use State Pattern to implement different FindNext in TextWindowIn We defined public interface IFindState
{
void ShowMessage();
void FindNext(WindowSearcher windowSearcher);
}
We implemented concrete States by deriving from public class FirstFindState : IFindState {
public void ShowMessage(){
}
public void FindNext(WindowSearcher windowSearcher){
windowSearcher.SetSearchStartPoint();
if(windowSearcher.SearchInTextWindowOnce()) {
windowSearcher.SelectMatchedText();
windowSearcher.SetState(new FirstFindSucceededState());
}
else{
windowSearcher.MoveToStartInTextWindow();
windowSearcher.SetState(new FirstFindFailedState());
windowSearcher.SetLatestFindStartPosToStartOfDoc();
windowSearcher.FindNext();
}
}
}
public class FirstFindFailedState: IFindState {
public void ShowMessage() {
UIHelper.ShowInfo("Didn't find");
}
public void FindNext(WindowSearcher windowSearcher) {
if(windowSearcher.SearchInTextWindowOnce()){
windowSearcher.SelectMatchedText();
windowSearcher.SetState(new FirstSearchFailedAndSecondSucceededState());
}
else{
windowSearcher.ResetLatestFindStartPos();
windowSearcher.SetState(new FirstFindState());
ShowMessage();
}
}
}
public class WindowSearcher : Searcher {
private IFindState _state;
public void SetState(IFindState newState) {
_state = newState;
}
public void FindNext() {
setLatestFindStartPos();
_state.FindNext(this);
}
...
How to replace Text in TextWindowThe DTE component model provides three methods to replace text in private void tryToReplaceSelectedText(string replacePattern) {
TextSelection objSel = getTextSelection();
if(_matchedStartPoint == objSel.AnchorPoint.AbsoluteCharOffset
&& _matchedEndPoint == objSel.ActivePoint.AbsoluteCharOffset){
objSel.Text =
getReplaceText(_searchLatestEditPoint.GetText(getTextDocument().EndPoint),
replacePattern);
}
setLatestFindStartPos();
}
How to use Regular Expression in searching and replacingThe FCL of .NET Framework provides support for Regular Expressions, and it's pretty good. The namespace is public MatchInfo GetMatch() {
Regex rg = new Regex(_pattern, GetRegexOptions());
Match match = rg.IsMatch(_windowSource, _nextSearchStartPos);
if(!match.Success){
return null;
}
int startLine =
StringHandleHelp.GetLineCount(ref _windowSource, match.Index);
int startLineOffset =
StringHandleHelp.GetPosInLine(ref _windowSource, match.Index);
int endLine =
StringHandleHelp.GetLineCount(ref _windowSource,
match.Index + match.Length - 1);
int endLineOffset = StringHandleHelp.GetPosInLine(ref _windowSource,
match.Index + match.Length - 1);
return new MatchInfo(startLine, endLine, match.Value,
startLineOffset, match.Index, match.Length, endLineOffset);
}public string Replace(string source, string replacePattern){
Regex rg = new Regex(_pattern, GetRegexOptions());
return rg.Replace(source, replacePattern);
}
public string Replace(string source, string replacePattern, int startPos){
Regex rg = new Regex(_pattern, GetRegexOptions());
return rg.Replace(source, replacePattern, 1, startPos);
}
protected string replaceAll(string source,
string replacePattern, out int repeatCount)
{
Regex rg = new Regex(_pattern, GetRegexOptions());
repeatCount = rg.Matches(source).Count;
return repeatCount > 0?rg.Replace(source,
replacePattern):string.Empty;
}
|
||||||||||||||||||||||