akinsho / bufferline.nvim

A snazzy bufferline for Neovim

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: Bufferline sets `showtabline=2`

HakonHarnes opened this issue · comments

Is there an existing issue for this?

  • I have searched the existing issues

What happened?

I have set showtabline=0 in my config. When I interact with the tabs (e.g. tabnew or tabnext), bufferline.nvim sets showtabline = 2.

Steps to reproduce

  1. Open Neovim
  2. :set showtabline=0
  3. :tabnew
  4. Observe set showtabline? = 2

What did you expect to happen?

set showtabline=0 should hide the tabline. The plugin should not alter the showtabline value.

The problem can be somewhat circumvented by setting always_show_bufferline = true and manually invoking set showtabline=0, or setting up an autocmd to do this. This isn't ideal, though.

Config

return {
  "akinsho/bufferline.nvim",
  opts = {
    options = {
      mode = "tabs",
      numbers = "ordinal",
      close_icon = "",
      buffer_close_icon = "",
      modified_icon = "",
      diagnostics = false,
    },
    highlights = {
      tab_close = {
        bg = "#0E0E14",
      },
    },
  },
}

Additional Information

Alternatively implement a enable, disable and toggle command for bufferline.nvim.

commit

No response

commented

This isn't a bug, the only way to show the tabline is all the time is setting it to 2 and only when there are two tabpages uses 1. The vast majority of this plugins users certainly from it's early days were not familiar with the showtabline setting and asking them to set it as well as configure this plugin would have created unnecessary noise.

For the most part if you are using this plugin you are delegating control of showtabline or not to this plugin and it's options 🤷🏾‍♂️

Okay, but how do you propose I toggle the bufferline then? In certain situations I want to hide the bufferline. Setting the showtabline option doesn't work because bufferline.nvim overwrites this value. There are no methods for disabling/enabling/toggling the bufferline either.

That is to say, I want to be able to arbitrarily hide the bufferline, without it automatically reappearing when I navigate between the tabs. How can I accomplish that?

commented

@HakonHarnes I haven't touched this code in a while, but setting showtabline should only happen on startup rather than continuously as far as I recall. So you should still be allowed to change it inside of an auto command or something without it getting reset. Can you confirm that it's being automatically reset constantly? Because otherwise I'm not sure how come you can't just override this as you say? If the issue is then that it is being called more than once then my suggestion for a fix would just be to make sure that it only sets the value of showtabline once.

For what it's worth, I would strongly recommend against yet another option. This plugin is drowning in them and so I'm very strongly opposed to adding new ones for the time being.

@akinsho

setting showtabline should only happen on startup rather than continuously as far as I recall.

local function toggle_bufferline()
local item_count = config:is_tabline() and utils.get_tab_count() or utils.get_buf_count()
local status = (config.options.always_show_bufferline or item_count > 1) and 2 or 0
if vim.o.showtabline ~= status then vim.o.showtabline = status end
end

The toggle_bufferline() command sets the showtabline value, and this function is invoked by various autocmds. Thus, setting showtabline = 0 is overwritten by bufferline.nvim when these autocmds are triggered.

The closest I have gotten to getting what I want is setting always_show_bufferline = true which ensures certain autocmds are not setup and then doing:

vim.api.nvim_create_autocmd("User", {
  pattern = "LazyLoad",
  callback = function(args)
    if args.data == "bufferline.nvim" then
      vim.opt.showtabline = 0
    end
  end,
})

But the bufferline still reappears when I create new tabs, so I have to figure out which autocmd is doing that and somehow overwrite it. Nonetheless, expecting the user to dig into the source code to figure this out is not ideal. I simply want to hide/show the tabline on demand, without it reappearing.

Can you confirm that it's being automatically reset constantly?

Can confirm its being automatically reset when interacting with tabs.

Steps to reproduce

  1. Open Neovim
  2. :set showtabline=0
  3. :tabnew
  4. Observe set showtabline? = 2 (tabline reappears)

Please see PR #876 which allows the user to control the showtabline option themselves.

