diff options
| author | kylo252 <[email protected]> | 2022-10-17 17:29:15 +0200 | 
|---|---|---|
| committer | kylo252 <[email protected]> | 2022-10-17 17:29:15 +0200 | 
| commit | 4ef07315003f723bb8e97d5a91b2bde3773ec1b8 (patch) | |
| tree | e9889a492f76e3f9573228343aaba647dfd48136 /lua | |
| parent | e4a5fe97abe500bbbe78fb137d57a59f558da05a (diff) | |
| parent | 6f6cbc394d2a7e64964b6067a2f42d2e6a07824e (diff) | |
Merge remote-tracking branch 'origin/rolling'
Diffstat (limited to 'lua')
49 files changed, 2077 insertions, 811 deletions
| diff --git a/lua/lvim/bootstrap.lua b/lua/lvim/bootstrap.lua index f637c144..5d980498 100644 --- a/lua/lvim/bootstrap.lua +++ b/lua/lvim/bootstrap.lua @@ -1,7 +1,7 @@  local M = {} -if vim.fn.has "nvim-0.7" ~= 1 then -  vim.notify("Please upgrade your Neovim base installation. Lunarvim requires v0.7+", vim.log.levels.WARN) +if vim.fn.has "nvim-0.8" ~= 1 then +  vim.notify("Please upgrade your Neovim base installation. Lunarvim requires v0.8+", vim.log.levels.WARN)    vim.wait(5000, function()      return false    end) @@ -19,15 +19,9 @@ function _G.join_paths(...)    return result  end ----Require a module in protected mode without relying on its cached value ----@param module string ----@return any -function _G.require_clean(module) -  package.loaded[module] = nil -  _G[module] = nil -  local _, requested = pcall(require, module) -  return requested -end +_G.require_clean = require("lvim.utils.modules").require_clean +_G.require_safe = require("lvim.utils.modules").require_safe +_G.reload = require("lvim.utils.modules").reload  ---Get the full path to `$LUNARVIM_RUNTIME_DIR`  ---@return string @@ -70,7 +64,7 @@ function M:init(base_dir)    self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim")    self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua") -  ---@meta overridden to use LUNARVIM_CACHE_DIR instead, since a lot of plugins call this function interally +  ---@meta overridden to use LUNARVIM_CACHE_DIR instead, since a lot of plugins call this function internally    ---NOTE: changes to "data" are currently unstable, see #2507    vim.fn.stdpath = function(what)      if what == "cache" then @@ -90,6 +84,7 @@ function M:init(base_dir)      vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site"))      vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site", "after"))      vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site")) +    vim.opt.rtp:append(join_paths(self.runtime_dir, "lvim", "after"))      vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after"))      vim.opt.rtp:remove(vim.call("stdpath", "config")) @@ -120,10 +115,10 @@ end  ---Update LunarVim  ---pulls the latest changes from github and, resets the startup cache  function M:update() -  require_clean("lvim.utils.hooks").run_pre_update() -  local ret = require_clean("lvim.utils.git").update_base_lvim() +  reload("lvim.utils.hooks").run_pre_update() +  local ret = reload("lvim.utils.git").update_base_lvim()    if ret then -    require_clean("lvim.utils.hooks").run_post_update() +    reload("lvim.utils.hooks").run_post_update()    end  end diff --git a/lua/lvim/config/defaults.lua b/lua/lvim/config/defaults.lua index 7546644f..1bd57b94 100644 --- a/lua/lvim/config/defaults.lua +++ b/lua/lvim/config/defaults.lua @@ -1,6 +1,7 @@  return {    leader = "space", -  colorscheme = "onedarker", +  reload_config_on_save = true, +  colorscheme = "tokyonight",    transparent_window = false,    format_on_save = {      ---@usage pattern string pattern used for the autocommand (Default: '*') @@ -13,6 +14,7 @@ return {    keys = {},    use_icons = true, +  icons = require "lvim.icons",    builtin = {}, diff --git a/lua/lvim/config/init.lua b/lua/lvim/config/init.lua index c6765f56..59722673 100644 --- a/lua/lvim/config/init.lua +++ b/lua/lvim/config/init.lua @@ -111,45 +111,56 @@ end  --- Override the configuration with a user provided one  -- @param config_path The path to the configuration overrides  function M:load(config_path) -  local autocmds = require "lvim.core.autocmds" +  local autocmds = reload "lvim.core.autocmds"    config_path = config_path or self:get_user_config_path()    local ok, err = pcall(dofile, config_path)    if not ok then      if utils.is_file(user_config_file) then        Log:warn("Invalid configuration: " .. err)      else -      vim.notify_once(string.format("Unable to find configuration file [%s]", config_path), vim.log.levels.WARN) +      vim.notify_once( +        string.format("User-configuration not found. Creating an example configuration in %s", config_path) +      ) +      local example_config = join_paths(get_lvim_base_dir(), "utils", "installer", "config.example.lua") +      vim.loop.fs_copyfile(example_config, config_path)      end    end +  Log:set_level(lvim.log.level) +    handle_deprecated_settings()    autocmds.define_autocmds(lvim.autocommands)    vim.g.mapleader = (lvim.leader == "space" and " ") or lvim.leader -  require("lvim.keymappings").load(lvim.keys) +  reload("lvim.keymappings").load(lvim.keys)    if lvim.transparent_window then      autocmds.enable_transparent_mode()    end + +  if lvim.reload_config_on_save then +    autocmds.enable_reload_config_on_save() +  end  end  --- Override the configuration with a user provided one  -- @param config_path The path to the configuration overrides  function M:reload()    vim.schedule(function() -    require_clean("lvim.utils.hooks").run_pre_reload() +    reload("lvim.utils.hooks").run_pre_reload()      M:load() -    require("lvim.core.autocmds").configure_format_on_save() +    reload("lvim.core.autocmds").configure_format_on_save() -    local plugins = require "lvim.plugins" -    local plugin_loader = require "lvim.plugin-loader" +    local plugins = reload "lvim.plugins" +    local plugin_loader = reload "lvim.plugin-loader"      plugin_loader.reload { plugins, lvim.plugins } -    require_clean("lvim.utils.hooks").run_post_reload() +    reload("lvim.core.theme").setup() +    reload("lvim.utils.hooks").run_post_reload()    end)  end diff --git a/lua/lvim/config/settings.lua b/lua/lvim/config/settings.lua index faa28641..4f61ed09 100644 --- a/lua/lvim/config/settings.lua +++ b/lua/lvim/config/settings.lua @@ -13,8 +13,7 @@ M.load_default_options = function()    local default_options = {      backup = false, -- creates a backup file      clipboard = "unnamedplus", -- allows neovim to access the system clipboard -    cmdheight = 2, -- more space in the neovim command line for displaying messages -    colorcolumn = "99999", -- fixes indentline for now +    cmdheight = 1, -- more space in the neovim command line for displaying messages      completeopt = { "menuone", "noselect" },      conceallevel = 0, -- so that `` is visible in markdown files      fileencoding = "utf-8", -- the encoding written to a file @@ -34,28 +33,31 @@ M.load_default_options = function()      splitright = true, -- force all vertical splits to go to the right of current window      swapfile = false, -- creates a swapfile      termguicolors = true, -- set term gui colors (most terminals support this) -    timeoutlen = 250, -- time to wait for a mapped sequence to complete (in milliseconds) +    timeoutlen = 1000, -- time to wait for a mapped sequence to complete (in milliseconds)      title = true, -- set the title of window to the value of the titlestring      -- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to      undodir = undodir, -- set an undo directory      undofile = true, -- enable persistent undo -    updatetime = 300, -- faster completion +    updatetime = 100, -- faster completion      writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited      expandtab = true, -- convert tabs to spaces      shiftwidth = 2, -- the number of spaces inserted for each indentation      tabstop = 2, -- insert 2 spaces for a tab      cursorline = true, -- highlight the current line      number = true, -- set numbered lines -    relativenumber = false, -- set relative numbered lines      numberwidth = 4, -- set number column width to 2 {default 4}      signcolumn = "yes", -- always show the sign column, otherwise it would shift the text each time      wrap = false, -- display lines as one long line      shadafile = join_paths(get_cache_dir(), "lvim.shada"),      scrolloff = 8, -- minimal number of screen lines to keep above and below the cursor.      sidescrolloff = 8, -- minimal number of screen lines to keep left and right of the cursor. +    showcmd = false, +    ruler = false, +    laststatus = 3,    }    ---  SETTINGS  --- +  vim.opt.spelllang:append "cjk" -- disable spellchecking for asian characters (VIM algorithm does not support it)    vim.opt.shortmess:append "c" -- don't show redundant messages from ins-completion-menu    vim.opt.shortmess:append "I" -- don't show the default intro message    vim.opt.whichwrap:append "<,>,[,],h,l" diff --git a/lua/lvim/core/alpha.lua b/lua/lvim/core/alpha.lua index fd637818..58b787ed 100644 --- a/lua/lvim/core/alpha.lua +++ b/lua/lvim/core/alpha.lua @@ -65,7 +65,10 @@ local function configure_additional_autocmds()  end  function M.setup() -  local alpha = require "alpha" +  local status_ok, alpha = pcall(require, "alpha") +  if not status_ok then +    return +  end    local mode = lvim.builtin.alpha.mode    local config = lvim.builtin.alpha[mode].config diff --git a/lua/lvim/core/alpha/dashboard.lua b/lua/lvim/core/alpha/dashboard.lua index d65980fb..5e73206f 100644 --- a/lua/lvim/core/alpha/dashboard.lua +++ b/lua/lvim/core/alpha/dashboard.lua @@ -1,32 +1,86 @@  local M = {} +local banner = { +  "                ⢀⣀⣤⣤⣤⣶⣶⣶⣶⣶⣶⣤⣤⣤⣀⡀                ", +  "             ⣀⣤⣶⣿⠿⠟⠛⠉⠉⠉⠁⠈⠉⠉⠉⠛⠛⠿⣿⣷⣦⣀             ", +  "          ⢀⣤⣾⡿⠛⠉                ⠉⠛⢿⣷⣤⡀          ", +  "         ⣴⣿⡿⠃                      ⠙⠻⣿⣦         ", +  " ⢀⣠⣤⣤⣤⣤⣤⣾⣿⣉⣀⡀                        ⠙⢻⣷⡄       ", +  "⣼⠋⠁   ⢠⣿⡟ ⠉⠉⠉⠛⠛⠶⠶⣤⣄⣀    ⣀⣀      ⢠⣤⣤⡄   ⢻⣿⣆      ", +  "⢻⡄   ⢰⣿⡟        ⢠⣿⣿⣿⠉⠛⠲⣾⣿⣿⣷    ⢀⣾⣿⣿⠁    ⢻⣿⡆     ", +  " ⠹⣦⡀ ⣿⣿⠁        ⢸⣿⣿⡇   ⠻⣿⣿⠟⠳⠶⣤⣀⣸⣿⣿⠇      ⣿⣷     ", +  "   ⠙⢷⣿⡇         ⣸⣿⣿⠃          ⢸⣿⣿⢷⣤⡀     ⢸⣿⡆    ", +  "    ⢸⣿⠇         ⣿⣿⣿     ⣿⣿⣷  ⢠⣿⣿⡏ ⠈⠙⠳⢦⣄  ⠈⣿⡇    ", +  "    ⢸⣿⡆        ⢸⣿⣿⡇     ⣿⣿⣿ ⢀⣿⣿⡟      ⠈⠙⠷⣤⣿⡇    ", +  "    ⠘⣿⡇        ⣼⣿⣿⠁     ⣿⣿⣿ ⣼⣿⣿⠃         ⢸⣿⠷⣄⡀  ", +  "     ⣿⣿        ⣿⣿⡿      ⣿⣿⣿⢸⣿⣿⠃          ⣾⡿ ⠈⠻⣆ ", +  "     ⠸⣿⣧      ⢸⣿⣿⣇⣀⣀⣀⣀⣀⣀⣸⣿⣿⣿⣿⠇          ⣼⣿⠇   ⠘⣧", +  "      ⠹⣿⣧     ⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏          ⣼⣿⠏    ⣠⡿", +  "       ⠘⢿⣷⣄   ⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉         ⢠⣼⡿⠛⠛⠛⠛⠛⠛⠉ ", +  "         ⠻⣿⣦⣄                      ⣀⣴⣿⠟         ", +  "          ⠈⠛⢿⣶⣤⣀                ⣀⣤⣶⡿⠛⠁          ", +  "             ⠉⠻⢿⣿⣶⣤⣤⣀⣀⡀  ⢀⣀⣀⣠⣤⣶⣿⡿⠟⠋             ", +  "                ⠈⠉⠙⠛⠻⠿⠿⠿⠿⠿⠿⠟⠛⠋⠉⠁                ", +} + +M.banner_alt_1 = { +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣶⣶⣶⣶⣶⣶⣶⣦⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣾⣿⠿⠛⠛⠉⠉⠉⠉⠉⠉⠉⠙⠛⠻⢿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠈⠉⠉⠉⠉⠉⣹⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⣰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⢰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⡀⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢺⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠉⠑⠢⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡇⠀⠀⠀⠈⠑⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠉⠐⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⡟⠀⠈⠑⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠒⠠⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⠁⠀⠀⢀⣼⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠁⠒⠂⠤⠤⠀⣀⡀⠀⠀⠀⣼⣿⠇⠀⠀⢀⣸⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠀⣿⡟⠀⠀⠀⠀⠀⠀⣤⡄⠀⠀⠀⣠⣤⠀⠀⢠⣭⣀⣤⣤⣤⡀⠀⠀⠀⢀⣤⣤⣤⣤⡀⠀⠀⠀⢠⣤⢀⣤⣤⣄⠀⠀⣿⣿⠀⠉⣹⣿⠏⠉⠉⢱⣶⣶⣶⡦⠀⠀⠀⢠⣶⣦⣴⣦⣠⣴⣦⡀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⢠⣿⠇⠀⠀⠀⣿⡇⠀⠀⣿⡿⠉⠀⠈⣿⣧⠀⠀⠰⠿⠋⠀⠀⢹⣿⠀⠀⠀⣿⡿⠋⠀⠹⠿⠀⠀⢻⣿⡇⢠⣿⡟⠀⠀⠀⠈⠉⢹⣿⡇⠀⠀⠀⢸⣿⡏⢹⣿⡏⢹⣿⡇⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⢰⣿⠃⠀⢠⣿⡇⠀⠀⠀⣿⡇⠀⠀⣠⣴⡶⠶⠶⣿⣿⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⣇⣿⡿⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⠀⣿⣿⠀⣾⣿⠀⣾⣿⠁⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⣿⣟⠀⠀⠀⠀⠀⠀⢻⣿⡀⠀⢀⣼⣿⠀⠀⢸⣿⠀⠀⠀⢰⣿⠇⠀⢰⣿⣇⠀⠀⣠⣿⡏⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠁⠀⠀⠀⣀⣀⣠⣿⣿⣀⡀⠀⢠⣿⡟⢠⣿⡟⢀⣿⡿⠀⠀⠀⠀⠀", +  "⠀⠀⠀⠀⠀⠛⠛⠛⠛⠛⠛⠁⠀⠈⠛⠿⠟⠋⠛⠃⠀⠀⠛⠛⠀⠀⠀⠘⠛⠀⠀⠀⠙⠿⠿⠛⠙⠛⠃⠀⠀⠚⠛⠀⠀⠀⠀⠀⠀⠀⠘⠿⠿⠃⠀⠀⠀⠀⠿⠿⠿⠿⠿⠿⠿⠀⠸⠿⠇⠸⠿⠇⠸⠿⠇⠀⠀⠀⠀⠀", +  "                                                                                ", +} + +M.banner_alt_2 = { +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠟⠛⠛⠉⠉⠉⠉⠉⠉⠛⠛⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠉⠀⣀⣤⣴⣶⣶⣾⣿⣿⣷⣶⣶⣦⣤⣀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⠿⠟⠛⠛⠛⠛⠛⠁⠀⠾⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⠁⣴⣾⣿⣿⣿⡟⠀⣰⣿⣶⣶⣶⣤⣤⣉⣉⠛⠛⠿⠿⣿⣿⡿⠿⠿⣿⣿⣿⣿⣿⣿⡟⠛⠛⢛⣿⣿⣿⣆⠀⢻⣿⣿⣿⣿⣿⣿⣿", +  "⣿⡄⠻⣿⣿⣿⡟⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⣦⣤⡈⠀⠀⠀⠈⣿⣿⣿⣿⡿⠁⠀⠀⣾⣿⣿⣿⣿⡄⠀⢻⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣄⠙⠿⣿⠁⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣄⠀⠀⣠⣄⣉⠛⠻⠃⠀⠀⣼⣿⣿⣿⣿⣿⣿⡀⠈⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣷⣦⡈⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠆⠀⠀⡀⠛⠿⣿⣿⣿⣿⣿⡇⠀⢻⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⡇⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⢀⣿⣿⣿⣿⡇⠀⠀⠘⣿⣿⡟⠀⠀⢰⣿⣷⣦⣌⡙⠻⢿⣿⣷⠀⢸⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⡇⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⠀⠀⠀⣿⡿⠀⠀⢀⣿⣿⣿⣿⣿⣿⣷⣤⣈⠛⠀⢸⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣧⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⣾⣿⣿⣿⣿⣿⠀⠀⠀⣿⠁⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⡈⠻⢿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⡀⠈⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⢀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠃⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⢀⣿⣶⣄⠙⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣧⠀⠘⣿⣿⣿⣿⣿⣿⡇⠀⠀⠸⠿⠿⠿⠿⠿⠿⠇⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣼⣿⣿⣿⣦⠘⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣧⠀⠹⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣼⣿⣿⣿⡿⠟⢀⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠈⢿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⢀⣤⣤⣤⣤⣤⣴⣶⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣀⠀⠉⠛⠻⠿⠿⢿⣿⣿⡿⠿⠿⠟⠛⠉⠀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣤⣤⣀⣀⣀⣀⣀⣀⣤⣤⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +  "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿", +} + +if vim.o.lines < 36 then +  banner = vim.list_slice(banner, 16, 22) +end +  function M.get_sections()    local header = {      type = "text", -    val = { -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣶⣶⣶⣶⣶⣶⣶⣦⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣾⣿⠿⠛⠛⠉⠉⠉⠉⠉⠉⠉⠙⠛⠻⢿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠈⠉⠉⠉⠉⠉⣹⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⣰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⢰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⡀⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢺⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠉⠑⠢⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡇⠀⠀⠀⠈⠑⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠉⠐⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⡟⠀⠈⠑⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠒⠠⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⠁⠀⠀⢀⣼⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠁⠒⠂⠤⠤⠀⣀⡀⠀⠀⠀⣼⣿⠇⠀⠀⢀⣸⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠀⣿⡟⠀⠀⠀⠀⠀⠀⣤⡄⠀⠀⠀⣠⣤⠀⠀⢠⣭⣀⣤⣤⣤⡀⠀⠀⠀⢀⣤⣤⣤⣤⡀⠀⠀⠀⢠⣤⢀⣤⣤⣄⠀⠀⣿⣿⠀⠉⣹⣿⠏⠉⠉⢱⣶⣶⣶⡦⠀⠀⠀⢠⣶⣦⣴⣦⣠⣴⣦⡀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⢠⣿⠇⠀⠀⠀⣿⡇⠀⠀⣿⡿⠉⠀⠈⣿⣧⠀⠀⠰⠿⠋⠀⠀⢹⣿⠀⠀⠀⣿⡿⠋⠀⠹⠿⠀⠀⢻⣿⡇⢠⣿⡟⠀⠀⠀⠈⠉⢹⣿⡇⠀⠀⠀⢸⣿⡏⢹⣿⡏⢹⣿⡇⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⢰⣿⠃⠀⢠⣿⡇⠀⠀⠀⣿⡇⠀⠀⣠⣴⡶⠶⠶⣿⣿⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⣇⣿⡿⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⠀⣿⣿⠀⣾⣿⠀⣾⣿⠁⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⣿⣟⠀⠀⠀⠀⠀⠀⢻⣿⡀⠀⢀⣼⣿⠀⠀⢸⣿⠀⠀⠀⢰⣿⠇⠀⢰⣿⣇⠀⠀⣠⣿⡏⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠁⠀⠀⠀⣀⣀⣠⣿⣿⣀⡀⠀⢠⣿⡟⢠⣿⡟⢀⣿⡿⠀⠀⠀⠀⠀", -      "⠀⠀⠀⠀⠀⠛⠛⠛⠛⠛⠛⠁⠀⠈⠛⠿⠟⠋⠛⠃⠀⠀⠛⠛⠀⠀⠀⠘⠛⠀⠀⠀⠙⠿⠿⠛⠙⠛⠃⠀⠀⠚⠛⠀⠀⠀⠀⠀⠀⠀⠘⠿⠿⠃⠀⠀⠀⠀⠿⠿⠿⠿⠿⠿⠿⠀⠸⠿⠇⠸⠿⠇⠸⠿⠇⠀⠀⠀⠀⠀", -      "                                                                                ", -    }, +    val = banner,      opts = {        position = "center",        hl = "Label", @@ -48,21 +102,30 @@ function M.get_sections()        hl = "Number",      },    } +  local buttons = {} -  local buttons = { -    entries = { -      { "SPC f", "  Find File", "<CMD>Telescope find_files<CR>" }, -      { "SPC n", "  New File", "<CMD>ene!<CR>" }, -      { "SPC P", "  Recent Projects ", "<CMD>Telescope projects<CR>" }, -      { "SPC s r", "  Recently Used Files", "<CMD>Telescope oldfiles<CR>" }, -      { "SPC s t", "  Find Word", "<CMD>Telescope live_grep<CR>" }, -      { -        "SPC L c", -        "  Configuration", -        "<CMD>edit " .. require("lvim.config"):get_user_config_path() .. " <CR>", +  local status_ok, dashboard = pcall(require, "alpha.themes.dashboard") +  if status_ok then +    local function button(sc, txt, keybind, keybind_opts) +      local b = dashboard.button(sc, txt, keybind, keybind_opts) +      b.opts.hl_shortcut = "Macro" +      return b +    end +    buttons = { +      val = { +        button("f", lvim.icons.ui.FindFile .. "  Find File", "<CMD>Telescope find_files<CR>"), +        button("n", lvim.icons.ui.NewFile .. "  New File", "<CMD>ene!<CR>"), +        button("p", lvim.icons.ui.Project .. "  Projects ", "<CMD>Telescope projects<CR>"), +        button("r", lvim.icons.ui.History .. "  Recent files", ":Telescope oldfiles <CR>"), +        button("t", lvim.icons.ui.FindText .. "  Find Text", "<CMD>Telescope live_grep<CR>"), +        button( +          "c", +          lvim.icons.ui.Gear .. "  Configuration", +          "<CMD>edit " .. require("lvim.config"):get_user_config_path() .. " <CR>" +        ),        }, -    }, -  } +    } +  end    return {      header = header, diff --git a/lua/lvim/core/alpha/startify.lua b/lua/lvim/core/alpha/startify.lua index 2ea541f5..b1e83d1d 100644 --- a/lua/lvim/core/alpha/startify.lua +++ b/lua/lvim/core/alpha/startify.lua @@ -19,7 +19,7 @@ function M.get_sections()    local top_buttons = {      entries = { -      { "e", "  New File", "<CMD>ene!<CR>" }, +      { "e", lvim.icons.ui.NewFile .. " New File", "<CMD>ene!<CR>" },      },      val = {},    } diff --git a/lua/lvim/core/autocmds.lua b/lua/lvim/core/autocmds.lua index f5c63588..ae10d552 100644 --- a/lua/lvim/core/autocmds.lua +++ b/lua/lvim/core/autocmds.lua @@ -3,13 +3,25 @@ local Log = require "lvim.core.log"  --- Load the default set of autogroups and autocommands.  function M.load_defaults() -  local user_config_file = require("lvim.config"):get_user_config_path() - -  if vim.loop.os_uname().version:match "Windows" then -    -- autocmds require forward slashes even on windows -    user_config_file = user_config_file:gsub("\\", "/") -  end - +  vim.api.nvim_create_autocmd({ "FileType" }, { +    pattern = { +      "Jaq", +      "qf", +      "help", +      "man", +      "lspinfo", +      "spectre_panel", +      "lir", +      "DressingSelect", +      "tsplayground", +    }, +    callback = function() +      vim.cmd [[ +      nnoremap <silent> <buffer> q :close<CR> +      set nobuflisted +    ]] +    end, +  })    local definitions = {      {        "TextYankPost", @@ -18,19 +30,16 @@ function M.load_defaults()          pattern = "*",          desc = "Highlight text on yank",          callback = function() -          require("vim.highlight").on_yank { higroup = "Search", timeout = 200 } +          require("vim.highlight").on_yank { higroup = "Search", timeout = 100 }          end,        },      },      { -      "BufWritePost", +      "FileType",        { -        group = "_general_settings", -        pattern = user_config_file, -        desc = "Trigger LvimReload on saving " .. vim.fn.expand "%:~", -        callback = function() -          require("lvim.config"):reload() -        end, +        group = "_hide_dap_repl", +        pattern = "dap-repl", +        command = "set nobuflisted",        },      },      { @@ -73,6 +82,31 @@ function M.load_defaults()          command = "tabdo wincmd =",        },      }, +    { +      "FileType", +      { +        group = "_filetype_settings", +        pattern = "alpha", +        callback = function() +          vim.cmd [[ +            nnoremap <silent> <buffer> q :qa<CR> +            nnoremap <silent> <buffer> <esc> :qa<CR> +            set nobuflisted +          ]] +        end, +      }, +    }, +    { +      "FileType", +      { +        group = "_filetype_settings", +        pattern = "lir", +        callback = function() +          vim.opt_local.number = false +          vim.opt_local.relativenumber = false +        end, +      }, +    },    }    M.define_autocmds(definitions) @@ -129,6 +163,23 @@ function M.toggle_format_on_save()    end  end +function M.enable_reload_config_on_save() +  local user_config_file = require("lvim.config"):get_user_config_path() + +  if vim.loop.os_uname().version:match "Windows" then +    -- autocmds require forward slashes even on windows +    user_config_file = user_config_file:gsub("\\", "/") +  end +  vim.api.nvim_create_autocmd("BufWritePost", { +    group = "_general_settings", +    pattern = user_config_file, +    desc = "Trigger LvimReload on saving config.lua", +    callback = function() +      require("lvim.config"):reload() +    end, +  }) +end +  function M.enable_transparent_mode()    vim.api.nvim_create_autocmd("ColorScheme", {      pattern = "*", diff --git a/lua/lvim/core/autopairs.lua b/lua/lvim/core/autopairs.lua index 469a38a4..5daffba5 100644 --- a/lua/lvim/core/autopairs.lua +++ b/lua/lvim/core/autopairs.lua @@ -47,7 +47,10 @@ function M.config()  end  M.setup = function() -  local autopairs = require "nvim-autopairs" +  local status_ok, autopairs = pcall(require, "nvim-autopairs") +  if not status_ok then +    return +  end    local Rule = require "nvim-autopairs.rule"    autopairs.setup { diff --git a/lua/lvim/core/breadcrumbs.lua b/lua/lvim/core/breadcrumbs.lua new file mode 100644 index 00000000..ab5aa86d --- /dev/null +++ b/lua/lvim/core/breadcrumbs.lua @@ -0,0 +1,226 @@ +local M = {} + +-- local Log = require "lvim.core.log" + +local icons = lvim.icons.kind + +M.config = function() +  lvim.builtin.breadcrumbs = { +    active = true, +    on_config_done = nil, +    winbar_filetype_exclude = { +      "help", +      "startify", +      "dashboard", +      "packer", +      "neo-tree", +      "neogitstatus", +      "NvimTree", +      "Trouble", +      "alpha", +      "lir", +      "Outline", +      "spectre_panel", +      "toggleterm", +      "DressingSelect", +      "Jaq", +      "harpoon", +      "dap-repl", +      "dap-terminal", +      "dapui_console", +      "lab", +      "Markdown", +      "notify", +      "noice", +      "", +    }, +    options = { +      icons = { +        Array = icons.Array .. " ", +        Boolean = icons.Boolean, +        Class = icons.Class .. " ", +        Color = icons.Color .. " ", +        Constant = icons.Constant .. " ", +        Constructor = icons.Constructor .. " ", +        Enum = icons.Enum .. " ", +        EnumMember = icons.EnumMember .. " ", +        Event = icons.Event .. " ", +        Field = icons.Field .. " ", +        File = icons.File .. " ", +        Folder = icons.Folder .. " ", +        Function = icons.Function .. " ", +        Interface = icons.Interface .. " ", +        Key = icons.Key .. " ", +        Keyword = icons.Keyword .. " ", +        Method = icons.Method .. " ", +        Module = icons.Module .. " ", +        Namespace = icons.Namespace .. " ", +        Null = icons.Null .. " ", +        Number = icons.Number .. " ", +        Object = icons.Object .. " ", +        Operator = icons.Operator .. " ", +        Package = icons.Package .. " ", +        Property = icons.Property .. " ", +        Reference = icons.Reference .. " ", +        Snippet = icons.Snippet .. " ", +        String = icons.String .. " ", +        Struct = icons.Struct .. " ", +        Text = icons.Text .. " ", +        TypeParameter = icons.TypeParameter .. " ", +        Unit = icons.Unit .. " ", +        Value = icons.Value .. " ", +        Variable = icons.Variable .. " ", +      }, +      highlight = true, +      separator = " " .. ">" .. " ", +      depth_limit = 0, +      depth_limit_indicator = "..", +    }, +  } +end + +M.setup = function() +  local status_ok, navic = pcall(require, "nvim-navic") +  if not status_ok then +    return +  end + +  M.create_winbar() +  navic.setup(lvim.builtin.breadcrumbs.options) + +  if lvim.builtin.breadcrumbs.on_config_done then +    lvim.builtin.breadcrumbs.on_config_done() +  end +end + +M.get_filename = function() +  local filename = vim.fn.expand "%:t" +  local extension = vim.fn.expand "%:e" +  local f = require "lvim.utils.functions" + +  if not f.isempty(filename) then +    local file_icon, file_icon_color = +      require("nvim-web-devicons").get_icon_color(filename, extension, { default = true }) + +    local hl_group = "FileIconColor" .. extension + +    vim.api.nvim_set_hl(0, hl_group, { fg = file_icon_color }) +    if f.isempty(file_icon) then +      file_icon = lvim.icons.kind.File +    end + +    local buf_ft = vim.bo.filetype + +    if buf_ft == "dapui_breakpoints" then +      file_icon = lvim.icons.ui.Bug +    end + +    if buf_ft == "dapui_stacks" then +      file_icon = lvim.icons.ui.Stacks +    end + +    if buf_ft == "dapui_scopes" then +      file_icon = lvim.icons.ui.Scopes +    end + +    if buf_ft == "dapui_watches" then +      file_icon = lvim.icons.ui.Watches +    end + +    -- if buf_ft == "dapui_console" then +    --   file_icon = lvim.icons.ui.DebugConsole +    -- end + +    local navic_text = vim.api.nvim_get_hl_by_name("Normal", true) +    vim.api.nvim_set_hl(0, "Winbar", { fg = navic_text.foreground }) + +    return " " .. "%#" .. hl_group .. "#" .. file_icon .. "%*" .. " " .. "%#Winbar#" .. filename .. "%*" +  end +end + +local get_gps = function() +  local status_gps_ok, gps = pcall(require, "nvim-navic") +  if not status_gps_ok then +    return "" +  end + +  local status_ok, gps_location = pcall(gps.get_location, {}) +  if not status_ok then +    return "" +  end + +  if not gps.is_available() or gps_location == "error" then +    return "" +  end + +  if not require("lvim.utils.functions").isempty(gps_location) then +    -- TODO: replace with chevron +    return ">" .. " " .. gps_location +  else +    return "" +  end +end + +local excludes = function() +  return vim.tbl_contains(lvim.builtin.breadcrumbs.winbar_filetype_exclude or {}, vim.bo.filetype) +end + +M.get_winbar = function() +  if excludes() then +    return +  end +  local f = require "lvim.utils.functions" +  local value = M.get_filename() + +  local gps_added = false +  if not f.isempty(value) then +    local gps_value = get_gps() +    value = value .. " " .. gps_value +    if not f.isempty(gps_value) then +      gps_added = true +    end +  end + +  if not f.isempty(value) and f.get_buf_option "mod" then +    -- TODO: replace with circle +    local mod = "%#LspCodeLens#" .. lvim.icons.ui.Circle .. "%*" +    if gps_added then +      value = value .. " " .. mod +    else +      value = value .. mod +    end +  end + +  local num_tabs = #vim.api.nvim_list_tabpages() + +  if num_tabs > 1 and not f.isempty(value) then +    local tabpage_number = tostring(vim.api.nvim_tabpage_get_number(0)) +    value = value .. "%=" .. tabpage_number .. "/" .. tostring(num_tabs) +  end + +  local status_ok, _ = pcall(vim.api.nvim_set_option_value, "winbar", value, { scope = "local" }) +  if not status_ok then +    return +  end +end + +M.create_winbar = function() +  vim.api.nvim_create_augroup("_winbar", {}) +  if vim.fn.has "nvim-0.8" == 1 then +    vim.api.nvim_create_autocmd( +      { "CursorMoved", "CursorHold", "BufWinEnter", "BufFilePost", "InsertEnter", "BufWritePost", "TabClosed" }, +      { +        group = "_winbar", +        callback = function() +          local status_ok, _ = pcall(vim.api.nvim_buf_get_var, 0, "lsp_floating_window") +          if not status_ok then +            -- TODO: +            require("lvim.core.breadcrumbs").get_winbar() +          end +        end, +      } +    ) +  end +end + +return M diff --git a/lua/lvim/core/bufferline.lua b/lua/lvim/core/bufferline.lua index 36e5ff54..b8143813 100644 --- a/lua/lvim/core/bufferline.lua +++ b/lua/lvim/core/bufferline.lua @@ -6,7 +6,11 @@ end  local function diagnostics_indicator(num, _, diagnostics, _)    local result = {} -  local symbols = { error = "", warning = "", info = "" } +  local symbols = { +    error = lvim.icons.diagnostics.Error, +    warning = lvim.icons.diagnostics.Warning, +    info = lvim.icons.diagnostics.Information, +  }    if not lvim.use_icons then      return "(" .. num .. ")"    end @@ -59,14 +63,14 @@ M.config = function()        left_mouse_command = "buffer %d", -- can be a string | function, see "Mouse actions"        middle_mouse_command = nil, -- can be a string | function, see "Mouse actions"        indicator = { -        icon = "▎", -- this should be omitted if indicator style is not 'icon' +        icon = lvim.icons.ui.BoldLineLeft, -- this should be omitted if indicator style is not 'icon'          style = "icon", -- can also be 'underline'|'none',        }, -      buffer_close_icon = "", -      modified_icon = "●", -      close_icon = "", -      left_trunc_marker = "", -      right_trunc_marker = "", +      buffer_close_icon = lvim.icons.ui.Close, +      modified_icon = lvim.icons.ui.Circle, +      close_icon = lvim.icons.ui.BoldClose, +      left_trunc_marker = lvim.icons.ui.ArrowCircleLeft, +      right_trunc_marker = lvim.icons.ui.ArrowCircleRight,        --- name_formatter can be used to change the buffer's label in the bufferline.        --- Please note some names can/will break the        --- bufferline so use this at your discretion knowing that it has @@ -140,7 +144,13 @@ end  M.setup = function()    require("lvim.keymappings").load(lvim.builtin.bufferline.keymap) -  require("bufferline").setup { + +  local status_ok, bufferline = pcall(require, "bufferline") +  if not status_ok then +    return +  end + +  bufferline.setup {      options = lvim.builtin.bufferline.options,      highlights = lvim.builtin.bufferline.highlights,    } diff --git a/lua/lvim/core/builtins/init.lua b/lua/lvim/core/builtins/init.lua index 5cad2a00..0060c460 100644 --- a/lua/lvim/core/builtins/init.lua +++ b/lua/lvim/core/builtins/init.lua @@ -1,6 +1,7 @@  local M = {}  local builtins = { +  "lvim.core.theme",    "lvim.core.which-key",    "lvim.core.gitsigns",    "lvim.core.cmp", @@ -9,6 +10,10 @@ local builtins = {    "lvim.core.telescope",    "lvim.core.treesitter",    "lvim.core.nvimtree", +  "lvim.core.lir", +  "lvim.core.illuminate", +  "lvim.core.indentlines", +  "lvim.core.breadcrumbs",    "lvim.core.project",    "lvim.core.bufferline",    "lvim.core.autopairs", @@ -21,7 +26,8 @@ local builtins = {  function M.config(config)    for _, builtin_path in ipairs(builtins) do -    local builtin = require(builtin_path) +    local builtin = reload(builtin_path) +      builtin.config(config)    end  end diff --git a/lua/lvim/core/cmp.lua b/lua/lvim/core/cmp.lua index 408691a6..4ebc4d43 100644 --- a/lua/lvim/core/cmp.lua +++ b/lua/lvim/core/cmp.lua @@ -19,6 +19,7 @@ end  local function feedkeys(key, mode)    vim.api.nvim_feedkeys(T(key), mode, true)  end +  M.methods.feedkeys = feedkeys  ---when inside a snippet, seeks to the nearest luasnip field if possible, and checks if it is jumpable @@ -113,6 +114,7 @@ local function jumpable(dir)      return luasnip.in_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable(1)    end  end +  M.methods.jumpable = jumpable  M.config = function() @@ -135,39 +137,13 @@ M.config = function()        keyword_length = 1,      },      experimental = { -      ghost_text = true, +      ghost_text = false,        native_menu = false,      },      formatting = {        fields = { "kind", "abbr", "menu" },        max_width = 0, -      kind_icons = { -        Class = " ", -        Color = " ", -        Constant = "ﲀ ", -        Constructor = " ", -        Enum = "練", -        EnumMember = " ", -        Event = " ", -        Field = " ", -        File = "", -        Folder = " ", -        Function = " ", -        Interface = "ﰮ ", -        Keyword = " ", -        Method = " ", -        Module = " ", -        Operator = "", -        Property = " ", -        Reference = " ", -        Snippet = " ", -        Struct = " ", -        Text = " ", -        TypeParameter = " ", -        Unit = "塞", -        Value = " ", -        Variable = " ", -      }, +      kind_icons = lvim.icons.kind,        source_names = {          nvim_lsp = "(LSP)",          emoji = "(Emoji)", @@ -178,6 +154,8 @@ M.config = function()          luasnip = "(Snippet)",          buffer = "(Buffer)",          tmux = "(TMUX)", +        copilot = "(Copilot)", +        treesitter = "(TreeSitter)",        },        duplicates = {          buffer = 1, @@ -189,10 +167,40 @@ M.config = function()        format = function(entry, vim_item)          local max_width = lvim.builtin.cmp.formatting.max_width          if max_width ~= 0 and #vim_item.abbr > max_width then -          vim_item.abbr = string.sub(vim_item.abbr, 1, max_width - 1) .. "…" +          vim_item.abbr = string.sub(vim_item.abbr, 1, max_width - 1) .. lvim.icons.ui.Ellipsis          end          if lvim.use_icons then            vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind] + +          -- TODO: not sure why I can't put this anywhere else +          vim.api.nvim_set_hl(0, "CmpItemKindCopilot", { fg = "#6CC644" }) +          if entry.source.name == "copilot" then +            vim_item.kind = lvim.icons.git.Octoface +            vim_item.kind_hl_group = "CmpItemKindCopilot" +          end + +          vim.api.nvim_set_hl(0, "CmpItemKindTabnine", { fg = "#CA42F0" }) +          if entry.source.name == "cmp_tabnine" then +            vim_item.kind = lvim.icons.misc.Robot +            vim_item.kind_hl_group = "CmpItemKindTabnine" +          end + +          vim.api.nvim_set_hl(0, "CmpItemKindCrate", { fg = "#F64D00" }) +          if entry.source.name == "crates" then +            vim_item.kind = lvim.icons.misc.Package +            vim_item.kind_hl_group = "CmpItemKindCrate" +          end + +          if entry.source.name == "lab.quick_data" then +            vim_item.kind = lvim.icons.misc.CircuitBoard +            vim_item.kind_hl_group = "CmpItemKindConstant" +          end + +          vim.api.nvim_set_hl(0, "CmpItemKindEmoji", { fg = "#FDE030" }) +          if entry.source.name == "emoji" then +            vim_item.kind = lvim.icons.misc.Smiley +            vim_item.kind_hl_group = "CmpItemKindEmoji" +          end          end          vim_item.menu = lvim.builtin.cmp.formatting.source_names[entry.source.name]          vim_item.dup = lvim.builtin.cmp.formatting.duplicates[entry.source.name] @@ -210,7 +218,50 @@ M.config = function()        documentation = cmp.config.window.bordered(),      },      sources = { -      { name = "nvim_lsp" }, +      { +        name = "copilot", +        -- keyword_length = 0, +        max_item_count = 3, +        trigger_characters = { +          { +            ".", +            ":", +            "(", +            "'", +            '"', +            "[", +            ",", +            "#", +            "*", +            "@", +            "|", +            "=", +            "-", +            "{", +            "/", +            "\\", +            "+", +            "?", +            " ", +            -- "\t", +            -- "\n", +          }, +        }, +      }, +      { +        name = "nvim_lsp", +        entry_filter = function(entry, ctx) +          local kind = require("cmp.types").lsp.CompletionItemKind[entry:get_kind()] +          if kind == "Snippet" and ctx.prev_context.filetype == "java" then +            return false +          end +          if kind == "Text" then +            return false +          end +          return true +        end, +      }, +        { name = "path" },        { name = "luasnip" },        { name = "cmp_tabnine" }, @@ -223,8 +274,8 @@ M.config = function()        { name = "tmux" },      },      mapping = cmp.mapping.preset.insert { -      ["<C-k>"] = cmp.mapping.select_prev_item(), -      ["<C-j>"] = cmp.mapping.select_next_item(), +      ["<C-k>"] = cmp.mapping(cmp.mapping.select_prev_item(), { "i", "c" }), +      ["<C-j>"] = cmp.mapping(cmp.mapping.select_next_item(), { "i", "c" }),        ["<Down>"] = cmp.mapping(cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Select }, { "i" }),        ["<Up>"] = cmp.mapping(cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Select }, { "i" }),        ["<C-d>"] = cmp.mapping.scroll_docs(-4), @@ -247,7 +298,8 @@ M.config = function()          elseif jumpable(1) then            luasnip.jump(1)          elseif has_words_before() then -          cmp.complete() +          -- cmp.complete() +          fallback()          else            fallback()          end @@ -283,11 +335,38 @@ M.config = function()          fallback() -- if not exited early, always fallback        end),      }, +    cmdline = { +      enable = true, +      options = { +        { +          type = ":", +          sources = { +            { name = "path" }, +          }, +        }, +        { +          type = { "/", "?" }, +          sources = { +            { name = "buffer" }, +          }, +        }, +      }, +    },    }  end  function M.setup() -  require("cmp").setup(lvim.builtin.cmp) +  local cmp = require "cmp" +  cmp.setup(lvim.builtin.cmp) + +  if lvim.builtin.cmp.cmdline.enable then +    for _, option in ipairs(lvim.builtin.cmp.cmdline.options) do +      cmp.setup.cmdline(option.type, { +        mapping = cmp.mapping.preset.cmdline(), +        sources = option.sources, +      }) +    end +  end  end  return M diff --git a/lua/lvim/core/comment.lua b/lua/lvim/core/comment.lua index d07739c6..501d01b6 100644 --- a/lua/lvim/core/comment.lua +++ b/lua/lvim/core/comment.lua @@ -1,27 +1,10 @@  local M = {}  function M.config() -  local pre_hook = nil -  if lvim.builtin.treesitter.context_commentstring.enable then -    pre_hook = function(ctx) -      local U = require "Comment.utils" - -      -- Determine whether to use linewise or blockwise commentstring -      local type = ctx.ctype == U.ctype.linewise and "__default" or "__multiline" - -      -- Determine the location where to calculate commentstring from -      local location = nil -      if ctx.ctype == U.ctype.blockwise then -        location = require("ts_context_commentstring.utils").get_cursor_location() -      elseif ctx.cmotion == U.cmotion.v or ctx.cmotion == U.cmotion.V then -        location = require("ts_context_commentstring.utils").get_visual_start_location() -      end - -      return require("ts_context_commentstring.internal").calculate_commentstring { -        key = type, -        location = location, -      } -    end +  local pre_hook +  local loaded, ts_comment = pcall(require, "ts_context_commentstring.integrations.comment_nvim") +  if loaded and ts_comment then +    pre_hook = ts_comment.create_pre_hook()    end    lvim.builtin.comment = {      active = true, @@ -30,6 +13,11 @@ function M.config()      ---@type boolean      padding = true, +    ---Whether cursor should stay at the +    ---same position. Only works in NORMAL +    ---mode mappings +    sticky = true, +      ---Lines to be ignored while comment/uncomment.      ---Could be a regex string or a function that returns a regex string.      ---Example: Use '^$' to ignore empty lines @@ -45,9 +33,6 @@ function M.config()        ---Extra mapping        ---Includes `gco`, `gcO`, `gcA`        extra = true, -      ---Extended mapping -      ---Includes `g>`, `g<`, `g>[count]{motion}` and `g<[count]{motion}` -      extended = false,      },      ---LHS of line and block comment toggle mapping in NORMAL/VISUAL mode @@ -68,6 +53,17 @@ function M.config()        block = "gb",      }, +    ---LHS of extra mappings +    ---@type table +    extra = { +      ---Add comment on the line above +      above = "gcO", +      ---Add comment on the line below +      below = "gco", +      ---Add comment at the end of line +      eol = "gcA", +    }, +      ---Pre-hook, called before commenting the line      ---@type function|nil      pre_hook = pre_hook, diff --git a/lua/lvim/core/dap.lua b/lua/lvim/core/dap.lua index 727e238f..cff50f64 100644 --- a/lua/lvim/core/dap.lua +++ b/lua/lvim/core/dap.lua @@ -2,31 +2,37 @@ local M = {}  M.config = function()    lvim.builtin.dap = { -    active = false, +    active = true,      on_config_done = nil,      breakpoint = { -      text = "", -      texthl = "LspDiagnosticsSignError", +      text = lvim.icons.ui.Bug, +      texthl = "DiagnosticSignError",        linehl = "",        numhl = "",      },      breakpoint_rejected = { -      text = "", -      texthl = "LspDiagnosticsSignHint", +      text = lvim.icons.ui.Bug, +      texthl = "DiagnosticSignError",        linehl = "",        numhl = "",      },      stopped = { -      text = "", -      texthl = "LspDiagnosticsSignInformation", -      linehl = "DiagnosticUnderlineInfo", -      numhl = "LspDiagnosticsSignInformation", +      text = lvim.icons.ui.BoldArrowRight, +      texthl = "DiagnosticSignWarn", +      linehl = "Visual", +      numhl = "DiagnosticSignWarn", +    }, +    ui = { +      auto_open = true,      },    }  end  M.setup = function() -  local dap = require "dap" +  local status_ok, dap = pcall(require, "dap") +  if not status_ok then +    return +  end    if lvim.use_icons then      vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint) @@ -34,8 +40,6 @@ M.setup = function()      vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped)    end -  dap.defaults.fallback.terminal_win_cmd = "50vsplit new" -    lvim.builtin.which_key.mappings["d"] = {      name = "Debug",      t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" }, @@ -51,6 +55,7 @@ M.setup = function()      r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" },      s = { "<cmd>lua require'dap'.continue()<cr>", "Start" },      q = { "<cmd>lua require'dap'.close()<cr>", "Quit" }, +    U = { "<cmd>lua require'dapui'.toggle()<cr>", "Toggle UI" },    }    if lvim.builtin.dap.on_config_done then @@ -58,21 +63,65 @@ M.setup = function()    end  end --- TODO put this up there ^^^ call in ftplugin +M.setup_ui = function() +  local status_ok, dap = pcall(require, "dap") +  if not status_ok then +    return +  end +  local dapui = require "dapui" +  dapui.setup { +    expand_lines = true, +    icons = { expanded = "", collapsed = "", circular = "" }, +    mappings = { +      -- Use a table to apply multiple mappings +      expand = { "<CR>", "<2-LeftMouse>" }, +      open = "o", +      remove = "d", +      edit = "e", +      repl = "r", +      toggle = "t", +    }, +    layouts = { +      { +        elements = { +          { id = "scopes", size = 0.33 }, +          { id = "breakpoints", size = 0.17 }, +          { id = "stacks", size = 0.25 }, +          { id = "watches", size = 0.25 }, +        }, +        size = 0.33, +        position = "right", +      }, +      { +        elements = { +          { id = "repl", size = 0.45 }, +          { id = "console", size = 0.55 }, +        }, +        size = 0.27, +        position = "bottom", +      }, +    }, +    floating = { +      max_height = 0.9, +      max_width = 0.5, -- Floats will be treated as percentage of your screen. +      border = vim.g.border_chars, -- Border style. Can be 'single', 'double' or 'rounded' +      mappings = { +        close = { "q", "<Esc>" }, +      }, +    }, +  } --- M.dap = function() ---   if lvim.plugin.dap.active then ---     local dap_install = require "dap-install" ---     dap_install.config("python_dbg", {}) ---   end --- end --- --- M.dap = function() ---   -- gem install readapt ruby-debug-ide ---   if lvim.plugin.dap.active then ---     local dap_install = require "dap-install" ---     dap_install.config("ruby_vsc_dbg", {}) ---   end --- end +  if lvim.builtin.dap.ui.auto_open then +    dap.listeners.after.event_initialized["dapui_config"] = function() +      dapui.open() +    end +    -- dap.listeners.before.event_terminated["dapui_config"] = function() +    --   dapui.close() +    -- end +    -- dap.listeners.before.event_exited["dapui_config"] = function() +    --   dapui.close() +    -- end +  end +end  return M diff --git a/lua/lvim/core/gitsigns.lua b/lua/lvim/core/gitsigns.lua index 0365fc69..cc727c8b 100644 --- a/lua/lvim/core/gitsigns.lua +++ b/lua/lvim/core/gitsigns.lua @@ -8,31 +8,31 @@ M.config = function()        signs = {          add = {            hl = "GitSignsAdd", -          text = "▎", +          text = lvim.icons.ui.BoldLineLeft,            numhl = "GitSignsAddNr",            linehl = "GitSignsAddLn",          },          change = {            hl = "GitSignsChange", -          text = "▎", +          text = lvim.icons.ui.BoldLineLeft,            numhl = "GitSignsChangeNr",            linehl = "GitSignsChangeLn",          },          delete = {            hl = "GitSignsDelete", -          text = "契", +          text = lvim.icons.ui.Triangle,            numhl = "GitSignsDeleteNr",            linehl = "GitSignsDeleteLn",          },          topdelete = {            hl = "GitSignsDelete", -          text = "契", +          text = lvim.icons.ui.Triangle,            numhl = "GitSignsDeleteNr",            linehl = "GitSignsDeleteLn",          },          changedelete = {            hl = "GitSignsChange", -          text = "▎", +          text = lvim.icons.ui.BoldLineLeft,            numhl = "GitSignsChangeNr",            linehl = "GitSignsChangeLn",          }, @@ -79,7 +79,7 @@ M.config = function()  end  M.setup = function() -  local gitsigns = require "gitsigns" +  local gitsigns = reload "gitsigns"    gitsigns.setup(lvim.builtin.gitsigns.opts)    if lvim.builtin.gitsigns.on_config_done then diff --git a/lua/lvim/core/illuminate.lua b/lua/lvim/core/illuminate.lua new file mode 100644 index 00000000..a3ca6711 --- /dev/null +++ b/lua/lvim/core/illuminate.lua @@ -0,0 +1,68 @@ +local M = {} + +M.config = function() +  lvim.builtin.illuminate = { +    active = true, +    on_config_done = nil, +    options = { +      -- providers: provider used to get references in the buffer, ordered by priority +      providers = { +        "lsp", +        "treesitter", +        "regex", +      }, +      -- delay: delay in milliseconds +      delay = 120, +      -- filetypes_denylist: filetypes to not illuminate, this overrides filetypes_allowlist +      filetypes_denylist = { +        "dirvish", +        "fugitive", +        "alpha", +        "NvimTree", +        "packer", +        "neogitstatus", +        "Trouble", +        "lir", +        "Outline", +        "spectre_panel", +        "toggleterm", +        "DressingSelect", +        "TelescopePrompt", +      }, +      -- filetypes_allowlist: filetypes to illuminate, this is overridden by filetypes_denylist +      filetypes_allowlist = {}, +      -- modes_denylist: modes to not illuminate, this overrides modes_allowlist +      modes_denylist = {}, +      -- modes_allowlist: modes to illuminate, this is overridden by modes_denylist +      modes_allowlist = {}, +      -- providers_regex_syntax_denylist: syntax to not illuminate, this overrides providers_regex_syntax_allowlist +      -- Only applies to the 'regex' provider +      -- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name') +      providers_regex_syntax_denylist = {}, +      -- providers_regex_syntax_allowlist: syntax to illuminate, this is overridden by providers_regex_syntax_denylist +      -- Only applies to the 'regex' provider +      -- Use :echom synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name') +      providers_regex_syntax_allowlist = {}, +      -- under_cursor: whether or not to illuminate under the cursor +      under_cursor = true, +    }, +  } +end + +M.setup = function() +  local status_ok, illuminate = pcall(reload, "illuminate") +  if not status_ok then +    return +  end + +  local config_ok, _ = pcall(illuminate.configure, lvim.builtin.illuminate.options) +  if not config_ok then +    return +  end + +  if lvim.builtin.illuminate.on_config_done then +    lvim.builtin.illuminate.on_config_done() +  end +end + +return M diff --git a/lua/lvim/core/indentlines.lua b/lua/lvim/core/indentlines.lua new file mode 100644 index 00000000..dc4a72ba --- /dev/null +++ b/lua/lvim/core/indentlines.lua @@ -0,0 +1,42 @@ +local M = {} + +M.config = function() +  lvim.builtin.indentlines = { +    active = true, +    on_config_done = nil, +    options = { +      enabled = true, +      buftype_exclude = { "terminal", "nofile" }, +      filetype_exclude = { +        "help", +        "startify", +        "dashboard", +        "packer", +        "neogitstatus", +        "NvimTree", +        "Trouble", +        "text", +      }, +      char = lvim.icons.ui.LineLeft, +      show_trailing_blankline_indent = false, +      show_first_indent_level = true, +      use_treesitter = true, +      show_current_context = true, +    }, +  } +end + +M.setup = function() +  local status_ok, indent_blankline = pcall(reload, "indent_blankline") +  if not status_ok then +    return +  end + +  indent_blankline.setup(lvim.builtin.indentlines.options) + +  if lvim.builtin.indentlines.on_config_done then +    lvim.builtin.indentlines.on_config_done() +  end +end + +return M diff --git a/lua/lvim/core/info.lua b/lua/lvim/core/info.lua index da9ddbe6..c413f0f1 100644 --- a/lua/lvim/core/info.lua +++ b/lua/lvim/core/info.lua @@ -25,8 +25,8 @@ local function make_formatters_info(ft)      "Formatters info",      fmt(        "* Active: %s%s", -      table.concat(registered_formatters, "  , "), -      vim.tbl_count(registered_formatters) > 0 and "  " or "" +      table.concat(registered_formatters, " " .. lvim.icons.ui.BoxChecked .. " , "), +      vim.tbl_count(registered_formatters) > 0 and " " .. lvim.icons.ui.BoxChecked .. " " or ""      ),      fmt("* Supported: %s", str_list(supported_formatters)),    } @@ -41,8 +41,8 @@ local function make_code_actions_info(ft)      "Code actions info",      fmt(        "* Active: %s%s", -      table.concat(registered_actions, "  , "), -      vim.tbl_count(registered_actions) > 0 and "  " or "" +      table.concat(registered_actions, " " .. lvim.icons.ui.BoxChecked .. " , "), +      vim.tbl_count(registered_actions) > 0 and " " .. lvim.icons.ui.BoxChecked .. " " or ""      ),    } @@ -57,8 +57,8 @@ local function make_linters_info(ft)      "Linters info",      fmt(        "* Active: %s%s", -      table.concat(registered_linters, "  , "), -      vim.tbl_count(registered_linters) > 0 and "  " or "" +      table.concat(registered_linters, " " .. lvim.icons.ui.BoxChecked .. " , "), +      vim.tbl_count(registered_linters) > 0 and " " .. lvim.icons.ui.BoxChecked .. " " or ""      ),      fmt("* Supported: %s", str_list(supported_linters)),    } @@ -202,7 +202,7 @@ function M.toggle_popup(ft)      vim.fn.matchadd("LvimInfoIdentifier", " " .. ft .. "$")      vim.fn.matchadd("string", "true")      vim.fn.matchadd("string", "active") -    vim.fn.matchadd("string", "") +    vim.fn.matchadd("string", lvim.icons.ui.BoxChecked)      vim.fn.matchadd("boolean", "inactive")      vim.fn.matchadd("error", "false")      tbl_set_highlight(require("lvim.lsp.null-ls.formatters").list_registered(ft), "LvimInfoIdentifier") diff --git a/lua/lvim/core/lir.lua b/lua/lvim/core/lir.lua new file mode 100644 index 00000000..68445664 --- /dev/null +++ b/lua/lvim/core/lir.lua @@ -0,0 +1,118 @@ +local M = {} + +M.config = function() +  lvim.builtin.lir = { +    active = true, +    on_config_done = nil, +    icon = "", +  } + +  local status_ok, _ = pcall(require, "lir") +  if not status_ok then +    return +  end + +  local actions = require "lir.actions" +  local mark_actions = require "lir.mark.actions" +  local clipboard_actions = require "lir.clipboard.actions" + +  lvim.builtin.lir = vim.tbl_extend("force", lvim.builtin.lir, { +    show_hidden_files = false, +    devicons_enable = true, +    mappings = { +      ["l"] = actions.edit, +      ["<CR>"] = actions.edit, +      ["<C-s>"] = actions.split, +      ["v"] = actions.vsplit, +      ["<C-t>"] = actions.tabedit, + +      ["h"] = actions.up, +      ["q"] = actions.quit, + +      ["A"] = actions.mkdir, +      ["a"] = actions.newfile, +      ["r"] = actions.rename, +      ["@"] = actions.cd, +      ["Y"] = actions.yank_path, +      ["i"] = actions.toggle_show_hidden, +      ["d"] = actions.delete, + +      ["J"] = function() +        mark_actions.toggle_mark() +        vim.cmd "normal! j" +      end, +      ["c"] = clipboard_actions.copy, +      ["x"] = clipboard_actions.cut, +      ["p"] = clipboard_actions.paste, +    }, +    float = { +      winblend = 0, +      curdir_window = { +        enable = false, +        highlight_dirname = true, +      }, + +      -- -- You can define a function that returns a table to be passed as the third +      -- -- argument of nvim_open_win(). +      win_opts = function() +        local width = math.floor(vim.o.columns * 0.7) +        local height = math.floor(vim.o.lines * 0.7) +        return { +          border = "rounded", +          width = width, +          height = height, +          -- row = 1, +          -- col = math.floor((vim.o.columns - width) / 2), +        } +      end, +    }, +    hide_cursor = false, +    on_init = function() +      -- use visual mode +      vim.api.nvim_buf_set_keymap( +        0, +        "x", +        "J", +        ':<C-u>lua require"lir.mark.actions".toggle_mark("v")<CR>', +        { noremap = true, silent = true } +      ) + +      -- echo cwd +      -- vim.api.nvim_echo({ { vim.fn.expand "%:p", "Normal" } }, false, {}) +    end, +  }) +end + +function M.icon_setup() +  local function get_hl_by_name(name) +    local ret = vim.api.nvim_get_hl_by_name(name.group, true) +    return string.format("#%06x", ret[name.property]) +  end + +  local found, icon_hl = pcall(get_hl_by_name, { group = "NvimTreeFolderIcon", property = "foreground" }) +  if not found then +    icon_hl = "#42A5F5" +  end + +  reload("nvim-web-devicons").set_icon { +    lir_folder_icon = { +      icon = lvim.builtin.lir.icon, +      color = icon_hl, +      name = "LirFolderNode", +    }, +  } +end + +function M.setup() +  local status_ok, lir = pcall(reload, "lir") +  if not status_ok then +    return +  end +  lir.setup(lvim.builtin.lir) + +  if lvim.builtin.lir.on_config_done then +    lvim.builtin.lir.on_config_done(lir) +  end +end + +return M diff --git a/lua/lvim/core/log.lua b/lua/lvim/core/log.lua index 48891139..d88a659b 100644 --- a/lua/lvim/core/log.lua +++ b/lua/lvim/core/log.lua @@ -12,26 +12,23 @@ vim.tbl_add_reverse_lookup(Log.levels)  local notify_opts = {}  function Log:set_level(level) -  local logger_ok, _ = xpcall(function() -    local log_level = Log.levels[level:upper()] -    local structlog = require "structlog" -    if structlog then -      local logger = structlog.get_logger "lvim" -      for _, s in ipairs(logger.sinks) do -        s.level = log_level -      end +  local logger_ok, logger = pcall(function() +    return require("structlog").get_logger "lvim" +  end) +  local log_level = Log.levels[level:upper()] +  if logger_ok and logger and log_level then +    for _, s in ipairs(logger.sinks) do +      s.level = log_level      end -  end, debug.traceback) -  if not logger_ok then -    Log:debug("Unable to set logger's level: " .. debug.traceback()) +  else +    vim.notify_once("Unable to set logger's level to " .. level)    end    local packer_ok, _ = xpcall(function() -    package.loaded["packer.log"] = nil -    require("packer.log").new { level = lvim.log.level } +    require("packer.log").cfg { log = { level = level } }    end, debug.traceback)    if not packer_ok then -    Log:debug("Unable to set packer's log level: " .. debug.traceback()) +    vim.notify_once("Unable to set packer's log level to " .. level)    end  end @@ -91,7 +88,7 @@ function Log:init()          vim_log_level = vim_log_level + 1        end -      logger:log(vim_log_level, msg) +      self:info(vim_log_level, msg)      end    end @@ -145,8 +142,9 @@ function Log:configure_notifications(notif_handle)  end  --- Adds a log entry using Plenary.log +---@param level integer [same as vim.log.levels]  ---@param msg any ----@param level string [same as vim.log.log_levels] +---@param event any  function Log:add_entry(level, msg, event)    local logger = self:get_logger()    if not logger then @@ -158,11 +156,15 @@ end  ---Retrieves the handle of the logger object  ---@return table|nil logger handle if found  function Log:get_logger() -  if self.__handle then -    return self.__handle +  local logger_ok, logger = pcall(function() +    return require("structlog").get_logger "lvim" +  end) +  if logger_ok and logger then +    return logger    end -  local logger = self:init() +  logger = self:init() +    if not logger then      return    end diff --git a/lua/lvim/core/lualine/components.lua b/lua/lvim/core/lualine/components.lua index c88bf82b..e4148e20 100644 --- a/lua/lvim/core/lualine/components.lua +++ b/lua/lvim/core/lualine/components.lua @@ -12,10 +12,35 @@ local function diff_source()    end  end +local statusline_hl = vim.api.nvim_get_hl_by_name("StatusLine", true) +local cursorline_hl = vim.api.nvim_get_hl_by_name("CursorLine", true) +local normal_hl = vim.api.nvim_get_hl_by_name("Normal", true) + +vim.api.nvim_set_hl(0, "SLCopilot", { fg = "#6CC644", bg = statusline_hl.background }) +vim.api.nvim_set_hl(0, "SLGitIcon", { fg = "#E8AB53", bg = cursorline_hl.background }) +vim.api.nvim_set_hl(0, "SLBranchName", { fg = normal_hl.foreground, bg = cursorline_hl.background }) +vim.api.nvim_set_hl(0, "SLProgress", { fg = "#ECBE7B", bg = statusline_hl.background }) + +local location_color = nil +local branch = lvim.icons.git.Branch +local separator = lvim.icons.ui.LineMiddle + +if lvim.colorscheme == "tokyonight" then +  location_color = "SLBranchName" +  branch = "%#SLGitIcon#" .. lvim.icons.git.Branch .. "%*" .. "%#SLBranchName#" + +  local status_ok, tnc = pcall(require, "tokyonight.colors") +  if status_ok then +    local tncolors = tnc.setup { transform = true } +    vim.api.nvim_set_hl(0, "SLSeparator", { fg = cursorline_hl.background, bg = tncolors.black }) +    separator = "%#SLSeparator#" .. lvim.icons.ui.LineMiddle .. "%*" +  end +end +  return {    mode = {      function() -      return " " +      return " " .. lvim.icons.ui.Target .. " "      end,      padding = { left = 0, right = 0 },      color = {}, @@ -23,9 +48,8 @@ return {    },    branch = {      "b:gitsigns_head", -    icon = " ", +    icon = branch,      color = { gui = "bold" }, -    cond = conditions.hide_in_width,    },    filename = {      "filename", @@ -35,7 +59,12 @@ return {    diff = {      "diff",      source = diff_source, -    symbols = { added = "  ", modified = " ", removed = " " }, +    symbols = { +      added = lvim.icons.git.LineAdded .. " ", +      modified = lvim.icons.git.LineModified .. " ", +      removed = lvim.icons.git.LineRemoved .. " ", +    }, +    padding = { left = 2, right = 1 },      diff_color = {        added = { fg = colors.green },        modified = { fg = colors.yellow }, @@ -49,7 +78,9 @@ return {        if vim.bo.filetype == "python" then          local venv = os.getenv "CONDA_DEFAULT_ENV" or os.getenv "VIRTUAL_ENV"          if venv then -          return string.format("  (%s)", utils.env_cleanup(venv)) +          local icons = require "nvim-web-devicons" +          local py_icon, _ = icons.get_icon ".py" +          return string.format(" " .. py_icon .. " (%s)", utils.env_cleanup(venv))          end        end        return "" @@ -60,12 +91,17 @@ return {    diagnostics = {      "diagnostics",      sources = { "nvim_diagnostic" }, -    symbols = { error = " ", warn = " ", info = " ", hint = " " }, -    cond = conditions.hide_in_width, +    symbols = { +      error = lvim.icons.diagnostics.BoldError .. " ", +      warn = lvim.icons.diagnostics.BoldWarning .. " ", +      info = lvim.icons.diagnostics.BoldInformation .. " ", +      hint = lvim.icons.diagnostics.BoldHint .. " ", +    }, +    -- cond = conditions.hide_in_width,    },    treesitter = {      function() -      return "" +      return lvim.icons.ui.Tree      end,      color = function()        local buf = vim.api.nvim_get_current_buf() @@ -87,12 +123,17 @@ return {        end        local buf_ft = vim.bo.filetype        local buf_client_names = {} +      local copilot_active = false        -- add client        for _, client in pairs(buf_clients) do -        if client.name ~= "null-ls" then +        if client.name ~= "null-ls" and client.name ~= "copilot" then            table.insert(buf_client_names, client.name)          end + +        if client.name == "copilot" then +          copilot_active = true +        end        end        -- add formatter @@ -106,26 +147,35 @@ return {        vim.list_extend(buf_client_names, supported_linters)        local unique_client_names = vim.fn.uniq(buf_client_names) -      return "[" .. table.concat(unique_client_names, ", ") .. "]" + +      local language_servers = "[" .. table.concat(unique_client_names, ", ") .. "]" + +      if copilot_active then +        language_servers = language_servers .. "%#SLCopilot#" .. " " .. lvim.icons.git.Octoface .. "%*" +      end + +      return language_servers      end, +    separator = separator,      color = { gui = "bold" },      cond = conditions.hide_in_width,    }, -  location = { "location", cond = conditions.hide_in_width, color = {} }, -  progress = { "progress", cond = conditions.hide_in_width, color = {} }, +  location = { "location", color = location_color }, +  progress = { +    "progress", +    fmt = function() +      return "%P/%L" +    end, +    color = {}, +  }, +    spaces = {      function() -      if not vim.api.nvim_buf_get_option(0, "expandtab") then -        return "Tab size: " .. vim.api.nvim_buf_get_option(0, "tabstop") .. " " -      end -      local size = vim.api.nvim_buf_get_option(0, "shiftwidth") -      if size == 0 then -        size = vim.api.nvim_buf_get_option(0, "tabstop") -      end -      return "Spaces: " .. size .. " " +      local shiftwidth = vim.api.nvim_buf_get_option(0, "shiftwidth") +      return lvim.icons.ui.Tab .. " " .. shiftwidth      end, -    cond = conditions.hide_in_width, -    color = {}, +    separator = separator, +    padding = 1,    },    encoding = {      "o:encoding", @@ -133,7 +183,7 @@ return {      color = {},      cond = conditions.hide_in_width,    }, -  filetype = { "filetype", cond = conditions.hide_in_width }, +  filetype = { "filetype", cond = nil, padding = { left = 1, right = 1 } },    scrollbar = {      function()        local current_line = vim.fn.line "." @@ -144,7 +194,7 @@ return {        return chars[index]      end,      padding = { left = 0, right = 0 }, -    color = { fg = colors.yellow, bg = colors.bg }, +    color = "SLProgress",      cond = nil,    },  } diff --git a/lua/lvim/core/lualine/conditions.lua b/lua/lvim/core/lualine/conditions.lua index 6e120b26..42d52a83 100644 --- a/lua/lvim/core/lualine/conditions.lua +++ b/lua/lvim/core/lualine/conditions.lua @@ -1,11 +1,11 @@ -local window_width_limit = 70 +local window_width_limit = 100  local conditions = {    buffer_not_empty = function()      return vim.fn.empty(vim.fn.expand "%:t") ~= 1    end,    hide_in_width = function() -    return vim.fn.winwidth(0) > window_width_limit +    return vim.o.columns > window_width_limit    end,    -- check_git_workspace = function()    --   local filepath = vim.fn.expand "%:p:h" diff --git a/lua/lvim/core/lualine/init.lua b/lua/lvim/core/lualine/init.lua index e041e8a8..0ee35c04 100644 --- a/lua/lvim/core/lualine/init.lua +++ b/lua/lvim/core/lualine/init.lua @@ -9,7 +9,7 @@ M.config = function()        section_separators = nil,        theme = nil,        disabled_filetypes = nil, -      globalstatus = false, +      globalstatus = true,      },      sections = {        lualine_a = nil, @@ -34,16 +34,19 @@ M.config = function()  end  M.setup = function() -  -- avoid running in headless mode since it's harder to detect failures    if #vim.api.nvim_list_uis() == 0 then      local Log = require "lvim.core.log"      Log:debug "headless mode detected, skipping running setup for lualine"      return    end +  local status_ok, lualine = pcall(require, "lualine") +  if not status_ok then +    return +  end +    require("lvim.core.lualine.styles").update() -  local lualine = require "lualine"    lualine.setup(lvim.builtin.lualine)    if lvim.builtin.lualine.on_config_done then diff --git a/lua/lvim/core/lualine/styles.lua b/lua/lvim/core/lualine/styles.lua index 8991d9d9..81dbbabb 100644 --- a/lua/lvim/core/lualine/styles.lua +++ b/lua/lvim/core/lualine/styles.lua @@ -11,6 +11,7 @@ styles.none = {    style = "none",    options = {      theme = "auto", +    globalstatus = true,      icons_enabled = lvim.use_icons,      component_separators = { left = "", right = "" },      section_separators = { left = "", right = "" }, @@ -40,9 +41,16 @@ styles.default = {    style = "default",    options = {      theme = "auto", +    globalstatus = true,      icons_enabled = lvim.use_icons, -    component_separators = { left = "", right = "" }, -    section_separators = { left = "", right = "" }, +    component_separators = { +      left = lvim.icons.ui.DividerRight, +      right = lvim.icons.ui.DividerLeft, +    }, +    section_separators = { +      left = lvim.icons.ui.BoldDividerRight, +      right = lvim.icons.ui.BoldDividerLeft, +    },      disabled_filetypes = {},    },    sections = { @@ -69,10 +77,11 @@ styles.lvim = {    style = "lvim",    options = {      theme = "auto", +    globalstatus = true,      icons_enabled = lvim.use_icons,      component_separators = { left = "", right = "" },      section_separators = { left = "", right = "" }, -    disabled_filetypes = { "alpha", "NvimTree", "Outline" }, +    disabled_filetypes = { "alpha" },    },    sections = {      lualine_a = { @@ -80,7 +89,6 @@ styles.lvim = {      },      lualine_b = {        components.branch, -      components.filename,      },      lualine_c = {        components.diff, @@ -88,27 +96,39 @@ styles.lvim = {      },      lualine_x = {        components.diagnostics, -      components.treesitter,        components.lsp, +      components.spaces,        components.filetype,      }, -    lualine_y = {}, +    lualine_y = { components.location },      lualine_z = { -      components.scrollbar, +      components.progress,      },    },    inactive_sections = {      lualine_a = { -      "filename", +      components.mode, +    }, +    lualine_b = { +      components.branch, +    }, +    lualine_c = { +      components.diff, +      components.python_env, +    }, +    lualine_x = { +      components.diagnostics, +      components.lsp, +      components.spaces, +      components.filetype, +    }, +    lualine_y = { components.location }, +    lualine_z = { +      components.progress,      }, -    lualine_b = {}, -    lualine_c = {}, -    lualine_x = {}, -    lualine_y = {}, -    lualine_z = {},    },    tabline = {}, -  extensions = { "nvim-tree" }, +  extensions = {},  }  function M.get_style(style) @@ -132,6 +152,14 @@ function M.update()    local style = M.get_style(lvim.builtin.lualine.style)    lvim.builtin.lualine = vim.tbl_deep_extend("keep", lvim.builtin.lualine, style) + +  local color_template = vim.g.colors_name or lvim.colorscheme +  local theme_supported, template = pcall(function() +    require("lualine.utils.loader").load_theme(color_template) +  end) +  if theme_supported and template then +    lvim.builtin.lualine.options.theme = color_template +  end  end  return M diff --git a/lua/lvim/core/mason.lua b/lua/lvim/core/mason.lua index 39be4f42..19dee633 100644 --- a/lua/lvim/core/mason.lua +++ b/lua/lvim/core/mason.lua @@ -3,6 +3,7 @@ local M = {}  function M.config()    lvim.builtin.mason = {      ui = { +      border = "rounded",        keymaps = {          toggle_package_expand = "<CR>",          install_package = "i", @@ -30,7 +31,7 @@ function M.config()  end  function M.setup() -  local status_ok, mason = pcall(require, "mason") +  local status_ok, mason = pcall(reload, "mason")    if not status_ok then      return    end diff --git a/lua/lvim/core/notify.lua b/lua/lvim/core/notify.lua index 2db4c4d5..b08c45a6 100644 --- a/lua/lvim/core/notify.lua +++ b/lua/lvim/core/notify.lua @@ -3,7 +3,7 @@ local M = {}  local Log = require "lvim.core.log"  local defaults = { -  active = false, +  active = true,    on_config_done = nil,    opts = {      ---@usage Animation style one of { "fade", "slide", "fade_in_slide_out", "static" } @@ -29,11 +29,11 @@ local defaults = {      ---@usage Icons for the different levels      icons = { -      ERROR = "", -      WARN = "", -      INFO = "", -      DEBUG = "", -      TRACE = "✎", +      ERROR = lvim.icons.diagnostics.Error, +      WARN = lvim.icons.diagnostics.Warning, +      INFO = lvim.icons.diagnostics.Information, +      DEBUG = lvim.icons.diagnostics.Debug, +      TRACE = lvim.icons.diagnostics.Trace,      },    },  } @@ -43,7 +43,7 @@ function M.config()      defaults.opts.icons = {        ERROR = "[ERROR]",        WARN = "[WARNING]", -      INFO = "[INFo]", +      INFO = "[INFO]",        DEBUG = "[DEBUG]",        TRACE = "[TRACE]",      } @@ -58,7 +58,11 @@ function M.setup()    end    local opts = lvim.builtin.notify and lvim.builtin.notify.opts or defaults -  local notify = require "notify" + +  local status_ok, notify = pcall(require, "notify") +  if not status_ok then +    return +  end    notify.setup(opts)    vim.notify = notify diff --git a/lua/lvim/core/nvimtree.lua b/lua/lvim/core/nvimtree.lua index 15e80e85..199279a6 100644 --- a/lua/lvim/core/nvimtree.lua +++ b/lua/lvim/core/nvimtree.lua @@ -6,34 +6,24 @@ function M.config()      active = true,      on_config_done = nil,      setup = { -      disable_netrw = true, -      hijack_netrw = true, -      open_on_setup = false, -      open_on_setup_file = false, -      sort_by = "name", -      ignore_buffer_on_setup = false,        ignore_ft_on_setup = {          "startify",          "dashboard",          "alpha",        }, -      auto_reload_on_write = true, -      hijack_unnamed_buffer_when_opening = false, +      auto_reload_on_write = false,        hijack_directories = { -        enable = true, -        auto_open = true, +        enable = false,        }, -      open_on_tab = false, -      hijack_cursor = false, -      update_cwd = false, +      update_cwd = true,        diagnostics = {          enable = lvim.use_icons,          show_on_dirs = false,          icons = { -          hint = "", -          info = "", -          warning = "", -          error = "", +          hint = lvim.icons.diagnostics.BoldHint, +          info = lvim.icons.diagnostics.BoldInformation, +          warning = lvim.icons.diagnostics.BoldWarning, +          error = lvim.icons.diagnostics.BoldError,          },        },        update_focused_file = { @@ -52,10 +42,8 @@ function M.config()        },        view = {          width = 30, -        height = 30,          hide_root_folder = false,          side = "left", -        preserve_window_proportions = false,          mappings = {            custom_only = false,            list = {}, @@ -83,27 +71,28 @@ function M.config()              folder_arrow = lvim.use_icons,            },            glyphs = { -            default = "", -            symlink = "", +            default = lvim.icons.ui.Text, +            symlink = lvim.icons.ui.FileSymlink,              git = { -              unstaged = "", -              staged = "S", -              unmerged = "", -              renamed = "➜", -              deleted = "", -              untracked = "U", -              ignored = "◌", +              deleted = lvim.icons.git.FileDeleted, +              ignored = lvim.icons.git.FileIgnored, +              renamed = lvim.icons.git.FileRenamed, +              staged = lvim.icons.git.FileStaged, +              unmerged = lvim.icons.git.FileUnmerged, +              unstaged = lvim.icons.git.FileUnstaged, +              untracked = lvim.icons.git.FileUntracked,              },              folder = { -              default = "", -              open = "", -              empty = "", -              empty_open = "", -              symlink = "", +              default = lvim.icons.ui.Folder, +              empty = lvim.icons.ui.EmptyFolder, +              empty_open = lvim.icons.ui.EmptyFolderOpen, +              open = lvim.icons.ui.FolderOpen, +              symlink = lvim.icons.ui.FolderSymlink,              },            },          },          highlight_git = true, +        group_empty = false,          root_folder_modifier = ":t",        },        filters = { @@ -158,6 +147,24 @@ function M.setup()      return    end +  local status_ok_1, utils = pcall(require, "nvim-tree.utils") +  if not status_ok_1 then +    return +  end + +  local function notify_level() +    return function(msg) +      vim.schedule(function() +        vim.api.nvim_echo({ { msg, "WarningMsg" } }, false, {}) +      end) +    end +  end + +  utils.notify.warn = notify_level(vim.log.levels.WARN) +  utils.notify.error = notify_level(vim.log.levels.ERROR) +  utils.notify.info = notify_level(vim.log.levels.INFO) +  utils.notify.debug = notify_level(vim.log.levels.DEBUG) +    if lvim.builtin.nvimtree._setup_called then      Log:debug "ignoring repeated setup call for nvim-tree, see kyazdani42/nvim-tree.lua#1308"      return diff --git a/lua/lvim/core/project.lua b/lua/lvim/core/project.lua index e33d8720..c3734a16 100644 --- a/lua/lvim/core/project.lua +++ b/lua/lvim/core/project.lua @@ -22,7 +22,7 @@ function M.config()      detection_methods = { "pattern" },      ---@usage patterns used to detect root dir, when **"pattern"** is in detection_methods -    patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json" }, +    patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "pom.xml" },      ---@ Show hidden files in telescope when searching for files in a project      show_hidden = false, diff --git a/lua/lvim/core/telescope.lua b/lua/lvim/core/telescope.lua index f556913b..77bf552d 100644 --- a/lua/lvim/core/telescope.lua +++ b/lua/lvim/core/telescope.lua @@ -1,5 +1,63 @@  local M = {} +local function get_pickers(actions) +  return { +    find_files = { +      theme = "dropdown", +      hidden = true, +      previewer = false, +    }, +    live_grep = { +      --@usage don't include the filename in the search results +      only_sort_text = true, +      theme = "dropdown", +    }, +    grep_string = { +      only_sort_text = true, +      theme = "dropdown", +    }, +    buffers = { +      theme = "dropdown", +      previewer = false, +      initial_mode = "normal", +      mappings = { +        i = { +          ["<C-d>"] = actions.delete_buffer, +        }, +        n = { +          ["dd"] = actions.delete_buffer, +        }, +      }, +    }, +    planets = { +      show_pluto = true, +      show_moon = true, +    }, +    git_files = { +      theme = "dropdown", +      hidden = true, +      previewer = false, +      show_untracked = true, +    }, +    lsp_references = { +      theme = "dropdown", +      initial_mode = "normal", +    }, +    lsp_definitions = { +      theme = "dropdown", +      initial_mode = "normal", +    }, +    lsp_declarations = { +      theme = "dropdown", +      initial_mode = "normal", +    }, +    lsp_implementations = { +      theme = "dropdown", +      initial_mode = "normal", +    }, +  } +end +  function M.config()    -- Define this minimal config so that it's available if telescope is not yet available. @@ -15,8 +73,8 @@ function M.config()    end    lvim.builtin.telescope = vim.tbl_extend("force", lvim.builtin.telescope, {      defaults = { -      prompt_prefix = " ", -      selection_caret = " ", +      prompt_prefix = lvim.icons.ui.Telescope .. " ", +      selection_caret = lvim.icons.ui.Forward .. " ",        entry_prefix = "  ",        initial_mode = "insert",        selection_strategy = "reset", @@ -47,6 +105,7 @@ function M.config()          "--hidden",          "--glob=!.git/",        }, +      ---@usage Mappings are fully customizable. Many familiar mapping patterns are setup as defaults.        mappings = {          i = {            ["<C-n>"] = actions.move_selection_next, @@ -63,23 +122,16 @@ function M.config()            ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,          },        }, +      pickers = get_pickers(actions),        file_ignore_patterns = {}, -      path_display = { shorten = 5 }, +      path_display = { "smart" },        winblend = 0,        border = {},        borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },        color_devicons = true,        set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil,      }, -    pickers = { -      find_files = { -        hidden = true, -      }, -      live_grep = { -        --@usage don't include the filename in the search results -        only_sort_text = true, -      }, -    }, +    pickers = get_pickers(actions),      extensions = {        fzf = {          fuzzy = true, -- false will only do exact matching @@ -94,7 +146,6 @@ end  function M.setup()    local previewers = require "telescope.previewers"    local sorters = require "telescope.sorters" -  local actions = require "telescope.actions"    lvim.builtin.telescope = vim.tbl_extend("keep", {      file_previewer = previewers.vim_buffer_cat.new, @@ -102,23 +153,6 @@ function M.setup()      qflist_previewer = previewers.vim_buffer_qflist.new,      file_sorter = sorters.get_fuzzy_file,      generic_sorter = sorters.get_generic_fuzzy_sorter, -    ---@usage Mappings are fully customizable. Many familiar mapping patterns are setup as defaults. -    mappings = { -      i = { -        ["<C-n>"] = actions.move_selection_next, -        ["<C-p>"] = actions.move_selection_previous, -        ["<C-c>"] = actions.close, -        ["<C-j>"] = actions.cycle_history_next, -        ["<C-k>"] = actions.cycle_history_prev, -        ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist, -        ["<CR>"] = actions.select_default + actions.center, -      }, -      n = { -        ["<C-n>"] = actions.move_selection_next, -        ["<C-p>"] = actions.move_selection_previous, -        ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist, -      }, -    },    }, lvim.builtin.telescope)    local telescope = require "telescope" diff --git a/lua/lvim/core/telescope/custom-finders.lua b/lua/lvim/core/telescope/custom-finders.lua index 69428a44..9ab06326 100644 --- a/lua/lvim/core/telescope/custom-finders.lua +++ b/lua/lvim/core/telescope/custom-finders.lua @@ -88,11 +88,12 @@ end  -- Smartly opens either git_files or find_files, depending on whether the working directory is  -- contained in a Git repo. -function M.find_project_files() -  local ok = pcall(builtin.git_files) +function M.find_project_files(opts) +  opts = opts or {} +  local ok = pcall(builtin.git_files, opts)    if not ok then -    builtin.find_files() +    builtin.find_files(opts)    end  end diff --git a/lua/lvim/core/terminal.lua b/lua/lvim/core/terminal.lua index 6f543d06..006452e1 100644 --- a/lua/lvim/core/terminal.lua +++ b/lua/lvim/core/terminal.lua @@ -3,11 +3,11 @@ local Log = require "lvim.core.log"  M.config = function()    lvim.builtin["terminal"] = { +    active = true,      on_config_done = nil,      -- size can be a number or function which is passed the current terminal      size = 20, -    -- open_mapping = [[<c-\>]], -    open_mapping = [[<c-t>]], +    open_mapping = [[<c-\>]],      hide_numbers = true, -- hide the number column in toggleterm buffers      shade_filetypes = {},      shade_terminals = true, @@ -39,8 +39,11 @@ M.config = function()      -- { exec, keymap, name}      -- lvim.builtin.terminal.execs = {{}} to overwrite      -- lvim.builtin.terminal.execs[#lvim.builtin.terminal.execs+1] = {"gdb", "tg", "GNU Debugger"} +    -- TODO: pls add mappings in which key and refactor this      execs = { -      { "lazygit", "<leader>gg", "LazyGit", "float" }, +      { vim.o.shell, "<M-1>", "Horizontal Terminal", "horizontal", 10 }, +      { vim.o.shell, "<M-2>", "Vertical Terminal", "vertical", 60 }, +      { vim.o.shell, "<M-3>", "Float Terminal", "float", nil },      },    }  end @@ -57,7 +60,7 @@ M.setup = function()        -- NOTE: unable to consistently bind id/count <= 9, see #2146        count = i + 100,        direction = exec[4] or lvim.builtin.terminal.direction, -      size = lvim.builtin.terminal.size, +      size = exec[5] or lvim.builtin.terminal.size,      }      M.add_exec(opts) @@ -76,14 +79,14 @@ M.add_exec = function(opts)    end    vim.keymap.set({ "n", "t" }, opts.keymap, function() -    M._exec_toggle { cmd = opts.cmd, count = opts.count, direction = opts.direction } +    M._exec_toggle { cmd = opts.cmd, count = opts.count, direction = opts.direction, size = opts.size }    end, { desc = opts.label, noremap = true, silent = true })  end  M._exec_toggle = function(opts)    local Terminal = require("toggleterm.terminal").Terminal    local term = Terminal:new { cmd = opts.cmd, count = opts.count, direction = opts.direction } -  term:toggle(lvim.builtin.terminal.size, opts.direction) +  term:toggle(opts.size, opts.direction)  end  ---Toggles a log viewer according to log.viewer.layout_config @@ -109,4 +112,24 @@ M.toggle_log_view = function(logfile)    log_view:toggle()  end +M.lazygit_toggle = function() +  local Terminal = require("toggleterm.terminal").Terminal +  local lazygit = Terminal:new { +    cmd = "lazygit", +    hidden = true, +    direction = "float", +    float_opts = { +      border = "none", +      width = 100000, +      height = 100000, +    }, +    on_open = function(_) +      vim.cmd "startinsert!" +    end, +    on_close = function(_) end, +    count = 99, +  } +  lazygit:toggle() +end +  return M diff --git a/lua/lvim/core/theme.lua b/lua/lvim/core/theme.lua new file mode 100644 index 00000000..0f960d3d --- /dev/null +++ b/lua/lvim/core/theme.lua @@ -0,0 +1,113 @@ +local Log = require "lvim.core.log" + +local M = {} + +M.config = function() +  lvim.builtin.theme = { +    name = "tokyonight", +    options = { +      on_highlights = function(hl, c) +        hl.IndentBlanklineContextChar = { +          fg = c.dark5, +        } +        hl.TSConstructor = { +          fg = c.blue1, +        } +        hl.TSTagDelimiter = { +          fg = c.dark5, +        } +        -- local prompt = "#2d3149" +        -- hl.TelescopeNormal = { +        --   bg = c.bg_dark, +        --   fg = c.fg_dark, +        -- } +        -- hl.TelescopeBorder = { +        --   bg = c.bg_dark, +        --   fg = c.bg_dark, +        -- } +        -- hl.TelescopePromptNormal = { +        --   bg = prompt, +        -- } +        -- hl.TelescopePromptBorder = { +        --   bg = prompt, +        --   fg = prompt, +        -- } +        -- hl.TelescopePromptTitle = { +        --   bg = prompt, +        --   fg = prompt, +        -- } +        -- hl.TelescopePreviewTitle = { +        --   bg = c.bg_dark, +        --   fg = c.bg_dark, +        -- } +        -- hl.TelescopeResultsTitle = { +        --   bg = c.bg_dark, +        --   fg = c.bg_dark, +        -- } +      end, +      style = "night", -- The theme comes in three styles, `storm`, a darker variant `night` and `day` +      transparent = lvim.transparent_window, -- Enable this to disable setting the background color +      terminal_colors = true, -- Configure the colors used when opening a `:terminal` in Neovim +      styles = { +        -- Style to be applied to different syntax groups +        -- Value is any valid attr-list value for `:help nvim_set_hl` +        comments = { italic = true }, +        keywords = { italic = true }, +        functions = {}, +        variables = {}, +        -- Background styles. Can be "dark", "transparent" or "normal" +        sidebars = "dark", -- style for sidebars, see below +        floats = "dark", -- style for floating windows +      }, +      -- Set a darker background on sidebar-like windows. For example: `["qf", "vista_kind", "terminal", "packer"]` +      sidebars = { +        "qf", +        "vista_kind", +        "terminal", +        "packer", +        "spectre_panel", +        "NeogitStatus", +        "help", +      }, +      day_brightness = 0.3, -- Adjusts the brightness of the colors of the **Day** style. Number between 0 and 1, from dull to vibrant colors +      hide_inactive_statusline = false, -- Enabling this option, will hide inactive statuslines and replace them with a thin border instead. Should work with the standard **StatusLine** and **LuaLine**. +      dim_inactive = false, -- dims inactive windows +      lualine_bold = false, -- When `true`, section headers in the lualine theme will be bold +      use_background = true, -- can be light/dark/auto. When auto, background will be set to vim.o.background +    }, +  } +  local status_ok, theme = pcall(require, "tokyonight") +  if not status_ok then +    return +  end + +  theme.setup(lvim.builtin.theme.options) +end + +M.setup = function() +  -- avoid running in headless mode since it's harder to detect failures +  if #vim.api.nvim_list_uis() == 0 then +    Log:debug "headless mode detected, skipping running setup for lualine" +    return +  end + +  local status_ok, theme = pcall(require, "tokyonight") +  if status_ok and theme then +    theme.setup(lvim.builtin.theme.options) +  end + +  -- ref: https://github.com/neovim/neovim/issues/18201#issuecomment-1104754564 +  local colors = vim.api.nvim_get_runtime_file(("colors/%s.*"):format(lvim.colorscheme), false) +  if #colors == 0 then +    Log:warn(string.format("Could not find '%s' colorscheme", lvim.colorscheme)) +    lvim.colorscheme = "tokyonight" +  end + +  vim.g.colors_name = lvim.colorscheme +  vim.cmd("colorscheme " .. lvim.colorscheme) + +  require("lvim.core.lualine").setup() +  require("lvim.core.lir").icon_setup() +end + +return M diff --git a/lua/lvim/core/which-key.lua b/lua/lvim/core/which-key.lua index 2301943f..55e3aae0 100644 --- a/lua/lvim/core/which-key.lua +++ b/lua/lvim/core/which-key.lua @@ -6,8 +6,8 @@ M.config = function()      on_config_done = nil,      setup = {        plugins = { -        marks = true, -- shows a list of your marks on ' and ` -        registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode +        marks = false, -- shows a list of your marks on ' and ` +        registers = false, -- shows your registers on " in NORMAL or <C-r> in INSERT mode          -- the presets plugin, adds help for a bunch of default keybindings in Neovim          -- No actual key bindings are created          presets = { @@ -15,16 +15,16 @@ M.config = function()            motions = false, -- adds help for motions            text_objects = false, -- help for text objects triggered after entering an operator            windows = false, -- default bindings on <c-w> -          nav = true, -- misc bindings to work with windows -          z = true, -- bindings for folds, spelling and others prefixed with z -          g = true, -- bindings for prefixed with g +          nav = false, -- misc bindings to work with windows +          z = false, -- bindings for folds, spelling and others prefixed with z +          g = false, -- bindings for prefixed with g          },          spelling = { enabled = true, suggestions = 20 }, -- use which-key for spelling hints        },        icons = { -        breadcrumb = "»", -- symbol used in the command line area that shows your active key combo -        separator = "➜", -- symbol used between a key and it's label -        group = "+", -- symbol prepended to a group +        breadcrumb = lvim.icons.ui.DoubleChevronRight, -- symbol used in the command line area that shows your active key combo +        separator = lvim.icons.ui.BoldArrowRight, -- symbol used between a key and it's label +        group = lvim.icons.ui.Plus, -- symbol prepended to a group        },        popup_mappings = {          scroll_down = "<c-d>", -- binding to scroll down inside the popup @@ -130,8 +130,9 @@ M.config = function()        -- " Debugging        g = {          name = "Git", -        j = { "<cmd>lua require 'gitsigns'.next_hunk()<cr>", "Next Hunk" }, -        k = { "<cmd>lua require 'gitsigns'.prev_hunk()<cr>", "Prev Hunk" }, +        g = { "<cmd>lua require 'lvim.core.terminal'.lazygit_toggle()<cr>", "Lazygit" }, +        j = { "<cmd>lua require 'gitsigns'.next_hunk({navigation_message = false})<cr>", "Next Hunk" }, +        k = { "<cmd>lua require 'gitsigns'.prev_hunk({navigation_message = false})<cr>", "Prev Hunk" },          l = { "<cmd>lua require 'gitsigns'.blame_line()<cr>", "Blame" },          p = { "<cmd>lua require 'gitsigns'.preview_hunk()<cr>", "Preview Hunk" },          r = { "<cmd>lua require 'gitsigns'.reset_hunk()<cr>", "Reset Hunk" }, @@ -170,12 +171,6 @@ M.config = function()            "Prev Diagnostic",          },          l = { vim.lsp.codelens.run, "CodeLens Action" }, -        p = { -          name = "Peek", -          d = { "<cmd>lua require('lvim.lsp.peek').Peek('definition')<cr>", "Definition" }, -          t = { "<cmd>lua require('lvim.lsp.peek').Peek('typeDefinition')<cr>", "Type Definition" }, -          i = { "<cmd>lua require('lvim.lsp.peek').Peek('implementation')<cr>", "Implementation" }, -        },          q = { vim.diagnostic.setloclist, "Quickfix" },          r = { vim.lsp.buf.rename, "Rename" },          s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" }, diff --git a/lua/lvim/icons.lua b/lua/lvim/icons.lua new file mode 100644 index 00000000..d0f0cf69 --- /dev/null +++ b/lua/lvim/icons.lua @@ -0,0 +1,154 @@ +return { +  kind = { +    Array = "", +    Boolean = "蘒", +    Class = "", +    Color = "", +    Constant = "", +    Constructor = "", +    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 = "", +  }, +  git = { +    LineAdded = "", +    LineModified = "", +    LineRemoved = "", +    FileDeleted = "", +    FileIgnored = "◌", +    FileRenamed = "➜", +    FileStaged = "S", +    FileUnmerged = "", +    FileUnstaged = "", +    FileUntracked = "U", +    Diff = "", +    Repo = "", +    Octoface = "", +    Branch = "", +  }, +  ui = { +    ArrowCircleDown = "", +    ArrowCircleLeft = "", +    ArrowCircleRight = "", +    ArrowCircleUp = "", +    BoldArrowDown = "", +    BoldArrowLeft = "", +    BoldArrowRight = "", +    BoldArrowUp = "", +    BoldClose = "", +    BoldDividerLeft = "", +    BoldDividerRight = "", +    BoldLineLeft = "▎", +    BookMark = "", +    BoxChecked = "", +    Bug = "", +    Stacks = " ", +    Scopes = "", +    Watches = "", +    DebugConsole = " ", +    Calendar = "", +    Check = "", +    ChevronRight = ">", +    ChevronShortDown = "", +    ChevronShortLeft = "", +    ChevronShortRight = "", +    ChevronShortUp = "", +    Circle = "", +    Close = "", +    CloudDownload = "", +    Code = "", +    Comment = "", +    Dashboard = "", +    DividerLeft = "", +    DividerRight = "", +    DoubleChevronRight = "»", +    Ellipsis = "…", +    EmptyFolder = "", +    EmptyFolderOpen = "", +    File = "", +    FileSymlink = "", +    Files = "", +    FindFile = "", +    FindText = "", +    Fire = "", +    Folder = "", +    FolderOpen = "", +    FolderSymlink = "", +    Forward = "", +    Gear = "", +    History = "", +    Lightbulb = "", +    LineLeft = "▏", +    LineMiddle = "│", +    List = "", +    Lock = "", +    NewFile = "", +    Note = "", +    Package = "", +    Pencil = "", +    Plus = "", +    Project = "", +    Search = "", +    SignIn = "", +    SignOut = "", +    Tab = "", +    Table = "", +    Target = "", +    Telescope = "", +    Text = "", +    Tree = "", +    Triangle = "契", +    TriangleShortArrowDown = "", +    TriangleShortArrowLeft = "", +    TriangleShortArrowRight = "", +    TriangleShortArrowUp = "", +  }, +  diagnostics = { +    BoldError = "", +    Error = "", +    BoldWarning = "", +    Warning = "", +    BoldInformation = "", +    Information = "", +    BoldQuestion = "", +    Question = "", +    BoldHint = "", +    Hint = "", +    Debug = "", +    Trace = "✎", +  }, +  misc = { +    Robot = "ﮧ", +    Squirrel = "", +    Tag = "", +    Watch = "", +    Smiley = "ﲃ", +    Package = "", +    CircuitBoard = "", +  }, +} diff --git a/lua/lvim/impatient.lua b/lua/lvim/impatient.lua index fe26b940..beb3862a 100644 --- a/lua/lvim/impatient.lua +++ b/lua/lvim/impatient.lua @@ -1,5 +1,4 @@  -- modified version from https://github.com/lewis6991/impatient.nvim -  local vim = vim  local api = vim.api  local uv = vim.loop @@ -7,66 +6,96 @@ local _loadfile = loadfile  local get_runtime = api.nvim__get_runtime  local fs_stat = uv.fs_stat  local mpack = vim.mpack +local loadlib = package.loadlib + +local std_cache = vim.fn.stdpath "cache" + +local sep +if jit.os == "Windows" then +  sep = "\\" +else +  sep = "/" +end + +local std_dirs = { +  ["<APPDIR>"] = os.getenv "APPDIR", +  ["<VIMRUNTIME>"] = os.getenv "VIMRUNTIME", +  ["<STD_DATA>"] = vim.fn.stdpath "data", +  ["<STD_CONFIG>"] = vim.fn.stdpath "config", +  ["<LVIM_BASE>"] = get_lvim_base_dir(), +  ["<LVIM_RUNTIME>"] = get_runtime_dir(), +  ["<LVIM_CONFIG>"] = get_config_dir(), +} -local appdir = os.getenv "APPDIR" +local function modpath_mangle(modpath) +  for name, dir in pairs(std_dirs) do +    modpath = modpath:gsub(dir, name) +  end +  return modpath +end -local M = { +local function modpath_unmangle(modpath) +  for name, dir in pairs(std_dirs) do +    modpath = modpath:gsub(name, dir) +  end +  return modpath +end + +-- Overridable by user +local default_config = { +  chunks = { +    enable = true, +    path = std_cache .. sep .. "luacache_chunks", +  }, +  modpaths = { +    enable = true, +    path = std_cache .. sep .. "luacache_modpaths", +  }, +} + +-- State used internally +local default_state = {    chunks = {      cache = {},      profile = nil,      dirty = false, -    path = vim.fn.stdpath "cache" .. "/luacache_chunks", +    get = function(self, path) +      return self.cache[modpath_mangle(path)] +    end, +    set = function(self, path, chunk) +      self.cache[modpath_mangle(path)] = chunk +    end,    },    modpaths = {      cache = {},      profile = nil,      dirty = false, -    path = vim.fn.stdpath "cache" .. "/luacache_modpaths", +    get = function(self, mod) +      if self.cache[mod] then +        return modpath_unmangle(self.cache[mod]) +      end +    end, +    set = function(self, mod, path) +      self.cache[mod] = modpath_mangle(path) +    end,    },    log = {},  } +---@diagnostic disable-next-line: undefined-field +local M = vim.tbl_deep_extend("keep", _G.__luacache_config or {}, default_config, default_state)  _G.__luacache = M -if not get_runtime then -  -- nvim 0.5 compat -  get_runtime = function(paths, all, _) -    local r = {} -    for _, path in ipairs(paths) do -      local found = api.nvim_get_runtime_file(path, all) -      for i = 1, #found do -        r[#r + 1] = found[i] -      end -    end -    return r -  end -end -  local function log(...)    M.log[#M.log + 1] = table.concat({ string.format(...) }, " ")  end -function M.print_log() +local function print_log()    for _, l in ipairs(M.log) do      print(l)    end  end -function M.enable_profile() -  local P = require "lvim.impatient.profile" - -  M.chunks.profile = {} -  M.modpaths.profile = {} - -  P.setup(M.modpaths.profile) - -  M.print_profile = function() -    P.print_profile(M) -  end - -  vim.cmd [[command! LuaCacheProfile lua _G.__luacache.print_profile()]] -end -  local function hash(modpath)    local stat = fs_stat(modpath)    if stat then @@ -75,20 +104,6 @@ local function hash(modpath)    error("Could not hash " .. modpath)  end -local function modpath_mangle(modpath) -  if appdir then -    modpath = modpath:gsub(appdir, "/$APPDIR") -  end -  return modpath -end - -local function modpath_unmangle(modpath) -  if appdir then -    modpath = modpath:gsub("/$APPDIR", appdir) -  end -  return modpath -end -  local function profile(m, entry, name, loader)    if m.profile then      local mp = m.profile @@ -107,18 +122,41 @@ local function mprofile(mod, name, loader)  end  local function cprofile(path, name, loader) +  if M.chunks.profile then +    path = modpath_mangle(path) +  end    profile(M.chunks, path, name, loader)  end -local function get_runtime_file(basename, paths) +function M.enable_profile() +  local P = require "lvim.impatient.profile" + +  M.chunks.profile = {} +  M.modpaths.profile = {} + +  loadlib = function(path, fun) +    cprofile(path, "load_start") +    local f, err = package.loadlib(path, fun) +    cprofile(path, "load_end", "standard") +    return f, err +  end + +  P.setup(M.modpaths.profile) + +  api.nvim_create_user_command("LuaCacheProfile", function() +    P.print_profile(M, std_dirs) +  end, {}) +end + +local function get_runtime_file_from_parent(basename, paths)    -- Look in the cache to see if we have already loaded a parent module.    -- If we have then try looking in the parents directory first. -  local parents = vim.split(basename, "/") +  local parents = vim.split(basename, sep)    for i = #parents, 1, -1 do -    local parent = table.concat(vim.list_slice(parents, 1, i), "/") -    local ppath = M.modpaths.cache[parent] +    local parent = table.concat(vim.list_slice(parents, 1, i), sep) +    local ppath = M.modpaths:get(parent)      if ppath then -      if ppath:sub(-9) == "/init.lua" then +      if ppath:sub(-9) == (sep .. "init.lua") then          ppath = ppath:sub(1, -10) -- a/b/init.lua -> a/b        else          ppath = ppath:sub(1, -5) -- a/b.lua -> a/b @@ -126,38 +164,71 @@ local function get_runtime_file(basename, paths)        for _, path in ipairs(paths) do          -- path should be of form 'a/b/c.lua' or 'a/b/c/init.lua' -        local modpath = ppath .. "/" .. path:sub(#("lua/" .. parent) + 2) +        local modpath = ppath .. sep .. path:sub(#("lua" .. sep .. parent) + 2)          if fs_stat(modpath) then            return modpath, "cache(p)"          end        end      end    end +end + +local rtp = vim.split(vim.o.rtp, ",") -  -- What Neovim does by default; slowest -  local modpath = get_runtime(paths, false, { is_lua = true })[1] -  return modpath, "standard" +-- Make sure modpath is in rtp and that modpath is in paths. +local function validate_modpath(modpath, paths) +  local match = false +  for _, p in ipairs(paths) do +    if vim.endswith(modpath, p) then +      match = true +      break +    end +  end +  if not match then +    return false +  end +  for _, dir in ipairs(rtp) do +    if vim.startswith(modpath, dir) then +      return fs_stat(modpath) ~= nil +    end +  end +  return false  end  local function get_runtime_file_cached(basename, paths) +  local modpath, loader    local mp = M.modpaths -  if mp.cache[basename] then -    local modpath = mp.cache[basename] -    if fs_stat(modpath) then -      mprofile(basename, "resolve_end", "cache") -      return modpath +  if mp.enable then +    local modpath_cached = mp:get(basename) +    if modpath_cached then +      modpath, loader = modpath_cached, "cache" +    else +      modpath, loader = get_runtime_file_from_parent(basename, paths) +    end + +    if modpath and not validate_modpath(modpath, paths) then +      modpath = nil + +      -- Invalidate +      mp.cache[basename] = nil +      mp.dirty = true      end -    mp.cache[basename] = nil -    mp.dirty = true    end -  local modpath, loader = get_runtime_file(basename, paths) +  if not modpath then +    -- What Neovim does by default; slowest +    modpath, loader = get_runtime(paths, false, { is_lua = true })[1], "standard" +  end +    if modpath then      mprofile(basename, "resolve_end", loader) -    log("Creating cache for module %s", basename) -    mp.cache[basename] = modpath_mangle(modpath) -    mp.dirty = true +    if mp.enable and loader ~= "cache" then +      log("Creating cache for module %s", basename) +      mp:set(basename, modpath) +      mp.dirty = true +    end    end +    return modpath  end @@ -168,8 +239,12 @@ local function extract_basename(pats)    for _, pat in ipairs(pats) do      for i, npat in ipairs {        -- Ordered by most specific -      "lua/(.*)/init%.lua", -      "lua/(.*)%.lua", +      "lua" +        .. sep +        .. "(.*)" +        .. sep +        .. "init%.lua", +      "lua" .. sep .. "(.*)%.lua",      } do        local m = pat:match(npat)        if i == 2 and m and m:sub(-4) == "init" then @@ -211,8 +286,8 @@ end  -- Copied from neovim/src/nvim/lua/vim.lua with two lines changed  local function load_package(name) -  local basename = name:gsub("%.", "/") -  local paths = { "lua/" .. basename .. ".lua", "lua/" .. basename .. "/init.lua" } +  local basename = name:gsub("%.", sep) +  local paths = { "lua" .. sep .. basename .. ".lua", "lua" .. sep .. basename .. sep .. "init.lua" }    -- Original line:    -- local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true}) @@ -239,7 +314,7 @@ local function load_package(name)      -- So "foo-bar.baz" should result in "luaopen_bar_baz"      local dash = name:find("-", 1, true)      local modname = dash and name:sub(dash + 1) or name -    local f, err = package.loadlib(found[1], "luaopen_" .. modname:gsub("%.", "_")) +    local f, err = loadlib(found[1], "luaopen_" .. modname:gsub("%.", "_"))      return f or error(err)    end    return nil @@ -248,14 +323,16 @@ end  local function load_from_cache(path)    local mc = M.chunks -  if not mc.cache[path] then +  local cache = mc:get(path) + +  if not cache then      return nil, string.format("No cache for path %s", path)    end -  local mhash, codes = unpack(mc.cache[path]) +  local mhash, codes = unpack(cache) -  if mhash ~= hash(modpath_unmangle(path)) then -    mc.cache[path] = nil +  if mhash ~= hash(path) then +    mc:set(path)      mc.dirty = true      return nil, string.format("Stale cache for path %s", path)    end @@ -263,7 +340,7 @@ local function load_from_cache(path)    local chunk = loadstring(codes)    if not chunk then -    mc.cache[path] = nil +    mc:set(path)      mc.dirty = true      return nil, string.format("Cache error for path %s", path)    end @@ -274,19 +351,23 @@ end  local function loadfile_cached(path)    cprofile(path, "load_start") -  local chunk, err = load_from_cache(path) -  if chunk and not err then -    log("Loaded cache for path %s", path) -    cprofile(path, "load_end", "cache") -    return chunk +  local chunk, err + +  if M.chunks.enable then +    chunk, err = load_from_cache(path) +    if chunk and not err then +      log("Loaded cache for path %s", path) +      cprofile(path, "load_end", "cache") +      return chunk +    end +    log(err)    end -  log(err)    chunk, err = _loadfile(path) -  if not err then +  if not err and M.chunks.enable then      log("Creating cache for path %s", path) -    M.chunks.cache[modpath_mangle(path)] = { hash(path), string.dump(chunk) } +    M.chunks:set(path, { hash(path), string.dump(chunk) })      M.chunks.dirty = true    end @@ -296,9 +377,12 @@ end  function M.save_cache()    local function _save_cache(t) +    if not t.enable then +      return +    end      if t.dirty then        log("Updating chunk cache file: %s", t.path) -      local f = io.open(t.path, "w+b") +      local f = assert(io.open(t.path, "w+b"))        f:write(mpack.encode(t.cache))        f:flush()        t.dirty = false @@ -308,7 +392,7 @@ function M.save_cache()    _save_cache(M.modpaths)  end -function M.clear_cache() +local function clear_cache()    local function _clear_cache(t)      t.cache = {}      os.remove(t.path) @@ -319,9 +403,12 @@ end  local function init_cache()    local function _init_cache(t) +    if not t.enable then +      return +    end      if fs_stat(t.path) then        log("Loading cache file %s", t.path) -      local f = io.open(t.path, "rb") +      local f = assert(io.open(t.path, "rb"))        local ok        ok, t.cache = pcall(function()          return mpack.decode(f:read "*a") @@ -336,6 +423,10 @@ local function init_cache()      end    end +  if not uv.fs_stat(std_cache) then +    vim.fn.mkdir(std_cache, "p") +  end +    _init_cache(M.chunks)    _init_cache(M.modpaths)  end @@ -343,20 +434,42 @@ end  local function setup()    init_cache() +  -- Usual package loaders +  -- 1. package.preload +  -- 2. vim._load_package +  -- 3. package.path +  -- 4. package.cpath +  -- 5. all-in-one +    -- Override default functions +  for i, loader in ipairs(package.loaders) do +    if loader == vim._load_package then +      package.loaders[i] = load_package +      break +    end +  end    vim._load_package = load_package +    vim.api.nvim__get_runtime = get_runtime_cached -  -- luacheck: ignore 121    loadfile = loadfile_cached -  vim.cmd [[ -    augroup impatient -      autocmd VimEnter,VimLeave * lua _G.__luacache.save_cache() -    augroup END +  local augroup = api.nvim_create_augroup("impatient", {}) + +  api.nvim_create_user_command("LuaCacheClear", clear_cache, {}) +  api.nvim_create_user_command("LuaCacheLog", print_log, {}) + +  api.nvim_create_autocmd({ "VimEnter", "VimLeave" }, { +    group = augroup, +    callback = M.save_cache, +  }) -    command! LuaCacheClear lua _G.__luacache.clear_cache() -    command! LuaCacheLog   lua _G.__luacache.print_log() -  ]] +  api.nvim_create_autocmd("OptionSet", { +    group = augroup, +    pattern = "runtimepath", +    callback = function() +      rtp = vim.split(vim.o.rtp, ",") +    end, +  })  end  setup() diff --git a/lua/lvim/impatient/profile.lua b/lua/lvim/impatient/profile.lua index 0ab04d65..2eafbbf2 100644 --- a/lua/lvim/impatient/profile.lua +++ b/lua/lvim/impatient/profile.lua @@ -1,12 +1,13 @@  local M = {} -local api, uv = vim.api, vim.loop +local sep +if jit.os == "Windows" then +  sep = "\\" +else +  sep = "/" +end -local std_data = vim.fn.stdpath "data" -local std_config = vim.fn.stdpath "config" -local vimruntime = os.getenv "VIMRUNTIME" -local lvim_runtime = get_runtime_dir() -local lvim_config = get_config_dir() +local api, uv = vim.api, vim.loop  local function load_buffer(title, lines)    local bufnr = api.nvim_create_buf(false, false) @@ -19,19 +20,6 @@ local function load_buffer(title, lines)    api.nvim_set_current_buf(bufnr)  end -local function mod_path(path) -  if not path then -    return "?" -  end -  path = path:gsub(std_data .. "/site/pack/packer/", "<PACKER>/") -  path = path:gsub(std_data .. "/", "<STD_DATA>/") -  path = path:gsub(std_config .. "/", "<STD_CONFIG>/") -  path = path:gsub(vimruntime .. "/", "<VIMRUNTIME>/") -  path = path:gsub(lvim_runtime .. "/", "<LVIM_RUNTIME>/") -  path = path:gsub(lvim_config .. "/", "<LVIM_CONFIG>/") -  return path -end -  local function time_tostr(x)    if x == 0 then      return "?" @@ -51,7 +39,7 @@ local function mem_tostr(x)    return string.format("%1.1f%s", x, unit)  end -function M.print_profile(I) +function M.print_profile(I, std_dirs)    local mod_profile = I.modpaths.profile    local chunk_profile = I.chunks.profile @@ -67,42 +55,50 @@ function M.print_profile(I)    for path, m in pairs(chunk_profile) do      m.load = m.load_end - m.load_start      m.load = m.load / 1000000 -    m.path = mod_path(path) +    m.path = path or "?"    end    local module_content_width = 0 +  local unloaded = {} +    for module, m in pairs(mod_profile) do -    m.resolve = 0 -    if m.resolve_end then -      m.resolve = m.resolve_end - m.resolve_start -      m.resolve = m.resolve / 1000000 -    end +    local module_dot = module:gsub(sep, ".") +    m.module = module_dot -    m.module = module:gsub("/", ".") -    m.loader = m.loader or m.loader_guess +    if not package.loaded[module_dot] and not package.loaded[module] then +      unloaded[#unloaded + 1] = m +    else +      m.resolve = 0 +      if m.resolve_start and m.resolve_end then +        m.resolve = m.resolve_end - m.resolve_start +        m.resolve = m.resolve / 1000000 +      end -    local path = I.modpaths.cache[module] -    local path_prof = chunk_profile[path] -    m.path = mod_path(path) +      m.loader = m.loader or m.loader_guess -    if path_prof then -      chunk_profile[path] = nil -      m.load = path_prof.load -      m.ploader = path_prof.loader -    else -      m.load = 0 -      m.ploader = "NA" -    end +      local path = I.modpaths.cache[module] +      local path_prof = chunk_profile[path] +      m.path = path or "?" -    total_resolve = total_resolve + m.resolve -    total_load = total_load + m.load +      if path_prof then +        chunk_profile[path] = nil +        m.load = path_prof.load +        m.ploader = path_prof.loader +      else +        m.load = 0 +        m.ploader = "NA" +      end -    if #module > module_content_width then -      module_content_width = #module -    end +      total_resolve = total_resolve + m.resolve +      total_load = total_load + m.load + +      if #module > module_content_width then +        module_content_width = #module +      end -    modules[#modules + 1] = m +      modules[#modules + 1] = m +    end    end    table.sort(modules, function(a, b) @@ -181,6 +177,12 @@ function M.print_profile(I)    end    add "" +  add "Standard directories:" +  for alias, path in pairs(std_dirs) do +    add("  %-12s -> %s", alias, path) +  end +  add "" +    add("%s─%s┬%s─%s┐", tcwl, lcwl, tcwl, lcwl)    add(title1_fmt, "Resolve", "Load")    add("%s┬%s┼%s┬%s┼%s┬%s", tcwl, lcwl, tcwl, lcwl, mcwl, n) @@ -207,7 +209,17 @@ function M.print_profile(I)        add(f3, p.load, p.loader, p.path)      end      add("%s┴%s┴%s", tcwl, lcwl, n) +  end + +  if #unloaded > 0 then      add "" +    add(n) +    add "Modules which were unable to loaded" +    add(n) +    for _, p in ipairs(unloaded) do +      lines[#lines + 1] = p.module +    end +    add(n)    end    load_buffer("Impatient Profile Report", lines) @@ -216,13 +228,12 @@ end  M.setup = function(profile)    local _require = require -  -- luacheck: ignore 121    require = function(mod) -    local basename = mod:gsub("%.", "/") +    local basename = mod:gsub("%.", sep)      if not profile[basename] then        profile[basename] = {}        profile[basename].resolve_start = uv.hrtime() -      profile[basename].loader_guess = "C" +      profile[basename].loader_guess = ""      end      return _require(mod)    end @@ -232,7 +243,7 @@ M.setup = function(profile)    for i = 1, #pl do      local l = pl[i]      pl[i] = function(mod) -      local basename = mod:gsub("%.", "/") +      local basename = mod:gsub("%.", sep)        profile[basename].loader_guess = i == 1 and "preloader" or "loader #" .. i        return l(mod)      end diff --git a/lua/lvim/keymappings.lua b/lua/lvim/keymappings.lua index 82113398..d0d46fd7 100644 --- a/lua/lvim/keymappings.lua +++ b/lua/lvim/keymappings.lua @@ -31,12 +31,6 @@ local mode_adapters = {  local defaults = {    insert_mode = { -    -- 'jk' for quitting insert mode -    ["jk"] = "<ESC>", -    -- 'kj' for quitting insert mode -    ["kj"] = "<ESC>", -    -- 'jj' for quitting insert mode -    ["jj"] = "<ESC>",      -- Move current line / block with Alt-j/k ala vscode.      ["<A-j>"] = "<Esc>:m .+1<CR>==gi",      -- Move current line / block with Alt-j/k ala vscode. @@ -89,10 +83,6 @@ local defaults = {    },    visual_block_mode = { -    -- Move selected line / block of text in visual mode -    ["K"] = ":move '<-2<CR>gv-gv", -    ["J"] = ":move '>+1<CR>gv-gv", -      -- Move current line / block with Alt-j/k ala vscode.      ["<A-j>"] = ":m '>+1<CR>gv-gv",      ["<A-k>"] = ":m '<-2<CR>gv-gv", diff --git a/lua/lvim/lsp/config.lua b/lua/lvim/lsp/config.lua index 96a1b823..358e83f8 100644 --- a/lua/lvim/lsp/config.lua +++ b/lua/lvim/lsp/config.lua @@ -10,6 +10,7 @@ local skipped_servers = {    "eslint",    "eslintls",    "golangci_lint_ls", +  "gradle_ls",    "graphql",    "jedi_language_server",    "ltex", @@ -18,10 +19,12 @@ local skipped_servers = {    "psalm",    "pylsp",    "quick_lint_js", -  "rome",    "reason_ls", +  "rome", +  "ruby_ls",    "scry",    "solang", +  "solc",    "solidity_ls",    "sorbet",    "sourcekit", @@ -30,8 +33,8 @@ local skipped_servers = {    "sqlls",    "sqls",    "stylelint_lsp", -  "tflint",    "svlangserver", +  "tflint",    "verible",    "vuels",  } @@ -46,10 +49,10 @@ return {      signs = {        active = true,        values = { -        { name = "DiagnosticSignError", text = "" }, -        { name = "DiagnosticSignWarn", text = "" }, -        { name = "DiagnosticSignHint", text = "" }, -        { name = "DiagnosticSignInfo", text = "" }, +        { name = "DiagnosticSignError", text = lvim.icons.diagnostics.Error }, +        { name = "DiagnosticSignWarn", text = lvim.icons.diagnostics.Warning }, +        { name = "DiagnosticSignHint", text = lvim.icons.diagnostics.Hint }, +        { name = "DiagnosticSignInfo", text = lvim.icons.diagnostics.Info },        },      },      virtual_text = true, @@ -72,18 +75,13 @@ return {        end,      },    }, -  document_highlight = true, +  document_highlight = false,    code_lens_refresh = true,    float = {      focusable = true,      style = "minimal",      border = "rounded",    }, -  peek = { -    max_height = 15, -    max_width = 30, -    context = 10, -  },    on_attach_callback = nil,    on_init_callback = nil,    automatic_configuration = { @@ -100,12 +98,6 @@ return {        ["gr"] = { vim.lsp.buf.references, "Goto references" },        ["gI"] = { vim.lsp.buf.implementation, "Goto Implementation" },        ["gs"] = { vim.lsp.buf.signature_help, "show signature help" }, -      ["gp"] = { -        function() -          require("lvim.lsp.peek").Peek "definition" -        end, -        "Peek definition", -      },        ["gl"] = {          function()            local config = lvim.lsp.diagnostics.float @@ -143,7 +135,9 @@ return {      },    },    null_ls = { -    setup = {}, +    setup = { +      debug = false, +    },      config = {},    },    ---@deprecated use lvim.lsp.automatic_configuration.skipped_servers instead diff --git a/lua/lvim/lsp/init.lua b/lua/lvim/lsp/init.lua index 0b361972..c8a2b22f 100644 --- a/lua/lvim/lsp/init.lua +++ b/lua/lvim/lsp/init.lua @@ -25,6 +25,11 @@ local function add_lsp_buffer_keybindings(bufnr)  end  function M.common_capabilities() +  local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") +  if status_ok then +    return cmp_nvim_lsp.default_capabilities() +  end +    local capabilities = vim.lsp.protocol.make_client_capabilities()    capabilities.textDocument.completion.completionItem.snippetSupport = true    capabilities.textDocument.completion.completionItem.resolveSupport = { @@ -35,11 +40,6 @@ function M.common_capabilities()      },    } -  local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") -  if status_ok then -    capabilities = cmp_nvim_lsp.update_capabilities(capabilities) -  end -    return capabilities  end @@ -74,6 +74,7 @@ function M.common_on_attach(client, bufnr)    end    add_lsp_buffer_keybindings(bufnr)    add_lsp_buffer_options(bufnr) +  lu.setup_document_symbols(client, bufnr)  end  function M.get_common_opts() diff --git a/lua/lvim/lsp/peek.lua b/lua/lvim/lsp/peek.lua deleted file mode 100644 index 65c67e92..00000000 --- a/lua/lvim/lsp/peek.lua +++ /dev/null @@ -1,157 +0,0 @@ -local M = { -  floating_buf = nil, -  floating_win = nil, -  prev_result = nil, -} - -local function create_floating_file(location, opts) -  vim.validate { -    location = { location, "t" }, -    opts = { opts, "t", true }, -  } - -  -- Set some defaults -  opts = opts or {} -  local close_events = opts.close_events or { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" } - -  -- location may be LocationLink or Location -  local uri = location.targetUri or location.uri -  if uri == nil then -    return -  end -  local bufnr = vim.uri_to_bufnr(uri) -  if not vim.api.nvim_buf_is_loaded(bufnr) then -    vim.fn.bufload(bufnr) -  end - -  local range = location.targetRange or location.range - -  local contents = vim.api.nvim_buf_get_lines( -    bufnr, -    range.start.line, -    math.min( -      range["end"].line + 1 + (opts.context or lvim.lsp.peek.max_height), -      range.start.line + (opts.max_height or lvim.lsp.peek.max_height) -    ), -    false -  ) -  if next(contents) == nil then -    vim.notify("peek: Unable to get contents of the file!", vim.log.levels.WARN) -    return -  end -  local width, height = vim.lsp.util._make_floating_popup_size(contents, opts) -  local if_nil = vim.F.if_nil -  opts = vim.lsp.util.make_floating_popup_options( -    if_nil(width, lvim.lsp.peek.max_width), -    if_nil(height, lvim.lsp.peek.max_height), -    opts -  ) -  -- Don't make it minimal as it is meant to be fully featured -  opts["style"] = nil - -  vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe") - -  local winnr = vim.api.nvim_open_win(bufnr, false, opts) -  vim.api.nvim_win_set_option(winnr, "winblend", 0) - -  vim.api.nvim_win_set_cursor(winnr, { range.start.line + 1, range.start.character }) -  vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr) - -  -- Set some autocmds to close the window -  vim.api.nvim_command( -    string.format("autocmd %s <buffer> ++once lua pcall(vim.api.nvim_win_close, %d, true)", unpack(close_events), winnr) -  ) - -  return bufnr, winnr -end - -local function preview_location_callback(result) -  if result == nil or vim.tbl_isempty(result) then -    return nil -  end - -  local opts = { -    border = "rounded", -    context = lvim.lsp.peek.context, -  } - -  if vim.tbl_islist(result) then -    M.prev_result = result[1] -    M.floating_buf, M.floating_win = create_floating_file(result[1], opts) -  else -    M.prev_result = result -    M.floating_buf, M.floating_win = create_floating_file(result, opts) -  end -end - -local function preview_location_callback_new_signature(_, result) -  return preview_location_callback(result) -end - -function M.open_file() -  -- Get the file currently open in the floating window -  local filepath = vim.fn.expand "%:." - -  if not filepath then -    vim.notify("peek: Unable to open the file!", vim.log.levels.ERROR) -    return -  end - -  -- Close the floating window -  pcall(vim.api.nvim_win_close, M.floating_win, true) - -  -- Edit the file -  vim.cmd("edit " .. filepath) - -  local winnr = vim.api.nvim_get_current_win() - -  -- Set the cursor at the right position -  M.set_cursor_to_prev_pos(winnr) -end - -function M.set_cursor_to_prev_pos(winnr) -  -- Get position of the thing to peek at -  local location = M.prev_result -  local range = location.targetRange or location.range -  local cursor_pos = { range.start.line + 1, range.start.character } - -  -- Set the winnr to the floating window if none was passed in -  winnr = winnr or M.floating_win -  -- Set the cursor at the correct position in the floating window -  vim.api.nvim_win_set_cursor(winnr, cursor_pos) -end - -function M.Peek(what) -  -- If a window already exists, focus it at the right position! -  if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then -    local success_1, _ = pcall(vim.api.nvim_set_current_win, M.floating_win) -    if not success_1 then -      vim.notify("peek: You cannot edit the current file in a preview!", vim.log.levels.ERROR) -      return -    end - -    -- Set the cursor at the correct position in the floating window -    M.set_cursor_to_prev_pos() - -    vim.api.nvim_buf_set_keymap( -      M.floating_buf, -      "n", -      "<CR>", -      ":lua require('lvim.lsp.peek').open_file()<CR>", -      { noremap = true, silent = true } -    ) -  else -    -- Make a new request and then create the new window in the callback -    local params = vim.lsp.util.make_position_params() -    local preview_callback = preview_location_callback_new_signature -    local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback) -    if not success then -      vim.notify( -        'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.', -        vim.log.levels.ERROR -      ) -    end -  end -end - -return M diff --git a/lua/lvim/lsp/providers/sumneko_lua.lua b/lua/lvim/lsp/providers/sumneko_lua.lua index 6cd78157..2caa23b6 100644 --- a/lua/lvim/lsp/providers/sumneko_lua.lua +++ b/lua/lvim/lsp/providers/sumneko_lua.lua @@ -1,32 +1,59 @@ -local dev_opts = { +local default_workspace = {    library = { -    vimruntime = true, -- runtime path -    types = true, -- full signature, docs and completion of vim.api, vim.treesitter, vim.lsp and others -    -- plugins = true, -- installed opt or start plugins in packpath -    -- you can also specify the list of plugins to make available as a workspace library -    plugins = { "plenary.nvim" }, +    vim.fn.expand "$VIMRUNTIME", +    get_lvim_base_dir(), +    require("neodev.config").types(),    }, -  override = nil, -- function(root_dir, options) end, + +  maxPreload = 5000, +  preloadFileSize = 10000,  } -local lua_dev_loaded, lua_dev = pcall(require, "lua-dev") -if lua_dev_loaded then -  lua_dev.setup(dev_opts) +local add_packages_to_workspace = function(packages, config) +  -- config.settings.Lua = config.settings.Lua or { workspace = default_workspace } +  local runtimedirs = vim.api.nvim__get_runtime({ "lua" }, true, { is_lua = true }) +  local workspace = config.settings.Lua.workspace +  for _, v in pairs(runtimedirs) do +    for _, pack in ipairs(packages) do +      if v:match(pack) and not vim.tbl_contains(workspace.library, v) then +        table.insert(workspace.library, v) +      end +    end +  end +end + +local lspconfig = require "lspconfig" + +local make_on_new_config = function(on_new_config, _) +  return lspconfig.util.add_hook_before(on_new_config, function(new_config, _) +    local server_name = new_config.name + +    if server_name ~= "sumneko_lua" then +      return +    end +    local plugins = { "plenary.nvim", "telescope.nvim", "nvim-treesitter", "LuaSnip" } +    add_packages_to_workspace(plugins, new_config) +  end)  end +lspconfig.util.default_config = vim.tbl_extend("force", lspconfig.util.default_config, { +  on_new_config = make_on_new_config(lspconfig.util.default_config.on_new_config), +}) +  local opts = {    settings = {      Lua = { -      diagnostics = { -        globals = { "vim", "lvim", "packer_plugins" }, -      }, -      workspace = { -        library = { -          [require("lvim.utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true, +      telemetry = { enable = false }, +      runtime = { +        version = "LuaJIT", +        special = { +          reload = "require",          }, -        maxPreload = 100000, -        preloadFileSize = 10000,        }, +      diagnostics = { +        globals = { "vim", "lvim", "packer_plugins", "reload" }, +      }, +      workspace = default_workspace,      },    },  } diff --git a/lua/lvim/lsp/utils.lua b/lua/lvim/lsp/utils.lua index b92ef11c..44e4f5f7 100644 --- a/lua/lvim/lsp/utils.lua +++ b/lua/lvim/lsp/utils.lua @@ -1,6 +1,7 @@  local M = {}  local tbl = require "lvim.utils.table" +local Log = require "lvim.core.log"  function M.is_client_active(name)    local clients = vim.lsp.get_active_clients() @@ -22,25 +23,14 @@ function M.get_active_clients_by_ft(filetype)  end  function M.get_client_capabilities(client_id) -  local client -  if not client_id then -    local buf_clients = vim.lsp.buf_get_clients() -    for _, buf_client in pairs(buf_clients) do -      if buf_client.name ~= "null-ls" then -        client = buf_client -        break -      end -    end -  else -    client = vim.lsp.get_client_by_id(tonumber(client_id)) -  end +  local client = vim.lsp.get_client_by_id(tonumber(client_id))    if not client then -    error "Unable to determine client_id" +    Log:warn("Unable to determine client from client_id: " .. client_id)      return    end    local enabled_caps = {} -  for capability, status in pairs(client.server_capabilities or client.resolved_capabilities) do +  for capability, status in pairs(client.server_capabilities) do      if status == true then        table.insert(enabled_caps, capability)      end @@ -82,30 +72,55 @@ function M.get_all_supported_filetypes()  end  function M.setup_document_highlight(client, bufnr) +  if lvim.builtin.illuminate.active then +    Log:debug "skipping setup for document_highlight, illuminate already active" +    return +  end    local status_ok, highlight_supported = pcall(function()      return client.supports_method "textDocument/documentHighlight"    end)    if not status_ok or not highlight_supported then      return    end -  local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, { -    group = "lsp_document_highlight", +  local group = "lsp_document_highlight" +  local hl_events = { "CursorHold", "CursorHoldI" } + +  local ok, hl_autocmds = pcall(vim.api.nvim_get_autocmds, { +    group = group, +    buffer = bufnr, +    event = hl_events,    }) -  if not augroup_exist then -    vim.api.nvim_create_augroup("lsp_document_highlight", {}) + +  if ok and #hl_autocmds > 0 then +    return    end -  vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { -    group = "lsp_document_highlight", + +  vim.api.nvim_create_augroup(group, { clear = false }) +  vim.api.nvim_create_autocmd(hl_events, { +    group = group,      buffer = bufnr,      callback = vim.lsp.buf.document_highlight,    })    vim.api.nvim_create_autocmd("CursorMoved", { -    group = "lsp_document_highlight", +    group = group,      buffer = bufnr,      callback = vim.lsp.buf.clear_references,    })  end +function M.setup_document_symbols(client, bufnr) +  vim.g.navic_silence = false -- can be set to true to suppress error +  local symbols_supported = client.supports_method "textDocument/documentSymbol" +  if not symbols_supported then +    Log:debug("skipping setup for document_symbols, method not supported by " .. client.name) +    return +  end +  local status_ok, navic = pcall(require, "nvim-navic") +  if status_ok then +    navic.attach(client, bufnr) +  end +end +  function M.setup_codelens_refresh(client, bufnr)    local status_ok, codelens_supported = pcall(function()      return client.supports_method "textDocument/codeLens" @@ -113,14 +128,20 @@ function M.setup_codelens_refresh(client, bufnr)    if not status_ok or not codelens_supported then      return    end -  local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, { -    group = "lsp_code_lens_refresh", +  local group = "lsp_code_lens_refresh" +  local cl_events = { "BufEnter", "InsertLeave" } +  local ok, cl_autocmds = pcall(vim.api.nvim_get_autocmds, { +    group = group, +    buffer = bufnr, +    event = cl_events,    }) -  if not augroup_exist then -    vim.api.nvim_create_augroup("lsp_code_lens_refresh", {}) + +  if ok and #cl_autocmds > 0 then +    return    end -  vim.api.nvim_create_autocmd({ "BufEnter", "InsertLeave" }, { -    group = "lsp_code_lens_refresh", +  vim.api.nvim_create_augroup(group, { clear = false }) +  vim.api.nvim_create_autocmd(cl_events, { +    group = group,      buffer = bufnr,      callback = vim.lsp.codelens.refresh,    }) @@ -135,9 +156,9 @@ function M.format_filter(client)    local n = require "null-ls"    local s = require "null-ls.sources"    local method = n.methods.FORMATTING -  local avalable_formatters = s.get_available(filetype, method) +  local available_formatters = s.get_available(filetype, method) -  if #avalable_formatters > 0 then +  if #available_formatters > 0 then      return client.name == "null-ls"    elseif client.supports_method "textDocument/formatting" then      return true @@ -146,47 +167,13 @@ function M.format_filter(client)    end  end ----Provide vim.lsp.buf.format for nvim <0.8 ----@param opts table +---Simple wrapper for vim.lsp.buf.format() to provide defaults +---@param opts table|nil  function M.format(opts)    opts = opts or {}    opts.filter = opts.filter or M.format_filter -  if vim.lsp.buf.format then -    return vim.lsp.buf.format(opts) -  end - -  local bufnr = opts.bufnr or vim.api.nvim_get_current_buf() - -  ---@type table|nil -  local clients = vim.lsp.get_active_clients { -    id = opts.id, -    bufnr = bufnr, -    name = opts.name, -  } - -  if opts.filter then -    clients = vim.tbl_filter(opts.filter, clients) -  end - -  clients = vim.tbl_filter(function(client) -    return client.supports_method "textDocument/formatting" -  end, clients) - -  if #clients == 0 then -    vim.notify_once "[LSP] Format request failed, no matching language servers." -  end - -  local timeout_ms = opts.timeout_ms or 1000 -  for _, client in pairs(clients) do -    local params = vim.lsp.util.make_formatting_params(opts.formatting_options) -    local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr) -    if result and result.result then -      vim.lsp.util.apply_text_edits(result.result, bufnr, client.offset_encoding) -    elseif err then -      vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN) -    end -  end +  return vim.lsp.buf.format(opts)  end  return M diff --git a/lua/lvim/plugin-loader.lua b/lua/lvim/plugin-loader.lua index c10fe75e..f6cb4651 100644 --- a/lua/lvim/plugin-loader.lua +++ b/lua/lvim/plugin-loader.lua @@ -16,14 +16,19 @@ function plugin_loader.init(opts)    local install_path = opts.install_path      or join_paths(vim.fn.stdpath "data", "site", "pack", "packer", "start", "packer.nvim") +  local max_jobs = 100 +  if vim.fn.has "mac" == 1 then +    max_jobs = 50 +  end +    local init_opts = {      package_root = opts.package_root or join_paths(vim.fn.stdpath "data", "site", "pack"),      compile_path = compile_path,      snapshot_path = snapshot_path, -    max_jobs = 40, +    max_jobs = max_jobs,      log = { level = "warn" },      git = { -      clone_timeout = 300, +      clone_timeout = 120,      },      display = {        open_fn = function() @@ -106,10 +111,8 @@ function plugin_loader.load(configurations)          end        end      end) -    -- colorscheme must get called after plugins are loaded or it will break new installs. -    vim.g.colors_name = lvim.colorscheme -    vim.cmd("colorscheme " .. lvim.colorscheme)    end, debug.traceback) +    if not status_ok then      Log:warn "problems detected while loading plugins' configurations"      Log:trace(debug.traceback()) diff --git a/lua/lvim/plugins.lua b/lua/lvim/plugins.lua index bfe76bb8..db84d878 100644 --- a/lua/lvim/plugins.lua +++ b/lua/lvim/plugins.lua @@ -1,3 +1,4 @@ +-- local require = require("lvim.utils.require").require  local core_plugins = {    -- Packer can manage itself as an optional plugin    { "wbthomason/packer.nvim" }, @@ -6,7 +7,6 @@ local core_plugins = {    {      "jose-elias-alvarez/null-ls.nvim",    }, -  { "antoinemadec/FixCursorHold.nvim" }, -- Needed while issue https://github.com/neovim/neovim/issues/12587 is still open    { "williamboman/mason-lspconfig.nvim" },    {      "williamboman/mason.nvim", @@ -15,17 +15,7 @@ local core_plugins = {      end,    },    { -    "lunarvim/onedarker.nvim", -    branch = "freeze", -    config = function() -      pcall(function() -        if lvim and lvim.colorscheme == "onedarker" then -          require("onedarker").setup() -          lvim.builtin.lualine.options.theme = "onedarker" -        end -      end) -    end, -    disable = lvim.colorscheme ~= "onedarker", +    "folke/tokyonight.nvim",    },    {      "rcarriga/nvim-notify", @@ -102,8 +92,8 @@ local core_plugins = {      "hrsh7th/cmp-path",    },    { -    "folke/lua-dev.nvim", -    module = "lua-dev", +    "folke/neodev.nvim", +    module = "neodev",    },    -- Autopairs @@ -139,7 +129,15 @@ local core_plugins = {      end,      disable = not lvim.builtin.nvimtree.active,    }, - +  -- Lir +  { +    "christianchiarulli/lir.nvim", +    config = function() +      require("lvim.core.lir").setup() +    end, +    requires = { "kyazdani42/nvim-web-devicons" }, +    disable = not lvim.builtin.lir.active, +  },    {      "lewis6991/gitsigns.nvim", @@ -196,6 +194,15 @@ local core_plugins = {      disable = not lvim.builtin.lualine.active,    }, +  -- breadcrumbs +  { +    "SmiteshP/nvim-navic", +    config = function() +      require("lvim.core.breadcrumbs").setup() +    end, +    disable = not lvim.builtin.breadcrumbs.active, +  }, +    {      "akinsho/bufferline.nvim",      config = function() @@ -216,12 +223,12 @@ local core_plugins = {      disable = not lvim.builtin.dap.active,    }, -  -- Debugger management +  -- Debugger user interface    { -    "Pocco81/dap-buddy.nvim", -    branch = "dev", -    -- event = "BufWinEnter", -    -- event = "BufRead", +    "rcarriga/nvim-dap-ui", +    config = function() +      require("lvim.core.dap").setup_ui() +    end,      disable = not lvim.builtin.dap.active,    }, @@ -249,6 +256,36 @@ local core_plugins = {    {      "b0o/schemastore.nvim",    }, + +  { +    "RRethy/vim-illuminate", +    config = function() +      require("lvim.core.illuminate").setup() +    end, +    disable = not lvim.builtin.illuminate.active, +  }, + +  { +    "lukas-reineke/indent-blankline.nvim", +    config = function() +      require("lvim.core.indentlines").setup() +    end, +    disable = not lvim.builtin.indentlines.active, +  }, + +  { +    "lunarvim/onedarker.nvim", +    branch = "freeze", +    config = function() +      pcall(function() +        if lvim and lvim.colorscheme == "onedarker" then +          require("onedarker").setup() +          lvim.builtin.lualine.options.theme = "onedarker" +        end +      end) +    end, +    disable = lvim.colorscheme ~= "onedarker", +  },  }  local default_snapshot_path = join_paths(get_lvim_base_dir(), "snapshots", "default.json") @@ -260,8 +297,8 @@ local get_default_sha1 = function(spec)    return default_sha1[short_name] and default_sha1[short_name].commit  end -for _, spec in ipairs(core_plugins) do -  if not vim.env.LVIM_DEV_MODE then +if not vim.env.LVIM_DEV_MODE then +  for _, spec in ipairs(core_plugins) do      -- Manually lock the commit hash since Packer's snapshots are unreliable in headless mode      spec["commit"] = get_default_sha1(spec)    end diff --git a/lua/lvim/utils/functions.lua b/lua/lvim/utils/functions.lua index de46bc8a..1cb8ec8e 100644 --- a/lua/lvim/utils/functions.lua +++ b/lua/lvim/utils/functions.lua @@ -16,4 +16,17 @@ function M.smart_quit()    end  end +function M.isempty(s) +  return s == nil or s == "" +end + +function M.get_buf_option(opt) +  local status_ok, buf_option = pcall(vim.api.nvim_buf_get_option, 0, opt) +  if not status_ok then +    return nil +  else +    return buf_option +  end +end +  return M diff --git a/lua/lvim/utils/git.lua b/lua/lvim/utils/git.lua index 99c178f3..c1bdca1b 100644 --- a/lua/lvim/utils/git.lua +++ b/lua/lvim/utils/git.lua @@ -1,6 +1,7 @@  local M = {}  local Log = require "lvim.core.log" +local fmt = string.format  local if_nil = vim.F.if_nil  local function git_cmd(opts) @@ -39,13 +40,20 @@ local function safe_deep_fetch()      Log:error(vim.inspect(error))      return    end -  -- git fetch --unshallow will cause an error on a a complete clone +  -- git fetch --unshallow will cause an error on a complete clone    local fetch_mode = result[1] == "true" and "--unshallow" or "--all"    ret = git_cmd { args = { "fetch", fetch_mode } }    if ret ~= 0 then -    Log:error("Git fetch failed! Please pull the changes manually in " .. get_lvim_base_dir()) +    Log:error(fmt "Git fetch %s failed! Please pull the changes manually in %s", fetch_mode, get_lvim_base_dir())      return    end +  if fetch_mode == "--unshallow" then +    ret = git_cmd { args = { "remote", "set-branches", "origin", "*" } } +    if ret ~= 0 then +      Log:error(fmt "Git fetch %s failed! Please pull the changes manually in %s", fetch_mode, get_lvim_base_dir()) +      return +    end +  end    return true  end @@ -53,6 +61,11 @@ end  function M.update_base_lvim()    Log:info "Checking for updates" +  if not vim.loop.fs_access(get_lvim_base_dir(), "w") then +    Log:warn(fmt("Lunarvim update aborted! cannot write to %s", get_lvim_base_dir())) +    return +  end +    if not safe_deep_fetch() then      return    end diff --git a/lua/lvim/utils/hooks.lua b/lua/lvim/utils/hooks.lua index f15f6729..bf0dac60 100644 --- a/lua/lvim/utils/hooks.lua +++ b/lua/lvim/utils/hooks.lua @@ -19,7 +19,7 @@ function M.run_on_packer_complete()    pcall(vim.cmd, "colorscheme " .. lvim.colorscheme)    if M._reload_triggered then -    Log:info "Reloaded configuration" +    Log:debug "Reloaded configuration"      M._reload_triggered = nil    end  end @@ -34,10 +34,7 @@ end  ---It also forces regenerating any template ftplugin files  ---Tip: Useful for clearing any outdated settings  function M.reset_cache() -  local impatient = _G.__luacache -  if impatient then -    impatient.clear_cache() -  end +  vim.cmd [[LuaCacheClear]]    local lvim_modules = {}    for module, _ in pairs(package.loaded) do      if module:match "lvim.core" or module:match "lvim.lsp" then @@ -52,8 +49,8 @@ end  function M.run_post_update()    Log:debug "Starting post-update hook" -  if vim.fn.has "nvim-0.7" ~= 1 then -    local compat_tag = "1.1.3" +  if vim.fn.has "nvim-0.8" ~= 1 then +    local compat_tag = "1.1.4"      vim.notify(        "Please upgrade your Neovim base installation. Newer version of Lunarvim requires v0.7+",        vim.log.levels.WARN @@ -61,9 +58,9 @@ function M.run_post_update()      vim.wait(1000, function()        return false      end) -    local ret = require_clean("lvim.utils.git").switch_lvim_branch(compat_tag) +    local ret = reload("lvim.utils.git").switch_lvim_branch(compat_tag)      if ret then -      vim.notify("Reverted to the last known compatibile version: " .. compat_tag, vim.log.levels.WARN) +      vim.notify("Reverted to the last known compatible version: " .. compat_tag, vim.log.levels.WARN)      end      return    end diff --git a/lua/lvim/utils/modules.lua b/lua/lvim/utils/modules.lua new file mode 100644 index 00000000..d5674483 --- /dev/null +++ b/lua/lvim/utils/modules.lua @@ -0,0 +1,98 @@ +local M = {} + +local Log = require "lvim.core.log" +-- revisit this +-- function prequire(package) +--   local status, lib = pcall(require, package) +--   if status then +--     return lib +--   else +--     vim.notify("Failed to require '" .. package .. "' from " .. debug.getinfo(2).source) +--     return nil +--   end +-- end + +local function _assign(old, new, k) +  local otype = type(old[k]) +  local ntype = type(new[k]) +  -- print("hi") +  if (otype == "thread" or otype == "userdata") or (ntype == "thread" or ntype == "userdata") then +    vim.notify(string.format("warning: old or new attr %s type be thread or userdata", k)) +  end +  old[k] = new[k] +end + +local function _replace(old, new, repeat_tbl) +  if repeat_tbl[old] then +    return +  end +  repeat_tbl[old] = true + +  local dellist = {} +  for k, _ in pairs(old) do +    if not new[k] then +      table.insert(dellist, k) +    end +  end +  for _, v in ipairs(dellist) do +    old[v] = nil +  end + +  for k, _ in pairs(new) do +    if not old[k] then +      old[k] = new[k] +    else +      if type(old[k]) ~= type(new[k]) then +        Log:debug( +          string.format("Reloader: mismatch between old [%s] and new [%s] type for [%s]", type(old[k]), type(new[k]), k) +        ) +        _assign(old, new, k) +      else +        if type(old[k]) == "table" then +          _replace(old[k], new[k], repeat_tbl) +        else +          _assign(old, new, k) +        end +      end +    end +  end +end + +M.require_clean = function(m) +  package.loaded[m] = nil +  _G[m] = nil +  local _, module = pcall(require, m) +  return module +end + +M.require_safe = function(mod) +  local status_ok, module = pcall(require, mod) +  if not status_ok then +    local trace = debug.getinfo(2, "SL") +    local shorter_src = trace.short_src +    local lineinfo = shorter_src .. ":" .. (trace.currentline or trace.linedefined) +    local msg = string.format("%s : skipped loading [%s]", lineinfo, mod) +    Log:debug(msg) +  end +  return module +end + +M.reload = function(mod) +  if not package.loaded[mod] then +    return M.require_safe(mod) +  end + +  local old = package.loaded[mod] +  package.loaded[mod] = nil +  local new = M.require_safe(mod) + +  if type(old) == "table" and type(new) == "table" then +    local repeat_tbl = {} +    _replace(old, new, repeat_tbl) +  end + +  package.loaded[mod] = old +  return old +end + +return M | 
