Compare commits

35 Commits

Author SHA1 Message Date
597de90d41 add lsp document symbols telescope keybind 2025-10-16 21:38:01 -04:00
47b0e795cd fix highlighting 2025-10-16 21:37:04 -04:00
a96cb4bef7 ooh a fancy border that actually looks good 2025-10-16 21:36:41 -04:00
06a9c9e45d comment a problem for future me 2025-10-16 21:36:06 -04:00
55f11ab1ba add basedpyright lsp configuration 2025-10-16 21:34:49 -04:00
43b4369041 A while ago I decided to try out tabs instead of spaces. Bad idea...
It just doesn't make sense, why would you choose to use tabs when you
really get nothing out of them. I've heard arguments that everyone get's
what they want in terms of formatting, but that doesn't really feel
accurate because now I've got code looking messy depending on where it
is you're looking at it on which really sucks. I'm going back to two
space indentation and if a project really wants to use something else
they can setup a formatter and/or .editorconfig file. If you read this
rant, respectfully, what are you doing with your time.
2025-09-24 01:16:40 -04:00
baec11b559 remove formatting 2025-09-22 13:12:02 -04:00
72d99537bf more stuff 2025-09-16 00:34:25 -04:00
9c7c46855c protect calls to lsp/wtf funcs as most of them are only on dev builds atm 2025-09-02 21:58:57 -04:00
86d7f17341 not sure why I forgot to update this comment the colors were removed...
a while ago
2025-09-02 11:06:13 -04:00
869859a2ce do I look like I want to write a commit message for my nvim config? 2025-09-02 10:58:12 -04:00
33b35f16c1 inline a thingy for funsies 2025-08-28 19:14:11 -04:00
a7ac4e76ea turns out gitsigns is actually very useful 2025-08-24 02:36:51 -04:00
b20f5d07a6 uhhhhh 2025-08-23 22:48:12 -04:00
62945314e2 it got merged \o/ 2025-08-10 13:11:22 -04:00
d320577772 I'm not gonna bother 2025-08-10 13:10:05 -04:00
7c96b43098 kitchen sink...
just gonna put the changes that I can remember making here:
 - replace blink with native completion (omnifunc)
 - remove some unneeded plugins
 - add a misc function for making sure complex bindings don't cause
   flickering
 - remove some stale snippets
 - remove folding (I don't find myself folding that often)
2025-08-02 11:25:38 -04:00
27f55ed03c this is a bit unstable but whatever 2025-07-27 14:21:49 -04:00
afdefb7dc3 fix mellow theming 2025-07-14 19:42:40 -04:00
64afe9c9ee revert treesitter back to master branch 2025-07-14 19:42:16 -04:00
cace587a09 more more more 2025-07-13 18:58:27 -04:00
101bc55f15 quick fix goes to a more sane place now 2025-07-11 14:08:53 -04:00
cd26cbb825 small changes...
if you want more look at the changes, there's not that many
2025-06-21 22:49:37 -04:00
7ef68dea92 gotta use new remote 2025-06-13 19:36:07 -04:00
9ea9d9f516 more!!! add python support and formatters and null ls to manage all...
that automatically also change my stylua.toml to ignore everything
cause I don't like the way it formats stuff
2025-06-11 03:21:25 -04:00
e830931ff4 wozers 2025-05-31 03:32:58 -04:00
ef678f31fd turns out neovim supports lsp line diagnostics natively 2025-05-19 02:22:49 -04:00
f9311db805 try and make everything confined to 80chars 2025-05-18 22:33:36 -04:00
d0155fcc7c make telescope work better in projects 2025-05-18 22:22:39 -04:00
df666dec0f fix dap
add showkeys thingy
remove nyooom
2025-05-18 14:28:57 -04:00
450750835a need I say what type of commit this is?
*kitchen sink*
2025-05-18 13:03:31 -05:00
77130d61af add a lil guy who provides git information on the current buffer 2025-05-09 17:58:06 -05:00
922dfb8c7e opts.lua 2025-05-09 00:17:42 -05:00
f3bd08968a formatting 2025-05-09 00:16:55 -05:00
a6007ff694 this hasn't worked for a long time, I might choose to re-impl if I have time 2025-05-09 00:15:41 -05:00
62 changed files with 1545 additions and 1610 deletions

View File

@@ -1,3 +1,2 @@
indent_type = "Spaces" # Use spaces instead of tabs
indent_width = 2 # Number of spaces per indent level
quote_style = "ForceDouble" # Always use double quotes for strings
# I don't like stylua formatting in my config
ignore = [ "./" ]

View File

@@ -1,6 +1,5 @@
local misc = require('core.misc')
local map_local = misc.map_local
local map_local, lz = core.misc.map_local, core.misc.lz
-- sort #includes <> (very jank)
-- TODO: rewrite in a semi-sane way
map_local("n", "cri", "mz/^#include.*<.*>$<CR>ggVGN:sort<CR>`z<cmd>delm z<CR>:nohlsearch<Bar>:echo<CR>")
map_local("n", "cri", lz "mz/^#include.*<.*>$<CR>ggVGN:sort<CR>`z<cmd>delm z<CR>:nohlsearch<Bar>:echo<CR>")

View File

@@ -0,0 +1 @@
core.misc.map_local("n", "q", "<cmd>q<CR>")

View File

@@ -1,18 +1,22 @@
local misc = require("core.misc")
local map, auto = misc.map, misc.auto
-- TODO: find out why this doesn't work when java isn't the first filetype I open
local map, auto = core.misc.map, core.misc.auto
local jdtls = require("jdtls")
local jdtls_install = vim.fs.joinpath(vim.fn.stdpath('data'),
"/mason/packages/jdtls")
local java_dap_install = vim.fs.joinpath(vim.fn.stdpath('data'),
"/mason/packages/java-debug-adapter")
local ok, jdtls = pcall(require, "jdtls")
if not ok then
vim.notify("jdtls not loaded, can't setup jdtls lsp or dap")
return
end
local jdtls_install = core.mason.get_pkg_path("jdtls")
local java_dap_install = core.mason.get_pkg_path("java-debug-adapter")
-- make sure to check if things with 💀 need updating
local config = {
cmd = {
"/usr/lib/jvm/openjdk21/bin/java", -- 💀
"-jar", vim.fn.glob(jdtls_install.."/plugins/org.eclipse.equinox.launcher_*.jar"), -- 💀
"-configuration", jdtls_install.."/config_linux",
"-jar",
vim.fn.glob(vim.fs.joinpath(jdtls_install, "plugins/org.eclipse.equinox.launcher_*.jar")),
"-configuration", jdtls_install.."config_linux",
"-data", vim.fn.stdpath("cache").."/nvim-jdtls",
"--add-modules=ALL-SYSTEM",
@@ -23,7 +27,7 @@ local config = {
"-Dlog.level=ALL",
"-Dlog.protocol=true",
"-Dosgi.bundles.defaultStartLevel=4",
"-Xmx1G",
"-Xmx1G"
},
root_dir = vim.fs.dirname(vim.fs.find({
@@ -48,6 +52,7 @@ local config = {
map("x", "crc", function() jdtls.extract_constant(true) end, opts)
map("x", "crm", function() jdtls.extract_method(true) end, opts)
-- do some refreshes often because I don't trust jdtls
pcall(vim.lsp.codelens.refresh)
auto("BufWritePost", {
buffer = bufnr,
@@ -58,31 +63,36 @@ local config = {
})
-- setup nvim-dap
require("dap").adapters.java = nil -- remove any old java adapters
local ok, dap = pcall(require, "dap")
if not ok then
vim.notify("dap not loaded can't setup dap for jdtls")
return
end
dap.adapters.java = nil -- remove any old java adapters
jdtls.setup_dap({ hotcodereplace = "auto" })
require("jdtls.dap").setup_dap_main_class_configs()
end,
-- don"t print out status messages
handlers = {
["language/status"] = function() end
},
init_options = {
bundles = {
vim.fs.joinpath(java_dap_install,
vim.fn.glob("/extension/server/com.microsoft.java.debug.plugin-*.jar",
vim.fn.glob("extension/server/com.microsoft.java.debug.plugin-*.jar",
true)
)
}
},
-- don't print out status messages
handlers = {
["language/status"] = function() end
}
}
-- generate the path to the java file(s)
---@type string|nil
local cache_path = vim.fs.joinpath(vim.fn.stdpath("cache"), "/JavaVersion.class")
---@type string|nil
local src_path = vim.fs.joinpath(vim.fn.stdpath("config"), "/extras/JavaVersion.java")
---@type string?
local cache_path = vim.fs.joinpath(vim.fn.stdpath("cache"),
"/JavaVersion.class")
---@type string?
local src_path = vim.fs.joinpath(vim.fn.stdpath("config"),
"/extras/JavaVersion.java")
-- if either path is invalid
if not cache_path or not src_path then
@@ -92,19 +102,18 @@ end
--- build a cache of the JavaVersion code
local function build_cache()
-- check if we have javac
vim.system({ "javac" }, {}, function(out)
if out.code == 127 then
cache_path = nil
return
end
if vim.fn.executable("javac") ~= 1 then
cache_path = nil
return
end
-- compile our code
vim.system({ "javac", src_path, "-d", vim.fn.stdpath("cache") }, {}, function(out)
-- compile our code
vim.system({ "javac", src_path, "-d", vim.fn.stdpath("cache"), }, {},
function(out)
if out.code ~= 0 then
cache_path = nil
end
end)
end)
end
-- check if we have a compiled version of JavaVersion
@@ -130,27 +139,23 @@ local function version_check()
if out.code ~= 0 then
vim.notify(string.format(
"java version check failed: exit code %s", out.code),
vim.log.levels.ERROR, { title = misc.appid })
vim.log.levels.ERROR)
vim.notify(string.format(
"%s", vim.inspect(out.stdout)),
vim.log.levels.ERROR, { title = misc.appid })
"%s", vim.inspect(out.stdout)), vim.log.levels.ERROR)
return false
elseif not v then
vim.notify("no java version info found", vim.log.levels.ERROR,
{ title = misc.appid })
vim.notify("no java version info found", vim.log.levels.ERROR)
return false
elseif v.major < 21 then
vim.notify(string.format(
"java version %s < 21.0.0 Cannot run jdtls, bailing out",
v[1] .. "." .. v[2] .. "." .. v[3]),
vim.log.levels.ERROR, { title = misc.appid })
v[1].."."..v[2].."."..v[3]), vim.log.levels.ERROR)
return false
end
return true
end
-- start the jdtls with dap!
if not version_check() then
return

View File

@@ -1,9 +1,8 @@
local misc = require("core.misc")
local map_local = misc.map_local
local map_local = core.misc.map_local
map_local("n", "h", "-", { noremap = false, remap = true }) -- Go up a directory
map_local("n", "l", "<CR>", { noremap = false, remap = true }) -- Go down a directory / open a file
map_local("n", ".", "gh", { noremap = false, remap = true }) -- Toggle hidden files
map_local("n", "g.", "gh", { noremap = false, remap = true }) -- Toggle hidden files
map_local("n", "P", "<C-w>z", { noremap = false, remap = true }) -- Close preview window
-- Close netrw only if it isn't the last window
@@ -16,5 +15,5 @@ end)
-- change neovim root
map_local("n", "rt", function()
vim.api.nvim_set_current_dir(vim.b.netrw_curdir)
vim.notify("root dir updated: "..vim.b.netrw_curdir, vim.log.levels.LOW, { title = misc.appid })
vim.notify("root dir updated: "..vim.b.netrw_curdir)
end)

View File

@@ -1,9 +1,17 @@
local map = require("core.misc").map
return {
on_attach = function(_, bufnr)
-- add some basedpyright specific mappings
local opts = { buffer = bufnr }
map("n", "cri", "<cmd>PyrightOrganizeImports<CR>", opts)
end,
settings = {
python = {
pythonPath = "python"
},
basedpyright = {
reportAny = false,
analysis = {
autoSearchPaths = true,
diagnosticMode = "workspace",
inlayHints = {
callArgumentNames = true
}
}
}
}
}

View File

@@ -1,12 +1,4 @@
local map = require("core.misc").map
return {
on_attach = function(_, bufnr)
-- add some clangd specific mappings
local opts = { buffer = bufnr }
map("n", "<leader>o", "<cmd>ClangdSwitchSourceHeader<CR>", opts)
end,
cmd = {
"clangd",
"--background-index",
@@ -21,7 +13,7 @@ return {
usePlaceholders = true,
clangdFileStatus = true,
fallback_flags = {
"-xc" -- makes clangd think we"re using c instead of c++
-- "-xc" -- makes clangd think we"re using c instead of c++
}
}
}

View File

@@ -11,14 +11,14 @@ return {
enable = false
},
workspace = {
checkThirdParty = true,
checkThirdParty = "ApplyInMemory",
library = {
vim.env.VIMRUNTIME
vim.env.VIMRUNTIME,
"${3rd}/luv/library"
}
}
}
},
root_markers = { ".luarc.json", ".luarc.jsonc", ".luacheckrc", ".stylua.toml",
"stylua.toml", "selene.toml", "selene.yml", "README.md" }
}

View File

@@ -1 +1,5 @@
vim.cmd("colorscheme mellow")
if vim.fn.has("termguicolors") and not os.getenv("TERM") ~= "linux" then
vim.cmd("colo mellow")
else
vim.cmd("colo default")
end

View File

@@ -1,44 +1,33 @@
-- TODO: after switching to dep with lazy loading check out vim-startuptime
-- again
-- load core utilities
_G.core = require("core")
-- enable performance stuff
if vim.fn.has("nvim-0.9") == true then
vim.loader.enable()
end
vim.loader.enable()
-- load user config
require("conf")
-- setup lsp stuff
core.lsp.setup()
-- bootstrap plugin manager
local path = vim.fn.stdpath("data").."/site/pack/deps/opt/dep"
if vim.fn.empty(vim.fn.glob(path)) > 0 then
vim.fn.system({ "git", "clone", "--depth=1", "https://git.squi.bid/dep", path })
if not vim.uv.fs_stat(path) then
vim.fn.system({ "git", "clone", "--depth=1", "https://git.squi.bid/squibid/dep",
"--branch=lazy", path })
end
vim.opt.rtp:prepend(path)
vim.cmd("packadd dep")
-- load miscellaneous utilities
local misc = require("core.misc")
-- load user config
misc.include("conf.opts") -- setup options
misc.include("conf.binds") -- setup keybinds
misc.include("conf.autos") -- setup autos
_G.dep_short = require("dep.lazy.loader.short")
-- load plugins
require("dep") {
{ "squibid/dep",
url = "https://git.squi.bid/dep",
branch = "dev"
url = "https://git.squi.bid/squibid/dep",
branch = "lazy"
},
load = function()
-- aquire all plugin specs
local plugs = {}
for _, file in ipairs(vim.api.nvim_get_runtime_file("lua/conf/plugins/*.lua", true)) do
local ret = misc.include("conf.plugins."..file:gsub("^.*/", ""):gsub("%.lua$", ""))
if type(ret) ~= "boolean" then
plugs[#plugs + 1] = ret
end
end
return plugs
end
modules = {
prefix = "conf.plugins"
}
}

View File

@@ -1,7 +1,6 @@
local misc = require("core.misc")
local auto, augroup = misc.auto, misc.augroup
local auto, augroup = core.misc.auto, core.misc.augroup
-- auto commands which interact with bufferes without modifying them
-- auto commands which interact with buffers without modifying them
local bufcheck = augroup("bufcheck")
-- auto commands which modify things on the filesystem
local fsmod = augroup("fsmod")
@@ -12,14 +11,6 @@ auto("FocusGained", {
command = "checktime"
})
auto("TextYankPost", {
group = bufcheck,
desc = "Highlight on yank.",
callback = function()
vim.highlight.on_yank { timeout = 250 }
end
})
auto("BufRead", {
group = bufcheck,
desc = "Return to the last place the buffer was closed in.",
@@ -39,12 +30,12 @@ auto("BufWritePre", {
end
})
auto("BufWritePre", {
group = fsmod,
desc = "Basically mkdir -p.",
callback = function(ctx)
if ctx.match:match("^%w%w+://") then return end
local dir = vim.fn.fnamemodify(ctx.file, ":p:h")
vim.fn.mkdir(dir, "p")
end
})
-- FIXME: disable for now until I can do more work and make it work better
-- auto({ "BufEnter", "CursorMoved", "CursorMovedI" }, {
-- group = bufcheck,
-- callback = function()
-- core.color.todo_comments()
-- end
-- })
core.color.setup_termbg_sync()

View File

@@ -1,62 +1,76 @@
local misc = require("core.misc")
local map = misc.map
local map, lz = core.misc.map, core.misc.lz
--- feed keys as userinput
---@param keys string keys
local function feedkeys(keys)
vim.api.nvim_feedkeys(
vim.api.nvim_replace_termcodes(keys, true, false, true),
"n", true)
end
-- vim binds
vim.g.mapleader = " " -- set leader key
map("x", "<leader>p", [["_dP]], { desc = "Greatest remap of all time." })
map("n", "<esc>", ":nohlsearch<Bar>:echo<CR>", { desc = "Clear search." })
-- move selected text up/down
map("v", "<S-k>", ":m '<-2<CR>gv=gv", { desc = "Move selected text up." })
map("v", "<S-j>", ":m '>+1<CR>gv=gv", { desc = "Move selected text down." })
map("n", "<esc>", "<cmd>noh<Bar>:ec<CR>", { desc = "Clear search." })
map("n", "<leader>a", lz "<cmd>e #<CR>zz", { desc = "swap to alt file" })
-- the cursor STAYS IN THE MIDDLE
map("n", "<S-j>", "mzJ`z<cmd>delm z<CR>") -- when combining lines
map("n", "n", "nzzzv") -- when searching
map("n", "N", "Nzzzv")
map("n", "<C-d>", "<C-d>zzzv") -- half page jumping
map("n", "<C-u>", "<C-u>zzzv")
map("n", "<S-j>", lz "mzJ`z<cmd>delm z<CR>") -- when combining lines
map("n", "n", lz "nzzzv") -- when searching
map("n", "N", lz "Nzzzv")
map("n", "<C-d>", lz "<C-d>zz") -- half page jumping
map("n", "<C-u>", lz "<C-u>zz")
map("n", "<C-o>", lz "<C-o>zz") -- jump history
map("n", "<C-i>", lz "<C-i>zz")
map({ "n", "i" }, "<C-c>", "<Esc>")
map("n", "<leader>x", function() -- execute order 111
local fn = vim.fn.expand("%:p")
if vim.fn.getftype(fn) == "file" then
local perm = vim.fn.getfperm(fn)
if string.match(perm, "x", 3) then
vim.notify("Removed executable flags", vim.log.levels.INFO, { title = misc.appid })
vim.fn.setfperm(fn, string.sub(fn, 1, 2).."-"..string.sub(fn, 4, 5).."-"..string.sub(fn, 7, 8).."-")
else
vim.notify("Add executable flags", vim.log.levels.INFO, { title = misc.appid })
vim.fn.setfperm(fn, string.sub(fn, 1, 2).."x"..string.sub(fn, 4, 5).."x"..string.sub(fn, 7, 8).."x")
end
else
vim.notify("File doesn't exist", vim.log.levels.INFO, { title = misc.appid })
end
end, { desc = "toggle executable flag of the file" })
-- good spell suggestion ui
-- (stolen from https://github.com/neovim/neovim/pull/25833)
vim.keymap.set("n", "z=", function()
local spell_on_choice = vim.schedule_wrap(function(_, idx)
if type(idx) == "number" then
vim.cmd("normal! "..idx.."z=")
end
end)
if vim.v.count > 0 then
spell_on_choice(nil, vim.v.count)
return
end
local cword = vim.fn.expand("<cword>")
local prompt = "Change "..vim.inspect(cword).." to:"
vim.ui.select(vim.fn.spellsuggest(cword, vim.o.lines), { prompt = prompt }, spell_on_choice)
end, { desc = "Shows spelling suggestions" })
-- trigger completion menu
-- (stolen from https://gist.github.com/MariaSolOs/2e44a86f569323c478e5a078d0cf98cc)
map("i", "<C-n>", function()
-- if the completion menu is already visible just go to the next item
if vim.fn.pumvisible() ~= 0 then
feedkeys("<C-n>")
else
if #vim.lsp.get_clients({ bufnr = 0 }) > 0 then
vim.lsp.completion.get()
else
if vim.bo.omnifunc == "" then
feedkeys("<C-x><C-n>")
else
feedkeys("<C-x><C-o>")
end
end
end
end, { desc = "Trigger/select next completion" })
map("i", "<CR>", function()
if vim.fn.pumvisible() ~= 0 then
feedkeys("<C-e><CR>")
else
feedkeys("<CR>")
end
end, { desc = "prevent omnifunc from completing on <CR>" })
map("i", "<C-s>", "<C-x><C-s>", { desc = "Trigger spell completion" })
map("n", "<C-s>", lz "<cmd>se spell<CR>ea<C-x><C-s><cmd>se nospell<CR>", { desc = "Trigger spell completion" })
-- quickfix
map("n", "<M-j>", "<cmd>cnext<CR>")
map("n", "<M-k>", "<cmd>cprev<CR>")
map("n", "<M-c>", "<cmd>cclose<CR>")
map("n", "<M-j>", lz "<cmd>cnext<CR>zz", { desc = "qf next" })
map("n", "<M-k>", lz "<cmd>cprev<CR>zz", { desc = "qf prev" })
map("n", "<M-c>", "<cmd>cclose<CR>", { desc = "qf close" })
map("n", "<M-x>", lz(function()
local win = vim.api.nvim_get_current_win()
vim.cmd.cope()
vim.api.nvim_set_current_win(win)
end), { desc = "qf open" })
-- man pages
map("n", "<C-k>", "<cmd>Man<CR>")
-- okay this is gonna sound crazy, but I like emacs binds for editing when I'm
-- stuck without modal editing like in command mode.
map("c", "<C-a>", function() feedkeys("<Home>") end)
map("c", "<C-e>", function() feedkeys("<End>") end)
map("c", "<C-d>", function() feedkeys("<Del>") end)
-- execute line/block
map("n", "<leader>x", ":.lua<CR>")
map("x", "<leader>x", ":lua<CR>")

3
lua/conf/init.lua Normal file
View File

@@ -0,0 +1,3 @@
require("conf.opts") -- setup options
require("conf.binds") -- setup keybinds
require("conf.autos") -- setup autos

View File

@@ -1,158 +1,95 @@
local misc = require("core.misc")
local auto = misc.auto
-- color stuff
if vim.fn.has("termguicolors") then
vim.opt.termguicolors = true
end
vim.opt.laststatus = 3
-- make .h files default to c code
vim.filetype.add({ extension = { h = "c", }, })
-- numbers
vim.opt.number = true
vim.opt.relativenumber = true
vim.o.nu = true
vim.o.rnu = true
-- buffer
vim.opt.scrolloff = 5
vim.opt.wrap = true -- wraping lines
vim.opt.linebreak = true -- fix where line is wraped
vim.opt.cursorline = true
vim.opt.colorcolumn = { 80 }
vim.o.lbr = true -- fix where line is wraped
vim.o.cul = true
vim.o.cc = "80"
-- indents + tabs
local tabwidth = 2
vim.opt.expandtab = true
vim.opt.smarttab = true
vim.opt.cindent = true
vim.opt.autoindent = true
vim.opt.tabstop = tabwidth
vim.opt.shiftwidth = tabwidth
vim.opt.softtabstop = tabwidth
vim.o.et = true
vim.o.ts = tabwidth
vim.o.sw = tabwidth
vim.o.sts = -1
-- Schedule the setting after `UiEnter` because it can increase startup-time.
-- (yoinked from kickstart.nvim)
vim.schedule(function()
vim.opt.clipboard = "unnamedplus" -- system clipboard
vim.o.cb = "unnamedplus" -- system clipboard
end)
vim.opt.updatetime = 200
-- file saving
vim.opt.swapfile = false
vim.opt.undofile = true
vim.opt.confirm = true
vim.o.swf = false
vim.o.udf = true
-- searching
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.wrapscan = true
vim.opt.showmatch = true
vim.opt.incsearch = true
vim.o.ic = true
-- make windows look nice wrapped in pcall cause it's causing my setup to go
-- bezerk inside of git commit buffers
pcall(function() vim.o.winborder = '▄,▄,▄,█,▀,▀,▀,█' end)
-- wild menus
vim.opt.wildoptions = "pum"
vim.opt.pumblend = 3
vim.opt.pumheight = 20
vim.o.ph = 20
vim.o.wic = true
vim.o.wop = "fuzzy,pum"
vim.o.wim = "noselect:lastused,full"
vim.opt.wildignorecase = true
vim.opt.wildignore = "*.o"
-- completion
vim.o.cpt = ".,w,b,u,d,i"
vim.o.cot = "menu,menuone,noinsert,fuzzy,popup"
vim.o.cia = "kind,abbr,menu"
-- waiting for https://github.com/neovim/neovim/pull/25541 to land
-- vim.o.completepopup = "border:"..vim.o.winborder
-- netrw
vim.g.netrw_banner = 0
vim.g.netrw_winsize = 30
vim.g.netrw_liststyle = 1
vim.g.netrw_sizestyle = "H"
vim.g.netrw_hide = 1
do -- statusline
---@return string out formatted status line
function _G.Status()
--- get the percentage through the file
---@return string out the formatted percentage
local function percentage()
local percent, line, lines
-- border (this doesn"t actually do anything within vim, I"m just setting it
-- here so it"s easy to find)
vim.g.border_style = "solid"
-- get the current and total # of lines
line = vim.api.nvim_win_get_cursor(0)[1]
lines = vim.api.nvim_buf_line_count(0)
-- folding
auto("FileType", {
callback = function()
-- FIXME: it causes errors every once in a while
-- support lsp folding
-- if vim.fn.has("nvim-0.11") then
-- auto("LspAttach", {
-- callback = function(args)
-- local client = vim.lsp.get_client_by_id(args.data.client_id)
-- if not client then
-- return
-- end
-- calculate the percentage through the file
percent = math.floor((line / lines) * 100)
if percent == 0 or line == 1 then
return "Top"
elseif percent == 100 or line == lines then
return "Bot"
end
-- if client:supports_method("textDocument/foldingRange") then
-- local win = vim.api.nvim_get_current_win()
-- vim.wo[win][0].foldmethod = "expr"
-- vim.wo[win][0].foldexpr = "v:lua.vim.lsp.foldexpr()"
-- end
-- end,
-- })
-- end
-- or just rely on treesitter
if require("nvim-treesitter.parsers").has_parser() then
vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"
else
vim.opt.foldmethod = "syntax"
return percent.."%%"
end
end
})
-- lsp folding: vim.o.foldexpr = "v:lua.vim.lsp.foldexpr()"
-- waiting on https://github.com/neovim/neovim/pull/31311 to hit a release
vim.lsp.config['*'] = {
capabilities = {
textDocument = {
foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true
}
-- this is my statusline:
--
-- opts.lua [+] λ1 163,61-60 88%
--
return table.concat {
"%t", -- file name
" %h", -- help buffer tag
"%m", -- modify tag
"%r", -- readonly flag
"%=", -- seperate left and right side
-- print out the number of lsp clients attached
"λ"..#vim.lsp.get_clients({ bufnr = 0 }), " ",
"%<", -- we can start truncating here (I want to keep the file name)
"%l,%c%V", -- line, column-virtual column
"%<", -- we can start truncating here
" "..percentage() -- percentage through the buffer
}
}
}
vim.opt.foldlevelstart = 99
vim.opt.foldlevel = 99
vim.opt.foldenable = true
vim.o.fillchars = "fold: "
_G.Fold_text = require("core.folding")
vim.opt.foldtext = "v:lua.Fold_text()"
-- statusline
function _G.Status()
local function percentage()
local percent, line, lines
line = vim.api.nvim_win_get_cursor(0)[1]
lines = vim.api.nvim_buf_line_count(0)
percent = math.floor((line / lines) * 100)
if percent == 0 then
return "Top"
elseif percent == 100 then
return "Bot"
end
return percent.."%%"
end
return table.concat {
"%t", -- file name
" %h", -- help buffer tag
"%m", -- modify tag
"%r", -- readonly flag
"%=", -- seperate left and right side
-- print out the number of lsp clients attached
"λ"..#vim.lsp.get_clients({ bufnr = 0 }).." ",
"%<", -- we can start truncating here (I want to keep the file name)
"%l,%c%V", -- line, column-virtual column
"%<", -- we can start truncating here
" "..percentage() -- percentage through the buffer
}
vim.o.stl = "%!v:lua.Status()"
vim.o.ls = 3
end
vim.o.statusline="%!v:lua.Status()"

View File

@@ -1,125 +0,0 @@
return { "Saghen/blink.cmp",
branch = "v1.2.0",
requires = {
"xzbdmw/colorful-menu.nvim",
"L3MON4D3/LuaSnip"
},
function()
local colormenu = require("colorful-menu")
require("blink.cmp").setup {
keymap = {
preset = "none", -- I don't like the default documentation scroll binds
["<C-y>"] = { "select_and_accept" },
["<C-n>"] = { "select_next", "fallback_to_mappings" },
["<C-p>"] = { "select_prev", "fallback_to_mappings" },
["<C-u>"] = { "scroll_documentation_up", "fallback" },
["<C-d>"] = { "scroll_documentation_down", "fallback" }
},
completion = {
menu = {
scrollbar = false,
border = vim.g.border_style,
draw = {
columns = {
{ "kind_icon" },
{ "label", "label_description", gap = 1 },
{ "kind" }
},
-- blink.cmp should not take this much damn work to make it look
-- semi-decent
components = {
-- we replace the kind icon with the an icon for the source
kind_icon = {
text = function(ctx)
local menu_icon = {
"?", -- fallback
lsp = "λ",
snippets = "%",
buffer = "@",
path = "#",
cmdline = "$"
}
local icon = menu_icon[ctx.source_id]
if icon == nil then
icon = menu_icon[1]
end
return icon
end,
highlight = function(_)
return { { group = "CmpItemMenu" } }
end
},
label = {
text = function(ctx)
return colormenu.blink_components_text(ctx)
end,
highlight = function(ctx)
return colormenu.blink_components_highlight(ctx)
end
},
kind = {
-- these highlights are technically for nvim-cmp, but they're
-- built into my colorscheme so I don"t mind using them here
highlight = function(ctx)
return {
{ group = "CmpItemKind"..ctx.kind, priority = 20000 }
}
end
}
}
}
},
ghost_text = {
enabled = true
},
-- documentation should show up immediately
documentation = {
auto_show = true,
auto_show_delay_ms = 0,
window = {
border = vim.g.border_style
}
}
},
-- I like the default command line completion
cmdline = {
enabled = false
},
-- signature support is necessary
signature = {
enabled = true,
window = {
border = vim.g.border_style
}
},
-- TODO: find a way to make my fancy luasnip snippets with multiple
-- triggers not look stupid e.g. "fn\|main" for a function that could
-- be triggered by fn or main
snippets = {
preset = "luasnip"
},
sources = {
default = { "lsp", "path", "snippets", "buffer" }
},
fuzzy = {
implementation = "prefer_rust_with_warning",
sorts = {
"score",
"sort_text"
}
}
}
end
}

View File

@@ -1,7 +0,0 @@
return { "numToStr/Comment.nvim",
function()
require("Comment").setup {
ignore = "^$"
}
end
}

View File

@@ -1,27 +0,0 @@
return { "theHamsta/nvim-dap-virtual-text",
requires = {
"nvim-treesitter/nvim-treesitter",
"mfussenegger/nvim-dap"
},
function()
require("nvim-dap-virtual-text").setup {
virt_text_pos = vim.fn.has("nvim-0.10") == 1 and "inline" or "eol",
--- A callback that determines how a variable is displayed or whether it should be omitted
--- @param variable Variable https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable
--- @param buf number
--- @param stackframe dap.StackFrame https://microsoft.github.io/debug-adapter-protocol/specification#Types_StackFrame
--- @param node userdata tree-sitter node identified as variable definition of reference (see `:h tsnode`)
--- @param options nvim_dap_virtual_text_options Current options for nvim-dap-virtual-text
--- @return string|nil A text how the virtual text should be displayed or nil, if this variable shouldn't be displayed
display_callback = function(variable, buf, stackframe, node, options)
-- by default, strip out new line characters
if options.virt_text_pos == "inline" then
return " = "..variable.value:gsub("%s+", " ")
else
return variable.name.." = "..variable.value:gsub("%s+", " ")
end
end
}
end
}

View File

@@ -1,33 +1,22 @@
local misc = require("core.misc")
local map = misc.map
--- select a program to execute
---@return thread coroutine containing the picker
local function select_program()
return coroutine.create(function(coro)
---@diagnostic disable-next-line: param-type-mismatch
local entries = vim.fn.readdir(".", [[v:val !~ '^\.']])
vim.ui.select(entries, { prompt = "Select the executable to run:" },
function(choice)
coroutine.resume(coro, choice)
end)
end)
end
local map = core.misc.map
local keymap_restore = {}
--- make the default hover binding work for nvim-dap instead of lsp
local function set_hover_bind()
for _, buf in pairs(vim.api.nvim_list_bufs()) do
local keymaps = vim.api.nvim_buf_get_keymap(buf, 'n')
local keymaps = vim.api.nvim_buf_get_keymap(buf, "n")
for _, keymap in pairs(keymaps) do
if keymap.lhs == "K" then
table.insert(keymap_restore, keymap)
vim.api.nvim_buf_del_keymap(buf, 'n', 'K')
vim.api.nvim_buf_del_keymap(buf, "n", "K")
end
end
end
vim.keymap.set('n', 'K', require("dap.ui.widgets").hover,
{ silent = true })
map("n", "K", function()
require("dap.ui.widgets").hover(nil, {
border = vim.g.border_style
})
end, { silent = true })
end
--- revert the hover bind back to whatever it was
@@ -44,55 +33,109 @@ local function unset_hover_bind()
keymap_restore = {}
end
return { "mfussenegger/nvim-dap",
requires = {
"mason-org/mason.nvim",
"nvim-telescope/telescope.nvim"
},
disable = not vim.fn.has("nvim-0.9.5"),
branch = "0.10.0",
function()
local dap = require("dap")
return {
{ "mfussenegger/nvim-dap",
reqs = {
"mason-org/mason.nvim",
"nvim-telescope/telescope.nvim"
},
deps = "theHamsta/nvim-dap-virtual-text",
branch = "0.10.0",
lazy = function(load)
load:keymap("n", "<leader>ec")
load:keymap("n", "<leader>el")
load:keymap("n", "<leader>et")
load:keymap("n", "<leader>eb")
load:keymap("n", "<leader>e]")
load:keymap("n", "<leader>e[")
load:keymap("n", "<leader>er")
load:keymap("n", "<leader>eR")
end,
load = function()
local dap = require("dap")
-- define codelldb
dap.adapters.codelldb = {
type = "executable",
command = "codelldb",
}
-- define the c configuration for codelldb
dap.configurations.c = {
{
name = "Launch file",
type = "codelldb",
request = "launch",
program = select_program,
cwd = "${workspaceFolder}",
stopOnEntry = false
-- define codelldb
dap.adapters.codelldb = {
type = "executable",
command = "codelldb"
}
}
-- and define them for cpp, zig, and rust
dap.configurations.cpp = dap.configurations.c
dap.configurations.zig = dap.configurations.c
dap.configurations.rust = dap.configurations.c
-- define the c configuration for codelldb
dap.configurations.c = {
{
name = "Launch file",
type = "codelldb",
request = "launch",
program = function()
return vim.fn.input("Path to executable: ", vim.fn.getcwd().."/", "file")
end,
-- keybinds
map("n", "<Leader>ec", dap.continue, { desc = "dap continue " })
map("n", "<Leader>el", dap.run_last, { desc = "dap run last" })
map("n", "<Leader>et", function()
dap.terminate()
unset_hover_bind()
end, { desc = "dap terminate " })
map("n", "<Leader>eb", require("dap.breakpoints").toggle, { desc = "dap toggle breakpoint" })
map("n", "<Leader>e]", dap.step_over, { desc = "dap step over" })
map("n", "<Leader>e[", dap.step_back, { desc = "dap step back" })
map("n", "<Leader>er", dap.repl.toggle, { desc = "dap repl toggle" })
map("n", "<Leader>eR", dap.restart, { desc = "dap restart" })
cwd = "${workspaceFolder}",
stopOnEntry = false
}
}
-- events
dap.listeners.after['event_initialized']['me'] = set_hover_bind
dap.listeners.after['event_terminated']['me'] = unset_hover_bind
end
-- and define them for cpp, zig, and rust
dap.configurations.cpp = dap.configurations.c
dap.configurations.zig = dap.configurations.c
dap.configurations.rust = dap.configurations.c
-- keybinds
map("n", "<leader>ec", dap.continue, { desc = "dap continue" })
map("n", "<leader>el", dap.run_last, { desc = "dap run last" })
map("n", "<leader>et", function()
dap.terminate()
unset_hover_bind()
end, { desc = "dap terminate " })
map("n", "<leader>eb", require("dap.breakpoints").toggle, {
desc = "dap toggle breakpoint"
})
map("n", "<leader>e]", dap.step_over, { desc = "dap step over" })
map("n", "<leader>e[", dap.step_back, { desc = "dap step back" })
map("n", "<leader>er", dap.repl.toggle, { desc = "dap repl toggle" })
map("n", "<leader>eR", dap.restart, { desc = "dap restart" })
-- events
dap.listeners.after["event_initialized"]["me"] = set_hover_bind
dap.listeners.after["event_terminated"]["me"] = unset_hover_bind
end
},
{ "theHamsta/nvim-dap-virtual-text",
reqs = {
"nvim-treesitter/nvim-treesitter",
"mfussenegger/nvim-dap"
},
lazy = dep_short.cmd("DapVirtualTextToggle"),
load = function()
require("nvim-dap-virtual-text").setup {
virt_text_pos = vim.fn.has("nvim-0.10") == 1 and "inline" or "eol",
--- A callback that determines how a variable is displayed or whether it should be omitted
--- @param variable Variable https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable
--- @param buf number
--- @param stackframe dap.StackFrame https://microsoft.github.io/debug-adapter-protocol/specification#Types_StackFrame
--- @param node userdata tree-sitter node identified as variable definition of reference (see `:h tsnode`)
--- @param options nvim_dap_virtual_text_options Current options for nvim-dap-virtual-text
--- @return string|nil A text how the virtual text should be displayed or nil, if this variable shouldn't be displayed
display_callback = function(variable, buf, stackframe, node, options)
-- by default, strip out new line characters
if options.virt_text_pos == "inline" then
return " = "..variable.value:gsub("%s+", " ")
else
return variable.name.." = "..variable.value:gsub("%s+", " ")
end
end
}
end
},
{ "mfussenegger/nvim-dap-python",
reqs = "mfussenegger/nvim-dap",
lazy = dep_short.ft("python"),
load = function()
local debugpy = core.mason.get_pkg_path("debugpy", "/venv/bin/python3")
require("dap-python").setup(debugpy)
end
}
}

View File

@@ -1,36 +0,0 @@
return { "j-hui/fidget.nvim",
disable = not vim.fn.has("nvim-0.9.0"),
branch = "v1.5.0",
function()
local notification_defaults = require("fidget.notification").default_config
notification_defaults["icon"] = ""
require("fidget").setup {
progress = {
display = {
progress_icon = {
pattern = "line",
period = 1
},
done_icon = ":)"
}
},
notification = {
filter = vim.log.levels.DEBUG,
override_vim_notify = true,
configs = {
default = notification_defaults
},
view = {
icon_separator = " ",
group_separator = "---",
group_separator_hl = "Comment"
},
window = {
zindex = 44,
relative = "editor"
}
}
}
end
}

View File

@@ -1,9 +1,18 @@
local misc = require("core.misc")
local map = misc.map
local map = core.misc.map
return { "lewis6991/gitsigns.nvim",
disable = not vim.fn.has("nvim-0.9.0"),
function()
lazy = function(load)
load:auto({ "BufEnter", "BufNew" }, {
callback = function()
local paths = vim.fs.find({ ".git", }, { upward = true })
if #paths > 0 then
load:cleanup()
end
end
})
load:cmd("Gitsigns")
end,
load = function()
local gs = require("gitsigns")
gs.setup {
@@ -40,7 +49,6 @@ return { "lewis6991/gitsigns.nvim",
return "]c"
end
vim.schedule(function() gs.next_hunk() end)
return "<Ignore>"
end, { expr = true, buffer = bufnr })
map("n", "[c", function()
@@ -48,7 +56,6 @@ return { "lewis6991/gitsigns.nvim",
return "[c"
end
vim.schedule(function() gs.prev_hunk() end)
return "<Ignore>"
end, { expr = true, buffer = bufnr })
-- Actions
@@ -64,7 +71,7 @@ return { "lewis6991/gitsigns.nvim",
map("n", "<leader>hu", gs.undo_stage_hunk, opts)
map("n", "<leader>hR", gs.reset_buffer, opts)
map("n", "<leader>hp", gs.preview_hunk, opts)
map("n", "<leader>hb", function() gs.blame_line { full=true } end, opts)
map("n", "<leader>hb", function() gs.blame_line { full = true } end, opts)
map("n", "<leader>tb", gs.toggle_current_line_blame, opts)
map("n", "<leader>hd", gs.diffthis, opts)
map("n", "<leader>hD", function() gs.diffthis("~") end, opts)

View File

@@ -1,32 +0,0 @@
local misc = require("core.misc")
local map = misc.map
return { "ThePrimeagen/harpoon",
disable = not vim.fn.has("nvim-0.8.0"),
commit = "e76cb03",
branch = "harpoon2",
requires = "nvim-lua/plenary.nvim",
function()
local harpoon = require("harpoon")
harpoon:setup()
map("n", "<leader>a", function()
harpoon:list():add()
vim.notify("added "..vim.fn.expand("%:t").." to quickmarks", vim.log.levels.INFO, {
title = misc.appid
})
end, { desc = "add current file to quickmarks" })
map("n", "<C-e>", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end)
map("n", "<C-h>", function() harpoon:list():select(1) end)
map("n", "<C-t>", function() harpoon:list():select(2) end)
map("n", "<C-n>", function() harpoon:list():select(3) end)
map("n", "<C-c>", function() harpoon:list():select(4) end)
-- Toggle previous & next buffers stored within Harpoon list
map("n", "<C-S-P>", function() harpoon:list():prev() end)
map("n", "<C-S-N>", function() harpoon:list():next() end)
end
}

View File

@@ -1 +0,0 @@
return { "tweekmonster/helpful.vim" }

View File

@@ -1,5 +0,0 @@
return { "mawkler/hml.nvim",
function()
require("hml").setup {}
end
}

View File

@@ -1,5 +0,0 @@
return { "jbyuki/instant.nvim",
function()
vim.g.instant_username = "squibid"
end
}

View File

@@ -1,4 +0,0 @@
return { "mfussenegger/nvim-jdtls",
disable = not vim.fn.has("nvim-0.6.0"),
requires = "mfussenegger/nvim-dap"
}

View File

@@ -1,17 +0,0 @@
return { "kawre/leetcode.nvim",
requires = {
"nvim-lua/plenary.nvim",
"nvim-telescope/telescope.nvim",
"MunifTanjim/nui.nvim",
"nvim-treesitter/nvim-treesitter"
},
config = function()
-- because we"re using treesitter make sure to install the html parser
vim.cmd("TSUpdate html")
end,
function()
require("leetcode").setup {
lang = "java"
}
end
}

41
lua/conf/plugins/lsp.lua Normal file
View File

@@ -0,0 +1,41 @@
return {
{ "neovim/nvim-lspconfig",
reqs = {
"mason-org/mason.nvim",
"mason-org/mason-lspconfig.nvim"
},
load = function()
core.lsp.setup()
require("mason-lspconfig").setup {
ensure_added = {
"clangd",
"mesonlsp",
"bashls",
"jdtls",
"lua_ls",
"basedpyright",
"debugpy"
}
}
end
},
{ "mason-org/mason.nvim",
load = function()
require("mason").setup {
ui = {
-- not sure why these are nerdfont icons by default
icons = {
package_installed = "+",
package_pending = "?",
package_uninstalled = "x"
}
}
}
end
},
{ "mfussenegger/nvim-jdtls",
reqs = "mfussenegger/nvim-dap"
},
}

View File

@@ -1,4 +0,0 @@
return { "whynothugo/lsp_lines",
url = "https://git.sr.ht/~whynothugo/lsp_lines.nvim",
disable = not vim.fn.has("nvim-0.8.0")
}

View File

@@ -1,17 +0,0 @@
return { "neovim/nvim-lspconfig",
disable = not vim.fn.has("nvim-0.10.0"),
requires = {
"mason-org/mason.nvim",
"mason-org/mason-lspconfig.nvim"
},
function()
require("core.lsp.functions").setup()
require("mason-lspconfig").setup {
ensure_added = {
"clangd",
"lua_ls",
"jdtls"
}
}
end
}

View File

@@ -1,67 +1,49 @@
local misc = require("core.misc")
local map = misc.map
local map = core.misc.map
return { "L3MON4D3/LuaSnip",
branch = "v2.4.0",
disable = not vim.fn.has("nvim-0.7.0"),
config = function()
vim.cmd("make install_jsregexp")
end,
function()
local luasnip = require("luasnip")
local types = require("luasnip.util.types")
branch = "v2.*",
config = function()
vim.cmd("make install_jsregexp")
end,
lazy = function(load)
load:keymap({"i", "s"}, "<c-a>")
load:keymap({"i", "s"}, "<c-e>")
load:keymap({"i", "s"}, "<c-j>")
load:keymap({"i", "s"}, "<c-k>")
load:auto("InsertEnter")
end,
load = function()
local ls = require("luasnip")
luasnip.config.set_config {
history = true, -- return back into snippet
enable_autosnippets = true,
-- replace the builtin snippet handler with luasnip so I get all my fancy
-- stuff
vim.snippet.expand = ls.lsp_expand
-- update on text insert and cursor hold
updateevents = { "TextChanged", "TextChangedI", "CursorHold" },
ext_opts = {
[types.choiceNode] = {
active = {
virt_text = {{ "", "@boolean" }}
}
},
[types.insertNode] = {
active = {
virt_text = {{ "", "@constant" }}
}
}
}
}
ls.config.setup {
keep_roots = true,
link_roots = true,
link_children = true,
exit_roots = not true
}
map({"i", "s"}, "<c-a>", function()
if luasnip.choice_active() then
luasnip.change_choice(1)
end
end)
map({"i", "s"}, "<C-e>", ls.expand)
map({"i", "s"}, "<C-j>", function() ls.jump(1) end)
map({"i", "s"}, "<C-k>", function() ls.jump(-1) end)
map({"i", "s"}, "<C-a>", function()
if ls.choice_active() then
ls.change_choice(1)
end
end)
map({"i", "s"}, "<c-e>", function()
if luasnip.expandable() then
luasnip.expand()
end
end)
-- collect all snippets and add them
for _, file in ipairs(vim.api.nvim_get_runtime_file("lua/snippets/*.lua",
true)) do
local fn = file:gsub("^.*/", ""):gsub("%.lua$", "")
map({"i", "s"}, "<C-j>", function()
if luasnip.jumpable(1) then
luasnip.jump(1)
end
end)
map({"i", "s"}, "<C-k>", function()
if luasnip.jumpable(-1) then
luasnip.jump(-1)
end
end)
-- load all snippets from snippet directory
for _, file in ipairs(vim.api.nvim_get_runtime_file("lua/snippets/*.lua", true)) do
local fn = file:gsub("^.*/", ""):gsub("%.lua$", "")
local ret = misc.include("snippets."..fn)
if type(ret) ~= "boolean" then
luasnip.add_snippets(fn, ret, { key = fn })
end
end
end
local ret = require("snippets."..fn)
if type(ret) ~= "boolean" then
ls.add_snippets(fn, ret, { key = fn })
end
end
end
}

View File

@@ -1,31 +0,0 @@
return { "mason-org/mason.nvim",
disable = not vim.fn.has("nvim-0.7.0"),
function()
local mason = require("mason")
mason.setup {
ui = {
border = vim.g.border_style,
width = 0.8,
height = 0.9,
icons = {
package_installed = "+",
package_pending = "?",
package_uninstalled = "x"
}
},
keymaps = {
toggle_package_expand = "<CR>",
install_package = "i",
update_package = "u",
check_package_version = "c",
update_all_packages = "U",
check_outdated_packages = "C",
uninstall_package = "r",
cancel_installation = "<C-c>",
apply_language_filter = "<C-f>"
}
}
end
}

View File

@@ -1,29 +1,62 @@
return { "mellow-theme/mellow.nvim",
disable = not vim.fn.has("nvim-0.8.0"),
requires = "nvim-treesitter/nvim-treesitter",
function()
reqs = "nvim-treesitter/nvim-treesitter",
load = function()
vim.g.mellow_variant = "dark"
local c = require("mellow.colors")[vim.g.mellow_variant]
vim.g.mellow_highlight_overrides = {
-- stop inactive windows from having a darker bg
["NormalNC"] = { link = "Normal" },
if vim.g.mellow_variant == "dark" then
vim.g.mellow_highlight_overrides = {
-- stop inactive windows from having a darker bg
["NormalNC"] = { link = "Normal" },
-- make floats darker
["NormalFloat"] = { fg = c.fg, bg = "#111111" },
["FloatBorder"] = { link = "NormalFloat" },
-- revert change with statusline coloring
["StatusLine"] = { fg = c.white, bg = c.gray01 },
["StatusLineNC"] = { fg = c.bg_dark },
-- make diagnostics have an undercurl
["DiagnosticUnderlineError"] = { fg = c.red, undercurl = true },
["DiagnosticUnderlineWarn"] = { fg = c.yellow, undercurl = true },
["DiagnosticUnderlineInfo"] = { fg = c.blue, undercurl = true },
["DiagnosticUnderlineHint"] = { fg = c.cyan, undercurl = true },
-- make splits look cleaner
["WinSeparator"] = { fg = c.gray01 },
-- make blink actually look nice
["BlinkCmpMenu"] = { link = "NormalFloat" },
["BlinkCmpMenuBorder"] = { link = "BlinkCmpMenu" },
["BlinkCmpMenuSelection"] = { bg = c.gray01 },
["BlinkCmpLabelDeprecated"] = { link = "CmpItemAbbrDeprecated" }
}
-- make floats darker
["NormalFloat"] = { fg = c.fg, bg = "#111111" },
["FloatBorder"] = { fg = "#111111" },
-- Make pmenu look good
["Pmenu"] = { link = "NormalFloat" },
["PmenuSel"] = { link = "Normal" },
["PmenuKind"] = { link = "@constant" },
["PmenuKindSel"] = {
fg = core.color.copyhl("Comment").fg,
bold = true
},
-- make diagnostics have an undercurl
["DiagnosticUnderlineError"] = { fg = c.red, undercurl = true },
["DiagnosticUnderlineWarn"] = { fg = c.yellow, undercurl = true },
["DiagnosticUnderlineInfo"] = { fg = c.blue, undercurl = true },
["DiagnosticUnderlineHint"] = { fg = c.cyan, undercurl = true },
["DiagnosticHint"] = { fg = c.cyan }, -- revert
-- telescope styling so I can see when coding outside (real)
["TelescopeResultsNormal"] = { bg = c.bg_dark },
["TelescopeResultsBorder"] = { link = "TelescopeResultsNormal" },
["TelescopeResultsTitle"] = { bg = c.bg, fg = c.bg },
["TelescopePreviewNormal"] = { link = "NormalFloat" },
["TelescopePreviewBorder"] = { link = "TelescopePreviewNormal" },
-- add highlight groups for my todo highlighting
["TodoTODO"] = { link = "DiagnosticHint" },
["TodoTODOBG"] = { fg = c.bg, bg = c.cyan, bold = true },
["TodoTODOSIGN"] = { fg = c.cyan, bg = c.cyan, bold = true },
["TodoBUG"] = { link = "DiagnosticError" },
["TodoBUGBG"] = { fg = c.bg, bg = c.red, bold = true },
["TodoBUGSIGN"] = { fg = c.red, bg = c.red, bold = true },
["TodoTEST"] = { link = "DiagnosticInfo" },
["TodoTESTBG"] = { fg = c.bg, bg = c.blue, bold = true },
["TodoTESTSIGN"] = { fg = c.blue, bg = c.blue, bold = true },
["TodoWARN"] = { link = "DiagnosticWarn" },
["TodoWARNBG"] = { fg = c.bg, bg = c.yellow, bold = true },
["TodoWARNSIGN"] = { fg = c.yellow, bg = c.yellow, bold = true },
}
end
end
}

View File

@@ -1,12 +1,12 @@
local misc = require("core.misc")
local map = misc.map
local map = core.misc.map
return { "danymat/neogen",
requires = {
reqs = {
"nvim-treesitter/nvim-treesitter",
"L3MON4D3/LuaSnip"
},
function()
lazy = dep_short.keymap("n", "<leader>d"),
load = function()
local neogen = require("neogen")
neogen.setup {
enabled = true,

View File

@@ -1,9 +0,0 @@
return { "norcalli/nvim-colorizer.lua",
disable = not vim.fn.has("nvim-0.4.0") and not vim.fn.has("termguicolors"),
function()
require("colorizer").setup(nil, {
names = false,
css = true
})
end
}

View File

@@ -1,7 +0,0 @@
return { "squibid/nyooom",
url = "https://git.squi.bid/nyooom",
pin = true,
function()
require("nyooom").setup {}
end
}

View File

@@ -1,85 +1,8 @@
local misc = require("core.misc")
local map = misc.map
-- helper function to parse output
local function parse_output(proc)
local result = proc:wait()
local ret = {}
if result.code == 0 then
for line in vim.gsplit(result.stdout, "\n", { plain = true, trimempty = true }) do
-- Remove trailing slash
line = line:gsub("/$", "")
ret[line] = true
end
end
return ret
end
-- build git status cache
local function new_git_status()
return setmetatable({}, {
__index = function(self, key)
local ignore_proc = vim.system(
{ "git", "ls-files", "--ignored", "--exclude-standard", "--others", "--directory" },
{
cwd = key,
text = true,
}
)
local tracked_proc = vim.system({ "git", "ls-tree", "HEAD", "--name-only" }, {
cwd = key,
text = true,
})
local ret = {
ignored = parse_output(ignore_proc),
tracked = parse_output(tracked_proc),
}
rawset(self, key, ret)
return ret
end,
})
end
local git_status = new_git_status()
local permission_hlgroups = {
["-"] = "NonText",
["r"] = "DiagnosticSignWarn",
["w"] = "DiagnosticSignHint",
["x"] = "DiagnosticSignOk",
}
local map = core.misc.map
return { "stevearc/oil.nvim",
disable = not vim.fn.has("nvim-0.8.0"),
deps = {
{ "refractalize/oil-git-status.nvim",
function()
require("oil-git-status").setup {
symbols = { -- customize the symbols that appear in the git status columns
index = {
["A"] = "+",
["D"] = "-",
["M"] = "~",
},
working_tree = {
["A"] = "+",
["D"] = "-",
["M"] = "~",
}
}
}
end
}
},
function()
-- Clear git status cache on refresh
local refresh = require("oil.actions").refresh
local orig_refresh = refresh.callback
refresh.callback = function(...)
git_status = new_git_status()
orig_refresh(...)
end
lazy = dep_short.keymap("n", "-"),
load = function()
require("oil").setup {
-- ID is automatically added at the beginning, and name at the end
-- See :help oil-columns
@@ -90,7 +13,12 @@ return { "stevearc/oil.nvim",
local hls = {}
for i = 1, #permission_str do
local char = permission_str:sub(i, i)
table.insert(hls, { permission_hlgroups[char], i - 1, i })
table.insert(hls, { ({
["-"] = "NonText",
["r"] = "DiagnosticSignWarn",
["w"] = "DiagnosticSignHint",
["x"] = "DiagnosticSignOk"
})[char], i - 1, i })
end
return hls
end,
@@ -98,136 +26,12 @@ return { "stevearc/oil.nvim",
{ "size", highlight = "@number" }
},
-- Window-local options to use for oil buffers
win_options = {
number = false,
relativenumber = false,
wrap = false,
signcolumn = "yes:2",
cursorcolumn = false,
foldcolumn = "0",
spell = false,
list = false,
conceallevel = 3,
concealcursor = "nvic"
},
-- Send deleted files to the trash instead of permanently deleting them (:help oil-trash)
delete_to_trash = false,
-- Skip the confirmation popup for simple operations (:help oil.skip_confirm_for_simple_edits)
skip_confirm_for_simple_edits = false,
-- Selecting a new/moved/renamed file or directory will prompt you to save changes first
-- (:help prompt_save_on_select_new_entry)
prompt_save_on_select_new_entry = true,
-- Oil will automatically delete hidden buffers after this delay
-- You can set the delay to false to disable cleanup entirely
-- Note that the cleanup process only starts when none of the oil buffers are currently displayed
cleanup_delay_ms = 2000,
lsp_file_methods = {
-- Enable or disable LSP file operations
enabled = true,
-- Time to wait for LSP file operations to complete before skipping
timeout_ms = 1000,
-- Set to true to autosave buffers that are updated with LSP willRenameFiles
-- Set to "unmodified" to only save unmodified buffers
autosave_changes = "unmodified"
},
-- Constrain the cursor to the editable parts of the oil buffer
-- Set to `false` to disable, or "name" to keep it on the file names
constrain_cursor = "editable",
-- Set to true to watch the filesystem for changes and reload oil
watch_for_changes = false,
-- Keymaps in oil buffer. Can be any value that `vim.keymap.set` accepts OR a table of keymap
-- options with a `callback` (e.g. { callback = function() ... end, desc = "", mode = "n" })
-- Additionally, if it is a string that matches "actions.<name>",
-- it will use the mapping at require("oil.actions").<name>
-- Set to `false` to remove a keymap
-- See :help oil-actions for a list of all available actions
keymaps = {
["g?"] = { "actions.show_help", mode = "n" },
["<C-l>"] = "actions.refresh",
["<CR>"] = "actions.select",
["-"] = { "actions.parent", mode = "n" },
["_"] = { "actions.open_cwd", mode = "n" },
["`"] = { "actions.cd", mode = "n" },
["~"] = { "actions.cd", opts = { scope = "tab" }, mode = "n" },
["gs"] = { "actions.change_sort", mode = "n" },
["gx"] = "actions.open_external",
["g."] = { "actions.toggle_hidden", mode = "n" },
["g\\"] = { "actions.toggle_trash", mode = "n" }
},
view_options = {
-- Show files and directories that start with "."
show_hidden = false,
-- This function defines what is considered a "hidden" file
is_hidden_file = function(name, bufnr)
local dir = require("oil").get_current_dir(bufnr)
local is_dotfile = vim.startswith(name, ".") and name ~= ".."
-- if no local directory (e.g. for ssh connections), just hide dotfiles
if not dir then
return is_dotfile
end
-- dotfiles are considered hidden unless tracked
if is_dotfile then
return not git_status[dir].tracked[name]
end
end,
-- This function defines what will never be shown, even when `show_hidden` is set
is_always_hidden = function(name, bufnr)
return false
end,
-- Sort file names with numbers in a more intuitive order for humans.
-- Can be "fast", true, or false. "fast" will turn it off for large directories.
natural_order = "fast",
-- Sort file and directory names case insensitive
case_insensitive = false,
sort = {
-- sort order can be "asc" or "desc"
-- see :help oil-columns to see which columns are sortable
{ "type", "asc" },
{ "name", "asc" },
},
-- Customize the highlight group for the file name
highlight_filename = function(entry, is_hidden, is_link_target, is_link_orphan)
return nil
end,
},
-- Configuration for the floating window in oil.open_float
float = {
border = vim.g.border_style
},
-- Configuration for the floating action confirmation window
confirmation = {
border = vim.g.border_style
},
-- Configuration for the floating progress window
progress = {
border = vim.g.border_style
},
-- Configuration for the floating SSH window
ssh = {
border = vim.g.border_style
},
-- Configuration for the floating keymaps help window
keymaps_help = {
border = vim.g.border_style
}
}
-- fix the damn border
confirmation = { winborder = vim.o.winborder },
progress = { winborder = vim.o.winborder },
ssh = { winborder = vim.o.winborder },
keymaps_help = { winborder = vim.o.winborder }
}
map("n", "-", "<cmd>Oil<CR>")
end

View File

@@ -0,0 +1,10 @@
return { "NickvanDyke/opencode.nvim",
load = function()
core.misc.map("n", "<leader>oa", function()
require("opencode").ask()
end, { desc = "Ask opencode" })
core.misc.map("v", "<leader>oa", function()
require("opencode").ask("@selection: ")
end, { desc = "Ask opencode about selection" })
end
}

View File

@@ -1,51 +1,129 @@
local misc = require("core.misc")
local map = misc.map
local map = core.misc.map
--- get the root directory for telescope to search
---@return string the root directory
local function root_dir()
local clients = vim.lsp.get_clients({ bufnr = 0 })
if #clients > 0 then
return clients[1].config.root_dir
end
return "."
end
--- wrap a telebuilt picker to make it work for the current project root
---@param fn function telebuilt function
---@return function the new function
local function telebuilt_picker(fn)
return function()
fn { cwd = root_dir() }
end
end
return { "nvim-telescope/telescope.nvim",
disable = not vim.fn.has("nvim-0.9.0"),
requires = {
reqs = {
"nvim-lua/plenary.nvim",
{ "nvim-telescope/telescope-fzf-native.nvim",
config = function()
vim.cmd("make")
end
},
"mollerhoj/telescope-recent-files.nvim",
"nvim-telescope/telescope-ui-select.nvim"
},
function()
lazy = function(load)
load:cmd("Telescope")
load:keymap("n", "<leader>f")
load:keymap("n", "<leader>s")
load:keymap("n", "<leader>i")
load:keymap("n", "<leader>;")
load:keymap("n", "<leader>tc")
load:keymap("n", "<leader>tp")
end,
load = function()
local telescope = require("telescope")
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local function send_limited_to_qflist_and_open(prompt_bufnr)
local picker = action_state.get_current_picker(prompt_bufnr)
local entries = {}
local max_items = 100
local count = 0
for entry in picker.manager:iter() do
if count >= max_items then
break
end
local filename = entry.path or entry.filename or entry.value
local text = entry.text or entry.value
if not text then
if type(entry.value) == "table" then
text = entry.value.text
else
text = entry.value
end
end
local pattern
if not entry.lnum then
if type(entry.display) == "string" then
pattern = entry.display
elseif type(entry.ordinal) == "string" then
pattern = entry.ordinal
elseif type(text) == "string" then
pattern = text
else
entry.lnum = 1
end
end
if filename then
table.insert(entries, {
filename = filename,
text = text,
lnum = entry.lnum,
col = entry.col,
-- we try and put a pattern in based on the info we receive from
-- telescope so that the qf list takes us to the correct place
pattern = pattern
})
count = count + 1
end
end
if #entries > 0 then
-- make sure errors get suppressed. I don't care
pcall(vim.fn.setqflist, {}, " ", {
title = "Telescope Limited Results",
items = entries
})
end
actions.select_default(prompt_bufnr)
end
telescope.setup {
defaults = {
borderchars = {
prompt = { " ", " ", " ", " ", " ", " ", " ", " " },
results = { " ", " ", " ", " ", " ", " ", " ", " " },
preview = { " ", " ", " ", " ", " ", " ", " ", " " },
},
winblend = 0,
layout_strategy = "horizontal",
sorting_strategy = "descending",
scroll_strategy = "limit",
layout_config = {
horizontal = {
height = 20,
prompt_position = "bottom",
anchor = "N",
}
},
layout_strategy = "bottom_pane",
borderchars = { " ", " ", " ", " ", " ", " ", " ", " " },
mappings = {
i = {
["<esc>"] = actions.close,
["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,
["<C-u>"] = actions.preview_scrolling_up,
["<C-d>"] = actions.preview_scrolling_down,
["<CR>"] = send_limited_to_qflist_and_open,
}
}
},
pickers = {
colorscheme = {
enable_preview = true
}
},
extensions = {
fzf = {}
}
@@ -53,37 +131,29 @@ return { "nvim-telescope/telescope.nvim",
-- load in the fzf extension
telescope.load_extension("fzf")
telescope.load_extension("recent-files")
telescope.load_extension("ui-select")
-- keymaps
local telebuilt = require("telescope.builtin")
map("n", "<leader>f", function()
telescope.extensions["recent-files"].recent_files { follow = true }
end, { desc = "Find files." })
map("n", "<leader>s", telebuilt.live_grep, { desc = "Find string in project." })
map("n", "<leader>b", telebuilt.current_buffer_fuzzy_find, {
desc = "Find string in current buffer.",
map("n", "<leader>f", telebuilt_picker(telebuilt.find_files), {
desc = "Find files."
})
map("n", "<leader>i", telebuilt.help_tags, {
desc = "find help tags.",
map("n", "<leader>s", telebuilt_picker(telebuilt.live_grep), {
desc = "Find strings."
})
map("n", "<leader>i", telebuilt.help_tags, { desc = "find help tags." })
map("n", "<leader>;", telebuilt.lsp_document_symbols, { desc = "find doc symbols." })
-- find over specific directories
map("n", "<leader>tc", function()
require("telescope.builtin").find_files {
cwd = vim.fn.stdpath("config")
}
telebuilt.find_files { cwd = vim.fn.stdpath("config") }
end, { desc = "find config files" })
map("n", "<leader>tp", function()
require("telescope.builtin").find_files {
telebuilt.find_files {
cwd = vim.fs.joinpath(vim.fn.stdpath("data"), "site/pack/deps/opt")
}
end, { desc = "find files in plugin directory" })
-- enable previewing in the default colorscheme switcher
telebuilt.colorscheme = function()
require("telescope.builtin.__internal").colorscheme { enable_preview = true }
end
map("n", "<leader>tt", "<cmd>Telescope<CR>")
end
}

View File

@@ -1,37 +0,0 @@
return { "folke/todo-comments.nvim",
requires = "nvim-lua/plenary.nvim",
disable = not vim.fn.has("nvim-0.8.0"),
function()
require("todo-comments").setup {
keywords = {
FIX = {
icon = "# ",
alt = { "FIXME", "BUG" },
},
HACK = {
icon = "* ",
color = "warning",
},
WARN = {
icon = "! ",
color = "warning",
alt = { "WARNING", "XXX" },
},
NOTE = {
icon = "i ",
color = "hint",
alt = { "INFO", "TODO" },
},
PERF = {
icon = "@ ",
alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" },
},
TEST = {
icon = "@ ",
color = "test",
alt = { "TESTING", "PASSED", "FAILED" },
},
},
}
end
}

View File

@@ -1,59 +1,86 @@
table.contains = function(self, string)
for _, v in pairs(self) do
if v == string then
return true
end
end
return false
end
local map = core.misc.map
return { "nvim-treesitter/nvim-treesitter",
disable = not vim.fn.has("nvim-0.10.0"),
config = function()
vim.cmd("TSUpdate")
end,
function()
require("nvim-treesitter.configs").setup {
-- good default parsers
ensure_installed = { "c", "lua", "vim", "vimdoc", "markdown",
"markdown_inline", "java", "bash", "css", "html", "luadoc",
"make"
},
return {
{ "nvim-treesitter/nvim-treesitter",
config = function()
vim.cmd("TSUpdate")
end,
load = function()
require("nvim-treesitter.configs").setup {
-- good default parsers
ensure_installed = { "c", "lua", "vim", "vimdoc", "markdown",
"markdown_inline", "java", "bash", "css", "html", "luadoc",
"make"
},
-- indentation
indent = {
enable = true,
-- indentation
indent = {
enable = true,
disable = function(lang, _)
-- disable indenting in php (it's more broken with than without)
return table.contains(({
"php"
}), lang)
end
},
-- enable highlighting
highlight = {
enable = true,
-- use vim highlighting in addition to treesitter
additional_vim_regex_highlighting = true,
disable = function(lang, buf)
-- disable in some files where vim's builtin highlighting is better
if table.contains(({
"diff", "tex"
}), lang) then
return true
disable = function(lang, _)
-- disable indenting in php (it's more broken with than without)
return table.contains(({
"php"
}), lang)
end
},
-- disable in big files
-- TODO: update before nvim 1.0 when vim.loop is removed
local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf))
if ok and stats and stats.size > (1024 * 100 * 10) --[[1MB]] then
return true
-- enable highlighting
highlight = {
enable = true,
-- use vim highlighting in addition to treesitter
additional_vim_regex_highlighting = true,
disable = function(lang, buf)
-- disable in some files where vim's builtin highlighting is better
if table.contains(({
"diff", "tex"
}), lang) then
return true
end
-- disable in big files
local ok, stats = pcall(vim.uv.fs_stat,
vim.api.nvim_buf_get_name(buf))
if ok and stats and stats.size > (1024 * 100 * 10) --[[1MB]] then
return true
end
end
end
}
}
}
end
core.misc.map("n", "<leader><leader>t", function()
pcall(vim.cmd.TSInstall, vim.api.nvim_get_option_value("ft", {
buf = vim.api.nvim_get_current_buf()
}))
end)
end
},
{ "Wansmer/treesj",
disable = not vim.fn.has("nvim-0.9.0"),
reqs = "nvim-treesitter/nvim-treesitter",
lazy = function(load)
load:keymap("n", "<leader>j")
load:cmd("TSJToggle")
load:cmd("TSJSplit")
load:cmd("TSJJoin")
end,
load = function()
require("treesj").setup {
use_default_keymaps = false,
}
map("n", "<leader>j", require("treesj").toggle, { desc = "fold code" })
end
},
{ "windwp/nvim-ts-autotag",
reqs = "nvim-treesitter/nvim-treesitter",
disable = true,
-- lazy = dep_short.auto({ "BufReadPre", "BufNewFile" }),
load = function()
require("nvim-ts-autotag").setup {}
end
}
}

View File

@@ -1,14 +0,0 @@
local misc = require("core.misc")
local map = misc.map
return { "Wansmer/treesj",
disable = not vim.fn.has("nvim-0.9.0"),
requires = "nvim-treesitter/nvim-treesitter",
function()
require("treesj").setup {
use_default_keymaps = false,
}
map("n", "<leader>j", require("treesj").toggle, { desc = "fold code" })
end
}

View File

@@ -1,8 +0,0 @@
return { "windwp/nvim-ts-autotag",
requires = "nvim-treesitter/nvim-treesitter",
disable = not vim.fn.has("nvim-0.9.5"),
function()
require("nvim-ts-autotag").setup {}
end
}

View File

@@ -1,12 +0,0 @@
local misc = require("core.misc")
local map = misc.map
return { "mbbill/undotree",
function()
if vim.g.loaded_undotree then
vim.g.undotree_DiffAutoOpen = 0
end
map("n", "<leader>u", "<cmd>UndotreeToggle<CR>")
end
}

279
lua/core/color.lua Normal file
View File

@@ -0,0 +1,279 @@
local M = {}
--- copy highlight group
---@param hlgroup string highlight group to copy
---@param namespace? number highlight space
---@return table
function M.copyhl(hlgroup, namespace)
namespace = namespace or 0
local res = {
["foreground"] = "#ff0000",
["background"] = "#ff0000",
["special"] = "#ff0000"
}
local ok, hl = pcall(vim.api.nvim_get_hl, namespace, {
name = hlgroup,
create = false
})
if not ok then
-- return error colors
return res
end
for _, key in pairs({ "foreground", "background", "special" }) do
if hl[key] then
res[key] = string.format("#%06x", hl[key])
end
end
return res
end
local todo_comments_conf = {
TODO = {
-- TODO:
-- NOTE:
-- INFO:
"TODO", "NOTE", "INFO",
hlgroup = "TodoTODO"
},
BUG = {
-- BUG:
-- FIXME:
"BUG", "FIXME",
hlgroup = "TodoBUG"
},
TEST = {
-- TEST:
-- PERF:
"TEST", "PERF",
hlgroup = "TodoTEST"
},
WARN = {
-- WARN:
-- HACK:
"WARN", "HACK",
hlgroup = "TodoWARN"
}
}
local todo_hl_ns = vim.api.nvim_create_namespace("todo_highlights")
--- highlight todo comments in the current buffer.
--- No I won't use folke's super bloated plugin.
---
--- TODO: make this work with coniguious comment blocks like this one.
--- currently this line won't be highlighted, but I'd like it to be
---
--- TEST: We could make this a plugin called ts-todo-hl or smthn like that, but
--- I'd be willing to bet no one would use it cause everyone loves folke too
--- much
function M.todo_comments()
local bufnr = vim.api.nvim_win_get_buf(0)
local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
if not ok or not parser then
return
end
-- Construct the query for comments.
-- We're using treesitter so that I don't have to use external tooling.
local ok, comment_query = pcall(vim.treesitter.query.parse,
parser:lang(),
"(comment) @comment"
)
if not ok then
return
end
parser:parse(false, function(err, trees)
if err then
return
end
local root = trees[1]:root()
for _, match in comment_query:iter_matches(root, bufnr, 0, -1) do
for _, nodes in pairs(match) do
for _, node in ipairs(nodes) do
if not node or node:type() ~= "comment" then
goto continue
end
local text = vim.treesitter.get_node_text(node, bufnr)
-- TODO: instead of doing everything relative to the node we at this
-- point should obtain the node start and use a for loop to iterate
-- over the lines until we're no longer in a comment. This should
-- make dealing with comment blocks easier, and working with these
-- multiline comments easier.
for _, type in pairs(todo_comments_conf) do
for _, v in ipairs(type) do
local s, e = string.find(text, v..":")
if not s or not e then
s, e = string.find(text, v.."%b():")
end
if s and e then
local s_row, s_col = node:start()
local e_row, e_col = node:end_()
-- ensure that our string indicies are relative to the line
s = s + s_col
e = e + s_col
ok, err = pcall(vim.api.nvim_buf_set_extmark, bufnr, todo_hl_ns, s_row, e, {
hl_mode = "replace",
hl_group = type.hlgroup,
end_col = e_col,
end_row = e_row
})
if not ok then
print("fg", s_row, e, e_col, e_row)
print("fg", err)
end
ok, err = pcall(vim.api.nvim_buf_set_extmark, bufnr, todo_hl_ns, s_row, s - 2, {
hl_mode = "replace",
hl_group = type.hlgroup.."BG",
end_col = e - 1,
end_row = s_row
})
if not ok then
print("bg", s_row, s - 2, e - 1, s_row)
print("bg", err)
end
ok, err = pcall(vim.api.nvim_buf_set_extmark, bufnr, todo_hl_ns, s_row, e - 1, {
hl_mode = "replace",
hl_group = type.hlgroup.."SIGN",
end_col = e,
end_row = s_row
})
if not ok then
print("sn", s_row, e - 1, e, s_row)
print("sn", err)
end
end
end
end
::continue::
end
end
end
end)
end
-- Source: 'runtime/lua/vim/_defaults.lua' in Neovim source
local function parse_osc11(x)
local r, g, b = x:match('^\027%]11;rgb:(%x+)/(%x+)/(%x+)$')
if not (r and g and b) then
local a
r, g, b, a = x:match('^\027%]11;rgba:(%x+)/(%x+)/(%x+)/(%x+)$')
if not (a and a:len() <= 4) then
return
end
end
if not (r and g and b) then
return
end
if not (r:len() <= 4 and g:len() <= 4 and b:len() <= 4) then
return
end
local parse_osc_hex = function(c)
return c:len() == 1 and (c..c) or c:sub(1, 2)
end
return '#'..parse_osc_hex(r)..parse_osc_hex(g)..parse_osc_hex(b)
end
local _termbg_init
--- taken from github.com/echasnovski/mini.misc modified to work for me
--- sets up terminal background synchronization which enables neovim to set the
--- background of the terminal it is running in
function M.setup_termbg_sync()
-- Handling `'\027]11;?\007'` response was added in Neovim 0.10
if vim.fn.has('nvim-0.10') == 0 then
vim.notify('`setup_termbg_sync()` requires Neovim>=0.10',
vim.log.levels.WARN)
end
-- Proceed only if there is a valid stdout to use
local has_stdout_tty = false
for _, ui in ipairs(vim.api.nvim_list_uis()) do
has_stdout_tty = has_stdout_tty or ui.stdout_tty
end
if not has_stdout_tty then return end
local augroup = vim.api.nvim_create_augroup('TermbgSync', {
clear = true,
})
local track_au_id, bad_responses, had_proper_response = nil, {}, false
local f = function(args)
-- Process proper response only once
if had_proper_response then
return
end
-- Neovim=0.10 uses string sequence as response, while Neovim>=0.11 sets it
-- in `sequence` table field
local seq = type(args.data) == 'table' and args.data.sequence or args.data
local ok, bg_init = pcall(parse_osc11, seq)
if not (ok and type(bg_init) == 'string') then
return table.insert(bad_responses, seq)
end
had_proper_response = true
pcall(vim.api.nvim_del_autocmd, track_au_id)
-- Set up sync
local sync = function()
local normal = vim.api.nvim_get_hl(0, {
name = "Normal",
create = false
})
if normal.bg == nil then
return
end
-- NOTE: use `io.stdout` instead of `io.write` to ensure correct target
-- Otherwise after `io.output(file); file:close()` there is an error
io.stdout:write(string.format('\027]11;#%06x\007', normal.bg))
end
vim.api.nvim_create_autocmd({ 'VimResume', 'ColorScheme' }, {
group = augroup,
callback = sync,
})
-- Set up reset to the color returned from the very first call
_termbg_init = _termbg_init or bg_init
local reset = function()
io.stdout:write('\027]11;'.._termbg_init..'\007')
end
vim.api.nvim_create_autocmd({ 'VimLeavePre', 'VimSuspend' }, {
group = augroup,
callback = reset,
})
-- Sync immediately
sync()
end
-- Ask about current background color and process the proper response.
-- NOTE: do not use `once = true` as Neovim itself triggers `TermResponse`
-- events during startup, so this should wait until the proper one.
track_au_id = vim.api.nvim_create_autocmd('TermResponse', {
group = augroup,
callback = f,
nested = true
})
io.stdout:write('\027]11;?\007')
vim.defer_fn(function()
if had_proper_response then
return
end
pcall(vim.api.nvim_del_augroup_by_id, augroup)
local bad_suffix = #bad_responses == 0 and '' or
(', only these: '..vim.inspect(bad_responses))
local msg =
"`setup_termbg_sync()` did not get proper response from terminal emulator"
..bad_suffix
vim.notify(msg, vim.log.levels.WARN)
end, 1000)
end
return M

View File

@@ -1,120 +0,0 @@
--- Stolen from: https://github.com/Wansmer/nvim-config/blob/main/lua/modules/foldtext.lua
--- modified for my use
---
---@module Foldtext
---Based on https://www.reddit.com/r/neovim/comments/16sqyjz/finally_we_can_have_highlighted_folds/
---Updated with vim.treesitter._fold.foldtext()
local function parse_line(linenr)
local bufnr = vim.api.nvim_get_current_buf()
local line = vim.api.nvim_buf_get_lines(bufnr, linenr - 1, linenr, false)[1]
if not line then
return nil
end
local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
if not ok then
return nil
end
local query = vim.treesitter.query.get(parser:lang(), "highlights")
if not query then
return nil
end
local tree = parser:parse({ linenr - 1, linenr })[1]
local result = {}
local line_pos = 0
for id, node, metadata in query:iter_captures(tree:root(), 0, linenr - 1, linenr) do
local name = query.captures[id]
local start_row, start_col, end_row, end_col = node:range()
local priority = tonumber(metadata.priority or vim.highlight.priorities.treesitter)
if start_row == linenr - 1 and end_row == linenr - 1 then
-- check for characters ignored by treesitter
if start_col > line_pos then
table.insert(result, {
line:sub(line_pos + 1, start_col),
{ { "Folded", priority } },
range = { line_pos, start_col },
})
end
line_pos = end_col
local text = line:sub(start_col + 1, end_col)
table.insert(result, { text, { { "@" .. name, priority } }, range = { start_col, end_col } })
end
end
local i = 1
while i <= #result do
-- find first capture that is not in current range and apply highlights on the way
local j = i + 1
while j <= #result and result[j].range[1] >= result[i].range[1] and result[j].range[2] <= result[i].range[2] do
for k, v in ipairs(result[i][2]) do
if not vim.tbl_contains(result[j][2], v) then
table.insert(result[j][2], k, v)
end
end
j = j + 1
end
-- remove the parent capture if it is split into children
if j > i + 1 then
table.remove(result, i)
else
-- highlights need to be sorted by priority, on equal prio, the deeper nested capture (earlier
-- in list) should be considered higher prio
if #result[i][2] > 1 then
table.sort(result[i][2], function(a, b)
return a[2] < b[2]
end)
end
result[i][2] = vim.tbl_map(function(tbl)
return tbl[1]
end, result[i][2])
result[i] = { result[i][1], result[i][2] }
i = i + 1
end
end
return result
end
--- create a string of highlighted text for folds
---@return table|string
local function HighlightedFoldtext()
local result = parse_line(vim.v.foldstart)
if not result then
return vim.fn.foldtext()
end
table.insert(result, {
" ... ",
"LspCodeLens",
})
local result2 = parse_line(vim.v.foldend)
if result2 then
local first = result2[1]
result2[1] = { vim.trim(first[1]), first[2] }
for _, item in ipairs(result2) do
table.insert(result, item)
end
end
table.insert(result, {
" "..(vim.v.foldend - vim.v.foldstart + 1).." Lines Folded ",
"LspCodeLens",
})
return result
end
return HighlightedFoldtext

54
lua/core/init.lua Normal file
View File

@@ -0,0 +1,54 @@
-- inspired by (and partially yoinked from): github.com/gonstoll/dotfiles
local notify = vim.notify
--- overidden version of vim.notify
---@param msg string message
---@param level vim.log.levels? log level
---@param opts table? options
---@diagnostic disable-next-line: duplicate-set-field
vim.notify = function(msg, level, opts)
notify(msg, level or vim.log.levels.INFO, opts or {
title = require("core.misc").appid
})
end
--- check if the given table contains an item, and return the key value pair if
--- it does
---@param self table table
---@param item any item to find
---@return boolean, [any, any]? found true if found
table.contains = function(self, item)
for k, v in pairs(self) do
if v == item then
return true, { k, v }
end
end
return false
end
local M = {
misc = require("core.misc"),
lsp = require("core.lsp"),
color = require("core.color"),
snippets = vim.fs.joinpath(vim.fn.stdpath("config"), "lua/core/snippets.lua"),
}
M.mason = {
--- Gets a path to a package in the Mason registry.
--- Prefer this to `get_package`, since the package might not always be
--- available yet and trigger errors.
---@param pkg string
---@param path? string
get_pkg_path = function(pkg, path)
pcall(require, "mason") -- make sure Mason is loaded. Will fail when
-- generating docs
local root = vim.env.MASON or vim.fs.joinpath(vim.fn.stdpath("data"),
"mason")
path = path or ""
return vim.fs.joinpath(root, "packages", pkg, path)
end
}
return M

68
lua/core/lsp/binds.lua Normal file
View File

@@ -0,0 +1,68 @@
local misc = require("core.misc")
local map, auto = misc.map, misc.auto
local function on_list(opts)
vim.fn.setqflist({}, "r", opts)
if #opts.items > 1 then
vim.cmd.copen()
-- get to the closest reference to the cursor (likely the one gr or gd was
-- called on)
--
-- TODO: switch this to use opts.idx?
local closest, distance = 1, false
for i, item in ipairs(opts.items) do
if item.filename and vim.fn.expand("%:p") == item.filename then
local lnum = vim.api.nvim_win_get_cursor(0)[1]
if item.lnum then
local new_distance = math.abs(lnum - item.lnum)
if not distance or new_distance < distance then
distance = new_distance
closest = i
end
end
end
vim.cmd(".cc! "..closest)
end
else
vim.cmd(".cc! 1")
end
end
-- disable the default keybinds (they're bad)
for _, bind in ipairs({ "grn", "gra", "gri", "grr" }) do
pcall(vim.keymap.del, "n", bind)
end
local group = misc.augroup("lsp.bind")
auto("LspAttach", {
group = group,
callback = function(ctx)
local list_opts = { on_list = on_list }
local opts = { buffer = ctx.buf, nowait = true }
-- LSP actions
map("n", "K", vim.lsp.buf.hover, opts)
map("n", "gd", function() vim.lsp.buf.definition(list_opts) end, opts)
map("n", "gD", function() vim.lsp.buf.declaration(list_opts) end, opts)
map("n", "gi", function() vim.lsp.buf.implementation(list_opts) end, opts)
map("n", "gy", function() vim.lsp.buf.type_definition(list_opts) end, opts)
map("n", "gr", function() vim.lsp.buf.references(nil, list_opts) end, opts)
map("n", "<S-Tab>", vim.lsp.buf.signature_help, opts)
map("n", "<leader>r", vim.lsp.buf.rename, opts)
map("n", "gA", vim.lsp.buf.code_action, opts)
-- Diagnostics
map("n", "[d", function()
vim.diagnostic.jump({ count = -1 })
end, opts)
map("n", "]d", function()
vim.diagnostic.jump({ count = 1 })
end, opts)
map("n", "gb", vim.diagnostic.setqflist, opts)
-- formatting
map("n", "<leader>c", vim.lsp.buf.format)
end
})

201
lua/core/lsp/completion.lua Normal file
View File

@@ -0,0 +1,201 @@
-- My neovim autocomplete setup.
-- partially stolen from https://github.com/glepnir/nvim
--
-- To make this work nicely you're gonna want a solid snippet setup, for me this
-- is luasnip. If you too would like to use luasnip just set vim.snippet.expand
-- to luasnip.lsp_expand
--- add char to list of triggerable chars
---@param list table list of chars
---@param char number|string char to add
local function add_to_client(list, char)
local c
if type(char) == "string" then
c = char
elseif type(char) == "number" then
c = string.char(char)
end
if not table.contains(list, c) then
table.insert(list, c)
end
end
-- make sure we can add autos
local misc = require("core.misc")
local auto = misc.auto
local completion_group = misc.augroup("lsp.completion")
-- Configure the lsp completion menu. In addition to setting up lsp completion
-- this also styles it to look nice.
auto("LspAttach", {
group = completion_group,
callback = function(ctx)
local client = vim.lsp.get_client_by_id(ctx.data.client_id)
if not client or not client:supports_method("textDocument/completion") then
return
end
-- Make completion menu appear whenever you type something.
local c = client.server_capabilities.completionProvider.triggerCharacters
if c then
for i = 32, 126 do
add_to_client(c, string.char(i))
end
end
vim.lsp.completion.enable(true, client.id, ctx.buf, {
autotrigger = true,
convert = function(item)
local kind = vim.lsp.protocol.CompletionItemKind[item.kind] or 'u'
return {
-- in the future if we ever get the ability to highlight specific
-- entries in the pummenu I'd like to add treesitter highlighting to
-- the entries
abbr = item.label:gsub('%b()', ''),
kind = kind:sub(1, 1):lower(),
menu = ''
}
end
})
end
})
-- attempt to style the completion documentation popup
auto("CompleteChanged", {
group = completion_group,
callback = function()
local info = vim.fn.complete_info({ "selected" })
if info.preview_bufnr and vim.bo[info.preview_bufnr].filetype == "" then
vim.bo[info.preview_bufnr].filetype = "markdown"
vim.wo[info.preview_winid].conceallevel = 2
vim.wo[info.preview_winid].concealcursor = "niv"
end
end
})
-- Add snippet support to lsp clients who don't do it for us. Currently this
-- only supports function calls.
--
-- there's a very good chance this will give us problems for languages who do
-- not follow the c-style function call style. I've only gotten this working in
-- lua thus far.
auto("CompleteDonePre", {
group = completion_group,
callback = function()
local item = vim.tbl_get(
vim.v.completed_item,
"user_data",
"nvim",
"lsp",
"completion_item"
)
if not item then
return
end
-- TODO: we need to truncate the item.label to ensure that we don't
-- duplicate any text below is my attempt to start work on it:
--
-- local cursor = vim.api.nvim_win_get_cursor(0)
-- local line = vim.api.nvim_buf_get_lines(
-- vim.api.nvim_win_get_buf(0),
-- cursor[1] - 1,
-- cursor[1],
-- false
-- )[1]
-- item.label = string.gsub(item.label, string.sub(line, cursor[2] + 1), "")
-- item.insertText = item.label
-- if the item isn't a snippet then we might want to create a snippet
if item.label and item.kind and item.insertTextFormat then
if item.insertTextFormat ~= 2 and item.kind == 3 then
local n_complete_item = vim.v.completed_item
-- attempt to modify the function args to create a snippet
local paren1 = string.find(item.label, "%(")
if not paren1 then
return
end
-- try and create a snippet from a function call
local i = 1
local text = ""
local l_paren = paren1
local next, is_paren
while not is_paren do
-- find the next token
next = string.find(item.label, "%,", l_paren + 1)
if not next then
next = string.find(item.label, "%)", l_paren + 1)
if not next then
return
end
is_paren = true
end
-- concat text
if text == "" then
-- start the snippet
text = string.sub(item.label, 0, l_paren).."${"..i..":"
else
-- continue the snippet
text = text.."}, ".."${"..i..":"
end
do -- add the content of the argument to the snippet
-- we need to account for cases in which the developer uses spaces
-- between their commas and code
local is_space = string.sub(item.label, l_paren + 1, l_paren + 1)
local plus = is_space == " " and 2 or 1
text = text..string.sub(item.label, l_paren + plus, next - 1)
end
-- increment
l_paren = next
i = i + 1
end
-- end the snippet
text = text.."})"
n_complete_item.user_data.nvim.lsp.completion_item.insertText = text
n_complete_item.user_data.nvim.lsp.completion_item.insertTextFormat = 2
n_complete_item.user_data.nvim.lsp.completion_item.kind = 3
vim.v.completed_item = n_complete_item
end
end
end
})
-- show the signature help when inside a function call
auto("CompleteDone", {
group = completion_group,
callback = function(ctx)
-- make sure there's an lsp client, and make sure the lsp client supports
-- textDocument/signatureHelp
local client = vim.lsp.get_clients({ bufnr = ctx.buf })[1]
if not client or not client:supports_method("textDocument/signatureHelp") then
return
end
-- show the signature help
local item = vim.tbl_get(
vim.v.completed_item,
"user_data",
"nvim",
"lsp",
"completion_item"
)
if not item then
return
end
-- show signature help when the completion is a function
if item.kind == 3 and (item.textEdit ~= nil or item.insertText ~= nil) then
-- for some reason calling vim.schedule didn't work for me
vim.defer_fn(vim.lsp.buf.signature_help, 100)
end
end,
desc = "Auto show signature help when completion is done"
})

View File

@@ -1,102 +0,0 @@
local misc = require("core.misc")
local map, auto = misc.map, misc.auto
local M = {}
-- TODO: find a way to make the qflist current item be the one closest to the
-- cursor whenever we open it
local function on_list(opts)
vim.fn.setqflist({}, "r", opts)
if #opts.items > 1 then
vim.cmd.copen()
end
vim.cmd(".cc! 1")
end
---@type vim.lsp.util.open_floating_preview.Opts
local popup_opts = {
border = vim.g.border_style
}
---@type vim.lsp.buf.hover.Opts
---@diagnostic disable-next-line: assign-type-mismatch
local hover_opts = vim.tbl_deep_extend("force", popup_opts, {})
---@type vim.lsp.buf.signature_help.Opts
---@diagnostic disable-next-line: assign-type-mismatch
local signature_opts = vim.tbl_deep_extend("force", popup_opts, {})
---@type vim.lsp.ListOpts
local list_opts = {
on_list = on_list
}
---@type vim.lsp.LocationOpts
---@diagnostic disable-next-line: assign-type-mismatch
local location_opts = vim.tbl_deep_extend("force", list_opts, {})
-- disable the default keybinds (they're bad)
for _, bind in ipairs({ "grn", "gra", "gri", "grr" }) do
pcall(vim.keymap.del, "n", bind)
end
--- setup basic options on lsp attach
---@param bufnr number buffer number
local function attach(bufnr)
local opts = { buffer = bufnr, nowait = true }
-- LSP actions
map("n", "K", function() vim.lsp.buf.hover(hover_opts) end, opts)
map("n", "gd", function() vim.lsp.buf.definition(location_opts) end, opts)
map("n", "gD", function() vim.lsp.buf.declaration(location_opts) end, opts)
map("n", "gi", function() vim.lsp.buf.implementation(location_opts) end, opts)
map("n", "gy", function() vim.lsp.buf.type_definition(location_opts) end, opts)
map("n", "gr", function() vim.lsp.buf.references(nil, list_opts) end, opts)
map("n", "<S-Tab>", function() vim.lsp.buf.signature_help(signature_opts) end, opts)
map("n", { "<leader>r", "<F2>" }, vim.lsp.buf.rename, opts)
map("n", { "gA", "<F4>" }, vim.lsp.buf.code_action, {
buffer = bufnr,
desc = "check code actions",
})
-- Diagnostics
map("n", "[d", function()
vim.diagnostic.jump({ count = -1 })
end, opts)
map("n", "]d", function()
vim.diagnostic.jump({ count = 1 })
end, opts)
end
function M.setup()
vim.diagnostic.config {
virtual_text = false,
virtual_lines = {
only_current_line = true
},
update_in_insert = false,
underline = true,
severity_sort = true,
signs = {
text = {
[vim.diagnostic.severity.ERROR] = "x",
[vim.diagnostic.severity.WARN] = "!",
[vim.diagnostic.severity.INFO] = "i",
[vim.diagnostic.severity.HINT] = "h",
}
}
}
-- set default capabilities and attach function
vim.lsp.config['*'] = {
capabilities = vim.lsp.protocol.make_client_capabilities()
}
-- make my attach function always run
auto("LspAttach", {
callback = function(event)
attach(event.buf)
end
})
end
return M

31
lua/core/lsp/init.lua Normal file
View File

@@ -0,0 +1,31 @@
local M = {}
--- setup vim lsp options
function M.setup()
-- confgiure lsp
vim.diagnostic.config {
virtual_lines = {
current_line = true
},
severity_sort = true,
signs = {
text = {
[vim.diagnostic.severity.ERROR] = "x",
[vim.diagnostic.severity.WARN] = "!",
[vim.diagnostic.severity.INFO] = "i",
[vim.diagnostic.severity.HINT] = "h"
}
}
}
-- set default capabilities and attach function
vim.lsp.config['*'] = {
capabilities = vim.lsp.protocol.make_client_capabilities()
}
require("core.lsp.binds")
require("core.lsp.completion")
require("core.lsp.wtf")
end
return M

37
lua/core/lsp/wtf.lua Normal file
View File

@@ -0,0 +1,37 @@
-- wtf why does the language server protocol have these features?
-- partially stolen from https://github.com/glepnir/nvim
local misc = require("core.misc")
local auto = misc.auto
local wtf_group = misc.augroup("lsp.wtf")
auto('LspAttach', {
group = wtf_group,
callback = function(ctx)
local client = vim.lsp.get_client_by_id(ctx.data.client_id)
if not client then
return
end
-- highlight color codes via lsp (supported by cssls)
-- #ff0000
if client:supports_method('textDocument/documentColor') then
pcall(vim.lsp.document_color.enable, true, ctx.buf)
end
-- enable linked editing this allows lsps to modify things like html tags
-- for example when you change <p> to <a> </p> will be changed by the lsp
-- to </a>
if client:supports_method('textDocument/linkedEditingRange') then
pcall(vim.lsp.linked_editing_range.enable, true, { client_id = client.id })
end
-- disabled for now cause I don't like it
-- -- enable type formatting which allows lsps to modify text while you're
-- -- typing for example if you insert {} in a string in python basedpyright
-- -- will change the string to a format string
-- if client:supports_method('textDocument/onTypeFormatting') then
-- pcall(vim.lsp.on_type_formatting.enable, true, { client_id = client.id })
-- end
end
})

View File

@@ -3,32 +3,9 @@ local M = {}
--- vim.notify title
M.appid = "Nvim Config"
--- safe version of require
---@param fn string name of file to include
---@return any
function M.include(fn)
local ok, r = pcall(require, fn)
if not ok then
vim.notify("Could not find '"..fn.."': "..r, vim.log.levels.WARN, { title = M.appid })
return ok
end
return r
end
--- loop through files in directory
---@param path string absolute path of directory to be looped through
---@param body function function to use on every recursion of the loop
---@param ext string? desired file extension of files to be returned from directory
function M.loopf(path, body, ext)
ext = ext and [[v:val =~ '\.]]..ext..[[$']] or nil
for _, file in ipairs(vim.fn.readdir(path, ext)) do
body(file)
end
end
--- extend vim.kemap.set
---@param mode string|table mode for the keymap
---@param bind string|table keymap
---@param bind string keymap
---@param cmd function|string command to run
---@param opts vim.keymap.set.Opts? keymap options
function M.map(mode, bind, cmd, opts)
@@ -47,19 +24,12 @@ function M.map(mode, bind, cmd, opts)
end
end
-- define the keybinds
if type(bind) == "table" then
for i in pairs(bind) do
vim.keymap.set(mode, bind[i], cmd, opts)
end
elseif type(bind) == "string" then
vim.keymap.set(mode, bind, cmd, opts)
end
vim.keymap.set(mode, bind, cmd, opts)
end
--- a small map wrapper to easily create local buffer mappings
---@param mode string|table mode for the keymap
---@param bind string|table keymap
---@param bind string keymap
---@param cmd function|string command to run
---@param opts table? keymap options
function M.map_local(mode, bind, cmd, opts)
@@ -68,123 +38,36 @@ function M.map_local(mode, bind, cmd, opts)
M.map(mode, bind, cmd, opts)
end
--- extend vim.api.nvim_create_autocmd
---@param event string|table event or events
---@param opts vim.api.keyset.create_autocmd options
function M.auto(event, opts)
vim.api.nvim_create_autocmd(event, opts)
end
--- shorten vim.api.nvim_create_autocmd call
M.auto = vim.api.nvim_create_autocmd
--- extend auto group
---@param name string name of the autogroup
---@param opts table? table of options
---@return integer
function M.augroup(name, opts)
opts = opts or {}
vim.api.nvim_create_augroup(name, opts)
return vim.api.nvim_create_augroup(name, opts)
end
--- extend vim.api.nvim_set_hl
---@param group string|table highlight group
---@param opts table highlight options
---@param namespace? number highlight space
function M.highlight(group, opts, namespace)
namespace = namespace or 0
if type(group) == "table" then
for i in pairs(group) do
vim.api.nvim_set_hl(namespace, group[i], opts)
end
elseif type(group) == "string" then
vim.api.nvim_set_hl(namespace, group, opts)
end
end
--- copy highlight group
---@param hlgroup string highlight group to copy
---@param namespace? number highlight space
---@return table
function M.cpyhl(hlgroup, namespace)
namespace = namespace or 0
local ok, hl = pcall(vim.api.nvim_get_hl, namespace, {
name = hlgroup,
create = false
})
if not ok then
return {}
end
for _, key in pairs({"foreground", "background", "special"}) do
if hl[key] then
hl[key] = string.format("#%06x", hl[key])
end
end
return hl
end
--- highlight something with some highlight group for a certain amount of time
---@param opts table? options
--- example:
--- ```lua
--- {
--- -- highlight group to use
--- hl = "IncSearch",
---
--- -- # of ms to stay highlighted for
--- timeout = 250,
---
--- -- line to highlight
--- line = vim.api.nvim_win_get_cursor(0)[1],
---
--- -- range to highlight if this is used line will be ignored
--- range = {
--- { 0, 0 },
--- { 0, 0 }
--- }
--- }
--- ```
--- opts is optional and if empty will simply highlight the current line for
--- 250ms using IncSearch as the highlight group
function M.timeout_highlight(opts)
opts = opts or {}
opts.hl = opts.hl or "IncSearch"
opts.timeout = opts.timeout or 250
if type(opts.range) ~= "table" or type(opts.range[1]) ~= "table" or
type(opts.range[2]) ~= "table" then
local curline = opts.line or vim.api.nvim_win_get_cursor(0)[1]
opts.range = {
{ curline - 1, 0 },
{ curline, 0 }
}
end
local namespaceid = vim.api.nvim_create_namespace("timeout_highlight")
-- timer code was happily stolen from neovim/runtime/lua/vim/highlight.lua :)
local timer, timer_cancel
if not vim.fn.has("nvim-0.11") then
if timer then
timer:close()
assert(timer_cancel)
timer_cancel()
end
end
-- set the highlight
vim.highlight.range(0, namespaceid, opts.hl, opts.range[1], opts.range[2], {
opts.timeout,
})
if not vim.fn.has("nvim-0.11") then
timer_cancel = function()
timer = nil
timer_cancel = nil
pcall(vim.api.nvim_buf_clear_namespace, 0, namespaceid, 0, -1)
pcall(vim.api.nvim_win_remove_ns, 0, namespaceid)
end
timer = vim.defer_fn(timer_cancel, opts.timeout)
end
--- Make an action lazy. This is mostly useful for keybinds which do a lot and
--- you want to make sure the screen doesn't flash
---@param txt string|function the action
---@return string|function lazified
---@nodiscard
function M.lz(txt)
if type(txt) == "string" then
return "<cmd>se lz<CR>"..txt.."<cmd>se lz!<CR>"
elseif type(txt) == "function" then
return function()
vim.cmd.se("lz")
-- gotta make sure we can always unset lz
pcall(txt)
vim.cmd.se("lz!")
end
else
return txt
end
end
return M

View File

@@ -21,3 +21,7 @@ conds_expand = require("luasnip.extras.conditions.expand")
ts_postfix = require("luasnip.extras.treesitter_postfix").treesitter_postfix
postfix = require("luasnip.extras.postfix").postfix
ms = ls.multi_snippet
file_name = function(_, _, _)
return vim.fn.expand("%:t:r")
end

View File

@@ -1,3 +0,0 @@
function file_name(_, _, _)
return vim.fn.expand("%:t:r")
end

View File

@@ -1,46 +1,4 @@
require("core.snippets.shorthands")
--- create a decleration of a function from it's definition using treesitter
---@param func string
---@return string|nil
local function c_func(func)
local tree = vim.treesitter.get_parser():parse()[1]:root()
local q = vim.treesitter.query.parse("c", "(function_definition) @f")
local matches = q:iter_matches(tree, 0)
vim.treesitter.query.parse("c", "(identifier) @i")
local m = q:iter_matches(matches, 0)
print(vim.treesitter.get_node_text(m:child(), 0))
if true then
return
end
for _, match in matches do
for _, node in pairs(match) do
if not node or not node:child(1) or not node:child(1):child() then
-- print(vim.treesitter.get_node_text(node:child(1):child(), 0))
goto continue
end
if vim.treesitter.get_node_text(node:child(1):child(), 0) == func then
local def = ""
for i = 0, node:child_count() - 2 do
def = def..vim.treesitter.get_node_text(node:child(i), 0)
if i < node:child_count() - 2 then
def = def.." "
end
end
-- Print the function name using node text
return def:gsub("\n", "")
end
::continue::
end
end
return nil
end
dofile(core.snippets)
return {
-- function snippet
@@ -82,19 +40,4 @@ return {
i(0),
t({ "", "}" })
}),
-- create decleration based on existing c function
postfix(".d", {
f(function(_, parent)
local r = c_func(parent.snippet.env.POSTFIX_MATCH)
if not r then
return parent.snippet.env.POSTFIX_MATCH
end
local bidx, aidx = r:find(parent.snippet.env.POSTFIX_MATCH)
return r:sub(1, bidx - 1)..
parent.snippet.env.POSTFIX_MATCH..
r:sub(aidx + 1)..";"
end, {})
})
}

View File

@@ -1,5 +1,4 @@
require("core.snippets.shorthands")
require("core.snippets.functions")
dofile(core.snippets)
--- shortcut to choose between java access modifiers
---@param idx number index of the node

19
lua/snippets/lua.lua Normal file
View File

@@ -0,0 +1,19 @@
dofile(core.snippets)
return {
-- print inspect text
s("inspect", {
t("print(vim.inspect("),
i(0),
t("))")
}),
-- print inspect text
s("M", {
i(1, "M");
t({ " = {}", "" }),
i(0),
t({ "", "return " }),
r(1)
})
}

View File

@@ -1,25 +0,0 @@
require("core.snippets.shorthands")
require("core.snippets.functions")
return {
-- header level 1, usually this has the same name as the file
s("h1", {
t("* "),
c(1, {
f(file_name, {}),
i(1, "header")
})
}),
-- link snippet
s("link", {
t("{"),
c(1, {
sn(nil, { t({":$/"}), i(1, "path to file"), t(":") }),
i(1, "https://example.com")
}),
t("}["),
i(2, "description"),
t("]")
})
}

View File

@@ -1,4 +1,4 @@
require("core.snippets.shorthands")
dofile(core.snippets)
return {
-- translate snippet

View File

@@ -1,4 +1,4 @@
require("core.snippets.shorthands")
dofile(core.snippets)
return {
s("php", {

108
lua/snippets/python.lua Normal file
View File

@@ -0,0 +1,108 @@
dofile(core.snippets)
--- convert snake to pascal case
---@return string classname
local function py_file_name()
local fn = file_name()
local new = ""
-- convert snake to pascal case
for i = 1, #fn do
if i == 1 then
new = fn:sub(1, 1):upper()
elseif fn:sub(i - 1, i - 1) == "_" then
new = new..fn:sub(i, i):upper()
elseif fn:sub(i, i) ~= "_" then
new = new..fn:sub(i, i)
end
end
return new
end
--- find the current class and return its name if not available defaults to
--- the file name
---@return string
local function python_class()
-- set the starting node to the node under the cursor
local node = require("nvim-treesitter.ts_utils").get_node_at_cursor()
while node do
-- check if we're in a class
if node:type() == "class_definition" then
-- find the class name in the class declaration and return it
for i = 0, node:child_count() - 1 do
local child = node:child(i)
if child and child:type() == "identifier" then
return vim.treesitter.get_node_text(child, 0)
end
end
end
node = node:parent()
end
-- if no class can be found default to the current file name
return file_name()
end
return {
s("class", {
t("class "),
c(1, {
f(py_file_name, {}),
i(0, "MyClass")
}),
c(2, {
t(""),
sn(nil, {
t("("),
i(1, "object"),
t(")")
})
}),
t({ ": ", "\t" }),
i(0)
}),
s({ trig = [[fn\|def\|constr\|init]], trigEngine = "vim" }, {
t("def "),
d(1, function(_, snip)
if snip.trigger == "constr" or snip.trigger == "init" then
print(python_class())
return sn(nil, {
t("__init__")
})
else
return sn(nil, {
i(1, "myFunc")
})
end
end, {}),
t("("),
d(2, function(_, snip)
-- if this is a constructor or a function in a class then we need to put
-- self as the first argument
if snip.trigger == "constr" or snip.trigger == "init"
or python_class() ~= file_name() then
return sn(nil, {
t("self")
})
else
return sn(nil, {})
end
end, {}),
i(3),
t(")"),
t(" -> "),
i(4, "None"),
t({ ":", "\t" }),
i(0, "pass")
}),
s("main", {
t({ "def main() -> None:", "\t" }),
i(0, 'print("hello world")'),
t({ "", "", 'if __name__ == "__main__":', "\tmain()" })
})
}

View File

@@ -1,5 +1,4 @@
require("core.snippets.shorthands")
require("core.snippets.functions")
dofile(core.snippets)
return {
-- document snippet