Edit: Here's a demo. Notice how the tabline reappears after I do :tabprev even though set showtabline=0 was executed.

demo.mp4
commented

Nonetheless, expecting the user to dig into the source code to figure this out is not ideal.

@HakonHarnes to be clear the main use case that this plugin is designed for and the main target audience of this plugin are people who want to set it and forget. The rare neovim user who just wants something that generally works and are fine to leave most things be. I think along the spectrum of configurability and rigidity this plugin leans (somewhat) rigid because that makes it easier to maintain and less complicated.

I'll have a think about whether or not the option in the PR is a good addition, although I do really appreciate you putting in the work to solve your own issue 🙏🏾. Currently the number of options for this plugin is > 40 I really do not want anymore if possible. Will get back to this once I get a chance to consider all the possible solutions

The rare neovim user who just wants something that generally works and are fine to leave most things be.

Not so rare; #829, #651, #484.

Will get back to this once I get a chance to consider all the possible solutions

Thanks. I'd prefer to not have to use my own fork which would have to be manually synced all the time.

commented

The rare in the context I mentioned above directly relates to

fine to leave most things be

I think wanting granular control of when the tabline shows doesn't match with the original vision I had for this plugin. It's fine to want that just not what I built this for, anyway I digress.

It's useful to have those issues as a reference.

I've looked into this a bit now as I would love to put and end to all this for good. I tried setting showtabline myself locally and using tabnew, tabprevious and tabnext, using the same config as you except the highlights and the tabline stays gone. Looking at this code again it only uses one autocommand to retrigger the tabline status and that is only setup if the user sets always_show_bufferline to true.

Can you confirm that you are seeing this behaviour in a minimal environment i.e. you are not running this from kickstart or lazyvim or any of the other config frameworks as they frequently have additional logic layered on top

fwiw, I just came here looking for a solution to this.

@jblyberg Here's a workaround:

local root = vim.fn.fnamemodify("./.repro", ":p")

for _, name in ipairs({ "config", "data", "state", "runtime", "cache" }) do
	vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

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)

local plugins = {
	{
		"akinsho/bufferline.nvim",
		opts = {
			options = {
				mode = "tabs",
				always_show_bufferline = true,
			},
		},
	},
}
require("lazy").setup(plugins, {
	root = root .. "/plugins",
})

vim.api.nvim_create_autocmd("User", {
	pattern = "LazyLoad",
	callback = function(args)
		if args.data == "bufferline.nvim" then
			vim.o.showtabline = 0
		end
	end,
})

You need to set always_show_bufferline = true and then setup an autocmd which sets the showtabline to the correct value after the plugin has loaded. If you're using LazyVim or another Neovim distrobution you need to setup this autocmd before plugins are installed to avoid flickering (e.g. first thing you do in init.lua).

@akinsho My bad, I left out the always_show_bufferline option in my original post. Here's a minimal environment where the issue is reproducable:

local root = vim.fn.fnamemodify("./.repro", ":p")

for _, name in ipairs({ "config", "data", "state", "runtime", "cache" }) do
	vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

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)

local plugins = {
	{
		"akinsho/bufferline.nvim",
		opts = {
			options = {
				mode = "tabs",
				always_show_bufferline = false,
			},
		},
	},
}
require("lazy").setup(plugins, {
	root = root .. "/plugins",
})

As previously mentioned setting always_show_bufferline = true and setting up an autocmd which executes after the plugin has loaded and sets the correct showtabline option resolves the issue for me.

Still, this requires the user to dig into the code and understand why this is happening to come up with this workaround. In my opinion PR #876 is still the solution as it allows the user to control the showtabline option themself, and have the tabline behave as it does with the built-in tabline. The "solution" outlined above is more of a hacky workaround IMO.

Also, don't find it particularily intuitive or user-friendly that you have to set always_show_bufferline = true, because I don't want the bufferline to show by default. I want to trigger it myself when I need it.

@jblyberg Here's a workaround:

Thanks--This is the direction I was working toward. Your solution is not working for me, unfortunately. Autocmd gets triggered once when opening nvim but not when I add additional buffers, remove, etc.

