Jump to Header in Editor Mode?

It seems scrollToHash only works in Rich Text Editor but not in the Raw Editor. Is it possible to jump to a certain header in Raw Editor, such as by trigger a in-note search with the target title as search keyword?

Joplin uses the CodeMirror editor when in markdown mode. The plugin contentScript features give you full access to the CodeMirror editor. This means you can write a custom scrollTo implementation for the editor and use it from your plugin.

Thanks for the link! But as I am trying to implement this feature, I met a few problems:

  1. Current CodeMirror instance (cm) is can not be retrived using contentScript feature. I can only get the class but not the instance. Is it possible to get the current CodeMirror instance using contentScript?

  2. As a workaround, I tried to use joplin.command.execute (editor.execCommand) and use scrollIntoView as the command name along with the line number parameter, as shown below.

await joplin.commands.execute('editor.execCommand', {
          name: 'scrollIntoView',
          args: [{line: message.lineno, char: 0}],
        })

This works, but the target line only appears in the bottom of the editor. scrollIntoView command has a parameter named margin, which is the amount of vertical pixels around the given area that should be made visible. To move the header line to top of the editor, I need to get the current viewpoint and calculate the margin. However, it seems that editor.execCommand don't return anything.

const currentView = await joplin.commands.execute('editor.execCommand', {
          name: 'getScrollInfo',
          args: []
        })
console.log(currentView) // undefined
  1. I'd like the "jump to header" feature work both in the raw editor mode and the WYSIWYG mode, but currently there isn't a way to tell which editor is displayed via the plugin API. If I use both scrollToHash and scrollIntoView, only the scrollToHash will work. Is there anyway to change the plugin's behavior based on the current editor mode?

If you define an extension through the CodeMirror content script, you will have access to the current cm instance as the this variable. You can find an example of defining the extension here.

My suggestion for you would be to define a 'scrollToHash` command (defineExtension in CodeMirror lingo) for the CodeMirror editor, then you can call that to scroll. I don't think anything bad will happen if you call it and the WYSIWYG editor is open. Likewise you can call the regular scroll to hash, without hurting anything when CodeMirror is open. So if you call both, I think you'll get the behaviour you want.

Thanks for the example! I tweaked around and now it works in Markdown editor mode. Unfortunately, scrollToHash still triggers scrolling in CodeMirror. (Bad thing do happen and it hurts...)

joplin/useWindowCommandHandler.ts at 80b16dd17e227e3f538aa221d7b6cc2d81688e72 · laurent22/joplin (github.com)

Currently I am trying to workaround this issue by manually delaying the CodeMirror scrollTo operation by 200ms after calling scrollToHash. In the editor it will first scroll up then scroll down. This kinds of works but I think that's not a very elegant solution.

joplin_scroll

I did a check and it looks like you can actually get the currently opened editor! You can get the currently opened editor from settings, using the globalValue function.
You can use it like this.

let codeMirrorOpen = joplin.settings.globalValue('editor.codeView');
1 Like

Thanks! I just removed the delay workaround and used the global setting value. Now it works flawlessly, whether in editor, preview or split mode. I just submitted a pull request to the joplin-outline plugin. A new version with scroll to header support in editor mode should be released soon.

Pull Request: Support Scroll to Header In Editor Mode by jerrylususu · Pull Request #43 · cqroot/joplin-outline (github.com)

Demo
joplin_outline_new

2 Likes

The pull request mentioned in #7 is rejected as the scrolling function failed in the viewer mode. After some digging I found that there is a globalValue called noteVisiblePanes, which is an array showing whether editor or viewer or both is visible. Adding an additional if check fixes the issue. Just want to mention it here so future developer may find this helpful.

2 Likes

My PR is merged! :tada: You can try the newest version (1.25) of joplin-outline plugin here:
Release 1.2.5 · cqroot/joplin-outline (github.com)

1 Like