2

This question is similar to Disabling single line copy in Visual Studio, except that I'm wanting to change it to just copy the word the cursor is on, if nothing is not selected. If it's on white space, sure, I don't care, copy the line, but 99% I'm trying to copy a word, not the line Is this possible?

Daryl
  • 18,592
  • 9
  • 78
  • 145
  • I don't know if you can make it copy the word your cursor is on, but it looks like you can turn whole line copy off: https://stackoverflow.com/questions/10959126/turn-off-whole-line-copy-in-visual-studio – Andrew Meservy May 01 '19 at 20:22
  • @AndrewMeservy that answer appears to apply to using Macros. I don't believe Macros are supported in VS 2017 – Daryl May 01 '19 at 20:26
  • hmm... good point. I think the problem is that the Edit.Copy keyboard functionality is mapped to do the entire line and it doesn't seem like there is much that can be done about that. I did find one more link for you to try out: https://stackoverflow.com/questions/39322024/turn-off-whole-line-copy-in-visual-studio-code?rq=1 – Andrew Meservy May 01 '19 at 20:29
  • It does however, look like there is an extension that will let you do macros: https://stackoverflow.com/questions/12062515/can-i-record-play-macros-in-visual-studio-2012-2013-2015-2017 – Andrew Meservy May 01 '19 at 20:31
  • 1
    @AndrewMeservy I reached out to the authors of that github extensions, but it doesn't have the concept of knowing if something is currently selected... so that wouldn't work. – Daryl May 02 '19 at 18:24

1 Answers1

4

To copy the word the caret is on, you can assign a shortcut to the following Visual Commander (developed by me) command (language C#):

public class C : VisualCommanderExt.ICommand
{
    public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package) 
    {
        this.DTE = DTE;
        EnvDTE.TextSelection ts = TryGetFocusedDocumentSelection();
        if (ts != null && ts.IsEmpty)
            CopyWord(ts);
        else if (IsCommandAvailable("Edit.Copy"))
            DTE.ExecuteCommand("Edit.Copy");
    }

    private void CopyWord(EnvDTE.TextSelection ts)
    {
        EnvDTE.EditPoint left = ts.ActivePoint.CreateEditPoint();
        left.WordLeft();

        EnvDTE.EditPoint right = ts.ActivePoint.CreateEditPoint();
        right.WordRight();

        System.Windows.Clipboard.SetText(left.GetText(right));
    }

    private EnvDTE.TextSelection TryGetFocusedDocumentSelection()
    {
        try
        {
            return DTE.ActiveWindow.Document.Selection as EnvDTE.TextSelection;
        }
        catch(System.Exception)
        {
        }
        return null;
    }

    private bool IsCommandAvailable(string commandName)
    {
        EnvDTE80.Commands2 commands = DTE.Commands as EnvDTE80.Commands2;
        if (commands == null)
            return false;
        EnvDTE.Command command = commands.Item(commandName, 0);
        if (command == null)
            return false;
        return command.IsAvailable;
    }

    private EnvDTE80.DTE2 DTE;
}
Sergey Vlasov
  • 26,641
  • 3
  • 64
  • 66
  • This looks like you have to have some text selected (EnvDTE.TextSelection) in order for this to work? If I have text selected, I want it to just copy the selection, if I don't, then I want to select and copy the word the cursor is on. Does the visual Commander support this? – Daryl May 02 '19 at 18:27
  • 1
    @Daryl The sample works when nothing is selected. It just gets the active point from the selection, not selected text. – Sergey Vlasov May 03 '19 at 04:16
  • Can you change it so that if something is selected, the selection is copied, just like a normal Ctrl+C, but if nothing is selected, then the word the cursor is currently in is copied? – Daryl May 03 '19 at 10:09
  • 1
    @Daryl I've changed it to normal copy when something is selected. – Sergey Vlasov May 03 '19 at 16:17
  • Any suggestions on the best way to transfer this to my next computer, or version of VS? – Daryl May 03 '19 at 20:22
  • hmm... did find that it doesn't work when I'm doing a comparison on check-in. If I click the old version, and do a Ctrl+C, it copies the value from where the caret is in the new file, rather than the old... – Daryl May 04 '19 at 02:16
  • 1
    To transfer the command to another computer, VCmd menu - Export it and then Import. Within a computer, commands are shared between all versions of VS. – Sergey Vlasov May 04 '19 at 02:47
  • @Daryl Yes, VS diff window uses a single document to show two files. It should be possible to access separate files via IWpfTextView, but it will be a completely different command implementation. – Sergey Vlasov May 04 '19 at 12:21
  • I'm having lots of issues with the command not realizing that it isn't the active window. Maybe I'm in the immediate window, or in an exception window, or some other window. It copies the value from the Code editor window. Any way for it to tell if it has focus, and if not, don't do anything? – Daryl May 14 '19 at 11:33
  • @Daryl I've changed DTE.ActiveDocument to DTE.ActiveWindow.Document to detect the actually focused window. – Sergey Vlasov May 14 '19 at 16:20
  • hmm... this still isn't working... It still doesn't work when trying to copy something from the old version of the compare... – Daryl May 21 '19 at 00:54
  • @Daryl Yes, to support the diff window requires completely different implementation. – Sergey Vlasov May 21 '19 at 02:24
  • Unfortunately, all of the edge cases where the Visual Commander does not recognize what window has the focus makes this too frustrating to use. – Daryl Jun 10 '19 at 13:51