NvChad Updater | Chadrc Fixes | Cleanup and Formatting | Misc (#288)

* tree-wide: Format files

ugh why do people don't push formatted stuff

* mappings|init: Move init mappings to a function, only call when required | Show err message for init

because mappings.lua is called from multiple places, so there should't be any code that executes without calling a specific function

show error message when something fails in init.lua
makes no sense to not

rearrange plugin functions alphabetically, but keep misc at top

* feat: Do not depend on user config | Fix merging of configs

because it is a user config, so our config shoudn't break even we if dont have it

use our own table merge function

move loading config to a function

use a global variable to store the config, so no need to call the table function everytime

* Add NvChadUpdate command and shortcut for it

map leader+uu to it

summary of what it does:

first ask the user for confirmation and tell that the updater is gonna run git reset --hard in config repo and chadrc will be restored

take backup of chadrc in a lua string and locally in a file with chadrc.bak.(random numbers)

git reset on config dir and git pull

whether success or error, restore the chadrc file

if restore fails, then print backup file path

for more deep understanding, read the comments in utils.lua

* NvChadUpdater: Make update repo and url configurable | Improvr logging
This commit is contained in:
Aki 2021-08-19 12:33:11 +05:30 committed by GitHub
parent 623a2a0d1a
commit 36cb57ecce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 389 additions and 197 deletions

View file

@ -4,5 +4,9 @@ local chad_modules = {
} }
for i = 1, #chad_modules, 1 do for i = 1, #chad_modules, 1 do
pcall(require, chad_modules[i]) if not pcall(require, chad_modules[i]) then
error("Error loading " .. chad_modules[i] .. "\n")
end
end end
require("mappings").misc()

View file

@ -37,6 +37,9 @@ M.options = {
mapleader = " ", mapleader = " ",
autosave = false, autosave = false,
enable_insertNav = true, -- navigation in insertmode enable_insertNav = true, -- navigation in insertmode
-- used for updater
update_url = "https://github.com/NvChad/NvChad",
update_branch = "main",
} }
-- enable and disable plugins (false for disable) -- enable and disable plugins (false for disable)
@ -140,9 +143,8 @@ M.mappings = {
copywhole_file = "<C-a>", copywhole_file = "<C-a>",
toggle_linenr = "<leader>n", -- show or hide line number toggle_linenr = "<leader>n", -- show or hide line number
theme_toggle = "<leader>x", theme_toggle = "<leader>x",
update_nvchad = "<leader>uu",
}, },
} }
M = vim.tbl_deep_extend("force", require "default_config", M)
return M return M

View file

@ -37,6 +37,9 @@ M.options = {
mapleader = " ", mapleader = " ",
autosave = false, autosave = false,
enable_insertNav = true, -- navigation in insertmode enable_insertNav = true, -- navigation in insertmode
-- used for updater
update_url = "https://github.com/NvChad/NvChad",
update_branch = "main",
} }
-- enable and disable plugins (false for disable) -- enable and disable plugins (false for disable)
@ -140,6 +143,7 @@ M.mappings = {
copywhole_file = "<C-a>", copywhole_file = "<C-a>",
toggle_linenr = "<leader>n", -- show or hide line number toggle_linenr = "<leader>n", -- show or hide line number
theme_toggle = "<leader>x", theme_toggle = "<leader>x",
update_nvchad = "<leader>uu",
}, },
} }

View file

