Click here to Skip to main content
15,879,535 members
Articles / Programming Languages / C#

Standard Regular Expression Searcher Addin For VS.NET 2003

Rate me:
Please Sign up or sign in to vote.
4.88/5 (42 votes)
11 Jan 2005CPOL3 min read 106.9K   930   52  
Standard Regular Expression Searcher add-in for VS.NET 2003.
using System;
using EnvDTE;
using System.Text.RegularExpressions;
using SearcherAddIn.FindState;
using System.Diagnostics;
using SearcherAddIn.Helper;

namespace SearcherAddIn {
	/// <summary>
	/// Summary description for WindowSearcher.
	/// </summary>
	public class WindowSearcher : Searcher {
		private EditPoint _serachStartEditPoint = null;
		private EditPoint _searchLatestEditPoint = null;	

		private int _nextMatchTextStartLine;
		private int _nextMatchTextStartLineCharOffset;
		private int _nextMatchTextEndLine;
		private int _nextMatchTextEndLineCharOffset;
		
		private int _matchedStartPoint;
		private int _matchedEndPoint;
		public WindowSearcher(_DTE dte) : base(dte)	{
		}

		public override string Pattern {
			get {
				return base.Pattern;
			}
			set {
				if(base.Pattern != value){
					base.Pattern = value;
					_state = new FirstFindState();
				}
			}
		}

		private string _windowSource;
		public string WindowSource {
			set{_windowSource = value;}
		}

		public override void SetRegexOpetions(bool isSingleLine, bool isMultipleLine, bool isIgnoreCase, bool isECMAScript) {
			RegexOptions regexOptions = RegexOptions.None;
			if(isSingleLine) regexOptions |= RegexOptions.Singleline;
			if(isMultipleLine) regexOptions |= RegexOptions.Multiline;
			if(isIgnoreCase) regexOptions |= RegexOptions.IgnoreCase;
			if(isECMAScript) regexOptions |= RegexOptions.ECMAScript;
			if(base.RegexOptions != regexOptions) {
				base.RegexOptions = regexOptions;
				_state = new FirstFindState();
			}
		}

		
		private IFindState _state;
		public void SetState(IFindState newState) {
			_state = newState;
		}
		
		public void FindNext() {
			setLatestFindStartPos();
			_state.FindNext(this);
		}

		public void SetSearchStartPoint() {
			TextSelection objSel = _dte.ActiveDocument.Selection as TextSelection;
			_serachStartEditPoint = objSel.ActivePoint.CreateEditPoint();
		}

		public void MoveToStartInTextWindow() {
			TextSelection objSel = getTextSelection();
			objSel.MoveToPoint(getTextDocument().StartPoint, false);
		}

		private int _nextSearchStartPos;
		public int NextSearchStartPos {
			set{_nextSearchStartPos = value;}
		}

