Skip to content

Efficient targetted menu built for fast buffer navigation

Notifications You must be signed in to change notification settings

leath-dub/snipe.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 

Repository files navigation

Snipe.nvim

NOTE: Main development is now on the branch snipe2, try it out and let me know what you think! To switch to the branch just add branch = "snipe2" in your lazy plugin spec.

Efficient targetted menu built for fast buffer navigation

recording

Description

Snipe.nvim is selection menu that can accept any list of items and present a user interface with quick minimal character navigation hints to select exactly what you want. It is not flashy it is just fast !

Motivation

If you ever find yourself in a tangle of buffers scrabbling to find your way back to where you came from, this plugin can help ! Maybe you use harpoon, this is great for project files, but what if you want a fast fallback for when you're in someone else's project. Maybe you use telescope, but that can feel inconsistent and visually distracting. This is why I made this, because I wanted a Vimium-like way of hopping around a large amount of buffers

Usage

For lazy.nvim:

{
  "leath-dub/snipe.nvim",
  keys = {
    {"gb", function () require("snipe").open_buffer_menu() end, desc = "Open Snipe buffer menu"}
  },
  opts = {}
}

For packadd (builtin package manager), clone the repo into $HOME/.config/nvim/pack/snipe/opt/snipe.nvim and add this to your configuration:

vim.cmd.packadd "snipe.nvim"
local snipe = require("snipe")
snipe.setup()
vim.keymap.set("n", "gb", snipe.open_buffer_menu)

Options

You can pass in a table of options to the setup function, here are the default options:

Snipe.config = {
  ui = {
    max_width = -1, -- -1 means dynamic width
    -- Where to place the ui window
    -- Can be any of "topleft", "bottomleft", "topright", "bottomright", "center", "cursor" (sets under the current cursor pos)
    position = "topleft",
    -- Override options passed to `nvim_open_win`
    -- Be careful with this as snipe will not validate
    -- anything you override here. See `:h nvim_open_win`
    -- for config options
    open_win_override = {
      -- title = "My Window Title",
      border = "single", -- use "rounded" for rounded border
    },
  },
  hints = {
    -- Charaters to use for hints (NOTE: make sure they don't collide with the navigation keymaps)
    dictionary = "sadflewcmpghio",
  },
  navigate = {
    -- When the list is too long it is split into pages
    -- `[next|prev]_page` options allow you to navigate
    -- this list
    next_page = "J",
    prev_page = "K",

    -- You can also just use normal navigation to go to the item you want
    -- this option just sets the keybind for selecting the item under the
    -- cursor
    under_cursor = "<cr>",

    -- In case you changed your mind, provide a keybind that lets you
    -- cancel the snipe and close the window.
    cancel_snipe = "<esc>",

    -- Close the buffer under the cursor
    -- Remove "j" and "k" from your dictionary to navigate easier to delete
    -- NOTE: Make sure you don't use the character below on your dictionary
    close_buffer = "D",
  },
  -- The default sort used for the buffers
  -- Can be any of "last", (sort buffers by last accessed) "default" (sort buffers by its number)
  sort = "default"
}

You can also pass options to create_buffer_menu_toggler:

{
  -- Limit the width of path buffer names
  -- /my/long/path/is/really/annoying will be is/really/annoying (max of 3)
  max_path_width = 3
}

Events

The following User events can be hooked into:

  • SnipeCreateBuffer - event is triggered after tag and default mappings are set. The following code allows you to hook into this:
vim.api.nvim_create_autocmd("User", {
  pattern = "SnipeCreateBuffer",
  callback = function (args)
    -- | Format of `args`:
    --
    -- args = {
    --   data = {
    --     menu = {
    --       close = <function>,
    --       open = <function>,
    --       is_open = <function>,
    --     }
    --     buf = <menu bufnr>,
    --   }
    -- }

    -- Do something with args
  end,
})

Producers

A producer is just a function that returns two lists (tables), the first is a user/meta-data table, this is will later be passed into a callback allowing you to give context to the selections (e.g. for buffer producer the meta-data is the list of buffer-id's). The second table is the list of actual strings you want to list as selections.

Below is an example of a file producer:

local function file_menu_toggler()
  local function file_producer()
    local uv = (vim.loop or vim.uv)
    local items = {}

    for name, type in vim.fs.dir(uv.cwd()) do
      table.insert(items, { type, name })
    end

    local items_display = vim.tbl_map(function (ent)
      return string.format("%s %s", (ent[1] == "file" and "F" or "D"), ent[2])
    end, items)

    return items, items_display
  end

  return snipe.create_menu_toggler(file_producer, function (meta, _) vim.cmd.edit(meta[2]) end)
end

vim.keymap.set("n", "<leader>f", file_menu_toggler())

This lets you navigate files in the current directory with <leader>f

About

Efficient targetted menu built for fast buffer navigation

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages