/// <summary> /// Menu-command handler, undo the last occurrence /// </summary> /// <param name="sender"></param> /// <param name="e"></param> internal override void OnCommandInvoked(object sender, EventArgs e) { if (!View.HasAggregateFocus) { return; } if (AdornmentLayer.Selector.Selections.Count > 1) { AdornmentLayer.Selector.Selections.RemoveAt(AdornmentLayer.Selector.Selections.Count - 1); if (AdornmentLayer.Selector.Selections.Count == 1) { AdornmentLayer.Selector.HasWrappedDocument = false; } } if (AdornmentLayer.Selector.Selections.Any()) { AdornmentLayer.DrawAdornments(); View.Caret.MoveTo(AdornmentLayer.Selector.Selections.Last().Caret.GetPoint(AdornmentLayer.Snapshot)); View.ViewScroller.EnsureSpanVisible( new SnapshotSpan(View.Caret.Position.BufferPosition, 0) ); } }
/// <summary> /// Menu-command handler, selects previous exact occurrence /// </summary> /// <param name="sender"></param> /// <param name="e"></param> internal override void OnCommandInvoked(object sender, EventArgs e) { if (!View.HasAggregateFocus) { return; } AdornmentLayer.Selector.SelectNextOccurrence(reverseDirection: true, exactMatch: true); if (AdornmentLayer.Selector.Selections.Any()) { AdornmentLayer.DrawAdornments(); } }
/// <summary> /// Menu-command handler, puts cursors at a selections line-ends /// </summary> /// <param name="sender"></param> /// <param name="e"></param> internal override void OnCommandInvoked(object sender, EventArgs e) { if (!View.HasAggregateFocus || View.Selection.IsEmpty) { return; } AdornmentLayer.Selector.ConvertSelectionToMultipleCursors(); if (AdornmentLayer.Selector.Selections.Any()) { AdornmentLayer.DrawAdornments(); } }
/// <summary> /// Menu-command handler, aka Ctrl+D /// </summary> /// <param name="sender"></param> /// <param name="e"></param> internal override void OnCommandInvoked(object sender, EventArgs e) { if (!View.HasAggregateFocus) { return; } AdornmentLayer.Selector.SelectAllOccurrences(); if (AdornmentLayer.Selector.Selections.Any()) { AdornmentLayer.DrawAdornments(); } }
/// <summary> /// Menu-command handler, adds a new caret one line above the active caret /// </summary> /// <param name="sender"></param> /// <param name="e"></param> internal override void OnCommandInvoked(object sender, EventArgs e) { if (!View.HasAggregateFocus) { return; } if (!AdornmentLayer.Selector.Selections.Any()) { // Add current caret AdornmentLayer.Selector.AddCurrentCaretToSelections(); } AdornmentLayer.Selector.AddCaretAbove(); AdornmentLayer.DrawAdornments(); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { // Return not supported when the command does nothing int result = unchecked ((int)Constants.OLECMDERR_E_NOTSUPPORTED); if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.SolutionPlatform: return(result); } } if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { switch ((VSConstants.VSStd97CmdID)nCmdID) { case VSConstants.VSStd97CmdID.SolutionCfg: return(result); } } result = VSConstants.S_OK; System.Diagnostics.Debug.WriteLine("grp: {0}, id: {1}", pguidCmdGroup.ToString(), nCmdID.ToString()); if (!Selector.Selections.Any()) { return(ProcessSingleCursor(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut, ref result)); } bool modifySelections = false; bool clearSelections = false; if (pguidCmdGroup == typeof(VSConstants.VSStd2KCmdID).GUID || pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { switch (nCmdID) { case ((uint)VSConstants.VSStd97CmdID.Copy): case ((uint)VSConstants.VSStd97CmdID.Cut): return(HandleMultiCopyCut(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); case ((uint)VSConstants.VSStd97CmdID.Paste): // Only multi-paste different texts if all our selections have been copied with // this extension, otherwise paste as default. // Copied text get reset when new new selections are added if (Selector.Selections.All(s => !String.IsNullOrEmpty(s.CopiedText))) { return(HandleMultiPaste(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } break; case ((uint)VSConstants.VSStd97CmdID.Undo): case ((uint)VSConstants.VSStd97CmdID.Redo): result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); Selector.IsReversing = false; adornmentLayer.DrawAdornments(); return(result); } } if (pguidCmdGroup == typeof(VSConstants.VSStd2KCmdID).GUID) { switch (nCmdID) { case ((uint)VSConstants.VSStd2KCmdID.LEFT): case ((uint)VSConstants.VSStd2KCmdID.RIGHT): case ((uint)VSConstants.VSStd2KCmdID.UP): case ((uint)VSConstants.VSStd2KCmdID.DOWN): case ((uint)VSConstants.VSStd2KCmdID.WORDPREV): case ((uint)VSConstants.VSStd2KCmdID.WORDNEXT): // Remove selected spans but keep carets clearSelections = true; Selector.IsReversing = false; break; case ((uint)VSConstants.VSStd2KCmdID.CANCEL): Selector.IsReversing = false; Selector.DiscardSelections(); break; case ((uint)VSConstants.VSStd2KCmdID.PAGEDN): case ((uint)VSConstants.VSStd2KCmdID.PAGEUP): case ((uint)VSConstants.VSStd2KCmdID.END): case ((uint)VSConstants.VSStd2KCmdID.HOME): case ((uint)VSConstants.VSStd2KCmdID.END_EXT): case ((uint)VSConstants.VSStd2KCmdID.HOME_EXT): Selector.DiscardSelections(); Selector.IsReversing = false; result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); break; case ((uint)VSConstants.VSStd2KCmdID.WORDPREV_EXT): case ((uint)VSConstants.VSStd2KCmdID.BOL_EXT): case ((uint)VSConstants.VSStd2KCmdID.LEFT_EXT): case ((uint)VSConstants.VSStd2KCmdID.UP_EXT): Selector.IsReversing = Selector.Selections.All(s => !s.IsSelection()) || Selector.IsReversing || Selector.Selections.Last().Reversing(Snapshot); modifySelections = true; break; case ((uint)VSConstants.VSStd2KCmdID.WORDNEXT_EXT): case ((uint)VSConstants.VSStd2KCmdID.EOL_EXT): case ((uint)VSConstants.VSStd2KCmdID.RIGHT_EXT): case ((uint)VSConstants.VSStd2KCmdID.DOWN_EXT): Selector.IsReversing = !(Selector.Selections.All(s => !s.IsSelection()) || !Selector.IsReversing); modifySelections = true; break; } } if (Selector.Selections.Any()) { result = ProcessSelections(modifySelections, clearSelections, ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } view.Selection.Clear(); Selector.RemoveDuplicates(); } else { if (Selector.Selections.Any()) { result = ProcessSelections(modifySelections, clearSelections, ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } view.Selection.Clear(); Selector.RemoveDuplicates(); } adornmentLayer.DrawAdornments(); return(result); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { int result = VSConstants.S_OK; if (!Selector.Selections.Any()) { return(ProcessSingleCursor(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut, ref result)); } bool modifySelections = false; bool clearSelections = false; if (pguidCmdGroup == typeof(VSConstants.VSStd2KCmdID).GUID || pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { switch (nCmdID) { case ((uint)VSConstants.VSStd97CmdID.Copy): case ((uint)VSConstants.VSStd97CmdID.Cut): return(HandleCopyCut(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); case ((uint)VSConstants.VSStd97CmdID.Paste): // Only multi-paste different texts if all our selections have been copied with // this extension, otherwise paste as default. // Copied text get reset when new new selections are added if (Selector.Selections.All(s => !String.IsNullOrEmpty(s.CopiedText))) { return(HandlePaste(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } break; case ((uint)VSConstants.VSStd97CmdID.Undo): case ((uint)VSConstants.VSStd97CmdID.Redo): result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); Selector.IsReversing = false; adornmentLayer.DrawAdornments(); return(result); } } if (pguidCmdGroup == typeof(VSConstants.VSStd2KCmdID).GUID) { switch (nCmdID) { case ((uint)VSConstants.VSStd2KCmdID.TYPECHAR): case ((uint)VSConstants.VSStd2KCmdID.BACKSPACE): case ((uint)VSConstants.VSStd2KCmdID.BACKTAB): case ((uint)VSConstants.VSStd2KCmdID.RETURN): case ((uint)VSConstants.VSStd2KCmdID.BOL): case ((uint)VSConstants.VSStd2KCmdID.EOL): break; case ((uint)VSConstants.VSStd2KCmdID.LEFT): case ((uint)VSConstants.VSStd2KCmdID.RIGHT): case ((uint)VSConstants.VSStd2KCmdID.UP): case ((uint)VSConstants.VSStd2KCmdID.DOWN): case ((uint)VSConstants.VSStd2KCmdID.WORDPREV): case ((uint)VSConstants.VSStd2KCmdID.WORDNEXT): // Remove selected spans but keep carets clearSelections = true; Selector.IsReversing = false; break; case ((uint)VSConstants.VSStd2KCmdID.CANCEL): Selector.IsReversing = false; Selector.DiscardSelections(); break; case ((uint)VSConstants.VSStd2KCmdID.PAGEDN): case ((uint)VSConstants.VSStd2KCmdID.PAGEUP): case ((uint)VSConstants.VSStd2KCmdID.END): case ((uint)VSConstants.VSStd2KCmdID.HOME): case ((uint)VSConstants.VSStd2KCmdID.END_EXT): case ((uint)VSConstants.VSStd2KCmdID.HOME_EXT): Selector.DiscardSelections(); Selector.IsReversing = false; result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); break; case ((uint)VSConstants.VSStd2KCmdID.WORDPREV_EXT): case ((uint)VSConstants.VSStd2KCmdID.BOL_EXT): case ((uint)VSConstants.VSStd2KCmdID.LEFT_EXT): case ((uint)VSConstants.VSStd2KCmdID.UP_EXT): Selector.IsReversing = Selector.Selections.All(s => !s.IsSelection()) || Selector.IsReversing || Selector.Selections.Last().Reversing(Snapshot); modifySelections = true; break; case ((uint)VSConstants.VSStd2KCmdID.WORDNEXT_EXT): case ((uint)VSConstants.VSStd2KCmdID.EOL_EXT): case ((uint)VSConstants.VSStd2KCmdID.RIGHT_EXT): case ((uint)VSConstants.VSStd2KCmdID.DOWN_EXT): Selector.IsReversing = !(Selector.Selections.All(s => !s.IsSelection()) || !Selector.IsReversing); modifySelections = true; break; } } if (Selector.Selections.Any()) { result = ProcessSelections(modifySelections, clearSelections, ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } view.Selection.Clear(); Selector.RemoveDuplicates(); } else { result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } adornmentLayer.DrawAdornments(); return(result); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.SolutionPlatform: return(NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } } if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { switch ((VSConstants.VSStd97CmdID)nCmdID) { case VSConstants.VSStd97CmdID.SolutionCfg: case VSConstants.VSStd97CmdID.SearchCombo: return(NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } } var result = VSConstants.S_OK; if (!Selector.Selections.Any()) { return(ProcessSingleCursor(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut, ref result)); } var modifySelections = false; var clearSelections = false; var verticalMove = false; var invokeCommand = false; var processOrder = ProcessOrder.Normal; if (pguidCmdGroup == typeof(VSConstants.VSStd97CmdID).GUID) { switch ((VSConstants.VSStd97CmdID)nCmdID) { case VSConstants.VSStd97CmdID.Copy: case VSConstants.VSStd97CmdID.Cut: return(HandleMultiCopyCut(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); case VSConstants.VSStd97CmdID.Paste: // Only perform multi-paste if the saved clipboard have been copied with // this extension, otherwise paste as default. if (Selector.SavedClipboard.Any() && Selector.Selections.Any()) { // Copy/cut has been made from a non multi-edit place, proceed normal multi-processing if (Clipboard.GetText() != string.Join(Environment.NewLine, Selector.SavedClipboard)) { Selector.ClearSavedClipboard(); } else { return(HandleMultiPaste()); } } break; case VSConstants.VSStd97CmdID.Undo: result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); Selector.UndoSelectionsHistory(); adornmentLayer.DrawAdornments(); return(result); case VSConstants.VSStd97CmdID.Redo: result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); Selector.RedoSelectionsHistory(); adornmentLayer.DrawAdornments(); return(result); default: Debug.WriteLine($"{nameof(VSConstants.VSStd97CmdID)}, com: {(VSConstants.VSStd97CmdID) nCmdID}"); break; } } else if (pguidCmdGroup == typeof(VSConstants.VSStd2KCmdID).GUID) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.UP: case VSConstants.VSStd2KCmdID.DOWN: verticalMove = true; clearSelections = true; break; case VSConstants.VSStd2KCmdID.LEFT: case VSConstants.VSStd2KCmdID.RIGHT: case VSConstants.VSStd2KCmdID.WORDPREV: case VSConstants.VSStd2KCmdID.WORDNEXT: clearSelections = true; break; case VSConstants.VSStd2KCmdID.CANCEL: Selector.CancelSelectNextOccurence(); break; case VSConstants.VSStd2KCmdID.PAGEDN: case VSConstants.VSStd2KCmdID.PAGEUP: case VSConstants.VSStd2KCmdID.END: case VSConstants.VSStd2KCmdID.HOME: case VSConstants.VSStd2KCmdID.END_EXT: case VSConstants.VSStd2KCmdID.HOME_EXT: Selector.DiscardSelections(); result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); break; case VSConstants.VSStd2KCmdID.UP_EXT: case VSConstants.VSStd2KCmdID.DOWN_EXT: verticalMove = true; modifySelections = true; break; case VSConstants.VSStd2KCmdID.WORDPREV_EXT: case VSConstants.VSStd2KCmdID.BOL_EXT: case VSConstants.VSStd2KCmdID.LEFT_EXT: case VSConstants.VSStd2KCmdID.WORDNEXT_EXT: case VSConstants.VSStd2KCmdID.EOL_EXT: case VSConstants.VSStd2KCmdID.RIGHT_EXT: modifySelections = true; break; case VSConstants.VSStd2KCmdID.SELLOWCASE: case VSConstants.VSStd2KCmdID.SELUPCASE: case VSConstants.VSStd2KCmdID.COMMENT_BLOCK: case VSConstants.VSStd2KCmdID.UNCOMMENT_BLOCK: invokeCommand = true; break; case VSConstants.VSStd2KCmdID.TOGGLE_OVERTYPE_MODE: case VSConstants.VSStd2KCmdID.TOGGLEVISSPACE: case VSConstants.VSStd2KCmdID.TOGGLEWORDWRAP: result = NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); adornmentLayer.DrawAdornments(); return(result); default: Debug.WriteLine($"{nameof(VSConstants.VSStd2KCmdID)}, com: {(VSConstants.VSStd2KCmdID) nCmdID}"); break; } } else if (pguidCmdGroup == typeof(VSConstants.VSStd12CmdID).GUID) { switch ((VSConstants.VSStd12CmdID)nCmdID) { case VSConstants.VSStd12CmdID.MoveSelLinesUp: invokeCommand = true; processOrder = ProcessOrder.TopToBottom; break; case VSConstants.VSStd12CmdID.MoveSelLinesDown: invokeCommand = true; processOrder = ProcessOrder.BottomToTop; break; default: Debug.WriteLine($"{nameof(VSConstants.VSStd12CmdID)}, com: {(VSConstants.VSStd12CmdID) nCmdID}"); break; } } else if (pguidCmdGroup == PackageGuids.guidVS16Commands) { // Support for toggle line comment and toggle block comment command that was introduced in VS2019 if (nCmdID == 48 || nCmdID == 49) { invokeCommand = true; } else { Debug.WriteLine($"{nameof(PackageGuids.guidVS16Commands)}, id: {nCmdID}"); } } else if (pguidCmdGroup == PackageGuids.guidExtensionSubWordNavigation) { switch (nCmdID) { case PackageIds.ExtensionSubwordNavigationNextExtend: case PackageIds.ExtensionSubwordNavigationPreviousExtend: modifySelections = true; break; default: Debug.WriteLine($"{nameof(PackageGuids.guidExtensionSubWordNavigation)}, id: {nCmdID}"); break; } } else if (pguidCmdGroup == PackageGuids.guidNextOccurrenceCommandsPackageCmdSet) { return(NextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } else { Debug.WriteLine($"group: {pguidCmdGroup}, id: {nCmdID}"); } if (Selector.Selections.Any()) { result = ProcessSelections( modifySelections, clearSelections, verticalMove, processOrder, invokeCommand, ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut ); } Selector.RemoveDuplicates(); view.Selection.Clear(); adornmentLayer.DrawAdornments(); return(result); }