319 lines
8.0 KiB
Lua
319 lines
8.0 KiB
Lua
-- Rafi's Neovim config loader
|
||
-- https://github.com/rafi/vim-config
|
||
|
||
-- This is part of LazyVim's code, with my modifications.
|
||
-- See: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/init.lua
|
||
|
||
---@type plexConfig
|
||
local M = {}
|
||
|
||
M.lazy_version = '>=9.1.0'
|
||
|
||
---@class plexConfig
|
||
local defaults = {
|
||
-- Load the default settings
|
||
-- stylua: ignore
|
||
defaults = {
|
||
autocmds = true, -- plex.config.autocmds
|
||
keymaps = true, -- plex.config.keymaps
|
||
-- plex.config.options can't be configured here since it's loaded
|
||
-- prematurely. You can disable loading options with the following line at
|
||
-- the top of your lua/config/setup.lua or init.lua:
|
||
-- `package.loaded['plex.config.options'] = true`
|
||
},
|
||
|
||
-- String like `habamax` or a function that will load the colorscheme.
|
||
-- Disabled by default to allow theme-loader.nvim to manage the colorscheme.
|
||
---@type string|fun()
|
||
colorscheme = '',
|
||
|
||
features = {
|
||
elite_mode = true,
|
||
window_q_mapping = true,
|
||
},
|
||
|
||
-- stylua: ignore
|
||
icons = {
|
||
git = ' ',
|
||
diagnostics = {
|
||
Error = '', -- ✘
|
||
Warn = '', --
|
||
Info = '', -- ⁱ
|
||
Hint = '', --
|
||
},
|
||
status = {
|
||
git = {
|
||
added = '₊', -- ₊
|
||
modified = '∗', -- ∗
|
||
removed = '₋', -- ₋
|
||
},
|
||
diagnostics = {
|
||
error = ' ',
|
||
warn = ' ',
|
||
info = ' ',
|
||
hint = ' ',
|
||
},
|
||
filename = {
|
||
modified = '+',
|
||
readonly = '🔒',
|
||
zoomed = '🔎',
|
||
},
|
||
},
|
||
-- Default completion kind symbols.
|
||
kinds = {
|
||
Array = ' ', --
|
||
Boolean = '◩ ', -- ◩
|
||
Class = ' ', -- 𝓒
|
||
Color = ' ', --
|
||
Constant = ' ', --
|
||
Constructor = ' ', --
|
||
Copilot = ' ', --
|
||
Enum = ' ', -- ℰ
|
||
EnumMember = ' ', --
|
||
Event = ' ', --
|
||
Field = ' ', --
|
||
File = ' ', --
|
||
Folder = ' ', --
|
||
Function = ' ', --
|
||
Interface = ' ', --
|
||
Key = ' ', --
|
||
Keyword = ' ', --
|
||
Method = ' ', -- ƒ
|
||
Module = ' ', --
|
||
Namespace = ' ', --
|
||
Null = ' ', --
|
||
Number = ' ', --
|
||
Object = ' ', --
|
||
Operator = ' ', -- +
|
||
Package = ' ', --
|
||
Property = ' ', --
|
||
Reference = ' ', --
|
||
Snippet = ' ', -- ⮡
|
||
String = ' ', --
|
||
Struct = ' ', -- 𝓢
|
||
Text = ' ', -- 𝓐
|
||
TypeParameter = ' ', -- 𝙏
|
||
Unit = ' ', --
|
||
Value = ' ', --
|
||
Variable = ' ', --
|
||
},
|
||
},
|
||
}
|
||
|
||
M.renames = {}
|
||
|
||
M.did_init = false
|
||
function M.init()
|
||
if not M.did_init then
|
||
M.did_init = true
|
||
-- delay notifications till vim.notify was replaced or after 500ms
|
||
require('plex.config').lazy_notify()
|
||
|
||
-- load options here, before lazy init while sourcing plugin modules
|
||
-- this is needed to make sure options will be correctly applied
|
||
-- after installing missing plugins
|
||
require('plex.config').load('options')
|
||
|
||
-- carry over plugin options that their name has been changed.
|
||
local Plugin = require('lazy.core.plugin')
|
||
local add = Plugin.Spec.add
|
||
---@diagnostic disable-next-line: duplicate-set-field
|
||
Plugin.Spec.add = function(self, plugin, ...)
|
||
if type(plugin) == 'table' and M.renames[plugin[1]] then
|
||
plugin[1] = M.renames[plugin[1]]
|
||
end
|
||
return add(self, plugin, ...)
|
||
end
|
||
end
|
||
end
|
||
|
||
---@type plexConfig
|
||
local options
|
||
|
||
-- Load plex and user config files.
|
||
---@param user_opts table|nil
|
||
function M.setup(user_opts)
|
||
if not M.did_init then
|
||
M.init()
|
||
end
|
||
options = vim.tbl_deep_extend('force', defaults, user_opts or {})
|
||
if not M.has_version() then
|
||
require('lazy.core.util').error(
|
||
string.format(
|
||
'**lazy.nvim** version %s is required.\n Please upgrade **lazy.nvim**',
|
||
M.lazy_version
|
||
)
|
||
)
|
||
error('Exiting')
|
||
end
|
||
|
||
-- Override config with user config at lua/config/setup.lua
|
||
local ok, user_setup = pcall(require, 'config.setup')
|
||
if ok and user_setup.override then
|
||
options = vim.tbl_deep_extend('force', options, user_setup.override())
|
||
end
|
||
for feat_name, feat_val in pairs(options.features) do
|
||
vim.g['plex_' .. feat_name] = feat_val
|
||
end
|
||
|
||
M.load('autocmds')
|
||
M.load('keymaps')
|
||
|
||
-- Set colorscheme
|
||
require('lazy.core.util').try(function()
|
||
if type(M.colorscheme) == 'function' then
|
||
M.colorscheme()
|
||
elseif #M.colorscheme > 0 then
|
||
vim.cmd.colorscheme(M.colorscheme)
|
||
end
|
||
end, {
|
||
msg = 'Could not load your colorscheme',
|
||
on_error = function(msg)
|
||
require('lazy.core.util').error(msg)
|
||
vim.cmd.colorscheme('habamax')
|
||
end,
|
||
})
|
||
end
|
||
|
||
---@return table
|
||
function M.user_lazy_opts()
|
||
local ok, user_setup = pcall(require, 'config.setup')
|
||
if ok and user_setup.lazy_opts then
|
||
return user_setup.lazy_opts()
|
||
end
|
||
return {}
|
||
end
|
||
|
||
---@param range? string
|
||
---@return boolean
|
||
function M.has_version(range)
|
||
local Semver = require('lazy.manage.semver')
|
||
return Semver.range(range or M.lazy_version)
|
||
:matches(require('lazy.core.config').version or '0.0.0')
|
||
end
|
||
|
||
---@param name "autocmds" | "options" | "keymaps"
|
||
function M.load(name)
|
||
local Util = require('lazy.core.util')
|
||
local function _load(mod)
|
||
Util.try(function()
|
||
require(mod)
|
||
end, {
|
||
msg = 'Failed loading ' .. mod,
|
||
on_error = function(msg)
|
||
local info = require('lazy.core.cache').find(mod)
|
||
if info == nil or (type(info) == 'table' and #info == 0) then
|
||
return
|
||
end
|
||
Util.error(msg)
|
||
end,
|
||
})
|
||
end
|
||
-- always load plex's file, then user file
|
||
if M.defaults[name] or name == 'options' then
|
||
_load('plex.config.' .. name)
|
||
end
|
||
_load('config.' .. name)
|
||
if vim.bo.filetype == 'lazy' then
|
||
vim.cmd([[do VimResized]])
|
||
end
|
||
end
|
||
|
||
-- Ensure package manager (lazy.nvim) exists.
|
||
function M.ensure_lazy()
|
||
local lazypath = M.path_join(vim.fn.stdpath('data'), 'lazy', 'lazy.nvim')
|
||
if not vim.loop.fs_stat(lazypath) then
|
||
print('Installing lazy.nvim…')
|
||
vim.fn.system({
|
||
'git',
|
||
'clone',
|
||
'--filter=blob:none',
|
||
'--branch=stable',
|
||
'https://github.com/folke/lazy.nvim.git',
|
||
lazypath,
|
||
})
|
||
end
|
||
vim.opt.rtp:prepend(lazypath)
|
||
end
|
||
|
||
-- Validate if lua/plugins/ or lua/plugins.lua exist.
|
||
---@return boolean
|
||
function M.has_user_plugins()
|
||
local user_path = M.path_join(vim.fn.stdpath('config'), 'lua')
|
||
return vim.loop.fs_stat(M.path_join(user_path, 'plugins')) ~= nil
|
||
or vim.loop.fs_stat(M.path_join(user_path, 'plugins.lua')) ~= nil
|
||
end
|
||
|
||
-- Delay notifications till vim.notify was replaced or after 500ms.
|
||
function M.lazy_notify()
|
||
local notifs = {}
|
||
local function temp(...)
|
||
table.insert(notifs, vim.F.pack_len(...))
|
||
end
|
||
|
||
local orig = vim.notify
|
||
vim.notify = temp
|
||
|
||
local timer = vim.loop.new_timer()
|
||
local check = vim.loop.new_check()
|
||
if timer == nil or check == nil then
|
||
return
|
||
end
|
||
|
||
local replay = function()
|
||
timer:stop()
|
||
check:stop()
|
||
if vim.notify == temp then
|
||
vim.notify = orig -- put back the original notify if needed
|
||
end
|
||
vim.schedule(function()
|
||
---@diagnostic disable-next-line: no-unknown
|
||
for _, notif in ipairs(notifs) do
|
||
vim.notify(vim.F.unpack_len(notif))
|
||
end
|
||
end)
|
||
end
|
||
|
||
-- wait till vim.notify has been replaced
|
||
check:start(function()
|
||
if vim.notify ~= temp then
|
||
replay()
|
||
end
|
||
end)
|
||
-- or if it took more than 500ms, then something went wrong
|
||
timer:start(500, 0, replay)
|
||
end
|
||
|
||
-- Join paths.
|
||
---@private
|
||
M.path_join = function(...)
|
||
return table.concat({ ... }, M.path_sep)
|
||
end
|
||
|
||
-- Variable holds OS directory separator.
|
||
---@private
|
||
M.path_sep = (function()
|
||
if jit then
|
||
local os = string.lower(jit.os)
|
||
if os ~= 'windows' then
|
||
return '/'
|
||
else
|
||
return '\\'
|
||
end
|
||
else
|
||
return package.config:sub(1, 1)
|
||
end
|
||
end)()
|
||
|
||
setmetatable(M, {
|
||
__index = function(_, key)
|
||
if options == nil then
|
||
return vim.deepcopy(defaults)[key]
|
||
end
|
||
---@cast options plexConfig
|
||
return options[key]
|
||
end,
|
||
})
|
||
|
||
return M
|