/// <summary> /// 获取选中行 /// </summary> /// <returns></returns> public string GetSelectedLines() { TextSelection selectedText = _dte.ActiveDocument.Selection as TextSelection; TextPoint topPoint = selectedText.TopPoint; EditPoint bottomPoint = selectedText.BottomPoint.CreateEditPoint(); return(bottomPoint.GetLines(topPoint.Line, bottomPoint.Line + 1)); }
public string GetCode(out TextPoint startPoint) { var range = this.GetCodeRange(); EditPoint startEdit = range.Item1.CreateEditPoint(); string result = startEdit.GetLines(startEdit.Line, range.Item2.Line + 1); startPoint = startEdit; return(result); }
public void IndexGetterTests() { CSharpHardCodedString hcs = new CSharpHardCodedString(this.codeFile, 349, 362); TextDocument doc = ((EnvDTE.TextDocument) this.codeFile.Document.Object(null)); EditPoint ep = doc.StartPoint.CreateEditPoint(); string text = ep.GetLines(17, 18); Assert.AreEqual(text.IndexOf("\"Test\\\"\\\"\\n\\t\""), hcs.StartIndex); Assert.AreEqual(15, hcs.StartingLine); }
public void IndexGetterTests() { VBHardCodedString hcs = new VBHardCodedString(this.codeFile, 157, 172); TextDocument doc = ((EnvDTE.TextDocument) this.codeFile.Document.Object(null)); EditPoint ep = doc.StartPoint.CreateEditPoint(); string text = ep.GetLines(9, 10); Assert.AreEqual(text.IndexOf("\"Test Instance\""), hcs.StartIndex); Assert.AreEqual(text.IndexOf("\"Test Instance\"") + "\"Test Instance\"".Length, hcs.EndIndex); Assert.AreEqual(8, hcs.StartingLine); }
internal static void InsertBlankLineAfterPoint(EditPoint point) { if (point.AtEndOfDocument) return; point.LineDown(1); point.StartOfLine(); string text = point.GetLines(point.Line, point.Line + 1); if (Regex.IsMatch(text, @"^\s*[^\s\}]")) { point.Insert(Environment.NewLine); } }
public string GetCurrentWord() { var selectedText = _dte.ActiveDocument.Selection as TextSelection; if (selectedText != null) { EditPoint topPoint = selectedText.TopPoint.CreateEditPoint(); string currentLine = topPoint.GetLines(topPoint.Line, topPoint.Line + 1); if (IsBlank(currentLine)) { return(string.Empty); } string result; int charIndex = topPoint.LineCharOffset - 1; if (topPoint.AtStartOfLine || (!char.IsWhiteSpace(currentLine[charIndex]) && char.IsWhiteSpace(currentLine[charIndex - 1]))) { EditPoint rightPoint = topPoint.CreateEditPoint(); rightPoint.WordRight(); result = currentLine.Substring(topPoint.LineCharOffset - 1, rightPoint.LineCharOffset - topPoint.LineCharOffset).Trim(); } else if (topPoint.AtEndOfLine || (!char.IsWhiteSpace(currentLine[charIndex - 1]) && char.IsWhiteSpace(currentLine[charIndex]))) { EditPoint leftPoint = topPoint.CreateEditPoint(); leftPoint.WordLeft(); result = currentLine.Substring(leftPoint.LineCharOffset - 1, topPoint.LineCharOffset - leftPoint.LineCharOffset).Trim(); } else if (char.IsLetterOrDigit(currentLine[charIndex - 1]) && char.IsLetterOrDigit(currentLine[charIndex + 1])) { topPoint.WordLeft(); EditPoint rightPoint = topPoint.CreateEditPoint(); rightPoint.WordRight(); result = currentLine.Substring(topPoint.LineCharOffset - 1, rightPoint.LineCharOffset - topPoint.LineCharOffset); } else { result = GetSelectedText(); } return(result); } return(string.Empty); }
internal static void InsertBlankLineBeforePoint(EditPoint point) { if (point.Line <= 1) return; point.LineUp(1); point.StartOfLine(); string text = point.GetLines(point.Line, point.Line + 1); if (Regex.IsMatch(text, @"^\s*[^\s\{]")) { point.EndOfLine(); point.Insert(Environment.NewLine); } }
private void ReadModelines(TextDocument td, Settings settings) { int totalLines = td.EndPoint.Line - td.StartPoint.Line + 1; int readLines = totalLines > kMaxLines ? kMaxLines : totalLines; EditPoint ep = td.StartPoint.CreateEditPoint(); string text = ep.GetLines(1, readLines); string[] lines = text.Split(new[] { '\r', '\n' }); for (int i = 0; i < lines.Length; i++) { string line = lines[i].Trim(); DetectVimModeline(settings, line); } }
/// <summary> /// 获取触发行的代码 /// </summary> /// <param name="dte"></param> /// <returns></returns> public static string GetSelectRowCode(DTE2 dte) { // 触发内容 var selection = (TextSelection)dte.ActiveDocument.Selection; // 触发起始点 EditPoint editPoint = selection.AnchorPoint.CreateEditPoint(); // 选中触发行 string code = editPoint.GetLines(editPoint.Line, editPoint.Line + 1); // 多行转成一行 code = Regex.Replace(code, @"\s+", s => " "); return(code.Trim()); }
/// <summary> /// Checks the document in the window for preprocessor directives. /// </summary> /// <param name="ideWindow">The window of the document to check.</param> /// <returns>True if there are preprocessor directives present.</returns> private bool CheckForPreprocessorDirectives(EnvDTE.Window ideWindow) { TextDocument doc = (TextDocument)ideWindow.Document.Object("TextDocument"); EditPoint editPoint = doc.CreateEditPoint(doc.StartPoint); while (!editPoint.AtEndOfDocument) { if (editPoint.GetLines(editPoint.Line, editPoint.Line + 1).StartsWith("#")) { return(true); } editPoint.LineDown(1); } return(false); }
public EditedLine GetEditedLine() { TextSelection textSelection = _document.Selection; if (!String.IsNullOrEmpty(textSelection.Text)) { return(new EditedLine(textSelection.Text, 0)); } VirtualPoint point = textSelection.ActivePoint; EditPoint editPoint = point.CreateEditPoint(); string line = editPoint.GetLines(point.Line, point.Line + 1); int caret = point.LineCharOffset - 1; return(new EditedLine(line, caret)); }
private Tuple <TextPoint, TextPoint> GetCodeRange() { // The C# and VB code models don't return comments with vsCMPartWholeWithAttributes // (even though some of the member types have Comment and DocComment properties // and the code model's RemoveMember will remove the comments). So we have to // grab any attached comment lines manually. TextPoint startPoint = this.element.GetStartPoint(vsCMPart.vsCMPartWholeWithAttributes); TextPoint endPoint = this.element.GetEndPoint(vsCMPart.vsCMPartWholeWithAttributes); Regex commentRegex; switch (this.language) { case Language.CSharp: // Look for lines starting with optional whitespace followed by //, /*, */, or *. commentRegex = new Regex(@"^\s*(//|/\*|\*/|\*)"); break; case Language.VB: // Look for lines starting with optional whitespace followed by '. commentRegex = new Regex(@"^\s*'"); break; default: throw new NotSupportedException("Unsupported language: " + this.language); } EditPoint startEdit = startPoint.CreateEditPoint(); startEdit.LineUp(); while (!startEdit.AtStartOfDocument && commentRegex.IsMatch(startEdit.GetLines(startEdit.Line, startEdit.Line + 1))) { startEdit.LineUp(); startEdit.StartOfLine(); } startEdit.LineDown(); startEdit.StartOfLine(); Tuple <TextPoint, TextPoint> result = Tuple.Create((TextPoint)startEdit, endPoint); return(result); }
private static void SelectInnerDefinition(TextSelection selection, TextDocument document) { EditPoint pt = document.CreateEditPoint(); int startPos = selection.ActivePoint.Line; int currentLine = startPos; bool IsCssRule(int lineNum) { string line = pt.GetLines(lineNum, lineNum + 1); // We reached the edge of element styles definition. if (line.Contains('}') || line.Contains('{')) { return(false); } // Current line does not contain any CSS rules, break to support invalid/incomplete files. if (!line.Contains(':')) { return(false); } return(true); } // Find the start of styles definition block. while (IsCssRule(currentLine) && currentLine-- > 0) { ; } selection.MoveToLineAndOffset(currentLine + 1, 1, false); currentLine = startPos; // Find the end of styles definition block. while (IsCssRule(currentLine) && ++currentLine < document.EndPoint.Line) { ; } selection.MoveToLineAndOffset(currentLine, 1, true); }
/// <summary> /// 获取触发行的代码 /// </summary> /// <param name="dte"></param> /// <returns></returns> public static string GetSelection(DTE2 dte) { // 触发内容 var selection = (TextSelection)dte.ActiveDocument.Selection; string code = selection.Text; // 没有选中内容则获取当前行代码 if (string.IsNullOrEmpty(code)) { // 触发起始点 EditPoint editPoint = selection.AnchorPoint.CreateEditPoint(); // 选中触发行 code = editPoint.GetLines(editPoint.Line, editPoint.Line + 1); } // 多行转成一行 code = Regex.Replace(code, @"\s+", s => " "); return(code.Trim()); }
/// <summary> /// Gets the text for the line where the edit point is located. /// </summary> /// <param name="editPoint">The edit point.</param> /// <returns>The text of the edit point's line.</returns> internal static string GetLine(this EditPoint editPoint) { return(editPoint.GetLines(editPoint.Line, editPoint.Line + 1)); }
private void inspectCurrentCppFile(out string functionOfInterest, out string curCodeLine) { // get the currently active document from the IDE Document doc = dte.ActiveDocument; TextDocument tdoc = doc.Object("TextDocument") as TextDocument; if (tdoc == null) { throw new Exception("Could not obtain the active TextDocument object"); } // do we want a line found in a previous run? if (_lastCodeLine != null) { functionOfInterest = _lastFunctionOfInterest; _lastFunctionOfInterest = null; curCodeLine = _lastCodeLine; _lastCodeLine = null; // don't exit if we are still in some header file if (!currentFileIsHeaderFile()) { return; } } // find suitable code line near the cursor // TODO: comments are removed when preprocessing and thus can't find a line with comments TextSelection selection = tdoc.Selection; int line = selection.TopPoint.Line; EditPoint editPoint = tdoc.CreateEditPoint(); curCodeLine = editPoint.GetLines(line, line + 1); if (string.IsNullOrWhiteSpace(curCodeLine)) { ++line; curCodeLine = editPoint.GetLines(line, line + 1); if (string.IsNullOrWhiteSpace(curCodeLine)) { line -= 2; curCodeLine = editPoint.GetLines(line, line + 1); if (string.IsNullOrWhiteSpace(curCodeLine)) { throw new Exception("Choose a distinctive line of code inside a function or the function definition itself."); } } selection.GotoLine(line, true); } // get currently viewed function functionOfInterest = ""; CodeElement codeEl = selection.TopPoint.CodeElement[vsCMElement.vsCMElementFunction]; if (codeEl != null) { functionOfInterest = codeEl.FullName; } else { dte.StatusBar.Text = "Warning: could not get function object from the IDE."; dte.StatusBar.Highlight(true); } // TODO: in case of a template this gets something like funcName<T>, the assembly contains funcName<actualType> // it doesn't in the case of macros either, e.g. gets _tmain but in the asm it will be wmain // now that we extracted the function of interest handle the header file case if (currentFileIsHeaderFile() && !trySwitchToCppFile()) { _lastFunctionOfInterest = functionOfInterest; _lastCodeLine = curCodeLine; throw new Exception("Please open a cpp file calling this code and re-run."); } }
public void Remove() { Tuple <TextPoint, TextPoint> range = null; try { // To use RemoveMember, we'd have to cast to CodeClass, CodeStruct, CodeInterface, or CodeEnum. // However, RemoveMember won't remove a leading comment other than a DocComment, // and in VB RemoveMember doesn't remove the whitespace line after the member. // So to make our Remove consistent with GetCode, we'll use GetCodeRange and Delete. range = this.GetCodeRange(); } catch (ArgumentException ex) { // In VS 2015 Update 2, an ArgumentException can occur while removing members with explicitly // implemented interface member names if the same named non-explicitly implemented member // was just removed. The Roslyn code model seems to get out of sync on the explicit members, // and we have to look them back up to remove them. This happens, for example, on the second // GetEnumerator when sorting these lines (from DictionarySet.cs): // public IEnumerator<T> GetEnumerator() { throw new NotImplementedException(); } // bool ISet< T >.Add(T item) { throw new NotImplementedException(); } // IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } bool rethrow = this.element.InfoLocation != vsCMInfoLocation.vsCMInfoLocationProject; if (!rethrow) { ProjectItem projectItem = this.element.ProjectItem; FileCodeModel2 codeModel = (FileCodeModel2)projectItem.FileCodeModel; codeModel.Synchronize(); this.element = MemberSorter.FindMember(codeModel.CodeElements, this.Name); if (this.element == null) { rethrow = true; } else { range = this.GetCodeRange(); } } if (rethrow) { throw new ArgumentException($"Unable to remove or reorder element {this.Name} due to VS FileCodeModel2 limitations.", ex); } } if (range != null) { EditPoint startEdit = range.Item1.CreateEditPoint(); startEdit.StartOfLine(); EditPoint endEdit = range.Item2.CreateEditPoint(); endEdit.LineDown(); if (endEdit.GetLines(endEdit.Line, endEdit.Line + 1).Trim().Length == 0) { endEdit.LineDown(); } endEdit.StartOfLine(); startEdit.Delete(endEdit); } }
protected void onPaneUpdated(OutputWindowPane pane) { if (pane == null || pane.Guid == null) { return; } TextDocument textD; try { textD = pane.TextDocument; } catch (System.Runtime.InteropServices.COMException ex) { Log.Debug("notifyRaw: COMException - '{0}'", ex.Message); return; } int countLines = textD.EndPoint.Line; if (countLines <= 1 || countLines - getPrevCountLines(pane.Guid) < 1) { return; } if (!dataList.ContainsKey(pane.Guid)) { dataList[pane.Guid] = new ConcurrentQueue <string>(); } EditPoint point = textD.StartPoint.CreateEditPoint(); // text between Start (inclusive) and ExclusiveEnd (exclusive) dataList[pane.Guid].Enqueue(point.GetLines(getPrevCountLines(pane.Guid), countLines)); // e.g. first line: 1, 2 setPrevCountLines(countLines, pane.Guid); //TODO: fix me. Prevent Duplicate Data / bug with OutputWindowPane if (tUpdated == null || tUpdated.ThreadState == ThreadState.Unstarted || tUpdated.ThreadState == ThreadState.Stopped) { tUpdated = new System.Threading.Thread(() => { if (pane == null) { return; } try { notifyRaw(pane.Guid, pane.Name); } catch (Exception ex) { Log.Debug("notifyRaw: failed '{0}'", ex.Message); } }); try { tUpdated.Start(); } catch (Exception ex) { // ThreadStateException, OutOfMemoryException Log.Debug("notifyRaw: can't start '{0}'", ex.Message); } } }
private void ToggleCommentsAboveMember(EditPoint editPoint, string commentPrefix) { try { int? firstLineOfComment = null; editPoint.StartOfLine(); editPoint.CharLeft(); while(!editPoint.AtStartOfDocument) { String line = editPoint.GetLines(editPoint.Line, editPoint.Line + 1).Trim(); if(line.Length == 0 || line.StartsWith(commentPrefix)) { if(line.Length > 0) { firstLineOfComment = editPoint.Line; } else if(firstLineOfComment.HasValue) { ToggleExpansionAtLine(editPoint.CreateEditPoint(), firstLineOfComment.Value, commentPrefix); firstLineOfComment = null; } editPoint.StartOfLine(); editPoint.CharLeft(); } else { break; } } if(firstLineOfComment.HasValue) { ToggleExpansionAtLine(editPoint.CreateEditPoint(), firstLineOfComment.Value, commentPrefix); } } catch(Exception) { } }
protected int ShowEventHandler(string document, string codeBehind, string codeBehindFile, string className, string objectTypeName, string eventName, string eventHandlerName) { var projectItem = GetProjectItem(document, codeBehind, codeBehindFile); var binder = GetBinder(projectItem); if (binder == null) { return(NativeMethods.E_FAIL); } projectItem.Open(EnvDTE.Constants.vsViewKindCode); var function = binder.FindEventHandler(className, objectTypeName, eventName, eventHandlerName); if (function != null) { bool prevLineIsEmpty = true; EditPoint point = function.EndPoint.CreateEditPoint(); point.LineUp(1); string lines = point.GetLines(point.Line, (int)(point.Line + 1)); for (int i = 0; i < lines.Length; i++) { if (!char.IsWhiteSpace(lines[i])) { prevLineIsEmpty = false; break; } } Document document2 = projectItem.Document; if (document2 != null) { Window activeWindow = document2.ActiveWindow; if (activeWindow != null) { TextSelection selection = activeWindow.Selection as TextSelection; if (selection != null) { selection.MoveToPoint(function.EndPoint, false); if (prevLineIsEmpty) { selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false); int virtualCharOffset = selection.AnchorPoint.VirtualCharOffset; selection.LineUp(false, 1); if (selection.AnchorPoint.VirtualCharOffset <= virtualCharOffset) { int indentSize = 4; TextDocument document3 = document2 as TextDocument; if (document3 != null) { indentSize = document3.IndentSize; } selection.MoveToLineAndOffset(selection.AnchorPoint.Line, (int)(virtualCharOffset + indentSize), false); } } else { selection.LineUp(false, 1); //selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false); selection.EndOfLine(false); } } } } } return(NativeMethods.S_OK); }
// 1: show assembly code for currently open source file // 2: show preprocessed source code private void showCppOutput(int mode = 1) { // if in a header try to open the cpp file switchToCppFile(); // get the currently active document from the IDE Document doc = dte.ActiveDocument; TextDocument tdoc = doc.Object("TextDocument") as TextDocument; if (tdoc == null) { package.showMsgBox("Could not obtain the active TextDocument object"); return; } // get currently viewed function string functionOfInterest = ""; TextSelection selection = tdoc.Selection; CodeElement codeEl = selection.ActivePoint.CodeElement[vsCMElement.vsCMElementFunction]; if (codeEl == null) { dte.StatusBar.Text = "You should place the cursor inside a function."; dte.StatusBar.Highlight(true); } else { functionOfInterest = codeEl.FullName; } // TODO: in case of a template this gets something like funcName<T>, the assembly contains funcName<actualType> // it doesn't in the case of macros either, e.g. gets _tmain but in the asm it will be wmain // http://www.viva64.com/en/a/0082/#ID0ELOBK // EditPoint directly manipulates text buffer data instead of operating with the text through the editor UI. int line = selection.ActivePoint.Line; EditPoint editPoint = tdoc.CreateEditPoint(); string curCodeLine = editPoint.GetLines(line, line + 1); // TODO: comments are removed when preprocessing and thus can't find a line with comments // get current configuration Project proj = doc.ProjectItem.ContainingProject; ConfigurationManager mgr = proj.ConfigurationManager; string platform = mgr.ActiveConfiguration.PlatformName; string conf = mgr.ActiveConfiguration.ConfigurationName; // find the currently active configuration for the current file // don't use SolutionBuild as there may be mixed platforms // use late binding for version independence dynamic file = doc.ProjectItem.Object; // as VCFile dynamic fileconfigs = file.FileConfigurations; // as IVCCollection dynamic fileconfig = fileconfigs.Item(conf + "|" + platform); // as VCFileConfiguration dynamic tool = fileconfig.Tool; // VCCLCompilerTool // save original settings to restore them later // there seems to be no better way // DTE undo contexts doesn't cover these project settings // unload/reload the project may close all open files // manipulating proj.Saved or .IsDirty does not work bool lto = tool.WholeProgramOptimization; dynamic asmtype = tool.AssemblerOutput; dynamic genPreprocessed = tool.GeneratePreprocessedFile; string asmloc = tool.AssemblerListingLocation; string objFileLocation = tool.ObjectFile; string generatedFile; if (mode == 1) { // asmListingAsmSrc => '.asm' generatedFile = Path.GetTempFileName() + ".asm"; //System.IO.Path.GetTempPath tool.WholeProgramOptimization = false; tool.AssemblerOutput = (dynamic)Enum.Parse(tool.AssemblerOutput.GetType(), "asmListingAsmSrc"); tool.AssemblerListingLocation = generatedFile; } else /*if (mode == 2)*/ { // not generally applicable //generatedFile = prj.ProjectDirectory + prjconfig.IntermediateDirectory + Replace(file.Name, ".cpp", ".i"); generatedFile = Path.GetTempFileName() + ".cpp"; tool.GeneratePreprocessedFile = (dynamic)Enum.Parse(tool.GeneratePreprocessedFile.GetType(), "preprocessYes"); // there's no separate option for this, so misuse /Fo tool.ObjectFile = generatedFile; } try { // forceBuild (even if up-to-date) and waitOnBuild fileconfig.Compile(true, true); } catch (Exception e) { package.writeStatus($"VCFileConfiguration.Compile() failed: {e.Message}. Trying command Build.Compile now..."); _dispBuildEvents_OnBuildProjConfigDoneEventHandler onProjBuildDone = null; onProjBuildDone = (project, projectConfig, platfrm, solutionConfig, success) => { dte.Events.BuildEvents.OnBuildProjConfigDone -= onProjBuildDone; // naive cleanup if (mode == 1) { tool.WholeProgramOptimization = lto; tool.AssemblerOutput = asmtype; tool.AssemblerListingLocation = asmloc; } else if (mode == 2) { tool.GeneratePreprocessedFile = genPreprocessed; tool.ObjectFile = objFileLocation; } if (success) { postCompileCpp(generatedFile, mode, functionOfInterest, curCodeLine); } }; dte.Events.BuildEvents.OnBuildProjConfigDone += onProjBuildDone; dte.ExecuteCommand("Build.Compile"); return; } // naive cleanup if (mode == 1) { tool.WholeProgramOptimization = lto; tool.AssemblerOutput = asmtype; tool.AssemblerListingLocation = asmloc; } else if (mode == 2) { tool.GeneratePreprocessedFile = genPreprocessed; tool.ObjectFile = objFileLocation; } postCompileCpp(generatedFile, mode, functionOfInterest, curCodeLine); }
/// <summary>Parses for strings by iterating through the FileCodeModel.</summary> /// <param name="startPoint">The start point.</param> /// <param name="endPoint">The end point.</param> /// <param name="lastDocumentLength">Last length of the document.</param> private void ParseForStrings(TextPoint startPoint, TextPoint endPoint, int lastDocumentLength) { //0.35-0.06 seconds (threaded: 2.47-1.77 seconds) List <StringResource> stringResources = new List <StringResource>(); bool isFullDocument = startPoint.AtStartOfDocument && endPoint.AtEndOfDocument, isTextWithStringLiteral = true; int startLine = startPoint.Line, startCol = startPoint.LineCharOffset, endLine = endPoint.Line, endCol = endPoint.LineCharOffset, documentLength = endPoint.Parent.EndPoint.Line, insertIndex = 0; if (isFullDocument) { m_StringResources.Clear(); } else { #region document manipulated -> adapt string resources and locations //determine whether the text between startLine and endLine (including) contains double quotes EditPoint editPoint = startPoint.CreateEditPoint() as EditPoint2; if (!startPoint.AtStartOfLine) { editPoint.StartOfLine(); } isTextWithStringLiteral = editPoint.GetLines(startLine, endLine + 1).Contains("\""); //move trailing locations behind changed lines if needed and //remove string resources on changed lines int lineOffset = documentLength - lastDocumentLength; #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Line offset is {0}", lineOffset); #endif for (int i = m_StringResources.Count - 1; i >= 0; --i) { StringResource stringResource = m_StringResources[i]; int lineNo = stringResource.Location.X; if (lineNo + lineOffset > endLine) { if (lineOffset != 0) { #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Move string literal from line {0} to {1}", lineNo, lineNo + lineOffset); #endif stringResource.Offset(lineOffset, 0); //move } //if } else if (lineNo >= startLine) { #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Remove string literal {0} ({1}): {2}", i, stringResource.Location, stringResource.Text); #endif m_StringResources.RemoveAt(i); //remove changed line } else if (insertIndex == 0) { #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" List insert index is {0} / {1}", i + 1, m_StringResources.Count - 1); #endif insertIndex = i + 1; } //else if } //for #endregion } //else #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Text has{0} string literals.", isTextWithStringLiteral ? string.Empty : " no"); #endif if (isTextWithStringLiteral) { CodeElements elements = m_Window.Document.ProjectItem.FileCodeModel.CodeElements; foreach (CodeElement element in elements) { ParseForStrings(element, m_DoProgress, stringResources, m_Settings, m_IsCSharp, startLine, endLine); #if DEBUG if (element.Kind == vsCMElement.vsCMElementProperty) { CodeProperty prop = element as CodeProperty; if ((prop.Getter == null) && (prop.Setter == null)) { //here we have an expression bodied property //if (m_IVsTextView != null) //{ // m_IVsTextView. //} } } #endif } //foreach #if DEBUG_OUTPUT System.Diagnostics.Debug.Print(" Found {0} string literals", stringResources.Count); #endif if (isFullDocument) { m_StringResources.AddRange(stringResources); } else if (stringResources.Count > 0) { m_StringResources.InsertRange(insertIndex, stringResources); } } //if m_DoCompleted(isFullDocument || (stringResources.Count > 0)); }
public bool Start() { try { if (!ProjectItem.IsOpen) { ProjectItem.Open(); } Document document = ProjectItem.Document; TextDocument textDocument = document.Object(Constants.TEXT_DOCUMENT) as TextDocument; TextPoint startPoint = textDocument.StartPoint; TextPoint endPoint = textDocument.EndPoint; int lastDocumentLength = textDocument.EndPoint.Line; logger.Debug("Start - parsing document: " + FileName); List <StringResource> stringResources = new List <StringResource>(); bool isFullDocument = startPoint.AtStartOfDocument && endPoint.AtEndOfDocument, isTextWithStringLiteral = true; int startLine = startPoint.Line; int startCol = startPoint.LineCharOffset; int endLine = endPoint.Line; int endCol = endPoint.LineCharOffset; int documentLength = endPoint.Parent.EndPoint.Line; int insertIndex = 0; if (isFullDocument) { StringResources.Clear(); } else { //determine whether the text between startLine and endLine (including) contains double quotes EditPoint editPoint = startPoint.CreateEditPoint() as EditPoint2; if (!startPoint.AtStartOfLine) { editPoint.StartOfLine(); } isTextWithStringLiteral = editPoint.GetLines(startLine, endLine + 1).Contains("\""); //move trailing locations behind changed lines if needed and //remove string resources on changed lines int lineOffset = documentLength - lastDocumentLength; for (int i = StringResources.Count - 1; i >= 0; --i) { StringResource stringResource = StringResources[i]; int lineNo = stringResource.Location.X; if (lineNo + lineOffset > endLine) { if (lineOffset != 0) { stringResource.Offset(lineOffset, 0); //move } } else if (lineNo >= startLine) { StringResources.RemoveAt(i); //remove changed line } else if (insertIndex == 0) { insertIndex = i + 1; } } } if (isTextWithStringLiteral) { CodeElements elements = ProjectItem.FileCodeModel.CodeElements; foreach (CodeElement element in elements) { ParseForStrings(element, stringResources, isCsharp, m_Settings, startLine, endLine); } if (isFullDocument) { StringResources.AddRange(stringResources); } else if (stringResources.Count > 0) { StringResources.InsertRange(insertIndex, stringResources); } } logger.Debug("End - parsing document: " + FileName); return(true); } catch (Exception e) { logger.Warn(e, "An error occurred while parsing file: " + FileName); return(false); } }