Skip to content

Opening a tree in a new tab messes up local statusline settings #2768

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
mkalinski opened this issue May 4, 2024 · 6 comments
Closed

Opening a tree in a new tab messes up local statusline settings #2768

mkalinski opened this issue May 4, 2024 · 6 comments
Labels
awaiting feedback bug Something isn't working

Comments

@mkalinski
Copy link

mkalinski commented May 4, 2024

Description

According to this comment, I'm using nvim-tree's event system to set local statusline for the tree's window.

This works fine, except for a weird case when nvim-tree is opened in a new tab, and then opening a file from the tree causes the local statusline to be removed from nvim-tree window and set in the newly opened file window.

It's a bit hard to explain, so please see the attached screenshots below.

Neovim version

NVIM v0.9.5
Build type: RelWithDebInfo
LuaJIT 2.1.1707061634

Operating system and version

Fedora 39

Windows variant

No response

nvim-tree version

64f61e4

Clean room replication

vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

vim.cmd [[set runtimepath=$VIMRUNTIME]]
vim.cmd [[set packpath=/tmp/nvt-min/site]]
local package_root = "/tmp/nvt-min/site/pack"
local install_path = package_root .. "/packer/start/packer.nvim"
local function load_plugins()
  require("packer").startup {
    {
      "wbthomason/packer.nvim",
      "nvim-tree/nvim-tree.lua",
      "nvim-tree/nvim-web-devicons",
      -- ADD PLUGINS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
    },
    config = {
      package_root = package_root,
      compile_path = install_path .. "/plugin/packer_compiled.lua",
      display = { non_interactive = true },
    },
  }
end
if vim.fn.isdirectory(install_path) == 0 then
  print "Installing nvim-tree and dependencies."
  vim.fn.system { "git", "clone", "--depth=1", "https://github.com/wbthomason/packer.nvim", install_path }
end
load_plugins()
require("packer").sync()
vim.cmd [[autocmd User PackerComplete ++once echo "Ready!" | lua setup()]]
vim.opt.termguicolors = true
vim.opt.cursorline = true

-- MODIFY NVIM-TREE SETTINGS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
_G.setup = function()
  require("nvim-tree").setup {}

  vim.opt.statusline = 'global'

  local events = require'nvim-tree.api'.events

  events.subscribe(events.Event.TreeOpen, function()
    vim.opt_local.statusline = 'tree'
  end)
end

-- UNCOMMENT this block for diagnostics issues, substituting pattern and cmd as appropriate.
-- Requires diagnostics.enable = true in setup.
--[[
vim.api.nvim_create_autocmd("FileType", {
  pattern = "lua",
  callback = function()
    vim.lsp.start { cmd = { "lua-language-server" } }
  end,
})
]]

Steps to reproduce

  1. nvim -nu /tmp/nvt-min.lua
  2. :NvimTreeOpen
  3. :tabedit .
  4. <Enter> to open any file visible in the tree opened in the new tab

Expected behavior

The same behaviour as in the first tab: statusline is set locally for the tree is in the tree's window, and global statusline is set for file opened from the tree.

image

Actual behavior

In the second tab, after the file is opened from the tree, the local statusline from tree is set for the opened file, and global statusline gets reset for the tree.

image

@mkalinski mkalinski added the bug Something isn't working label May 4, 2024
@alex-courtis
Copy link
Member

Many thanks for the detailed description and reproducer.

We don't have any guarantees on which window / buffer is focused on TreeOpen TreeAttachedPost etc.

That's no issue, we can simply set the statusline (window local, not buffer local) on the nvim-tree window itself.

This worked for me:

local api = require("nvim-tree.api")
events.subscribe(events.Event.TreeOpen, function()
  vim.api.nvim_set_option_value("statusline", "tree", { win = api.tree.winid() })
end)

@alex-courtis
Copy link
Member

I'm guessing that "tree" and "global" are just for testing. I'm assuming you have an interesting and useful setup for these.

It would be great if you could share a Recipe once it's working.

@mkalinski
Copy link
Author

mkalinski commented May 5, 2024

This does work in the case I've outlined here, thanks.

But when testing the solution, I've also found an even weirder bug. I was thinking about opening a new issue, but it also may be another facet of #2255. Please advise, if I should open a new issue or not.

To reproduce the other bug, you can use the same setup as here (or, because it has nothing to do with statuslines this time, you can even use the raw nvt-min.lua template), and then just skip step 2. of reproduction, so:

  1. nvim -nu /tmp/nvt-min.lua
  2. :tabedit .
  3. <Enter> to open any file visible in the tree opened in the new tab

The new tree opens correctly in a new tab on :tabedit, but after pressing <Enter>, the new tab is closed and the file is opened in the first tab in a vertical split. This behaviour seems nonsensical.

It might be because of the "shared global state" mentioned in #2255. But maybe it's a separate bug, so if you think it is, I would elaborate in a new issue.

It would be great if you could share a Recipe once it's working.

I'm not sure if I have much useful stuff to add to the topic. Just like the original poster of #424, I wanted the tree window to not have a statusline, because my configuration also didn't behave well when squished into a narrow window. So I don't really have a useful custom statusline for nvim-tree ready, just the bare minimum. 😉

If I was to create a recipe, it would just be a simple combination of #424 (comment) and your solution. Something like this:


Setting a separate statusline for nvim-tree windows

Often, a rich statusline does not behave well in a very narrow vertical split window, like nvim-tree normally uses. See #424 for example.

A different, simpler statusline for nvim-tree windows can be configured like this:

local nt_api = require'nvim-tree.api'

nt_api.events.subscribe(nt_api.events.Event.TreeOpen, function()
  local tree_winid = nt_api.tree.winid()

  if tree_winid ~= nil then
    vim.api.nvim_set_option_value('statusline', '%t', {scope = 'local', win = tree_winid})
  end
end)

Statusline value of '%t' will make nvim-tree windows display just the title NvimTree_#. See :h 'statusline for explanation of how statusline strings work.

To make nvim-tree have no visible statusline at all, you can use a value of a single space ' '. Note, that using a value of empty string '' will make Neovim fall back to global statusline, which is the opposite of what we want.


If you think it's valuable, I can post it to recipes.

@alex-courtis
Copy link
Member

It might be because of the "shared global state" mentioned in #2255. But maybe it's a separate bug, so if you think it is, I would elaborate in a new issue.

That is most likely the issue; it's using the window from the other tab to make the decision. The whole lot needs to be fixed.

@alex-courtis
Copy link
Member

alex-courtis commented May 5, 2024

If I was to create a recipe, it would just be a simple combination of #424 (comment) and your solution. Something like this:

That's fantastic, really helpful for a common use case. Much better than messing around with lualine profiles...

Thank you for explaining all the details and answering people's questions in advance.

@mkalinski
Copy link
Author

Okay, I've added the recipe. Thanks for your help.

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

No branches or pull requests

2 participants