I have been trying to create a Lua function that allows me to clone a Neovim buffer. Here is what I have in my init.lua
file:
-- Set max optimum columns
vim.opt.colorcolumn = "80"
-- function to clone buffers
Clone_buffer = function()
local rfp = vim.fn.expand("%:h")
local ft = vim.bo.filetype
vim.cmd(string.format("%s" .. "/copy" .. ".%s", rfp, ft))
end
I have mapped it but every time I use it I get the next error:
E5108: Error executing lua vim/_editor.lua:0: nvim_exec2(): Vim(lua):E5107: Error loading lua [string ":lua"]:1: unexpected symbol near '/'
stack traceback:
[C]: in function 'nvim_exec2'
vim/_editor.lua: in function 'cmd'
~/.config/nvim/lua/custom/init.lua:7: in function 'Clone_buffer'
[string ":lua"]:1: in main chunk
I don't know what unexpected symbol near '/'
means. If anyone can help me I would appreciate it.
I have also tried changing "/copy" to "copy" but the same exception is raised, so I assume it has something to do with rfp
and ft
variables.
It's not clear how you intend to select which buffer to clone, nor where you want the cloned (copied) version to go. I'll assume that you want to clone the current buffer and output the contents to a duplicate file in the same directory as the file open in the current buffer. Upon pressing Alt
+d
, the following solution:
local function inc_file_name_until_unique(path_to_file)
-- Get the file name (with extension)
local file_name = string.match(path_to_file, "[^/]+$")
-- Get the file extension
local file_ext = string.match(path_to_file, "[.][^.]+$")
-- Get the file name (without extension) (use gsub to escape Lua magic characters with "%" symbol)
local file_name_wo_ext = string.gsub(file_name, file_ext:gsub("%W", "%%%1"), "")
-- Get the directory of the file (use gsub to escape Lua magic characters with "%" symbol)
local file_path = string.gsub(path_to_file, file_name:gsub("%W", "%%%1"), "")
local inc = 1
-- Create new file name
local new_file_name = file_path .. file_name_wo_ext .. "-clone" .. tostring(inc) .. file_ext
-- Check new file name is unique, if not, increment its counter until it is
while vim.fn.filereadable(new_file_name) == 1 do
inc = inc + 1
new_file_name = file_path .. file_name_wo_ext .. "-clone" .. tostring(inc) .. file_ext
end
return new_file_name
end
local function clone_buffer()
local curr_bufnr = vim.api.nvim_get_current_buf()
local curr_buf_content = vim.api.nvim_buf_get_lines(curr_bufnr, 0, -1, false)
local curr_buf_content_str = table.concat(curr_buf_content, "\n")
local curr_buf_name = vim.api.nvim_buf_get_name(curr_bufnr)
local clone_name = inc_file_name_until_unique(curr_buf_name)
local clone_file = io.output(clone_name)
clone_file:write(curr_buf_content_str)
clone_file:close()
vim.api.nvim_echo({{"Cloned current buffer to \"" .. clone_name .. "\""}}, false, {})
end
vim.keymap.set({'n'}, '<A-d>', '', {
callback = clone_buffer
})