Skip to content

LintaoAmons/context-menu.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Warning

This plugin is in its early stages, and the data structures is like to undergo significant changes over time.

Philosophy · Install & Configuration · Usecases

Instead of keymaps, you can put your actions in the context menu

  • Menu is a buffer, use hjkl to navigate the items and trigger it or just trigger it by the number
  • Build your own menu, (items order) and (display or hide) are easily configurable
  • Split you config in multiple places, encapsulating those item in its own place
  • Adjust your config at runtime, simply source the setup function again
  • Local keymaps of the items

show

Philosophy

  • Minimise the cognitive overload in the head, but still put every functionality around you hand
  • Less keybindings but remian productivity
  • Configuration can be put in seperated spec files, and behaviour can be config at runtime and take effect immediately

Install & Configuration

For more complex usecases, you can use my config as a reference

local default_config = {
  -- add menu_items, if you call setup function at multiple place, this field will merge together instead of overwrite
  menu_items = {
    {
      cmd = "Run File",
      order = 1,
      not_ft = { "markdown" },
      action = {
        type = "callback",
        callback = function(context)
          if context.ft == "lua" then
            return vim.cmd([[source %]])
          elseif context.ft == "javascript" then
            return vim.print("run javascript:: haven't impl yet")
          end
        end,
      },
    }
  },
  enable_log = true, -- Optional, enable error log be printed out. Turn it off if you don't want see those lines
  default_action_keymaps = {
    -- hint: if you have keymap set to trigger menu like:
    -- vim.keymap.set({ "v", "n" }, "<M-l>", function() require("context-menu").trigger_context_menu() end, {})
    -- You can put the same key here to close the menu, which results like a toggle menu key:
    -- close_menu = { "q", "<ESC>", "<M-l>" },
    close_menu = { "q", "<ESC>" },
    trigger_action = { "<CR>", "o" },
  },
  ui = {
    selected_item = { bg = "#244C55", fg = "white" },
  },
}
Click here to check the items config demo
---@enum ContextMenu.ActionType
M.ActionType = {
  callback = "callback",
  sub_cmds = "sub_cmds",
}

---@class ContextMenu.Item
---@field cmd string **Unique identifier** and display name for the menu item.
---@field action ContextMenu.Action
---
--- filter
---@field ft? string[] Optional list of filetypes that determine menu item visibility.
---@field not_ft? string[] Optional list of filetypes that exclude the menu item's display.
---@field filter_func? fun(context: ContextMenu.Context): boolean Optional, true will remain, false will be filtered out
---
--- order
---@field fix? number Optional, fix the order of the menu item.
---@field order? number Optional, order of the menu item.
---
---@field keymap? string Optional, local keymap in menu

---@class ContextMenu.Action
---@field type ContextMenu.ActionType
---@field callback? fun(context: ContextMenu.Context): nil Function executed upon menu item selection, with context provided.
---@field sub_cmds? ContextMenu.Item[]


return {
  "LintaoAmons/context-menu.nvim",
  config = function(_, opts)
    -- setup function can be called multiple time at multiple places
    -- MenuItems will be merged instead of overwrite
    -- You can also source the setup function at runtime to test your configuration
    -- run `:lua = vim.g.context_menu_config` to check your current configuration
    require("context-menu").setup({
      menu_items = {
        {
          order = 1,
          cmd = "Code Action",
          not_ft = { "markdown" },
          action = {
            type = "callback",
            callback = function(_)
              vim.cmd([[Lspsaga code_action]])
            end,
          },
        },
        {
          cmd = "ChatGPT :: New",
          keymap = "a", -- keymap `a` will trigger this action when it show in the menu
          action = {
            type = "callback",
            callback = function(_)
              vim.cmd([[GpChatNew vsplit]])
            end,
          },
        },
        {
          order = 2,
          cmd = "Run Test",
          filter_func = function(context)
            local a = context.filename
            if string.find(a, ".test.") or string.find(a, "spec.") then
              return true
            else
              return false
            end
          end,
          action = {
            type = "callback",
            callback = function(_)
              require("neotest").run.run()
            end,
          },
        },
      },
    })
  end,
}

Keymaps

No default keymaps, you need to set the shortcut by yourself, here's a reference

vim.keymap.set({ "v", "n" }, "<M-l>", function()
  require("context-menu").trigger_context_menu()
end, {})

Usecases

Copy paste the module into your config.

Please share your usecases by provided a PR.

CONTRIBUTING

Don't hesitate to ask me anything about the codebase if you want to contribute.

By telegram or 微信: CateFat

Some Other Neovim Stuff


TODO:

  • make configuration source-able in the runtime
  • configurable keymaps
  • Show shortcut in the menu
  • fix the reorder function
  • fix_order field in MenuItem
  • enhance j/k: k jump from the first item to the last time, j jump from the last item to the first item
  • navi back/forward
  • beautify menu buffer
    • highlight item under cursor
    • sub menu position
    • render shortcuts at the end of the line

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages