/// <summary> /// Flushes the pending data. /// </summary> public override void Flush() { // If there is no data in the buffer, then there is nothing to do. if (0 == usedBuffer) { // Make sure that the read-only region is correct and exit. ExtendReadOnlyRegion(); return; } string text = null; // We have to use a StreamReader in order to work around problems with the // encoding of the data sent in, but in order to build the reader we need // a memory stream to read the data in the buffer. using (MemoryStream s = new MemoryStream(byteBuffer, 0, usedBuffer)) { // Now we can build the reader from the memory stream. using (StreamReader reader = new StreamReader(s)) { // At the end we can get the text. text = reader.ReadToEnd(); } } // Now the buffer is empty. usedBuffer = 0; // The text is always added at the end of the buffer. int lastLine; int lastColumn; Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( textLines.GetLastLineIndex(out lastLine, out lastColumn)); // Lock the buffer before changing its content. Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( textLines.LockBuffer()); try { GCHandle handle = GCHandle.Alloc(text, GCHandleType.Pinned); try { TextSpan[] span = new TextSpan[1]; Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( textLines.ReplaceLines(lastLine, lastColumn, lastLine, lastColumn, handle.AddrOfPinnedObject(), text.Length, span)); } finally { handle.Free(); } // Extend the read-only region of the buffer to include this text. ExtendReadOnlyRegion(); } finally { Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( textLines.UnlockBuffer()); } }
/// <summary> /// Gets the entire text from the buffer. /// </summary> private string GetAllText() { var span = new TextSpan(); textBuffer.GetLastLineIndex(out span.iEndLine, out span.iEndIndex); string text; textBuffer.GetLineText(span.iStartLine, span.iStartIndex, span.iEndLine, span.iEndIndex, out text); return(text); }
static string GetLine(IVsTextLines lines, int lineNr) { if (lineNr < 0) { throw new ArgumentOutOfRangeException("lineNr"); } else if (lines == null) { return(null); } int lastLine, lastIndex; if (!VSErr.Succeeded(lines.GetLastLineIndex(out lastLine, out lastIndex))) { return(null); } if (lineNr > lastLine) { return(null); } LINEDATA[] data = new LINEDATA[1]; if (!VSErr.Succeeded(lines.GetLineData(lineNr, data, null))) { return(null); } return(Marshal.PtrToStringUni(data[0].pszText, data[0].iLength)); }
private static string GetBufferContents(object docDataObj) { string text = null; IVsTextLines buffer = null; if (docDataObj is IVsTextLines) { buffer = (IVsTextLines)docDataObj; } else if (docDataObj is IVsTextBufferProvider) { IVsTextBufferProvider tp = (IVsTextBufferProvider)docDataObj; if (tp.GetTextBuffer(out buffer) != NativeMethods.S_OK) { buffer = null; } } if (buffer != null) { int endLine, endIndex; NativeMethods.ThrowOnFailure(buffer.GetLastLineIndex(out endLine, out endIndex)); NativeMethods.ThrowOnFailure(buffer.GetLineText(0, 0, endLine, endIndex, out text)); buffer = null; } return(text); }
private string GetText() { int line, index; string buffer; if (textLines.GetLastLineIndex(out line, out index) != VSConstants.S_OK) { return(String.Empty); } if (textLines.GetLineText(0, 0, line, index, out buffer) != VSConstants.S_OK) { return(String.Empty); } return(buffer); }
public bool DocumentSetText(string text) { IVsTextLines VsTxtlines = TextLines; if (VsTxtlines == null) { return(false); } bool Result = false; GCHandle handle = GCHandle.Alloc(text, GCHandleType.Pinned); try { TextSpan[] span = new TextSpan[1]; int line, col; Int32 result = VsTxtlines.GetLastLineIndex(out line, out col); if (result == VSConstants.S_OK) { result = VsTxtlines.ReloadLines(0, 0, line, col, handle.AddrOfPinnedObject(), text.Length, span); } if (result == VSConstants.S_OK) { Result = true; } } finally { handle.Free(); } return(Result); }
private void ExecuteQueryCommandExecute(object sender, EventArgs e) { try { var activeTextView = GetActiveTextView(); string queryToExecute; ErrorHandler.ThrowOnFailure(activeTextView.GetSelectedText(out queryToExecute)); if (string.IsNullOrEmpty(queryToExecute)) { IVsTextLines textLines = null; ErrorHandler.ThrowOnFailure(activeTextView.GetBuffer(out textLines)); int iLineCount; int iIndex; ErrorHandler.ThrowOnFailure(textLines.GetLastLineIndex(out iLineCount, out iIndex)); ErrorHandler.ThrowOnFailure(textLines.GetLineText(0, 0, iLineCount, iIndex, out queryToExecute)); } var bismInfoProvider = GetBismInfoProvider(); bismInfoProvider.SetUpdateEditorMargin(GetEditorMargin(activeTextView)); bismInfoProvider.ExecuteQuery(queryToExecute); } catch (Exception exc) { DisplayExceptionWindow(exc); } }
/// <summary> /// Replaces given IVsTextLines with given MemoryStream content /// </summary> /// <param name="stream"></param> /// <param name="textLines"></param> /// <param name="removeFromUndoStack">True if new undo units (created by this operation) should be removed</param> public static void SaveStreamToBuffer(MemoryStream stream, IVsTextLines textLines, bool removeFromUndoStack) { if (stream == null) { throw new ArgumentNullException("stream"); } if (textLines == null) { throw new ArgumentNullException("textLines"); } byte[] buffer = stream.ToArray(); string text = Encoding.UTF8.GetString(buffer, 3, buffer.Length - 3); // get ResX file text int lastLine, lastLineIndex; int hr = textLines.GetLastLineIndex(out lastLine, out lastLineIndex); Marshal.ThrowExceptionForHR(hr); TextSpan[] spans = null; // replace current buffer text with new text hr = textLines.ReplaceLines(0, 0, lastLine, lastLineIndex, Marshal.StringToBSTR(text), text.Length, spans); Marshal.ThrowExceptionForHR(hr); if (removeFromUndoStack) { IOleUndoManager manager; // previous operation created undo unit - remove it hr = textLines.GetUndoManager(out manager); Marshal.ThrowExceptionForHR(hr); manager.RemoveTopFromUndoStack(1); } }
/// <summary> /// Set the cursor at the end of the current buffer and, if needed, scrolls the text /// view so that the cursor is visible. /// </summary> private void SetCursorAtEndOfBuffer() { // If the text view is not created, then there is no reason to set the cursor. if (null == textView) { return; } int lastLine; int lastIndex; // Get the size of the buffer. Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( textLines.GetLastLineIndex(out lastLine, out lastIndex)); // Set the cursor at the end. Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure( textView.SetCaretPos(lastLine, lastIndex)); // Make sure that the last line of the buffer is visible. // Note that we will not throw an exception if we can not set the scroll informations. int minUnit; int maxUnit; int visibleUnits; int firstVisibleUnit; if (Microsoft.VisualStudio.ErrorHandler.Succeeded( textView.GetScrollInfo(verticalScrollbar, out minUnit, out maxUnit, out visibleUnits, out firstVisibleUnit))) { if (maxUnit >= visibleUnits) { textView.SetScrollPosition(verticalScrollbar, maxUnit + 1 - visibleUnits); } } // Make sure that the text view is showing the beginning of the new line. if (Microsoft.VisualStudio.ErrorHandler.Succeeded( textView.GetScrollInfo(horizontalScrollbar, out minUnit, out maxUnit, out visibleUnits, out firstVisibleUnit))) { textView.SetScrollPosition(horizontalScrollbar, minUnit); } }
public static string GetText(this IVsTextLines buffer) { int lastLine; int lastIndex; buffer.GetLastLineIndex(out lastLine, out lastIndex); string text; var ret = buffer.GetLineText(0, 0, lastLine, lastIndex, out text); return(text); }
private static string GetAllText(IVsTextLines buffer) { int endLine, endIndex; string text; if (buffer.GetLastLineIndex(out endLine, out endIndex) != VSConstants.S_OK || buffer.GetLineText(0, 0, endLine, endIndex, out text) != VSConstants.S_OK) { text = null; } return(text); }
static string GetText(IVsTextLines buffer) { // Create span for all lines: TextSpan entireSpan = new TextSpan(); buffer.GetLastLineIndex(out entireSpan.iEndLine, out entireSpan.iEndIndex); // Get text: string text; buffer.GetLineText(entireSpan.iStartLine, entireSpan.iStartIndex, entireSpan.iEndLine, entireSpan.iEndIndex, out text); return(text); }
private void Replace(string value) { int endLine, endCol; IVsTextLines lines = (IVsTextLines)textBuffer; lines.GetLastLineIndex(out endLine, out endCol); IntPtr pText = Marshal.StringToCoTaskMemAuto(value); try { lines.ReplaceLines(0, 0, endLine, endCol, pText, value.Length, null); } finally { Marshal.FreeCoTaskMem(pText); } }
public string GetTextOfFileIfOpenInIde(string filePath) { IVsRunningDocumentTable rdt = _serviceProvider.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable; IVsHierarchy hierarchy = null; uint itemid = 0; IntPtr docDataUnk = IntPtr.Zero; uint lockCookie = 0; int hr = rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, filePath, out hierarchy, out itemid, out docDataUnk, out lockCookie); try { if (hr == VSConstants.S_OK) { IVsTextLines textLines = Marshal.GetUniqueObjectForIUnknown(docDataUnk) as IVsTextLines; if (textLines != null) { string text = null; int endLine = 0; int endIndex = 0; hr = textLines.GetLastLineIndex(out endLine, out endIndex); Debug.Assert(hr == VSConstants.S_OK, "GetLastLineIndex did not return S_OK."); hr = textLines.GetLineText(0, 0, endLine, endIndex, out text); Debug.Assert(hr == VSConstants.S_OK, "GetLineText did not return S_OK."); return(text); } } return(null); } finally { if (lockCookie != 0) { rdt.UnlockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, lockCookie); } } }
/// <summary> /// Returns content of the given text buffer in a string /// </summary> public static string GetTextFrom(IVsTextLines textLines) { if (textLines == null) { throw new ArgumentNullException("textLines"); } int lastLine, lastLineIndex; int hr = textLines.GetLastLineIndex(out lastLine, out lastLineIndex); Marshal.ThrowExceptionForHR(hr); string textBuffer = ""; hr = textLines.GetLineText(0, 0, lastLine, lastLineIndex, out textBuffer); Marshal.ThrowExceptionForHR(hr); return(textBuffer); }
public void RemoveRange(int start, int count) { // Check if there is any line to remove. if (count <= 0) { hasMerged = true; return; } // Check if the index of the first line is correct. if (start < 0) { throw new ArgumentOutOfRangeException("start"); } int startLine = start; // Find the number of lines in the buffer. int totalLines = LineCount; // If the start line if after the end of the buffer, then there is nothing to do. if (startLine >= totalLines) { hasMerged = true; return; } // Find the last line to remove. int endLine = startLine + count; int endIndex = 0; if (endLine >= totalLines) { ErrorHandler.ThrowOnFailure(textBuffer.GetLastLineIndex(out endLine, out endIndex)); } // Lock the buffer. ErrorHandler.ThrowOnFailure(textBuffer.LockBuffer()); try { // Remove the text replacing the lines with an empty string. TextSpan[] span = new TextSpan[1]; ErrorHandler.ThrowOnFailure(textBuffer.ReplaceLines(startLine, 0, endLine, endIndex, IntPtr.Zero, 0, span)); hasMerged = true; } finally { // unlock the buffer textBuffer.UnlockBuffer(); } }
private void SaveMeasuresAndCalculatedColumnsCommandExecute(object sender, EventArgs e) { try { var activeTextView = GetActiveTextView(); string viewText; IVsTextLines textLines = null; ErrorHandler.ThrowOnFailure(activeTextView.GetBuffer(out textLines)); int iLineCount; int iIndex; ErrorHandler.ThrowOnFailure(textLines.GetLastLineIndex(out iLineCount, out iIndex)); ErrorHandler.ThrowOnFailure(textLines.GetLineText(0, 0, iLineCount, iIndex, out viewText)); var bismInfoProvider = GetBismInfoProvider(); bismInfoProvider.SaveMeasuresAndCalcColumns(viewText); } catch (Exception exc) { DisplayExceptionWindow(exc); } }
/// <summary> /// performs lazy initialization to ensure our current code model is up-to-date. /// /// If we haven't yet created our CodeDom backing we'll create it for the 1st time. If we've /// created our backing, but some elements have been changed that we haven't yet reparsed /// then we'll reparse & merge any of the appropriate changes. /// </summary> private void Initialize() { if (ccu != null) { if (isDirty) { Reparse(); isDirty = false; } return; } IMergeDestination merger = MergeDestination; if (null == textBuffer) { using (FileStream fs = new FileStream(Name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { if ((null == merger) && (null != parent)) { merger = new FileCodeMerger(parent); } ccu = provider.ParseMergable(new StreamReader(fs), merger); } } else { // Find the size of the buffer. int lastLine; int lastColumn; ErrorHandler.ThrowOnFailure(textBuffer.GetLastLineIndex(out lastLine, out lastColumn)); // Get the text in the buffer. string text; ErrorHandler.ThrowOnFailure(textBuffer.GetLineText(0, 0, lastLine, lastColumn, out text)); if (null == merger) { merger = new TextBufferMerger(textBuffer); } ccu = provider.ParseMergable(text, Name, merger); } }
static string GetLine(IVsTextLines lines, int lineNr) { if (lineNr < 0) throw new ArgumentOutOfRangeException("lineNr"); else if (lines == null) return null; int lastLine, lastIndex; if (!ErrorHandler.Succeeded(lines.GetLastLineIndex(out lastLine, out lastIndex))) return null; if (lineNr > lastLine) return null; LINEDATA[] data = new LINEDATA[1]; if (!ErrorHandler.Succeeded(lines.GetLineData(lineNr, data, null))) return null; return Marshal.PtrToStringUni(data[0].pszText, data[0].iLength); }
private static void UpdateServiceDefinition(IVsTextLines lines, string roleType, string projectName) { if (lines == null) { throw new ArgumentException("lines"); } int lastLine, lastIndex; string text; ErrorHandler.ThrowOnFailure(lines.GetLastLineIndex(out lastLine, out lastIndex)); ErrorHandler.ThrowOnFailure(lines.GetLineText(0, 0, lastLine, lastIndex, out text)); var doc = new XmlDocument(); doc.LoadXml(text); UpdateServiceDefinition(doc, roleType, projectName); var encoding = Encoding.UTF8; var userData = lines as IVsUserData; if (userData != null) { var guid = VSConstants.VsTextBufferUserDataGuid.VsBufferEncodingVSTFF_guid; object data; int cp; if (ErrorHandler.Succeeded(userData.GetData(ref guid, out data)) && (cp = (data as int? ?? (int)(data as uint? ?? 0)) & (int)__VSTFF.VSTFF_CPMASK) != 0) { try { encoding = Encoding.GetEncoding(cp); } catch (NotSupportedException) { } catch (ArgumentException) { } } } var sw = new StringWriterWithEncoding(encoding); doc.Save(XmlWriter.Create( sw, new XmlWriterSettings { Indent = true, IndentChars = " ", NewLineHandling = NewLineHandling.Entitize, Encoding = encoding } )); var sb = sw.GetStringBuilder(); var len = sb.Length; var pStr = Marshal.StringToCoTaskMemUni(sb.ToString()); try { ErrorHandler.ThrowOnFailure(lines.ReplaceLines(0, 0, lastLine, lastIndex, pStr, len, new TextSpan[1])); } finally { Marshal.FreeCoTaskMem(pStr); } }
public int GetLastLineIndex(out int piLine, out int piIndex) { return(_textBuffer.GetLastLineIndex(out piLine, out piIndex)); }
private bool Parse() { IVsTextLines lines = _buffer; int lastLine, linelen; Marshal.ThrowExceptionForHR(lines.GetLastLineIndex(out lastLine, out linelen)); bool changed = false; int n = 0; for (int i = 0; i < lastLine; i++) { Marshal.ThrowExceptionForHR(lines.GetLengthOfLine(i, out linelen)); if (linelen < 8) { continue; // No 'Index: ' line } string start; Marshal.ThrowExceptionForHR(lines.GetLineText(i, 0, i, 7, out start)); if (!string.Equals(start, "Index: ")) { continue; } Marshal.ThrowExceptionForHR(lines.GetLineText(i, 7, i, linelen, out start)); start = start.Trim(); if (n >= _indexes.Count || _indexes[n] != start || _lines[n] != i) { changed = true; if (n <= _indexes.Count) { _lines.RemoveRange(n, _indexes.Count - n); _indexes.RemoveRange(n, _indexes.Count - n); } _indexes.Add(start); _lines.Add(i); } n++; } if (changed) { DropDownTypes.Clear(); for (int i = 0; i < _indexes.Count; i++) { TextSpan ts; ts.iStartLine = _lines[i]; ts.iStartIndex = 0; ts.iEndLine = (i + 1 < _lines.Count) ? _lines[i + 1] - 1 : lastLine; Marshal.ThrowExceptionForHR(lines.GetLengthOfLine(ts.iEndLine, out ts.iEndIndex)); ts.iEndIndex++; DropDownTypes.Add(new ComboMember(_indexes[i], 1, DROPDOWNFONTATTR.FONTATTR_PLAIN, ts)); } } return(changed); }
internal static void OnDocumentSaved(uint docCookie) { // The document identified by docCookie has been saved. Now we have to update // our internal data structures and persist them to file. This will ensure we // will display the same data again when the user closes and reopens the document. // If there is currently no clone report available there is nothing to do. if (!IsCloneReportAvailable) { return; } CloneDetectiveResult cloneDetectiveResult = CloneDetectiveResult; // Get the text buffer. We're done if this fails because that means it was not // a text document. IVsTextLines textLines = GetDocumentTextLines(docCookie); if (textLines == null) { return; } // Get the SourceFile of the document in our data structure. We're done if this // fails because that means the document was not included in clone detection. string path = GetDocumentPath(textLines); SourceNode sourceNode = cloneDetectiveResult.SourceTree.FindNode(path); if (sourceNode == null) { return; } SourceFile sourceFile = sourceNode.SourceFile; // And we need to be able to map existing clone markers to their corresponding // clone classes. If that fails we cannot update any clone information. DocumentInfo documentInfo; if (!_textLinesToDocInfos.TryGetValue(textLines, out documentInfo)) { return; } // If the hash of the file didn't match when we opened it, we don't want to save // any changes. if (!documentInfo.HashMatched) { return; } // Store the new line count of the file. Be aware of the fact that the last line // is not taken into account if it is empty. Replace the fingerprint of the file // with the new one such that we get no problems when opening up the file the // next time. int lastLineIndex; int lastLineLength; if (ErrorHandler.Failed(textLines.GetLastLineIndex(out lastLineIndex, out lastLineLength))) { return; } sourceFile.Length = lastLineIndex + ((lastLineLength > 0) ? 1 : 0); sourceFile.Fingerprint = GetHashFromFile(path); // We need to track which source file clone information was modified to be able // to update the rollups afterwards. HashSet <SourceFile> modifiedSourceFiles = new HashSet <SourceFile>(); // Clear old clone information of the saved document as we're going to rebuild // it from scratch. foreach (Clone clone in sourceFile.Clones) { clone.CloneClass.Clones.Remove(clone); } sourceFile.Clones.Clear(); modifiedSourceFiles.Add(sourceFile); // Store information about current position of each marker. foreach (KeyValuePair <IVsTextLineMarker, CloneClass> markerWithCloneClass in documentInfo.MarkersToCloneClasses) { // Retrieve the current text span of the marker we just enumerated. TextSpan[] span = new TextSpan[1]; ErrorHandler.ThrowOnFailure(markerWithCloneClass.Key.GetCurrentSpan(span)); // Create a new clone object and initialize it appropriately. Clone clone = new Clone(); clone.CloneClass = markerWithCloneClass.Value; clone.SourceFile = sourceFile; clone.StartLine = span[0].iStartLine; clone.LineCount = span[0].iEndLine - span[0].iStartLine + 1; // Add the clone to the clone class as well as the source file. clone.CloneClass.Clones.Add(clone); clone.SourceFile.Clones.Add(clone); } // Remove clone classes with less than two clones. List <CloneClass> cloneClasses = cloneDetectiveResult.CloneReport.CloneClasses; for (int i = cloneClasses.Count - 1; i >= 0; i--) { List <Clone> clones = cloneClasses[i].Clones; if (clones.Count < 2) { foreach (Clone clone in clones) { clone.SourceFile.Clones.Remove(clone); modifiedSourceFiles.Add(clone.SourceFile); } cloneClasses.RemoveAt(i); } } // Save the new clone report to disk. string solutionPath = VSPackage.Instance.GetSolutionPath(); string cloneReportPath = PathHelper.GetCloneReportPath(solutionPath); CloneReport.ToFile(cloneReportPath, cloneDetectiveResult.CloneReport); // Rollup changes within the SourceTree. foreach (SourceFile modifiedSourceFile in modifiedSourceFiles) { SourceNode modifiedSourceNode = cloneDetectiveResult.SourceTree.FindNode(modifiedSourceFile.Path); SourceTree.RecalculateRollups(modifiedSourceNode); } // Send notification about changed result to listeners. OnCloneDetectiveResultChanged(); }
/// <summary> /// Gets the text. /// </summary> /// <param name="textLines">The text lines.</param> /// <returns></returns> private static string GetText(IVsTextLines textLines) { int line, index; string buffer; if (textLines.GetLastLineIndex(out line, out index) != VSConstants.S_OK) return String.Empty; if (textLines.GetLineText(0, 0, line, index, out buffer) != VSConstants.S_OK) return String.Empty; return buffer; }
private static string GetAllText(IVsTextLines buffer) { int endLine, endIndex; string text; if (buffer.GetLastLineIndex(out endLine, out endIndex) != VSConstants.S_OK || buffer.GetLineText(0, 0, endLine, endIndex, out text) != VSConstants.S_OK) { text = null; } return text; }
public static List<EditSpan> ReformatCode(IVsTextLines pBuffer, TextSpan span, int tabSize) { string filePath = FilePathUtilities.GetFilePath(pBuffer); // Return dynamic scanner based on file extension List<EditSpan> changeList = new List<EditSpan>(); int nbLines; pBuffer.GetLineCount(out nbLines); string codeToFormat; int lastLine; int lastLineIndex; pBuffer.GetLastLineIndex(out lastLine, out lastLineIndex); pBuffer.GetLineText(0, 0, lastLine, lastLineIndex, out codeToFormat); NShaderScanner shaderScanner = NShaderScannerFactory.GetShaderScanner(filePath); Scanner lexer = shaderScanner.Lexer; lexer.SetSource(codeToFormat, 0); int spanStart; int spanEnd; pBuffer.GetPositionOfLineIndex(span.iStartLine, span.iStartIndex, out spanStart); pBuffer.GetPositionOfLineIndex(span.iEndLine, span.iEndIndex, out spanEnd); int state = 0; int start, end; ShaderToken token = (ShaderToken) lexer.GetNext(ref state, out start, out end); List<int> brackets = new List<int>(); List<int> delimiters = new List<int>(); // !EOL and !EOF int level = 0; int startCopy = 0; int levelParenthesis = 0; while (token != ShaderToken.EOF) { switch (token) { case ShaderToken.LEFT_PARENTHESIS: levelParenthesis++; break; case ShaderToken.RIGHT_PARENTHESIS: levelParenthesis--; if ( levelParenthesis < 0 ) { levelParenthesis = 0; } break; case ShaderToken.LEFT_BRACKET: level++; if (codeToFormat[start] == '{' && start >= spanStart && end <= spanEnd) { Match match = matchBraceStart.Match(codeToFormat, start); StringBuilder codeFormatted = new StringBuilder(); codeFormatted.Append("{\r\n"); int levelToIndentNext = level; if (match.Groups.Count == 2) { string matchStr = match.Groups[1].Value; levelToIndentNext--; } for (int i = 0; i < levelToIndentNext; i++) { for (int j = 0; j < tabSize; j++) { codeFormatted.Append(' '); } } if (match.Groups.Count == 2) { codeFormatted.Append("}\r\n"); } TextSpan editTextSpan = new TextSpan(); pBuffer.GetLineIndexOfPosition(start, out editTextSpan.iStartLine, out editTextSpan.iStartIndex); pBuffer.GetLineIndexOfPosition(startCopy + match.Index + match.Length, out editTextSpan.iEndLine, out editTextSpan.iEndIndex); changeList.Add(new EditSpan(editTextSpan, codeFormatted.ToString())); } break; case ShaderToken.RIGHT_BRACKET: level--; if (level < 0) { level = 0; } brackets.Add(start); break; case ShaderToken.DELIMITER: if (codeToFormat[start] == ';' && start >= spanStart && end <= spanEnd && levelParenthesis == 0) { Match match = matchEndOfStatement.Match(codeToFormat, start); StringBuilder codeFormatted = new StringBuilder(); codeFormatted.Append(";\r\n"); int levelToIndentNext = level; bool isBracketFound = (match.Groups.Count == 2 && match.Groups[1].Value == "}"); if (isBracketFound) { string matchStr = match.Groups[1].Value; levelToIndentNext--; } for (int i = 0; i < levelToIndentNext; i++) { for (int j = 0; j < tabSize; j++) { codeFormatted.Append(' '); } } if (isBracketFound) { codeFormatted.Append("}\r\n"); } TextSpan editTextSpan = new TextSpan(); pBuffer.GetLineIndexOfPosition(start, out editTextSpan.iStartLine, out editTextSpan.iStartIndex); pBuffer.GetLineIndexOfPosition(startCopy + match.Index + match.Length, out editTextSpan.iEndLine, out editTextSpan.iEndIndex); changeList.Add(new EditSpan(editTextSpan, codeFormatted.ToString())); } break; } token = (ShaderToken) lexer.GetNext(ref state, out start, out end); } return changeList; }
public static List <EditSpan> ReformatCode(IVsTextLines pBuffer, TextSpan span, int tabSize) { string filePath = FilePathUtilities.GetFilePath(pBuffer); // Return dynamic scanner based on file extension List <EditSpan> changeList = new List <EditSpan>(); int nbLines; pBuffer.GetLineCount(out nbLines); string codeToFormat; int lastLine; int lastLineIndex; pBuffer.GetLastLineIndex(out lastLine, out lastLineIndex); pBuffer.GetLineText(0, 0, lastLine, lastLineIndex, out codeToFormat); NShaderScanner shaderScanner = NShaderScannerFactory.GetShaderScanner(filePath); Scanner lexer = shaderScanner.Lexer; lexer.SetSource(codeToFormat, 0); int spanStart; int spanEnd; pBuffer.GetPositionOfLineIndex(span.iStartLine, span.iStartIndex, out spanStart); pBuffer.GetPositionOfLineIndex(span.iEndLine, span.iEndIndex, out spanEnd); int state = 0; int start, end; ShaderToken token = (ShaderToken)lexer.GetNext(ref state, out start, out end); List <int> brackets = new List <int>(); List <int> delimiters = new List <int>(); // !EOL and !EOF int level = 0; int startCopy = 0; int levelParenthesis = 0; while (token != ShaderToken.EOF) { switch (token) { case ShaderToken.LEFT_PARENTHESIS: levelParenthesis++; break; case ShaderToken.RIGHT_PARENTHESIS: levelParenthesis--; if (levelParenthesis < 0) { levelParenthesis = 0; } break; case ShaderToken.LEFT_BRACKET: level++; if (codeToFormat[start] == '{' && start >= spanStart && end <= spanEnd) { Match match = matchBraceStart.Match(codeToFormat, start); StringBuilder codeFormatted = new StringBuilder(); codeFormatted.Append("{\r\n"); int levelToIndentNext = level; if (match.Groups.Count == 2) { string matchStr = match.Groups[1].Value; levelToIndentNext--; } for (int i = 0; i < levelToIndentNext; i++) { for (int j = 0; j < tabSize; j++) { codeFormatted.Append(' '); } } if (match.Groups.Count == 2) { codeFormatted.Append("}\r\n"); } TextSpan editTextSpan = new TextSpan(); pBuffer.GetLineIndexOfPosition(start, out editTextSpan.iStartLine, out editTextSpan.iStartIndex); pBuffer.GetLineIndexOfPosition(startCopy + match.Index + match.Length, out editTextSpan.iEndLine, out editTextSpan.iEndIndex); changeList.Add(new EditSpan(editTextSpan, codeFormatted.ToString())); } break; case ShaderToken.RIGHT_BRACKET: level--; if (level < 0) { level = 0; } brackets.Add(start); break; case ShaderToken.DELIMITER: if (codeToFormat[start] == ';' && start >= spanStart && end <= spanEnd && levelParenthesis == 0) { Match match = matchEndOfStatement.Match(codeToFormat, start); StringBuilder codeFormatted = new StringBuilder(); codeFormatted.Append(";\r\n"); int levelToIndentNext = level; bool isBracketFound = (match.Groups.Count == 2 && match.Groups[1].Value == "}"); if (isBracketFound) { string matchStr = match.Groups[1].Value; levelToIndentNext--; } for (int i = 0; i < levelToIndentNext; i++) { for (int j = 0; j < tabSize; j++) { codeFormatted.Append(' '); } } if (isBracketFound) { codeFormatted.Append("}\r\n"); } TextSpan editTextSpan = new TextSpan(); pBuffer.GetLineIndexOfPosition(start, out editTextSpan.iStartLine, out editTextSpan.iStartIndex); pBuffer.GetLineIndexOfPosition(startCopy + match.Index + match.Length, out editTextSpan.iEndLine, out editTextSpan.iEndIndex); changeList.Add(new EditSpan(editTextSpan, codeFormatted.ToString())); } break; } token = (ShaderToken)lexer.GetNext(ref state, out start, out end); } return(changeList); }