local M = {} function M.map(mode, shortcut, command, description, buffer) local opts = { noremap = true, silent = true } opts.desc = description or nil opts.buffer = buffer or nil vim.keymap.set(mode, shortcut, command, opts) end function M.remove_trailing_whitespace() local curpos = vim.api.nvim_win_get_cursor(0) vim.cmd([[keeppatterns %s/\s\+$//e]]) vim.api.nvim_win_set_cursor(0, curpos) end vim.api.nvim_create_augroup('config_functions', { clear = true }) vim.api.nvim_create_autocmd( { 'BufWritePre' }, { group = 'config_functions', pattern = { '*.lua', '*.cpp', '*.hpp', '*.conf', '*.cfg', '*.ini', '*.adoc' }, callback = M.remove_trailing_whitespace } ) -- Insert or update a modeline at the bottom of the buffer function M.insert_modeline() local comment_string = vim.o.commentstring local space_maybe = '' if string.match(comment_string, '%%s(.*)') ~= '' then space_maybe = ' ' end local fenc = vim.o.fileencoding if fenc == '' then fenc = 'utf-8' end local modeline_elements = { ' vim: set', ' fenc=' .. fenc, ' ts=' .. vim.o.tabstop, ' sw=' .. vim.o.shiftwidth, (vim.o.expandtab and ' et' or ' noet'), ' tw=' .. vim.o.textwidth, ':', space_maybe } local modeline = comment_string:gsub('%%s', table.concat(modeline_elements)) modeline = modeline:gsub(' ', ' ') local buffer = vim.api.nvim_win_get_buf(0) local current = vim.api.nvim_buf_get_lines(buffer, -2, -1, true)[1] if current == modeline then print('modeline already exists') elseif string.match(current, 'vim:') then vim.api.nvim_buf_set_lines(buffer, -2, -1, true, { modeline }) print('modeline updated') else vim.api.nvim_buf_set_lines(buffer, -1, -1, true, { '', modeline }) print('modeline inserted') end end vim.api.nvim_create_user_command('ModelineInsert', M.insert_modeline, {}) -- set colorcolumn to textwidth after buffer is displayed or option is changed function M.set_colorcolumn() if vim.o.textwidth > 0 then vim.opt_local.colorcolumn = { vim.o.textwidth } else vim.opt_local.colorcolumn = '' end end vim.api.nvim_create_augroup('config_settings', { clear = true }) vim.api.nvim_create_autocmd( { 'BufEnter' }, { group = 'config_settings', callback = M.set_colorcolumn } ) vim.api.nvim_create_autocmd( { 'OptionSet' }, { group = 'config_settings', pattern = { 'textwidth' }, callback = M.set_colorcolumn } ) function M.get_project_root() local path = vim.api.nvim_buf_get_name(0) local root_markers = { '.git', '.hg', '.svn', '.bzr', '_darcs', '.projectile', '.clang-format', '.luarc.json' } local sep = '/' repeat path = path:gsub(string.format('%s[^%s]*$', sep, sep), '') for _, marker in ipairs(root_markers) do if io.open(path .. sep .. marker) then return path end end until path == '' return nil end function M.shell_capture(command) local handle = io.popen(command) if not handle then return nil end local result = handle:read() or nil handle:close() return result end return M