@ -1,7 +1,6 @@
local user_map = require("chadrc").mappings local user_map = require("utils").load_config().mappings
local miscMap = user_map.misc local miscMap = user_map.misc
local M = {}
local cmd = vim.cmd local cmd = vim.cmd
local function map(mode, lhs, rhs, opts) local function map(mode, lhs, rhs, opts)
@ -12,65 +11,117 @@ local function map(mode, lhs, rhs, opts)
vim.api.nvim_set_keymap(mode, lhs, rhs, options) vim.api.nvim_set_keymap(mode, lhs, rhs, options)
end end
local M = {}
local opt = {} local opt = {}
-- dont copy any deleted text , this is disabled by default so uncomment the below mappings if you want them -- these mappings will only be called during initialization
--[[ remove this line M.misc = function()
-- 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)
-- todo: this should be configurable via chadrc
map("n", "dd", [=[ "_dd ]=], opt) -- Don't copy the replaced text after pasting in visual mode
map("v", "dd", [=[ "_dd ]=], opt) map("v", "p", '"_dP', opt)
map("v", "x", [=[ "_x ]=], opt)
this line too ]] -- Allow moving the cursor through wrapped lines with j, k, <Up> and <Down>
-- -- http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/
-- empty mode is same as using :map
map("", "j", 'v:count ? "j" : "gj"', { expr = true })
map("", "k", 'v:count ? "k" : "gk"', { expr = true })
map("", "<Down>", 'v:count ? "j" : "gj"', { expr = true })
map("", "<Up>", 'v:count ? "k" : "gk"', { expr = true })
-- Don't copy the replaced text after pasting in visual mode -- copy whole file content
map("v", "p", '"_dP', opt) map("n", miscMap.copywhole_file, ":%y+<CR>", opt)
-- Allow moving the cursor through wrapped lines with j, k, <Up> and <Down> -- toggle numbers
-- http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/ map("n", miscMap.toggle_linenr, ":set nu!<CR>", opt)
-- empty mode is same as using :map
map("", "j", 'v:count ? "j" : "gj"', { expr = true })
map("", "k", 'v:count ? "k" : "gk"', { expr = true })
map("", "<Down>", 'v:count ? "j" : "gj"', { expr = true })
map("", "<Up>", 'v:count ? "k" : "gk"', { expr = true })
-- copy whole file content -- terminals
map("n", miscMap.copywhole_file, ":%y+<CR>", opt) local function terms()
local m = user_map.terms
-- toggle numbers -- get out of terminal mode
map("n", miscMap.toggle_linenr, ":set nu!<CR>", opt) map("t", m.esc_termmode, "<C-\\><C-n>", opt)
-- hide a term from within terminal mode
map("t", m.esc_hide_termmode, "<C-\\><C-n> :lua require('utils').close_buffer() <CR>", opt)
-- pick a hidden term
map("n", m.pick_term, ":Telescope terms <CR>", opt)
-- Open terminals
-- TODO this opens on top of an existing vert/hori term, fixme
map("n", m.new_wind, ":execute 'terminal' | let b:term_type = 'wind' | startinsert <CR>", opt)
map("n", m.new_vert, ":execute 'vnew +terminal' | let b:term_type = 'vert' | startinsert <CR>", opt)
map("n", m.new_hori, ":execute 15 .. 'new +terminal' | let b:term_type = 'hori' | startinsert <CR>", opt)
end
terms()
-- terminals -- ctrl + s to save file
local function terms() map("n", "<C-s>", ":w <CR>", opt)
local m = user_map.terms
-- get out of terminal mode -- use ESC to turn off search highlighting
map("t", m.esc_termmode, "<C-\\><C-n>", opt) map("n", "<Esc>", ":noh<CR>", opt)
-- hide a term from within terminal mode
map("t", m.esc_hide_termmode, "<C-\\><C-n> :lua require('utils').close_buffer() <CR>", opt)
-- pick a hidden term
map("n", m.pick_term, ":Telescope terms <CR>", opt)
-- Open terminals -- navigation within insert mode
-- TODO this opens on top of an existing vert/hori term, fixme local check_insertNav = require("utils").load_config().options.enable_insertNav
map("n", m.new_wind, ":execute 'terminal' | let b:term_type = 'wind' | startinsert <CR>", opt)
map("n", m.new_vert, ":execute 'vnew +terminal' | let b:term_type = 'vert' | startinsert <CR>", opt) if check_insertNav == true then
map("n", m.new_hori, ":execute 15 .. 'new +terminal' | let b:term_type = 'hori' | startinsert <CR>", opt) local m = user_map.insert_nav
map("i", m.forward, "<Right>", opt)
map("i", m.backward, "<Left>", opt)
map("i", m.top_of_line, "<ESC>^i", opt)
map("i", m.end_of_line, "<End>", opt)
map("i", m.next_line, "<Up>", opt)
map("i", m.prev_line, "<Down>", opt)
end
-- check the theme toggler
local theme_toggler = require("utils").load_config().ui.theme_toggler
if theme_toggler == true then
local m = user_map.misc.theme_toggle
map("n", m, ":lua require('utils').toggle_theme(require('utils').load_config().ui.fav_themes)<CR>", opt)
end
-- Packer commands till because we are not loading it at startup
cmd "silent! command PackerCompile lua require 'pluginList' require('packer').compile()"
cmd "silent! command PackerInstall lua require 'pluginList' require('packer').install()"
cmd "silent! command PackerStatus lua require 'pluginList' require('packer').status()"
cmd "silent! command PackerSync lua require 'pluginList' require('packer').sync()"
cmd "silent! command PackerUpdate lua require 'pluginList' require('packer').update()"
-- add NvChadUpdate command and mapping
cmd "silent! command! NvChadUpdate lua require('utils').update_nvchad()"
map("n", user_map.misc.update_nvchad, ":NvChadUpdate<CR>", opt)
end end
terms() M.bufferline = function()
local m = user_map.bufferline
M.truezen = function() map("n", m.new_buffer, ":enew<CR>", opt) -- new buffer
local m = user_map.truezen map("n", m.newtab, ":tabnew<CR>", opt) -- new tab
map("n", m.close, ":lua require('utils').close_buffer() <CR>", opt) -- close buffer
map("n", m.ataraxisMode, ":TZAtaraxis<CR>", opt) -- move between tabs
map("n", m.minimalisticmode, ":TZMinimalist<CR>", opt)
map("n", m.focusmode, ":TZFocus<CR>", opt) map("n", m.cycleNext, ":BufferLineCycleNext<CR>", opt)
map("n", m.cyclePrev, ":BufferLineCyclePrev<CR>", opt)
end end
map("n", "<C-s>", ":w <CR>", opt) M.chadsheet = function()
local m = user_map.chadsheet
map("n", m.default_keys, ":lua require('cheatsheet').show_cheatsheet_telescope()<CR>", opt)
map(
"n",
m.user_keys,
":lua require('cheatsheet').show_cheatsheet_telescope{bundled_cheatsheets = false, bundled_plugin_cheatsheets = false }<CR>",
opt
)
end
M.comment_nvim = function() M.comment_nvim = function()
local m = user_map.comment_nvim.comment_toggle local m = user_map.comment_nvim.comment_toggle
@ -78,6 +129,25 @@ M.comment_nvim = function()
map("v", m, ":CommentToggle<CR>", opt) map("v", m, ":CommentToggle<CR>", opt)
end end
M.dashboard = function()
local m = user_map.dashboard
map("n", m.open, ":Dashboard<CR>", opt)
map("n", m.newfile, ":DashboardNewFile<CR>", opt)
map("n", m.bookmarks, ":DashboardJumpMarks<CR>", opt)
map("n", m.sessionload, ":SessionLoad<CR>", opt)
map("n", m.sessionsave, ":SessionSave<CR>", opt)
end
M.fugitive = function()
local m = user_map.fugitive
map("n", m.Git, ":Git<CR>", opt)
map("n", m.diffget_2, ":diffget //2<CR>", opt)
map("n", m.diffget_3, ":diffget //3<CR>", opt)
map("n", m.git_blame, ":Git blame<CR>", opt)
end
M.nvimtree = function() M.nvimtree = function()
local m = user_map.nvimtree.treetoggle local m = user_map.nvimtree.treetoggle
@ -89,14 +159,12 @@ M.neoformat = function()
map("n", m, ":Neoformat<CR>", opt) map("n", m, ":Neoformat<CR>", opt)
end end
M.dashboard = function() M.truezen = function()
local m = user_map.dashboard local m = user_map.truezen
map("n", m.open, ":Dashboard<CR>", opt) map("n", m.ataraxisMode, ":TZAtaraxis<CR>", opt)
map("n", m.newfile, ":DashboardNewFile<CR>", opt) map("n", m.minimalisticmode, ":TZMinimalist<CR>", opt)
map("n", m.bookmarks, ":DashboardJumpMarks<CR>", opt) map("n", m.focusmode, ":TZFocus<CR>", opt)
map("n", m.sessionload, ":SessionLoad<CR>", opt)
map("n", m.sessionsave, ":SessionSave<CR>", opt)
end end
M.telescope = function() M.telescope = function()
@ -117,69 +185,4 @@ M.telescope_media = function()
map("n", m.media_files, ":Telescope media_files <CR>", opt) map("n", m.media_files, ":Telescope media_files <CR>", opt)
end end
M.chadsheet = function()
local m = user_map.chadsheet
map("n", m.default_keys, ":lua require('cheatsheet').show_cheatsheet_telescope()<CR>", opt)
map(
"n",
m.user_keys,
":lua require('cheatsheet').show_cheatsheet_telescope{bundled_cheatsheets = false, bundled_plugin_cheatsheets = false }<CR>",
opt
)
end
M.bufferline = function()
local m = user_map.bufferline
map("n", m.new_buffer, ":enew<CR>", opt) -- new buffer
map("n", m.newtab, ":tabnew<CR>", opt) -- new tab
map("n", m.close, ":lua require('utils').close_buffer() <CR>", opt) -- close buffer
-- move between tabs
map("n", m.cycleNext, ":BufferLineCycleNext<CR>", opt)
map("n", m.cyclePrev, ":BufferLineCyclePrev<CR>", opt)
end
-- use ESC to turn off search highlighting
map("n", "<Esc>", ":noh<CR>", opt)
-- Packer commands till because we are not loading it at startup
cmd "silent! command PackerCompile lua require 'pluginList' require('packer').compile()"
cmd "silent! command PackerInstall lua require 'pluginList' require('packer').install()"
cmd "silent! command PackerStatus lua require 'pluginList' require('packer').status()"
cmd "silent! command PackerSync lua require 'pluginList' require('packer').sync()"
cmd "silent! command PackerUpdate lua require 'pluginList' require('packer').update()"
M.fugitive = function()
local m = user_map.fugitive
map("n", m.Git, ":Git<CR>", opt)
map("n", m.diffget_2, ":diffget //2<CR>", opt)
map("n", m.diffget_3, ":diffget //3<CR>", opt)
map("n", m.git_blame, ":Git blame<CR>", opt)
end
-- navigation within insert mode
local check_insertNav = require("chadrc").options.enable_insertNav
if check_insertNav == true then
local m = user_map.insert_nav
map("i", m.forward, "<Right>", opt)
map("i", m.backward, "<Left>", opt)
map("i", m.top_of_line, "<ESC>^i", opt)
map("i", m.end_of_line, "<End>", opt)
map("i", m.next_line, "<Up>", opt)
map("i", m.prev_line, "<Down>", opt)
end
local theme_toggler = require("chadrc").ui.theme_toggler
if theme_toggler == true then
local m = user_map.misc.theme_toggle
map("n", m, ":lua require('utils').toggle_theme(require('chadrc').ui.fav_themes)<CR>", opt)
end
return M return M

View file

@ -1,7 +1,11 @@
local options = require("chadrc").options
local opt = vim.opt local opt = vim.opt
local g = vim.g local g = vim.g
-- export user config as a global varibale
g.nvchad_user_config = "chadrc"
local options = require("utils").load_config().options
opt.completeopt = { "menuone", "noselect" } opt.completeopt = { "menuone", "noselect" }
opt.undofile = options.permanent_undo opt.undofile = options.permanent_undo
opt.ruler = options.ruler opt.ruler = options.ruler
@ -76,7 +80,7 @@ vim.cmd [[ au TermOpen term://* setlocal nonumber norelativenumber ]]
-- Don't show status line on certain windows -- Don't show status line on certain windows
vim.cmd [[ au TermOpen term://* setfiletype terminal ]] vim.cmd [[ au TermOpen term://* setfiletype terminal ]]
vim.cmd [[ let hidden_statusline = luaeval('require("chadrc").ui.hidden_statusline') | autocmd BufEnter,BufWinEnter,WinEnter,CmdwinEnter,TermEnter * nested if index(hidden_statusline, &ft) >= 0 | set laststatus=0 | else | set laststatus=2 | endif ]] vim.cmd [[ let hidden_statusline = luaeval('require("utils").load_config().ui.hidden_statusline') | autocmd BufEnter,BufWinEnter,WinEnter,CmdwinEnter,TermEnter * nested if index(hidden_statusline, &ft) >= 0 | set laststatus=0 | else | set laststatus=2 | endif ]]
-- Open a file from its last left off position -- Open a file from its last left off position
-- vim.cmd [[ au BufReadPost * if expand('%:p') !~# '\m/\.git/' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif ]] -- vim.cmd [[ au BufReadPost * if expand('%:p') !~# '\m/\.git/' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif ]]

View file

@ -1,4 +1,4 @@
local plugin_status = require("chadrc").plugin_status local plugin_status = require("utils").load_config().plugin_status
local present, _ = pcall(require, "packerInit") local present, _ = pcall(require, "packerInit")
local packer local packer

View file

@ -25,23 +25,23 @@ bufferline.setup {
mappings = true, mappings = true,
always_show_bufferline = true, always_show_bufferline = true,
custom_filter = function(buf_number) custom_filter = function(buf_number)
-- Func to filter out our managed/persistent split terms -- Func to filter out our managed/persistent split terms
local present_type, type = pcall(function() local present_type, type = pcall(function()
return vim.api.nvim_buf_get_var(buf_number, "term_type") return vim.api.nvim_buf_get_var(buf_number, "term_type")
end) end)
if present_type then if present_type then
if type == "vert" then if type == "vert" then
return false return false
elseif type == "hori" then elseif type == "hori" then
return false return false
else else
return true return true
end end
else else
return true return true
end end
end, end,
}, },
highlights = { highlights = {
fill = { fill = {

View file

@ -4,7 +4,7 @@ if not present then
return return
end end
local mappings = require("chadrc").mappings local mappings = require("utils").load_config().mappings
-- add user mappings to the cheetsheet -- add user mappings to the cheetsheet
for section, data in pairs(mappings) do for section, data in pairs(mappings) do

View file

@ -38,8 +38,8 @@ telescope.setup {
file_ignore_patterns = {}, file_ignore_patterns = {},
generic_sorter = require("telescope.sorters").get_generic_fuzzy_sorter, generic_sorter = require("telescope.sorters").get_generic_fuzzy_sorter,
path_display = function(opts, path) path_display = function(opts, path)
local tail = require("telescope.utils").path_tail(path) local tail = require("telescope.utils").path_tail(path)
return string.format("%s (%s)", tail, path) return string.format("%s (%s)", tail, path)
end, end,
winblend = 0, winblend = 0,
border = {}, border = {},

View file

@ -38,7 +38,6 @@ M.term_picker = function(opts)
return false return false
end end
-- if 1 ~= vim.fn.buflisted(b) then -- if 1 ~= vim.fn.buflisted(b) then
-- return false -- return false
-- end -- end
@ -105,22 +104,22 @@ M.term_picker = function(opts)
local buf = entry.bufnr local buf = entry.bufnr
local chad_term, type = pcall(function() local chad_term, type = pcall(function()
return vim.api.nvim_buf_get_var(buf, "term_type") return vim.api.nvim_buf_get_var(buf, "term_type")
end) end)
-- TODO buffer checks/error detection (make sure we do get a buf) -- TODO buffer checks/error detection (make sure we do get a buf)
if chad_term then if chad_term then
if type == "wind" then if type == "wind" then
-- swtich to term buff & show in bufferline -- swtich to term buff & show in bufferline
vim.cmd(string.format('b %d | setlocal bl', buf)) vim.cmd(string.format("b %d | setlocal bl", buf))
-- vim.cmd('startinsert') TODO fix this -- vim.cmd('startinsert') TODO fix this
elseif type == "vert" then elseif type == "vert" then
vim.cmd(string.format('vsp #%d', buf)) vim.cmd(string.format("vsp #%d", buf))
-- vim.cmd('startinsert') TODO fix this -- vim.cmd('startinsert') TODO fix this
elseif type == "hori" then elseif type == "hori" then
-- TODO change 15 to a chad config var number -- TODO change 15 to a chad config var number
vim.cmd(string.format('15 sp #%d ', buf)) vim.cmd(string.format("15 sp #%d ", buf))
-- vim.cmd('startinsert') TODO fix this -- vim.cmd('startinsert') TODO fix this
end end
end end

View file

@ -1,4 +1,4 @@
local chad_theme = require("chadrc").ui.theme local chad_theme = require("utils").load_config().ui.theme
vim.g.nvchad_theme = chad_theme vim.g.nvchad_theme = chad_theme
local present, base16 = pcall(require, "base16") local present, base16 = pcall(require, "base16")

View file

@ -10,7 +10,8 @@ M.change_theme = function(current_theme, new_theme)
return return
end end
local file = vim.fn.stdpath "config" .. "/lua/chadrc.lua" local user_config = vim.g.nvchad_user_config
local file = vim.fn.stdpath "config" .. "/lua/" .. user_config .. ".lua"
-- store in data variable -- store in data variable
local data = assert(M.file("r", file)) local data = assert(M.file("r", file))
-- escape characters which can be parsed as magic chars -- escape characters which can be parsed as magic chars
@ -42,8 +43,8 @@ M.close_buffer = function(bufexpr, force)
-- Options -- Options
local opts = { local opts = {
next = 'cycle', -- how to retrieve the next buffer next = "cycle", -- how to retrieve the next buffer
quit = false, -- exit when last buffer is deleted quit = false, -- exit when last buffer is deleted
--TODO make this a chadrc flag/option --TODO make this a chadrc flag/option
} }
@ -55,20 +56,20 @@ M.close_buffer = function(bufexpr, force)
local function switch_buffer(windows, buf) local function switch_buffer(windows, buf)
local cur_win = vim.fn.winnr() local cur_win = vim.fn.winnr()
for _, winid in ipairs(windows) do for _, winid in ipairs(windows) do
vim.cmd(string.format('%d wincmd w', vim.fn.win_id2win(winid))) vim.cmd(string.format("%d wincmd w", vim.fn.win_id2win(winid)))
vim.cmd(string.format('buffer %d', buf)) vim.cmd(string.format("buffer %d", buf))
end end
vim.cmd(string.format('%d wincmd w', cur_win)) -- return to original window vim.cmd(string.format("%d wincmd w", cur_win)) -- return to original window
end end
-- Select the first buffer with a number greater than given buffer -- Select the first buffer with a number greater than given buffer
local function get_next_buf(buf) local function get_next_buf(buf)
local next = vim.fn.bufnr('#') local next = vim.fn.bufnr "#"
if opts.next == 'alternate' and vim.fn.buflisted(next) == 1 then if opts.next == "alternate" and vim.fn.buflisted(next) == 1 then
return next return next
end end
for i = 0, vim.fn.bufnr('$') - 1 do for i = 0, vim.fn.bufnr "$" - 1 do
next = (buf + i) % vim.fn.bufnr('$') + 1 -- will loop back to 1 next = (buf + i) % vim.fn.bufnr "$" + 1 -- will loop back to 1
if vim.fn.buflisted(next) == 1 then if vim.fn.buflisted(next) == 1 then
return next return next
end end
@ -80,66 +81,66 @@ M.close_buffer = function(bufexpr, force)
-- ---------------- -- ----------------
local buf = vim.fn.bufnr() local buf = vim.fn.bufnr()
if vim.fn.buflisted(buf) == 0 then -- exit if buffer number is invalid if vim.fn.buflisted(buf) == 0 then -- exit if buffer number is invalid
return return
end end
if #vim.fn.getbufinfo({buflisted = 1}) < 2 then if #vim.fn.getbufinfo { buflisted = 1 } < 2 then
if opts.quit then if opts.quit then
-- exit when there is only one buffer left -- exit when there is only one buffer left
if force then if force then
vim.cmd('qall!') vim.cmd "qall!"
else else
vim.cmd('confirm qall') vim.cmd "confirm qall"
end end
return return
end end
local chad_term, type = pcall(function() local chad_term, type = pcall(function()
return vim.api.nvim_buf_get_var(buf, "term_type") return vim.api.nvim_buf_get_var(buf, "term_type")
end) end)
if chad_term then if chad_term then
-- Must be a window type -- Must be a window type
vim.cmd(string.format('setlocal nobl', buf)) vim.cmd(string.format("setlocal nobl", buf))
vim.cmd('enew') vim.cmd "enew"
return return
end end
-- don't exit and create a new empty buffer -- don't exit and create a new empty buffer
vim.cmd('enew') vim.cmd "enew"
vim.cmd('bp') vim.cmd "bp"
end end
local next_buf = get_next_buf(buf) local next_buf = get_next_buf(buf)
local windows = vim.fn.getbufinfo(buf)[1].windows local windows = vim.fn.getbufinfo(buf)[1].windows
-- force deletion of terminal buffers to avoid the prompt -- force deletion of terminal buffers to avoid the prompt
if force or vim.fn.getbufvar(buf, '&buftype') == 'terminal' then if force or vim.fn.getbufvar(buf, "&buftype") == "terminal" then
local chad_term, type = pcall(function() local chad_term, type = pcall(function()
return vim.api.nvim_buf_get_var(buf, "term_type") return vim.api.nvim_buf_get_var(buf, "term_type")
end) end)
-- TODO this scope is error prone, make resilient -- TODO this scope is error prone, make resilient
if chad_term then if chad_term then
if type == "wind" then if type == "wind" then
-- hide from bufferline -- hide from bufferline
vim.cmd(string.format('%d bufdo setlocal nobl', buf)) vim.cmd(string.format("%d bufdo setlocal nobl", buf))
-- swtich to another buff -- swtich to another buff
-- TODO switch to next bufffer, this works too -- TODO switch to next bufffer, this works too
vim.cmd('BufferLineCycleNext') vim.cmd "BufferLineCycleNext"
else else
local cur_win = vim.fn.winnr() local cur_win = vim.fn.winnr()
-- we can close this window -- we can close this window
vim.cmd(string.format('%d wincmd c', cur_win)) vim.cmd(string.format("%d wincmd c", cur_win))
return return
end end
else else
switch_buffer(windows, next_buf) switch_buffer(windows, next_buf)
vim.cmd(string.format('bd! %d', buf)) vim.cmd(string.format("bd! %d", buf))
end end
else else
switch_buffer(windows, next_buf) switch_buffer(windows, next_buf)
vim.cmd(string.format('silent! confirm bd %d', buf)) vim.cmd(string.format("silent! confirm bd %d", buf))
end end
-- revert buffer switches if user has canceled deletion -- revert buffer switches if user has canceled deletion
if vim.fn.buflisted(buf) == 1 then if vim.fn.buflisted(buf) == 1 then
@ -147,6 +148,16 @@ M.close_buffer = function(bufexpr, force)
end end
end end
-- wrapper to use vim.api.nvim_echo
-- table of {string, highlight}
-- e.g echo({{"Hello", "Title"}, {"World"}})
M.echo = function(opts)
if opts == nil or type(opts) ~= "table" then
return
end
vim.api.nvim_echo(opts, false, {})
end
-- 1st arg - r or w -- 1st arg - r or w
-- 2nd arg - file path -- 2nd arg - file path
-- 3rd arg - content if 1st arg is w -- 3rd arg - content if 1st arg is w
@ -195,6 +206,89 @@ M.list_themes = function(return_type)
return themes return themes
end 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, 2nd arg - table to merge
M.merge_table = function(into, from)
-- make sure both are table
if type(into) ~= "table" or type(from) ~= "table" then
return 1
end
local stack, seen = {}, {}
local table1, table2 = into, from
while true do
for k, v in pairs(table2) do
if type(v) == "table" and type(table1[k]) == "table" then
table.insert(stack, { table1[k], table2[k] })
else
local present = seen[v] or false
if not present then
-- add the value to seen table until value is found
for _, value in pairs(table1) do
seen[value] = true
if value == v then
present = true
break
end
end
end
seen[v] = true
if not present then
-- if type is number, then it is a sub table value, so append
if type(k) == "number" then
table1[#table1 + 1] = v
else
table1[k] = v
end
end
end
end
if #stack > 0 then
local t = stack[#stack]
table1, table2 = t[1], t[2]
stack[#stack] = nil
else
break
end
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
-- 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
local config_name = vim.g.nvchad_user_config or "chadrc"
local config_file = vim.fn.stdpath "config" .. "/lua/" .. config_name .. ".lua"
-- 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("utils").merge_table(_G._NVCHAD_CONFIG_CONTENTS, config)
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
-- reload a plugin ( will try to load even if not loaded) -- reload a plugin ( will try to load even if not loaded)
-- can take a string or list ( table ) -- can take a string or list ( table )
-- return true or false -- return true or false
@ -315,4 +409,86 @@ M.toggle_theme = function(themes)
end end
end end
-- update nvchad
M.update_nvchad = function()
-- in all the comments below, config means user config
local config_path = vim.fn.stdpath "config"
local config_name = vim.g.nvchad_user_config or "chadrc"
local config_file = config_path .. "/lua/" .. config_name .. ".lua"
-- generate a random file name
local config_file_backup = config_path .. "/" .. config_name .. ".lua.bak." .. math.random()
local utils = require "utils"
local echo = utils.echo
local current_config = utils.load_config()
local update_url = current_config.options.update_url or "https://github.com/NvChad/NvChad"
local update_branch = current_config.options.update_branch or "main"
-- ask the user for confirmation to update because we are going to run git reset --hard
echo { { "Url: ", "Title" }, { update_url } }
echo { { "Branch: ", "Title" }, { update_branch } }
echo {
{ "\nUpdater will run", "WarningMsg" },
{ " git reset --hard " },
{
"in config folder, so changes to existing repo files except ",
"WarningMsg",
},
{ config_name },
{ " will be lost!\n\nUpdate NvChad ? [y/N]", "WarningMsg" },
}
local ans = string.lower(vim.fn.input "-> ") == "y"
utils.clear_cmdline()
if not ans then
echo { { "Update cancelled!", "Title" } }
return
end
-- first try to fetch contents of config, this will make sure it is readable and taking backup of its contents
local config_contents = utils.file("r", config_file)
-- also make a local backup in ~/.config/nvim, will be removed when config is succesfully restored
utils.file("w", config_file_backup, config_contents)
-- write original config file with its contents, will make sure charc is writable, this maybe overkill but a little precaution always helps
utils.file("w", config_file, config_contents)
-- function that will executed when git commands are done
local function update_exit(_, code)
-- restore config file irrespective of whether git commands were succesfull or not
if pcall(function()
utils.file("w", config_file, config_contents)
end) then
-- config restored succesfully, remove backup file that was created
if not pcall(os.remove, config_file_backup) then
echo { { "Warning: Failed to remove backup chadrc, remove manually.", "WarningMsg" } }
echo { { "Path: ", "WarningMsg" }, { config_file_backup } }
end
else
echo { { "Error: Restoring " .. config_name .. " failed.\n", "ErrorMsg" } }
echo { { "Backed up " .. config_name .. " path: " .. config_file_backup .. "\n\n", "None" } }
end
-- close the terminal buffer only if update was success, as in case of error, we need the error message
if code == 0 then
vim.cmd "bd!"
echo { { "NvChad succesfully updated.\n", "String" } }
else
echo { { "Error: NvChad Update failed.\n", "ErrorMsg" } }
end
end
-- git commands that will executed, reset in case config was modfied
-- use --ff-only to not mess up if the local repo is outdated
local update_script = [[git reset --hard && git pull --set-upstream https://github.com/NvChad/NvChad main --ff-only]]
-- open a new buffer
vim.cmd "new"
-- finally open the pseudo terminal buffer
vim.fn.termopen(update_script, {
-- change dir to config path so we don't need to move in script
cwd = config_path,
on_exit = update_exit,
})
end
return M return M