Amend part of a note

Is it possible to get amend lines or part of a line in a note using the plugin api?

joplin.data and joplin.command do not seem to have the ability to read or replace lines or parts of lines in the same way that you can directly with the CodeMirror api.

read the complete body, modify it and write it back.

1 Like

Thanks, I thought that may be the case.

Some of my notes could be 40 A4 pages in length. Having to read in a file of this size and rewrite it back in order to insert half a dozen characters is pretty ugly especially when CodeMIrror can amend between specified lines and characters.

You can create a content script that uses CodeMirror.defineExtension to create a new command. Then from within the plugin you can use the editor.execCommand to run it.

You can find an example here

So in simple terms, how does this work please? Does it allow access to native CodeMirror calls, but effectively through the joplin api instead?

Can all CodeMirror calls be utilised through this method, such as cm.scrollIntoView or cm.scrollTo which I really need (as ScrollToHash will not work in my case).

Finally what are the advantages/disadvantages of defining an extension in this way rather then using CodeMirror code directly or have I misunderstood the way in which all this works?

Thanks for any light you can shed on this.

That's right. You don't need to define an extension actually, you can just call replaceRange or whatever you need.

That's right. You can see the definition of the execCommand here

For scrollIntoView it would look like

await joplin.commands.execute('editor.execCommand', {
	name: 'scrollIntoView',
	args: [{line: 10, ch: 20}]
});

There's no real advantages one way or the other. Defining your own extension just allows you to define what the interface looks like. I was overlooking the fact that you can just call into the codemirror api directly.
If you need to do a lot of things in the CodeMirror context (and for certain CodeMirror functionality) it makes sense to move everything into a contentScript. But for most use cases, it's better to have the majority of the code in the plugin context in order to keep the plugin process and main processes seperate.

2 Likes

I obviously wasn't thinking straight, I've just realised that whilst I can use cm.scrollIntoView to scroll the CodeMirror editor to where I want it, this won't scroll the viewer to a known position which is what I am trying to achieve, ideally from the joplin api.

Can this be done? FYI scrollToHash will not work as I'd have to insert hashes into the note which I can't do.

If I'm remembering correctly, scroll into view should work because Joplin is watching the onscroll event..

No, unfortunately it will follow a manual scroll, but not if you tell CodeMirror to scroll (jump) to a particular position. I want to be able to scroll to a particular position (line) without in the viewer with the CodeMirror editor even being open, much like scrollToHash. I know that one other plugin writer also requested this recently. It doesn't seem possible at the moment.

I have copied your code from this link to get a better understanding of the editor.execCommand but when I run the plugin and click on the "print some random string" menu item I get the following error -

Uncaught (in promise) Error: Command not found: editor.execCommand. Make sure the declaration has been registered.

Any ideas where to look please?

That's my mistake, the command is not available in the current version of Joplin. It won't be available until v1.8.0.

You'll need to run the current version of Joplin locally if you need to test it.

Okay, thanks.