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

[Bug]: Closing tabs doesn't work as expected

Open SergioBenitez opened this issue 3 years ago • 10 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

What happened?

I am using bufferline in tabs mode and experiencing several issues with closing tabs:

  1. The last tab is "closeable" even though closing the last tab in vim is always an error. This means you get an ugly error if you try to do this. It would be nice if either 1) bufferline could disappear if it's the last tab and/or 2) "close" did nothing.

  2. Overriding close_command and right_mouse_command doesn't seem to do anything. That if, if I add:

    bufferline.setup {
        options = {
            mode = "tabs",
            close_command = function(bufNr)
                print(bufNr)
            end,
        }
    }
    

    The default command (tabclose) runs anyway. Setting close_command seems to work just find in buffers mode.

  3. ~~The tabpage number passed to tabclose is wrong. It certainly doesn't pass the tabpage number. It seems to pass something related to the number of buffers open. To replicate: open two tabs, close the second, open another, try to close the second.~~ Based on https://github.com/akinsho/bufferline.nvim/commit/0652db63345454701bfb8ed7705546c177bc4ef2, I see that it actually passes the tabpage handle. That commit makes the default close_comand work, but the default right_mouse_command is still incorrect, and the above 2 issues still stand, 2) in particular making it impossible to fix right_mouse_command on the user end.

What did you expect to happen?

  1. Either nothing or for bufferline to disappear.
  2. For the close_command setting to have an effect.
  3. For the tabpage number to be passed to the function.

Config

bufferline.setup {
    options = {
        mode = "tabs",
        close_command = function(bufNr)
            print(bufNr)
        end,
    }
}

Additional Information

No response

commit

No response

SergioBenitez avatar Jul 05 '22 23:07 SergioBenitez

Hi @SergioBenitez,

So essentially tabs mode exists almost entirely due to user pressure rather than any specific desire of mine (/the curiosity of implementing it) I don't actually use it at all and most of its development comes from tabs users of this plugin. So it doesn't really have feature parity with the rest of the plugin. I don't personally actively develop it unless there are critical issues.

In answer to some points

  1. This plugin doesn't really seek to get involved in the specifics of managing tabs or buffers, the commands are all entry points for users to put whatever behaviour they like there. I wouldn't want to get involved in hiding x due to some vim error that comes up. I think if there is specific non-standard functionality desired, there a user should override it. If it's a simple matter of maybe returning early or adding a simple conditional, then that sounds fine, but I essentially don't want to maintain specific buffer/tab management logic.
  2. The close command is probably just not hooked up at all for tabs. As I mentioned, once I had the mode working i.e. showing up, I've since crowdsourced all future development.
  3. Think the same goes here as for 2.

Think I'll add something to the README to clarify this situation with tabs a bit more. I'm never sure whether I should have added it at all since I don't actively develop it but users have generally seemed to use it regardless with only the occasional issue and a few tab users have stepped up to contribute so 🤷🏿‍♂️

akinsho avatar Jul 06 '22 07:07 akinsho

@SergioBenitez I found a workaround.

It seems that we can override {left,middle,right}_mouse_command options after bufferline.nvim merges user config with its default values.

require('bufferline.config').options.right_mouse_command = function(arg)
  print(arg)
end

However, I couldn't override close_command option in this way.

yuttie avatar Jul 13 '22 03:07 yuttie

@SergioBenitez I disabled right click and made middle click close a tab unless it's a last one with the following code:

require('bufferline.config').options.middle_mouse_command = function(tabhandle)
  if table.getn(vim.api.nvim_list_tabpages()) > 1 then
    vim.cmd('tabclose ' .. vim.api.nvim_tabpage_get_number(tabhandle))
  end
end
require('bufferline.config').options.right_mouse_command = nil

yuttie avatar Jul 13 '22 03:07 yuttie

@yuttie I'm not sure why you can't just override the mouse commands in your config rather than importing an internal module bufferline.config and using that directly. I'd say that that is strongly discouraged because those modules are for internal usage and the structure for them could change with refactors. If not for the way lua handles requires, those would definitely not be visible outside the plugin

you should use

require('bufferline').setup({
 options = {
   middle_mouse_command = func,
 }
})

akinsho avatar Jul 13 '22 06:07 akinsho

@akinsho Yes, I know that the module should not be used in that way and do not want to do such a dirty hack. That's why I wrote it's a "workaround."

I'm not sure why you can't just override the mouse commands in your config...

I think it's because *_mouse_command values are unconditionally set without considering a user's provided values here after merging user config with default values.

yuttie avatar Jul 13 '22 07:07 yuttie

Oh right, this is a regression from https://github.com/akinsho/bufferline.nvim/commit/0652db63345454701bfb8ed7705546c177bc4ef2

akinsho avatar Jul 13 '22 07:07 akinsho

I've pushed a commit to dev which should allow normal overriding of the click commands in tab mode.

akinsho avatar Jul 13 '22 07:07 akinsho

@akinsho I confirmed that I can override *_mouse_command options in a normal way.

For example, the above workaround can be written as follows:

require('bufferline').setup {
  options = {
    mode = 'tabs',
    left_mouse_command = vim.api.nvim_set_current_tabpage,
    middle_mouse_command = function(tabhandle)
      if table.getn(vim.api.nvim_list_tabpages()) > 1 then
        vim.cmd('tabclose ' .. vim.api.nvim_tabpage_get_number(tabhandle))
      end
    end,
    right_mouse_command = '',
  },
}

Thank you for your quick fix!

yuttie avatar Jul 13 '22 08:07 yuttie

Thanks! Those workarounds work.

Another issue with respect to tabs that I found was that using sort_by = "tabs" doesn't seem to work. However, I found that :BufferLineSortByTabs does, and that it persists. So I added the following to my bufferline config:

-- the 'sort_by' above doesn't work, for some reason, but this does
vim.api.nvim_create_autocmd("TabNew", {
    pattern = "*",
    group = vim.api.nvim_create_augroup("BufferLineSetSortToTabs", {}),
    callback = function()
        vim.api.nvim_del_augroup_by_name("BufferLineSetSortToTabs")
        bufferline.sort_buffers_by('tabs')
    end,
})

SergioBenitez avatar Jul 14 '22 03:07 SergioBenitez

Is this issue still present? there have been some PRs since it was opened. Please make sure to test without tags and to also have a look at the dev branch if it's not resolved in main

akinsho avatar Jul 27 '22 15:07 akinsho

I think the original issues raised here have been resolved. If there are still tab related issue, please feel free to raise another issue or (preferably) a PR for those. If the original issue is not actually resolved, let me know.

akinsho avatar Aug 17 '22 07:08 akinsho