Marcell Cruz
Posted on June 2, 2023
One of the great things about neovim is the ability to easilty create plugins using lua, lua is a very simple language and the way that it's integrated with neovim is really straight foward, when neovim is initiated it reads a file called init.lua in one of the paths configured, you can check the path by opening neovim and typing :h rtp
for run time path
you should see something like this
the first path is the one that matters for us, it means that neovim will search for the file inside ~/nvim
we can then go ahead and create a file there or use the file that you already have to create a function, just to test things out.
we can create a function to open a pop up menu using plenary.popup
, you need to install neovim plenary if you don't already have it here's the link https://github.com/nvim-lua/plenary.nvim, here's the function to show a popup menu using neovim plenary
local popup = require("plenary.popup")
local Win_id
function ShowMenu(opts, cb)
local height = 20
local width = 30
local borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }
Win_id = popup.create(opts, {
title = "MyProjects",
highlight = "MyProjectWindow",
line = math.floor(((vim.o.lines - height) / 2) - 1),
col = math.floor((vim.o.columns - width) / 2),
minwidth = width,
minheight = height,
borderchars = borderchars,
callback = cb,
})
local bufnr = vim.api.nvim_win_get_buf(Win_id)
vim.api.nvim_buf_set_keymap(bufnr, "n", "q", "<cmd>lua CloseMenu()<CR>", { silent=false })
end
The code is pretty self explanatory the only part that is a little confusing is the cb parameter, this parameter is the function that you gonna call when someone intereact with the popup menu, also we create a keymap for the popup buffer to close the popup when you hit q
vim.api.nvim_buf_set_keymap(bufnr, "n", "q", "<cmd>lua CloseMenu()<CR>", { silent=false })
This part can also be a little confusing.
and the following is the code to close the UI
function CloseMenu()
vim.api.nvim_win_close(Win_id, true)
end
this is the function that we gonna call when we hit q
when the pop up menu is openened
Now let's create another function to call the function that shows the menu
function MyMenu()
local opts = {}
local cb = function(_, sel)
print("it works")
end
ShowMenu(opts, cb)
end
We not gonna do anything here for now just open the menu with nothing inside it and then you can close the menu by hitting q
After writing this data to ~/nvim/init.lua you can load the file by running :so
then you can run :lua MyMenu()
to call the function and show the menu, you should see something like this
there's cool but not useful, how do we add data inside the menu? we can add data there the same way that we do in any buffer, just by setting lines of text, the plugin that we gonna build is just a list of projects that we can chose from and the cd in to the project from vim.
we can add the lines of text by filling out opts
the variable that we pass to the menu like this
function MyMenu()
local opts = {
"/home/me/myproject1",
"/home/me/myproject2",
"/home/me/myproject3",
}
........
this is just a list of things to show in the menu if you do that you should be able to see a list of those things now
Awesome!
We're almost there, now we just need to do something when someone choses one of the thing in the list, we can do that in the cb that we pass to the function.
local cb = function(_, sel)
vim.cmd("cd " .. sel)
end
if you hit enter on top of one of the lines, that line will be passed to this function and then we'll change neovim current directory to that path, in our example the paths aren't real but you get the idea, you just need to put a real path there, and that should do it, one upgrade that we can do is to load a file with paths instead of hardcoding the paths in the function, that way you don't need to open this lua file everytime you want to add a project to your list of projects, we can do that just by reading a simple file with a list of projects, same a list of project in ~/projects
/home/me/myproject1
/home/me/myproject2
/home/me/myproject3
now we can read this file and add to the options like this
local file = io.open("~/projects", "r") -- Open the file in read mode
local opts = {}
if file then
for line in file:lines() do
table.insert(opts, line)
end
end
--- pass the opts to the file later
the last thing we need to do is map this function to a shortcut that way we can hit the short cut and show the menu where we can chose our project
vim.keymap.set("n", "<leader>o", '<cmd>lua MyMenu()<CR>')
and that's pretty much it, after you have a way of creating a menu you can thing about a lot of interesint things todo the idea presented here is just to show a easy way of creating a menu in neovim, you can use lua to do anything that you want
Posted on June 2, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.