mkdnflow.nvim icon indicating copy to clipboard operation
mkdnflow.nvim copied to clipboard

Feature: `MkdnEnter`/`MkdnFollowLink` follow links that are split across lines

Open binyomen opened this issue 2 years ago • 12 comments

This isn't a major issue, but I often format my markdown with hard line breaks using the gq command in vim. Sometimes this splits long links across lines. Here are a couple examples:

[some link
text](https://www.example.com/a/really/really/really/really/really/really/long/url/path)

[just a whole bunch of words in the link description that will overflow to the
next line](short-url.md)

Here are words in the line before the link and the link will be short [here it
is](short-url.md).

Links split across lines are valid markdown at least in so far as tools like Pandoc and Marked properly parse them.

When I execute MkdnEnter (mapped to {{'n', 'x'}, '<cr>'}) or MkdnFollowLink (mapped to {{'n'}, '<leader>wF'}) on these split links, mkdnflow just tries to create a new link from the cursor word rather than follow the existing link.

Would it be possible to address this so that links split by single newlines can still be followed?

Thanks so much!

binyomen avatar Aug 18 '22 04:08 binyomen

Hi @binyomen. Yeah, currently when you try to follow a link, the plug-in will look for a link pattern just on the line the cursor is on. This would definitely be possible to change, but I'll have to think a bit about what approach to take. Do you ever have links spanning more than two lines?

jakewvincent avatar Aug 19 '22 21:08 jakewvincent

I rarely have links that are more than 2 lines, but it does occur sometimes.

I'm also not sure the best way to address this. I assume you don't want to rely on tree-sitter. You could do a search of the file where you replace all single newlines with spaces, search for links, then check if the cursor is on one of them, but that might be a performance hit. Maybe a reasonable heuristic would be to search the two lines above and two lines below the cursor?

binyomen avatar Aug 20 '22 04:08 binyomen

So, what I'm thinking is that when the followLink function is triggered, I'll have it retrieve the contextual lines as well and concatenation those with the cursor line (and update the cursor index accordingly). I'm not too sure how much of a performance hit this will result in--probably negligible, but if it's more than expected I might add a new config option. A corollary update I should probably make is to the function that jumps to next/previous links, which won't work for links split over multiple lines either.

jakewvincent avatar Aug 26 '22 16:08 jakewvincent

@binyomen I've got this set up in the dev branch. If you want to pull that branch and test it out (specify branch = 'dev' if you're using Packer), that would be great. In your mkdnflow config, you'll need to specify the number of contextual lines to have the plugin consider (default is 0). The following config example would result in a total of three lines being considered when you follow a link: the line the cursor is on and the preceding and following lines.

require('mkdnflow').setup({
    links = {
        context = 1
    }
})

jakewvincent avatar Aug 28 '22 03:08 jakewvincent

Sorry for the lack of responses! I'll be doing a decent amount of markdown this next week so I'll pull it and let you know if I run into any issues. Thanks so much for taking a look at this!

binyomen avatar Aug 28 '22 05:08 binyomen

I have noticed some errors when trying to remove links using <m-cr>. Using that hotkey on the link in the following example yields the error afterwards:

Some text
and now the next line. [link text](link-text.md)
Error executing Lua callback: ...e\pack\packer\start\mkdnflow.nvim/lua\mkdnflow\links.lua:605: end_col out of bounds
stack traceback:
	[C]: in function 'nvim_buf_set_text'
	...e\pack\packer\start\mkdnflow.nvim/lua\mkdnflow\links.lua:605: in function 'destroyLink'
	...site\pack\packer\start\mkdnflow.nvim\plugin\mkdnflow.lua:40: in function <...site\pack\packer\start\mkdnflow.nvim\plugin\mkdnflow.lua:40>

This doesn't happen if there's only one line of text. If you join the two lines together it works fine. The error still occurs no matter how many lines you add after this link.

Note that I have the links.context value set to 2 in my config.

I haven't gotten a chance to dig deeper, but hopefully it should be an easy repro for you.

binyomen avatar Aug 31 '22 00:08 binyomen

Oh this makes sense. I didn't think about how the destroy link function would work for multi-line links. MkdnMoveSource (for renaming a link and the corresponding file) won't work either. It might take me a few days to get to this--I need to work on a solution that will work well for all three of these functions.

jakewvincent avatar Aug 31 '22 03:08 jakewvincent

Thanks so much for taking the time to look at this!

binyomen avatar Sep 01 '22 06:09 binyomen

@binyomen I've just pushed a new implementation of this (to the dev branch) that bakes in the consideration of contextual lines when following or manipulating links. The config key is still the same as in my first implementation (links.context), and it's 0 by default. If you're able to test the new implementation, let me know how it goes. It should now be able to handle link following, link destruction, and link renaming when the link spans one or more lines.

jakewvincent avatar Oct 03 '22 03:10 jakewvincent

I apologize for the incredibly late reply to this! It's been a wild month.

This works great! The only issue is that for multi-line links, text isn't properly rejoined with spaces. So for example this link:

[some
text](destination)

Should become:

some text

But instead it becomes:

sometext

binyomen avatar Nov 05 '22 02:11 binyomen

Just to clarify, do you mean that it becomes sometext when the markdown is rendered? (Sorry for the incredibly late reply as well!)

jakewvincent avatar Jan 02 '23 00:01 jakewvincent

I mean that after the operation (me pressing <m-cr> to delete the link) it becomes "sometext" in the file. The space isn't preserved after deleting the link.

binyomen avatar Jan 07 '23 00:01 binyomen