feat(config): various config updates

Packaged updates to configuration.
This commit is contained in:
2025-08-23 11:52:26 -04:00
parent 00b23548c3
commit 4545e18a68
20 changed files with 564 additions and 107 deletions
+17
View File
@@ -152,3 +152,20 @@ vim.api.nvim_create_autocmd('FileType', {
vim.opt_local.formatoptions:remove({ 'o' })
end,
})
-- Run async commands with output to split
vim.api.nvim_create_user_command('RunAsync', function(async_opts)
-- Save current buffer first
vim.cmd('w')
-- Construct the full command
local cmd = table.concat(async_opts.fargs, ' ')
-- Open a horizontal split with the terminal running the command
vim.cmd('belowright split | terminal ' .. cmd)
-- Optional: return focus to original window
vim.cmd('wincmd p')
end, {
nargs = '+', -- Require at least one argument
})
+6
View File
@@ -2,6 +2,12 @@
-- │ Early interventions │
-- ╰─────────────────────────────────────────────────────────╯
-- Execute project-specific configuration if it exists
local project_config = vim.fn.getcwd() .. '/.nvim.lua'
if vim.fn.filereadable(project_config) == 1 then
dofile(project_config)
end
-- Address vim.hl bug impacting `:Inspect` command
---@see https://github.com/neovim/neovim/issues/31675
vim.hl = vim.highlight
+22 -13
View File
@@ -22,6 +22,7 @@ vim.opt.rtp:prepend(vim.env.LAZY or lazypath)
local plugin_specs = {
{ -- LazyVim
'LazyVim/LazyVim',
-- dev = true,
priority = 900,
opts = require('data.types').lazyvim.opts,
},
@@ -35,19 +36,9 @@ local plugin_specs = {
{ 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
-- ━━━━━━━━━━━━━━━━━━━━━━━━━ Lazy Configuration ━━━━━━━━━━━━━━━━━━━━━━
-- Initialize Lazy plugin manager
require('lazy').setup({
local lazy_spec = {
spec = plugin_specs,
rocks = {
hererocks = vim.g.use_luarocks,
@@ -100,4 +91,22 @@ require('lazy').setup({
border = 'rounded',
title = ' Plugin Manager ',
},
})
}
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━ Import 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
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Setup Lazy ━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Initialize Lazy plugin manager
require('lazy').setup(lazy_spec)
+1 -1
View File
@@ -8,7 +8,7 @@
vim.opt.guifont = 'Iosevka Rootiest V2:#e-subpixelantialias:h12'
-- refresh rate and translucency
vim.g.neovide_refresh_rate = 120
vim.g.neovide_transparency = 0.85
vim.g.neovide_opacity = 0.85
vim.g.neovide_window_blurred = true
vim.g.neovide_floating_blur_amount_x = 2.0
vim.g.neovide_floating_blur_amount_y = 2.0
+1 -1
View File
@@ -192,7 +192,7 @@ vim.g.statusline = "lualine" ---@type string Options: [status
-- Click git components on statusline to open LazyGit
vim.g.statusline_clickable_git = true ---@type boolean Options: <true|false>
-- Show wakatime stats on statusline
vim.g.stats_wakatime = true ---@type boolean Options: <true|false>
vim.g.stats_wakatime = false ---@type boolean Options: <true|false>
-- Show music stats on statusline
vim.g.stats_music = true ---@type boolean Options: <true|false>
-- Ignored player sources for music stats
+31
View File
@@ -107,6 +107,13 @@ vim.keymap.set(
{ noremap = true, desc = 'Replay last register' }
)
-- Duplicate and comment lines
vim.keymap.set('n', 'ycc', function()
vim.cmd('normal! ' .. vim.v.count1 .. 'yy')
vim.cmd('normal ' .. vim.v.count1 .. 'gcc')
vim.cmd("normal! ']$p")
end, { desc = 'Duplicate and comment lines' })
---------------------------------------------------------------------------
-- ╓─────────────────────────────────────────────────────────╖
-- ║ Scroll half a screen with <C-d> and <C-u> ║
@@ -149,3 +156,27 @@ vim.keymap.set('n', '<C-u>', function()
scroll('up')
end, { silent = true })
---------------------------------------------------------------------------
-- Dump floating window info to file
vim.keymap.set(
'n',
'<leader>fd',
require('data.func').dump_floating_window_info,
{ desc = 'Dump floating window info to file' }
)
---------------------------------------------------------------------------
-- Obsidian Project Configuration:
local function run_obsidian_config()
-- Reduce conceallevel for Obsidian UI
vim.o.conceallevel = 2
vim.cmd('Neominimap off')
end
vim.api.nvim_create_augroup('obsidian_config', { clear = true })
vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead', 'BufEnter' }, {
group = 'obsidian_config',
pattern = vim.fn.expand('~') .. '/vaults/Rootiest Notes/**',
callback = run_obsidian_config,
})
---------------------------------------------------------------------------
+79
View File
@@ -2571,5 +2571,84 @@ function M.swap_buffers()
end
end
--- Get relative window width
---@param fraction number fraction of the main window width
---@return number width the relative width in columns
function M.get_relative_win_width(fraction)
-- Validate param types
vim.validate({
fraction = { fraction, 'number', true },
})
-- Catch out-of-range parameters
if fraction < 0 then
return 0
elseif fraction > 1 then
return 1
end
-- Get window width
local win_width = vim.api.nvim_win_get_width(0)
-- Round relative width to nearest whole number
return math.floor(win_width * fraction + 0.5)
end
--- Testing truncated width
---@param fraction number fraction of the main window width
function M.trunc_test(fraction)
local trunc_width = (M.get_relative_win_width(fraction))
Snacks.picker.files({ formatters = { file = { truncate = trunc_width } } })
end
--- Function to get identifying information for all current floating windows
---@return table info A table of floating windows and their info
function M.get_floating_window_info()
local info = {}
for _, win in ipairs(vim.api.nvim_list_wins()) do
local config = vim.api.nvim_win_get_config(win)
if config.relative ~= '' then
local buf = vim.api.nvim_win_get_buf(win)
table.insert(info, {
win_id = win,
bufname = vim.api.nvim_buf_get_name(buf),
filetype = vim.api.nvim_get_option_value('filetype', { buf = buf }),
width = vim.api.nvim_win_get_width(win),
height = vim.api.nvim_win_get_height(win),
})
end
end
return info
end
--- Function to get identifying information for all current
--- floating windows and dump that info to a temporary file
---@param path string? The path to the file (optional)
function M.dump_floating_window_info(path)
local float_info = M.get_floating_window_info()
local output = {}
for _, win in ipairs(float_info) do
table.insert(
output,
string.format(
'Win ID: %d\n Buffer: %s\n Filetype: %s\n Width: %d\n Height: %d\n---',
win.win_id,
win.bufname ~= '' and win.bufname or '[No Name]',
win.filetype,
win.width,
win.height
)
)
end
if not path then
path = vim.fn.stdpath('cache') .. '/float_dump.txt'
end
local f = assert(io.open(path, 'w'))
f:write(table.concat(output, '\n'))
f:close()
print('Floating window info written to ' .. path)
end
-- Export the module
return M
+6
View File
@@ -1243,6 +1243,12 @@ M.misc = {
desc = 'Yank buffer',
mode = 'n',
},
{ -- Pick keymaps
lhs = '<leader>fk',
rhs = '<cmd>Pick keymaps<cr>',
desc = 'Pick keymaps',
mode = 'n',
},
}
M.nekifoch = {
+28 -3
View File
@@ -1750,6 +1750,13 @@ M.catppuccin = {
light = 'latte',
dark = 'mocha',
},
-- color_overrides = { -- OLED black background
-- mocha = {
-- base = '#000000',
-- mantle = '#000000',
-- crust = '#000000',
-- },
-- },
transparent_background = false,
integrations = {
native_lsp = {
@@ -1780,6 +1787,7 @@ M.catppuccin = {
},
grug_far = true,
mason = true,
markview = true,
mini = {
enabled = true,
indentscope_color = 'mauve',
@@ -1857,9 +1865,27 @@ M.noice = {
M.grug_far = {
opts = {
showCompactInputs = true,
showInputsTopPadding = false,
showInputsBottomPadding = false,
helpLine = {
enabled = false,
},
enabledEngines = { 'ripgrep', 'astgrep' },
engines = {
astgrep = {
path = 'ast-grep',
placeholders = {
enabled = false,
},
},
ripgrep = {
placeholders = {
enabled = false,
},
},
['astgrep-rules'] = {
path = 'ast-grep',
},
},
engine = 'ripgrep',
@@ -1869,15 +1895,14 @@ M.grug_far = {
--- Smear Cursor
M.smearcursor = function()
local bg = require('data.func').get_bg_color('Normal') or '#1d1d2d'
local fg = require('data.func').get_fg_color('Normal') or '#d3cdc3'
local fg = require('data.func').get_fg_color('Normal') or '#f7e0dc'
return {
-- Cursor color. Defaults to Normal gui foreground color
cursor_color = fg,
-- cursor_color = 'none',
-- Background color. Defaults to Normal gui background color
--normal_bg = bg,
normal_bg = bg,
-- Smear cursor when switching buffers
smear_between_buffers = true,
+4
View File
@@ -14,6 +14,10 @@ return {
import = 'lazyvim.plugins.extras.ai.copilot',
cond = require('data.cond').copilot,
},
{ -- Copilot Chat
import = 'lazyvim.plugins.extras.ai.copilot-chat',
cond = require('data.cond').copilot,
},
{ -- Tabnine
import = 'lazyvim.plugins.extras.ai.tabnine',
cond = require('data.cond').tabnine,
+61 -3
View File
@@ -30,11 +30,16 @@ if vim.g.useblinkcmp then
vim.g.lazyvim_blink_main = true
end
return {
{
return { -- Blink.cmp
{ -- Overide the lazy-load event to include CmdlineEnter
'saghen/blink.cmp',
event = { 'InsertEnter', 'CmdlineEnter' },
},
{ -- Load blink.cmp configuration
'saghen/blink.cmp',
dependencies = {
'mikavilpas/blink-ripgrep.nvim',
'archie-judd/blink-cmp-words',
},
opts = {
enabled = function()
@@ -65,6 +70,15 @@ if vim.g.useblinkcmp then
snippets = {
preset = 'luasnip',
},
fuzzy = {
implementation = 'prefer_rust',
use_frecency = true,
sorts = {
'exact',
'score',
'sort_text',
},
},
keymap = {
preset = 'enter',
['<C-y>'] = { 'select_and_accept' },
@@ -113,7 +127,11 @@ if vim.g.useblinkcmp then
module = 'blink-ripgrep',
name = 'Ripgrep',
opts = {
search_casing = '--smart-case',
backend = {
ripgrep = {
search_casing = '--smart-case',
},
},
},
transform_items = function(_, items)
for _, item in ipairs(items) do
@@ -125,13 +143,53 @@ if vim.g.useblinkcmp then
return items
end,
},
-- Use the thesaurus source
thesaurus = {
name = 'blink-cmp-words',
module = 'blink-cmp-words.thesaurus',
-- All available options
opts = {
-- A score offset applied to returned items.
-- By default the highest score is 0 (item 1 has a score of -1, item 2 of -2 etc..).
score_offset = 0,
-- Default pointers define the lexical relations listed under each definition,
-- see Pointer Symbols below.
-- Default is as below ("antonyms", "similar to" and "also see").
pointer_symbols = { '!', '&', '^' },
},
},
-- Use the dictionary source
dictionary = {
name = 'blink-cmp-words',
module = 'blink-cmp-words.dictionary',
-- All available options
opts = {
-- The number of characters required to trigger completion.
-- Set this higher if completion is slow, 3 is default.
dictionary_search_threshold = 3,
-- See above
score_offset = 0,
-- See above
pointer_symbols = { '!', '&', '^' },
},
},
},
default = {
'lsp',
'path',
'lazydev',
'snippets',
'buffer',
'ripgrep',
'thesaurus',
},
-- Setup completion by filetype
per_filetype = {
text = { 'dictionary' },
markdown = { 'thesaurus' },
},
},
},
+15
View File
@@ -65,4 +65,19 @@ return {
cond = require('data.cond').tiny_inline_diagnostic,
config = require('data.types').tiny_inline_diagnostic.config,
},
{
'neovim/nvim-lspconfig',
init = function() end,
opts = {
servers = {
yamlls = {
settings = {
yaml = {
customTags = vim.g.custom_yaml_tags,
},
},
},
},
},
},
}
+6
View File
@@ -9,6 +9,12 @@ return {
'ehpi/vim-illuminate',
opts = require('data.types').illuminate.opts,
},
{ -- Nvim-notify
'rcarriga/nvim-notify',
opts = {
fps = 144, -- your monitor refresh rate
},
},
{ -- Grug-Far
'MagicDuck/grug-far.nvim',
opts = require('data.types').grug_far.opts,
+4
View File
@@ -44,4 +44,8 @@ return {
vim.fn['mkdp#util#install']()
end,
},
{ -- CookLang
'luizribeiro/vim-cooklang',
lazy = false,
},
}
+25 -23
View File
@@ -2,27 +2,29 @@
-- │ Nvim-Updater │
-- ╰─────────────────────────────────────────────────────────╯
return { -- Neovim Updater
'rootiest/nvim-updater.nvim',
version = '*', -- Pin to GitHub releases
lazy = false,
opts = {
build_type = 'RelWithDebInfo',
branch = 'master',
verbose = false,
check_for_updates = true,
update_interval = (60 * 60) * 6, -- 6 hours
notify_updates = false,
default_keymaps = false,
},
keys = function()
-- Load Neovim Updater Debugging Functions
require('config.nvim_updater') -- Debugging Functions
-- return { -- Neovim Updater
-- 'rootiest/nvim-updater.nvim',
-- version = '*', -- Pin to GitHub releases
-- lazy = false,
-- opts = {
-- build_type = 'Release',
-- branch = 'master',
-- verbose = false,
-- check_for_updates = true,
-- update_interval = (60 * 60) * 6, -- 6 hours
-- notify_updates = false,
-- default_keymaps = false,
-- },
-- keys = function()
-- -- Load Neovim Updater Debugging Functions
-- require('config.nvim_updater') -- Debugging Functions
--
-- -- Add Neovim Updater menu
-- require('data.func').add_keymap(require('data.keys').group.nvimup)
-- -- Add Neovim Updater keys
-- return require('data.keys').nvimup
-- end,
-- dev = vim.g.rootiest_dev or false,
-- }
-- Add Neovim Updater menu
require('data.func').add_keymap(require('data.keys').group.nvimup)
-- Add Neovim Updater keys
return require('data.keys').nvimup
end,
dev = vim.g.rootiest_dev or false,
}
return {}
+53 -28
View File
@@ -1,34 +1,59 @@
return {
'epwalsh/obsidian.nvim',
version = '*', -- recommended, use latest release instead of latest commit
lazy = true,
event = {
'BufReadPre ' .. vim.fn.expand('~' .. '/vaults/rootiest/*.md'),
'BufNewFile ' .. vim.fn.expand('~' .. '/vaults/rootiest/*.md'),
{
'obsidian-nvim/obsidian.nvim',
version = '*', -- recommended, use latest release instead of latest commit
lazy = true,
event = {
'BufReadPre ' .. vim.fn.expand('~' .. '/vaults/Rootiest Notes/*.md'),
'BufNewFile ' .. vim.fn.expand('~' .. '/vaults/Rootiest Notes/*.md'),
},
cmd = 'Obsidian',
dependencies = {
-- Required.
'nvim-lua/plenary.nvim',
},
opts = {
completion = {
nvim_cmp = false,
blink = true,
min_chars = 2,
},
picker = {
name = 'snacks.pick',
},
workspaces = {
{
name = 'Rootiest Notes',
path = '~/vaults/Rootiest Notes',
},
},
templates = {
folder = 'templates',
date_format = '%Y-%m-%d-%a',
time_format = '%H:%M',
substitutions = {
yesterday = function()
return os.date('%Y-%m-%d', os.time() - 86400)
end,
},
},
-- ui = {
-- enable = false,
-- },
},
},
dependencies = {
-- Required.
'nvim-lua/plenary.nvim',
},
opts = {
workspaces = {
{
name = 'rootiest',
path = '~/vaults/rootiest',
{
'arakkkkk/kanban.nvim',
ft = 'markdown',
opts = {
markdown = {
description_folder = './tasks/', -- Path to save the file corresponding to the task.
list_head = '## ',
},
},
templates = {
folder = 'templates',
date_format = '%Y-%m-%d-%a',
time_format = '%H:%M',
substitutions = {
yesterday = function()
return os.date('%Y-%m-%d', os.time() - 86400)
end,
},
},
ui = {
enable = false,
},
},
{
'marcocofano/excalidraw.nvim',
lazy = false,
},
}
+33 -1
View File
@@ -106,9 +106,16 @@ local profiler = {
},
}
---@class PickerList
---@field row2idx fun(self: PickerList, row: integer): integer
---@field _move fun(self: PickerList, index: integer, a: boolean, b: boolean): nil
---@class SnacksPicker
---@field list PickerList
--- flash_on_picker
---Use the flash.nvim plugin in Snacks picker
---@param picker table: The picker instance to interact with.
---@param picker SnacksPicker The picker instance to interact with.
local flash_on_picker = function(picker)
require('flash').jump({
pattern = '^',
@@ -162,11 +169,36 @@ local picker = {
jump = { close = true },
auto_close = true,
layout = { preset = 'sidebar' },
-- ignored = true, -- Show .ignore/.gitignore files
-- hidden = true, -- Show hidden files
},
},
layouts = {
-- default = vscode_layout,
vscode = vscode_layout,
ivy = {
layout = {
box = 'vertical',
backdrop = false,
row = -1,
width = 0.8,
height = 0.4,
border = 'top',
title = ' {title} {live} {flags}',
title_pos = 'left',
{ win = 'input', height = 1, border = 'bottom' },
{
box = 'horizontal',
{ win = 'list', width = 0.4, border = 'none' },
{
win = 'preview',
title = '{preview}',
width = 0.6,
border = 'left',
},
},
},
},
left = { preset = 'sidebar', layout = { position = 'left' } },
right = { preset = 'sidebar', layout = { position = 'right' } },
top = { preset = 'ivy', layout = { position = 'top' } },
+34 -34
View File
@@ -285,40 +285,40 @@ return { -- Lualine
end,
padding = { left = 0, right = 1 },
},
{ -- Music
function()
return music_stats.get_icon_with_text()
end,
cond = function()
return require('data.func').is_window_wide_enough(100)
end,
padding = { left = 0, right = 1 },
},
{ -- Neovim Updater Status
function()
return require('nvim_updater').get_statusline().icon_text
end,
color = function()
local fg = require('data.func').get_fg_color(
require('nvim_updater').get_statusline().color
)
local bg = require('data.func').get_bg_color('lualine_x')
return { fg = fg, bg = bg }
end,
on_click = function()
require('nvim_updater').show_new_commits({
isupdate = true,
short = false,
})
end,
padding = { left = 1, right = 1 },
cond = function()
if not pcall(require, 'nvim_updater') then
return false
end
return not string.find(vim.bo.filetype, 'neovim_updater_term')
end,
},
-- { -- Music
-- function()
-- return music_stats.get_icon_with_text()
-- end,
-- cond = function()
-- return require('data.func').is_window_wide_enough(100)
-- end,
-- padding = { left = 0, right = 1 },
-- },
-- { -- Neovim Updater Status
-- function()
-- return require('nvim_updater').get_statusline().icon_text
-- end,
-- color = function()
-- local fg = require('data.func').get_fg_color(
-- require('nvim_updater').get_statusline().color
-- )
-- local bg = require('data.func').get_bg_color('lualine_x')
-- return { fg = fg, bg = bg }
-- end,
-- on_click = function()
-- require('nvim_updater').show_new_commits({
-- isupdate = true,
-- short = false,
-- })
-- end,
-- padding = { left = 1, right = 1 },
-- cond = function()
-- if not pcall(require, 'nvim_updater') then
-- return false
-- end
-- return not string.find(vim.bo.filetype, 'neovim_updater_term')
-- end,
-- },
},
lualine_y = {
{ -- NeoCodeium Status
+33
View File
@@ -0,0 +1,33 @@
-- ╭─────────────────────────────────────────────────────────╮
-- │ LSP Operations │
-- ╰─────────────────────────────────────────────────────────╯
local M = {}
--- Function to get attached LSP server names
---@return string|nil list A list of attached lsp servers
function M.get_attached_lsp_clients()
local clients =
vim.lsp.get_clients({ bufnr = vim.api.nvim_get_current_buf() })
if #clients == 0 then
return nil
else
local names = {}
for _, client in ipairs(clients) do
table.insert(names, client.name)
end
return 'LSP~ ' .. table.concat(names, ', ')
end
end
--- Function to print the list of attached LSP servers
function M.print_attached_lsp_clients()
local clients = M.get_attached_lsp_clients()
if clients == nil then
print('No LSP clients attached')
else
print(clients)
end
end
return M
+105
View File
@@ -0,0 +1,105 @@
local M = {}
--- Recursively find the width for a window by name
---@param layout table
---@param target_win string
---@return number|nil
local function find_win_width(layout, target_win)
for _, item in ipairs(layout) do
if type(item) == 'table' then
if item.win == target_win and item.width then
return item.width
elseif vim.islist(item) or item.box then
local result = find_win_width(item, target_win)
if result then
return result
end
end
end
end
return nil
end
--- Get relative window width
---@param fraction number fraction of the main window width
---@param layout_name string the snacks layout to use
---@param target_win string the window name to extract width for
---@return number width the relative width in columns
function M.get_relative_win_width(fraction, layout_name, target_win)
vim.validate({
fraction = { fraction, 'number', true },
layout_name = { layout_name, 'string', true },
target_win = { target_win, 'string', true },
})
if fraction < 0 then
return 0
elseif fraction > 1 then
return 1
end
local win_width = vim.api.nvim_win_get_width(0)
local top_level_fraction = 1
local nested_win_fraction = 1
local ok, snacks = pcall(require, 'snacks')
if ok then
local layouts = snacks.config
and snacks.config.picker
and snacks.config.picker.layouts
local chosen_layout = layouts
and layouts[layout_name]
and layouts[layout_name].layout
if chosen_layout then
-- Check for layout-wide width
if type(chosen_layout) == 'table' and chosen_layout.width then
top_level_fraction = chosen_layout.width
end
-- Check inside nested win="target_win"
nested_win_fraction = find_win_width(chosen_layout, target_win) or 1
end
end
local combined_fraction = fraction * top_level_fraction * nested_win_fraction
return math.floor(win_width * combined_fraction + 0.5)
end
--- Truncate the picker file text
---@param fraction number|nil
---@param layout_name string|nil
---@param target_win string|nil
---@param picker_type string|nil
function M.trunc_text(fraction, layout_name, target_win, picker_type)
fraction = fraction or 1.0
layout_name = layout_name or 'default'
target_win = target_win or 'list'
picker_type = picker_type or 'files'
local trunc_width =
M.get_relative_win_width(fraction, layout_name, target_win)
local ok, snacks = pcall(require, 'snacks')
if not ok then
vim.notify('snacks.nvim not loaded', vim.log.levels.ERROR)
return
end
local picker = snacks.picker and snacks.picker[picker_type]
if type(picker) ~= 'function' then
vim.notify(
'Invalid Snacks.picker type: ' .. tostring(picker_type),
vim.log.levels.ERROR
)
return
end
picker({
layout = { preset = layout_name },
formatters = { file = { truncate = trunc_width } },
})
end
return M