Bekaboo / dropbar.nvim

IDE-like breadcrumbs, out of the box
GNU General Public License v3.0
896 stars 17 forks source link

[Question]: Is there a way to get `bar_idx` of currently opened bar? #160

Closed sahinakkaya closed 1 month ago

sahinakkaya commented 1 month ago

Description

I want to get the bar index of currently opened bar.

Let's say I've executed :lua require('dropbar.api').pick(3), it will open bar 3 if it is available. Now, inside this bar, when I press some key, I want to get its id which is 3. Is there a way to get that information?

I want to open previous bar by pressing h, that's why I need the current bar number.

I've tried

local utils = require('dropbar.utils')
print(utils.bar.get_current())

but it prints nil

willothy commented 1 month ago

Try using utils.menu.get_current() instead, that may work :)

Bekaboo commented 1 month ago

image

@sahinakkaya After picking a symbol in a bar, you are inside a menu, not a bar, and that's why utils.bar.get_current() returns nil -- because there is no bar attached to the menu window. As @willothy said, you can use utils.menu.get_current() to get current menu.

sahinakkaya commented 1 month ago

Thanks both, I know about utils.menu.get_current. I even use it in my keymaps. However that doesn't solve my problem. How can I get the previous bar's id from the current menu?

Consider I have chosen an H2 header with api.pick or by clicking on it. Is there a way to go to H1 header from the H2 menu or that information is lost as soon as the menu is opened? @Bekaboo @willothy If it is lost and doesn't make sense to implement it then you may close this issue.

resim

sahinakkaya commented 1 month ago

I think the first menu should have access to bar id it is attached. And the other menus may get that information inherited from parent menu or may have nil if you think it doesn't make sense.

resim

Bekaboo commented 1 month ago

@sahinakkaya Suppose menu is the first menu opened from a bar, then menu.prev_win is the source window to which the bar is attached, with this you can use require('utils.bar').get({ win = menu.prev_win }) to get the bar you want.

sahinakkaya commented 1 month ago

@Bekaboo thanks for pointing me in the right direction. I finally managed to make it work as I want.

https://github.com/Bekaboo/dropbar.nvim/assets/32161460/22b98072-5a3c-40cd-ac0d-c4ff1c5b899a

local open_item_and_close_menu = function()
  local utils = require('dropbar.utils')
  local menu = utils.menu.get_current()
  if not menu then
    return
  end

  local cursor = vim.api.nvim_win_get_cursor(menu.win)
  local entry = menu.entries[cursor[1]]
  -- stolen from https://github.com/Bekaboo/dropbar.nvim/issues/66
  local component = entry:first_clickable(entry.padding.left + entry.components[1]:bytewidth())
  if component then
    menu:click_on(component, nil, 1, 'l')
  end
end

keymaps = {
  ['h'] = function()
    local utils = require('dropbar.utils')
    local menu = utils.menu.get_current()
    if not menu then
      return
    end
    if menu.prev_menu then
      menu:close()
    else
      local bar = require('dropbar.utils.bar').get({ win = menu.prev_win })
      local barComponents = bar.components[1]._.bar.components
      for _, component in ipairs(barComponents) do
        if component.menu then
          local idx = component._.bar_idx
          menu:close()
          require('dropbar.api').pick(idx - 1)
        end
      end
    end
  end,
  ['l'] = function()
    local utils = require('dropbar.utils')
    local menu = utils.menu.get_current()
    if not menu then
      return
    end
    local cursor = vim.api.nvim_win_get_cursor(menu.win)
    local component = menu.entries[cursor[1]]:first_clickable(cursor[2])
    if component then
      menu:click_on(component, nil, 1, 'l')
    end
  end,
  ['<CR>'] = open_item_and_close_menu,
  ['o'] = open_item_and_close_menu,
}