summaryrefslogtreecommitdiff
path: root/lua/lvim/core/builtins
diff options
context:
space:
mode:
Diffstat (limited to 'lua/lvim/core/builtins')
-rw-r--r--lua/lvim/core/builtins/alpha.lua87
-rw-r--r--lua/lvim/core/builtins/alpha/dashboard.lua148
-rw-r--r--lua/lvim/core/builtins/alpha/startify.lua45
-rw-r--r--lua/lvim/core/builtins/autopairs.lua82
-rw-r--r--lua/lvim/core/builtins/breadcrumbs.lua233
-rw-r--r--lua/lvim/core/builtins/bufferline.lua239
-rw-r--r--lua/lvim/core/builtins/cmp.lua377
-rw-r--r--lua/lvim/core/builtins/comment.lua84
-rw-r--r--lua/lvim/core/builtins/dap.lua174
-rw-r--r--lua/lvim/core/builtins/gitsigns.lua81
-rw-r--r--lua/lvim/core/builtins/illuminate.lua69
-rw-r--r--lua/lvim/core/builtins/indentlines.lua40
-rw-r--r--lua/lvim/core/builtins/init.lua43
-rw-r--r--lua/lvim/core/builtins/lir.lua117
-rw-r--r--lua/lvim/core/builtins/lualine/colors.lua16
-rw-r--r--lua/lvim/core/builtins/lualine/components.lua179
-rw-r--r--lua/lvim/core/builtins/lualine/conditions.lua17
-rw-r--r--lua/lvim/core/builtins/lualine/init.lua54
-rw-r--r--lua/lvim/core/builtins/lualine/styles.lua165
-rw-r--r--lua/lvim/core/builtins/lualine/utils.lua14
-rw-r--r--lua/lvim/core/builtins/mason.lua91
-rw-r--r--lua/lvim/core/builtins/nvimtree.lua285
-rw-r--r--lua/lvim/core/builtins/project.lua64
-rw-r--r--lua/lvim/core/builtins/telescope.lua147
-rw-r--r--lua/lvim/core/builtins/terminal.lua165
-rw-r--r--lua/lvim/core/builtins/treesitter.lua116
-rw-r--r--lua/lvim/core/builtins/which-key.lua319
27 files changed, 3429 insertions, 22 deletions
diff --git a/lua/lvim/core/builtins/alpha.lua b/lua/lvim/core/builtins/alpha.lua
new file mode 100644
index 00000000..3270d01b
--- /dev/null
+++ b/lua/lvim/core/builtins/alpha.lua
@@ -0,0 +1,87 @@
+local M = {}
+
+function M.config()
+ local lvim_dashboard = require "lvim.core.builtins.alpha.dashboard"
+ local lvim_startify = require "lvim.core.builtins.alpha.startify"
+ lvim.builtin.alpha = {
+ dashboard = {
+ config = {},
+ section = lvim_dashboard.get_sections(),
+ opts = { autostart = true },
+ },
+ startify = {
+ config = {},
+ section = lvim_startify.get_sections(),
+ opts = { autostart = true },
+ },
+ active = true,
+ mode = "dashboard",
+ }
+end
+
+local function resolve_buttons(theme_name, button_section)
+ if button_section.val and #button_section.val > 0 then
+ return button_section.val
+ end
+
+ local selected_theme = require("alpha.themes." .. theme_name)
+ local val = {}
+ for _, entry in pairs(button_section.entries) do
+ local on_press = function()
+ local sc_ = entry[1]:gsub("%s", ""):gsub("SPC", "<leader>")
+ local key = vim.api.nvim_replace_termcodes(sc_, true, false, true)
+ vim.api.nvim_feedkeys(key, "normal", false)
+ end
+ local button_element = selected_theme.button(entry[1], entry[2], entry[3])
+ -- this became necessary after recent changes in alpha.nvim (06ade3a20ca9e79a7038b98d05a23d7b6c016174)
+ button_element.on_press = on_press
+
+ button_element.opts = vim.tbl_extend("force", button_element.opts, entry[4] or button_section.opts or {})
+
+ table.insert(val, button_element)
+ end
+ return val
+end
+
+local function resolve_config(theme_name)
+ local selected_theme = require("alpha.themes." .. theme_name)
+ local resolved_section = selected_theme.section
+ local section = lvim.builtin.alpha[theme_name].section
+
+ for name, el in pairs(section) do
+ for k, v in pairs(el) do
+ if name:match "buttons" and k == "entries" then
+ resolved_section[name].val = resolve_buttons(theme_name, el)
+ elseif v then
+ resolved_section[name][k] = v
+ end
+ end
+
+ resolved_section[name].opts = el.opts or {}
+ end
+
+ local opts = lvim.builtin.alpha[theme_name].opts or {}
+ selected_theme.config.opts = vim.tbl_extend("force", selected_theme.config.opts, opts)
+
+ return selected_theme.config
+end
+
+function M.setup()
+ 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
+
+ -- this makes it easier to use a completely custom configuration
+ if vim.tbl_isempty(config) then
+ config = resolve_config(mode)
+ end
+
+ alpha.setup(config)
+
+ return alpha
+end
+
+return M
diff --git a/lua/lvim/core/builtins/alpha/dashboard.lua b/lua/lvim/core/builtins/alpha/dashboard.lua
new file mode 100644
index 00000000..6a368924
--- /dev/null
+++ b/lua/lvim/core/builtins/alpha/dashboard.lua
@@ -0,0 +1,148 @@
+local M = {}
+
+local banner = {
+ " ⢀⣀⣤⣤⣤⣶⣶⣶⣶⣶⣶⣤⣤⣤⣀⡀ ",
+ " ⣀⣤⣶⣿⠿⠟⠛⠉⠉⠉⠁⠈⠉⠉⠉⠛⠛⠿⣿⣷⣦⣀ ",
+ " ⢀⣤⣾⡿⠛⠉ ⠉⠛⢿⣷⣤⡀ ",
+ " ⣴⣿⡿⠃ ⠙⠻⣿⣦ ",
+ " ⢀⣠⣤⣤⣤⣤⣤⣾⣿⣉⣀⡀ ⠙⢻⣷⡄ ",
+ "⣼⠋⠁ ⢠⣿⡟ ⠉⠉⠉⠛⠛⠶⠶⣤⣄⣀ ⣀⣀ ⢠⣤⣤⡄ ⢻⣿⣆ ",
+ "⢻⡄ ⢰⣿⡟ ⢠⣿⣿⣿⠉⠛⠲⣾⣿⣿⣷ ⢀⣾⣿⣿⠁ ⢻⣿⡆ ",
+ " ⠹⣦⡀ ⣿⣿⠁ ⢸⣿⣿⡇ ⠻⣿⣿⠟⠳⠶⣤⣀⣸⣿⣿⠇ ⣿⣷ ",
+ " ⠙⢷⣿⡇ ⣸⣿⣿⠃ ⢸⣿⣿⢷⣤⡀ ⢸⣿⡆ ",
+ " ⢸⣿⠇ ⣿⣿⣿ ⣿⣿⣷ ⢠⣿⣿⡏ ⠈⠙⠳⢦⣄ ⠈⣿⡇ ",
+ " ⢸⣿⡆ ⢸⣿⣿⡇ ⣿⣿⣿ ⢀⣿⣿⡟ ⠈⠙⠷⣤⣿⡇ ",
+ " ⠘⣿⡇ ⣼⣿⣿⠁ ⣿⣿⣿ ⣼⣿⣿⠃ ⢸⣿⠷⣄⡀ ",
+ " ⣿⣿ ⣿⣿⡿ ⣿⣿⣿⢸⣿⣿⠃ ⣾⡿ ⠈⠻⣆ ",
+ " ⠸⣿⣧ ⢸⣿⣿⣇⣀⣀⣀⣀⣀⣀⣸⣿⣿⣿⣿⠇ ⣼⣿⠇ ⠘⣧",
+ " ⠹⣿⣧ ⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏ ⣼⣿⠏ ⣠⡿",
+ " ⠘⢿⣷⣄ ⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉ ⢠⣼⡿⠛⠛⠛⠛⠛⠛⠉ ",
+ " ⠻⣿⣦⣄ ⣀⣴⣿⠟ ",
+ " ⠈⠛⢿⣶⣤⣀ ⣀⣤⣶⡿⠛⠁ ",
+ " ⠉⠻⢿⣿⣶⣤⣤⣀⣀⡀ ⢀⣀⣀⣠⣤⣶⣿⡿⠟⠋ ",
+ " ⠈⠉⠙⠛⠻⠿⠿⠿⠿⠿⠿⠟⠛⠋⠉⠁ ",
+}
+
+M.banner_small = {
+ " ⢀⣀ ⣰⣶ ⢀⣤⣄ ",
+ " ⢸⣿ ⣀⡀ ⣰⣿⠏ ⠘⠿⠟ ",
+ " ⣿⡟ ⣤⡄ ⣠⣤ ⢠⣤⣀⣤⣤⣤⡀ ⢀⣤⣤⣤⣤⡀ ⢠⣤⢀⣤⣤⣄ ⣿⣿ ⢰⣿⠏ ⣶⣶⣶⣶⡦ ⢠⣶⣦⣴⣦⣠⣴⣦⡀ ",
+ " ⢠⣿⡇ ⢠⣿⠇ ⣿⡇ ⣿⡿⠉ ⠈⣿⣧ ⠰⠿⠋ ⢹⣿ ⣿⡿⠋ ⠹⠿ ⢻⣿⡇⢠⣿⡟ ⠈⠉⢹⣿⡇ ⢸⣿⡏⢹⣿⡏⢹⣿⡇ ",
+ " ⢸⣿ ⢸⣿ ⢰⣿⠃ ⢠⣿⡇ ⣿⡇ ⣠⣴⡶⠶⠶⣿⣿ ⢠⣿⡇ ⢸⣿⣇⣿⡿ ⣿⣿⠁ ⣿⣿ ⣾⣿ ⣾⣿⠁ ",
+ " ⣿⣟ ⢻⣿⡀ ⢀⣼⣿ ⢸⣿ ⢰⣿⠇ ⢰⣿⣇ ⣠⣿⡏ ⢸⣿ ⢸⣿⣿⣿⠁ ⣀⣀⣠⣿⣿⣀⡀ ⢠⣿⡟⢠⣿⡟⢀⣿⡿ ",
+ " ⠛⠛⠛⠛⠛⠛⠁ ⠈⠛⠿⠟⠋⠛⠃ ⠛⠛ ⠘⠛ ⠙⠿⠿⠛⠙⠛⠃ ⠚⠛ ⠘⠿⠿⠃ ⠿⠿⠿⠿⠿⠿⠿ ⠸⠿⠇⠸⠿⠇⠸⠿⠇ ",
+}
+
+M.banner_alt_1 = {
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣶⣶⣶⣶⣶⣶⣶⣦⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣾⣿⠿⠛⠛⠉⠉⠉⠉⠉⠉⠉⠙⠛⠻⢿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠈⠉⠉⠉⠉⠉⣹⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⠀⠀⣰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⢰⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⡀⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢺⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠉⠑⠢⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡇⠀⠀⠀⠈⠑⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠉⠐⠢⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⡟⠀⠈⠑⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠒⠠⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⠁⠀⠀⢀⣼⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠁⠒⠂⠤⠤⠀⣀⡀⠀⠀⠀⣼⣿⠇⠀⠀⢀⣸⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠀⣿⡟⠀⠀⠀⠀⠀⠀⣤⡄⠀⠀⠀⣠⣤⠀⠀⢠⣭⣀⣤⣤⣤⡀⠀⠀⠀⢀⣤⣤⣤⣤⡀⠀⠀⠀⢠⣤⢀⣤⣤⣄⠀⠀⣿⣿⠀⠉⣹⣿⠏⠉⠉⢱⣶⣶⣶⡦⠀⠀⠀⢠⣶⣦⣴⣦⣠⣴⣦⡀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⢠⣿⠇⠀⠀⠀⣿⡇⠀⠀⣿⡿⠉⠀⠈⣿⣧⠀⠀⠰⠿⠋⠀⠀⢹⣿⠀⠀⠀⣿⡿⠋⠀⠹⠿⠀⠀⢻⣿⡇⢠⣿⡟⠀⠀⠀⠈⠉⢹⣿⡇⠀⠀⠀⢸⣿⡏⢹⣿⡏⢹⣿⡇⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⢰⣿⠃⠀⢠⣿⡇⠀⠀⠀⣿⡇⠀⠀⣠⣴⡶⠶⠶⣿⣿⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⣇⣿⡿⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⠀⣿⣿⠀⣾⣿⠀⣾⣿⠁⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⣿⣟⠀⠀⠀⠀⠀⠀⢻⣿⡀⠀⢀⣼⣿⠀⠀⢸⣿⠀⠀⠀⢰⣿⠇⠀⢰⣿⣇⠀⠀⣠⣿⡏⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠁⠀⠀⠀⣀⣀⣠⣿⣿⣀⡀⠀⢠⣿⡟⢠⣿⡟⢀⣿⡿⠀⠀⠀⠀⠀",
+ "⠀⠀⠀⠀⠀⠛⠛⠛⠛⠛⠛⠁⠀⠈⠛⠿⠟⠋⠛⠃⠀⠀⠛⠛⠀⠀⠀⠘⠛⠀⠀⠀⠙⠿⠿⠛⠙⠛⠃⠀⠀⠚⠛⠀⠀⠀⠀⠀⠀⠀⠘⠿⠿⠃⠀⠀⠀⠀⠿⠿⠿⠿⠿⠿⠿⠀⠸⠿⠇⠸⠿⠇⠸⠿⠇⠀⠀⠀⠀⠀",
+ " ",
+}
+
+M.banner_alt_2 = {
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠟⠛⠛⠉⠉⠉⠉⠉⠉⠛⠛⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠉⠀⣀⣤⣴⣶⣶⣾⣿⣿⣷⣶⣶⣦⣤⣀⠀⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⠿⠟⠛⠛⠛⠛⠛⠁⠀⠾⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⠁⣴⣾⣿⣿⣿⡟⠀⣰⣿⣶⣶⣶⣤⣤⣉⣉⠛⠛⠿⠿⣿⣿⡿⠿⠿⣿⣿⣿⣿⣿⣿⡟⠛⠛⢛⣿⣿⣿⣆⠀⢻⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⡄⠻⣿⣿⣿⡟⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⣦⣤⡈⠀⠀⠀⠈⣿⣿⣿⣿⡿⠁⠀⠀⣾⣿⣿⣿⣿⡄⠀⢻⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣄⠙⠿⣿⠁⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣄⠀⠀⣠⣄⣉⠛⠻⠃⠀⠀⣼⣿⣿⣿⣿⣿⣿⡀⠈⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣷⣦⡈⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠆⠀⠀⡀⠛⠿⣿⣿⣿⣿⣿⡇⠀⢻⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⡇⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⢀⣿⣿⣿⣿⡇⠀⠀⠘⣿⣿⡟⠀⠀⢰⣿⣷⣦⣌⡙⠻⢿⣿⣷⠀⢸⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⡇⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⠀⠀⠀⣿⡿⠀⠀⢀⣿⣿⣿⣿⣿⣿⣷⣤⣈⠛⠀⢸⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣧⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⣾⣿⣿⣿⣿⣿⠀⠀⠀⣿⠁⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⡈⠻⢿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⡀⠈⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⢀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠃⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⢀⣿⣶⣄⠙⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣧⠀⠘⣿⣿⣿⣿⣿⣿⡇⠀⠀⠸⠿⠿⠿⠿⠿⠿⠇⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣼⣿⣿⣿⣦⠘⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣧⠀⠹⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⣼⣿⣿⣿⡿⠟⢀⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠈⢿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⢀⣤⣤⣤⣤⣤⣴⣶⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣀⠀⠉⠛⠻⠿⠿⢿⣿⣿⡿⠿⠿⠟⠛⠉⠀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣤⣤⣀⣀⣀⣀⣀⣀⣤⣤⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+ "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿",
+}
+
+function M.get_sections()
+ local header = {
+ type = "text",
+ val = function()
+ local alpha_wins = vim.tbl_filter(function(win)
+ local buf = vim.api.nvim_win_get_buf(win)
+ return vim.api.nvim_buf_get_option(buf, "filetype") == "alpha"
+ end, vim.api.nvim_list_wins())
+
+ if vim.api.nvim_win_get_height(alpha_wins[#alpha_wins]) < 36 then
+ return M.banner_small
+ end
+ return banner
+ end,
+ opts = {
+ position = "center",
+ hl = "Label",
+ },
+ }
+
+ local text = require "lvim.interface.text"
+ local lvim_version = require("lvim.utils.git").get_lvim_version()
+
+ local footer = {
+ type = "text",
+ val = text.align_center({ width = 0 }, {
+ "",
+ "lunarvim.org",
+ lvim_version,
+ }, 0.5),
+ opts = {
+ position = "center",
+ hl = "Number",
+ },
+ }
+
+ local buttons = {
+ opts = {
+ hl_shortcut = "Include",
+ spacing = 1,
+ },
+ entries = {
+ { "f", lvim.icons.ui.FindFile .. " Find File", "<CMD>Telescope find_files<CR>" },
+ { "n", lvim.icons.ui.NewFile .. " New File", "<CMD>ene!<CR>" },
+ { "p", lvim.icons.ui.Project .. " Projects ", "<CMD>Telescope projects<CR>" },
+ { "r", lvim.icons.ui.History .. " Recent files", ":Telescope oldfiles <CR>" },
+ { "t", lvim.icons.ui.FindText .. " Find Text", "<CMD>Telescope live_grep<CR>" },
+ {
+ "c",
+ lvim.icons.ui.Gear .. " Configuration",
+ "<CMD>edit " .. require("lvim.config"):get_user_config_path() .. " <CR>",
+ },
+ { "q", lvim.icons.ui.Close .. " Quit", "<CMD>quit<CR>" },
+ },
+ }
+ return {
+ header = header,
+ buttons = buttons,
+ footer = footer,
+ }
+end
+
+return M
diff --git a/lua/lvim/core/builtins/alpha/startify.lua b/lua/lvim/core/builtins/alpha/startify.lua
new file mode 100644
index 00000000..e9d10a07
--- /dev/null
+++ b/lua/lvim/core/builtins/alpha/startify.lua
@@ -0,0 +1,45 @@
+local M = {}
+
+function M.get_sections()
+ local header = {
+ type = "text",
+ val = {
+ [[ __ _ ___ ]],
+ [[ / / __ ______ ____ _____| | / (_)___ ___ ]],
+ [[ / / / / / / __ \/ __ `/ ___/ | / / / __ `__ \]],
+ [[ / /___/ /_/ / / / / /_/ / / | |/ / / / / / / /]],
+ [[/_____/\__,_/_/ /_/\__,_/_/ |___/_/_/ /_/ /_/ ]],
+ },
+ opts = {
+ hl = "Label",
+ shrink_margin = false,
+ -- wrap = "overflow";
+ },
+ }
+
+ local top_buttons = {
+ entries = {
+ { "e", lvim.icons.ui.NewFile .. " New File", "<CMD>ene!<CR>" },
+ },
+ }
+
+ local bottom_buttons = {
+ entries = {
+ { "q", "Quit", "<CMD>quit<CR>" },
+ },
+ }
+
+ local footer = {
+ type = "group",
+ }
+
+ return {
+ header = header,
+ top_buttons = top_buttons,
+ bottom_buttons = bottom_buttons,
+ -- this is probably broken
+ footer = footer,
+ }
+end
+
+return M
diff --git a/lua/lvim/core/builtins/autopairs.lua b/lua/lvim/core/builtins/autopairs.lua
new file mode 100644
index 00000000..97f405be
--- /dev/null
+++ b/lua/lvim/core/builtins/autopairs.lua
@@ -0,0 +1,82 @@
+local M = {}
+
+function M.config()
+ lvim.builtin.autopairs = {
+ active = true,
+ ---@usage modifies the function or method delimiter by filetypes
+ map_char = {
+ all = "(",
+ tex = "{",
+ },
+ ---@usage check bracket in same line
+ enable_check_bracket_line = false,
+ ---@usage check treesitter
+ check_ts = true,
+ ts_config = {
+ lua = { "string", "source" },
+ javascript = { "string", "template_string" },
+ java = false,
+ },
+ disable_filetype = { "TelescopePrompt", "spectre_panel" },
+ ignored_next_char = string.gsub([[ [%w%%%'%[%"%.] ]], "%s+", ""),
+ enable_moveright = true,
+ ---@usage disable when recording or executing a macro
+ disable_in_macro = false,
+ ---@usage add bracket pairs after quote
+ enable_afterquote = true,
+ ---@usage map the <BS> key
+ map_bs = true,
+ ---@usage map <c-w> to delete a pair if possible
+ map_c_w = false,
+ ---@usage disable when insert after visual block mode
+ disable_in_visualblock = false,
+ ---@usage change default fast_wrap
+ fast_wrap = {
+ map = "<M-e>",
+ chars = { "{", "[", "(", '"', "'" },
+ pattern = string.gsub([[ [%'%"%)%>%]%)%}%,] ]], "%s+", ""),
+ offset = 0, -- Offset from pattern match
+ end_key = "$",
+ keys = "qwertyuiopzxcvbnmasdfghjkl",
+ check_comma = true,
+ highlight = "Search",
+ highlight_grey = "Comment",
+ },
+ }
+end
+
+local function on_confirm_done(...)
+ require("nvim-autopairs.completion.cmp").on_confirm_done()(...)
+end
+
+M.setup = function()
+ local status_ok, autopairs = pcall(require, "nvim-autopairs")
+ if not status_ok then
+ return
+ end
+
+ autopairs.setup {
+ check_ts = lvim.builtin.autopairs.check_ts,
+ enable_check_bracket_line = lvim.builtin.autopairs.enable_check_bracket_line,
+ ts_config = lvim.builtin.autopairs.ts_config,
+ disable_filetype = lvim.builtin.autopairs.disable_filetype,
+ disable_in_macro = lvim.builtin.autopairs.disable_in_macro,
+ ignored_next_char = lvim.builtin.autopairs.ignored_next_char,
+ enable_moveright = lvim.builtin.autopairs.enable_moveright,
+ enable_afterquote = lvim.builtin.autopairs.enable_afterquote,
+ map_c_w = lvim.builtin.autopairs.map_c_w,
+ map_bs = lvim.builtin.autopairs.map_bs,
+ disable_in_visualblock = lvim.builtin.autopairs.disable_in_visualblock,
+ fast_wrap = lvim.builtin.autopairs.fast_wrap,
+ }
+
+ pcall(function()
+ require "nvim-autopairs.completion.cmp"
+ require("cmp").event:off("confirm_done", on_confirm_done)
+ require("cmp").event:on("confirm_done", on_confirm_done)
+ end)
+
+ return autopairs
+end
+
+return M
diff --git a/lua/lvim/core/builtins/breadcrumbs.lua b/lua/lvim/core/builtins/breadcrumbs.lua
new file mode 100644
index 00000000..2ed0937e
--- /dev/null
+++ b/lua/lvim/core/builtins/breadcrumbs.lua
@@ -0,0 +1,233 @@
+local M = {}
+
+-- local Log = require "lvim.core.log"
+
+local icons = lvim.icons.kind
+
+M.config = function()
+ lvim.builtin.breadcrumbs = {
+ active = true,
+ winbar_filetype_exclude = {
+ "help",
+ "startify",
+ "dashboard",
+ "lazy",
+ "neo-tree",
+ "neogitstatus",
+ "NvimTree",
+ "Trouble",
+ "alpha",
+ "lir",
+ "Outline",
+ "spectre_panel",
+ "toggleterm",
+ "DressingSelect",
+ "Jaq",
+ "harpoon",
+ "dap-repl",
+ "dap-terminal",
+ "dapui_console",
+ "dapui_hover",
+ "lab",
+ "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 = " " .. lvim.icons.ui.ChevronRight .. " ",
+ 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)
+
+ return navic
+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, hl_group
+ local devicons_ok, devicons = pcall(require, "nvim-web-devicons")
+ if lvim.use_icons and devicons_ok then
+ file_icon, hl_group = devicons.get_icon(filename, extension, { default = true })
+
+ if f.isempty(file_icon) then
+ file_icon = lvim.icons.kind.File
+ end
+ else
+ file_icon = ""
+ hl_group = "Normal"
+ 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
+ return "%#NavicSeparator#" .. lvim.icons.ui.ChevronRight .. "%* " .. 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({
+ "CursorHoldI",
+ "CursorHold",
+ "BufWinEnter",
+ "BufFilePost",
+ "InsertEnter",
+ "BufWritePost",
+ "TabClosed",
+ "TabEnter",
+ }, {
+ group = "_winbar",
+ callback = function()
+ if lvim.builtin.breadcrumbs.active then
+ local status_ok, _ = pcall(vim.api.nvim_buf_get_var, 0, "lsp_floating_window")
+ if not status_ok then
+ -- TODO:
+ M.get_winbar()
+ end
+ end
+ end,
+ })
+ end
+end
+
+return M
diff --git a/lua/lvim/core/builtins/bufferline.lua b/lua/lvim/core/builtins/bufferline.lua
new file mode 100644
index 00000000..768ed988
--- /dev/null
+++ b/lua/lvim/core/builtins/bufferline.lua
@@ -0,0 +1,239 @@
+local M = {}
+
+local function is_ft(b, ft)
+ return vim.bo[b].filetype == ft
+end
+
+local function diagnostics_indicator(num, _, diagnostics, _)
+ local result = {}
+ 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
+ for name, count in pairs(diagnostics) do
+ if symbols[name] and count > 0 then
+ table.insert(result, symbols[name] .. " " .. count)
+ end
+ end
+ result = table.concat(result, " ")
+ return #result > 0 and result or ""
+end
+
+local function custom_filter(buf, buf_nums)
+ local logs = vim.tbl_filter(function(b)
+ return is_ft(b, "log")
+ end, buf_nums or {})
+ if vim.tbl_isempty(logs) then
+ return true
+ end
+ local tab_num = vim.fn.tabpagenr()
+ local last_tab = vim.fn.tabpagenr "$"
+ local is_log = is_ft(buf, "log")
+ if last_tab == 1 then
+ return true
+ end
+ -- only show log buffers in secondary tabs
+ return (tab_num == last_tab and is_log) or (tab_num ~= last_tab and not is_log)
+end
+
+M.config = function()
+ lvim.builtin.bufferline = {
+ active = true,
+ keymap = {
+ normal_mode = {},
+ },
+ highlights = {
+ background = {
+ italic = true,
+ },
+ buffer_selected = {
+ bold = true,
+ },
+ },
+ options = {
+ mode = "buffers", -- set to "tabs" to only show tabpages instead
+ numbers = "none", -- can be "none" | "ordinal" | "buffer_id" | "both" | function
+ close_command = function(bufnr) -- can be a string | function, see "Mouse actions"
+ M.buf_kill("bd", bufnr, false)
+ end,
+ right_mouse_command = "vert sbuffer %d", -- can be a string | function, see "Mouse actions"
+ 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 = lvim.icons.ui.BoldLineLeft, -- this should be omitted if indicator style is not 'icon'
+ style = "icon", -- can also be 'underline'|'none',
+ },
+ 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
+ --- some limitations that will *NOT* be fixed.
+ name_formatter = function(buf) -- buf contains a "name", "path" and "bufnr"
+ -- remove extension from markdown files for example
+ if buf.name:match "%.md" then
+ return vim.fn.fnamemodify(buf.name, ":t:r")
+ end
+ end,
+ max_name_length = 18,
+ max_prefix_length = 15, -- prefix used when a buffer is de-duplicated
+ truncate_names = true, -- whether or not tab names should be truncated
+ tab_size = 18,
+ diagnostics = "nvim_lsp",
+ diagnostics_update_in_insert = false,
+ diagnostics_indicator = diagnostics_indicator,
+ -- NOTE: this will be called a lot so don't do any heavy processing here
+ custom_filter = custom_filter,
+ offsets = {
+ {
+ filetype = "undotree",
+ text = "Undotree",
+ highlight = "PanelHeading",
+ padding = 1,
+ },
+ {
+ filetype = "NvimTree",
+ text = "Explorer",
+ highlight = "PanelHeading",
+ padding = 1,
+ },
+ {
+ filetype = "DiffviewFiles",
+ text = "Diff View",
+ highlight = "PanelHeading",
+ padding = 1,
+ },
+ {
+ filetype = "flutterToolsOutline",
+ text = "Flutter Outline",
+ highlight = "PanelHeading",
+ },
+ {
+ filetype = "lazy",
+ text = "Lazy",
+ highlight = "PanelHeading",
+ padding = 1,
+ },
+ },
+ color_icons = true, -- whether or not to add the filetype icon highlights
+ show_buffer_icons = lvim.use_icons, -- disable filetype icons for buffers
+ show_buffer_close_icons = lvim.use_icons,
+ show_close_icon = false,
+ show_tab_indicators = true,
+ persist_buffer_sort = true, -- whether or not custom sorted buffers should persist
+ -- can also be a table containing 2 custom separators
+ -- [focused and unfocused]. eg: { '|', '|' }
+ separator_style = "thin",
+ enforce_regular_tabs = false,
+ always_show_bufferline = false,
+ hover = {
+ enabled = false, -- requires nvim 0.8+
+ delay = 200,
+ reveal = { "close" },
+ },
+ sort_by = "id",
+ },
+ }
+end
+
+M.setup = function()
+ require("lvim.keymappings").load(lvim.builtin.bufferline.keymap)
+
+ local status_ok, bufferline = pcall(require, "bufferline")
+ if not status_ok then
+ return
+ end
+
+ -- can't be set in settings.lua because default tabline would flash before bufferline is loaded
+ vim.opt.showtabline = 2
+
+ bufferline.setup {
+ options = lvim.builtin.bufferline.options,
+ highlights = lvim.builtin.bufferline.highlights,
+ }
+
+ return bufferline
+end
+
+--stylua: ignore
+
+-- Common kill function for bdelete and bwipeout
+-- credits: based on bbye and nvim-bufdel
+---@param kill_command? string defaults to "bd"
+---@param bufnr? number defaults to the current buffer
+---@param force? boolean defaults to false
+function M.buf_kill(kill_command, bufnr, force)
+ kill_command = kill_command or "bd"
+
+ local bo = vim.bo
+ local api = vim.api
+ local fmt = string.format
+ local fnamemodify = vim.fn.fnamemodify
+
+ if bufnr == 0 or bufnr == nil then
+ bufnr = api.nvim_get_current_buf()
+ end
+
+ local bufname = api.nvim_buf_get_name(bufnr)
+
+ if not force then
+ local warning
+ if bo[bufnr].modified then
+ warning = fmt([[No write since last change for (%s)]], fnamemodify(bufname, ":t"))
+ elseif api.nvim_buf_get_option(bufnr, "buftype") == "terminal" then
+ warning = fmt([[Terminal %s will be killed]], bufname)
+ end
+ if warning then
+ vim.ui.input({
+ prompt = string.format([[%s. Close it anyway? [y]es or [n]o (default: no): ]], warning),
+ }, function(choice)
+ if choice ~= nil and choice:match "ye?s?" then M.buf_kill(kill_command, bufnr, true) end
+ end)
+ return
+ end
+ end
+
+ -- Get list of windows IDs with the buffer to close
+ local windows = vim.tbl_filter(function(win)
+ return api.nvim_win_get_buf(win) == bufnr
+ end, api.nvim_list_wins())
+
+ if force then
+ kill_command = kill_command .. "!"
+ end
+
+ -- Get list of active buffers
+ local buffers = vim.tbl_filter(function(buf)
+ return api.nvim_buf_is_valid(buf) and bo[buf].buflisted
+ end, api.nvim_list_bufs())
+
+ -- If there is only one buffer (which has to be the current one), vim will
+ -- create a new buffer on :bd.
+ -- For more than one buffer, pick the previous buffer (wrapping around if necessary)
+ if #buffers > 1 and #windows > 0 then
+ for i, v in ipairs(buffers) do
+ if v == bufnr then
+ local prev_buf_idx = i == 1 and #buffers or (i - 1)
+ local prev_buffer = buffers[prev_buf_idx]
+ for _, win in ipairs(windows) do
+ api.nvim_win_set_buf(win, prev_buffer)
+ end
+ end
+ end
+ end
+
+ -- Check if buffer still exists, to ensure the target buffer wasn't killed
+ -- due to options like bufhidden=wipe.
+ if api.nvim_buf_is_valid(bufnr) and bo[bufnr].buflisted then
+ vim.cmd(string.format("%s %d", kill_command, bufnr))
+ end
+end
+
+return M
diff --git a/lua/lvim/core/builtins/cmp.lua b/lua/lvim/core/builtins/cmp.lua
new file mode 100644
index 00000000..2bbb7ecc
--- /dev/null
+++ b/lua/lvim/core/builtins/cmp.lua
@@ -0,0 +1,377 @@
+local M = {}
+M.methods = {}
+
+local has_words_before = function()
+ local line, col = unpack(vim.api.nvim_win_get_cursor(0))
+ return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil
+end
+M.methods.has_words_before = has_words_before
+
+---@deprecated use M.methods.has_words_before instead
+M.methods.check_backspace = function()
+ return not has_words_before()
+end
+
+local T = function(str)
+ return vim.api.nvim_replace_termcodes(str, true, true, true)
+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
+---@param dir number 1 for forward, -1 for backward; defaults to 1
+---@return boolean true if a jumpable luasnip field is found while inside a snippet
+local function jumpable(dir)
+ local luasnip_ok, luasnip = pcall(require, "luasnip")
+ if not luasnip_ok then
+ return false
+ end
+
+ local win_get_cursor = vim.api.nvim_win_get_cursor
+ local get_current_buf = vim.api.nvim_get_current_buf
+
+ ---sets the current buffer's luasnip to the one nearest the cursor
+ ---@return boolean true if a node is found, false otherwise
+ local function seek_luasnip_cursor_node()
+ -- TODO(kylo252): upstream this
+ -- for outdated versions of luasnip
+ if not luasnip.session.current_nodes then
+ return false
+ end
+
+ local node = luasnip.session.current_nodes[get_current_buf()]
+ if not node then
+ return false
+ end
+
+ local snippet = node.parent.snippet
+ local exit_node = snippet.insert_nodes[0]
+
+ local pos = win_get_cursor(0)
+ pos[1] = pos[1] - 1
+
+ -- exit early if we're past the exit node
+ if exit_node then
+ local exit_pos_end = exit_node.mark:pos_end()
+ if (pos[1] > exit_pos_end[1]) or (pos[1] == exit_pos_end[1] and pos[2] > exit_pos_end[2]) then
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+
+ return false
+ end
+ end
+
+ node = snippet.inner_first:jump_into(1, true)
+ while node ~= nil and node.next ~= nil and node ~= snippet do
+ local n_next = node.next
+ local next_pos = n_next and n_next.mark:pos_begin()
+ local candidate = n_next ~= snippet and next_pos and (pos[1] < next_pos[1])
+ or (pos[1] == next_pos[1] and pos[2] < next_pos[2])
+
+ -- Past unmarked exit node, exit early
+ if n_next == nil or n_next == snippet.next then
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+
+ return false
+ end
+
+ if candidate then
+ luasnip.session.current_nodes[get_current_buf()] = node
+ return true
+ end
+
+ local ok
+ ok, node = pcall(node.jump_from, node, 1, true) -- no_move until last stop
+ if not ok then
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+
+ return false
+ end
+ end
+
+ -- No candidate, but have an exit node
+ if exit_node then
+ -- to jump to the exit node, seek to snippet
+ luasnip.session.current_nodes[get_current_buf()] = snippet
+ return true
+ end
+
+ -- No exit node, exit from snippet
+ snippet:remove_from_jumplist()
+ luasnip.session.current_nodes[get_current_buf()] = nil
+ return false
+ end
+
+ if dir == -1 then
+ return luasnip.in_snippet() and luasnip.jumpable(-1)
+ else
+ return luasnip.in_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable(1)
+ end
+end
+
+M.methods.jumpable = jumpable
+
+M.config = function()
+ local status_cmp_ok, cmp_types = pcall(require, "cmp.types.cmp")
+ if not status_cmp_ok then
+ return
+ end
+ local ConfirmBehavior = cmp_types.ConfirmBehavior
+ local SelectBehavior = cmp_types.SelectBehavior
+
+ local cmp = require("lvim.utils.modules").require_on_index "cmp"
+ local luasnip = require("lvim.utils.modules").require_on_index "luasnip"
+ local cmp_window = require "cmp.config.window"
+ local cmp_mapping = require "cmp.config.mapping"
+
+ lvim.builtin.cmp = {
+ active = true,
+ enabled = function()
+ local buftype = vim.api.nvim_buf_get_option(0, "buftype")
+ if buftype == "prompt" then
+ return false
+ end
+ return lvim.builtin.cmp.active
+ end,
+ confirm_opts = {
+ behavior = ConfirmBehavior.Replace,
+ select = false,
+ },
+ completion = {
+ ---@usage The minimum length of a word to complete on.
+ keyword_length = 1,
+ },
+ experimental = {
+ ghost_text = false,
+ native_menu = false,
+ },
+ formatting = {
+ fields = { "kind", "abbr", "menu" },
+ max_width = 0,
+ kind_icons = lvim.icons.kind,
+ source_names = {
+ nvim_lsp = "(LSP)",
+ emoji = "(Emoji)",
+ path = "(Path)",
+ calc = "(Calc)",
+ cmp_tabnine = "(Tabnine)",
+ vsnip = "(Snippet)",
+ luasnip = "(Snippet)",
+ buffer = "(Buffer)",
+ tmux = "(TMUX)",
+ copilot = "(Copilot)",
+ treesitter = "(TreeSitter)",
+ },
+ duplicates = {
+ buffer = 1,
+ path = 1,
+ nvim_lsp = 0,
+ luasnip = 1,
+ },
+ duplicates_default = 0,
+ 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) .. lvim.icons.ui.Ellipsis
+ end
+ if lvim.use_icons then
+ vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind]
+
+ if entry.source.name == "copilot" then
+ vim_item.kind = lvim.icons.git.Octoface
+ vim_item.kind_hl_group = "CmpItemKindCopilot"
+ end
+
+ if entry.source.name == "cmp_tabnine" then
+ vim_item.kind = lvim.icons.misc.Robot
+ vim_item.kind_hl_group = "CmpItemKindTabnine"
+ end
+
+ 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
+
+ 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]
+ or lvim.builtin.cmp.formatting.duplicates_default
+ return vim_item
+ end,
+ },
+ snippet = {
+ expand = function(args)
+ luasnip.lsp_expand(args.body)
+ end,
+ },
+ window = {
+ completion = cmp_window.bordered(),
+ documentation = cmp_window.bordered(),
+ },
+ sources = {
+ {
+ 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" },
+ { name = "nvim_lua" },
+ { name = "buffer" },
+ { name = "calc" },
+ { name = "emoji" },
+ { name = "treesitter" },
+ { name = "crates" },
+ { name = "tmux" },
+ },
+ mapping = cmp_mapping.preset.insert {
+ ["<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 = SelectBehavior.Select }, { "i" }),
+ ["<Up>"] = cmp_mapping(cmp_mapping.select_prev_item { behavior = SelectBehavior.Select }, { "i" }),
+ ["<C-d>"] = cmp_mapping.scroll_docs(-4),
+ ["<C-f>"] = cmp_mapping.scroll_docs(4),
+ ["<C-y>"] = cmp_mapping {
+ i = cmp_mapping.confirm { behavior = ConfirmBehavior.Replace, select = false },
+ c = function(fallback)
+ if cmp.visible() then
+ cmp.confirm { behavior = ConfirmBehavior.Replace, select = false }
+ else
+ fallback()
+ end
+ end,
+ },
+ ["<Tab>"] = cmp_mapping(function(fallback)
+ if cmp.visible() then
+ cmp.select_next_item()
+ elseif luasnip.expand_or_locally_jumpable() then
+ luasnip.expand_or_jump()
+ elseif jumpable(1) then
+ luasnip.jump(1)
+ elseif has_words_before() then
+ -- cmp.complete()
+ fallback()
+ else
+ fallback()
+ end
+ end, { "i", "s" }),
+ ["<S-Tab>"] = cmp_mapping(function(fallback)
+ if cmp.visible() then
+ cmp.select_prev_item()
+ elseif luasnip.jumpable(-1) then
+ luasnip.jump(-1)
+ else
+ fallback()
+ end
+ end, { "i", "s" }),
+ ["<C-Space>"] = cmp_mapping.complete(),
+ ["<C-e>"] = cmp_mapping.abort(),
+ ["<CR>"] = cmp_mapping(function(fallback)
+ if cmp.visible() then
+ local confirm_opts = vim.deepcopy(lvim.builtin.cmp.confirm_opts) -- avoid mutating the original opts below
+ local is_insert_mode = function()
+ return vim.api.nvim_get_mode().mode:sub(1, 1) == "i"
+ end
+ if is_insert_mode() then -- prevent overwriting brackets
+ confirm_opts.behavior = ConfirmBehavior.Insert
+ end
+ if cmp.confirm(confirm_opts) then
+ return -- success, exit early
+ end
+ end
+ fallback() -- if not exited early, always fallback
+ end),
+ },
+ cmdline = {
+ enable = false,
+ options = {
+ {
+ type = ":",
+ sources = {
+ { name = "path" },
+ { name = "cmdline" },
+ },
+ },
+ {
+ type = { "/", "?" },
+ sources = {
+ { name = "buffer" },
+ },
+ },
+ },
+ },
+ }
+end
+
+function M.setup()
+ 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
+
+ return cmp
+end
+
+return M
diff --git a/lua/lvim/core/builtins/comment.lua b/lua/lvim/core/builtins/comment.lua
new file mode 100644
index 00000000..677dfbb6
--- /dev/null
+++ b/lua/lvim/core/builtins/comment.lua
@@ -0,0 +1,84 @@
+local M = {}
+
+function M.config()
+ lvim.builtin.comment = {
+ active = true,
+ ---Add a space b/w comment and the line
+ ---@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
+ ---@type string|function
+ ignore = "^$",
+
+ ---Whether to create basic (operator-pending) and extra mappings for NORMAL/VISUAL mode
+ ---@type table
+ mappings = {
+ ---operator-pending mapping
+ ---Includes `gcc`, `gcb`, `gc[count]{motion}` and `gb[count]{motion}`
+ basic = true,
+ ---Extra mapping
+ ---Includes `gco`, `gcO`, `gcA`
+ extra = true,
+ },
+
+ ---LHS of line and block comment toggle mapping in NORMAL/VISUAL mode
+ ---@type table
+ toggler = {
+ ---line-comment toggle
+ line = "gcc",
+ ---block-comment toggle
+ block = "gbc",
+ },
+
+ ---LHS of line and block comment operator-mode mapping in NORMAL/VISUAL mode
+ ---@type table
+ opleader = {
+ ---line-comment opfunc mapping
+ line = "gc",
+ ---block-comment opfunc mapping
+ 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 = function(...)
+ local loaded, ts_comment = pcall(require, "ts_context_commentstring.integrations.comment_nvim")
+ if loaded and ts_comment then
+ return ts_comment.create_pre_hook()(...)
+ end
+ end,
+
+ ---Post-hook, called after commenting is done
+ ---@type function|nil
+ post_hook = nil,
+ }
+end
+
+function M.setup()
+ local nvim_comment = require "Comment"
+
+ nvim_comment.setup(lvim.builtin.comment)
+
+ return nvim_comment
+end
+
+return M
diff --git a/lua/lvim/core/builtins/dap.lua b/lua/lvim/core/builtins/dap.lua
new file mode 100644
index 00000000..bc5b8e9d
--- /dev/null
+++ b/lua/lvim/core/builtins/dap.lua
@@ -0,0 +1,174 @@
+local M = {}
+
+M.config = function()
+ lvim.builtin.dap = {
+ active = true,
+ breakpoint = {
+ text = lvim.icons.ui.Bug,
+ texthl = "DiagnosticSignError",
+ linehl = "",
+ numhl = "",
+ },
+ breakpoint_rejected = {
+ text = lvim.icons.ui.Bug,
+ texthl = "DiagnosticSignError",
+ linehl = "",
+ numhl = "",
+ },
+ stopped = {
+ text = lvim.icons.ui.BoldArrowRight,
+ texthl = "DiagnosticSignWarn",
+ linehl = "Visual",
+ numhl = "DiagnosticSignWarn",
+ },
+ log = {
+ level = "info",
+ },
+ ui = {
+ auto_open = true,
+ notify = {
+ threshold = vim.log.levels.INFO,
+ },
+ config = {
+ 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",
+ },
+ -- Use this to override mappings for specific elements
+ element_mappings = {},
+ expand_lines = true,
+ 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",
+ },
+ },
+ controls = {
+ enabled = true,
+ -- Display controls in this element
+ element = "repl",
+ icons = {
+ pause = "",
+ play = "",
+ step_into = "",
+ step_over = "",
+ step_out = "",
+ step_back = "",
+ run_last = "",
+ terminate = "",
+ },
+ },
+ 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>" },
+ },
+ },
+ windows = { indent = 1 },
+ render = {
+ max_type_length = nil, -- Can be integer or nil.
+ max_value_lines = 100, -- Can be integer or nil.
+ },
+ },
+ },
+ }
+end
+
+M.setup = function()
+ 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)
+ vim.fn.sign_define("DapBreakpointRejected", lvim.builtin.dap.breakpoint_rejected)
+ vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped)
+ end
+
+ dap.set_log_level(lvim.builtin.dap.log.level)
+
+ return dap
+end
+
+M.setup_ui = function()
+ local status_ok, dap = pcall(require, "dap")
+ if not status_ok then
+ return
+ end
+ local dapui = require "dapui"
+ dapui.setup(lvim.builtin.dap.ui.config)
+
+ 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
+
+ local Log = require "lvim.core.log"
+
+ -- until rcarriga/nvim-dap-ui#164 is fixed
+ local function notify_handler(msg, level, opts)
+ if level >= lvim.builtin.dap.ui.notify.threshold then
+ return vim.notify(msg, level, opts)
+ end
+
+ opts = vim.tbl_extend("keep", opts or {}, {
+ title = "dap-ui",
+ icon = "",
+ on_open = function(win)
+ vim.api.nvim_buf_set_option(vim.api.nvim_win_get_buf(win), "filetype", "markdown")
+ end,
+ })
+
+ -- vim_log_level can be omitted
+ if level == nil then
+ level = Log.levels["INFO"]
+ elseif type(level) == "string" then
+ level = Log.levels[(level):upper()] or Log.levels["INFO"]
+ else
+ -- https://github.com/neovim/neovim/blob/685cf398130c61c158401b992a1893c2405cd7d2/runtime/lua/vim/lsp/log.lua#L5
+ level = level + 1
+ end
+
+ msg = string.format("%s: %s", opts.title, msg)
+ Log:add_entry(level, msg)
+ end
+
+ local dapui_ok, _ = xpcall(function()
+ require("dapui.util").notify = notify_handler
+ end, debug.traceback)
+ if not dapui_ok then
+ Log:debug "Unable to override dap-ui logging level"
+ end
+end
+
+return M
diff --git a/lua/lvim/core/builtins/gitsigns.lua b/lua/lvim/core/builtins/gitsigns.lua
new file mode 100644
index 00000000..27f50562
--- /dev/null
+++ b/lua/lvim/core/builtins/gitsigns.lua
@@ -0,0 +1,81 @@
+local M = {}
+
+M.config = function()
+ lvim.builtin.gitsigns = {
+ active = true,
+ opts = {
+ signs = {
+ add = {
+ hl = "GitSignsAdd",
+ text = lvim.icons.ui.BoldLineLeft,
+ numhl = "GitSignsAddNr",
+ linehl = "GitSignsAddLn",
+ },
+ change = {
+ hl = "GitSignsChange",
+ text = lvim.icons.ui.BoldLineLeft,
+ numhl = "GitSignsChangeNr",
+ linehl = "GitSignsChangeLn",
+ },
+ delete = {
+ hl = "GitSignsDelete",
+ text = lvim.icons.ui.Triangle,
+ numhl = "GitSignsDeleteNr",
+ linehl = "GitSignsDeleteLn",
+ },
+ topdelete = {
+ hl = "GitSignsDelete",
+ text = lvim.icons.ui.Triangle,
+ numhl = "GitSignsDeleteNr",
+ linehl = "GitSignsDeleteLn",
+ },
+ changedelete = {
+ hl = "GitSignsChange",
+ text = lvim.icons.ui.BoldLineLeft,
+ numhl = "GitSignsChangeNr",
+ linehl = "GitSignsChangeLn",
+ },
+ },
+ signcolumn = true,
+ numhl = false,
+ linehl = false,
+ word_diff = false,
+ watch_gitdir = {
+ interval = 1000,
+ follow_files = true,
+ },
+ attach_to_untracked = true,
+ current_line_blame = false, -- Toggle with `:Gitsigns toggle_current_line_blame`
+ current_line_blame_opts = {
+ virt_text = true,
+ virt_text_pos = "eol", -- 'eol' | 'overlay' | 'right_align'
+ delay = 1000,
+ ignore_whitespace = false,
+ },
+ current_line_blame_formatter = "<author>, <author_time:%Y-%m-%d> - <summary>",
+ sign_priority = 6,
+ status_formatter = nil, -- Use default
+ update_debounce = 200,
+ max_file_length = 40000,
+ preview_config = {
+ -- Options passed to nvim_open_win
+ border = "rounded",
+ style = "minimal",
+ relative = "cursor",
+ row = 0,
+ col = 1,
+ },
+ yadm = { enable = false },
+ },
+ }
+end
+
+M.setup = function()
+ local gitsigns = reload "gitsigns"
+
+ gitsigns.setup(lvim.builtin.gitsigns.opts)
+
+ return gitsigns
+end
+
+return M
diff --git a/lua/lvim/core/builtins/illuminate.lua b/lua/lvim/core/builtins/illuminate.lua
new file mode 100644
index 00000000..75afa362
--- /dev/null
+++ b/lua/lvim/core/builtins/illuminate.lua
@@ -0,0 +1,69 @@
+local M = {}
+
+M.config = function()
+ lvim.builtin.illuminate = {
+ active = true,
+ options = {
+ -- providers: provider used to get references in the buffer, ordered by priority
+ providers = {
+ "lsp",
+ "treesitter",
+ "regex",
+ },
+ -- delay: delay in milliseconds
+ delay = 120,
+ -- filetype_overrides: filetype specific overrides.
+ -- The keys are strings to represent the filetype while the values are tables that
+ -- supports the same keys passed to .configure except for filetypes_denylist and filetypes_allowlist
+ filetype_overrides = {},
+ -- filetypes_denylist: filetypes to not illuminate, this overrides filetypes_allowlist
+ filetypes_denylist = {
+ "dirvish",
+ "fugitive",
+ "alpha",
+ "NvimTree",
+ "lazy",
+ "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
+
+ return illuminate
+end
+
+return M
diff --git a/lua/lvim/core/builtins/indentlines.lua b/lua/lvim/core/builtins/indentlines.lua
new file mode 100644
index 00000000..43f025c6
--- /dev/null
+++ b/lua/lvim/core/builtins/indentlines.lua
@@ -0,0 +1,40 @@
+local M = {}
+
+M.config = function()
+ lvim.builtin.indentlines = {
+ active = true,
+ options = {
+ enabled = true,
+ buftype_exclude = { "terminal", "nofile" },
+ filetype_exclude = {
+ "help",
+ "startify",
+ "dashboard",
+ "lazy",
+ "neogitstatus",
+ "NvimTree",
+ "Trouble",
+ "text",
+ },
+ char = lvim.icons.ui.LineLeft,
+ context_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)
+
+ return indent_blankline
+end
+
+return M
diff --git a/lua/lvim/core/builtins/init.lua b/lua/lvim/core/builtins/init.lua
index 51b47b36..cd2946ab 100644
--- a/lua/lvim/core/builtins/init.lua
+++ b/lua/lvim/core/builtins/init.lua
@@ -1,26 +1,25 @@
local M = {}
local builtins = {
- "lvim.core.theme",
- "lvim.core.which-key",
- "lvim.core.gitsigns",
- "lvim.core.cmp",
- "lvim.core.dap",
- "lvim.core.terminal",
- "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",
- "lvim.core.comment",
- "lvim.core.lualine",
- "lvim.core.alpha",
- "lvim.core.mason",
+ "lvim.core.builtins.which-key",
+ "lvim.core.builtins.gitsigns",
+ "lvim.core.builtins.cmp",
+ "lvim.core.builtins.dap",
+ "lvim.core.builtins.terminal",
+ "lvim.core.builtins.telescope",
+ "lvim.core.builtins.treesitter",
+ "lvim.core.builtins.nvimtree",
+ "lvim.core.builtins.lir",
+ "lvim.core.builtins.illuminate",
+ "lvim.core.builtins.indentlines",
+ "lvim.core.builtins.breadcrumbs",
+ "lvim.core.builtins.project",
+ "lvim.core.builtins.bufferline",
+ "lvim.core.builtins.autopairs",
+ "lvim.core.builtins.comment",
+ "lvim.core.builtins.lualine",
+ "lvim.core.builtins.alpha",
+ "lvim.core.builtins.mason",
}
---@class LvimBuiltin
@@ -39,10 +38,10 @@ function M.init(config)
end
function M.setup(modname)
- local plugin = require("lvim.core." .. modname).setup()
+ local plugin = require("lvim.core.builtins." .. modname).setup()
local builtin_tbl = lvim.builtin[modname:gsub("-", "_")]
- if type(builtin_tbl.on_config_done) == "function" then
+ if plugin and type(builtin_tbl.on_config_done) == "function" then
builtin_tbl.on_config_done(plugin)
end
end
diff --git a/lua/lvim/core/builtins/lir.lua b/lua/lvim/core/builtins/lir.lua
new file mode 100644
index 00000000..9c59a99c
--- /dev/null
+++ b/lua/lvim/core/builtins/lir.lua
@@ -0,0 +1,117 @@
+local M = {}
+
+M.config = function()
+ local utils = require "lvim.utils.modules"
+ local actions = utils.require_on_exported_call "lir.actions"
+ local clipboard_actions = utils.require_on_exported_call "lir.clipboard.actions"
+
+ lvim.builtin.lir = {
+ active = true,
+ icon = "",
+ show_hidden_files = false,
+ ignore = {}, -- { ".DS_Store" "node_modules" } etc.
+ devicons = {
+ enable = true,
+ highlight_dirname = 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()
+ require("lir.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,
+ }
+ 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 }
+ )
+ end,
+ }
+end
+
+function M.icon_setup()
+ local devicons_ok, devicons = pcall(require, "nvim-web-devicons")
+ if not devicons_ok then
+ return
+ end
+
+ 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
+
+ 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
+
+ if not lvim.use_icons then
+ lvim.builtin.lir.devicons.enable = false
+ end
+
+ lir.setup(lvim.builtin.lir)
+ M.icon_setup()
+
+ return lir
+end
+
+return M
diff --git a/lua/lvim/core/builtins/lualine/colors.lua b/lua/lvim/core/builtins/lualine/colors.lua
new file mode 100644
index 00000000..4984cd1f
--- /dev/null
+++ b/lua/lvim/core/builtins/lualine/colors.lua
@@ -0,0 +1,16 @@
+local colors = {
+ bg = "#202328",
+ fg = "#bbc2cf",
+ yellow = "#ECBE7B",
+ cyan = "#008080",
+ darkblue = "#081633",
+ green = "#98be65",
+ orange = "#FF8800",
+ violet = "#a9a1e1",
+ magenta = "#c678dd",
+ purple = "#c678dd",
+ blue = "#51afef",
+ red = "#ec5f67",
+}
+
+return colors
diff --git a/lua/lvim/core/builtins/lualine/components.lua b/lua/lvim/core/builtins/lualine/components.lua
new file mode 100644
index 00000000..755c42af
--- /dev/null
+++ b/lua/lvim/core/builtins/lualine/components.lua
@@ -0,0 +1,179 @@
+local conditions = require "lvim.core.builtins.lualine.conditions"
+local colors = require "lvim.core.builtins.lualine.colors"
+
+local function diff_source()
+ local gitsigns = vim.b.gitsigns_status_dict
+ if gitsigns then
+ return {
+ added = gitsigns.added,
+ modified = gitsigns.changed,
+ removed = gitsigns.removed,
+ }
+ end
+end
+
+local branch = lvim.icons.git.Branch
+
+if lvim.colorscheme == "lunar" then
+ branch = "%#SLGitIcon#" .. lvim.icons.git.Branch .. "%*" .. "%#SLBranchName#"
+end
+
+return {
+ mode = {
+ function()
+ return " " .. lvim.icons.ui.Target .. " "
+ end,
+ padding = { left = 0, right = 0 },
+ color = {},
+ cond = nil,
+ },
+ branch = {
+ "b:gitsigns_head",
+ icon = branch,
+ color = { gui = "bold" },
+ },
+ filename = {
+ "filename",
+ color = {},
+ cond = nil,
+ },
+ diff = {
+ "diff",
+ source = diff_source,
+ 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 },
+ removed = { fg = colors.red },
+ },
+ cond = nil,
+ },
+ python_env = {
+ function()
+ local utils = require "lvim.core.builtins.lualine.utils"
+ if vim.bo.filetype == "python" then
+ local venv = os.getenv "CONDA_DEFAULT_ENV" or os.getenv "VIRTUAL_ENV"
+ if venv then
+ 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 ""
+ end,
+ color = { fg = colors.green },
+ cond = conditions.hide_in_width,
+ },
+ diagnostics = {
+ "diagnostics",
+ sources = { "nvim_diagnostic" },
+ 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 lvim.icons.ui.Tree
+ end,
+ color = function()
+ local buf = vim.api.nvim_get_current_buf()
+ local ts = vim.treesitter.highlighter.active[buf]
+ return { fg = ts and not vim.tbl_isempty(ts) and colors.green or colors.red }
+ end,
+ cond = conditions.hide_in_width,
+ },
+ lsp = {
+ function(msg)
+ msg = msg or "LS Inactive"
+ local buf_clients = vim.lsp.buf_get_clients()
+ if next(buf_clients) == nil then
+ -- TODO: clean up this if statement
+ if type(msg) == "boolean" or #msg == 0 then
+ return "LS Inactive"
+ end
+ return msg
+ 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" 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
+ local formatters = require "lvim.lsp.null-ls.formatters"
+ local supported_formatters = formatters.list_registered(buf_ft)
+ vim.list_extend(buf_client_names, supported_formatters)
+
+ -- add linter
+ local linters = require "lvim.lsp.null-ls.linters"
+ local supported_linters = linters.list_registered(buf_ft)
+ vim.list_extend(buf_client_names, supported_linters)
+
+ local unique_client_names = vim.fn.uniq(buf_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,
+ color = { gui = "bold" },
+ cond = conditions.hide_in_width,
+ },
+ location = { "location" },
+ progress = {
+ "progress",
+ fmt = function()
+ return "%P/%L"
+ end,
+ color = {},
+ },
+
+ spaces = {
+ function()
+ local shiftwidth = vim.api.nvim_buf_get_option(0, "shiftwidth")
+ return lvim.icons.ui.Tab .. " " .. shiftwidth
+ end,
+ padding = 1,
+ },
+ encoding = {
+ "o:encoding",
+ fmt = string.upper,
+ color = {},
+ cond = conditions.hide_in_width,
+ },
+ filetype = { "filetype", cond = nil, padding = { left = 1, right = 1 } },
+ scrollbar = {
+ function()
+ local current_line = vim.fn.line "."
+ local total_lines = vim.fn.line "$"
+ local chars = { "__", "▁▁", "▂▂", "▃▃", "▄▄", "▅▅", "▆▆", "▇▇", "██" }
+ local line_ratio = current_line / total_lines
+ local index = math.ceil(line_ratio * #chars)
+ return chars[index]
+ end,
+ padding = { left = 0, right = 0 },
+ color = "SLProgress",
+ cond = nil,
+ },
+}
diff --git a/lua/lvim/core/builtins/lualine/conditions.lua b/lua/lvim/core/builtins/lualine/conditions.lua
new file mode 100644
index 00000000..42d52a83
--- /dev/null
+++ b/lua/lvim/core/builtins/lualine/conditions.lua
@@ -0,0 +1,17 @@
+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.o.columns > window_width_limit
+ end,
+ -- check_git_workspace = function()
+ -- local filepath = vim.fn.expand "%:p:h"
+ -- local gitdir = vim.fn.finddir(".git", filepath .. ";")
+ -- return gitdir and #gitdir > 0 and #gitdir < #filepath
+ -- end,
+}
+
+return conditions
diff --git a/lua/lvim/core/builtins/lualine/init.lua b/lua/lvim/core/builtins/lualine/init.lua
new file mode 100644
index 00000000..102dd6e6
--- /dev/null
+++ b/lua/lvim/core/builtins/lualine/init.lua
@@ -0,0 +1,54 @@
+local M = {}
+M.config = function()
+ lvim.builtin.lualine = {
+ active = true,
+ style = "lvim",
+ options = {
+ icons_enabled = nil,
+ component_separators = nil,
+ section_separators = nil,
+ theme = nil,
+ disabled_filetypes = { statusline = { "alpha" } },
+ globalstatus = true,
+ },
+ sections = {
+ lualine_a = nil,
+ lualine_b = nil,
+ lualine_c = nil,
+ lualine_x = nil,
+ lualine_y = nil,
+ lualine_z = nil,
+ },
+ inactive_sections = {
+ lualine_a = nil,
+ lualine_b = nil,
+ lualine_c = nil,
+ lualine_x = nil,
+ lualine_y = nil,
+ lualine_z = nil,
+ },
+ tabline = nil,
+ extensions = nil,
+ }
+end
+
+M.setup = function()
+ 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.builtins.lualine.styles").update()
+
+ lualine.setup(lvim.builtin.lualine)
+
+ return lualine
+end
+
+return M
diff --git a/lua/lvim/core/builtins/lualine/styles.lua b/lua/lvim/core/builtins/lualine/styles.lua
new file mode 100644
index 00000000..50b07bdd
--- /dev/null
+++ b/lua/lvim/core/builtins/lualine/styles.lua
@@ -0,0 +1,165 @@
+local M = {}
+local components = require "lvim.core.builtins.lualine.components"
+
+local styles = {
+ lvim = nil,
+ default = nil,
+ none = nil,
+}
+
+styles.none = {
+ style = "none",
+ options = {
+ theme = "auto",
+ globalstatus = true,
+ icons_enabled = lvim.use_icons,
+ component_separators = { left = "", right = "" },
+ section_separators = { left = "", right = "" },
+ disabled_filetypes = {},
+ },
+ sections = {
+ lualine_a = {},
+ lualine_b = {},
+ lualine_c = {},
+ lualine_x = {},
+ lualine_y = {},
+ lualine_z = {},
+ },
+ inactive_sections = {
+ lualine_a = {},
+ lualine_b = {},
+ lualine_c = {},
+ lualine_x = {},
+ lualine_y = {},
+ lualine_z = {},
+ },
+ tabline = {},
+ extensions = {},
+}
+
+styles.default = {
+ style = "default",
+ options = {
+ theme = "auto",
+ globalstatus = true,
+ icons_enabled = lvim.use_icons,
+ 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 = {
+ lualine_a = { "mode" },
+ lualine_b = { "branch" },
+ lualine_c = { "filename" },
+ lualine_x = { "encoding", "fileformat", "filetype" },
+ lualine_y = { "progress" },
+ lualine_z = { "location" },
+ },
+ inactive_sections = {
+ lualine_a = {},
+ lualine_b = {},
+ lualine_c = { "filename" },
+ lualine_x = { "location" },
+ lualine_y = {},
+ lualine_z = {},
+ },
+ tabline = {},
+ extensions = {},
+}
+
+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" },
+ },
+ sections = {
+ lualine_a = {
+ 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,
+ },
+ },
+ inactive_sections = {
+ lualine_a = {
+ 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,
+ },
+ },
+ tabline = {},
+ extensions = {},
+}
+
+function M.get_style(style)
+ local style_keys = vim.tbl_keys(styles)
+ if not vim.tbl_contains(style_keys, style) then
+ local Log = require "lvim.core.log"
+ Log:error(
+ "Invalid lualine style"
+ .. string.format('"%s"', style)
+ .. "options are: "
+ .. string.format('"%s"', table.concat(style_keys, '", "'))
+ )
+ Log:debug '"lvim" style is applied.'
+ style = "lvim"
+ end
+
+ return vim.deepcopy(styles[style])
+end
+
+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/builtins/lualine/utils.lua b/lua/lvim/core/builtins/lualine/utils.lua
new file mode 100644
index 00000000..3fd3c2d3
--- /dev/null
+++ b/lua/lvim/core/builtins/lualine/utils.lua
@@ -0,0 +1,14 @@
+local M = {}
+
+function M.env_cleanup(venv)
+ if string.find(venv, "/") then
+ local final_venv = venv
+ for w in venv:gmatch "([^/]+)" do
+ final_venv = w
+ end
+ venv = final_venv
+ end
+ return venv
+end
+
+return M
diff --git a/lua/lvim/core/builtins/mason.lua b/lua/lvim/core/builtins/mason.lua
new file mode 100644
index 00000000..958b9e76
--- /dev/null
+++ b/lua/lvim/core/builtins/mason.lua
@@ -0,0 +1,91 @@
+local M = {}
+
+local join_paths = require("lvim.utils").join_paths
+
+function M.config()
+ lvim.builtin.mason = {
+ ui = {
+ border = "rounded",
+ keymaps = {
+ toggle_package_expand = "<CR>",
+ install_package = "i",
+ update_package = "u",
+ check_package_version = "c",
+ update_all_packages = "U",
+ check_outdated_packages = "C",
+ uninstall_package = "X",
+ cancel_installation = "<C-c>",
+ apply_language_filter = "<C-f>",
+ },
+ },
+
+ -- NOTE: should be available in $PATH
+ install_root_dir = join_paths(vim.fn.stdpath "data", "mason"),
+
+ -- NOTE: already handled in the bootstrap stage
+ PATH = "skip",
+
+ pip = {
+ -- These args will be added to `pip install` calls. Note that setting extra args might impact intended behavior
+ -- and is not recommended.
+ --
+ -- Example: { "--proxy", "https://proxyserver" }
+ install_args = {},
+ },
+
+ -- Controls to which degree logs are written to the log file. It's useful to set this to vim.log.levels.DEBUG when
+ -- debugging issues with package installations.
+ log_level = vim.log.levels.INFO,
+
+ -- Limit for the maximum amount of packages to be installed at the same time. Once this limit is reached, any further
+ -- packages that are requested to be installed will be put in a queue.
+ max_concurrent_installers = 4,
+
+ github = {
+ -- The template URL to use when downloading assets from GitHub.
+ -- The placeholders are the following (in order):
+ -- 1. The repository (e.g. "rust-lang/rust-analyzer")
+ -- 2. The release version (e.g. "v0.3.0")
+ -- 3. The asset name (e.g. "rust-analyzer-v0.3.0-x86_64-unknown-linux-gnu.tar.gz")
+ download_url_template = "https://github.com/%s/releases/download/%s/%s",
+ },
+ }
+end
+
+function M.get_prefix()
+ local default_prefix = join_paths(vim.fn.stdpath "data", "mason")
+ return vim.tbl_get(lvim.builtin, "mason", "install_root_dir") or default_prefix
+end
+
+---@param append boolean|nil whether to append to prepend to PATH
+local function add_to_path(append)
+ local p = join_paths(M.get_prefix(), "bin")
+ if vim.env.PATH:match(p) then
+ return
+ end
+ local string_separator = vim.loop.os_uname().version:match "Windows" and ";" or ":"
+ if append then
+ vim.env.PATH = vim.env.PATH .. string_separator .. p
+ else
+ vim.env.PATH = p .. string_separator .. vim.env.PATH
+ end
+end
+
+function M.bootstrap()
+ add_to_path()
+end
+
+function M.setup()
+ local status_ok, mason = pcall(reload, "mason")
+ if not status_ok then
+ return
+ end
+
+ add_to_path(lvim.builtin.mason.PATH == "append")
+
+ mason.setup(lvim.builtin.mason)
+
+ return mason
+end
+
+return M
diff --git a/lua/lvim/core/builtins/nvimtree.lua b/lua/lvim/core/builtins/nvimtree.lua
new file mode 100644
index 00000000..bf76407c
--- /dev/null
+++ b/lua/lvim/core/builtins/nvimtree.lua
@@ -0,0 +1,285 @@
+local M = {}
+local Log = require "lvim.core.log"
+
+function M.config()
+ lvim.builtin.nvimtree = {
+ active = true,
+ setup = {
+ auto_reload_on_write = false,
+ disable_netrw = false,
+ hijack_cursor = false,
+ hijack_netrw = true,
+ hijack_unnamed_buffer_when_opening = false,
+ ignore_buffer_on_setup = false,
+ sort_by = "name",
+ root_dirs = {},
+ prefer_startup_root = false,
+ sync_root_with_cwd = true,
+ reload_on_bufenter = false,
+ respect_buf_cwd = false,
+ on_attach = "disable",
+ remove_keymaps = false,
+ select_prompts = false,
+ view = {
+ adaptive_size = false,
+ centralize_selection = false,
+ width = 30,
+ hide_root_folder = false,
+ side = "left",
+ preserve_window_proportions = false,
+ number = false,
+ relativenumber = false,
+ signcolumn = "yes",
+ mappings = {
+ custom_only = false,
+ list = {},
+ },
+ float = {
+ enable = false,
+ quit_on_focus_loss = true,
+ open_win_config = {
+ relative = "editor",
+ border = "rounded",
+ width = 30,
+ height = 30,
+ row = 1,
+ col = 1,
+ },
+ },
+ },
+ renderer = {
+ add_trailing = false,
+ group_empty = false,
+ highlight_git = true,
+ full_name = false,
+ highlight_opened_files = "none",
+ root_folder_label = ":t",
+ indent_width = 2,
+ indent_markers = {
+ enable = false,
+ inline_arrows = true,
+ icons = {
+ corner = "└",
+ edge = "│",
+ item = "│",
+ none = " ",
+ },
+ },
+ icons = {
+ webdev_colors = lvim.use_icons,
+ git_placement = "before",
+ padding = " ",
+ symlink_arrow = " ➛ ",
+ show = {
+ file = lvim.use_icons,
+ folder = lvim.use_icons,
+ folder_arrow = lvim.use_icons,
+ git = lvim.use_icons,
+ },
+ glyphs = {
+ default = lvim.icons.ui.Text,
+ symlink = lvim.icons.ui.FileSymlink,
+ bookmark = lvim.icons.ui.BookMark,
+ folder = {
+ arrow_closed = lvim.icons.ui.TriangleShortArrowRight,
+ arrow_open = lvim.icons.ui.TriangleShortArrowDown,
+ default = lvim.icons.ui.Folder,
+ open = lvim.icons.ui.FolderOpen,
+ empty = lvim.icons.ui.EmptyFolder,
+ empty_open = lvim.icons.ui.EmptyFolderOpen,
+ symlink = lvim.icons.ui.FolderSymlink,
+ symlink_open = lvim.icons.ui.FolderOpen,
+ },
+ git = {
+ unstaged = lvim.icons.git.FileUnstaged,
+ staged = lvim.icons.git.FileStaged,
+ unmerged = lvim.icons.git.FileUnmerged,
+ renamed = lvim.icons.git.FileRenamed,
+ untracked = lvim.icons.git.FileUntracked,
+ deleted = lvim.icons.git.FileDeleted,
+ ignored = lvim.icons.git.FileIgnored,
+ },
+ },
+ },
+ special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" },
+ symlink_destination = true,
+ },
+ hijack_directories = {
+ enable = false,
+ auto_open = true,
+ },
+ update_focused_file = {
+ enable = true,
+ debounce_delay = 15,
+ update_root = true,
+ ignore_list = {},
+ },
+ diagnostics = {
+ enable = lvim.use_icons,
+ show_on_dirs = false,
+ show_on_open_dirs = true,
+ debounce_delay = 50,
+ severity = {
+ min = vim.diagnostic.severity.HINT,
+ max = vim.diagnostic.severity.ERROR,
+ },
+ icons = {
+ hint = lvim.icons.diagnostics.BoldHint,
+ info = lvim.icons.diagnostics.BoldInformation,
+ warning = lvim.icons.diagnostics.BoldWarning,
+ error = lvim.icons.diagnostics.BoldError,
+ },
+ },
+ filters = {
+ dotfiles = false,
+ git_clean = false,
+ no_buffer = false,
+ custom = { "node_modules", "\\.cache" },
+ exclude = {},
+ },
+ filesystem_watchers = {
+ enable = true,
+ debounce_delay = 50,
+ ignore_dirs = {},
+ },
+ git = {
+ enable = true,
+ ignore = false,
+ show_on_dirs = true,
+ show_on_open_dirs = true,
+ timeout = 200,
+ },
+ actions = {
+ use_system_clipboard = true,
+ change_dir = {
+ enable = true,
+ global = false,
+ restrict_above_cwd = false,
+ },
+ expand_all = {
+ max_folder_discovery = 300,
+ exclude = {},
+ },
+ file_popup = {
+ open_win_config = {
+ col = 1,
+ row = 1,
+ relative = "cursor",
+ border = "shadow",
+ style = "minimal",
+ },
+ },
+ open_file = {
+ quit_on_open = false,
+ resize_window = false,
+ window_picker = {
+ enable = true,
+ picker = "default",
+ chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
+ exclude = {
+ filetype = { "notify", "lazy", "qf", "diff", "fugitive", "fugitiveblame" },
+ buftype = { "nofile", "terminal", "help" },
+ },
+ },
+ },
+ remove_file = {
+ close_window = true,
+ },
+ },
+ trash = {
+ cmd = "trash",
+ require_confirm = true,
+ },
+ live_filter = {
+ prefix = "[FILTER]: ",
+ always_show_folders = true,
+ },
+ tab = {
+ sync = {
+ open = false,
+ close = false,
+ ignore = {},
+ },
+ },
+ notify = {
+ threshold = vim.log.levels.INFO,
+ },
+ log = {
+ enable = false,
+ truncate = false,
+ types = {
+ all = false,
+ config = false,
+ copy_paste = false,
+ dev = false,
+ diagnostics = false,
+ git = false,
+ profile = false,
+ watcher = false,
+ },
+ },
+ system_open = {
+ cmd = nil,
+ args = {},
+ },
+ },
+ }
+end
+
+function M.setup()
+ local status_ok, nvim_tree = pcall(require, "nvim-tree")
+ if not status_ok then
+ Log:error "Failed to load nvim-tree"
+ return
+ end
+
+ if lvim.builtin.nvimtree._setup_called then
+ Log:debug "ignoring repeated setup call for nvim-tree, see kyazdani42/nvim-tree.lua#1308"
+ return
+ end
+
+ lvim.builtin.nvimtree._setup_called = true
+
+ -- Implicitly update nvim-tree when project module is active
+ if lvim.builtin.project.active then
+ lvim.builtin.nvimtree.setup.respect_buf_cwd = true
+ lvim.builtin.nvimtree.setup.update_cwd = true
+ lvim.builtin.nvimtree.setup.update_focused_file = { enable = true, update_cwd = true }
+ end
+
+ local function telescope_find_files(_)
+ require("lvim.core.builtin.nvimtree").start_telescope "find_files"
+ end
+
+ local function telescope_live_grep(_)
+ require("lvim.core.builtin.nvimtree").start_telescope "live_grep"
+ end
+
+ -- Add useful keymaps
+ if #lvim.builtin.nvimtree.setup.view.mappings.list == 0 then
+ lvim.builtin.nvimtree.setup.view.mappings.list = {
+ { key = { "l", "<CR>", "o" }, action = "edit", mode = "n" },
+ { key = "h", action = "close_node" },
+ { key = "v", action = "vsplit" },
+ { key = "C", action = "cd" },
+ { key = "gtf", action = "telescope_find_files", action_cb = telescope_find_files },
+ { key = "gtg", action = "telescope_live_grep", action_cb = telescope_live_grep },
+ }
+ end
+
+ nvim_tree.setup(lvim.builtin.nvimtree.setup)
+
+ return nvim_tree
+end
+
+function M.start_telescope(telescope_mode)
+ local node = require("nvim-tree.lib").get_node_at_cursor()
+ local abspath = node.link_to or node.absolute_path
+ local is_folder = node.open ~= nil
+ local basedir = is_folder and abspath or vim.fn.fnamemodify(abspath, ":h")
+ require("telescope.builtin")[telescope_mode] {
+ cwd = basedir,
+ }
+end
+
+return M
diff --git a/lua/lvim/core/builtins/project.lua b/lua/lvim/core/builtins/project.lua
new file mode 100644
index 00000000..10c4a71f
--- /dev/null
+++ b/lua/lvim/core/builtins/project.lua
@@ -0,0 +1,64 @@
+local M = {}
+
+function M.config()
+ lvim.builtin.project = {
+ ---@usage set to false to disable project.nvim.
+ --- This is on by default since it's currently the expected behavior.
+ active = true,
+
+ ---@usage set to true to disable setting the current-woriking directory
+ --- Manual mode doesn't automatically change your root directory, so you have
+ --- the option to manually do so using `:ProjectRoot` command.
+ manual_mode = false,
+
+ ---@usage Methods of detecting the root directory
+ --- Allowed values: **"lsp"** uses the native neovim lsp
+ --- **"pattern"** uses vim-rooter like glob pattern matching. Here
+ --- order matters: if one is not detected, the other is used as fallback. You
+ --- can also delete or rearangne the detection methods.
+ -- detection_methods = { "lsp", "pattern" }, -- NOTE: lsp detection will get annoying with multiple langs in one project
+ detection_methods = { "pattern" },
+
+ -- All the patterns used to detect root dir, when **"pattern"** is in
+ -- detection_methods
+ patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "pom.xml" },
+
+ -- Table of lsp clients to ignore by name
+ -- eg: { "efm", ... }
+ ignore_lsp = {},
+
+ -- Don't calculate root dir on specific directories
+ -- Ex: { "~/.cargo/*", ... }
+ exclude_dirs = {},
+
+ -- Show hidden files in telescope
+ show_hidden = false,
+
+ -- When set to false, you will get a message when project.nvim changes your
+ -- directory.
+ silent_chdir = true,
+
+ -- What scope to change the directory, valid options are
+ -- * global (default)
+ -- * tab
+ -- * win
+ scope_chdir = "global",
+
+ ---@type string
+ ---@usage path to store the project history for use in telescope
+ datapath = get_cache_dir(),
+ }
+end
+
+function M.setup()
+ local status_ok, project = pcall(require, "project_nvim")
+ if not status_ok then
+ return
+ end
+
+ project.setup(lvim.builtin.project)
+
+ return project
+end
+
+return M
diff --git a/lua/lvim/core/builtins/telescope.lua b/lua/lvim/core/builtins/telescope.lua
new file mode 100644
index 00000000..576c70e9
--- /dev/null
+++ b/lua/lvim/core/builtins/telescope.lua
@@ -0,0 +1,147 @@
+local M = {}
+
+---@alias telescope_themes
+---| "cursor" # see `telescope.themes.get_cursor()`
+---| "dropdown" # see `telescope.themes.get_dropdown()`
+---| "ivy" # see `telescope.themes.get_ivy()`
+---| "center" # retain the default telescope theme
+
+function M.config()
+ local actions = require("lvim.utils.modules").require_on_exported_call "telescope.actions"
+ lvim.builtin.telescope = {
+ ---@usage disable telescope completely [not recommended]
+ active = true,
+ theme = "dropdown", ---@type telescope_themes
+ defaults = {
+ prompt_prefix = lvim.icons.ui.Telescope .. " ",
+ selection_caret = lvim.icons.ui.Forward .. " ",
+ entry_prefix = " ",
+ initial_mode = "insert",
+ selection_strategy = "reset",
+ sorting_strategy = nil,
+ layout_strategy = nil,
+ layout_config = {},
+ vimgrep_arguments = {
+ "rg",
+ "--color=never",
+ "--no-heading",
+ "--with-filename",
+ "--line-number",
+ "--column",
+ "--smart-case",
+ "--hidden",
+ "--glob=!.git/",
+ },
+ ---@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>"] = function(...)
+ actions.smart_send_to_qflist(...)
+ actions.open_qflist(...)
+ end,
+ ["<CR>"] = actions.select_default,
+ },
+ n = {
+ ["<C-n>"] = actions.move_selection_next,
+ ["<C-p>"] = actions.move_selection_previous,
+ ["<C-q>"] = function(...)
+ actions.smart_send_to_qflist(...)
+ actions.open_qflist(...)
+ end,
+ },
+ },
+ file_ignore_patterns = {},
+ path_display = { "smart" },
+ winblend = 0,
+ border = {},
+ borderchars = nil,
+ 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,
+ },
+ grep_string = {
+ only_sort_text = true,
+ },
+ buffers = {
+ initial_mode = "normal",
+ mappings = {
+ i = {
+ ["<C-d>"] = actions.delete_buffer,
+ },
+ n = {
+ ["dd"] = actions.delete_buffer,
+ },
+ },
+ },
+ planets = {
+ show_pluto = true,
+ show_moon = true,
+ },
+ git_files = {
+ hidden = true,
+ show_untracked = true,
+ },
+ colorscheme = {
+ enable_preview = true,
+ },
+ },
+ extensions = {
+ fzf = {
+ fuzzy = true, -- false will only do exact matching
+ override_generic_sorter = true, -- override the generic sorter
+ override_file_sorter = true, -- override the file sorter
+ case_mode = "smart_case", -- or "ignore_case" or "respect_case"
+ },
+ },
+ }
+end
+
+function M.setup()
+ local previewers = require "telescope.previewers"
+ local sorters = require "telescope.sorters"
+
+ lvim.builtin.telescope = vim.tbl_extend("keep", {
+ file_previewer = previewers.vim_buffer_cat.new,
+ grep_previewer = previewers.vim_buffer_vimgrep.new,
+ qflist_previewer = previewers.vim_buffer_qflist.new,
+ file_sorter = sorters.get_fuzzy_file,
+ generic_sorter = sorters.get_generic_fuzzy_sorter,
+ }, lvim.builtin.telescope)
+
+ local telescope = require "telescope"
+
+ local theme = require("telescope.themes")["get_" .. (lvim.builtin.telescope.theme or "")]
+ if theme then
+ lvim.builtin.telescope.defaults = theme(lvim.builtin.telescope.defaults)
+ end
+
+ telescope.setup(lvim.builtin.telescope)
+
+ if lvim.builtin.project.active then
+ pcall(function()
+ require("telescope").load_extension "projects"
+ end)
+ end
+
+ if lvim.builtin.telescope.extensions and lvim.builtin.telescope.extensions.fzf then
+ pcall(function()
+ require("telescope").load_extension "fzf"
+ end)
+ end
+
+ return telescope
+end
+
+return M
diff --git a/lua/lvim/core/builtins/terminal.lua b/lua/lvim/core/builtins/terminal.lua
new file mode 100644
index 00000000..2fc8ea9c
--- /dev/null
+++ b/lua/lvim/core/builtins/terminal.lua
@@ -0,0 +1,165 @@
+local M = {}
+local Log = require "lvim.core.log"
+
+M.config = function()
+ lvim.builtin["terminal"] = {
+ active = true,
+ -- size can be a number or function which is passed the current terminal
+ size = 20,
+ open_mapping = [[<c-\>]],
+ hide_numbers = true, -- hide the number column in toggleterm buffers
+ shade_filetypes = {},
+ shade_terminals = true,
+ shading_factor = 2, -- the degree by which to darken to terminal colour, default: 1 for dark backgrounds, 3 for light
+ start_in_insert = true,
+ insert_mappings = true, -- whether or not the open mapping applies in insert mode
+ persist_size = false,
+ -- direction = 'vertical' | 'horizontal' | 'window' | 'float',
+ direction = "float",
+ close_on_exit = true, -- close the terminal window when the process exits
+ shell = vim.o.shell, -- change the default shell
+ -- This field is only relevant if direction is set to 'float'
+ float_opts = {
+ -- The border key is *almost* the same as 'nvim_win_open'
+ -- see :h nvim_win_open for details on borders however
+ -- the 'curved' border is a custom border type
+ -- not natively supported but implemented in this plugin.
+ -- border = 'single' | 'double' | 'shadow' | 'curved' | ... other options supported by win open
+ border = "curved",
+ -- width = <value>,
+ -- height = <value>,
+ winblend = 0,
+ highlights = {
+ border = "Normal",
+ background = "Normal",
+ },
+ },
+ -- Add executables on the config.lua
+ -- { cmd, keymap, description, direction, size }
+ -- 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 = {
+ { nil, "<M-1>", "Horizontal Terminal", "horizontal", 0.3 },
+ { nil, "<M-2>", "Vertical Terminal", "vertical", 0.4 },
+ { nil, "<M-3>", "Float Terminal", "float", nil },
+ },
+ }
+end
+
+--- Get current buffer size
+---@return {width: number, height: number}
+local function get_buf_size()
+ local cbuf = vim.api.nvim_get_current_buf()
+ local bufinfo = vim.tbl_filter(function(buf)
+ return buf.bufnr == cbuf
+ end, vim.fn.getwininfo(vim.api.nvim_get_current_win()))[1]
+ if bufinfo == nil then
+ return { width = -1, height = -1 }
+ end
+ return { width = bufinfo.width, height = bufinfo.height }
+end
+
+--- Get the dynamic terminal size in cells
+---@param direction number
+---@param size number
+---@return integer
+local function get_dynamic_terminal_size(direction, size)
+ size = size or lvim.builtin.terminal.size
+ if direction ~= "float" and tostring(size):find(".", 1, true) then
+ size = math.min(size, 1.0)
+ local buf_sizes = get_buf_size()
+ local buf_size = direction == "horizontal" and buf_sizes.height or buf_sizes.width
+ return buf_size * size
+ else
+ return size
+ end
+end
+
+M.setup = function()
+ local terminal = require "toggleterm"
+ terminal.setup(lvim.builtin.terminal)
+
+ for i, exec in pairs(lvim.builtin.terminal.execs) do
+ local direction = exec[4] or lvim.builtin.terminal.direction
+
+ local opts = {
+ cmd = exec[1] or lvim.builtin.terminal.shell,
+ keymap = exec[2],
+ label = exec[3],
+ -- NOTE: unable to consistently bind id/count <= 9, see #2146
+ count = i + 100,
+ direction = direction,
+ size = function()
+ return get_dynamic_terminal_size(direction, exec[5])
+ end,
+ }
+
+ M.add_exec(opts)
+ end
+
+ return terminal
+end
+
+M.add_exec = function(opts)
+ local binary = opts.cmd:match "(%S+)"
+ if vim.fn.executable(binary) ~= 1 then
+ Log:debug("Skipping configuring executable " .. binary .. ". Please make sure it is installed properly.")
+ return
+ end
+
+ vim.keymap.set({ "n", "t" }, opts.keymap, function()
+ 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(opts.size, opts.direction)
+end
+
+---Toggles a log viewer according to log.viewer.layout_config
+---@param logfile string the fullpath to the logfile
+M.toggle_log_view = function(logfile)
+ local log_viewer = lvim.log.viewer.cmd
+ if vim.fn.executable(log_viewer) ~= 1 then
+ log_viewer = "less +F"
+ end
+ Log:debug("attempting to open: " .. logfile)
+ log_viewer = log_viewer .. " " .. logfile
+ local term_opts = vim.tbl_deep_extend("force", lvim.builtin.terminal, {
+ cmd = log_viewer,
+ open_mapping = lvim.log.viewer.layout_config.open_mapping,
+ direction = lvim.log.viewer.layout_config.direction,
+ -- TODO: this might not be working as expected
+ size = lvim.log.viewer.layout_config.size,
+ float_opts = lvim.log.viewer.layout_config.float_opts,
+ })
+
+ local Terminal = require("toggleterm.terminal").Terminal
+ local log_view = Terminal:new(term_opts)
+ 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/builtins/treesitter.lua b/lua/lvim/core/builtins/treesitter.lua
new file mode 100644
index 00000000..c0cbb653
--- /dev/null
+++ b/lua/lvim/core/builtins/treesitter.lua
@@ -0,0 +1,116 @@
+local M = {}
+local Log = require "lvim.core.log"
+
+function M.config()
+ lvim.builtin.treesitter = {
+ -- A list of parser names, or "all"
+ ensure_installed = {},
+
+ -- List of parsers to ignore installing (for "all")
+ ignore_install = {},
+
+ -- A directory to install the parsers into.
+ -- By default parsers are installed to either the package dir, or the "site" dir.
+ -- If a custom path is used (not nil) it must be added to the runtimepath.
+ parser_install_dir = nil,
+
+ -- Install parsers synchronously (only applied to `ensure_installed`)
+ sync_install = false,
+
+ -- Automatically install missing parsers when entering buffer
+ auto_install = true,
+
+ matchup = {
+ enable = false, -- mandatory, false will disable the whole extension
+ -- disable = { "c", "ruby" }, -- optional, list of language that will be disabled
+ },
+ highlight = {
+ enable = true, -- false will disable the whole extension
+ additional_vim_regex_highlighting = false,
+ disable = function(lang, buf)
+ if vim.tbl_contains({ "latex" }, lang) then
+ return true
+ end
+
+ local status_ok, big_file_detected = pcall(vim.api.nvim_buf_get_var, buf, "bigfile_disable_treesitter")
+ return status_ok and big_file_detected
+ end,
+ },
+ context_commentstring = {
+ enable = true,
+ enable_autocmd = false,
+ config = {
+ -- Languages that have a single comment style
+ typescript = "// %s",
+ css = "/* %s */",
+ scss = "/* %s */",
+ html = "<!-- %s -->",
+ svelte = "<!-- %s -->",
+ vue = "<!-- %s -->",
+ json = "",
+ },
+ },
+ indent = { enable = true, disable = { "yaml", "python" } },
+ autotag = { enable = false },
+ textobjects = {
+ swap = {
+ enable = false,
+ -- swap_next = textobj_swap_keymaps,
+ },
+ -- move = textobj_move_keymaps,
+ select = {
+ enable = false,
+ -- keymaps = textobj_sel_keymaps,
+ },
+ },
+ textsubjects = {
+ enable = false,
+ keymaps = { ["."] = "textsubjects-smart", [";"] = "textsubjects-big" },
+ },
+ playground = {
+ enable = false,
+ disable = {},
+ updatetime = 25, -- Debounced time for highlighting nodes in the playground from source code
+ persist_queries = false, -- Whether the query persists across vim sessions
+ keybindings = {
+ toggle_query_editor = "o",
+ toggle_hl_groups = "i",
+ toggle_injected_languages = "t",
+ toggle_anonymous_nodes = "a",
+ toggle_language_display = "I",
+ focus_language = "f",
+ unfocus_language = "F",
+ update = "R",
+ goto_node = "<cr>",
+ show_help = "?",
+ },
+ },
+ rainbow = {
+ enable = false,
+ extended_mode = true, -- Highlight also non-parentheses delimiters, boolean or table: lang -> boolean
+ max_file_lines = 1000, -- Do not enable for files with more than 1000 lines, int
+ },
+ }
+end
+
+function M.setup()
+ -- 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 treesitter"
+ return
+ end
+
+ local status_ok, treesitter_configs = pcall(require, "nvim-treesitter.configs")
+ if not status_ok then
+ Log:error "Failed to load nvim-treesitter.configs"
+ return
+ end
+
+ local opts = vim.deepcopy(lvim.builtin.treesitter)
+
+ treesitter_configs.setup(opts)
+
+ return require "nvim-treesitter"
+end
+
+return M
diff --git a/lua/lvim/core/builtins/which-key.lua b/lua/lvim/core/builtins/which-key.lua
new file mode 100644
index 00000000..cdfc91e4
--- /dev/null
+++ b/lua/lvim/core/builtins/which-key.lua
@@ -0,0 +1,319 @@
+local M = {}
+M.config = function()
+ lvim.builtin.which_key = {
+ ---@usage disable which-key completely [not recommended]
+ active = true,
+ setup = {
+ plugins = {
+ marks = false, -- shows a list of your marks on ' and `
+ registers = false, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
+ spelling = {
+ enabled = true,
+ suggestions = 20,
+ }, -- use which-key for spelling hints
+ -- the presets plugin, adds help for a bunch of default keybindings in Neovim
+ -- No actual key bindings are created
+ presets = {
+ operators = false, -- adds help for operators like d, y, ...
+ 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 = 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
+ },
+ },
+ -- add operators that will trigger motion and text object completion
+ -- to enable all native operators, set the preset / operators plugin above
+ operators = { gc = "Comments" },
+ key_labels = {
+ -- override the label used to display some keys. It doesn't effect WK in any other way.
+ -- For example:
+ -- ["<space>"] = "SPC",
+ -- ["<cr>"] = "RET",
+ -- ["<tab>"] = "TAB",
+ },
+ icons = {
+ 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
+ scroll_up = "<c-u>", -- binding to scroll up inside the popup
+ },
+ window = {
+ border = "single", -- none, single, double, shadow
+ position = "bottom", -- bottom, top
+ margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]
+ padding = { 2, 2, 2, 2 }, -- extra window padding [top, right, bottom, left]
+ winblend = 0,
+ },
+ layout = {
+ height = { min = 4, max = 25 }, -- min and max height of the columns
+ width = { min = 20, max = 50 }, -- min and max width of the columns
+ spacing = 3, -- spacing between columns
+ align = "left", -- align columns left, center or right
+ },
+ ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
+ hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "call", "lua", "^:", "^ " }, -- hide mapping boilerplate
+ show_help = true, -- show help message on the command line when the popup is visible
+ show_keys = true, -- show the currently pressed key and its label as a message in the command line
+ triggers = "auto", -- automatically setup triggers
+ -- triggers = {"<leader>"} -- or specify a list manually
+ triggers_blacklist = {
+ -- list of mode / prefixes that should never be hooked by WhichKey
+ -- this is mostly relevant for key maps that start with a native binding
+ -- most people should not need to change this
+ i = { "j", "k" },
+ v = { "j", "k" },
+ },
+ -- disable the WhichKey popup for certain buf types and file types.
+ -- Disabled by deafult for Telescope
+ disable = {
+ buftypes = {},
+ filetypes = { "TelescopePrompt" },
+ },
+ },
+
+ opts = {
+ mode = "n", -- NORMAL mode
+ prefix = "<leader>",
+ buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
+ silent = true, -- use `silent` when creating keymaps
+ noremap = true, -- use `noremap` when creating keymaps
+ nowait = true, -- use `nowait` when creating keymaps
+ },
+ vopts = {
+ mode = "v", -- VISUAL mode
+ prefix = "<leader>",
+ buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
+ silent = true, -- use `silent` when creating keymaps
+ noremap = true, -- use `noremap` when creating keymaps
+ nowait = true, -- use `nowait` when creating keymaps
+ },
+ -- NOTE: Prefer using : over <cmd> as the latter avoids going back in normal-mode.
+ -- see https://neovim.io/doc/user/map.html#:map-cmd
+ vmappings = {
+ ["/"] = { "<Plug>(comment_toggle_linewise_visual)", "Comment toggle linewise (visual)" },
+ },
+ mappings = {
+ [";"] = { "<cmd>Alpha<CR>", "Dashboard" },
+ ["w"] = { "<cmd>w!<CR>", "Save" },
+ ["q"] = { "<cmd>confirm q<CR>", "Quit" },
+ ["/"] = { "<Plug>(comment_toggle_linewise_current)", "Comment toggle current line" },
+ ["c"] = { "<cmd>BufferKill<CR>", "Close Buffer" },
+ ["f"] = {
+ function()
+ require("lvim.core.telescope.custom-finders").find_project_files { previewer = false }
+ end,
+ "Find File",
+ },
+ ["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },
+ ["e"] = { "<cmd>NvimTreeToggle<CR>", "Explorer" },
+ b = {
+ name = "Buffers",
+ j = { "<cmd>BufferLinePick<cr>", "Jump" },
+ f = { "<cmd>Telescope buffers previewer=false<cr>", "Find" },
+ b = { "<cmd>BufferLineCyclePrev<cr>", "Previous" },
+ n = { "<cmd>BufferLineCycleNext<cr>", "Next" },
+ W = { "<cmd>noautocmd w<cr>", "Save without formatting (noautocmd)" },
+ -- w = { "<cmd>BufferWipeout<cr>", "Wipeout" }, -- TODO: implement this for bufferline
+ e = {
+ "<cmd>BufferLinePickClose<cr>",
+ "Pick which buffer to close",
+ },
+ h = { "<cmd>BufferLineCloseLeft<cr>", "Close all to the left" },
+ l = {
+ "<cmd>BufferLineCloseRight<cr>",
+ "Close all to the right",
+ },
+ D = {
+ "<cmd>BufferLineSortByDirectory<cr>",
+ "Sort by directory",
+ },
+ L = {
+ "<cmd>BufferLineSortByExtension<cr>",
+ "Sort by language",
+ },
+ },
+ d = {
+ name = "Debug",
+ t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" },
+ b = { "<cmd>lua require'dap'.step_back()<cr>", "Step Back" },
+ c = { "<cmd>lua require'dap'.continue()<cr>", "Continue" },
+ C = { "<cmd>lua require'dap'.run_to_cursor()<cr>", "Run To Cursor" },
+ d = { "<cmd>lua require'dap'.disconnect()<cr>", "Disconnect" },
+ g = { "<cmd>lua require'dap'.session()<cr>", "Get Session" },
+ i = { "<cmd>lua require'dap'.step_into()<cr>", "Step Into" },
+ o = { "<cmd>lua require'dap'.step_over()<cr>", "Step Over" },
+ u = { "<cmd>lua require'dap'.step_out()<cr>", "Step Out" },
+ p = { "<cmd>lua require'dap'.pause()<cr>", "Pause" },
+ 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({reset = true})<cr>", "Toggle UI" },
+ },
+ p = {
+ name = "Plugins",
+ i = { "<cmd>Lazy install<cr>", "Install" },
+ s = { "<cmd>Lazy sync<cr>", "Sync" },
+ S = { "<cmd>Lazy clear<cr>", "Status" },
+ c = { "<cmd>Lazy clean<cr>", "Clean" },
+ u = { "<cmd>Lazy update<cr>", "Update" },
+ p = { "<cmd>Lazy profile<cr>", "Profile" },
+ l = { "<cmd>Lazy log<cr>", "Log" },
+ d = { "<cmd>Lazy debug<cr>", "Debug" },
+ },
+
+ -- " Available Debug Adapters:
+ -- " https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/
+ -- " Adapter configuration and installation instructions:
+ -- " https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation
+ -- " Debug Adapter protocol:
+ -- " https://microsoft.github.io/debug-adapter-protocol/
+ -- " Debugging
+ g = {
+ name = "Git",
+ 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" },
+ R = { "<cmd>lua require 'gitsigns'.reset_buffer()<cr>", "Reset Buffer" },
+ s = { "<cmd>lua require 'gitsigns'.stage_hunk()<cr>", "Stage Hunk" },
+ u = {
+ "<cmd>lua require 'gitsigns'.undo_stage_hunk()<cr>",
+ "Undo Stage Hunk",
+ },
+ o = { "<cmd>Telescope git_status<cr>", "Open changed file" },
+ b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },
+ c = { "<cmd>Telescope git_commits<cr>", "Checkout commit" },
+ C = {
+ "<cmd>Telescope git_bcommits<cr>",
+ "Checkout commit(for current file)",
+ },
+ d = {
+ "<cmd>Gitsigns diffthis HEAD<cr>",
+ "Git Diff",
+ },
+ },
+ l = {
+ name = "LSP",
+ a = { "<cmd>lua vim.lsp.buf.code_action()<cr>", "Code Action" },
+ d = { "<cmd>Telescope diagnostics bufnr=0 theme=get_ivy<cr>", "Buffer Diagnostics" },
+ w = { "<cmd>Telescope diagnostics<cr>", "Diagnostics" },
+ f = { "<cmd>lua require('lvim.lsp.utils').format()<cr>", "Format" },
+ i = { "<cmd>LspInfo<cr>", "Info" },
+ I = { "<cmd>Mason<cr>", "Mason Info" },
+ j = {
+ "<cmd>lua vim.diagnostic.goto_next()<cr>",
+ "Next Diagnostic",
+ },
+ k = {
+ "<cmd>lua vim.diagnostic.goto_prev()<cr>",
+ "Prev Diagnostic",
+ },
+ l = { "<cmd>lua vim.lsp.codelens.run()<cr>", "CodeLens Action" },
+ q = { "<cmd>lua vim.diagnostic.setloclist()<cr>", "Quickfix" },
+ r = { "<cmd>lua vim.lsp.buf.rename()<cr>", "Rename" },
+ s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" },
+ S = {
+ "<cmd>Telescope lsp_dynamic_workspace_symbols<cr>",
+ "Workspace Symbols",
+ },
+ e = { "<cmd>Telescope quickfix<cr>", "Telescope Quickfix" },
+ },
+ L = {
+ name = "+LunarVim",
+ c = {
+ "<cmd>edit " .. get_config_dir() .. "/config.lua<cr>",
+ "Edit config.lua",
+ },
+ d = { "<cmd>LvimDocs<cr>", "View LunarVim's docs" },
+ f = {
+ "<cmd>lua require('lvim.core.telescope.custom-finders').find_lunarvim_files()<cr>",
+ "Find LunarVim files",
+ },
+ g = {
+ "<cmd>lua require('lvim.core.telescope.custom-finders').grep_lunarvim_files()<cr>",
+ "Grep LunarVim files",
+ },
+ k = { "<cmd>Telescope keymaps<cr>", "View LunarVim's keymappings" },
+ i = {
+ "<cmd>lua require('lvim.core.info').toggle_popup(vim.bo.filetype)<cr>",
+ "Toggle LunarVim Info",
+ },
+ I = {
+ "<cmd>lua require('lvim.core.telescope.custom-finders').view_lunarvim_changelog()<cr>",
+ "View LunarVim's changelog",
+ },
+ l = {
+ name = "+logs",
+ d = {
+ "<cmd>lua require('lvim.core.terminal').toggle_log_view(require('lvim.core.log').get_path())<cr>",
+ "view default log",
+ },
+ D = {
+ "<cmd>lua vim.fn.execute('edit ' .. require('lvim.core.log').get_path())<cr>",
+ "Open the default logfile",
+ },
+ l = {
+ "<cmd>lua require('lvim.core.terminal').toggle_log_view(vim.lsp.get_log_path())<cr>",
+ "view lsp log",
+ },
+ L = { "<cmd>lua vim.fn.execute('edit ' .. vim.lsp.get_log_path())<cr>", "Open the LSP logfile" },
+ n = {
+ "<cmd>lua require('lvim.core.terminal').toggle_log_view(os.getenv('NVIM_LOG_FILE'))<cr>",
+ "view neovim log",
+ },
+ N = { "<cmd>edit $NVIM_LOG_FILE<cr>", "Open the Neovim logfile" },
+ },
+ r = { "<cmd>LvimReload<cr>", "Reload LunarVim's configuration" },
+ u = { "<cmd>LvimUpdate<cr>", "Update LunarVim" },
+ },
+ s = {
+ name = "Search",
+ b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },
+ c = { "<cmd>Telescope colorscheme<cr>", "Colorscheme" },
+ f = { "<cmd>Telescope find_files<cr>", "Find File" },
+ h = { "<cmd>Telescope help_tags<cr>", "Find Help" },
+ H = { "<cmd>Telescope highlights<cr>", "Find highlight groups" },
+ M = { "<cmd>Telescope man_pages<cr>", "Man Pages" },
+ r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
+ R = { "<cmd>Telescope registers<cr>", "Registers" },
+ t = { "<cmd>Telescope live_grep<cr>", "Text" },
+ k = { "<cmd>Telescope keymaps<cr>", "Keymaps" },
+ C = { "<cmd>Telescope commands<cr>", "Commands" },
+ p = {
+ "<cmd>lua require('telescope.builtin').colorscheme({enable_preview = true})<cr>",
+ "Colorscheme with Preview",
+ },
+ },
+ T = {
+ name = "Treesitter",
+ i = { ":TSConfigInfo<cr>", "Info" },
+ },
+ },
+ }
+end
+
+M.setup = function()
+ local which_key = require "which-key"
+
+ which_key.setup(lvim.builtin.which_key.setup)
+
+ local opts = lvim.builtin.which_key.opts
+ local vopts = lvim.builtin.which_key.vopts
+
+ local mappings = lvim.builtin.which_key.mappings
+ local vmappings = lvim.builtin.which_key.vmappings
+
+ which_key.register(mappings, opts)
+ which_key.register(vmappings, vopts)
+
+ return which_key
+end
+
+return M