From 49216a9c9335e2543f014181ac22cfc359f7a63b Mon Sep 17 00:00:00 2001 From: Akianonymus Date: Wed, 25 Aug 2021 10:58:56 +0530 Subject: [PATCH] feat: Support for custom user mappings | Improve map function move map function to utils rearrange utils, was missed --- lua/chadrc.lua | 17 +++++ lua/core/mappings.lua | 141 +++++++++++++++++++------------------ lua/core/utils.lua | 156 +++++++++++++++++++++++++++-------------- lua/default_config.lua | 17 +++++ 4 files changed, 207 insertions(+), 124 deletions(-) diff --git a/lua/chadrc.lua b/lua/chadrc.lua index 2cec148..edadb13 100644 --- a/lua/chadrc.lua +++ b/lua/chadrc.lua @@ -1,6 +1,7 @@ -- IMPORTANT NOTE : This is the user config, can be edited. Will be preserved if updated with internal updater local M = {} +M.ui, M.options, M.plugin_status, M.mappings, M.custom = {}, {}, {}, {}, {} -- non plugin ui configs, available without any plugins M.ui = { @@ -191,4 +192,20 @@ M.mappings.plugin = { }, } +-- user custom mappings +-- e.g: name = { "mode" , "keys" , "cmd" , "options"} +-- name: can be empty or something unique with repect to other custom mappings +-- { mode, key, cmd } or name = { mode, key, cmd } +-- mode: usage: mode or { mode1, mode2 }, multiple modes allowed, available modes => :h map-modes, +-- keys: multiple keys allowed, same synxtax as modes +-- cmd: for vim commands, must use ':' at start and add at the end if want to execute +-- options: see :h nvim_set_keymap() opts section +M.custom.mappings = { + -- clear_all = { + -- "n", + -- "cc", + -- "gg0vG$d", + -- }, +} + return M diff --git a/lua/core/mappings.lua b/lua/core/mappings.lua index 6c36cd0..547fe60 100644 --- a/lua/core/mappings.lua +++ b/lua/core/mappings.lua @@ -1,37 +1,26 @@ -local config = require("core.utils").load_config() +local utils = require "core.utils" + +local config = utils.load_config() +local map = utils.map + local maps = config.mappings local plugin_maps = maps.plugin + local cmd = vim.cmd -local function map(mode, lhs, rhs, opts) - local options = { noremap = true, silent = true } - if opts then - options = vim.tbl_extend("force", options, opts) - end - - -- if list of keys provided then run set for all of them - if type(lhs) == "table" then - for _, key in ipairs(lhs) do - vim.api.nvim_set_keymap(mode, key, rhs, options) - end - else - vim.api.nvim_set_keymap(mode, lhs, rhs, options) - end -end - -local opt, M = {}, {} +local M = {} -- these mappings will only be called during initialization M.misc = function() local function non_config_mappings() -- dont copy any deleted text , this is disabled by default so uncomment the below mappings if you want them - -- map("n", "dd", [=[ "_dd ]=], opt) - -- map("v", "dd", [=[ "_dd ]=], opt) - -- map("v", "x", [=[ "_x ]=], opt) + -- map("n", "dd", [=[ "_dd ]=]) + -- map("v", "dd", [=[ "_dd ]=]) + -- map("v", "x", [=[ "_x ]=]) -- todo: this should be configurable via chadrc -- Don't copy the replaced text after pasting in visual mode - map("v", "p", '"_dP', opt) + map("v", "p", '"_dP') -- Allow moving the cursor through wrapped lines with j, k, and -- http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/ @@ -42,7 +31,7 @@ M.misc = function() map("", "", 'v:count ? "k" : "gk"', { expr = true }) -- use ESC to turn off search highlighting - map("n", "", ":noh ", opt) + map("n", "", ":noh ") end local function optional_mappings() @@ -50,12 +39,12 @@ M.misc = function() if config.options.insert_nav then local inav = maps.insert_nav - map("i", inav.backward, "", opt) - map("i", inav.end_of_line, "", opt) - map("i", inav.forward, "", opt) - map("i", inav.next_line, "", opt) - map("i", inav.prev_line, "", opt) - map("i", inav.top_of_line, "^i", opt) + map("i", inav.backward, "") + map("i", inav.end_of_line, "") + map("i", inav.forward, "") + map("i", inav.next_line, "") + map("i", inav.prev_line, "") + map("i", inav.top_of_line, "^i") end -- check the theme toggler @@ -70,21 +59,21 @@ M.misc = function() end local function required_mappings() - map("n", maps.close_buffer, ":lua require('core.utils').close_buffer() ", opt) -- close buffer - map("n", maps.copy_whole_file, ":%y+ ", opt) -- copy whole file content - map("n", maps.new_buffer, ":enew ", opt) -- new buffer - map("n", maps.new_tab, ":tabnew ", opt) -- new tabs - map("n", maps.line_number_toggle, ":set nu! ", opt) -- toggle numbers - map("n", maps.save_file, ":w ", opt) -- ctrl + s to save file + map("n", maps.close_buffer, ":lua require('core.utils').close_buffer() ") -- close buffer + map("n", maps.copy_whole_file, ":%y+ ") -- copy whole file content + map("n", maps.new_buffer, ":enew ") -- new buffer + map("n", maps.new_tab, ":tabnew ") -- new tabs + map("n", maps.line_number_toggle, ":set nu! ") -- toggle numbers + map("n", maps.save_file, ":w ") -- ctrl + s to save file -- terminal mappings -- local term_maps = maps.terminal -- get out of terminal mode - map("t", term_maps.esc_termmode, "", opt) + map("t", term_maps.esc_termmode, "") -- hide a term from within terminal mode - map("t", term_maps.esc_hide_termmode, " :lua require('core.utils').close_buffer() ", opt) + map("t", term_maps.esc_hide_termmode, " :lua require('core.utils').close_buffer() ") -- pick a hidden term - map("n", term_maps.pick_term, ":Telescope terms ", opt) + map("n", term_maps.pick_term, ":Telescope terms ") -- Open terminals -- TODO this opens on top of an existing vert/hori term, fixme map( @@ -93,8 +82,8 @@ M.misc = function() ":execute 15 .. 'new +terminal' | let b:term_type = 'hori' | startinsert ", opt ) - map("n", term_maps.new_vertical, ":execute 'vnew +terminal' | let b:term_type = 'vert' | startinsert ", opt) - map("n", term_maps.new_window, ":execute 'terminal' | let b:term_type = 'wind' | startinsert ", opt) + map("n", term_maps.new_vertical, ":execute 'vnew +terminal' | let b:term_type = 'vert' | startinsert ") + map("n", term_maps.new_window, ":execute 'terminal' | let b:term_type = 'wind' | startinsert ") -- terminal mappings end -- -- Add Packer commands because we are not loading it at startup @@ -107,12 +96,24 @@ M.misc = function() -- add NvChadUpdate command and mapping cmd "silent! command! NvChadUpdate lua require('nvchad').update_nvchad()" - map("n", maps.update_nvchad, ":NvChadUpdate ", opt) + map("n", maps.update_nvchad, ":NvChadUpdate ") + end + + local function user_config_mappings() + local custom_maps = config.custom.mappings or "" + if type(custom_maps) ~= "table" then + return + end + + for _, map_table in pairs(custom_maps) do + map(unpack(map_table)) + end end non_config_mappings() optional_mappings() required_mappings() + user_config_mappings() end -- below are all plugin related mappinsg @@ -124,14 +125,14 @@ end M.bufferline = function() local m = plugin_maps.bufferline - map("n", m.next_buffer, ":BufferLineCycleNext ", opt) - map("n", m.prev_buffer, ":BufferLineCyclePrev ", opt) + map("n", m.next_buffer, ":BufferLineCycleNext ") + map("n", m.prev_buffer, ":BufferLineCyclePrev ") end M.chadsheet = function() local m = plugin_maps.chadsheet - map("n", m.default_keys, ":lua require('cheatsheet').show_cheatsheet_telescope() ", opt) + map("n", m.default_keys, ":lua require('cheatsheet').show_cheatsheet_telescope() ") map( "n", m.user_keys, @@ -142,64 +143,64 @@ end M.comment = function() local m = plugin_maps.comment.toggle - map("n", m, ":CommentToggle ", opt) - map("v", m, ":CommentToggle ", opt) + map("n", m, ":CommentToggle ") + map("v", m, ":CommentToggle ") end M.dashboard = function() local m = plugin_maps.dashboard - map("n", m.bookmarks, ":DashboardJumpMarks ", opt) - map("n", m.new_file, ":DashboardNewFile ", opt) - map("n", m.open, ":Dashboard ", opt) - map("n", m.session_load, ":SessionLoad ", opt) - map("n", m.session_save, ":SessionSave ", opt) + map("n", m.bookmarks, ":DashboardJumpMarks ") + map("n", m.new_file, ":DashboardNewFile ") + map("n", m.open, ":Dashboard ") + map("n", m.session_load, ":SessionLoad ") + map("n", m.session_save, ":SessionSave ") end M.nvimtree = function() - map("n", plugin_maps.nvimtree.toggle, ":NvimTreeToggle ", opt) - map("n", plugin_maps.nvimtree.focus, ":NvimTreeFocus ", opt) + map("n", plugin_maps.nvimtree.toggle, ":NvimTreeToggle ") + map("n", plugin_maps.nvimtree.focus, ":NvimTreeFocus ") end M.neoformat = function() - map("n", plugin_maps.neoformat.format, ":Neoformat ", opt) + map("n", plugin_maps.neoformat.format, ":Neoformat ") end M.telescope = function() local m = plugin_maps.telescope - map("n", m.buffers, ":Telescope buffers ", opt) - map("n", m.find_files, ":Telescope find_files ", opt) + map("n", m.buffers, ":Telescope buffers ") + map("n", m.find_files, ":Telescope find_files ") map("n", m.find_hiddenfiles, ":Telescope find_files hidden=true ", opt) - map("n", m.git_commits, ":Telescope git_commits ", opt) - map("n", m.git_status, ":Telescope git_status ", opt) - map("n", m.help_tags, ":Telescope help_tags ", opt) - map("n", m.live_grep, ":Telescope live_grep ", opt) - map("n", m.oldfiles, ":Telescope oldfiles ", opt) - map("n", m.themes, ":Telescope themes ", opt) + map("n", m.git_commits, ":Telescope git_commits ") + map("n", m.git_status, ":Telescope git_status ") + map("n", m.help_tags, ":Telescope help_tags ") + map("n", m.live_grep, ":Telescope live_grep ") + map("n", m.oldfiles, ":Telescope oldfiles ") + map("n", m.themes, ":Telescope themes ") end M.telescope_media = function() local m = plugin_maps.telescope_media - map("n", m.media_files, ":Telescope media_files ", opt) + map("n", m.media_files, ":Telescope media_files ") end M.truezen = function() local m = plugin_maps.truezen - map("n", m.ataraxis_mode, ":TZAtaraxis ", opt) - map("n", m.focus_mode, ":TZFocus ", opt) - map("n", m.minimalistic_mode, ":TZMinimalist ", opt) + map("n", m.ataraxis_mode, ":TZAtaraxis ") + map("n", m.focus_mode, ":TZFocus ") + map("n", m.minimalistic_mode, ":TZMinimalist ") end M.vim_fugitive = function() local m = plugin_maps.vim_fugitive - map("n", m.git, ":Git ", opt) - map("n", m.git_blame, ":Git blame ", opt) - map("n", m.diff_get_2, ":diffget //2 ", opt) - map("n", m.diff_get_3, ":diffget //3 ", opt) + map("n", m.git, ":Git ") + map("n", m.git_blame, ":Git blame ") + map("n", m.diff_get_2, ":diffget //2 ") + map("n", m.diff_get_3, ":diffget //3 ") end return M diff --git a/lua/core/utils.lua b/lua/core/utils.lua index cafd1e3..e42cc67 100644 --- a/lua/core/utils.lua +++ b/lua/core/utils.lua @@ -136,6 +136,108 @@ M.hide_statusline = function() end end +-- load config +-- 1st arg = boolean - whether to force reload +-- Modifies _G._NVCHAD_CONFIG global variable +M.load_config = function(reload) + -- only do the stuff below one time, otherwise just return the set config + if _G._NVCHAD_CONFIG_CONTENTS ~= nil and not (reload or false) then + return _G._NVCHAD_CONFIG_CONTENTS + end + + -- these are the table value which will be always prioritiezed to take user config value + local to_replace = { + "['mappings']['plugin']['esc_insertmode']", + "['mappings']['terminal']['esc_termmode']", + "['mappings']['terminal']['esc_hide_termmode']", + } + + local default_config = "default_config" + local config_name = vim.g.nvchad_user_config or "chadrc" + local config_file = vim.fn.stdpath "config" .. "/lua/" .. config_name .. ".lua" + + -- unload the modules if force reload + if reload then + package.loaded[default_config or false] = nil + package.loaded[config_name or false] = nil + end + + -- don't enclose in pcall, it better break when default config is faulty + _G._NVCHAD_CONFIG_CONTENTS = require(default_config) + + -- user config is not required to run nvchad but a optional + -- Make sure the config doesn't break the whole system if user config is not present or in bad state or not a table + -- print warning texts if user config file is present + -- check if the user config is present + if vim.fn.empty(vim.fn.glob(config_file)) < 1 then + local present, config = pcall(require, config_name) + if present then + -- make sure the returned value is table + if type(config) == "table" then + -- data = require(config_name) + _G._NVCHAD_CONFIG_CONTENTS = require("core.utils").merge_table( + _G._NVCHAD_CONFIG_CONTENTS, + config, + to_replace + ) + else + print("Warning: " .. config_name .. " sourced successfully but did not return a lua table.") + end + else + print("Warning: " .. config_file .. " is present but sourcing failed.") + end + end + return _G._NVCHAD_CONFIG_CONTENTS +end + +M.map = function(mode, keys, cmd, opt) + local options = { noremap = true, silent = true } + if opt then + options = vim.tbl_extend("force", options, opt) + end + + -- all valid modes allowed for mappings + -- :h map-modes + local valid_modes = { + [""] = true, + ["n"] = true, + ["v"] = true, + ["s"] = true, + ["x"] = true, + ["o"] = true, + ["!"] = true, + ["i"] = true, + ["l"] = true, + ["c"] = true, + ["t"] = true, + } + + -- helper function for M.map + -- can gives multiple modes and keys + local function map_wrapper(mode, lhs, rhs, options) + if type(lhs) == "table" then + for _, key in ipairs(lhs) do + map_wrapper(mode, key, rhs, options) + end + else + if type(mode) == "table" then + for _, m in ipairs(mode) do + map_wrapper(m, lhs, rhs, options) + end + else + if valid_modes[mode] and lhs and rhs then + vim.api.nvim_set_keymap(mode, lhs, rhs, options) + else + mode, lhs, rhs = mode or "", lhs or "", rhs or "" + print("Cannot set mapping [ mode = '" .. mode .. "' | key = '" .. lhs .. "' | cmd = '" .. rhs .. "' ]") + end + end + end + end + + map_wrapper(mode, keys, cmd, options) +end + -- Base code: https://gist.github.com/revolucas/184aec7998a6be5d2f61b984fac1d7f7 -- Changes over it: preserving table 1 contents and also update with table b, without duplicating -- 1st arg - base table @@ -208,58 +310,4 @@ end]] return into end --- load config --- 1st arg = boolean - whether to force reload --- Modifies _G._NVCHAD_CONFIG global variable -M.load_config = function(reload) - -- only do the stuff below one time, otherwise just return the set config - if _G._NVCHAD_CONFIG_CONTENTS ~= nil and not (reload or false) then - return _G._NVCHAD_CONFIG_CONTENTS - end - - -- these are the table value which will be always prioritiezed to take user config value - local to_replace = { - "['mappings']['plugin']['esc_insertmode']", - "['mappings']['terminal']['esc_termmode']", - "['mappings']['terminal']['esc_hide_termmode']", - } - - local default_config = "default_config" - local config_name = vim.g.nvchad_user_config or "chadrc" - local config_file = vim.fn.stdpath "config" .. "/lua/" .. config_name .. ".lua" - - -- unload the modules if force reload - if reload then - package.loaded[default_config or false] = nil - package.loaded[config_name or false] = nil - end - - -- don't enclose in pcall, it better break when default config is faulty - _G._NVCHAD_CONFIG_CONTENTS = require(default_config) - - -- user config is not required to run nvchad but a optional - -- Make sure the config doesn't break the whole system if user config is not present or in bad state or not a table - -- print warning texts if user config file is present - -- check if the user config is present - if vim.fn.empty(vim.fn.glob(config_file)) < 1 then - local present, config = pcall(require, config_name) - if present then - -- make sure the returned value is table - if type(config) == "table" then - -- data = require(config_name) - _G._NVCHAD_CONFIG_CONTENTS = require("core.utils").merge_table( - _G._NVCHAD_CONFIG_CONTENTS, - config, - to_replace - ) - else - print("Warning: " .. config_name .. " sourced successfully but did not return a lua table.") - end - else - print("Warning: " .. config_file .. " is present but sourcing failed.") - end - end - return _G._NVCHAD_CONFIG_CONTENTS -end - return M diff --git a/lua/default_config.lua b/lua/default_config.lua index 63509a3..080254c 100644 --- a/lua/default_config.lua +++ b/lua/default_config.lua @@ -1,6 +1,7 @@ -- IMPORTANT NOTE : This is default config, so dont change anything here. (check chadrc.lua instead) local M = {} +M.ui, M.options, M.plugin_status, M.mappings, M.custom = {}, {}, {}, {}, {} -- non plugin ui configs, available without any plugins M.ui = { @@ -198,4 +199,20 @@ M.mappings.plugin = { }, } +-- user custom mappings +-- e.g: name = { "mode" , "keys" , "cmd" , "options"} +-- name: can be empty or something unique with repect to other custom mappings +-- { mode, key, cmd } or name = { mode, key, cmd } +-- mode: usage: mode or { mode1, mode2 }, multiple modes allowed, available modes => :h map-modes, +-- keys: multiple keys allowed, same synxtax as modes +-- cmd: for vim commands, must use ':' at start and add at the end if want to execute +-- options: see :h nvim_set_keymap() opts section +M.custom.mappings = { + -- clear_all = { + -- "n", + -- "cc", + -- "gg0vG$d", + -- }, +} + return M