Bekaboo / dropbar.nvim

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

[help]: keymap to toggle dropbar #115

Closed pwnwriter closed 7 months ago

pwnwriter commented 7 months ago

Is there any way to map keys to toggle the dropbar, than just clicking over ?

  menu = {
    quick_navigation = false,
    keymaps = {
      ["<C-c>"] = "<C-w>q",
      ["h"] = "<C-w>c",
      ["l"] = function()
        local menu = require("dropbar.api").get_current_dropbar_menu()
        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,
    },
  },

This is my config, i want to set C-; to toggle dropbar. I've gone through docx, issues but unfortunately, didn't get how'd i actually map.

Bekaboo commented 7 months ago

Is there any way to map keys to toggle the dropbar

What do you mean by "toggle the dropbar"? If you mean hiding/showing the winbar, just use :set winbar= to hide to winbar and :set winbar=%{%v:lua.dropbar.get_dropbar_str()%} to show the winbar.

... than just clicking over?

Sorry, I don't understand here. Clicking the winbar does not toggle it. In most cases clicking on a symbol in a winbar will open a drop-down menu for that symbol.

pwnwriter commented 7 months ago

Oh, I apologize. What I meant to convey is that I would like to add a keymap for toggling the drop-down menu.

Bekaboo commented 7 months ago

Ah, I see. Please check https://github.com/Bekaboo/dropbar.nvim#usage - pick mode and https://github.com/Bekaboo/dropbar.nvim#api - pick() function.

willothy commented 7 months ago

You may be looking for require("dropbar.api").pick(), which allows you to use keymaps to select a dropdown. You can also pass in an index to open that symbol's dropdown without picking. My keymap looks like this:

vim.keymap.set("n", "<leader>bs", function()
  require("dropbar.api").pick(vim.v.count ~= 0 and vim.v.count)
end)
pwnwriter commented 7 months ago

Hey, thanks for the reponse.

Btw, one lil' question.

How'd i know if dropbar is set or not?

i wanna write a function that toggles dropbar. like if already open then closes, if closed, opens .

For example, here's a function that i wrote to toggle numbering

local cmds = { "nu!", "rnu!", "nonu!" }
local current_index = 1

function M.toggle_numbering()
  current_index = current_index % #cmds + 1
  vim.cmd("set " .. cmds[current_index])
end
willothy commented 7 months ago

How'd i know if dropbar is set or not?

I'm not sure what you mean by set in this case, but maybe you could use utils.menu.get to find a menu object for a given window/buffer, then use dropbar_menu_t:toggle()?

pwnwriter commented 7 months ago

As @Bekaboo mentioned, We can set dropbar values, Prooly values, don't know if i'm wrong about the term.

We have two values nill? which doesn't show anything

:set winbar=

and another one with infos.

:set winbar=%{%v:lua.dropbar.get_dropbar_str()%}

i wanna write a mapping to toggle between these cmds .

pwnwriter commented 7 months ago

Also, @willothy, what's the use of vim.v.count ?

When i try to print it, i get zero everytime.

Edit,

Ohh, wow just realized i can actually use alphabets to grab them. Pretty cool.

Thanks

pwnwriter commented 7 months ago

I've made this workaround, it works pretty well,

local winbar_state = 0
function M.toggle_dropbar()
  if winbar_state == 0 then
    vim.cmd "set winbar=%{%v:lua.dropbar.get_dropbar_str()%}"
    winbar_state = 1
  else
    vim.cmd "set winbar="
    winbar_state = 0
  end
end

feel free to drop your thoughts tho.

willothy commented 7 months ago

Also, @willothy, what's the use of vim.v.count ?

When i try to print it, i get zero everytime.

vim.v.count (or v:count in vimscript) is the count that can be passed to mappings. Typing a number before a mapping sets v:count, which can be used inside the mapping. This works the same was as 3dd to delete 3 lines; for example, in the mapping I showed above, you would type 3<leader>bs to open the dropdown for the 3rd symbol in the winbar.

If no number is typed, v:count will be 0. You can also use vim.v.count to get a count that will always be 1 instead of 0 when unset.

Ohh, wow just realized i can actually use alphabets to grab them. Pretty cool.

That's why I check for 0 in the mapping, because passing nil to .pick() allows you to use the picker functionality.

I've made this workaround, it works pretty well,

local winbar_state = 0
function M.toggle_dropbar()
  if winbar_state == 0 then
    vim.cmd "set winbar=%{%v:lua.dropbar.get_dropbar_str()%}"
    winbar_state = 1
  else
    vim.cmd "set winbar="
    winbar_state = 0
  end
end

feel free to drop your thoughts tho.

Thoughts: that's pretty much what I would do, but I think you could simplify it a little. You can use the Lua API to set the winbar option for example, and check its value instead of tracking state:

function M.toggle_dropbar()
  if vim.o.winbar == "" then
    vim.o.winbar = "%{%v:lua.dropbar.get_dropbar_str()%}"
  else
    vim.o.winbar = ""
  end
end