		public MatchInfo GetMatch() {
			Regex rg = new Regex(_pattern, GetRegexOptions());
			Match match = rg.Match(_windowSource, _nextSearchStartPos);
			if(!match.Success){
				return null;
			}

			int startLine = StringHandleHelp.GetLineCount(ref _windowSource, match.Index); 
			int startLineOffset = StringHandleHelp.GetPosInLine(ref _windowSource, match.Index - 1);
			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 bool SearchInTextWindowOnce() {
			TextSelection objSel = getTextSelection();
			int activePointLine = objSel.ActivePoint.Line;
			int activePointLineCharOffset = objSel.ActivePoint.LineCharOffset;
			_windowSource = objSel.ActivePoint.CreateEditPoint().GetText(getTextDocument().EndPoint);
			MatchInfo match = GetMatch();
			if(match == null)
				return false;

			if(match.MatchContent.Length > 0) {
				if(match.StartLine == 1 && match.EndLine == match.StartLine) {
					_nextMatchTextStartLine = activePointLine;
					_nextMatchTextStartLineCharOffset = activePointLineCharOffset + match.StartLineOffset;
					_nextMatchTextEndLine = activePointLine + match.EndLine - 1;
					_nextMatchTextEndLineCharOffset = activePointLineCharOffset + match.EndLineOffset;
				}
				else {
					_nextMatchTextStartLine = activePointLine + match.StartLine - 1;
					_nextMatchTextStartLineCharOffset = match.StartLineOffset + 1;
					_nextMatchTextEndLine = activePointLine + match.EndLine - 1;
					_nextMatchTextEndLineCharOffset = match.EndLineOffset + 1;
				}
				return true;
			}
			return false;
		}
		
		public void SelectMatchedText() {
			TextSelection objSel = getTextSelection();
			objSel.MoveToLineAndOffset(_nextMatchTextStartLine, _nextMatchTextStartLineCharOffset, false);
			objSel.MoveToLineAndOffset(_nextMatchTextEndLine, _nextMatchTextEndLineCharOffset, true);
		}

		public bool IsGoAcrossStartPoint() {
			TextSelection objSel = _dte.ActiveDocument.Selection as TextSelection;
			return ((_nextMatchTextStartLine > _serachStartEditPoint.Line) || 
				(_nextMatchTextStartLine == _serachStartEditPoint.Line && _nextMatchTextStartLineCharOffset >= _serachStartEditPoint.LineCharOffset));
		}

		public void ReplaceNext(string replacePattern) {
			if(_searchLatestEditPoint == null){
				setLatestFindStartPos();
				FindNext();
			}
			else{
				tryToReplaceSelectedText(replacePattern);
				FindNext();
			}
			saveMatchedPostion();
		}

		private void saveMatchedPostion(){
			TextSelection objSel = getTextSelection();
			_matchedStartPoint = objSel.AnchorPoint.AbsoluteCharOffset;
			_matchedEndPoint = objSel.ActivePoint.AbsoluteCharOffset;
		}

		public int ReplaceAll(string replacePattern, bool isReplaceInOpenFiles) {
			SetSearchStartPoint();
			MoveToStartInTextWindow();
			TextSelection objSel = getTextSelection();
			TextDocument objTD = getTextDocument();
			
			string wholeWindowText = objSel.ActivePoint.CreateEditPoint().GetText(getTextDocument().EndPoint);
			
			EditPoint editPoint = objSel.ActivePoint.CreateEditPoint();
			TextPoint endPoint = objTD.EndPoint.CreateEditPoint();
			const int vsEPReplaceTextAutoformat = 3;// vsEPReplaceTextOptions.vsEPReplaceTextAutoformat);
			int repeatCount;
			string replaceWindowText = base.replaceAll(wholeWindowText, replacePattern, out repeatCount);
			if(repeatCount > 0) {
				editPoint.ReplaceText(endPoint, base.Replace(wholeWindowText, replacePattern), vsEPReplaceTextAutoformat);
				if(!isReplaceInOpenFiles)
					UIHelper.ShowInfo(repeatCount + " replaces happenned");
			}
			objSel.MoveToPoint(_serachStartEditPoint, false);
			return repeatCount;
		}
		
		private TextSelection getTextSelection() {
			TextDocument objTD = getTextDocument();
			return _dte.ActiveDocument.Selection as TextSelection;
		}

		private TextDocument getTextDocument() {
			TextDocument activeDocument = null;
			try{
				activeDocument = _dte.ActiveDocument.Object(string.Empty) as TextDocument;
			}
			catch{;}

			if(activeDocument == null)
				throw new ApplicationException("There are no active text window");
			return activeDocument;
		}

		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();
		}

		public bool ReplaceNextInSearchInFiles(string replacePattern){
			if(_searchLatestEditPoint == null){
				SetLatestFindStartPosToStartOfDoc();
				return FindNextInSearchInFiles();
			}
			else{
				tryToReplaceSelectedText(replacePattern);		
				return FindNextInSearchInFiles();
			}
		}

		public bool FindNextInSearchInFiles(){
			setLatestFindStartPos();
			if(SearchInTextWindowOnce()){
				SelectMatchedText();
				saveMatchedPostion();
				return true;
			}
			ResetLatestFindStartPos();
			return false;
		}

		private void setLatestFindStartPos(){
			TextDocument objTD = getTextDocument();
			TextSelection objSel = getTextSelection();

			_searchLatestEditPoint = objSel.ActivePoint.CreateEditPoint();
		}

		public void ResetLatestFindStartPos(){
			_searchLatestEditPoint = null;
		}

		public void SetLatestFindStartPosToStartOfDoc(){
			getTextSelection().StartOfDocument(false);
			_searchLatestEditPoint = getTextSelection().ActivePoint.CreateEditPoint();
		}

		public string GetSelectionText(){
			string selectionText = string.Empty;
			try{
				TextSelection objSel = getTextSelection();
				selectionText = objSel.Text;
			}
			catch(ApplicationException){;}
			return selectionText;
		}

		private string getReplaceText(string source, string replacePattern){
			string replacingSource = source;
			Regex rg = new Regex(_pattern, GetRegexOptions());
			Match match = rg.Match(replacingSource);
			if(match.Success){
				string changedSource = rg.Replace(replacingSource, replacePattern, 1);
				int replaceTextStartPos = match.Index;//position in changedSource
				int replaceTextEndPos = changedSource.Length - (replacingSource.Length - match.Index - match.Length);//position in changedSource
				return changedSource.Substring(replaceTextStartPos,  replaceTextEndPos - replaceTextStartPos);
			}
			return string.Empty;
		}
	}
}

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

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

License

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


Written By
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions