jannis-baum / vivify.vim

Live sync Vivify's Markdown viewer with Vim and Neovim
https://github.com/jannis-baum/vivify
5 stars 2 forks source link

Sync cursor when first opening on viewer #6

Open tuurep opened 3 months ago

tuurep commented 3 months ago

Hey, I've identified that one of my most common habits of opening a viewer is reading a markdown document far down somewhere, and wanting to preview that same section.

But the way it's currently set up is that it opens at top, and I have focus back to (n)vim and do a jk or something.

Of course at first I thought it'd be as simple as doing call vivify#sync_cursor() after first opening viv like so:

function! vivify#open()
    " Note: nvim's jobstart doesn't use these opt keys
    call s:job_start(
        \ ['viv', expand('%:p')],
        \ {"in_io": "null", "out_io": "null", "err_io": "null"}
    \)
    call vivify#sync_cursor()
endfunction

However then it tries syncing cursor before the webpage has finished loading (I believe?)

Putting a 1 second sleep before sync_cursor works:

function! vivify#open()
    " Note: nvim's jobstart doesn't use these opt keys
    call s:job_start(
        \ ['viv', expand('%:p')],
        \ {"in_io": "null", "out_io": "null", "err_io": "null"}
    \)
    exec 'sleep'
    call vivify#sync_cursor()
endfunction

So...

Do you know of an easy way to do the sync_cursor at the exact time the webpage has finished loading?

Maybe I could find something in how Vim's job control works. Thought I'd ask if this is something you know off the top of your head.

Also, agree it's something that should be added?

jannis-baum commented 2 months ago

I think this would be a cool addition!

tldr; I see two ways, the quick & dirty is sleep, the good is adding a query parameter to main Vivify for where to scroll when opening the page.


Do you know of an easy way to do the sync_cursor at the exact time the webpage has finished loading?

I unfortunately don't think that there is. Vim will only know when the viv command returns, which will happen whenever the system's (xgd-)open command returns, which depends on the system and holds no information about when the browser thinks the web page has finished loading. On top of this, the browser probably doesn't even know when the "web page has finished loading" in the sense that we can send the cursor sync request, because this time only comes when some client-side script has finished running and the web socket is connected to the Vivify server.

So with the current implementation Vim can't possibly know the right time to sync because of these hurdles. That said, I see two main ways we can make it sync:

  1. Using the sleep. This has the benefit of adding almost no code/implementation effort, but of course the disadvantage of not being optimally fast and/or having the chance of sending the request too early to make it do nothing at all
  2. Adding a feature to main Vivify so that we can have a query parameter that opens the web page at a specified scroll. This is of course the better way but requires small bits of work both here and on main Vivify.

If you want to implement either option I will accept the PR, the second one is of course the nicer one though :)

tuurep commented 2 months ago

Awesome, thank you. I'm going to attempt it at some point.

Lately using viv I've had to do a manual startup sync almost every single time I open it so I definitely feel motivated on this :smile: