Skip to content

feature: only "unconceal" at the cursorline #204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
petobens opened this issue Oct 12, 2024 · 9 comments
Closed

feature: only "unconceal" at the cursorline #204

petobens opened this issue Oct 12, 2024 · 9 comments
Labels
enhancement New feature or request

Comments

@petobens
Copy link

petobens commented Oct 12, 2024

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 petobens added the enhancement New feature or request label Oct 12, 2024
@petobens
Copy link
Author

petobens commented Oct 12, 2024

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

@MeanderingProgrammer
Copy link
Owner

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
Copy link
Owner

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.

@petobens
Copy link
Author

petobens commented Oct 12, 2024

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.

@MeanderingProgrammer
Copy link
Owner

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 added a commit that referenced this issue Oct 13, 2024
## Details

Request: #204

Previously the decoration elements that are hidden on the cursor line
was not something the user had direct control over.

The default behavior was to never hide virtual lines, spacing, signs or
code backgrounds. All other decorations on the line would always be
hidden if the user kept anti conceal enabled.

For the time being virtual lines and spacing remain permanently enabled.

However signs, code backgrounds and most other elements that by default
would be hidden are entirely within the users control.

This is all managed through the new `anti_conceal.ignore` property. This
table is a mapping from element name to a boolean. A value of `true` for
an element means it will not be concealed when the cursor enters the
line. A value of `false` behaves the same as no value being set and will
be hidden. A table is used rather than a list so that when users modify
values the defaults remain the same as they were unless explicitely changed.

Signs and code backgrounds set their values to `true` to remain ignored by
default as before, however now users have the ability to change this
behavior if they would like to hide signs and backgrounds.

Additionally most other decorations that remain concealable by default
like before can now be ignored if the user sets their value to true. A
complete list of possible values is provided in the default configuration
in the README.
@MeanderingProgrammer
Copy link
Owner

I've made most decorations configurable in terms of what gets concealed on cursor column and what does not here: fb6b3d1.

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.

@petobens
Copy link
Author

petobens commented Oct 13, 2024

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 neovim/neovim#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

MeanderingProgrammer added a commit that referenced this issue Oct 13, 2024
## Details

Request: #204

Updates the recently added `anti_conceal.ignore` settings to allow
values to be a string list of modes in addition to just booleans. This
behaves similarly to the top level `render_modes` setting but at a much
more granular, component level.

It is also a little confusing parsing all the negatives happening,
anti conceal & ignore, what does this mean.

When a list of modes is specified these are the modes where the
decorations will stick around, i.e. not be hidden when your cursor
enters the line. This is similar to neovim's concealcursor behavior.
@MeanderingProgrammer
Copy link
Owner

MeanderingProgrammer commented Oct 13, 2024

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: 29863dc.

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: #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.

@petobens
Copy link
Author

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants