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

feature: only "unconceal" at the cursorline

Open petobens opened this issue 1 year ago • 6 comments
trafficstars

Is your feature request related to a problem? Please describe.

Consider the folllowing minimal init.lua file:

local root = '/tmp/nvim-minimal'

-- Set stdpaths to use root dir
for _, name in ipairs({ 'config', 'data', 'state', 'cache' }) do
    vim.env[('XDG_%s_HOME'):format(name:upper())] = root .. '/' .. name
end

-- Bootstrap lazy
local lazypath = root .. '/plugins/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({
        'git',
        'clone',
        '--filter=blob:none',
        '--single-branch',
        'https://github.com/folke/lazy.nvim.git',
        lazypath,
    })
end
vim.opt.runtimepath:prepend(lazypath)

-- Install plugins
local plugins = {
    {
        'MeanderingProgrammer/render-markdown.nvim',
        dependencies = {
            'nvim-treesitter/nvim-treesitter',
            'nvim-tree/nvim-web-devicons',
        },
        config = function()
            require('render-markdown').setup({
                win_options = {
                    -- FIXME: With i it shows all but with t only the cursor
                    conceallevel = { rendered = 2 },
                    concealcursor = { rendered = 'nc' },
                },
            })
        end,
    },
    {
        'nvim-treesitter/nvim-treesitter',
        build = ':TSUpdate',
        config = function()
            require('nvim-treesitter.configs').setup({
                ensure_installed = {
                    'markdown',
                    'markdown_inline',
                },
            })
        end,
    },
}

require('lazy').setup(plugins, {
    root = root .. '/plugins',
})

Now, as in the GIF, open nvim and edit the following bar.md file:

# Heading 1

## Heading 2

### Heading 3

You will see that if you press i in order to get into insert mode every text in every heading is "unconceal`.

