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

Can't set multiple chars for spaces and tabs + leadmultispace chars move around when toggling #939

Closed
vicnett opened this issue Nov 10, 2024 · 2 comments · Fixed by #940
Closed
Labels
bug Something isn't working

Comments

@vicnett
Copy link

vicnett commented Nov 10, 2024

Problem

This is a duplicate of #665 but I didn't want to necro it.

Context:

My use case:

  • I like to make it obvious whether spaces or tabs are used for any given indentation
  • In the spirit of this plugin, I want to use a vertical line character for both
  • There don't seem to be any left-aligned vertical line characters that are very visually different. There's different thicknesses but that's about it. I'd love to use a left-aligned for example but that doesn't seem to exist

So, I've been trying to get indent-blankline to work with the following listchars:

vim.opt.listchars:append({
  tab = "▏-",
  leadmultispace = "▏·",
})

The problem(s):

My understanding is as follows:

  • By default, space-based indentation is represented with a , regardless of any vim settings
  • By default, tab-based indentation is represented with either as well if list is not set, or with lcs-tab if it is*
  • Both ibl.config.indent.char and ibl.config.indent.tab_char can only be one character, whereas listtab allows leadmultispace to be multiple characters, and requires tab to be at least two.
  • it seems only the first character of lcs-tab is used

As a consequence of the above, while one can set custom and different characters to represent space-based and tab-based characters, this configuration is not as flexible as listchars as one cannot set multiple characters to use based on the size of the indentation.

... Which wouldn't be a big deal except I seem to be hitting some weird glitch where the (and this is a wild guess on my part) the virtual text from indent-blankline seems to be displacing Neovim's virtual text from listchars?

Without indent-blankline, this is the result, tabs on the left and spaces on the right:

image

With indent-blankline toggled on, this is what things look like:

image

And here's a clip of me toggling it on and off, showing the Neovim lcs-leadmultispace shifting position:

Screencast_20241109_185329.webm

Recap:

  • ibl.config.indent.tab_char respects lcs-tab when list is set, but ibl.config.indent.char doesn't respect lcs-leadmultispace, which is inconsistent behavior
  • Whether or not they follow listchars, they can only be configured to a single character (or will use the first one in listchars if there's multiple), and the listchars still get displayed by Neovim so parts are re-colored, others aren't (which I'd be fine with, see Expected Behavior)
  • The characters from lcs-leadmultispace shift around when indent-blankline is toggled, leading to both showing, whereas for lcs-tab the vertical line seems to nicely just get re-colored.

Steps to reproduce

Here's the minimal init.lua I used to produce the screenshots I've attached. I've left in my color config as I think the colors do help distinguish between the plugin's and Neovim's virtual characters.

vim.g.mapleader = " "
vim.g.maplocalleader = "\\"

-- Display extra whitespace
vim.opt.list = true
vim.opt.listchars:append({
  tab = "▏-",
  leadmultispace = "▏·",
  trail = "·",
  nbsp = "·",
  multispace = "·",
})

-- Lazy
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
  spec = {
    {
      "ishan9299/nvim-solarized-lua",
      lazy = false,
      priority = 1000,
      config = function()
        vim.cmd([[ colorscheme solarized ]])
      end,
    },
    {
      "lukas-reineke/indent-blankline.nvim",
      main = "ibl",
      ---@module "ibl"
      ---@type ibl.config
      dependencies = { "https://gitlab.com/HiPhish/rainbow-delimiters.nvim" },
      config = function()
        local highlight = {
          "SolarizedMagenta",
          "SolarizedYellow",
          "SolarizedBlue",
          "SolarizedOrange",
          "SolarizedGreen",
          "SolarizedViolet",
          "SolarizedCyan",
        }

        local hooks = require "ibl.hooks"
        -- create the highlight groups in the highlight setup hook, so they are reset
        -- every time the colorscheme changes
        hooks.register(hooks.type.HIGHLIGHT_SETUP, function()
          vim.api.nvim_set_hl(0, "SolarizedMagenta", { fg = "#D33682" })
          vim.api.nvim_set_hl(0, "SolarizedYellow",  { fg = "#B58900" })
          vim.api.nvim_set_hl(0, "SolarizedBlue",    { fg = "#268BD2" })
          vim.api.nvim_set_hl(0, "SolarizedOrange",  { fg = "#CB4B16" })
          vim.api.nvim_set_hl(0, "SolarizedGreen",   { fg = "#859900" })
          vim.api.nvim_set_hl(0, "SolarizedViolet",  { fg = "#6C71C4" })
          vim.api.nvim_set_hl(0, "SolarizedCyan",    { fg = "#2AA198" })
        end)

        vim.g.rainbow_delimiters = { highlight = highlight }

        require("ibl").setup({
          scope = { highlight = highlight },
          indent = { highlight = highlight, },
        })

        hooks.register(
          hooks.type.SCOPE_HIGHLIGHT,
          hooks.builtin.scope_highlight_from_extmark
        )
      end,
    },
  },
  install = { colorscheme = { "solarized" } },
  checker = { enabled = true },
  change_detection = {
    enabled = true,
    notify = false,
  },
})

