Copy to clipboard with plugin

I would like to set text into clipboard via plugin.

From code of Joplin i've seen that clipboard access is made from electron package like here:

But electron isn't dependency of plugins (made with yo joplin) and building fails.
So is there other way to copy text to clipboard with plugin?

I suppose you can add electron (or whatever else you might need) as a dependency to your plugin.

1 Like

Or a generic clipboard package would work

navigator.clipboard.writeText seems to work. Thanks.

I couldn't work out anything for pasting from clipboard. Is there a way you guys know?

What did you try @coderrsid? What's not working?

I tried using

  1. navigator.clipboard.readText() and still got undefined in that.

  2. doc.execCommand but that is deprecated right now.

  3. tried adding electron but that lead to fs error.

Ok then it needs to be added to the plugin API. Would you be able to look into it and create a pull request?

It's not complicated, you'd need to do this:

  • Add the joplin.clipboard namespace to plugins/api/Joplin.ts
  • Create a new class plugins/api/JoplinClipboard.ts
  • In there, add two methods: readText, and writeText and use the Electron method in there to read/write from/to clipboard.

If you can do this and create a PR that's great. If you cannot, also let us know as we need a bit of clarity regarding your GSoC project.

I'll try to do the things you asked and see if it works.

Couldn't understand this correctly?
I've written this code in JoplinClipboard.d.ts till now.


import Plugin from '../Plugin';

export default class JoplinClipboard {
    private store;
    private plugin;
    constructor(plugin: Plugin, store: any);
    private registerCommandAccelerators;

    readText(): Promise<string>
    writeText(): Promise<void>
}
1 Like

I'd like some advice on here. Not very comfortable with interfaces.

JoplinClipboard.d.ts is for type definition and you shouldn't manually write them (they are automatically generated). You should instead create a JoplinClipboard.ts. But where are you creating this file by the way? It should be on the main repo, so here. Basically you are adding a functionality to the main app plugin system.

1 Like

Ohh i interpreted it wrong. Sure i'll do that way.

Okay i tried adding the functionality to the main app plugin system:

const { clipboard } = require('electron');

export default class JoplinClipboard {
    
    async readText() {
        return clipboard.readText();
    }

    async writeText(text: string = null) {
        if(text === (null || undefined)) {
            return ;
        }
        return clipboard.writeText(text);
    }
}

But shouldn't we use the general write() and read() function of clipboard api from electron instead of readText() and writeText()

Thanks but there's no need to show step by step what you've done. So far, it's pretty much just what I wrote above since the check for null/undefined shouldn't be there, but you also need to compile and make sure it works with your plugin (or a simple text plugin). Could you maybe try to get it working and then create the pull request?

Sure, but how can i create a test plugin locally from updated code on my machine. I know the yeoman method. Can you guide me for that?

The first step is to build the desktop application and after that it's just like testing any plugin for development, as documented in the Getting Started page: Getting started with plugin development | Joplin

To disable type checking errors in the plugin, you can cast to any. For example, await (joplin as any).clipboard.readText()

1 Like

Another option to explore may be to add something like this to your plugin's webpack config (joplin-plugin-resource-search/webpack.config.js at 14d1e5d4d45b71345b670aac245d6fe54f0d51d9 · roman-r-m/joplin-plugin-resource-search · GitHub

	node: {
		electron: "empty",
	}

As far as I understand (Laurent and others, please correct me if I'm wrong), it makes weback assume electron will be available at runtime and not try to package it with your plugin even if you have a dependency on it.

It worked for me with fs , will it work for electron I'm not sure.

If you use my dependency, importing electron works out of the box:

import joplin from '@thejohnfreeman/joplin-plugin'
const electron = require('electron')
joplin.plugins.register({
  async onStart() {
    console.log(electron.clipboard.readText())
  }
})

If you want type checking, remember to add @types/electron as a dev dependency.