@jblyberg, @akinsho

Actually, the workaround is not ideal. It still flickers sometimes when I open Neovim, even though the autocmd is configured first thing in the config:

demo.mp4

No such issues with PR #876.

+1 on the PR. I think it's a much cleaner solution than directing users toward autocmd.

commented

I fear the thread might be getting a little confused so I'll clarify some things which I hope we can put aside.

  1. In the first instance, there is no intention that the user should have dig through code to do X, obviously if they do to figure out how to do something they want it's FOSS after all but this is not by design.

  2. The reason I have stated a few times my design goal with this plugin is so that it's clear that to me the specific use case of only wanting to see the bufferline at specific intervals different from the native behaviour of showtabline whilst valid is not something I am specifically looking to support (this part is V. important)

  3. More than anything else it appears that there is potentially a bug or the reasoning around always_show_bufferline does not work as I would have expected/remember this is very likely because whenever a user wants something they propose another option and the interaction between options or the plans around them get very messy.

I am not looking to just add yet another option this leads to more confusion and complexity. What I'm looking is to simply ensure that the usage of always_show_bufferline actually works as intended/it is doing what users who are using it intend for it to be doing.

What's the intention behind the always_show_bufferline option?

For me, the following would make sense:

  1. If true, it alters the showtabline option such that the bufferline is always visible (e.g. when creating tabs, opening buffers, navigating, etc.)
  2. If false if doesn't touch the showtabline option at all

Currently, this is not how bufferline.nvim operates. Makes me wonder, is this if statement flipped?

if not options.always_show_bufferline then
-- toggle tabline
api.nvim_create_autocmd({ "BufAdd", "TabEnter" }, {
pattern = "*",
group = BUFFERLINE_GROUP,
callback = function() toggle_bufferline() end,
})
end

Why would the plugin force the bufferline to be shown on bufAdd and tabEnter events when always_show_bufferline is false? In my case removing the not in the if statement would resolve my issues I believe.

Edit: @akinsho I can confirm removing the not from the if-statement completely resolves the issue for me. Please clarify the intended behaviour for the always_show_bufferline option and whether this is intentional or not.

The reason I have stated a few times my design goal with this plugin is so that it's clear that to me the specific use case of only wanting to see the bufferline at specific intervals different from the native behaviour of showtabline whilst valid is not something I am specifically looking to support (this part is V. important)

I understand your design goal for the bufferline.nvim plugin and that supporting my specific use case of controlling the bufferline visibility at specific intervals may not be a priority for you. However, I want to clarify that the current behavior of the plugin does not align with the native functionality of the showtabline option.

When a user sets showtabline=0, they expect the tabline to remain hidden. However, bufferline.nvim plugin is currently overriding this setting and forcing the tabline to be shown in certain scenarios, such as when creating new tabs or navigating between them. This behavior deviates from how the native 'showtabline' option works.

The plugin overrides the showtabline option regardless of the value in always_show_bufferline, and that's confusing.

commented

The always_show_bufferline setting means always show in the context of replicating the functionality of showtabline i.e it's there all the time without user control for the most part or it follows the behaviour of showtabline i.e. there is no bufferline, or it appears only if > 1 tab or always there.

When I first created this plugin people were still writing their configs in viml and lua had just been introduced basically configuring stuff was confusing for new people and I wanted something automatic that didn't mean they had to learn to set values to some number.

The default setting of showtabline is 1 which will not show the tabline on starting neovim which many many people do not want i.e. they expect that much like sublime or vscode the bufferline is always there, this is also my preference. Also v. importantly showtabline does not natively support buffers so it has had to essentially be recreated to support buffers because setting it something like 1 but then having more than one buffer open won't trigger bufferline the same way it would if using tabs only.

So I decided a very long time ago now to just set it to 2. Then some users came along and wanted it to have the behaviour of showtabline=1 for buffers & tabs so now the plugin has logic that essentially reproduces that internally for both. It doesn't really support 0 because to my mind why is someone using this plugin who doesn't want 1 or 2 at least till the first of these issues showed up. So it does replicate showtabline but not the value of 0

