public static List <TextSpan> GetEmptyRegions(VSTextView textView) { List <TextSpan> allRegions = new List <TextSpan>(); List <TextSpan> textSpans = GetAllRegions(textView.GetWholeText()); for (int i = 0; i < textSpans.Count; i++) { TextSpan region = textSpans[i]; bool hasContent = false; //检测start和end之间是否都是空行 for (int j = region.iStartLine + 1; j <= region.iEndLine - 1; j++) { string s = textView.GetOneLineText(j); if (!string.IsNullOrEmpty(s.Trim())) { //region之间有内容 hasContent = true; break; } } if (!hasContent) { allRegions.Add(region); } } return(allRegions); }
protected override void OnExecute(Microsoft.VisualStudio.Shell.OleMenuCommand command) { VSCodeModel codeModel = new VSCodeModel(); VSTextView textView = new VSTextView(VSTextView.ActiveTextView); if (string.IsNullOrEmpty(textView.GetSelectedText().Trim())) { MessageBox.Show("please select valid text"); return; } //需要判断选中的内容属于哪个类或结构体下面 TextSpan ts = textView.GetSelectedSpan(); CodeElement classElement = GetClassElementSelectionBelong(textView, codeModel); if (classElement == null) { MessageBox.Show("Can't detect which class or struct the selection belongs to"); return; } MoveToRegionForm form = new MoveToRegionForm(classElement); form.OnSelectRegion += form_OnSelectRegion; form.ShowDialog(); }
private bool ReplaceComment() { //找到光标所在行的注释的textspan //在首尾添加增加的注释 TextSpan textSpan = GetCommentTextSpanAtCurrentCaret(); VSTextView textView = new VSTextView(VSTextView.ActiveTextView); if (textView != null && textSpan.iStartLine != -1) { //查看是否已经被替换过了 if (textView.GetOneLineText(textSpan.iStartLine + 1).Trim().StartsWith("///") && !textView.GetOneLineText(textSpan.iStartLine).Trim().StartsWith("#region")) { //using (VSUndo.StartUndo()) //{ // string spaceStr = GetSpaceBeforeComment(textView.GetOneLineText(textSpan.iStartLine + 1)); // textView.InsertText("\r\n" + spaceStr + "#region test", textSpan.iStartLine, 0); // textView.InsertText(spaceStr + "#endregion\r\n", textSpan.iEndLine + 1, 0); // textView.SetCursorPositon(textSpan.iStartLine + 1, spaceStr.Length); // VSDocument.SaveActiveDocument(); // DelayExecute.Execute(3000, () => // { // VSBase.ExecuteCommand((uint)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_CURRENT); // }); // return false; //} } } return(true); }
/// <summary> /// 得到选中部分所在的classElement /// </summary> /// <returns></returns> private CodeElement GetClassElementSelectionBelong(VSTextView textView, VSCodeModel codeModel) { TextSpan ts = textView.GetSelectedSpan(); return(codeModel.GetClassInCurrentFile().Where(o => o.StartPoint.Line < ts.iStartLine && o.EndPoint.Line > ts.iEndLine).FirstOrDefault()); }
protected override void OnExecute(Microsoft.VisualStudio.Shell.OleMenuCommand command) { int curLineIndex, curColumnIndex; VSTextView textView = new VSTextView(VSTextView.ActiveTextView); if (textView == null) { MessageBox.Show("textView is null"); return; } textView.GetCursorPositon(out curLineIndex, out curColumnIndex); //帮助:http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/c62a70eb-d84c-4410-890d-b41a86b2b55f/ ILangService langService; LangService_GetInstance(out langService); if (langService == null) { MessageBox.Show("langService is null"); return; } IDECompilerHost compilerHost = new IDECompilerHost(); IProject prj; Project currentPro = VSDocument.ActiveDocument.ProjectItem.ContainingProject; LangService_GetDteProject(langService, currentPro, out prj); if (prj == null) { MessageBox.Show("prj is null"); return; } FileName fileName = new Microsoft.RestrictedUsage.CSharp.Core.FileName(VSDocument.ActiveDocument.FullName); CSRPOSDATA data = new CSRPOSDATA() { LineIndex = curLineIndex, ColumnIndex = curColumnIndex }; CSharpMember m = Utilities.GetMemberAtLocation(compilerHost, prj, fileName.Value, data); if (m != null && m.ReturnType != null) { string returnName = m.ReturnType.GetFormattedName(InteropTypeFormatFlags.TypeFormatFlags_BestNameGUI); returnName = FilterReturnName(returnName); if (string.IsNullOrEmpty(returnName)) { return; } int insertCol = GetInsertPosition(textView, curLineIndex, curColumnIndex); textView.InsertText(returnName + " v =", curLineIndex, insertCol); textView.SelectText(curLineIndex, insertCol + returnName.Length + 1, curLineIndex, insertCol + returnName.Length + 2); } }
private static void InsertBlackLineBefore() { int line, col; VSTextView textView = new VSTextView(VSTextView.ActiveTextView); textView.GetCursorPositon(out line, out col); textView.InsertText("\r\n", line, 0); textView.MoveCursorTo(line, textView.GetStartTextIndexOfCurrLine()); }
private static void InsertPair(string pair) { if (BaseUCSetting.SettingModel.AutoBraceModel.OpenAutoBrace) { int currentLineIndex, currentColIndex; VSTextView textview = new VSTextView(VSTextView.ActiveTextView); textview.GetCursorPositon(out currentLineIndex, out currentColIndex); textview.InsertText(pair, currentLineIndex, currentColIndex); textview.MoveCursorTo(currentLineIndex, currentColIndex); } }
private static void SelectCurrentLine() { VSTextView text = new VSTextView(VSTextView.ActiveTextView); if (text != null) { int line = 0; int col = 0; text.GetCursorPositon(out line, out col); text.SelectText(line, 0, line, text.GetOneLineText(line).Length); } }
private void CleanBlankLine(VSCodeModel codeModel) { VSTextView textView = new VSTextView(VSTextView.ActiveTextView); List <TextSpan> blankLines = codeModel.GetBlankLines(textView, 3); //超过3行空白的一律合并 for (int i = blankLines.Count - 1; i >= 0; i--) { TextSpan emptyRegion = blankLines[i]; textView.DeleteText(emptyRegion.iStartLine, 0, emptyRegion.iEndLine, 0); } }
private int GetInsertPosition(VSTextView textView, int curLineIndex, int curColumnIndex) { //在鼠标之前的第一个空格的地方插入 int col = curColumnIndex; string text = textView.GetOneLineText(curLineIndex); while (text[col] != ' ') { col--; } return(col); }
/// <summary> /// 获得类体开始的行数 /// </summary> /// <param name="textView"></param> /// <param name="element"></param> /// <returns></returns> private int GetElementBodyStartLine(VSTextView textView, CodeElement element) { int line = element.StartPoint.Line; int start = line; while (start < textView.GetLines()) { if (textView.GetOneLineText(start).TrimStart().StartsWith("{")) { line = ++start; break; } start++; } return(line); }
/// <summary> /// 监测插入的文本位置上下是否有一行空白,如果没有则自动添加 /// </summary> /// <param name="insertLine"></param> /// <param name="insertLineCount"></param> private void InsertBlankLineAroundInsert(int insertLine, int insertLineCount) { VSTextView textView = new VSTextView(VSTextView.ActiveTextView); int endLine = insertLine + insertLineCount + 1; if (!string.IsNullOrEmpty(textView.GetOneLineText(endLine))) { textView.InsertText("\r\n", endLine, 0); } int startLine = insertLine - 1; if (!string.IsNullOrEmpty(textView.GetOneLineText(startLine))) { textView.InsertText("\r\n", startLine + 1, 0); } }
private void ShowSuggest() { if (VSTextView.ActiveTextView == null) { return; } VSTextView textView = new VSTextView(VSTextView.ActiveTextView); //检测到前面的类型名字 //如果类型后面隔了一个空格这进行提示,否则不提示 int cursorLine; int cursorCol; textView.GetCursorPositon(out cursorLine, out cursorCol); string before = textView.GetText(cursorLine, cursorCol - 1, cursorLine, cursorCol); }
private int CutRegionFlag(VSTextView textView, int topStart, int methodStart) { //这里要从下面往上找,不能从上往下找否则找到的第一个后面可能还会存在#region int current = methodStart; while (current > topStart) { string lineStr = textView.GetOneLineText(current).Trim(); if (lineStr.StartsWith("#region") || lineStr.StartsWith("#endregion")) { //返回#region 或者 #endregion的下一行作为分界线 return(++current); } current--; } return(topStart); }
/// <summary> /// 获得文档中所有的空白区域块 /// </summary> /// <param name="textView"></param> /// <param name="atLeastEmptyLines">连续几个空行才算空白区域</param> public static List <TextSpan> GetBlankLines(VSTextView textView, int atLeastEmptyLines) { List <TextSpan> blankLineRegion = new List <TextSpan>(); List <int> blankLiens = GetBlankLiens(textView); for (int i = 0; i < blankLiens.Count; i++) { TextSpan region = new TextSpan(); int startBlank = blankLiens[i]; region.iStartLine = startBlank; bool hasSequentialBlank = true; while (hasSequentialBlank) { if (i == blankLiens.Count - 1) //循环到了最后一行 { region.iEndLine = blankLiens[i]; if (region.iEndLine - region.iStartLine >= atLeastEmptyLines - 1) { blankLineRegion.Add(region); } break; } if (blankLiens[i + 1] != blankLiens[i] + 1) //检查下一个空行的行号是否是上一个空行行号+1 { hasSequentialBlank = false; region.iEndLine = blankLiens[i]; if (region.iEndLine - region.iStartLine >= atLeastEmptyLines - 1) { blankLineRegion.Add(region); } i--; //把下面i++多的减掉 } i++; } } return(blankLineRegion); }
public static List <int> GetBlankLiens(VSTextView textView) { List <int> lines = new List <int>(); using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(textView.GetWholeText()))) { parser.ParseMethodBodies = false; parser.Parse(); List <ISpecial> currentSpecials = parser.Lexer.SpecialTracker.CurrentSpecials; TextSpan textSpan = new TextSpan(); foreach (ISpecial currentSpecial in currentSpecials) { if (currentSpecial is BlankLine) { BlankLine region = currentSpecial as BlankLine; lines.Add(region.StartPosition.Line - 1); } } } return(lines); }
protected override void OnExecute(Microsoft.VisualStudio.Shell.OleMenuCommand command) { TextSelection selection = VSTextView.ActiveTextSelection; if (selection != null) { string selectedText = selection.Text; if (string.IsNullOrEmpty(selectedText)) { VSTextView view = new VSTextView(VSTextView.ActiveTextView); if (view != null) { selectedText = view.GetOneLineText(selection.TopPoint.Line - 1); view.InsertText(selectedText, selection.TopPoint.Line, 0); } } else { selection.Insert(selectedText + "\n" + selectedText); } } }
/// <summary> /// 得到文档中的using区域信息 /// </summary> /// <param name="textView"></param> /// <returns></returns> public static List <TextSpan> GetUsingDeclaration(VSTextView textView) { //List<int> lines = new List<int>(); ////using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(textView.GetWholeText()))) ////{ //// parser.ParseMethodBodies = false; //// parser.Parse(); //// List<ISpecial> currentSpecials = parser.Lexer.SpecialTracker.CurrentSpecials; //// TextSpan textSpan = new TextSpan(); //// foreach (ISpecial currentSpecial in currentSpecials) //// { //// if (currentSpecial is BlankLine) //// { //// BlankLine region = currentSpecial as BlankLine; //// lines.Add(region.StartPosition.Line - 1); //// } //// } ////} //return lines; return(null); }
private TextSpan GetCommentTextSpanAtCurrentCaret() { VSTextView textView = new VSTextView(VSTextView.ActiveTextView); if (textView != null) { int line, col; textView.GetCursorPositon(out line, out col); int topIndex = line; int bottomIndex = line; string topLineText = textView.GetOneLineText(topIndex); while (!string.IsNullOrEmpty(topLineText) && topLineText.Trim().StartsWith("///")) { topIndex--; topLineText = textView.GetOneLineText(topIndex); } string bottomLineText = textView.GetOneLineText(bottomIndex); while (!string.IsNullOrEmpty(topLineText) && bottomLineText.Trim().StartsWith("///")) { bottomIndex++; bottomLineText = textView.GetOneLineText(bottomIndex); } return(new TextSpan() { iStartLine = topIndex, iEndLine = bottomIndex }); } return(new TextSpan() { iStartLine = -1, iEndLine = -1 }); }
private void form_OnSelectRegion(RegionElement region) { VSTextView textView = new VSTextView(VSTextView.ActiveTextView); TextSpan ts = textView.GetSelectedSpan(); string cutStr = textView.GetText(ts.iStartLine, 0, ts.iEndLine + 1, 0); //if (!cutStr.StartsWith("\r\n")) //{ // cutStr = "\r\n" + cutStr; //} //if (!cutStr.EndsWith("\r\n")) //{ // cutStr = cutStr + "\r\n"; //} //判断要移动的文本和region的关系 if (ts.iStartLine > region.EndLine) { //要移动的文本在region下面,此时需要先删除再插入。才能让传过来的insertLine有效 textView.DeleteText(ts.iStartLine, 0, ts.iEndLine + 1, 0); textView.InsertText(cutStr, region.EndLine, 0); InsertBlankLineAroundInsert(region.EndLine, ts.iEndLine - ts.iStartLine); } else if (ts.iEndLine < region.StartLine) { //文本在region上面,先插入再删除 textView.InsertText(cutStr, region.EndLine, 0); textView.DeleteText(ts.iStartLine, 0, ts.iEndLine + 1, 0); //文本删除后,因为region要往上移动,所以这里的region实际位置发生了变化 InsertBlankLineAroundInsert(region.EndLine - (ts.iEndLine - ts.iStartLine) - 1, ts.iEndLine - ts.iStartLine); } else { MessageBox.Show("Selected text has intersection with this region, can't handle request."); } }
public IEnumerable <ITagSpan <EasyVSSmartTag> > GetTags(NormalizedSnapshotSpanCollection spans) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; if (snapshot.Length == 0) { yield break; //don't do anything if the buffer is empty } VSTextView tv = new VSTextView(VSTextView.ActiveTextView); int line, col; tv.GetCursorPositon(out line, out col); if (VSDocument.ActiveDocument != null) { //EditPoint p = tv.GetEditPoint(line, col); //CodeElement c = VSDocument.ActiveDocument.ProjectItem.FileCodeModel.CodeElementFromPoint(p, vsCMElement.vsCMElementProperty); //if (c != null) //{ //} //CodeElements elements = VSDocument.ActiveDocument.ProjectItem.FileCodeModel .CodeElements; //foreach (CodeElement element in elements) //{ // if (element.Kind == vsCMElement.vsCMElementNamespace) // { // CodeNamespace ns = (CodeNamespace)element; // foreach (CodeElement elem in ns.Members) // { // if (elem is CodeClass) // { // CodeClass cls = elem as CodeClass; // foreach (CodeElement member in cls.Members) // if (member is CodeProperty) // { // CodeType memberType = ((member as CodeProperty)).Type.CodeType; // } // } // } // } //} //set up the navigator ITextStructureNavigator navigator = smartTaggerProvider.NavigatorService.GetTextStructureNavigator(textBuffer); foreach (var span in spans) { ITextCaret caret = textView.Caret; SnapshotPoint point; if (caret.Position.BufferPosition > 0) { point = caret.Position.BufferPosition - 1; } else { yield break; } TextExtent extent = navigator.GetExtentOfWord(point); //don't display the tag if the extent has whitespace if (extent.IsSignificant) { yield return(new TagSpan <EasyVSSmartTag>(extent.Span, new EasyVSSmartTag(GetSmartTagActions(extent.Span)))); } else { yield break; } } } }
public void RegionElement(List <CodeElement> needRegionElements, int classIndex, string regionName) { VSTextView textView = new VSTextView(VSTextView.ActiveTextView); VSCodeModel codeModel = new VSCodeModel(); List <TextSpan> methodsBody = new List <TextSpan>(); StringBuilder sb = new StringBuilder(); foreach (CodeElement item in needRegionElements) { //在这里获得的位置是最新的修改后的位置。 CodeElement ce = codeModel.GetPrevElementInCurrentFile(item); if (ce != null) { TextSpan es = new TextSpan(); //这里的行数全部以(0,0)开始 es.iEndLine = item.EndPoint.Line - 1; //当前元素的开始定位其上一个元素的结尾 es.iStartLine = ce.EndPoint.Line; //当前元素是第一个元素,所以他的开始应该是紧接着他父元素 if (ce == item) { CodeElement parentElement = codeModel.GetParentElementInCurrentFile(item); int parentElementStartLine = GetElementBodyStartLine(textView, parentElement); es.iStartLine = parentElementStartLine; } //检查es.iStartLine到item.StartLine之间有没有#region或者#endregion,这些 //东西不能为算在里面,否则粘贴后会破坏现有的region es.iStartLine = CutRegionFlag(textView, es.iStartLine, item.StartPoint.Line); methodsBody.Add(es); sb.Append(textView.GetText(es.iStartLine, 0, es.iEndLine + 1, 0)); } } //开始删除原来的节点 int filedCount = methodsBody.Count; for (int i = filedCount - 1; i >= 0; i--) { textView.DeleteText(methodsBody[i].iStartLine, 0, methodsBody[i].iEndLine + 1, 0); } //插入新的region包围的内容 //首先检查当前是否已经存在给定的regionName,如果存在则不用新建 if (filedCount > 0) { //需要重新获得删除节点后最新的class位置信息 List <CodeElement> classLists = GetClassAndStructInFile(codeModel); int line = GetElementBodyStartLine(textView, classLists[classIndex]); //检查有没有已经同名的region int r = CheckExistRegionName(regionName, classLists[classIndex]); if (r != -1) { line = r; } else { sb.Insert(0, "\t\t#region " + regionName + "\r\n\r\n"); sb.Append("\t\n\t\t#endregion\r\n\r\n"); } textView.InsertText(sb.ToString(), line, 0); } }