diff --git a/.gitignore b/.gitignore index cdcfd0e..9ee428d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ debug/ .ignore-deps profile.json rocks.toml + /home/rootiest/.cache/nvim diff --git a/init.lua b/init.lua index 71734d4..9bc8238 100644 --- a/init.lua +++ b/init.lua @@ -51,9 +51,6 @@ -- ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ -- The rootiest NeoVim configuration! ----━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ OPTIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ --- Neovim options are configured in the lua/config/options.lua file - ---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ROOTIEST ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -- Rootiest Configuration require("config.rootiest").setup() -- Set up Rootiest options @@ -78,5 +75,47 @@ require("config.profile") -- Set profiling options with environment variables: -- │ :lua require("profile").start("lualine") │ -- ╰─────────────────────────────────────────────────────────────────────╯ +-- ╔═════════════════════════════════════════════════════════╗ +-- ║ CONFIGURATION STRUCTURE ║ +-- ╚═════════════════════════════════════════════════════════╝ +-- ╭─────────────────────────────────────────────────────────────────────╮ +-- │ Configuration modules are organized into categories: │ +-- │ - Options │ +-- │ - Keymaps │ +-- │ - Autocommands │ +-- │ - Utility functions │ +-- │ - Plugins │ +-- │ - Commands │ +-- │ - Dashboards │ +-- │ - Types │ +-- │ - Dependencies │ +-- ╰─────────────────────────────────────────────────────────────────────╯ +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ OPTIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Neovim options are configured in the lua/config/options.lua file + ---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ KEYMAPS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ --- Custom keymaps are configured in the lua/config/keymaps.lua file +-- Custom keymaps and plugin keys are configured in the lua/data/keys.lua file + +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ AUTOCOMMANDS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Custom autocommands are configured in the lua/config/autocmds.lua file + +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ UTILITY FUNCTIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Utility functions can be found in the lua/data/func.lua file + +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ PLUGINS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Plugin specs are defined in the lua/config/plugins.lua file +-- Plugin keys, cmds, dependencies, and opts/config tables are +-- defined in the lua/data/*.lua files. This allows all plugin configurations +-- to be defined in a centralized location and keeps them organised. + +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ COMMANDS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Plugin cmds are configured in the lua/data/cmds.lua file + +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ DASHBOARDS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Dashboard configurations can be found in the lua/data/dash.lua file + +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TYPES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Plugin configuration tables are configured in the lua/data/types.lua file + +---━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ DEPENDENCIES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +-- Plugin depenendencies are configured in the lua/data/deps.lua file diff --git a/lua/config/autocmds.lua b/lua/config/autocmds.lua index 411fb11..8350d37 100644 --- a/lua/config/autocmds.lua +++ b/lua/config/autocmds.lua @@ -1,3 +1,5 @@ +--- @module "config.autocmds" +--- This module defines the autocommands for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Autocommands │ -- ╰─────────────────────────────────────────────────────────╯ @@ -52,6 +54,18 @@ autocmd({ "BufEnter", "FocusGained" }, { end, }) +-- TodoFzfLua command override to use Telescope +-- when fzf-lua is not installed +autogrp("TodoFzfLua", { clear = true }) +autocmd({ "BufEnter" }, { + group = "TodoFzfLua", + callback = function() + if not pcall(require, "fzf-lua") then + vim.cmd([[command! -nargs=* TodoFzfLua :TodoTelescope]]) + end + end, +}) + -- Set up autocommands and highlight settings local load_highlight = require("utils.highlight") load_highlight.setup_autocommands() diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index abbfb31..18f1e12 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -1,3 +1,6 @@ +--- @module "config.keymaps" +--- This module defines the keymapping operations for the Neovim configuration. +--- The actual keybindings are defined in lua/data/keys.lua -- ╭─────────────────────────────────────────────────────────╮ -- │ Keybinds │ -- ╰─────────────────────────────────────────────────────────╯ diff --git a/lua/config/lazy.lua b/lua/config/lazy.lua index 8feee8c..076a920 100644 --- a/lua/config/lazy.lua +++ b/lua/config/lazy.lua @@ -1,8 +1,9 @@ +---@module "config.lazy" +--- This module bootstraps Lazy.nvim. +--- Lazy is a plugin manager for Neovim. -- ╭─────────────────────────────────────────────────────────╮ -- │ Lazy │ -- ╰─────────────────────────────────────────────────────────╯ ----@module "config.lazy" ---- Bootstrap the lazy.nvim plugin manager local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not vim.uv.fs_stat(lazypath) then -- stylua: ignore @@ -17,14 +18,28 @@ end vim.opt.rtp:prepend(vim.env.LAZY or lazypath) -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ PLUGINS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -require("lazy").setup({ - spec = { - { - "LazyVim/LazyVim", - import = "lazyvim.plugins", - }, - { import = "plugins" }, -- General Plugins + +local plugin_specs = { + { + "LazyVim/LazyVim", -- LazyVim + import = "lazyvim.plugins", -- LazyVim Core Plugins }, + { import = "plugins" }, -- General Plugins +} + +-- Automatically import all subdirectories of `lua/plugins` +local plugin_dirs = vim.fn.glob("~/.config/nvim/lua/plugins/*", true, true) +for _, dir in ipairs(plugin_dirs) do + if vim.fn.isdirectory(dir) == 1 then + table.insert( -- Add directory to the plugin import table + plugin_specs, + { import = "plugins." .. vim.fn.fnamemodify(dir, ":t") } + ) + end +end + +require("lazy").setup({ + spec = plugin_specs, defaults = { lazy = false, version = false, @@ -44,7 +59,6 @@ require("lazy").setup({ }, }, profiling = { - -- Track the time spent loading plugins loader = true, require = true, }, diff --git a/lua/config/neovide.lua b/lua/config/neovide.lua index 0479fe7..39028c9 100644 --- a/lua/config/neovide.lua +++ b/lua/config/neovide.lua @@ -1,3 +1,5 @@ +--- @module "config.neovide" +--- This module defines the neovide options for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Neovide │ -- ╰─────────────────────────────────────────────────────────╯ diff --git a/lua/config/options.lua b/lua/config/options.lua index ced9e84..06cafd5 100644 --- a/lua/config/options.lua +++ b/lua/config/options.lua @@ -1,41 +1,78 @@ +--- @module "config.options" +--- This module defines the user options for the Neovim configuration. +--- Variables defined here set configuration options for the rest +--- of the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Options │ -- ╰─────────────────────────────────────────────────────────╯ -- stylua: ignore start -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Leader Key ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -vim.g.mapleader = " " --- @type string Options: -vim.g.maplocalleader = " " --- @type string Options: +vim.g.mapleader = " " ---@type string Options: +vim.g.maplocalleader = " " ---@type string Options: -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ LSP ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -- We don't need perl -vim.g.loaded_perl_provider = 0 --- @type integer Options: <0|1> -vim.g.loaded_ruby_provider = 0 --- @type integer Options: <0|1> +vim.g.loaded_perl_provider = 0 ---@type integer Options: <0|1> +vim.g.loaded_ruby_provider = 0 ---@type integer Options: <0|1> -- Prefer basedpyright -vim.g.lazyvim_python_lsp = "basedpyright" --- @type string Options: [python lsp] +vim.g.lazyvim_python_lsp = "basedpyright" ---@type string Options: [python lsp] -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ OS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -- Check if we are on windows vim.g.is_windows = vim.fn.has("win32") == 1 or vim.fn.has("win64") == 1 -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ROOTIEST ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ --- ╭───────────────────────────╮ Options: --- │ │  codeium --- │ AI Tools: │  copilot --- │ Choose an AI provider │  tabnine --- │ from the list  │  minuet --- │ │  ollama --- ╰───────────────────────────╯  none - vim.g.aitool = "codeium" --- @type string Options: [ai tool] +vim.g.usewakatime = true ---@type boolean Options: +vim.g.usemusic = true ---@type boolean Options: +vim.g.usehardtime = false ---@type boolean Options: +vim.g.useimage = true ---@type boolean Options: +vim.g.ignore_no_lazy = false ---@type boolean Options: +vim.g.codesnap = true ---@type boolean Options: +vim.g.auto_cursorline = true ---@type boolean Options: +vim.g.auto_save = true ---@type boolean Options: -vim.g.usewakatime = true --- @type boolean Options: -vim.g.usehardtime = false --- @type boolean Options: -vim.g.useimage = true --- @type boolean Options: +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ AI TOOL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +vim.g.aitool = "codeium" ---@type string Options: [ai tool] +-- ╭───────────────────────────╮  codeium +-- │ │  copilot +-- │ AI Tools: │  tabnine +-- │ Choose an AI provider │  minuet +-- │ from the list  │  ollama +-- │ │  none +-- ╰───────────────────────────╯ --- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Lualine Stats ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -vim.g.stats_wakatime = true --- @type boolean Options: -vim.g.stats_music = true --- @type boolean Options: -vim.g.stats_ignored_players = { --- @type string[] Options: [ignored players] +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ STATUS LINE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +vim.g.statusline = "lualine" ---@type string Options: [statusline] +-- ╭───────────────────────────╮  lualine +-- │ │  heirline +-- │ Status Lines: │  basic +-- │ Choose a plugin from │  none +-- │ the list  │ +-- │ │ +-- ╰───────────────────────────╯ +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ STATUS COLUMN ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +vim.g.statuscolumn = "native" ---@type string Options: [statuscolumn] +-- ╭───────────────────────────╮  barsNlines +-- │ │  native +-- │ Status Columns: │ +-- │ Choose a plugin from │ +-- │ the list  │ +-- │ │ +-- ╰───────────────────────────╯ +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BUFFER LINE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +vim.g.tabline = "bufferline" ---@type string Options: [tabline] +-- ╭───────────────────────────╮  bufferline +-- │ │  barsNlines +-- │ Tab Lines: │  none +-- │ Choose a plugin from │ +-- │ the list  │ +-- │ │ +-- ╰───────────────────────────╯ +vim.g.statusline_clickable_git = false ---@type boolean Options: +vim.g.stats_wakatime = true ---@type boolean Options: +vim.g.stats_music = true ---@type boolean Options: +vim.g.stats_ignored_players = { ---@type string[] Options: [ignored players] "chromium", "firefox", "kdeconnect", @@ -46,20 +83,13 @@ vim.g.stats_ignored_players = { --- @type string[] Options: [ignored players] -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ COLOR ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -- Background color -vim.o.background = "dark" --- @type string Options: +vim.o.background = "dark" ---@type string Options: -- Dashboard header color -vim.g.DashboardHeaderColor = "#88fc9a" --- @type string Options: [hex color] +vim.g.DashboardHeaderColor = "#88fc9a"---@type string Options: [hex color] -- Disable Transparency -vim.g.disable_transparency = true --- @type boolean Options: +vim.g.disable_transparency = true ---@type boolean Options: --- ━━━━━━━━━━━━━━━━━━━━━━━━━━━ BLINKY CURSOR ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ --- Setup the blinky cursor -require("utils.blinky").enable() - --- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ OTHER ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ --- Suda smart edit: Automatically edit files in sudo mode when needed -vim.g.suda_smart_edit = 1 --- @type integer Options: <0|1> -vim.cmd("let g:suda#prompt = '  Enter Sudo Password  '") +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Completion ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -- Cmp Window Border -vim.g.completion_round_borders_enabled = true +vim.g.completion_round_borders_enabled = true ---Options: -- stylua: ignore end diff --git a/lua/config/profile.lua b/lua/config/profile.lua index e38b748..5986380 100644 --- a/lua/config/profile.lua +++ b/lua/config/profile.lua @@ -1,3 +1,12 @@ +--- @module "config.profile" +--- This module configures the profiler for the Neovim configuration. +--- This tool can be used to profile specific modules or all modules. +--- +--- The profiler can be toggled with the leader keybinding `d` +--- or with the `NVIM_PROFILE` environment variable. +--- +--- Specific modules can be selected with the `NVIM_PROFILE_MODULE` +--- environment variable. -- ╭─────────────────────────────────────────────────────────╮ -- │ PROFILER │ -- ╰─────────────────────────────────────────────────────────╯ diff --git a/lua/config/rocks.lua b/lua/config/rocks.lua index 53b053a..7eaf1b6 100644 --- a/lua/config/rocks.lua +++ b/lua/config/rocks.lua @@ -1,6 +1,10 @@ +--- @module "config.rocks" +--- This module bootstraps rocks.nvim. +--- Rocks is a package manager for Neovim. -- ╭─────────────────────────────────────────────────────────╮ -- │ ROCKS │ -- ╰─────────────────────────────────────────────────────────╯ +local M = {} -- ━━━━━━━━━━━━━━━━━━━━━━━━ Bootstrap rocks.nvim ━━━━━━━━━━━━━━━━━━━━━ do @@ -73,5 +77,27 @@ if not pcall(require, "rocks") then vim.fn.delete(rocks_location, "rf") end +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━ Rocks plugin spec ━━━━━━━━━━━━━━━━━━━━━━ +M.plugin_spec = { + "vhyrro/luarocks.nvim", + priority = 1000, -- Very high priority is required, luarocks.nvim should run as the first plugin in your config. + opts = { + rocks = { "magick" }, -- specifies a list of rocks to install + }, +} + -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Load plugins ━━━━━━━━━━━━━━━━━━━━━━━━━ -require("rocks") +-- Load rocks package manager +M.load_rocks = function() + require("rocks") +end + +-- Perform setup +M.setup = function() + M.load_rocks() +end + +-- Execute the setup function +M.setup() + +return M diff --git a/lua/config/rootiest.lua b/lua/config/rootiest.lua index bb5f8e1..957f907 100644 --- a/lua/config/rootiest.lua +++ b/lua/config/rootiest.lua @@ -1,5 +1,6 @@ ---@module "config.rootiest" ---- This module contains the configuration for the rootiest distro. +--- This module contains the configuration options and functions +--- for the rootiest distro. -- ╭─────────────────────────────────────────────────────────╮ -- │ Rootiest Module │ -- ╰─────────────────────────────────────────────────────────╯ @@ -83,10 +84,13 @@ function M.toggle_lazygit_float(my_args) if my_args ~= "" or my_args ~= nil then Util.terminal.open( { "lazygit", my_args }, - { cwd = Util.root(), esc_esc = false } + { cwd = Util.root(), interactive = true, esc_esc = false } ) else - Util.terminal.open({ "lazygit" }, { cwd = Util.root(), esc_esc = false }) + Util.terminal.open( + { "lazygit" }, + { cwd = Util.root(), interactive = true, esc_esc = false } + ) end return true else @@ -191,6 +195,14 @@ function M.setup() -- Setup Rootiest cmd window (override default command-line behavior) -- require("utils.cmd_window").setup({ override_cmdline = true }) + + -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━ BLINKY CURSOR ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + -- Setup the blinky cursor if it is enabled + if vim.g.blinky ~= false then + require("utils").blinky.enable() + else + require("utils").blinky.disable() + end end return M diff --git a/lua/data/autocmd.lua b/lua/data/autocmd.lua new file mode 100644 index 0000000..2dc6669 --- /dev/null +++ b/lua/data/autocmd.lua @@ -0,0 +1,63 @@ +---@module "data.autocmd" +--- This module defines the autocommands for the Neovim configuration. +-- ╭─────────────────────────────────────────────────────────╮ +-- │ Autocommands │ +-- ╰─────────────────────────────────────────────────────────╯ +local M = {} + +M.minifiles = function(opts) + vim.api.nvim_create_autocmd("User", { + pattern = "MiniFilesBufferCreate", + callback = function(args) + local buf_id = args.data.buf_id + + vim.keymap.set( + "n", + opts.mappings and opts.mappings.toggle_hidden or "g.", + toggle_dotfiles, + { buffer = buf_id, desc = "Toggle hidden files" } + ) + + vim.keymap.set( + "n", + opts.mappings and opts.mappings.change_cwd or "gc", + files_set_cwd, + { buffer = args.data.buf_id, desc = "Set cwd" } + ) + + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_horizontal or "s", + "horizontal", + false + ) + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_vertical or "v", + "vertical", + false + ) + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_horizontal_plus or "S", + "horizontal", + true + ) + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_vertical_plus or "V", + "vertical", + true + ) + end, + }) + + vim.api.nvim_create_autocmd("User", { + pattern = "MiniFilesActionRename", + callback = function(event) + LazyVim.lsp.on_rename(event.data.from, event.data.to) + end, + }) +end + +return M diff --git a/lua/data/cmd.lua b/lua/data/cmd.lua index 07a04ea..5d21402 100644 --- a/lua/data/cmd.lua +++ b/lua/data/cmd.lua @@ -1,13 +1,17 @@ +--- @module "data.cmd" +--- This module contains the commands for the plugins. -- ╭─────────────────────────────────────────────────────────╮ -- │ CMD DATA │ -- ╰─────────────────────────────────────────────────────────╯ local M = {} +--- Autosave plugin cmds M.autosave = { "ASToggle", } +--- Codesnap plugin cmds M.codesnap = { "CodeSnap", "CodeSnapSave", @@ -15,37 +19,25 @@ M.codesnap = { "CodeSnapASCII", } -M.diffview = { - "DiffviewOpen", - "DiffviewClose", - "DiffviewToggleFiles", - "DiffviewFocusFiles", - "DiffviewRefresh", - "DiffviewFileHistory", - "DiffviewLog", -} - -M.fugit = { - "Fugit2", - "Fugit2Diff", - "Fugit2Graph", -} - +--- Gists plugin cmds M.gist = { "GistCreate", "GistCreateFromFile", "GistsList", } +--- Gx plugin cmds M.gx = { "Browse", } +--- Kitty-Scrollback plugin cmds M.kitty_scrollback = { "KittyScrollbackGenerateKittens", "KittyScrollbackCheckHealth", } +--- LazyGit plugin cmds M.lazygit = { "LazyGit", "LazyGitConfig", @@ -54,8 +46,10 @@ M.lazygit = { "LazyGitFilterCurrentFile", } +--- Nekifoch plugin cmds M.nekifoch = "Nekifoch" +--- Thanks plugin cmds M.thanks = { "ThanksAll", "ThanksGithubAuth", @@ -63,31 +57,37 @@ M.thanks = { "ThanksClearCache", } +--- Gitlinker plugin cmds M.gitlinker = { "GitLink", } +--- Qalc plugin cmds M.qalc = { "Qalc", "QalcAttach", "QalcYank", } +--- Ripsub plugin cmds M.ripsub = { "RipSubstitute", } +--- Suda plugin cmds M.suda = { "SudaWrite", "SudaRead", } +--- Transparent plugin cmds M.transparent = { "TransparentEnable", "TransparentDisable", "TransparentToggle", } +--- Trouble plugin cmds M.trouble = { "Trouble", } diff --git a/lua/data/dash.lua b/lua/data/dash.lua index 0d967c3..1ae044f 100644 --- a/lua/data/dash.lua +++ b/lua/data/dash.lua @@ -1,71 +1,117 @@ +---@module "data.dash" +--- This module contains the data for the dashboard plugins. -- ╭─────────────────────────────────────────────────────────╮ -- │ DASH DATA │ -- ╰─────────────────────────────────────────────────────────╯ local M = {} -M.choices = { - { -- Find File - action = "lua LazyVim.pick()()", - desc = " Find File", - icon = " ", - key = "f", - }, - { -- New File - action = "ene | startinsert", - desc = " New File", - icon = " ", - key = "n", - }, - { -- Open Recent Files - action = 'lua LazyVim.pick("oldfiles")()', - desc = " Recent Files", - icon = " ", - key = "r", - }, - { -- Find Text - action = 'lua LazyVim.pick("live_grep")()', - desc = " Find Text", - icon = " ", - key = "g", - }, - { -- LazyGit - action = "LazyGit", - desc = " LazyGit", - icon = " ", - key = "z", - }, - { -- Config - action = "lua LazyVim.pick.config_files()()", - desc = " Config", - icon = " ", - key = "c", - }, - { -- Restore Session - action = 'lua require("persistence").load()', - desc = " Restore Session", - icon = " ", - key = "s", - }, - { -- Remote Session - action = 'lua require("config.rootiest").load_remote()', - desc = " Remote Session", - icon = "󰢹 ", - key = "S", - }, - { -- Lazy - action = "Lazy", - desc = " Lazy", - icon = "󰒲 ", - key = "l", - }, - { -- Quit - action = function() - vim.api.nvim_input("qa") - end, - desc = " Quit", - icon = " ", - key = "q", +--- Function to setup the Alpha dashboard options +---@return table The alpha dashboard options +M.alpha = { + opts = function() + local dashboard = require("alpha.themes.dashboard") + local logo = [[ +██████╗ ██████╗ ██████╗ ████████╗██╗███████╗███████╗████████╗ ███╗ ██╗██╗ ██╗██╗███╗ ███╗ +██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝╚══██╔══╝ ████╗ ██║██║ ██║██║████╗ ████║ +██████╔╝██║ ██║██║ ██║ ██║ ██║█████╗ ███████╗ ██║ ██╔██╗ ██║██║ ██║██║██╔████╔██║ +██╔══██╗██║ ██║██║ ██║ ██║ ██║██╔══╝ ╚════██║ ██║  ██║╚██╗██║╚██╗ ██╔╝██║██║╚██╔╝██║ +██║ ██║╚██████╔╝╚██████╔╝ ██║ ██║███████╗███████║ ██║ ██║ ╚████║ ╚████╔╝ ██║██║ ╚═╝ ██║ +╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ +]] + + dashboard.section.header.val = vim.split(logo, "\n") + -- stylua: ignore start + dashboard.section.buttons.val = { + ---@diagnostic disable: param-type-mismatch + dashboard.button("f", " " .. " Find file", LazyVim.pick()), + dashboard.button("n", " " .. " New file", [[ ene startinsert ]]), + dashboard.button("r", " " .. " Recent files", LazyVim.pick("oldfiles")), + dashboard.button("g", " " .. " Grep text", LazyVim.pick("live_grep")), + dashboard.button("z", " " .. " LazyGit", "lua require('config.rootiest').toggle_lazygit_float() "), + dashboard.button("c", " " .. " Config", LazyVim.pick.config_files()), + dashboard.button("s", " " .. " Restore Session", [[ lua require("persistence").load() ]]), + dashboard.button("S", " " .. " Remote Session", [[ lua require("config.rootiest").load_remote() ]]), + dashboard.button("l", "󰒲 " .. " Lazy", " Lazy "), + dashboard.button("q", " " .. " Quit", " qa "), + } + -- stylua: ignore end + for _, button in ipairs(dashboard.section.buttons.val) do + button.opts.hl = "AlphaButtons" + button.opts.hl_shortcut = "AlphaShortcut" + end + dashboard.section.header.opts.hl = "AlphaHeader" + dashboard.section.buttons.opts.hl = "AlphaButtons" + dashboard.section.footer.opts.hl = "AlphaFooter" + dashboard.opts.layout[1].val = 10 + return dashboard + end, +} + +M.dashboard_nvim = { + choices = { + { -- Find File + action = "lua LazyVim.pick()()", + desc = " Find File", + icon = " ", + key = "f", + }, + { -- New File + action = "ene | startinsert", + desc = " New File", + icon = " ", + key = "n", + }, + { -- Open Recent Files + action = 'lua LazyVim.pick("oldfiles")()', + desc = " Recent Files", + icon = " ", + key = "r", + }, + { -- Find Text + action = 'lua LazyVim.pick("live_grep")()', + desc = " Find Text", + icon = " ", + key = "g", + }, + { -- LazyGit + action = "LazyGit", + desc = " LazyGit", + icon = " ", + key = "z", + }, + { -- Config + action = "lua LazyVim.pick.config_files()()", + desc = " Config", + icon = " ", + key = "c", + }, + { -- Restore Session + action = 'lua require("persistence").load()', + desc = " Restore Session", + icon = " ", + key = "s", + }, + { -- Remote Session + action = 'lua require("config.rootiest").load_remote()', + desc = " Remote Session", + icon = " ", + key = "s", + }, + { -- Lazy + action = "Lazy", + desc = " Lazy", + icon = "󰒲 ", + key = "l", + }, + { -- Quit + action = function() + vim.api.nvim_input("qa") + end, + desc = " Quit", + icon = " ", + key = "q", + }, }, } diff --git a/lua/data/deps.lua b/lua/data/deps.lua index 87fbccd..858afe3 100644 --- a/lua/data/deps.lua +++ b/lua/data/deps.lua @@ -1,12 +1,18 @@ ---@module "data.deps" --- This module aggregates various dependencies used throughout the configuration. --- It provides a centralized way to access dependencies. - +-- ╭─────────────────────────────────────────────────────────╮ +-- │ DEPENDENCIES │ +-- ╰─────────────────────────────────────────────────────────╯ local M = {} +--- nvim-cmp dependencies +---@return table The nvim-cmp dependencies M.cmp = { { "L3MON4D3/LuaSnip", + --- Function to build the dependencies + ---@return string|nil The command to build the dependencies build = (function() if vim.fn.has("win32") == 1 or vim.fn.executable("make") == 0 then return @@ -25,6 +31,8 @@ M.cmp = { { "petertriho/cmp-git", opts = {}, + --- Function to configure the cmp-git dependency + ---@return table|nil The cmp-git config config = function() local cmp = require("cmp") cmp.setup.filetype("gitcommit", { @@ -60,42 +68,51 @@ M.cmp = { "Dynge/gitmoji.nvim", } +--- Gx plugin dependencies M.gx = { "nvim-lua/plenary.nvim", } +--- Hardtime plugin dependencies M.hardtime = { "MunifTanjim/nui.nvim", "nvim-lua/plenary.nvim", } +--- LazyGit plugin dependencies M.lazygit = { "nvim-telescope/telescope.nvim", "nvim-lua/plenary.nvim", } +--- Lualine plugin dependencies M.lualine = { { "bezhermoso/todos-lualine.nvim" }, { "folke/todo-comments.nvim" }, } +--- Minuet plugin dependencies M.minuet = { { "nvim-lua/plenary.nvim" }, { "hrsh7th/nvim-cmp" }, } +--- MusicControls plugin dependencies M.musiccontrols = { "rcarriga/nvim-notify", } +--- Table for plugins that need Telescope as a dependency M.needs_telescope = { "nvim-telescope/telescope.nvim", } +--- Table for plugins that need Treesitter as a dependency M.needs_treesitter = { "nvim-treesitter/nvim-treesitter", } +--- Neotest plugin adapters and dependencies M.neotest = { adapters = { "neotest-plenary", @@ -114,16 +131,19 @@ M.neotest = { }, } +--- Recorder plugin dependencies M.recorder = { "rcarriga/nvim-notify", } +--- nvim-remote plugin dependencies M.remotenvim = { "nvim-lua/plenary.nvim", -- For standard functions "MunifTanjim/nui.nvim", -- To build the plugin UI "nvim-telescope/telescope.nvim", -- For picking b/w different remote methods } +--- Zenbones plugin dependencies M.zenbones = { "rktjmp/lush.nvim", } diff --git a/lua/data/func.lua b/lua/data/func.lua index cf83a6a..05eff28 100644 --- a/lua/data/func.lua +++ b/lua/data/func.lua @@ -1,3 +1,5 @@ +---@module "data.func" +--- This module contains utility functions used throughout the configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Utility Functions │ -- ╰─────────────────────────────────────────────────────────╯ @@ -5,10 +7,7 @@ -- Define a namespace for utility functions local M = {} --- Load data module -local data = require("data") - ---- Check if the terminal is kitty +---@function Check if the terminal is kitty ---@return boolean condition true if the terminal is kitty, false otherwise function M.is_kitty() local term = os.getenv("TERM") or "" @@ -16,7 +15,7 @@ function M.is_kitty() return kit ~= nil end ---- Check if using kitty-scrollback +---@function Check if using kitty-scrollback ---@return boolean condition true if using kitty-scrollback, false otherwise function M.is_kitty_scrollback() if vim.env.KITTY_SCROLLBACK_NVIM == "true" then @@ -25,7 +24,7 @@ function M.is_kitty_scrollback() return false end ---- Check if the terminal is alacritty +---@function Check if the terminal is alacritty ---@return boolean condition true if the terminal is alacritty, false otherwise function M.is_alacritty() local term = os.getenv("TERM") or "" @@ -33,7 +32,7 @@ function M.is_alacritty() return alc ~= nil end ---- Check if the terminal is tmux +---@function Check if the terminal is tmux ---@return boolean condition true if the terminal is tmux, false otherwise function M.is_tmux() local tterm = os.getenv("TERM") @@ -49,7 +48,7 @@ function M.is_tmux() return false end ---- Check if the terminal is wezterm +---@function Check if the terminal is wezterm ---@return boolean condition true if the terminal is wezterm, false otherwise function M.is_wezterm() local wterm = os.getenv("TERM_PROGRAM") @@ -59,7 +58,7 @@ function M.is_wezterm() return false end ---- Check if the terminal is neovide +---@function Check if the terminal is neovide ---@return boolean condition true if the terminal is neovide, false otherwise function M.is_neovide() local neovide = vim.g.neovide @@ -69,7 +68,7 @@ function M.is_neovide() return false end ---- Check if the terminal is ssh +---@function Check if the terminal is ssh ---@return boolean condition true if the terminal is ssh, false otherwise function M.is_ssh() local ssh = os.getenv("SSH_TTY") or false @@ -79,7 +78,7 @@ function M.is_ssh() return false end ---- Check if OS is Windows +---@function Check if OS is Windows ---@return boolean condition true if the OS is Windows, false otherwise function M.is_windows() local win = vim.fn.has("win32") == 1 or vim.fn.has("win64") == 1 @@ -89,7 +88,7 @@ function M.is_windows() return false end ---- Check if OS is macOS +---@function Check if OS is macOS ---@return boolean condition true if the OS is macOS, false otherwise function M.is_mac() local mac = vim.fn.has("macunix") @@ -99,7 +98,7 @@ function M.is_mac() return false end ---- Check if OS is Linux +---@function Check if OS is Linux ---@return boolean condition true if the OS is Linux, false otherwise function M.is_linux() local lin = vim.fn.has("unix") @@ -109,14 +108,14 @@ function M.is_linux() return false end ---- Get the name of the OS. ---- @param format string The format of the OS name. +---@function Get the name of the OS. +---@param format string The format of the OS name. --- Possible values: --- - "verbose": Returns the full name of the OS. --- - "short": Returns a short name or abbreviation. --- - "code": Returns a code or identifier. --- - "platform": Returns either "windows", "osx", or "linux". ---- @return string os The name of the OS. +---@return string os The name of the OS. function M.get_os(format) ---@diagnostic disable-next-line: undefined-field local uname = vim.loop and vim.loop.os_uname and vim.loop.os_uname() or {} @@ -219,24 +218,64 @@ function M.get_os(format) end end ---- Function to send a notification +---@function Function to send a notification ---@param message string The message to send ----@param level string The level of the notification (default: "info") +---@param level string|nil The level of the notification (default: "info") +---@param title string|nil The title of the notification ---@return boolean condition true if the notification was sent successfully, false otherwise -function M.notify(message, level) +function M.notify(message, level, title) level = level or "info" - vim.notify(message, vim.log.levels[level:upper()]) + if title then + vim.notify(message, vim.log.levels[level:upper()], { title = title }) + else + vim.notify(message, vim.log.levels[level:upper()]) + end return true end ---- Function to reload all plugins. +---@function Function to reload all plugins. --- This is a messy operation. It's not recommended to use it. --- If you do, please define the exclusion list in your config.lua file. ---- @see data.types.plugin_reloader.exclusion_list ---- @return nil +--- Suggested defaults: +--- vim.g.plugin_reloader_exclusion_list = { +--- ["lazy.nvim"] = true, +--- ["noice.nvim"] = true, +--- ["unception.nvim"] = true, +--- ["nvim-unception"] = true, +--- ["nui.nvim"] = true, +--- ["packer.nvim"] = true, +--- ["trouble.nvim"] = true, +--- ["which-key.nvim"] = true, +--- }, +--- +--- You should add any other plugins that won't handle a live reload +--- well to this exclusion list and define it in your configuration. +--- The exclusion list can be defined with: +--- 'vim.g.plugin_reloader_exclusion_list' +---@see data.types.plugin_reloader.exclusion_list +---@return nil function M.reload_all_plugins() -- Define the exclusion list - local exclude = data.types.plugin_reloader.exclusion_list + local exclude = {} + if vim.g.plugin_reloader.exclusion_list then + -- Use global variable if provided + exclude = vim.g.plugin_reloader.exclusion_list + elseif pcall(require, "data.types") then + -- Use data.types if available + exclude = require("data.types").plugin_reloader.exclusion_list + else + -- Fallback to default + exclude = { + ["lazy.nvim"] = true, + ["noice.nvim"] = true, + ["unception.nvim"] = true, + ["nvim-unception"] = true, + ["nui.nvim"] = true, + ["packer.nvim"] = true, + ["trouble.nvim"] = true, + ["which-key.nvim"] = true, + } + end -- Get the list of currently loaded plugins local plugins = require("lazy.core.config").plugins @@ -249,30 +288,55 @@ function M.reload_all_plugins() end end ---- Check if a plugin is installed. ----@param plugin string The name of the plugin module to check. ----@return boolean condition true if the plugin is installed, false otherwise. -function M.is_installed(plugin) - -- Check for lazy.nvim - local lazy_installed = pcall(require, "lazy") - if lazy_installed then - return require("lazy.core.config").plugins[plugin] ~= nil +---@function Check if a plugin is installed. +---@param plugins string|table The name of the plugin module(s) to check. +--- Options: +--- - string: The name of the plugin module to check. +--- - table: A list of plugin modules to check. +---@return boolean|table condition The installed state of the plugin(s). +--- - boolean: The installed state of the plugin. +--- - table: A list of installed states of the plugins. +--- - boolean: The installed state of the plugin. +--- The return type is determined based on the input type. +--- If the input is a table of plugin modules, the return type is a table. +function M.is_installed(plugins) + local is_single = type(plugins) == "string" + if type(plugins) == "string" then + plugins = { plugins } end - -- Check for packer.nvim - local packer_installed = pcall(require, "packer_plugins") - if packer_installed then - ---@diagnostic disable-next-line: undefined-field - return _G.packer_plugins and _G.packer_plugins[plugin] ~= nil + + local installed_plugins = {} + for _, plugin in ipairs(plugins) do + local installed = false + local lazy_installed = pcall(require, "lazy") + if lazy_installed then + installed = require("lazy.core.config").plugins[plugin] ~= nil + end + local packer_installed = pcall(require, "packer_plugins") + if packer_installed then + ---@diagnostic disable-next-line: undefined-field + installed = _G.packer_plugins and _G.packer_plugins[plugin] ~= nil + end + if vim.fn.exists("g:plugs") == 1 then + installed = vim.g.plugs[plugin] ~= nil + end + if not installed then + local has_plug = pcall(require, plugin) + if has_plug then + installed = true + end + end + installed_plugins[plugin] = installed end - -- Check for vim-plug - if vim.fn.exists("g:plugs") == 1 then - return vim.g.plugs[plugin] ~= nil + + if is_single then + return installed_plugins[plugins[1]] + else + return installed_plugins end - -- Plugin not found - return false end ---- Condition function to check filetype is not in list +---@function Condition function to check filetype is not in list ---@param disabled_filetypes string[] The list of filetypes to check ---@return boolean|function true if filetype is not in list, false otherwise function M.disable_on_filetypes(disabled_filetypes) @@ -282,16 +346,18 @@ function M.disable_on_filetypes(disabled_filetypes) end end ---- Helper function to add keymaps with common properties +---@function Helper function to add keymaps with common properties ---@param lhs string|table The keybind (or list of keybinds) --- This field can be the following: --- - A string representing the keybind --- - A list of strings representing a set of keybinds --- - A table of multiple keybind specifications ----@param rhs string|function The function to execute when the key is pressed +--- This field is required. +---@param rhs string|function|nil The function to execute when the key is pressed --- This field can be the following: --- - A string representing the vimscript command --- - A lua function (only when using which-key.nvim or global keymaps) +--- This field is required. ---@param desc string|nil The description of the keybind (optional) --- This field can be the following: --- - A string representing the description @@ -310,6 +376,12 @@ end --- This field can be the following: --- - A number representing the buffer --- This option is incompatible with some extended keymap options +---@param hidden boolean|nil Whether the keybind should be hidden (optional) +--- This field can be the following: +--- - A boolean representing whether to hide the keymap in which-key menus +--- This option is only compatible with which-key configurations +--- It will be ignored if which-key is not installed +--- The default value is false ---@return boolean condition true if the keybind was added, false otherwise --- There are three main types of keymaps: --- - Global keymaps @@ -334,7 +406,8 @@ function M.add_keymap( mode, -- Mode(s) in which the keybind should be added icon, -- Icon to use for the keybind menu group, -- Group to use for the keybind menu - bufnr -- Buffer number to add the keymap to + bufnr, -- Buffer number to add the keymap to + hidden ) -- Check if which-key.nvim is installed if M.is_installed("which-key.nvim") and not bufnr then @@ -347,6 +420,7 @@ function M.add_keymap( mode = mode or "n", -- Default to "n" (normal mode) if mode is not provided icon = icon, -- Icon to use for the keybind group = group, -- Group to add the keybind to + hidden = hidden, -- Hide the keybind in which-key menus }, -- stylua: ignore end }) @@ -369,6 +443,7 @@ function M.add_keymap( vim.keymap.set( keymap_mode, -- Mode(s) in which the keybind should be added keymap_lhs, -- The keybind + ---@diagnostic disable-next-line: param-type-mismatch keymap_rhs, -- Function to execute when the key is pressed { desc = keymap_desc } -- Description of the keybind ) @@ -390,6 +465,7 @@ function M.add_keymap( bufnr, keymap_mode, keymap_lhs, + ---@diagnostic disable-next-line: param-type-mismatch keymap_rhs, { desc = keymap_desc } ) @@ -412,6 +488,7 @@ function M.add_keymap( vim.keymap.set( mode or "n", -- Default to "n" (normal mode) if mode is not provided lhs, -- The keybind + ---@diagnostic disable-next-line: param-type-mismatch rhs, -- Function to execute when the key is pressed { desc = desc } -- Description of the keybind and optional buffer number ) @@ -433,6 +510,7 @@ function M.add_keymap( bufnr, mode or "n", lhs, + ---@diagnostic disable-next-line: param-type-mismatch rhs, { desc = desc } ) @@ -451,7 +529,152 @@ function M.add_keymap( end end ---- Helper function to remove keymaps +---@function Add a new keymap with optional which-key integration +---@param lhs string|table The keybind or a table containing multiple keymaps +---@param rhs string|function|nil The function to execute when the keybind is pressed +---@param desc string|nil The description of the keybind +---@param mode string|table|nil The mode(s) in which the keybind should be added +---@param icon string|nil The icon to associate with the which-key entry (optional) +---@param group string|nil The which-key group to add the keybind to (optional) +---@param bufnr number|nil The buffer number to add the keymap to (optional, for buffer-specific mappings) +---@return boolean success True if all keymaps were successfully added, false otherwise +function M.add_km(lhs, rhs, desc, mode, icon, group, bufnr) + local function is_mode(value) + -- Identify common vim modes; this can be expanded based on requirements + local common_modes = + { n = true, i = true, v = true, x = true, s = true, o = true, c = true } + if type(value) == "string" and #value == 1 then + return common_modes[value] ~= nil + elseif type(value) == "table" then + for _, v in ipairs(value) do + if not common_modes[v] then + return false + end + end + return true + end + return false + end + + local function correct_swapped_params() + -- Try to correct common mistakes where rhs and mode might be swapped + + if type(rhs) == "string" and is_mode(rhs) then + if type(mode) == "string" or type(mode) == "function" then + -- Swap them if it looks like rhs is mode and mode is rhs + ---@diagnostic disable-next-line: cast-local-type + rhs, mode = mode, rhs + elseif type(mode) == "table" and is_mode(mode) then + -- Swap if rhs is mode and mode is list of modes + ---@diagnostic disable-next-line: cast-local-type + rhs, mode = mode, rhs + end + elseif + type(rhs) == "function" + and type(mode) == "string" + and not is_mode(mode) + then + -- This checks if mode is actually an rhs-like string or command + rhs, mode = mode, rhs + end + end + + -- Attempt to correct any common parameter swapping issues + correct_swapped_params() + + -- Helper function to set keymaps using native functions + local function set_keymap( + keymap_lhs, + keymap_rhs, + keymap_desc, + keymap_mode, + keymap_bufnr + ) + if keymap_bufnr then + vim.api.nvim_buf_set_keymap( + keymap_bufnr, + keymap_mode, + keymap_lhs, + keymap_rhs, + { desc = keymap_desc } + ) + else + vim.keymap.set( + keymap_mode, + keymap_lhs, + keymap_rhs, + { desc = keymap_desc } + ) + end + end + + -- Determine if which-key is available and should be used + local use_which_key = M.is_installed + and M.is_installed("which-key.nvim") + and not bufnr + + -- Process a single keymap entry + ---@function Helper function to process a single keymap + ---@param keymap table The table containing a keymap + ---@return boolean success True if the keymap was processed successfully, false otherwise + local function process_keymap(keymap) + local keymap_lhs = type(keymap) == "table" and keymap.lhs or lhs + local keymap_rhs = type(keymap) == "table" and (keymap.rhs or rhs) or rhs + local keymap_desc = type(keymap) == "table" and (keymap.desc or desc) + or desc + local keymap_mode = type(keymap) == "table" and (keymap.mode or mode) + or mode + or "n" + local keymap_icon = type(keymap) == "table" and (keymap.icon or icon) + or icon + local keymap_group = type(keymap) == "table" and (keymap.group or group) + or group + + -- Use which-key if possible; fallback to native keymap functions if not + if use_which_key then + require("which-key").add({ + [keymap_lhs] = { + keymap_rhs, + keymap_desc, + mode = keymap_mode, + icon = keymap_icon, + group = keymap_group, + }, + }) + else + -- Attempt to fall back to the native keymap functions + local success, err_msg = pcall( + set_keymap, + keymap_lhs, + keymap_rhs, + keymap_desc, + keymap_mode, + bufnr + ) + if not success then + -- Notify the user about the failed mapping + M.notify(("Failed to map %s: %s"):format(keymap_lhs, err_msg), "WARN") + return false + end + end + return true + end + + -- Handle the scenario where lhs is a table containing multiple keymaps + if type(lhs) == "table" then + for _, keymap in ipairs(lhs) do + if not process_keymap(keymap) then + return false + end + end + return true + else + -- Handle a single keymap entry + return process_keymap({}) + end +end + +---@function Helper function to remove keymaps ---@param lhs string The keybind ---@param mode string|nil The mode in which the keybind should be removed (optional) ---@param bufnr number|nil The buffer number to remove the keymap from (optional) @@ -465,13 +688,13 @@ function M.rm_keymap( ) mode = mode or "n" -- Default to "n" (normal mode) if mode is not provided - --- @class Keymap - --- @field lhs string The keybind - --- @field rhs string|function The function or command associated with the keybind + ---@class Keymap + ---@field lhs string The keybind + ---@field rhs string|function The function or command associated with the keybind if bufnr then -- If a buffer number is provided, remove the keymap from the specified buffer - --- @type Keymap[] + ---@type Keymap[] local keymaps = vim.api.nvim_buf_get_keymap(bufnr, mode) for _, keymap in pairs(keymaps) do if keymap.lhs and keymap.lhs == lhs then @@ -481,7 +704,7 @@ function M.rm_keymap( end else -- If no buffer number is provided, remove the global keymap - --- @type Keymap[] + ---@type Keymap[] local keymaps = vim.api.nvim_get_keymap(mode) for _, keymap in pairs(keymaps) do if keymap.lhs and keymap.lhs == lhs then @@ -494,7 +717,7 @@ function M.rm_keymap( return false -- Indicate that the keymap did not exist end ---- Helper function to add a mark +---@function Helper function to add a mark ---@param mark string The mark to add ---@param line integer The line to add the mark to ---@param col integer The column to add the mark to @@ -505,7 +728,7 @@ function M.add_mark(mark, line, col) return true -- Indicate that the mark was successfully added end ---- Helper function to remove a mark +---@function Helper function to remove a mark ---@param mark string The mark to remove ---@return boolean condition true if the mark was removed, false otherwise function M.rm_mark(mark) @@ -522,25 +745,25 @@ function M.rm_mark(mark) return false -- Indicate that the mark did not exist end ---- Function to check if buffer is modified +---@function Function to check if buffer is modified ---@return boolean condition true if buffer is modified, false otherwise function M.is_buffer_modified() return vim.bo.modified end ---- Function to check if buffer is empty +---@function Function to check if buffer is empty ---@return boolean condition true if buffer is empty, false otherwise function M.is_buffer_empty() return vim.fn.empty(vim.fn.expand("%:t")) == 1 end ---- Function to check if buffer is read-only +---@function Function to check if buffer is read-only ---@return boolean condition true if buffer is read-only, false otherwise function M.is_buffer_readonly() return vim.bo.readonly end ---- Function to check if file exists +---@function Function to check if file exists ---@param filepath string The path to the file ---@return boolean condition true if file exists, false otherwise function M.file_exists(filepath) @@ -551,7 +774,7 @@ function M.file_exists(filepath) return f ~= nil end ---- Function to get the current git branch +---@function Function to get the current git branch ---@return string branch git branch name or "No branch" function M.get_git_branch() local branch = vim.fn.systemlist("git rev-parse --abbrev-ref HEAD")[1] @@ -562,7 +785,7 @@ function M.get_git_branch() end end ---- Function to get the current git commit hash +---@function Function to get the current git commit hash ---@return string The current git commit hash or "No commit hash" function M.get_git_commit_hash() local commit_hash = vim.fn.systemlist("git rev-parse --short HEAD")[1] @@ -573,7 +796,7 @@ function M.get_git_commit_hash() end end ---- Function to run a shell command +---@function Function to run a shell command ---@param cmd string The command to run ---@return string|nil result The output of the command function M.run_shell_command(cmd) @@ -584,12 +807,12 @@ function M.run_shell_command(cmd) return result else -- Handle the error case where `handle` is nil - vim.notify("Failed to run the command: " .. cmd, vim.log.levels.ERROR) + M.notify("Failed to run the command: " .. cmd, "ERROR") return nil end end ---- Function to get the dimensions of the current window +---@function Function to get the dimensions of the current window ---@param format string The format of the dimensions ---@return string|table dimensions dimensions of the current window function M.get_ws_dimensions(format) @@ -614,7 +837,7 @@ function M.get_ws_dimensions(format) end end ---- Function to get the cursor position +---@function Function to get the cursor position ---@return integer row The current line number ---@return integer col The current column number function M.get_cursor_position() @@ -622,7 +845,24 @@ function M.get_cursor_position() return row, col end ---- Function to split a string +---@function Function to check if a global variable is set +---@param var_name string The name of the global variable +---@param expected_value any The expected value of the global variable +---@param default_value any The default value of the global variable +---@return boolean condition true if the global variable is set to the expected value, false otherwise +function M.check_global_var(var_name, expected_value, default_value) + local actual_value = vim.g[var_name] + + -- If the global variable is not set, use the default value (if provided) + if actual_value == nil and default_value ~= nil then + actual_value = default_value + end + + -- Return whether the actual value matches the expected value + return actual_value == expected_value +end + +---@function Function to split a string ---@param inputstr string The string to split ---@param sep string The separator ---@return table output The split string @@ -637,14 +877,14 @@ function M.split_string(inputstr, sep) return output end ---- Function to convert RGB to hexadecimal +---@function Function to convert RGB to hexadecimal ---@param rgb table The RGB color ---@return string hex The hexadecimal color function M.rgb_to_hex(rgb) return string.format("#%02x%02x%02x", rgb[1], rgb[2], rgb[3]) end ---- Function to get the foreground color of a highlight group +---@function Function to get the foreground color of a highlight group ---@param hlgroup string The name of the highlight group ---@return string|nil hex The foreground color of the highlight group function M.get_fg_color(hlgroup) @@ -660,7 +900,7 @@ function M.get_fg_color(hlgroup) return nil end ---- Function to get the background color of a highlight group +---@function Function to get the background color of a highlight group ---@param hlgroup string The name of the highlight group ---@return string|nil hex The background color of the highlight group function M.get_bg_color(hlgroup) @@ -676,7 +916,7 @@ function M.get_bg_color(hlgroup) return nil end ---- Function to check if the window is wide enough +---@function Function to check if the window is wide enough ---@param width_limit number The minimum width of the window ---@return boolean condition true if the window is wide enough, false otherwise function M.is_window_wide_enough(width_limit) @@ -684,7 +924,7 @@ function M.is_window_wide_enough(width_limit) return width >= width_limit end ---- Function to check if the window is tall enough +---@function Function to check if the window is tall enough ---@param height_limit number The minimum height of the window ---@return boolean condition true if the window is tall enough, false otherwise function M.is_window_tall_enough(height_limit) @@ -692,13 +932,13 @@ function M.is_window_tall_enough(height_limit) return height >= height_limit end ---- Function to get the current date +---@function Function to get the current date ---@return string|osdate date The current date function M.get_date() return os.date("%Y-%m-%d") end ---- Function to exit neovim +---@function Function to exit neovim ---@return nil function M.exit() vim.api.nvim_command("wqall") diff --git a/lua/data/init.lua b/lua/data/init.lua index 6881309..3b4b7db 100644 --- a/lua/data/init.lua +++ b/lua/data/init.lua @@ -1,25 +1,37 @@ ---@module "data" ---- This module aggregates various utility modules used throughout the configuration. ---- It provides a centralized way to access keymaps, data types, utility functions, commands, and dashboard utilities. +--- This module aggregates various data tables used throughout the configuration. +local M = {} -local keys = require("data.keys") -local types = require("data.types") -local func = require("data.func") -local cmd = require("data.cmd") -local deps = require("data.deps") -local dash = require("data.dash") +-- Explicitly specify for LSP support +M.keys = require("data.keys") +M.types = require("data.types") +M.func = require("data.func") +M.cmd = require("data.cmd") +M.deps = require("data.deps") +M.dash = require("data.dash") ----@alias DataModule ----| { keys: table, types: table, func: table, cmd: table, deps: table, dash: table } +-- Function to iterate over files in the directory +local function read_data_dir() + -- Getting the root path for the current module directory + local dir_path = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":h") ----@type DataModule -local data = { - keys = keys, - types = types, - func = func, - cmd = cmd, - deps = deps, - dash = dash, -} + -- Open the directory + local files = vim.fn.readdir(dir_path) -return data + for _, file in ipairs(files) do + -- Skip init.lua + if file ~= "init.lua" and file:match(".*%.lua$") then + -- Get the module name without the .lua extension + local module_name = file:sub(1, -5) + -- Load the module if not already explicitly set + if not M[module_name] then + M[module_name] = require("data." .. module_name) + end + end + end +end + +-- Read the directory and load any additional modules +read_data_dir() + +return M diff --git a/lua/data/keys.lua b/lua/data/keys.lua index dc059da..5f9fb38 100644 --- a/lua/data/keys.lua +++ b/lua/data/keys.lua @@ -1,3 +1,7 @@ +---@module "data.keys" +--- This module contains the keymaps for the plugins and commands. +--- Keymaps use the add_keymap function from data.func for flexible +--- keybinding functionality. -- ╭─────────────────────────────────────────────────────────╮ -- │ KEYS DATA │ -- ╰─────────────────────────────────────────────────────────╯ @@ -54,7 +58,7 @@ M.codesnap = { } M.flash = { - { + { -- Flash jump to next "", function() require("flash").jump() @@ -65,52 +69,72 @@ M.flash = { } M.minimap = { - { "nt", "Neominimap toggle", desc = "Toggle minimap" }, - { "no", "Neominimap on", desc = "Enable minimap" }, - { "nc", "Neominimap off", desc = "Disable minimap" }, - { "nf", "Neominimap focus", desc = "Focus on minimap" }, - { "nu", "Neominimap unfocus", desc = "Unfocus minimap" }, - { + { -- Toggle minimap + "nt", + "Neominimap toggle", + desc = "Toggle minimap", + }, + { -- Enable minimap + "no", + "Neominimap on", + desc = "Enable minimap", + }, + { -- Disable minimap + "nc", + "Neominimap off", + desc = "Disable minimap", + }, + { -- Refresh minimap + "nf", + "Neominimap focus", + desc = "Focus on minimap", + }, + { -- Unfocus minimap + "nu", + "Neominimap unfocus", + desc = "Unfocus minimap", + }, + { -- Toggle focus "ns", "Neominimap toggleFocus", desc = "Toggle focus on minimap", }, - { + { -- Toggle minimap for current window "nwt", "Neominimap winToggle", desc = "Toggle minimap for current window", }, - { + { -- Refresh minimap for current window "nwr", "Neominimap winRefresh", desc = "Refresh minimap for current window", }, - { + { -- Enable minimap for current window "nwo", "Neominimap winOn", desc = "Enable minimap for current window", }, - { + { -- Disable minimap for current window "nwc", "Neominimap winOff", desc = "Disable minimap for current window", }, - { + { -- Toggle minimap for current buffer "nbt", "Neominimap bufToggle", desc = "Toggle minimap for current buffer", }, - { + { -- Refresh minimap for current buffer "nbr", "Neominimap bufRefresh", desc = "Refresh minimap for current buffer", }, - { + { -- Enable minimap for current buffer "nbo", "Neominimap bufOn", desc = "Enable minimap for current buffer", }, - { + { -- Disable minimap for current buffer "nbc", "Neominimap bufOff", desc = "Disable minimap for current buffer", @@ -187,14 +211,6 @@ M.foldnav = { }, } -M.fugit = { - { -- Open Fugit - "F", - mode = "n", - "Fugit2", - }, -} - M.gitlinker = { { -- Yank git link "gy", @@ -235,32 +251,27 @@ M.gist = { } M.groups = { - -- Icon picker - { + { -- Icon picker menu lhs = "I", group = "IconPicker", icon = { icon = "󰥸", color = "orange" }, }, - -- Gists menu - { + { -- Gists menu lhs = "gn", group = "Gists", icon = { icon = "", color = "orange" }, }, - -- Lazy menu - { + { -- Lazy menu lhs = "l", group = "Lazy", icon = { icon = "󰒲", color = "red" }, }, - -- MiniMap menu - { + { -- MiniMap menu lhs = "n", group = "MiniMap", icon = { icon = "", color = "green" }, }, - -- Code action menu - { + { -- Code action menu lhs = "C", group = "CodeActions", icon = { icon = "", color = "yellow" }, @@ -314,65 +325,74 @@ M.lazygit = { }, } -M.misc = { - -- Yank line (without whitespace) +M.minifiles = { { + "fm", + function() + require("mini.files").open(vim.api.nvim_buf_get_name(0), true) + end, + desc = "Open mini.files (Directory of Current File)", + }, + { + "fM", + function() + require("mini.files").open(vim.uv.cwd(), true) + end, + desc = "Open mini.files (cwd)", + }, +} + +M.misc = { + { -- Yank line (without whitespace) lhs = "yo", rhs = function() rootiest.yank_line() end, desc = "Yank Line-text", }, - -- Hardmode - { + { -- Hardmode lhs = "uH", rhs = function() rootiest.toggle_hardmode() end, desc = "Toggle Hardmode", }, - -- Yank buffer - { + { -- Yank buffer lhs = "Y", rhs = "%y", desc = "Yank buffer contents", }, - -- Select all - { + { -- Select all lhs = "", rhs = "norm ggVG", desc = "Select all", }, - -- Neotree - { + { -- Neotree lhs = "|", rhs = "Neotree reveal toggle", desc = "Neotree toggle", }, - -- Exit Neovim - { + { -- Exit Neovim lhs = "Q", rhs = "lua require('data').func.exit()", desc = "Exit Neovim", }, - -- LazyVim - { + { -- LazyVim lhs = "lv", rhs = "Lazy", desc = "LazyVim", }, - -- LazyExtras - { + { -- LazyExtras lhs = "lx", rhs = "LazyExtras", desc = "LazyExtras", }, - -- De-map 's' to avoid conflicts with mini.surround - { - lhs = "s", + { -- De-map Ctrl+Shift+LeftClick to avoid conflicts with WezTerm + lhs = "", rhs = "", - desc = "Nos", - mode = { "n", "x" }, + desc = "Prevent conflict with WezTerm hyperlinks", + mode = "n", + hidden = true, }, } @@ -438,102 +458,102 @@ M.splitjoin = { M.splits = { resize = { - { + { -- Resize split leftwards "", function() require("smart-splits").resize_left() end, "Resize split left", }, - { + { -- Resize split downwards "", function() require("smart-splits").resize_down() end, "Resize split down", }, - { + { -- Resize split upwards "", function() require("smart-splits").resize_up() end, "Resize split up", }, - { + { -- Resize split rightwards "", function() require("smart-splits").resize_right() end, "Resize split right", }, - { + { -- Start interactive split resizing "", function() require("smart-splits").start_resize_mode() end, - "Resize split to previous size", + "Resize split interactively", }, }, move = { - { + { -- Move cursor to split left "", function() require("smart-splits").move_cursor_left() end, - "Move cursor left", + "Move to split left", }, - { + { -- Move cursor to split below "", function() require("smart-splits").move_cursor_down() end, - "Move cursor down", + "Move to split below", }, - { + { -- Move cursor to split above "", function() require("smart-splits").move_cursor_up() end, - "Move cursor up", + "Move to split above", }, - { + { -- Move cursor to split right "", function() require("smart-splits").move_cursor_right() end, - "Move cursor right", + "Move to split right", }, - { + { -- Move cursor to previous split "", function() require("smart-splits").move_cursor_previous() end, - "Move cursor to previous split", + "Move to previous split", }, }, swap = { - { + { -- Swap buffer with the one to the left "", function() require("smart-splits").swap_buf_left() end, "Swap buffer left", }, - { + { -- Swap buffer with the one below "", function() require("smart-splits").swap_buf_down() end, "Swap buffer down", }, - { + { -- Swap buffer with the one above "", function() require("smart-splits").swap_buf_up() end, "Swap buffer up", }, - { + { -- Swap buffer with the one to the right "", function() require("smart-splits").swap_buf_right() @@ -584,11 +604,12 @@ M.substitute = { } M.surround = { - { -- De-map 's' to prevent conflicts - "s", - "", - desc = "Nos", + { -- De-map 's' to avoid conflicts with mini.surround + lhs = "s", + rhs = "", + desc = "Prevent conflict with mini.surround", mode = { "n", "x" }, + hidden = true, }, } diff --git a/lua/data/types.lua b/lua/data/types.lua index fe1058e..46e9d15 100644 --- a/lua/data/types.lua +++ b/lua/data/types.lua @@ -1,14 +1,142 @@ +---@module "M" +--- This module aggregates various types used throughout the configuration. +--- Plugin opts/config tables/functions are defined in this module. +--- Other general tables and lists are also defined here. -- ╭─────────────────────────────────────────────────────────╮ -- │ TYPES │ -- ╰─────────────────────────────────────────────────────────╯ local M = {} -M.logo = { - icon = "", - color = "Special", +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━ Mode Indicators ━━━━━━━━━━━━━━━━━━━━━━━━━━━ +M.mode = { + n = { -- Normal mode + icon = "", + name = "NORMAL", + color = "Special", + }, + no = { -- Operator-pending mode + icon = "", + name = "NORMAL OPERATOR PENDING", + color = "Special", + }, + nov = { -- Operator-pending (charwise) mode + icon = "", + name = "NORMAL OP (CHARWISE)", + color = "Special", + }, + nt = { -- Terminal-mode within Normal mode + icon = "", + name = "NORMAL TERMINAL", + color = "Special", + }, + i = { -- Insert mode + icon = "", + name = "INSERT", + color = "Special", + }, + ic = { -- Insert completion mode + icon = "", + name = "INSERT COMPLETION", + color = "Special", + }, + R = { -- Replace mode + icon = "", + name = "REPLACE", + color = "Special", + }, + Rv = { -- Virtual replace mode + icon = "", + name = "REPLACE VIRT", + color = "Special", + }, + v = { -- Visual mode + icon = "󰸿", + name = "VISUAL", + color = "Special", + }, + V = { -- Visual Line mode + icon = "󰸽", + name = "VISUAL LINE", + color = "Special", + }, + [""] = { -- Visual Block mode + icon = "󰹀", + name = "VISUAL BLOCK", + color = "Special", + }, + c = { -- Command mode + icon = "󰑮", + name = "COMMAND", + color = "Special", + }, + s = { -- Select mode + icon = "", + name = "SELECT", + color = "Special", + }, + S = { -- Select Line mode + icon = "", + name = "SELECT LINE", + color = "Special", + }, + t = { -- Terminal mode + icon = "", + name = "INSERT TERMINAL", + color = "Special", + }, + + --- A collection of functions that return icons and names for + --- the current mode. + --- These use the tables defined above in `M.mode`. + current = { + --- Returns an icon representing the current mode + --- Ex: "" + ---@return string|function icon The current mode icon + icon = function() + local current_mode = vim.api.nvim_get_mode().mode + -- Check if current_mode exists in full in M.mode + if M.mode[current_mode] then + return M.mode[current_mode].icon + end + -- Fallback to single-character mode if full mode isn't available + local fallback_mode = current_mode:sub(1, 1) + return M.mode[fallback_mode] and M.mode[fallback_mode].icon or "" + end, + + --- Returns the name of the current mode + --- Ex: "NORMAL" + ---@return string|function name The current mode name + name = function() + local current_mode = vim.api.nvim_get_mode().mode + -- Check if current_mode exists in full in M.mode + if M.mode[current_mode] then + return M.mode[current_mode].name + end + -- Fallback to single-character mode if full mode isn't available + local fallback_mode = current_mode:sub(1, 1) + return M.mode[fallback_mode] and M.mode[fallback_mode].name or "UNKNOWN" + end, + + --- Returns a string representing the current mode with icon and name + --- Ex: " NORMAL" + ---@return string|function icon_text The current mode icon and name + icon_text = function() + return M.mode.current.icon() .. " " .. M.mode.current.name() + end, + + --- Returns a string representing the current mode with icon and name + --- Ex: " NORMAL" + ---@return string|function icon_text The current mode icon and name + lualine = function() + return M.mode.current.icon_text() + end, + }, } +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Type tables ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +--- General exclusion list for buffers and filetypes M.general = { -- Excluded buffer types buf = { @@ -32,7 +160,7 @@ M.general = { }, } --- All modes for keymaps +--- All-modes table for keymaps M.all_modes = { "n", "i", @@ -44,7 +172,7 @@ M.all_modes = { "t", } --- Filetypes for Alternate plugin +--- Filetypes for Alternate plugin M.alternate = { "cpp", "h", @@ -52,52 +180,272 @@ M.alternate = { "c", } +--- Arrow config options M.arrow = { show_icons = true, leader_key = ";", -- Recommended to be a single key buffer_leader_key = "m", -- Per Buffer Mappings } --- Bufferline configuration options +--- Bufferline configuration options M.bufferline = { - themable = true, - color_icons = true, - numbers = "ordinal", - separator_style = "slant", - auto_toggle_bufferline = true, - buffer_close_icon = "󱎘", - modified_icon = "●", - close_icon = "", - left_trunc_marker = "󰬨", - right_trunc_marker = "󰬪", - diagnostics_indicator = function(_, _, diagnostics_dict, _) - local s = " " - for e, n in pairs(diagnostics_dict) do - local sym = e == "error" and " " - or (e == "warning" and " " or " ") - s = s .. sym .. n - end - return s - end, + opts = { + options = { + themable = true, + color_icons = true, + numbers = "ordinal", + separator_style = "slant", + auto_toggle_bufferline = true, + buffer_close_icon = "󱎘", + modified_icon = "●", + close_icon = "", + left_trunc_marker = "󰬨", + right_trunc_marker = "󰬪", + diagnostics_indicator = function(_, _, diagnostics_dict, _) + local s = " " + for e, n in pairs(diagnostics_dict) do + local sym = e == "error" and " " + or (e == "warning" and " " or " ") + s = s .. sym .. n + end + return s + end, + }, + }, } --- Nvim-cmp excluded filetypes +--- LazyVim configuration options +M.lazyvim = { + opts = { + colorscheme = vim.g.my_colorscheme or "catppuccin-mocha", + news = { + lazyvim = true, + neovim = true, + }, + }, +} + +--- Nvim-cmp excluded filetypes M.cmp = { "dashboard", "qalc", } --- Git-Blame configuration -M.gitblame = { - display_virtual_text = 0, -- Disable virtual text - date_format = "%r", -- Relative date format - message_when_not_committed = " Not yet committed", - message_template = "", +M.neotree = { + opts = { + default_component_configs = { + git_status = { + symbols = { + untracked = "󱀶", + ignored = "", + unstaged = "󰄱", + staged = "󰱒", + conflict = "", + }, + }, + }, + }, } --- Git-Graph plugin options +M.minifiles = { + opts = { + windows = { + preview = true, + width_focus = 30, + width_preview = 80, + }, + options = { + -- Whether to use for editing directories + -- Disabled by default in LazyVim because neo-tree is used for that + use_as_default_explorer = false, + -- Whether to permanently delete or use trash + permanent_delete = false, + }, + }, + config = function(_, opts) + require("mini.files").setup(opts) + + local show_dotfiles = true + local filter_show = function(_) + return true + end + local filter_hide = function(fs_entry) + return not vim.startswith(fs_entry.name, ".") + end + + local toggle_dotfiles = function() + show_dotfiles = not show_dotfiles + local new_filter = show_dotfiles and filter_show or filter_hide + require("mini.files").refresh({ content = { filter = new_filter } }) + end + + local map_split = function(buf_id, lhs, direction, close_on_file) + local rhs = function() + local new_target_window + local cur_target_window = require("mini.files").get_target_window() + if cur_target_window ~= nil then + vim.api.nvim_win_call(cur_target_window, function() + vim.cmd("belowright " .. direction .. " split") + new_target_window = vim.api.nvim_get_current_win() + end) + + require("mini.files").set_target_window(new_target_window) + require("mini.files").go_in({ close_on_file = close_on_file }) + end + end + + local desc = "Open in " .. direction .. " split" + if close_on_file then + desc = desc .. " and close" + end + vim.keymap.set("n", lhs, rhs, { buffer = buf_id, desc = desc }) + end + + local files_set_cwd = function() + ---@diagnostic disable-next-line: undefined-global + local cur_entry_path = MiniFiles.get_fs_entry().path + local cur_directory = vim.fs.dirname(cur_entry_path) + if cur_directory ~= nil then + vim.fn.chdir(cur_directory) + end + end + + vim.api.nvim_create_autocmd("User", { + pattern = "MiniFilesBufferCreate", + callback = function(args) + local buf_id = args.data.buf_id + + vim.keymap.set( + "n", + opts.mappings and opts.mappings.toggle_hidden or "g.", + toggle_dotfiles, + { buffer = buf_id, desc = "Toggle hidden files" } + ) + + vim.keymap.set( + "n", + opts.mappings and opts.mappings.change_cwd or "gc", + files_set_cwd, + { buffer = args.data.buf_id, desc = "Set cwd" } + ) + + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_horizontal or "s", + "horizontal", + false + ) + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_vertical or "v", + "vertical", + false + ) + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_horizontal_plus or "S", + "horizontal", + true + ) + map_split( + buf_id, + opts.mappings and opts.mappings.go_in_vertical_plus or "V", + "vertical", + true + ) + end, + }) + + vim.api.nvim_create_autocmd("User", { + pattern = "MiniFilesActionRename", + callback = function(event) + LazyVim.lsp.on_rename(event.data.from, event.data.to) + end, + }) + end, +} + +--- Git-Blame configuration options +M.gitblame = { + opts = function() + if vim.g.statusline == "lualine" or vim.g.statusline == nil then + -- Get the current lualine configuration + local config = require("lualine").get_config() + local git_blame = require("gitblame") + local funcs = require("data.func") + -- Define the width limit for displaying the Git blame component + local width_limit = 245 -- Adjust this value as needed + -- Add Git-blame to lualine_c section + table.insert(config.sections.lualine_c, { + git_blame.get_current_blame_text, + cond = function() -- Only show if text is available + return git_blame.is_blame_text_available() + and funcs.is_window_wide_enough(width_limit) + end, + color = { fg = funcs.get_fg_color("GitSignsCurrentLineBlame") }, + padding = { left = 1, right = 0 }, + on_click = function() + if vim.g.statusline_clickable_git ~= false then + require("config.rootiest").toggle_lazygit_float() + end + end, + }) + -- Apply the lualine configuration + require("lualine").setup(config) + end + -- Return the git-blame options + return M.gitblame.style + end, + style = { + display_virtual_text = 0, -- Disable virtual text + date_format = "%r", -- Relative date format + message_when_not_committed = " Not yet committed", + message_template = "", + }, +} + +--- Neocodeium configuration options +M.neocodeium = { + opts = { + manual = false, + silent = true, + debounce = false, + }, +} + +--- Thanks configuration options +M.thanks = { + opts = { + star_on_install = false, + }, +} + +--- LSPConfig configuration options +M.lspconfig = { + opts = { + setup = { + clangd = function(_, opts) + opts.capabilities.offsetEncoding = { "utf-16" } + end, + }, + }, +} + +--- Which-Key configuration options +M.whichkey = { + opts = { + preset = "modern", + win = { + wo = { + winblend = 10, + }, + }, + }, +} + +--- Git-Graph plugin options M.gitgraph = { - -- Git-graph symbols check for kitty + --- Git-graph symbols check for kitty symbols = function() if require("data.func").is_kitty() then return { @@ -142,7 +490,7 @@ M.gitgraph = { fields = { "hash", "timestamp", "author", "branch_name", "tag" }, } --- Highlights module options +--- Highlights module options M.highlights = { -- Excluded buffer types exclude = { @@ -150,7 +498,7 @@ M.highlights = { }, } --- Indent characters +--- Indent characters M.ibl = { indent_char = { fancy = { @@ -179,7 +527,10 @@ M.ibl = { }, } +--- Smart-Splits plugin options M.smart_splits = { + --- Function to check if kitty is running + --- and install Smart-Splits kittens if it is. build = function() if require("data.func").is_kitty() then return "./kitty/install-kittens.bash" @@ -189,6 +540,7 @@ M.smart_splits = { end, } +--- Neominiap plugin options M.minimap = { -- Width of minimap width = 20, @@ -210,14 +562,14 @@ M.minimap = { "neorg", }, - -- Function to initialize or manipulate minimap settings + --- Function to initialize or manipulate minimap settings init = function() M.setup() vim.g.neominimap = { auto_enable = true, layout = "float", - exclude_filetypes = require("data.types").minimap.file, - exclude_buftypes = require("data.types").minimap.buf, + exclude_filetypes = M.minimap.file, + exclude_buftypes = M.minimap.buf, x_multiplier = 4, y_multiplier = 1, click = { @@ -238,7 +590,7 @@ M.minimap = { } end, - -- Function to check if minimap should be enabled + --- Function to check if minimap should be enabled cond = function() M.setup() local ex_ft = M.minimap.ft @@ -252,6 +604,7 @@ M.minimap = { end, } +--- Llama Copilot plugin options M.llama_copilot = { host = "localhost", port = "11434", @@ -260,6 +613,7 @@ M.llama_copilot = { debug = false, } +--- Plugin reloader function options M.plugin_reloader = { exclusion_list = { -- Define the exclusion list -- stylua: ignore start @@ -280,6 +634,69 @@ M.plugin_reloader = { }, } +M.trouble = { + opts = { + modes = { + symbols = { -- Configure symbols mode + win = { + type = "split", -- split window + relative = "win", -- relative to current window + position = "right", -- right side + size = 0.3, -- 30% of the window + }, + }, + }, + }, +} + +--- Function to set up bars-n-lines plugin options +M.barsNlines = function() + require("bars").setup({ + exclude_filetypes = M.minimap.ft, + exclude_buftypes = M.minimap.buf, + statuscolumn = { + enable = true, + parts = { + { + type = "fold", + markers = { + default = { + content = { " " }, + }, + open = { + { " ", "BarsStatuscolumnFold1" }, + }, + close = { + { "╴", "BarsStatuscolumnFold1" }, + }, + scope = { + { "│ ", "BarsStatuscolumnFold1" }, + }, + divider = { + { "├╴", "BarsStatuscolumnFold1" }, + }, + foldend = { + { "╰╼", "BarsStatuscolumnFold1" }, + }, + }, + }, + { + type = "number", + mode = "hybrid", + hl = "LineNr", + lnum_hl = "BarsStatusColumnNum", + relnum_hl = "LineNr", + virtnum_hl = "TablineSel", + wrap_hl = "TablineSel", + }, + }, + }, + tabline = false, + statusline = false, + }) +end + +--- Function to setup Pigeon plugin options M.pigeon = function() local data = require("data") local platform = data.func.get_os("platform") @@ -315,6 +732,7 @@ M.pigeon = function() require("pigeon").setup(config) end +--- Substitute plugin options M.substitute = { yank_substituted_text = false, preserve_cursor_position = true, @@ -323,7 +741,7 @@ M.substitute = { end, } --- Hightlight-colors +--- Hightlight-colors plugin options M.hightlight_colors = { render = "virtual", virtual_symbol = "", @@ -348,7 +766,7 @@ M.hightlight_colors = { exclude_buftypes = {}, } --- Catppuccin opts +--- Catppuccin options M.catppuccin = { background = { -- :h background light = "latte", @@ -398,15 +816,17 @@ M.catppuccin = { }, } --- Auto Dark Mode opts +--- Auto Dark Mode plugin options M.auto_dark_mode = { update_interval = 2000, + --- Function that runs when dark mode is enabled set_dark_mode = function() vim.o.background = "dark" vim.cmd.colorscheme( require("astral").colortheme or "catppuccin-mocha" or "tokyonight" ) end, + --- Function that runs when light mode is enabled set_light_mode = function() vim.o.background = "light" vim.cmd.colorscheme( @@ -415,33 +835,63 @@ M.auto_dark_mode = { end, } --- Image.nvim filetypes +--- Image.nvim enabled filetypes M.image = "markdown" --- Todo-comments +--- Todo-comments plugin options M.todo = { keywords = { FIX = { icon = " ", -- icon used for the sign, and in search results - color = "error", -- can be a hex color, or a named color (see below) - alt = { "FIXME", "BUG", "FIXIT", "ISSUE" }, -- a set of other keywords that all map to this FIX keywords - -- signs = false, -- configure signs for some keywords individually + color = "error", -- can be a hex color, or a named color + alt = { -- a set of other keywords that all map to this FIX keywords + "FIXME", + "BUG", + "FIXIT", + "ISSUE", + }, }, - TODO = { icon = " ", color = "info" }, + TODO = { icon = " ", color = "info" }, HACK = { icon = " ", color = "warning" }, WARN = { icon = " ", color = "warning", alt = { "WARNING", "XXX" } }, PERF = { icon = " ", alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" } }, NOTE = { icon = " ", color = "hint", alt = { "INFO" } }, + BUST = { + icon = "󰇷 ", + color = "broken", + alt = { "BROKEN", "UNAVAILABLE", "POOP" }, + }, + JUNK = { + icon = " ", + color = "trash", + alt = { "TRASH", "WASTE", "DUMP", "GARBAGE" }, + }, TEST = { - icon = "⏲ ", + icon = " ", color = "test", alt = { "TESTING", "PASSED", "FAILED" }, }, }, + colors = { + error = { "DiagnosticError", "ErrorMsg", "#DC2626" }, + warning = { "DiagnosticWarn", "WarningMsg", "#FBBF24" }, + info = { "DiagnosticInfo", "#2563EB" }, + hint = { "DiagnosticHint", "#10B981" }, + default = { "Identifier", "#7C3AED" }, + test = { "Identifier", "#FF00FF" }, + broken = { "DiagnosticError", "ErrorMsg", "#DC2626" }, + trash = { "DiagnosticUnnecessary", "Comment", "#DC2626" }, + }, lualine = function() local config = { -- The todo-comments types to show & in what order: - order = { "TODO", "FIX", "HACK", "WARN", "NOTE", "PERF", "TEST" }, + order = { + "TODO", + "FIX", + "WARN", + "BUST", + "JUNK", + }, keywords = M.todo.keywords, when_empty = "", } @@ -449,8 +899,26 @@ M.todo = { end, } --- Toggleterm plugin options +--- Colorful Window Separators plugin options +M.colorful_winsep = { + symbols = { "─", "│", "╭", "╮", "╰", "╯" }, + no_exec_files = { + "packer", + "TelescopePrompt", + "mason", + "CompetiTest", + "NvimTree", + "neotree", + "lazy", + "neominimap", + }, +} + +--- Toggleterm plugin options M.toggleterm = { + --- Sets the terminal panel size + ---@param term table The terminal object + ---@return number|nil The terminal size size = function(term) if term.direction == "horizontal" then return 10 @@ -478,12 +946,18 @@ M.toggleterm = { }, winbar = { enabled = true, + --- Function that formats the name of the terminal + ---@param term table The terminal object + ---@return string The formatted name name_formatter = function(term) return term.name end, }, } +--- Function to extend minimap.buf with general exclusions +---@private +---@return nil function M.setup() -- Extend minimap.buf with general exclusions for _, v in ipairs(M.general.buf) do diff --git a/lua/plugins/ai.lua b/lua/plugins/ai.lua index 9ed072f..aa71b33 100644 --- a/lua/plugins/ai.lua +++ b/lua/plugins/ai.lua @@ -1,18 +1,16 @@ +---@module "plugins.ai" +--- This module defines the AI plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ AI Tools │ -- ╰─────────────────────────────────────────────────────────╯ local data = require("data") return { - { + { -- -- Neocodeium "monkoose/neocodeium", event = "VeryLazy", - opts = { - manual = false, - silent = true, - debounce = false, - }, + opts = data.types.neocodeium.opts, keys = data.keys.neocodeium, }, { -- Copilot diff --git a/lua/plugins/alpha.lua b/lua/plugins/alpha.lua deleted file mode 100644 index 0aa8388..0000000 --- a/lua/plugins/alpha.lua +++ /dev/null @@ -1,79 +0,0 @@ --- ╭─────────────────────────────────────────────────────────╮ --- │ ALPHA │ --- ╰─────────────────────────────────────────────────────────╯ - -return { - "goolord/alpha-nvim", - event = "VimEnter", - enabled = true, - init = false, - opts = function() - local dashboard = require("alpha.themes.dashboard") - local logo = [[ -██████╗ ██████╗ ██████╗ ████████╗██╗███████╗███████╗████████╗ ███╗ ██╗██╗ ██╗██╗███╗ ███╗ -██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝╚══██╔══╝ ████╗ ██║██║ ██║██║████╗ ████║ -██████╔╝██║ ██║██║ ██║ ██║ ██║█████╗ ███████╗ ██║ ██╔██╗ ██║██║ ██║██║██╔████╔██║ -██╔══██╗██║ ██║██║ ██║ ██║ ██║██╔══╝ ╚════██║ ██║  ██║╚██╗██║╚██╗ ██╔╝██║██║╚██╔╝██║ -██║ ██║╚██████╔╝╚██████╔╝ ██║ ██║███████╗███████║ ██║ ██║ ╚████║ ╚████╔╝ ██║██║ ╚═╝ ██║ -╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ -]] - - dashboard.section.header.val = vim.split(logo, "\n") - -- stylua: ignore start - dashboard.section.buttons.val = { - ---@diagnostic disable: param-type-mismatch - dashboard.button("f", " " .. " Find file", LazyVim.pick()), - dashboard.button("n", " " .. " New file", [[ ene startinsert ]]), - dashboard.button("r", " " .. " Recent files", LazyVim.pick("oldfiles")), - dashboard.button("g", " " .. " Grep text", LazyVim.pick("live_grep")), - dashboard.button("z", " " .. " LazyGit", " LazyGit "), - dashboard.button("c", " " .. " Config", LazyVim.pick.config_files()), - dashboard.button("s", " " .. " Restore Session", [[ lua require("persistence").load() ]]), - dashboard.button("S", "󰢹 " .. " Remote Session", [[ lua require("config.rootiest").load_remote() ]]), - dashboard.button("l", "󰒲 " .. " Lazy", " Lazy "), - dashboard.button("q", " " .. " Quit", " qa "), - } - -- stylua: ignore end - for _, button in ipairs(dashboard.section.buttons.val) do - button.opts.hl = "AlphaButtons" - button.opts.hl_shortcut = "AlphaShortcut" - end - dashboard.section.header.opts.hl = "AlphaHeader" - dashboard.section.buttons.opts.hl = "AlphaButtons" - dashboard.section.footer.opts.hl = "AlphaFooter" - dashboard.opts.layout[1].val = 10 - return dashboard - end, - config = function(_, dashboard) - -- close Lazy and re-open when the dashboard is ready - if vim.o.filetype == "lazy" then - vim.cmd.close() - vim.api.nvim_create_autocmd("User", { - once = true, - pattern = "AlphaReady", - callback = function() - require("lazy").show() - end, - }) - end - - require("alpha").setup(dashboard.opts) - - vim.api.nvim_create_autocmd("User", { - once = true, - pattern = "LazyVimStarted", - callback = function() - local stats = require("lazy").stats() - local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100) - dashboard.section.footer.val = "⚡ Neovim loaded " - .. stats.loaded - .. "/" - .. stats.count - .. " plugins in " - .. ms - .. "ms" - pcall(vim.cmd.AlphaRedraw) - end, - }) - end, -} diff --git a/lua/plugins/astral.lua b/lua/plugins/astral.lua index 16baec3..7fe579d 100644 --- a/lua/plugins/astral.lua +++ b/lua/plugins/astral.lua @@ -1,20 +1,20 @@ +--- @module "plugins.astral" +--- This module defines the astral plugin spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Astral Plugin │ -- ╰─────────────────────────────────────────────────────────╯ -return { - { - "rootiest/astral.nvim", - version = "*", -- Pin to GitHub releases - opts = { - fallback_themes = { - "catppuccin-macchiato", - "catppuccin-frappe", - "tokyonight", - "kanagawa", - "monochrome", - "default", - }, +return { -- Astral + "rootiest/astral.nvim", + version = "*", -- Pin to GitHub releases + opts = { + fallback_themes = { + "catppuccin-macchiato", + "catppuccin-frappe", + "tokyonight", + "kanagawa", + "monochrome", + "default", }, - -- dev = true, -- Use local codebase }, + -- dev = true, -- Use local codebase } diff --git a/lua/plugins/cmp.lua b/lua/plugins/cmp.lua index b0a3c0e..419f3db 100644 --- a/lua/plugins/cmp.lua +++ b/lua/plugins/cmp.lua @@ -1,145 +1,143 @@ +--- @module "plugins.cmp" +--- This module defines the cmp plugin spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Auto Completion │ -- ╰─────────────────────────────────────────────────────────╯ local data = require("data") -return { - { - "hrsh7th/nvim-cmp", - -- HACK: Experiemental cmp performance fork - dev = true, - event = "VeryLazy", - dependencies = data.deps.cmp, - -- : - config = function() - local cmp = require("cmp") - local luasnip = require("luasnip") - local neocodeium = require("neocodeium") - local commands = require("neocodeium.commands") +return { -- + "hrsh7th/nvim-cmp", + -- HACK: Experiemental cmp performance fork + dev = true, + event = "VeryLazy", + dependencies = data.deps.cmp, + -- : + config = function() + local cmp = require("cmp") + local luasnip = require("luasnip") + local neocodeium = require("neocodeium") + local commands = require("neocodeium.commands") - cmp.event:on("menu_opened", function() - neocodeium.clear() - end) + cmp.event:on("menu_opened", function() + neocodeium.clear() + end) - cmp.event:on("menu_closed", function() - commands.enable() - neocodeium.cycle_or_complete() - end) + cmp.event:on("menu_closed", function() + commands.enable() + neocodeium.cycle_or_complete() + end) - local border_opts = { - border = "rounded", - } - local window_opts = { - completion = cmp.config.window.bordered(border_opts), - documentation = cmp.config.window.bordered(border_opts), - } - luasnip.config.setup({}) + local border_opts = { + border = "rounded", + } + local window_opts = { + completion = cmp.config.window.bordered(border_opts), + documentation = cmp.config.window.bordered(border_opts), + } + luasnip.config.setup({}) - cmp.setup({ - snippet = { - expand = function(args) - luasnip.lsp_expand(args.body) - end, - }, - completion = { completeopt = "menu,menuone,noinsert" }, - window = vim.g.completion_round_borders_enabled and window_opts or {}, - mapping = cmp.mapping.preset.insert({ - [""] = cmp.mapping.select_next_item(), - [""] = cmp.mapping.select_prev_item(), - [""] = cmp.mapping.select_prev_item({ - behavior = cmp.SelectBehavior.Select, - }), - [""] = cmp.mapping.select_next_item({ - behavior = cmp.SelectBehavior.Select, - }), - [""] = cmp.mapping.scroll_docs(-4), - [""] = cmp.mapping.scroll_docs(4), - [""] = cmp.mapping.confirm({ select = true }), - [""] = cmp.mapping.complete({}), - [""] = cmp.mapping(function() - if luasnip.expand_or_locally_jumpable() then - luasnip.expand_or_jump() - end - end, { "i", "s" }), - [""] = cmp.mapping(function() - if luasnip.locally_jumpable(-1) then - luasnip.jump(-1) - end - end, { "i", "s" }), + cmp.setup({ + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + completion = { completeopt = "menu,menuone,noinsert" }, + window = vim.g.completion_round_borders_enabled and window_opts or {}, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping.select_prev_item(), + [""] = cmp.mapping.select_prev_item({ + behavior = cmp.SelectBehavior.Select, }), - sources = { - { name = "nvim_lsp", priority = 1000 }, - { name = "luasnip", priority = 750 }, - { name = "path", priority = 250 }, - { name = "buffer", priority = 250 }, - { name = "cmp_yanky" }, - { name = "dotenv" }, - { name = "calc" }, - { name = "conventionalcommits" }, - { name = "gitmoji", priority = 9998 }, - { name = "emoji", priority = 9999 }, - }, - formatting = { - fields = { "abbr", "kind", "menu" }, - expandable_indicator = true, - format = function(entry, item) - local color_item = require("nvim-highlight-colors").format( - entry, - { kind = item.kind } - ) - item = require("lspkind").cmp_format({ - require("tailwind-tools.cmp").lspkind_format, - })(entry, item) - if color_item.abbr_hl_group then - item.kind_hl_group = color_item.abbr_hl_group - item.kind = color_item.abbr - end - return item - end, - }, - }) + [""] = cmp.mapping.select_next_item({ + behavior = cmp.SelectBehavior.Select, + }), + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.confirm({ select = true }), + [""] = cmp.mapping.complete({}), + [""] = cmp.mapping(function() + if luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + end + end, { "i", "s" }), + [""] = cmp.mapping(function() + if luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + end + end, { "i", "s" }), + }), + sources = { + { name = "nvim_lsp", priority = 1000 }, + { name = "luasnip", priority = 750 }, + { name = "path", priority = 250 }, + { name = "buffer", priority = 250 }, + { name = "cmp_yanky" }, + { name = "dotenv" }, + { name = "calc" }, + { name = "conventionalcommits" }, + { name = "gitmoji", priority = 9998 }, + { name = "emoji", priority = 9999 }, + }, + formatting = { + fields = { "abbr", "kind", "menu" }, + expandable_indicator = true, + format = function(entry, item) + local color_item = + require("nvim-highlight-colors").format(entry, { kind = item.kind }) + item = require("lspkind").cmp_format({ + require("tailwind-tools.cmp").lspkind_format, + })(entry, item) + if color_item.abbr_hl_group then + item.kind_hl_group = color_item.abbr_hl_group + item.kind = color_item.abbr + end + return item + end, + }, + }) - -- `:` cmdline setup. - cmp.setup.cmdline(":", { - mapping = cmp.mapping.preset.cmdline(), - sources = cmp.config.sources({ - { name = "path" }, - }, { - { - name = "cmdline", - option = { - ignore_cmds = { "Man", "!" }, - }, + -- `:` cmdline setup. + cmp.setup.cmdline(":", { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = "path" }, + }, { + { + name = "cmdline", + option = { + ignore_cmds = { "Man", "!" }, }, - }, { name = "cmp-cmdline-history" }, { - name = "cmp-cmdline-prompt", - }), - }) - - -- Additional setup for cmdline filetype - cmp.setup.filetype("cmdline", { - sources = { - { name = "cmdline" }, -- Ensure 'cmdline' source is available - { name = "path" }, - { name = "cmp-cmdline-history" }, - { name = "cmp-cmdline-prompt" }, }, - }) + }, { name = "cmp-cmdline-history" }, { + name = "cmp-cmdline-prompt", + }), + }) - -- Custom filetype configuration - cmp.setup.filetype("config", { - sources = vim.tbl_filter(function(source) - return source.name ~= "emoji" and source.name ~= "gitmoji" - end, cmp.get_config().sources), - }) + -- Additional setup for cmdline filetype + cmp.setup.filetype("cmdline", { + sources = { + { name = "cmdline" }, -- Ensure 'cmdline' source is available + { name = "path" }, + { name = "cmp-cmdline-history" }, + { name = "cmp-cmdline-prompt" }, + }, + }) - -- List of filetypes to disable completion - local disabled_filetypes = data.types.cmp - for _, filetype in ipairs(disabled_filetypes) do - cmp.setup.filetype(filetype, { - sources = {}, - }) - end - end, - }, + -- Custom filetype configuration + cmp.setup.filetype("config", { + sources = vim.tbl_filter(function(source) + return source.name ~= "emoji" and source.name ~= "gitmoji" + end, cmp.get_config().sources), + }) + + -- List of filetypes to disable completion + local disabled_filetypes = data.types.cmp + for _, filetype in ipairs(disabled_filetypes) do + cmp.setup.filetype(filetype, { + sources = {}, + }) + end + end, } diff --git a/lua/plugins/coding.lua b/lua/plugins/coding.lua index db226a6..d1592ca 100644 --- a/lua/plugins/coding.lua +++ b/lua/plugins/coding.lua @@ -1,3 +1,5 @@ +--- @module "plugins.coding" +--- This module defines the coding plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Coding │ -- ╰─────────────────────────────────────────────────────────╯ @@ -10,15 +12,9 @@ return { automatic_installation = true, }, }, - { + { -- "neovim/nvim-lspconfig", - opts = { - setup = { - clangd = function(_, opts) - opts.capabilities.offsetEncoding = { "utf-16" } - end, - }, - }, + opts = data.types.lspconfig.opts, }, { -- Yanky import = "lazyvim.plugins.extras.coding.yanky", @@ -32,13 +28,6 @@ return { { -- G-code "wilriker/gcode.vim", }, - { -- Mini Align - "echasnovski/mini.align", - event = "InsertEnter", - config = function() - require("mini.align").setup() - end, - }, { -- Alternate "ton/vim-alternate", lazy = true, @@ -57,16 +46,8 @@ return { opts = data.types.substitute, keys = data.keys.substitute, }, - { -- mini.splitjoin - "echasnovski/mini.splitjoin", - event = "InsertEnter", - opts = { - mappings = data.keys.splitjoin, - }, - }, - { -- mini-surround - "echasnovski/mini.surround", - opts = {}, - keys = data.keys.surround, + { + "iamcco/markdown-preview.nvim", + build = "cd app && yarn install", }, } diff --git a/lua/plugins/core.lua b/lua/plugins/core.lua index 6563c71..fdab396 100644 --- a/lua/plugins/core.lua +++ b/lua/plugins/core.lua @@ -1,38 +1,24 @@ +--- @module "plugins.core" +--- This module defines the core plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Core │ -- ╰─────────────────────────────────────────────────────────╯ local data = require("data") return { + require("config.rocks").plugin_spec, { -- LazyVim "LazyVim/LazyVim", - opts = { - colorscheme = vim.g.my_colorscheme or "catppuccin-mocha", - news = { - lazyvim = true, - neovim = true, - }, - }, - }, - { -- Mini-animate - import = "lazyvim.plugins.extras.ui.mini-animate", + priority = 900, + opts = data.types.lazyvim.opts, }, { -- Bufferline "akinsho/bufferline.nvim", - opts = { - options = data.types.bufferline, - }, + opts = data.types.bufferline.opts, }, { -- Which-Key "folke/which-key.nvim", lazy = true, - opts = { - preset = "modern", - win = { - wo = { - winblend = 10, - }, - }, - }, + opts = data.types.whichkey.opts, }, } diff --git a/lua/plugins/dashboard/alpha.lua b/lua/plugins/dashboard/alpha.lua new file mode 100644 index 0000000..7d2498d --- /dev/null +++ b/lua/plugins/dashboard/alpha.lua @@ -0,0 +1,49 @@ +--- @module "plugins.dashboard.alpha" +--- This module defines the alpha plugin spec for the Neovim configuration. +-- ╭─────────────────────────────────────────────────────────╮ +-- │ ALPHA │ +-- ╰─────────────────────────────────────────────────────────╯ +return { -- Alpha + "goolord/alpha-nvim", + event = "VimEnter", + enabled = true, + opts = require("data").dash.alpha.opts, + config = function(_, dashboard) + -- close Lazy and re-open when the dashboard is ready + if vim.o.filetype == "lazy" then + vim.cmd.close() + vim.api.nvim_create_autocmd("User", { + once = true, + pattern = "AlphaReady", + callback = function() + require("lazy").show() + end, + }) + end + + -- Setup the dashboard + require("alpha").setup(dashboard.opts) + + -- Open Alpha when Vim is started with no file arguments + vim.api.nvim_create_autocmd("User", { + once = true, + pattern = "LazyVimStarted", + callback = function() + local stats = require("lazy").stats() + local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100) + -- If auto-cursorline is installed, disable it + if pcall(require, "auto-cursorline") then + require("auto-cursorline").disable({ buffer = true }) + end + dashboard.section.footer.val = "⚡ Neovim loaded " + .. stats.loaded + .. "/" + .. stats.count + .. " plugins in " + .. ms + .. "ms" + pcall(vim.cmd.AlphaRedraw) + end, + }) + end, +} diff --git a/lua/plugins/dashboard.lua b/lua/plugins/dashboard/nvim-dashboard.lua similarity index 95% rename from lua/plugins/dashboard.lua rename to lua/plugins/dashboard/nvim-dashboard.lua index 7403ff2..1b96799 100644 --- a/lua/plugins/dashboard.lua +++ b/lua/plugins/dashboard/nvim-dashboard.lua @@ -1,11 +1,12 @@ +--- @module "plugins.dashboard.nvim-dashboard" +--- This module defines the dashboard plugin spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Dashboard │ -- ╰─────────────────────────────────────────────────────────╯ local data = require("data") -return { +return { -- -- Dashboard - enabled = false, "nvimdev/dashboard-nvim", event = "UIEnter", version = false, @@ -64,7 +65,7 @@ return { file_height = logo_dimensions.height, }, config = { - center = data.dash.choices, + center = data.dash.dashboard_nvim.choices, footer = function() local stats = require("lazy").stats() local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100) @@ -110,4 +111,5 @@ return { return opts end, + enabled = false, } diff --git a/lua/plugins/debug.lua b/lua/plugins/debug.lua index 87a390a..ee5fcf8 100644 --- a/lua/plugins/debug.lua +++ b/lua/plugins/debug.lua @@ -1,3 +1,5 @@ +--- @module "plugins.debug" +--- This module defines the debug plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Debug │ -- ╰─────────────────────────────────────────────────────────╯ @@ -13,8 +15,10 @@ return { { -- NeoTest import = "lazyvim.plugins.extras.test.core", }, - { "nvim-neotest/neotest-plenary" }, - { + { -- Neotest Plenary + "nvim-neotest/neotest-plenary", + }, + { -- Neotest "nvim-neotest/neotest", opts = { adapters = data.deps.neotest.adapters, diff --git a/lua/plugins/editor.lua b/lua/plugins/editor.lua index 0cc8416..9e16a22 100644 --- a/lua/plugins/editor.lua +++ b/lua/plugins/editor.lua @@ -1,3 +1,5 @@ +--- @module "plugins.editor" +--- This module defines the editor plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Editor │ -- ╰─────────────────────────────────────────────────────────╯ @@ -22,24 +24,10 @@ return { { -- Treesitter-context import = "lazyvim.plugins.extras.ui.treesitter-context", }, - { -- Mini.move - import = "lazyvim.plugins.extras.editor.mini-move", - }, - { + { -- Trouble "folke/trouble.nvim", cmd = data.cmd.trouble, - opts = { - modes = { - symbols = { -- Configure symbols mode - win = { - type = "split", -- split window - relative = "win", -- relative to current window - position = "right", -- right side - size = 0.3, -- 30% of the window - }, - }, - }, - }, + opts = data.types.trouble.opts, }, { -- Flash "folke/flash.nvim", @@ -48,6 +36,10 @@ return { }, keys = data.keys.flash, }, + { + "nvim-neo-tree/neo-tree.nvim", + opts = data.types.neotree.opts, + }, { -- Arrow "otavioschwanck/arrow.nvim", opts = data.types.arrow, @@ -114,9 +106,7 @@ return { }, { -- Todo Comments "folke/todo-comments.nvim", - opts = { - keywords = data.types.todo.keywords, - }, + opts = data.types.todo.opts, }, { -- Rainbow Delimeters "HiPhish/rainbow-delimiters.nvim", @@ -125,24 +115,26 @@ return { "nvim-zh/colorful-winsep.nvim", opts = { only_line_seq = false, - symbols = { "─", "│", "╭", "╮", "╰", "╯" }, - no_exec_files = { - "packer", - "TelescopePrompt", - "mason", - "CompetiTest", - "NvimTree", - "neotree", - "lazy", - "neominimap", - }, + symbols = data.types.colorful_winsep.symbols, + no_exec_files = data.types.colorful_winsep.no_exec_files, }, event = { "WinLeave" }, }, { -- Auto Cursorline "delphinus/auto-cursorline.nvim", + enabled = data.func.check_global_var("auto_cursorline", true, true), opts = { wait_ms = 2000, }, }, + { -- Bars N Lines + "OXY2DEV/bars-N-lines.nvim", + enabled = data.func.check_global_var( + "statuscolumn", + "barsNlines", + "native" + ), + lazy = false, + config = data.types.barsNlines, + }, } diff --git a/lua/plugins/git.lua b/lua/plugins/git.lua index 3ee2f23..166955d 100644 --- a/lua/plugins/git.lua +++ b/lua/plugins/git.lua @@ -1,3 +1,5 @@ +--- @module "plugins.git" +--- This module defines the git plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Git Plugins │ -- ╰─────────────────────────────────────────────────────────╯ @@ -7,11 +9,6 @@ return { { -- Octo plugin import = "lazyvim.plugins.extras.util.octo", }, - { -- DiffView - "sindrets/diffview.nvim", - lazy = true, - cmd = data.cmd.diffview, - }, { -- Gist Tools "Rawnly/gist.nvim", lazy = true, @@ -33,9 +30,7 @@ return { "jsongerber/thanks.nvim", lazy = true, cmd = data.cmd.thanks, - opts = { - star_on_install = false, - }, + opts = data.types.thanks.opts, }, { -- GitLinker "linrongbin16/gitlinker.nvim", @@ -47,31 +42,7 @@ return { { -- Git Blame "f-person/git-blame.nvim", event = "VeryLazy", - opts = function() - -- Get the current lualine configuration - local config = require("lualine").get_config() - local git_blame = require("gitblame") - local funcs = data.func - -- Define the width limit for displaying the Git blame component - local width_limit = 245 -- Adjust this value as needed - -- Add Git-blame to lualine_c section - table.insert(config.sections.lualine_c, { - git_blame.get_current_blame_text, - cond = function() -- Only show if text is available - return git_blame.is_blame_text_available() - and funcs.is_window_wide_enough(width_limit) - end, - color = { fg = funcs.get_fg_color("GitSignsCurrentLineBlame") }, - padding = { left = 1, right = 0 }, - on_click = function() - vim.cmd("LazyGit") - end, - }) - -- Apply the lualine configuration - require("lualine").setup(config) - -- Return the git-blame options - return data.types.gitblame - end, + opts = data.types.gitblame.opts, }, { -- Git Graph "isakbm/gitgraph.nvim", diff --git a/lua/plugins/init.lua b/lua/plugins/init.lua new file mode 100644 index 0000000..3dc8dce --- /dev/null +++ b/lua/plugins/init.lua @@ -0,0 +1,54 @@ +---@module "plugins" +--- This module defines the plugins for the Neovim configuration. +--- +--- If lazy.nvim is installed, this module returns an empty table +--- to defer plugin management to lazy.nvim. +--- +--- If lazy.nvim is not installed, the module loads each +--- Lua file in the `plugins` directory. +--- +--- Note: +--- A warning will be triggered if lazy.nvim is not installed unless +--- the variable `vim.g.ignore_no_lazy` is set to `true`. +-- +-- ╭─────────────────────────────────────────────────────────╮ +-- │ PLUGINS DATA │ +-- ╰─────────────────────────────────────────────────────────╯ + +local M = {} + +-- Check if lazy.nvim is installed +if pcall(require, "lazy") then + -- If lazy.nvim is installed, return an empty table and do nothing + return M +else + -- If lazy.nvim is not installed and vim.g.ignore_no_lazy is not set, display a warning + if not vim.g.ignore_no_lazy then + require("data").func.notify("lazy.nvim is not installed", "WARNING") + end + + -- Function to iterate over files in the directory and load them dynamically + local function read_plugins_dir() + -- Get the root path for the plugins directory + local dir_path = + vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":h") + + -- Open the directory + local files = vim.fn.readdir(dir_path) + + for _, file in ipairs(files) do + -- Skip init.lua + if file ~= "init.lua" and file:match(".*%.lua$") then + -- Get the module name without the .lua extension + local plugin_name = file:sub(1, -5) + -- Load the plugin configuration file + require("plugins." .. plugin_name) + end + end + end + + -- Read the directory and load plugin configuration files when lazy.nvim is not installed + read_plugins_dir() +end + +return M diff --git a/lua/plugins/languages.lua b/lua/plugins/languages.lua index 9de01a8..d4cc793 100644 --- a/lua/plugins/languages.lua +++ b/lua/plugins/languages.lua @@ -1,3 +1,5 @@ +--- @module "plugins.languages" +--- This module defines the languages plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Languages │ -- ╰─────────────────────────────────────────────────────────╯ diff --git a/lua/plugins/mini.lua b/lua/plugins/mini.lua new file mode 100644 index 0000000..ab58a97 --- /dev/null +++ b/lua/plugins/mini.lua @@ -0,0 +1,42 @@ +---@module "plugins.mini" +--- This module defines the mini plugins spec for the Neovim configuration. +-- ╭─────────────────────────────────────────────────────────╮ +-- │ Mini │ +-- ╰─────────────────────────────────────────────────────────╯ +local data = require("data") + +return { + { -- mini.animate + import = "lazyvim.plugins.extras.ui.mini-animate", + }, + { -- mini.move + import = "lazyvim.plugins.extras.editor.mini-move", + }, + { -- mini.align + "echasnovski/mini.align", + event = "InsertEnter", + config = function() + require("mini.align").setup() + end, + }, + { -- mini.splitjoin + "echasnovski/mini.splitjoin", + event = "InsertEnter", + opts = { + mappings = data.keys.splitjoin, + }, + }, + { -- mini.surround + "echasnovski/mini.surround", + opts = {}, + keys = function() + data.func.add_keymap(data.keys.surround) + end, + }, + { -- mini.files + "echasnovski/mini.files", + opts = data.types.minifiles.opts, + keys = data.keys.minifiles, + config = data.types.minifiles.config, + }, +} diff --git a/lua/plugins/override.lua b/lua/plugins/override.lua new file mode 100644 index 0000000..ccd3502 --- /dev/null +++ b/lua/plugins/override.lua @@ -0,0 +1,29 @@ +---@module "plugins.override" +--- This module defines the plugin spec overrides for the Neovim configuration. +--- This is used to prioritize certain plugins over others or to override +--- the default behavior of a core plugin. +--- +-- ╭─────────────────────────────────────────────────────────╮ +-- │ Overrides │ +-- ╰─────────────────────────────────────────────────────────╯ +return { + { -- Override build for markdown-preview + "iamcco/markdown-preview.nvim", + priority = 1001, + build = "cd app && yarn install", + }, + { -- Prioritize dadbod + "kristijanhusak/vim-dadbod-completion", + priority = 1001, + dependencies = "vim-dadbod", + }, + { -- Prioritize dadbod + "kristijanhusak/vim-dadbod-ui", + priority = 1001, + dependencies = "vim-dadbod", + }, + { -- Prioritize dadbod + "tpope/vim-dadbod", + priority = 1002, + }, +} diff --git a/lua/plugins/statusline/basic.lua b/lua/plugins/statusline/basic.lua new file mode 100644 index 0000000..f952fac --- /dev/null +++ b/lua/plugins/statusline/basic.lua @@ -0,0 +1,21 @@ +---@module "plugins.statusline.basic" +--- This module defines the basic statusline spec for the Neovim configuration. +--- This option uses the native statusline feature to create a basic statusline +--- +--- Activate this module by setting the 'vim.g.statusline' variable to 'basic' +-- ╭─────────────────────────────────────────────────────────╮ +-- │ BASIC │ +-- ╰─────────────────────────────────────────────────────────╯ + +-- If basic statusline is not enabled, return an empty table +if vim.g.statusline ~= "basic" then + return {} +end + +-- Set up the basic statusline + +---TODO: Write a basic statusline configuration using the +--- native statusline feature. + +-- No lazy.nvim plugin necessary +return {} diff --git a/lua/plugins/statusline/heirline.lua b/lua/plugins/statusline/heirline.lua new file mode 100644 index 0000000..6c28d2c --- /dev/null +++ b/lua/plugins/statusline/heirline.lua @@ -0,0 +1,19 @@ +--- @module "plugins.statusline.heirline" +--- This module defines the heirline plugin spec for the Neovim configuration. +--- This option uses the heirline plugin to create a statusline for Neovim +--- +--- Activate this module by setting the 'vim.g.statusline' variable to 'heirline' +-- ╭─────────────────────────────────────────────────────────╮ +-- │ Heirline │ +-- ╰─────────────────────────────────────────────────────────╯ + +local data = require("data") + +return { + { + "rebelot/heirline.nvim", + enabled = data.func.check_global_var("statusline", "heirline", "lualine"), + event = "UIEnter", + opts = {}, + }, +} diff --git a/lua/plugins/lualine.lua b/lua/plugins/statusline/lualine.lua similarity index 88% rename from lua/plugins/lualine.lua rename to lua/plugins/statusline/lualine.lua index 898c00f..ad70906 100644 --- a/lua/plugins/lualine.lua +++ b/lua/plugins/statusline/lualine.lua @@ -1,13 +1,26 @@ +--- @module "plugins.statusline.lualine" +--- This module defines the lualine plugin spec for the Neovim configuration. +--- This option uses the lualine plugin to create a statusline for Neovim +--- +--- Activate this module by setting the 'vim.g.statusline' variable to 'lualine' -- ╭─────────────────────────────────────────────────────────╮ -- │ Lualine │ -- ╰─────────────────────────────────────────────────────────╯ -local utils = require("utils") +local wakatime_stats = require("utils.wakatime_stats") +local music_stats = require("utils.music_stats") local data = require("data") local funcs = data.func -return { +-- Use lualine by default +if vim.g.statusline == nil then + vim.g.statusline = "lualine" +end + +return { -- Lualine "nvim-lualine/lualine.nvim", + enabled = data.func.check_global_var("statusline", "lualine", "lualine"), + dependencies = data.deps.lualine, init = function() vim.g.lualine_laststatus = vim.o.laststatus @@ -41,9 +54,11 @@ return { }, sections = { -- Sections lualine_a = { - { -- Mode - "mode", - icon = data.types.logo.icon, + { + -- Calls the current.lualine() function to get the mode string + function() + return data.types.mode.current.lualine() + end, padding = { left = 1, right = 0 }, }, }, @@ -128,7 +143,9 @@ return { removed = icons.git.removed, padding = { left = 0, right = 0 }, on_click = function() - vim.cmd("LazyGit") + if vim.g.statusline_clickable_git ~= false then + require("config.rootiest").toggle_lazygit_float() + end end, }, { -- GitSigns @@ -147,16 +164,18 @@ return { end, padding = { left = 0, right = 0 }, on_click = function() - vim.cmd("LazyGit") + if vim.g.statusline_clickable_git ~= false then + require("config.rootiest").toggle_lazygit_float() + end end, }, }, { -- Wakatime function() - return utils.wakatime_stats.get_icon_with_text() + return wakatime_stats.get_icon_with_text() end, color = function() - return utils.wakatime_stats.get_color() + return wakatime_stats.get_color() end, cond = function() return funcs.is_window_wide_enough(100) @@ -165,7 +184,7 @@ return { }, { -- Music function() - return utils.music_stats.get_icon_with_text() + return music_stats.get_icon_with_text() end, cond = function() return funcs.is_window_wide_enough(100) diff --git a/lua/plugins/statusline/none.lua b/lua/plugins/statusline/none.lua new file mode 100644 index 0000000..aa8f539 --- /dev/null +++ b/lua/plugins/statusline/none.lua @@ -0,0 +1,20 @@ +---@module "plugins.statusline.none" +--- This module sets up the no-statusline optional mode for the Neovim configuration. +--- This option disables the statusline entirely for a more minimalistic appearance. +--- +--- Activate this module by setting the 'vim.g.statusline' variable to 'none' +-- ╭─────────────────────────────────────────────────────────╮ +-- │ No Statusline │ +-- ╰─────────────────────────────────────────────────────────╯ + +if vim.g.statusline ~= "none" then + return {} +end + +-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ NO-STATUSLINE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +-- Set up the no-statusline +vim.o.laststatus = 0 + +-- No lazy.nvim plugin necessary +return {} diff --git a/lua/plugins/terminal.lua b/lua/plugins/terminal.lua index 5f6d109..3b7372d 100644 --- a/lua/plugins/terminal.lua +++ b/lua/plugins/terminal.lua @@ -1,15 +1,8 @@ +---@module "plugins.terminal" +--- This module defines the terminal plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Terminals │ -- ╰─────────────────────────────────────────────────────────╯ --- package.path = package.path --- .. ";" --- .. vim.fn.expand("$HOME") --- .. "/.luarocks/share/lua/5.1/?/init.lua" --- package.path = package.path --- .. ";" --- .. vim.fn.expand("$HOME") --- .. "/.luarocks/share/lua/5.1/?.lua" - local data = require("data") return { @@ -24,7 +17,14 @@ return { config = function() require("image").setup() end, - cond = vim.g.useimage and not vim.g.neovide, + cond = function() + -- Disable image rendering in Neovide + -- or when vim.g.useimage = false + if vim.g.useimage == false then + return false + end + return not vim.g.neovide + end, }, { -- ToggleTerm "akinsho/toggleterm.nvim", diff --git a/lua/plugins/themes.lua b/lua/plugins/themes.lua index 18181e0..a179498 100644 --- a/lua/plugins/themes.lua +++ b/lua/plugins/themes.lua @@ -1,3 +1,5 @@ +--- @module "plugins.themes" +--- This module defines the themes plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Themes │ -- ╰─────────────────────────────────────────────────────────╯ diff --git a/lua/plugins/util.lua b/lua/plugins/util.lua index f9c1ebe..c080f3e 100644 --- a/lua/plugins/util.lua +++ b/lua/plugins/util.lua @@ -1,3 +1,5 @@ +--- @module "plugins.util" +--- This module defines the utility plugins spec for the Neovim configuration. -- ╭─────────────────────────────────────────────────────────╮ -- │ Utilities │ -- ╰─────────────────────────────────────────────────────────╯ @@ -27,6 +29,7 @@ return { }, { -- Auto-save "okuuva/auto-save.nvim", + enabled = data.func.check_global_var("auto_save", true, true), cmd = data.cmd.autosave, event = { "InsertLeave", "TextChanged" }, opts = { @@ -55,6 +58,7 @@ return { }, { -- Codesnap "mistricky/codesnap.nvim", + enabled = data.func.check_global_var("codesnap", true, true), lazy = true, build = "make", opts = { @@ -89,6 +93,7 @@ return { }, { -- Music Controls "AntonVanAssche/music-controls.nvim", + enabled = data.func.check_global_var("usemusic", true, true), dependencies = data.deps.musiccontrols, opts = { default_player = "YoutubeMusic", @@ -129,6 +134,10 @@ return { { -- Suda "lambdalisue/vim-suda", cmd = data.cmd.suda, + config = function() + vim.g.suda_smart_edit = 1 + vim.cmd("let g:suda#prompt = '  Enter Sudo Password  '") + end, }, { -- Spell checker "matkrin/telescope-spell-errors.nvim", @@ -137,7 +146,7 @@ return { end, dependencies = data.deps.needs_telescope, }, - { + { -- "Pheon-Dev/pigeon", config = data.types.pigeon, }, diff --git a/lua/utils/blinky.lua b/lua/utils/blinky.lua index a542557..09e552a 100644 --- a/lua/utils/blinky.lua +++ b/lua/utils/blinky.lua @@ -1,3 +1,6 @@ +---@module "utils.blinky" +--- This module provides a function to set up and disable the blinky cursor. + local M = {} --- Function to set up blinky cursor diff --git a/lua/utils/cache_stats.lua b/lua/utils/cache_stats.lua index ff0e291..3126107 100644 --- a/lua/utils/cache_stats.lua +++ b/lua/utils/cache_stats.lua @@ -1,8 +1,11 @@ +---@module "utils.cache_stats" +--- This module provides a function to update the cached statistics. -- ╭─────────────────────────────────────────────────────────╮ -- │ Cache Stats │ -- ╰─────────────────────────────────────────────────────────╯ local M = {} + -- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -- Options can be set with: -- vim.g.stats_wakatime = true|false (default: true) @@ -14,6 +17,10 @@ local M = {} local config_dir = vim.fn.stdpath("config") --[[@as string]] local cache_script = vim.fs.joinpath(config_dir, "scripts", "update_cache.sh") +-- Path to the Neovim cache directory +_G.cache_stats_dir = -- Cache directory + vim.fn.stdpath("cache") --[[@as string]] + -- Flag to check if the script has already been run local script_run_once = false @@ -32,13 +39,9 @@ for _, player in ipairs(vim.g.stats_ignored_players or {}) do table.insert(ignored_players, player) end -if vim.g.stats_music == nil then - vim.g.stats_music = true -end - -if vim.g.stats_wakatime == nil then - vim.g.stats_wakatime = true -end +-- Set the default values for the options +vim.g.stats_music = vim.g.stats_music or true +vim.g.stats_wakatime = vim.g.stats_wakatime or true --- Function to run the cache script ---@return boolean|number pid The pid of the script @@ -47,6 +50,10 @@ function M.setup_script() -- Build the arguments for the cache script local args = { cache_script } + -- Add the --cache-dir option + table.insert(args, "--cache-dir") + table.insert(args, _G.cache_stats_dir) + -- Add the --ignore option with the ignored players if #ignored_players > 0 then table.insert(args, "--ignore") @@ -77,7 +84,7 @@ function M.setup_script() return false end --- Run the setup script only once +-- Run the setup script M.setup_script() return M diff --git a/lua/utils/cmd_window.lua b/lua/utils/cmd_window.lua index 5eda4d5..5b80fb6 100644 --- a/lua/utils/cmd_window.lua +++ b/lua/utils/cmd_window.lua @@ -1,3 +1,5 @@ +---@module "utils.cmd_window" +--- This module provides a function to open a floating window with a completion menu. -- ╭─────────────────────────────────────────────────────────╮ -- │ Rootiest Command Window │ -- ╰─────────────────────────────────────────────────────────╯ diff --git a/lua/utils/highlight.lua b/lua/utils/highlight.lua index 47d420d..52a0652 100644 --- a/lua/utils/highlight.lua +++ b/lua/utils/highlight.lua @@ -1,8 +1,8 @@ +---@module "utils.highlight" +--- This module provides functions to apply highlights to the statusline and other components. -- ╭─────────────────────────────────────────────────────────╮ -- │ Highlight │ -- ╰─────────────────────────────────────────────────────────╯ ----@module "utils.highlight" ---- This module provides functions to apply highlights to the statusline and other components. local M = {} diff --git a/lua/utils/init.lua b/lua/utils/init.lua index 7ea79eb..ab74bd2 100644 --- a/lua/utils/init.lua +++ b/lua/utils/init.lua @@ -1,25 +1,42 @@ ---@module "utils" --- This module aggregates various utility functions used across the configuration. ---- It provides access to caching mechanisms, Git utilities, WakaTime statistics, music status, highlighting utilities, and a blinking effect utility. +--- It provides access to caching mechanisms, Git utilities, WakaTime statistics, music status, highlight utilities, and a blinking effect utility. -local cache = require("utils.cache_stats") -local git = require("utils.git") -local wakatime = require("utils.wakatime_stats") -local music = require("utils.music_stats") -local highlight = require("utils.highlight") -local blinky = require("utils.blinky") +local utils = {} ----@alias UtilsModule ----| { cache_stats: table, git: table, wakatime_stats: table, music_stats: table, highlight: table, blinky: table } +-- Explicitly specify modules for LSP support +utils.cache_stats = require("utils.cache_stats") +utils.git = require("utils.git") +utils.wakatime_stats = require("utils.wakatime_stats") +utils.music_stats = require("utils.music_stats") +utils.highlight = require("utils.highlight") +utils.blinky = require("utils.blinky") + +-- Function to iterate over files in the directory and load them dynamically +local function read_utils_dir() + -- Getting the root path for the current module directory + local dir_path = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":h") + + -- Open the directory + local files = vim.fn.readdir(dir_path) + + for _, file in ipairs(files) do + -- Skip init.lua + if file ~= "init.lua" and file:match(".*%.lua$") then + -- Get the module name without the .lua extension + local module_name = file:sub(1, -5) + -- Load the module if not already explicitly set + if not utils[module_name] then + utils[module_name] = require("utils." .. module_name) + end + end + end +end + +-- Read the directory to load any additional modules +read_utils_dir() + +---@alias UtilsModule table ---@type UtilsModule -local utils = { - cache_stats = cache, - git = git, - wakatime_stats = wakatime, - music_stats = music, - highlight = highlight, - blinky = blinky, -} - return utils diff --git a/lua/utils/music_stats.lua b/lua/utils/music_stats.lua index d63f245..b537e1d 100644 --- a/lua/utils/music_stats.lua +++ b/lua/utils/music_stats.lua @@ -4,7 +4,7 @@ local M = {} require("utils.cache_stats") -local cache_file = os.getenv("HOME") .. "/.cache/music_cache.txt" +local cache_file = vim.fs.joinpath(_G.cache_stats_dir, "music_cache.txt") local separator = "␟" local last_known_value = "" diff --git a/lua/utils/wakatime_stats.lua b/lua/utils/wakatime_stats.lua index a6780c0..cd24902 100644 --- a/lua/utils/wakatime_stats.lua +++ b/lua/utils/wakatime_stats.lua @@ -1,10 +1,12 @@ +---@module "utils.wakatime_stats" +--- This module provides functions to retrieve wakatime statistics from the cache file. -- ╭─────────────────────────────────────────────────────────╮ -- │ WakaTime Stats │ -- ╰─────────────────────────────────────────────────────────╯ local M = {} require("utils.cache_stats") -local cache_file = os.getenv("HOME") .. "/.cache/wakatime_cache.txt" +local cache_file = vim.fs.joinpath(_G.cache_stats_dir, "wakatime_cache.txt") -- Local variable to store the last known value local last_known_value = "" @@ -41,7 +43,10 @@ end --- Function to get the wakatime today status ---@return string status The wakatime today status function M.get_today() - return get_wakatime_today() + local text = get_wakatime_today() + -- Check if it starts with "0 hrs " and remove it + text = text:gsub("^0 hrs%s*", "") + return text end --- Function to get the wakatime today icon diff --git a/scripts/update_cache.sh b/scripts/update_cache.sh index 55682c3..36db2ff 100755 --- a/scripts/update_cache.sh +++ b/scripts/update_cache.sh @@ -9,6 +9,7 @@ ignored_sources="" # Flags for disabling functionality disable_wakatime=false no_music=false +custom_cache_dir="" # Function to print usage print_usage() { @@ -18,6 +19,7 @@ print_usage() { echo " -i, --ignore Comma-separated list of sources to ignore" echo " -d, --disable-wakatime Disable wakatime integration" echo " -n, --no-music Disable music integration" + echo " -c, --cache-dir Specify a custom cache directory" exit 0 } @@ -42,6 +44,15 @@ while [[ $# -gt 0 ]]; do -n | --no-music) no_music=true ;; + -c | --cache-dir) + if [[ -n $2 && $2 != -* ]]; then + custom_cache_dir=$2 + shift + else + echo "Error: --cache-dir requires an argument." + exit 1 + fi + ;; *) echo "Unknown option: $1" print_usage @@ -50,15 +61,20 @@ while [[ $# -gt 0 ]]; do shift done +# Use custom cache directory if provided, else use Neovim's cache directory +cache_dir="${custom_cache_dir:-\ + ${NVIM_CACHE_DIR:-\ + ${XDG_CACHE_HOME:-$HOME/.cache}/nvim}}" +mkdir -p "$cache_dir" + # Lock file path -lock_file="/tmp/music_wakatime_update.lock" +lock_file="$cache_dir/music_wakatime_update.lock" # Create a lock file to ensure only one instance of the script runs if [[ -e $lock_file ]]; then echo "Another instance of this script is already running." exit 1 else - # Create the lock file touch "$lock_file" fi @@ -68,10 +84,27 @@ cleanup() { } trap cleanup EXIT +# Check if playerctl is available +if ! command -v playerctl &>/dev/null; then + echo "Warning: playerctl not found. Disabling music integration." + no_music=true +fi + +# Check if wakatime-cli is available +if ! command -v wakatime-cli &>/dev/null; then + echo "Warning: wakatime-cli not found. Disabling wakatime integration." + disable_wakatime=true +fi + # Update the music cache file every second, if not disabled if ! $no_music; then while true; do - playerctl --ignore-player "${ignored_sources}" metadata --format "{{ artist }}${separator}{{ title }}${separator}{{ album }}${separator}{{ status }}${separator}{{ volume }}${separator}{{ loop }}${separator}{{ shuffle }}" >~/.cache/music_cache.txt + playerctl --ignore-player "${ignored_sources}" \ + metadata \ + --format "{{ artist }}${separator}{{ title }}${separator} \ +{{ album }}${separator}{{ status }}${separator}{{ volume }}${separator} \ +{{ loop }}${separator}{{ shuffle }}" \ + >"$cache_dir/music_cache.txt" sleep 1 done & # Run this loop in the background fi @@ -79,7 +112,7 @@ fi # Update the Wakatime cache file every 60 seconds, if not disabled if ! $disable_wakatime; then while true; do - ~/.wakatime/wakatime-cli --today >~/.cache/wakatime_cache.txt 2>/dev/null + wakatime-cli --today >"$cache_dir/wakatime_cache.txt" 2>/dev/null sleep 60 done & # Run this loop in the background fi