//todo:尽在apsx下面才有效,cs文件下无效,不知道为什么 public void ToggleRegions() { IVsHiddenTextSession session = HiddenTextSession; TextSpan[] aspan = new TextSpan[1]; aspan[0] = new VSTextView(VSTextView.ActiveTextView).GetWholeTextSpan(); //获取IVsEnumHiddenRegions IVsEnumHiddenRegions ppenum; session.EnumHiddenRegions((uint)FIND_HIDDEN_REGION_FLAGS.FHR_ALL_REGIONS, 0, aspan, out ppenum); MessageBox.Show(GetHiddenRegionCount(ppenum).ToString()); //遍历IVsEnumHiddenRegions uint fetched; IVsHiddenRegion[] aregion = new IVsHiddenRegion[1]; while (ppenum.Next(1, aregion, out fetched) == VSConstants.S_OK && fetched == 1) { uint dwState; aregion[0].GetState(out dwState); dwState ^= (uint)HIDDEN_REGION_STATE.hrsExpanded; aregion[0].SetState(dwState, (uint)CHANGE_HIDDEN_REGION_FLAGS.chrDefault); } }
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 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 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 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); } }
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); } }
public List <int> GetBlankLiens(VSTextView textView) { List <int> lines = new List <int>(); int allLines = textView.GetLines(); for (int i = 0; i < allLines; i++) { if (string.IsNullOrEmpty(textView.GetOneLineText(i).Trim())) { lines.Add(i); } } return(lines); }
/// <summary> /// 获得文档中所有的空白区域块 /// </summary> /// <param name="textView"></param> /// <param name="atLeastEmptyLines">连续几个空行才算空白区域</param> public 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); }
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> /// 寻找所有的region,不包含层级关系 /// </summary> /// <param name="classElement"></param> /// <returns></returns> public List <RegionElement> GetAllRegionsInClass(CodeElement classElement) { List <RegionElement> allRegions = new List <RegionElement>(); int currentLine = classElement.StartPoint.Line - 1; VSTextView textView = new VSTextView(VSTextView.ActiveTextView); //使用栈来寻找可能嵌套的region Stack <int> stack = new Stack <int>(); while (currentLine <= classElement.EndPoint.Line) { string region = textView.GetOneLineText(currentLine); if (region != null) { if (region.TrimStart().StartsWith("#region")) { stack.Push(currentLine); } if (region.TrimStart().StartsWith("#endregion")) { RegionElement textSpan = new RegionElement(); if (stack.Count != 0) { textSpan.StartLine = stack.Pop(); textSpan.EndLine = currentLine; textSpan.Level = stack.Count + 1; textSpan.RegionName = textView.GetOneLineText(textSpan.StartLine).Trim() .Replace("#region ", "").Replace("\r\n", ""); allRegions.Add(textSpan); } } } currentLine++; } return(allRegions); }
public List<int> GetBlankLiens(VSTextView textView) { List<int> lines = new List<int>(); int allLines = textView.GetLines(); for (int i = 0; i < allLines; i++) { if (string.IsNullOrEmpty(textView.GetOneLineText(i).Trim())) { lines.Add(i); } } return lines; }
private int GetInsertPosition(VSTextView textView, int curLineIndex, int curColumnIndex) { //在鼠标之前的第一个空格的地方插入 int col = curColumnIndex; string text = textView.GetOneLineText(curLineIndex); while (text[col] != ' ') { col--; } return col; }
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 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 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; }
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> /// 寻找所有的region,不包含层级关系 /// </summary> /// <param name="classElement"></param> /// <returns></returns> public List<RegionElement> GetAllRegionsInClass(CodeElement classElement) { List<RegionElement> allRegions = new List<RegionElement>(); int currentLine = classElement.StartPoint.Line - 1; VSTextView textView = new VSTextView(VSTextView.ActiveTextView); //使用栈来寻找可能嵌套的region Stack<int> stack = new Stack<int>(); while (currentLine <= classElement.EndPoint.Line) { string region = textView.GetOneLineText(currentLine); if (region != null) { if (region.TrimStart().StartsWith("#region")) { stack.Push(currentLine); } if (region.TrimStart().StartsWith("#endregion")) { RegionElement textSpan = new RegionElement(); if (stack.Count != 0) { textSpan.StartLine = stack.Pop(); textSpan.EndLine = currentLine; textSpan.Level = stack.Count + 1; textSpan.RegionName = textView.GetOneLineText(textSpan.StartLine).Trim() .Replace("#region ", "").Replace("\r\n", ""); allRegions.Add(textSpan); } } } currentLine++; } return allRegions; }
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); } }
/// <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="textView"></param> /// <param name="atLeastEmptyLines">连续几个空行才算空白区域</param> public 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; }