Mark M
Mark M

Reputation: 2257

In a VS Code extension, how can I be notified when the user cuts/copies/or pastes?

For my extension I need to know when a cut/copy/paste happens and be able to get the text associated with those operations. I can probably get the text from the editor if I know when they happen.

I cannot find a listener for these operations. I suppose I can look for ctrl-x, ctrl-c, and ctrl-v keyboard inputs but some users may use the edit menu and not use the keyboard.

Is there a way to be notified when these operations happen either from the keyboard or the edit menu?

Upvotes: 4

Views: 2899

Answers (3)

Mark
Mark

Reputation: 181208

There is a proposed api in v1.68 for intercepting and modifying pastes. Since it is proposed for now you can only test it in the Insiders Build.

See copy/paste proposed extension api:

The new documentPaste API proposal lets extensions hook into copy and paste inside text editors. This can be used to modify the text that is inserted on paste. Your extension can also store metadata when text copy and use this metadata when pasting (for example for bringing along imports when pasting between two code files).

The document paste extension sample shows this API in action: <-long code example in the release notes->

Here is the actual (brief) api: proposed documentPaste api

See also using a proposed api

Upvotes: 0

Mark M
Mark M

Reputation: 2257

Original asker here...

I came up with a solution that involves overriding the default cut/copy/paste actions in the editor. Here is the code for 'copy' in extension.js (I am using js not ts):

//override the editor.action.clipboardCopyAction with our own
var clipboardCopyDisposable = vscode.commands.registerTextEditorCommand('editor.action.clipboardCopyAction', overriddenClipboardCopyAction); 

context.subscriptions.push(clipboardCopyDisposable);

/*
 * Function that overrides the default copy behavior. We get the selection and use it, dispose of this registered
 * command (returning to the default editor.action.clipboardCopyAction), invoke the default one, and then re-register it after the default completes
 */
function overriddenClipboardCopyAction(textEditor, edit, params) {

    //debug
    console.log("---COPY TEST---");

    //use the selected text that is being copied here
    getCurrentSelectionEvents(); //not shown for brevity

    //dispose of the overridden editor.action.clipboardCopyAction- back to default copy behavior
    clipboardCopyDisposable.dispose();

    //execute the default editor.action.clipboardCopyAction to copy
    vscode.commands.executeCommand("editor.action.clipboardCopyAction").then(function(){

        console.log("After Copy");

        //add the overridden editor.action.clipboardCopyAction back
        clipboardCopyDisposable = vscode.commands.registerTextEditorCommand('editor.action.clipboardCopyAction', overriddenClipboardCopyAction);

        context.subscriptions.push(clipboardCopyDisposable);
    }); 
}

This definitely doesn't feel like the best solution... however it does seem to work. Any comments/suggestions? Are there any issues that repeatedly registering and unregistering will cause?

Upvotes: 3

Matt Bierner
Matt Bierner

Reputation: 65253

There is no api to access the clipboard directly but some extensions override the default copy and paste shortcuts to customize the copy paste behavior. Here are two examples:

As you note, that approach will not work when copying using the context menu however. For supporting that as well, you could try intercepting the editor.action.clipboardCopyAction command. See how the Vim extension intercepts the type command for an example of this: https://github.com/VSCodeVim/Vim/blob/aa8d9549ac0d31b393a9346788f9a9a93187c222/extension.ts#L208

Upvotes: 1

Related Questions