On the other hand if I disable the plugin and just use some treesitter queries (as per https://github.com/petobens/dotfiles/blob/master/nvim/queries/markdown/highlights.scm) the ability to unconceal only at the cursor seems to work just fine (i.e only the Heading 3 line is unconcealed whereas Heading 1 and Heading 2 remain properly concealed).

Peek 2024-10-12 11-26

Describe the solution you'd like

See above

Describe alternatives you've considered

See above

Additional information

No response

petobens avatar Oct 12 '24 14:10 petobens

Bonus: one extra thing I noticed is that if we have markdown link as in:

[Google](www.google.com)

then when the cursor in on that line the icon disappears (even in normal mode). I would expect the icon not to disappear.

Peek 2024-10-12 11-38

petobens avatar Oct 12 '24 14:10 petobens

So there's 2 kinds of concealing happening.

The one you're describing that works is via treesitter highlights, where concealcursor dictates the behavior. However these are rather limited and impossible to make dynamic as they come from essentially a static file.

The second is all of the custom decorations added by this plugin which uses extmarks. To show and hide these there is an internal event listener that knows where your cursor is at and what to show / hide.

The setting you're looking for that controls this behavior is render_modes: https://github.com/MeanderingProgrammer/render-markdown.nvim/wiki#render-modes.

You can set this to a list of specific modes, the default value is:

require('render-markdown').setup({
    render_modes = { 'n', 'c' },
})

So to add insert mode to the modes we render marks for you would do:

require('render-markdown').setup({
    render_modes = { 'n', 'c', 'i' },
})

Or if you want rendering to happen in all modes you can simply set it to true:

require('render-markdown').setup({
    render_modes = true,
})

MeanderingProgrammer avatar Oct 12 '24 19:10 MeanderingProgrammer

For your bonus one, the implementation as is removes everything on the cursor line, the goal is to see the actual text. There is an exception for spacing elements to avoid overly jumpy behavior, but in general the goal was to let you interact with what's actually there.

I can try out an implementation that would make what stays and what goes on the cursor line more configurable, LMK if there are any other elements, in addition to link icons, that should not be hidden away.

MeanderingProgrammer avatar Oct 12 '24 20:10 MeanderingProgrammer

Or if you want rendering to happen in all modes you can simply set it to true:

Great! Thanks

I can try out an implementation that would make what stays and what goes on the cursor line more configurable MK > if there are any other elements, in addition to link icons, that should not be hidden away

Awesome! A similar thing happens with the icon and language in code blocks as well as in callouts ; I believe these elements should not be hidden away.

petobens avatar Oct 12 '24 23:10 petobens

icon and language in code blocks as well as in callouts, how would you edit these if you can't see the underlying text?

MeanderingProgrammer avatar Oct 13 '24 02:10 MeanderingProgrammer

I've made most decorations configurable in terms of what gets concealed on cursor column and what does not here: https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/fb6b3d145e5e12b838c0b84124354802f381b1af.

This is managed through the anti_conceal.ignore property. So if you do not want link icons to disappear you would set link to true. For code icon and language you would use code_language. And for callouts you can either keep the callout itself with callout or if you're referring to the block quote icon you would use quote. Putting these altogether you would end up with:

require('render-markdown').setup({
    anti_conceal = {
        ignore = {
            link = true,
            code_language = true,
            callout = true,
            quote = true,
        },
    },
})

Feel free to play around and mix and match these as you like. The complete list of decorations you can control is:

  • head_icon
  • head_background
  • head_border
  • code_language
  • code_background
  • code_border
  • dash
  • bullet
  • check_icon
  • check_scope
  • quote
  • table_border
  • callout
  • link
  • sign

Hopefully the things they control is intuitive enough.

MeanderingProgrammer avatar Oct 13 '24 09:10 MeanderingProgrammer

Feel free to play around and mix and match these as you like

This is great! Thanks for the quick implementation. One minor nuisance: it possible to hide those element in normal mode but not in insert mode (or more generally respect the conceal settings)?. Looking at the following gif now you can see for instance than in the code block the icon python bit is not hidden in normal mode but is not hidden either in insert mode which, at least from my point of view, I find counter intuitive.

Peek 2024-10-13 09-06

Since we are at it, and you've been incredibly generous and patient, I'm aware of https://github.com/neovim/neovim/pull/9496 but I was wondering whether something could be made from your side to avoid this thing (with links mostly) where the conceal "extends" an extra virtual line when a window is split (as in the image below): image

petobens avatar Oct 13 '24 12:10 petobens

Looking at the following gif now you can see for instance than in the code block the icon python bit is not hidden in normal mode but is not hidden either in insert mode which, at least from my point of view, I find counter intuitive.

Yeah this was my thinking when I asked:

how would you edit these if you can't see the underlying text?

I updated the values in ignore: https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/29863dc5262954ea04d76bd564f2f63330b42d7f.

You can now specify a list of modes where decorations will remain when the cursor enters. So rather than specifying to hide them in insert mode, you would specify continue showing them in say normal mode with:

require('render-markdown').setup({
    anti_conceal = {
        ignore = {
            code_language = { 'n' },
        },
    },
})

You can read this as the anti conceal behavior will ignore the code language in normal mode.

where the conceal "extends" an extra virtual line when a window is split (as in the image below):

I wish :( This is an issue I've gotten a few times and is also something I would love to get working but there does not seem to be a way around it: https://github.com/MeanderingProgrammer/render-markdown.nvim/issues/82, there's some links from this issue that go into more details about it, been an open issue for nearly a decade and realistically I don't think it will be fixed, kinda one of those things.

Lately I've taken to disabling line wrapping in markdown files as whole, since long lines are typically rare and mostly created by long links, like you mentioned. But that's more of a workaround than anything else.

If you have a concrete suggestion or something to try out I'm more than willing to take a look, but this would be an issue without my plugin if you just set the conceallevel to 2 or 3. And there really is not a good way to hide lines, at least that I'm aware of.

MeanderingProgrammer avatar Oct 13 '24 19:10 MeanderingProgrammer

You can now specify a list of modes where decorations will remain when the cursor enters.

Thanks! Works perfectly.

there really is not a good way to hide lines, at least that I'm aware of.

I suspected that too. Thanks anyway

(feel free to close this issue, and once again thanks for the superb responses)

petobens avatar Oct 13 '24 19:10 petobens