nvim/plugin/commands.lua

194 lines
6.0 KiB
Lua

-- :RStrip strip white psace from right of all lines, ranges supported
vim.api.nvim_create_user_command('RStrip', function(opts)
local pos = vim.fn.getcurpos(vim.api.nvim_get_current_win())
local range = opts.line1 .. ',' .. opts.line2
vim.cmd.execute("'" .. range .. 's/\\s\\+$//e' .. "'")
vim.cmd.nohlsearch()
vim.fn.setpos('.', pos)
end, { range = '%' })
-- :TabWidth set the tab width for the current buffer
vim.api.nvim_create_user_command('TabWidth', function(opts)
-- Set the tab width for the current filetype
local width = tonumber(opts.args)
vim.opt.tabstop = width
vim.opt.shiftwidth = width
vim.opt.softtabstop = width
end, { nargs = 1 })
-- :Remove the file associated with the current buffer, bang to delete buffer
vim.api.nvim_create_user_command('Remove', function(opts)
local path = vim.fn.expand('%:p')
-- Using opts.bang in the callback can cause a SEGFAULT, instead use it
-- before invoking the async unlink to select which callback should be called
-- on completion.
local callback = nil
if opts.bang then
-- Invoked as :Remove! so also delete the buffer.
callback = function(err, success)
if success then
vim.schedule(function()
vim.api.nvim_buf_delete(vim.api.nvim_get_current_buf(), {})
end)
else
error(err)
end
end
else
-- Invoked as :Remove so don't delete the buffer.
callback = function(err, success)
if not success then
error(err)
end
end
end
-- Actually remove the file using the selected callback.
vim.loop.fs_unlink(path, callback)
end, { bang = true })
-- :Move the file associated with the current buffer
vim.api.nvim_create_user_command('Move', function(opts)
local source = vim.fn.expand('%:p')
local dest = opts.args
if vim.fn.isdirectory(dest) ~= 0 then
dest = vim.fn.resolve(dest .. '/' .. vim.fn.expand('%:t'))
end
vim.loop.fs_rename(source, dest, function(err, success)
if success then
vim.schedule(function()
vim.cmd.edit(dest)
end)
else
error(err)
end
end)
end, {
nargs = 1,
complete = 'file',
})
-- :Rename the file associated with current buffer
vim.api.nvim_create_user_command('Rename', function(opts)
local source = vim.fn.expand('%')
local dest = nil
local dir = vim.fn.expand('%:h')
if dir == '.' then
dest = opts.args
else
dest = vim.fn.resolve(dir .. '/' .. opts.args)
end
local buffer = vim.api.nvim_get_current_buf()
vim.loop.fs_rename(source, dest, function(err, success)
if not success then
error(err)
else
vim.schedule(function()
vim.cmd.edit(dest)
vim.api.nvim_buf_delete(buffer, {})
end)
end
end)
end, {
nargs = 1,
complete = function()
return { vim.fn.expand('%:t') }
end
})
-- :Chmod change file mode bits
if vim.fn.executable('chmod') == 1 then
vim.api.nvim_create_user_command('Chmod', function(opts)
local file = vim.fn.expand('%:p')
vim.fn.system('chmod ' .. opts.args .. ' ' .. file)
end, { nargs = '+' })
end
-- :Mkdir create a directory, bang to create intermediate directories
vim.api.nvim_create_user_command('Mkdir', function(opts)
local flags = nil
if opts.bang then
flags = 'p'
end
vim.fn.mkdir(opts.args, flags)
end, {
bang = true,
nargs = 1,
complete = 'file',
})
-- :Rg grep for the given string, word under the cursor, or visual selection
-- then fuzzy find the results. Bang to enable regex in given string.
vim.api.nvim_create_user_command('Rg', function(opts)
local search = opts.args
if opts.range == 2 then
local lines = vim.fn.getline(vim.fn.line("'<"), vim.fn.line("'>"))
local start_col = vim.fn.col("'<")
local end_col = vim.fn.col("'>")
if #lines == 1 then
lines[1] = string.sub(lines[1], start_col, end_col)
else
lines[1] = string.sub(lines[1], start_col)
lines[#lines] = string.sub(lines[#lines], 1, end_col)
end
search = table.concat(lines, "\n")
elseif #search == 0 then
search = vim.fn.expand('<cword>')
end
local grep_opts = { search = search}
if opts.bang then
grep_opts['use_regex'] = true
end
require('telescope.builtin').grep_string(grep_opts)
end, { bang = true, range = true, nargs = '*' })
-- :PreProcIfWrap wraps the given range of lines in #if 0 / #endif.
vim.api.nvim_create_user_command('PreProcIfWrap', function(opts)
local buffer = vim.api.nvim_get_current_buf()
vim.api.nvim_buf_set_lines(
buffer, opts.line2, opts.line2, true, { '#endif' })
vim.api.nvim_buf_set_lines(
buffer, opts.line1 - 1, opts.line1 - 1, true, { '#if 0' })
local window = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_cursor(window, { opts.line1, 5 })
end, { range = true })
-- :CheckboxToggle toggles GitHub Flavoured Markdown style checkboxes.
vim.api.nvim_create_user_command('CheckboxToggle', function(opts)
local linenr = vim.fn.line('.')
local line = vim.fn.getline(linenr)
local pos = string.find(line, '[ ]', 0, true)
if pos == nil then
pos = string.find(line, '[x]', 0, true)
if pos == nil then
return
end
end
local x = string.sub(line, pos + 1, pos + 1)
if x == 'x' then x = ' ' else x = 'x' end
vim.fn.setline(linenr, string.sub(line, 1, pos) .. x .. string.sub(line, pos + 2))
end, {})
-- :Tac reverse the order of lines in the selected range or the whole file if
-- no range is specificed, works as if executing :!tac but purely in Lua making
-- it cross-platform.
vim.api.nvim_create_user_command('Tac', function(opts)
local buffer = vim.api.nvim_get_current_buf()
local line1 = opts.line1 - 1
local line2 = opts.line2
if opts.range == 0 then
line1 = 0
line2 = -1
end
print(opts.range, line1, line2)
local lines = vim.api.nvim_buf_get_lines(buffer, line1, line2, false)
if lines and #lines > 1 then
local temp = nil
for n = 1, math.floor(#lines / 2) do
temp = lines[n]
lines[n] = lines[#lines - (n - 1)]
lines[#lines - (n - 1)] = temp
end
vim.api.nvim_buf_set_lines(buffer, line1, line2, true, lines)
end
end, { range = true })