Skip to content
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

No way to emulate signcolumn=number with statuscolumn? #21788

Open
andrewferrier opened this issue Jan 13, 2023 · 11 comments
Open

No way to emulate signcolumn=number with statuscolumn? #21788

andrewferrier opened this issue Jan 13, 2023 · 11 comments
Labels
column sign/number column enhancement feature request

Comments

@andrewferrier
Copy link
Sponsor

andrewferrier commented Jan 13, 2023

Problem

I like the new statuscolumn capability, and am trying to use it to produce a more cleanly-formatted status column.

Prior the option's availablility, I used:

  • set number
  • set relativenumber
  • set signcolumn=number

This worked well, as lines would show a number unless there was a sign, in which case that sign would be overlaid in the number column instead. This saves horizontal space, and most numbers are still present (OK if you are just using them for navigation hints).

Unfortunately, as best I can tell, there doesn't seem to be a way of replicating that behaviour with statuscolumn. The sign column %s format item allows for the sign to be shown, but there's no way to test whether a sign is present and conditionally return/show a line number. Possibly I could iterate over all signs in the document (not sure how to get them) but that seems horribly inefficient for something evaluated on every line/redraw.

Expected behavior

Ideally, I'd be able to write code something like this:

    _G.custom_statuscol = function()
        if vim.v.has_signs
            return "%s"
        else
            return vim.v.relnum
        end
    end

    vim.opt.statuscolumn = "%{%v:lua.custom_statuscol()%}"                                                                                                                    
    vim.opt.relativenumber = true
    vim.opt.number = true

The new element in the code above that doesn't exist in the current featureset (as far as I know) is vim.v.has_signs.

Thanks for all the hard work on NeoVim!

@andrewferrier andrewferrier added the enhancement feature request label Jan 13, 2023
@zeertzjq zeertzjq added the column sign/number column label Jan 13, 2023
@luukvbaal
Copy link
Contributor

Seems reasonable to add to me, idk how core feels about adding new v:vars. Adding one that helps in tweaking the fold column could be useful as well.

@lewis6991
Copy link
Member

I think we're on a slippery slope of adding a bunch of v vars which is an idiom I've been wanting to move away from with Lua.

Longer term options like statuscolumn and statusline will be directly configurable using lua callbacks from which we can pass all the data they need using function arguments, similar to Lua autocmd and user command callbacks.

@andrewferrier
Copy link
Sponsor Author

@lewis6991 that's fair enough, I was a bit surprised I had to go through the incantation of the vim.opt.statuscolumn = "%{%v:lua.custom_statuscol()%}" to effectively make a configurable callback for statuscolumn anyway, understand now that's a roadmap thing, and obviously that gives more flexibility.

I guess in this particular case maybe we just have to accept that statuscolumn isn't going to be fully configurable to emulate existing functionality until that's a thing.

@luukvbaal
Copy link
Contributor

There is sign_getplaced() which might be used here as a workaround however it seems to return empty results for me.

@andrewferrier
Copy link
Sponsor Author

andrewferrier commented Jan 13, 2023

There is sign_getplaced() which might be used here as a workaround however it seems to return empty results for me.

Yes, vim.pretty_print(vim.fn.sign_getplaced(vim.fn.bufname())) seems to be broken for me.

@zeertzjq
Copy link
Member

It doesn't work for extmarks

@luukvbaal
Copy link
Contributor

luukvbaal commented Mar 13, 2023

So it turns out that if you supply a wildcard to the group it will properly list the placed signs(indeed except extmark signs but this was not the issue I ran into before). I previously only read the help with 'conceallevel' enabled which will hide the wildcard...

If {group} is '', then signs in all the groups including the
If {group} is '*', then signs in all the groups including the

@justinmk
Copy link
Member

that '*' should be changed to "*"

@andrewferrier
Copy link
Sponsor Author

@luukvbaal thanks, this seems to work:

            local signs = vim.fn.sign_getplaced(
                vim.fn.bufname(),
                { group = "*", lnum = vim.v.lnum }
            )[1].signs[1]

           if signs ~= nil then
                -- There are signs on the current line
           end

@luukvbaal
Copy link
Contributor

Yep. You could also choose to not supply lnum but instead get all placed signs once per window per redraw. You can do this by subscribing to neovim's display_tick through FFI. That's what I opted to do for a feature I'm working on for my statuscolumn plugin. I might look into supporting signcolumn=number there as well.

@luukvbaal
Copy link
Contributor

luukvbaal commented Mar 31, 2023

I added support for this in my statuscolumn plugin here: luukvbaal/statuscol.nvim#15 (comment).

I think that invalidates this issue? Unless if we want the %r/%l stl number items to implicitly obey 'signcolumn' == "number". Not sure if logic required for that is reasonable/worth it to add into core.

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

No branches or pull requests

5 participants