Expected behavior

Most importantly I wouldn't expect the Neovim lcs-leadmultispace characters to move around when toggling the plugin. This seems like a bug to me (let me know if you'd like a separate issue filed for it)

I also would ideally expect that indent-blankline would respect list and listchars if set, and simply recolor all the already-set characters (not just the first one). It just seems like the consistent and least-surprising behavior.

However, after staring at this for a couple of days trying to fix it... I actually do really like the idea of only the vertical line being colored and the extra characters staying muted so as to not visually clutter the indentation more than it already is.

Neovim version (nvim -v)

0.10.1

@lukas-reineke
Copy link
Owner

ibl.config.indent.tab_char respects lcs-tab when list is set, but ibl.config.indent.char doesn't respect lcs-leadmultispace, which is inconsistent behavior

lcs-leadmultispace is newer than this plugin. And changing char to default to leadmultispace now would be a breaking change.

Whether or not they follow listchars, they can only be configured to a single character (or will use the first one in listchars if there's multiple), and the listchars still get displayed by Neovim so parts are re-colored, others aren't (which I'd be fine with, see Expected Behavior)

Yes, because IBLs char and tab_char only apply to the indentation, not any other whitespace. They are always just one cell wide.

The characters from lcs-leadmultispace shift around when indent-blankline is toggled, leading to both showing, whereas for lcs-tab the vertical line seems to nicely just get re-colored.

This is a bug. I made a fix in #940

recolor all the already-set characters

You can change the highlight of the whitespace, take a look at :help hl-IblWhitespace:

@vicnett
Copy link
Author

vicnett commented Nov 10, 2024

Honestly, fixing the characters shifting around is really all I needed. Thank you for solving it so quickly, and for bearing with my ramblings... I've updated and everything is okay now! I'm glad it really was a bug and not me going crazy...

lcs-leadmultispace is newer than this plugin.

I didn't realize this! Thanks for pointing it out because I also was wondering how I'd missed leadmultispace all this time 😅

And changing char to default to leadmultispace now would be a breaking change.

I'm honestly okay if things stay as they are, but I'm curious how this would be a breaking change... If you changed char to default to leadmultispace, it wouldn't change anything for users who don't have leadmultispace set, but for those who do have it set the behavior would become more consistent. They also wouldn't have to set ibl.config.indent.char to match it manually, and if they already did then again nothing would change anyway.

Yes, because IBLs char and tab_char only apply to the indentation, not any other whitespace. They are always just one cell wide.

Makes sense 👍

You can change the highlight of the whitespace, take a look at :help hl-IblWhitespace:

Oh yeah I missed that!

Edit: found it! https://github.com/LuaLS/lua-language-server/wiki/Annotations
I've learned a lot while looking into this, but if you wouldn't mind an "extra credits" question... Can you point me to where I can learn what the lines that start with ---@ do? I've seen it a lot, but haven't had luck looking it up (search engines don't help as they refuse to search for that string literally)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants