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', ' ts=' .. vim.o.tabstop, ' sw=' .. vim.o.shiftwidth, (vim.o.expandtab and ' et' or ' noet'), ' tw=' .. vim.o.textwidth, ' ft=' .. vim.o.filetype, ':', 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, {}) -- Files that could indicate the project's root directory M.project_root_markers = { '.git', '.hg', '.svn', '.bzr', '_darcs', '.projectile', '.clang-format', '.luarc.json', '.editorconfig' } function M.get_project_root() local path = vim.api.nvim_buf_get_name(0) local sep = '/' repeat path = path:gsub(string.format('%s[^%s]*$', sep, sep), '') for _, marker in ipairs(M.project_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 colours from highlight groups in web notation (#rrggbb) function M.get_hl_hex(hl_group) local hl = vim.api.nvim_get_hl_by_name(hl_group, true) local hl_hex = {} if hl.foreground then hl_hex.foreground = string.format('#%.6x', hl.foreground) end if hl.background then hl_hex.background = string.format('#%.6x', hl.background) end return hl_hex end -- return true if 'Symbols Nerd Font' is known to fontconfig function M.nerdfont_installed() if os.execute([[fc-list -q 'Symbols Nerd Font']]) == 0 then return true end return false end return M