ThePrimeagen / harpoon

MIT License
6.7k stars 363 forks source link

Tabline or other *Line integrations #352

Open ThePrimeagen opened 9 months ago

ThePrimeagen commented 9 months ago

I don't know what is needed for these integrations, but i am glad to expose data for it.

if list needs an api change to be able to integrate well, please list it here.

if anyone has some integration with *line integrations would like to make a PR to the README i would be glad to merge it

jackielii commented 9 months ago

I have written my bufferline.nvim integration, and it looks like this: image

Green is harpoon buffer, and Orange is bufferline buffer

The config is pretty straight forward. However there seems to be a bug in bufferline.nvim preventing the highlights to be updated. The texts updates fine though

Relavant lazy.nvim config:

  {
    'akinsho/bufferline.nvim',
    event = 'VeryLazy',

    opts = function()
      -- local colors = require("base16-colorscheme").colors
      local colors = require('colors.tokyodark-terminal')
      vim.api.nvim_set_hl(0, 'MyBufferSelected', { fg = colors.base01, bg = colors.base09 })
      vim.api.nvim_set_hl(0, 'MyHarpoonSelected', { fg = colors.base01, bg = colors.base0B })
      return {
        options = {
          custom_areas = {
            left = function()
              local result = {}
              local items = require('harpoon'):list().items
              for i = 1, #items do
                local fn = items[i].value
                local fullpath = vim.fn.fnamemodify(fn, ':p')
                local name = ' ' .. i .. '> ' .. vim.fn.fnamemodify(fn, ':t') .. ' '
                local activename = ' ' .. i .. '>* ' .. vim.fn.fnamemodify(fn, ':t') .. ' '
                if fullpath == vim.fn.expand('%:p') then
                  -- table.insert(result, { text = '│', link = 'BufferLineIndicatorSelected' })
                  -- table.insert(result, { text = name, link = 'MyHarpoonSelected' })
                  table.insert(result, { text = activename, link = 'BufferLineBufferVisible' })
                  -- table.insert(result, { text = '│', link = 'BufferLineIndicatorSelected' })
                else
                  -- print('inactive: ' .. name)
                  table.insert(result, { text = name, link = 'BufferLineBufferVisible' })
                end
              end
              return result
            end
          },
      }
  }

Obviously I want to use the { text = name, link = 'MyHarpoonSelected' }, but can't. So I'm using just text update adding a * for now.

Update: The issue https://github.com/akinsho/bufferline.nvim/issues/838 is fixed. The highlight using link now works

cbackas commented 8 months ago

I use lualine so i made a little config to add harpoon buffers to the tabline

  -- define visual settings for harpoon tabline
  local yellow = '#DCDCAA'
  local yellow_orange = '#D7BA7D'
  local background_color = "#282829"
  local grey = "#797C91"
  local light_blue = "#9CDCFE"
  vim.api.nvim_set_hl(0, "HarpoonInactive", { fg = grey, bg = background_color })
  vim.api.nvim_set_hl(0, "HarpoonActive", { fg = light_blue, bg = background_color })
  vim.api.nvim_set_hl(0, "HarpoonNumberActive", { fg = yellow, bg = background_color })
  vim.api.nvim_set_hl(0, "HarpoonNumberInactive", { fg = yellow_orange, bg = background_color })
  vim.api.nvim_set_hl(0, "TabLineFill", { fg = "white", bg = background_color })

  local harpoon = require('harpoon')

  function Harpoon_files()
    local contents = {}
    local marks_length = harpoon:list():length()
    local current_file_path = vim.fn.fnamemodify(vim.fn.expand("%:p"), ":.")
    for index = 1, marks_length do
      local harpoon_file_path = harpoon:list():get(index).value

      local label = ""
      if vim.startswith(harpoon_file_path, "oil") then
        local dir_path = string.sub(harpoon_file_path, 7)
        dir_path = vim.fn.fnamemodify(dir_path, ":.")
        label = '[' .. dir_path .. ']'
      elseif harpoon_file_path ~= "" then
        label = vim.fn.fnamemodify(harpoon_file_path, ":t")
      end

      label = label ~= "" and label or "(empty)"
      if current_file_path == harpoon_file_path then
        contents[index] = string.format("%%#HarpoonNumberActive# %s. %%#HarpoonActive#%s ", index, label)
      else
        contents[index] = string.format("%%#HarpoonNumberInactive# %s. %%#HarpoonInactive#%s ", index, label)
      end
    end

    return table.concat(contents)
  end

require('lualine').setup {
  tabline = {
    lualine_a = { { Harpoon_files } },
  },
  -- other config
}

result for me: image

lokxii commented 8 months ago

I only wanted to use the builtin tabline functionality in neovim, without lualine or bufferline, so I register autocmd to update tabline, using the function by @cbackas

vim.keymap.set("n", "<leader>ha", function()
    harpoon:list():append()
    vim.cmd(":do User")
end)
vim.keymap.set("n", "<leader>hh", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end)
vim.keymap.set("n", "<a-1>", function() harpoon:list():select(1) end)
vim.keymap.set("n", "<a-2>", function() harpoon:list():select(2) end)
vim.keymap.set("n", "<a-3>", function() harpoon:list():select(3) end)
vim.keymap.set("n", "<a-4>", function() harpoon:list():select(4) end)

function Harpoon_files()
    local contents = {}
    local marks_length = harpoon:list():length()
    local current_file_path = vim.fn.fnamemodify(vim.fn.expand("%:p"), ":.")
    for index = 1, marks_length do
        local harpoon_file_path = harpoon:list():get(index).value
        local file_name = harpoon_file_path == "" and "(empty)" or vim.fn.fnamemodify(harpoon_file_path, ':t')

        if current_file_path == harpoon_file_path then
            contents[index] = string.format("%%#HarpoonNumberActive# %s. %%#HarpoonActive#%s ", index, file_name)
        else
            contents[index] = string.format("%%#HarpoonNumberInactive# %s. %%#HarpoonInactive#%s ", index, file_name)
        end
    end

    return table.concat(contents)
end

vim.opt.showtabline = 2
vim.api.nvim_create_autocmd({ "BufEnter", "BufAdd", "User" }, {
    callback = function(ev)
        vim.o.tabline = Harpoon_files()
    end
})
fjchen7 commented 7 months ago

If it is possible, I hope each tab has its individual harpoon list. Just like scope.nvim, but for harpoon.

lokxii commented 7 months ago

Do you mean limiting the scope of harpoon project to per tab?

fjchen7 commented 7 months ago

@lokxii Exactly!

lokxii commented 7 months ago

@ThePrimeagen Is it possible to set config.settings.key to modify the definition of project from a project folder to a tab?

abeldekat commented 4 months ago

if list needs an api change to be able to integrate well, please list it here.

My plugin, harpoonline.nvim, supports each "*line". The data is cached and only updated when needed.

Currently, there is no notion of a "current" list in harpoon2. When working with multiple lists, the user has to maintain the reference to the current list. As such, when working with harpoonline, the user needs to emit custom event HarpoonSwitchedList

@ThePrimeagen, would it be possible to maintain the reference to the current list in harpoon? On harpoon:list(), without arguments, harpoon uses the default list. That would need to be changed to the default or the current list. Furthermore, an api method switchList and an extension listSwitched might be useful.

amalavet commented 2 months ago

Created a barbar.nvim integration: https://github.com/romgrk/barbar.nvim/issues/589