commented

I'm starting to think the best solution here would actually have been to directly replicate the showtabline function as an option in bufferline i.e. showbufferline = 'always' | 'if_multiple' | 'never' and then you can set never and manipulate the showtabline functionality yourself.

EDIT: this would mean deprecating all the other options like always_user_bufferline etc.

Thanks for re-opening and looking into this. In my opinion it's better to add the auto_toggle_bufferline option and keep the always_use_bufferline option because:

  1. It's a non-breaking change. Deprecating the always_use_bufferline option would break a lot of existing configs
  2. showbufferline = never is not intuitive. It sounds like we're disabling the bufferline alltogether.

Setting auto_toggle_bufferline to false is intuitive; it tells the user the plugin won't toggle the bufferline (i.e. altering the showtabline option) automatically.

commented

To be honest I don't really think so, I mean if you give it some distance i.e. not just your use case but new people I don't think it's clear that this behaviour is even understandable as an option. If you consider that the main audience for this plugin might be people migrating from other editors or people new to neovim/programming then options about showing the bufferline automatically are kind of arcane. This could just be a difference of opinion. In hindsight I should probably not have even tried to mimic showtabline and should have just stuck with the behaviour I was trying to replicate from other editors i.e. on or off.

In general what concerns me the most is that whilst I obviously do not intend/want to alienate experienced vim users who are probably undoubtedly the main audience of nvim and it's plugins I don't want to build for that use case. There are so many more flexible alternatives like cokeline, heirline and several others where users with know how can do what they want. From that perspective I leave accommodating increasing complexity/use cases to them and keep this simple.

As far as I'm concerned every new option just shortens the lifespan of this plugin because it just brings forward the point in the future when I give up maintaining this plugin because of the increasing maintenance burden it brings me.

I'll continue have a think about whether or how to add this and get back to this. Please keep in mind my first priority is to make this plugin as low maintenance for myself as possible whilst working for the most amount of non tweaking user possible vs. accommodating feature requests.

If you consider that the main audience for this plugin might be people migrating from other editors or people new to neovim/programming then options about showing the bufferline automatically are kind of arcane.

In general what concerns me the most is that whilst I obviously do not intend/want to alienate experienced vim users who are probably undoubtedly the main audience of nvim and it's plugins I don't want to build for that use case.

I think you can strike a balance here though; auto toggle the bufferline by default. For users who want more granular control, they can disable the auto toggle feature. I think this is way more intuitive than setting setbufferline to never, but that's just my two cents.

I understand your intention behind this plugin and not wanting to support the experienced Vim users with complex use cases. Howevever, this is not a complex use case. It's simply a matter of hiding/showing the tabline, which I'd consider basic usage. I understand our opinions might differ here, though.

As far as I'm concerned every new option just shortens the lifespan of this plugin because it just brings forward the point in the future when I give up maintaining this plugin because of the increasing maintenance burden it brings me.

Please keep in mind my first priority is to make this plugin as low maintenance for myself as possible.

Consider this: For users who want to arbitrarily toggle the bufferline or need more granular control, you can simply direct them to set auto_toggle_bufferline to false and adjust showtabline accordingly. This approach keeps the plugin low-maintenance for you while providing an easy resolution for this recurring issue. This is the fourth time this topic has been raised, and it likely won't be the last.

Ultimately, the decision rests with you as the maintainer, and I respect your judgment. However, I believe implementing auto_toggle_bufferline (or similar) offers a pragmatic solution that balances the needs of different users without significantly compromising the plugin's simplicity or maintainability. It's a simple flag that's used just once in the entire codebase. It doesn't introduce complex code or significantly increase the plugin's complexity.

I agree, bufferline should avoid setting showtabline or provide some interface for modifying it if that's not possible. I have mode = "tabs" set, and I'd like to have showtabline set to 1 so tabs are always visible when more than one is open.

@akinsho Any updates on this?

commented

Just merged @HakonHarnes still not the biggest fan of that particular solution (although appreciate all the patience and work 💪🏾) but would rather put this to bed (hopefully forever now 🤞🏾)