Compare commits

30 Commits

Author SHA1 Message Date
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 1526 additions and 1612 deletions

View File

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

View File

@@ -1,6 +1,5 @@
local misc = require('core.misc') local map_local, lz = core.misc.map_local, core.misc.lz
local map_local = misc.map_local
-- sort #includes <> (very jank) -- sort #includes <> (very jank)
-- TODO: rewrite in a semi-sane way -- 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,21 @@
local misc = require("core.misc") local map, auto = core.misc.map, core.misc.auto
local map, auto = misc.map, misc.auto
local jdtls = require("jdtls") local ok, jdtls = pcall(require, "jdtls")
local jdtls_install = vim.fs.joinpath(vim.fn.stdpath('data'), if not ok then
"/mason/packages/jdtls") vim.notify("jdtls not loaded, can't setup jdtls lsp or dap")
local java_dap_install = vim.fs.joinpath(vim.fn.stdpath('data'), return
"/mason/packages/java-debug-adapter") 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 -- make sure to check if things with 💀 need updating
local config = { local config = {
cmd = { cmd = {
"/usr/lib/jvm/openjdk21/bin/java", -- 💀 "/usr/lib/jvm/openjdk21/bin/java", -- 💀
"-jar", vim.fn.glob(jdtls_install.."/plugins/org.eclipse.equinox.launcher_*.jar"), -- 💀 "-jar",
"-configuration", jdtls_install.."/config_linux", 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", "-data", vim.fn.stdpath("cache").."/nvim-jdtls",
"--add-modules=ALL-SYSTEM", "--add-modules=ALL-SYSTEM",
@@ -23,7 +26,7 @@ local config = {
"-Dlog.level=ALL", "-Dlog.level=ALL",
"-Dlog.protocol=true", "-Dlog.protocol=true",
"-Dosgi.bundles.defaultStartLevel=4", "-Dosgi.bundles.defaultStartLevel=4",
"-Xmx1G", "-Xmx1G"
}, },
root_dir = vim.fs.dirname(vim.fs.find({ root_dir = vim.fs.dirname(vim.fs.find({
@@ -48,6 +51,7 @@ local config = {
map("x", "crc", function() jdtls.extract_constant(true) end, opts) map("x", "crc", function() jdtls.extract_constant(true) end, opts)
map("x", "crm", function() jdtls.extract_method(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) pcall(vim.lsp.codelens.refresh)
auto("BufWritePost", { auto("BufWritePost", {
buffer = bufnr, buffer = bufnr,
@@ -58,31 +62,36 @@ local config = {
}) })
-- setup nvim-dap -- 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" }) jdtls.setup_dap({ hotcodereplace = "auto" })
require("jdtls.dap").setup_dap_main_class_configs()
end, end,
-- don"t print out status messages
handlers = {
["language/status"] = function() end
},
init_options = { init_options = {
bundles = { bundles = {
vim.fs.joinpath(java_dap_install, 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) true)
) )
} }
},
-- don't print out status messages
handlers = {
["language/status"] = function() end
} }
} }
-- generate the path to the java file(s) -- generate the path to the java file(s)
---@type string|nil ---@type string?
local cache_path = vim.fs.joinpath(vim.fn.stdpath("cache"), "/JavaVersion.class") local cache_path = vim.fs.joinpath(vim.fn.stdpath("cache"),
---@type string|nil "/JavaVersion.class")
local src_path = vim.fs.joinpath(vim.fn.stdpath("config"), "/extras/JavaVersion.java") ---@type string?
local src_path = vim.fs.joinpath(vim.fn.stdpath("config"),
"/extras/JavaVersion.java")
-- if either path is invalid -- if either path is invalid
if not cache_path or not src_path then if not cache_path or not src_path then
@@ -92,19 +101,18 @@ end
--- build a cache of the JavaVersion code --- build a cache of the JavaVersion code
local function build_cache() local function build_cache()
-- check if we have javac -- check if we have javac
vim.system({ "javac" }, {}, function(out) if vim.fn.executable("javac") ~= 1 then
if out.code == 127 then
cache_path = nil cache_path = nil
return return
end end
-- compile our code -- compile our code
vim.system({ "javac", src_path, "-d", vim.fn.stdpath("cache") }, {}, function(out) vim.system({ "javac", src_path, "-d", vim.fn.stdpath("cache"), }, {},
function(out)
if out.code ~= 0 then if out.code ~= 0 then
cache_path = nil cache_path = nil
end end
end) end)
end)
end end
-- check if we have a compiled version of JavaVersion -- check if we have a compiled version of JavaVersion
@@ -130,27 +138,23 @@ local function version_check()
if out.code ~= 0 then if out.code ~= 0 then
vim.notify(string.format( vim.notify(string.format(
"java version check failed: exit code %s", out.code), "java version check failed: exit code %s", out.code),
vim.log.levels.ERROR, { title = misc.appid }) vim.log.levels.ERROR)
vim.notify(string.format( vim.notify(string.format(
"%s", vim.inspect(out.stdout)), "%s", vim.inspect(out.stdout)), vim.log.levels.ERROR)
vim.log.levels.ERROR, { title = misc.appid })
return false return false
elseif not v then elseif not v then
vim.notify("no java version info found", vim.log.levels.ERROR, vim.notify("no java version info found", vim.log.levels.ERROR)
{ title = misc.appid })
return false return false
elseif v.major < 21 then elseif v.major < 21 then
vim.notify(string.format( vim.notify(string.format(
"java version %s < 21.0.0 Cannot run jdtls, bailing out", "java version %s < 21.0.0 Cannot run jdtls, bailing out",
v[1] .. "." .. v[2] .. "." .. v[3]), v[1].."."..v[2].."."..v[3]), vim.log.levels.ERROR)
vim.log.levels.ERROR, { title = misc.appid })
return false return false
end end
return true return true
end end
-- start the jdtls with dap! -- start the jdtls with dap!
if not version_check() then if not version_check() then
return return

View File

@@ -1,9 +1,8 @@
local misc = require("core.misc") local map_local = core.misc.map_local
local map_local = misc.map_local
map_local("n", "h", "-", { noremap = false, remap = true }) -- Go up a directory 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", "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 map_local("n", "P", "<C-w>z", { noremap = false, remap = true }) -- Close preview window
-- Close netrw only if it isn't the last window -- Close netrw only if it isn't the last window
@@ -16,5 +15,5 @@ end)
-- change neovim root -- change neovim root
map_local("n", "rt", function() map_local("n", "rt", function()
vim.api.nvim_set_current_dir(vim.b.netrw_curdir) 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) end)

View File

@@ -1,9 +0,0 @@
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,
}

View File

@@ -1,12 +1,4 @@
local map = require("core.misc").map
return { return {
on_attach = function(_, bufnr)
-- add some clangd specific mappings
local opts = { buffer = bufnr }
map("n", "<leader>o", "<cmd>ClangdSwitchSourceHeader<CR>", opts)
end,
cmd = { cmd = {
"clangd", "clangd",
"--background-index", "--background-index",
@@ -21,7 +13,7 @@ return {
usePlaceholders = true, usePlaceholders = true,
clangdFileStatus = true, clangdFileStatus = true,
fallback_flags = { 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 enable = false
}, },
workspace = { workspace = {
checkThirdParty = true, checkThirdParty = "ApplyInMemory",
library = { library = {
vim.env.VIMRUNTIME vim.env.VIMRUNTIME,
"${3rd}/luv/library"
} }
} }
} }
}, },
root_markers = { ".luarc.json", ".luarc.jsonc", ".luacheckrc", ".stylua.toml", root_markers = { ".luarc.json", ".luarc.jsonc", ".luacheckrc", ".stylua.toml",
"stylua.toml", "selene.toml", "selene.yml", "README.md" } "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 -- load core utilities
-- again _G.core = require("core")
-- enable performance stuff -- enable performance stuff
if vim.fn.has("nvim-0.9") == true then vim.loader.enable()
vim.loader.enable()
end -- load user config
require("conf")
-- setup lsp stuff
core.lsp.setup()
-- bootstrap plugin manager -- bootstrap plugin manager
local path = vim.fn.stdpath("data").."/site/pack/deps/opt/dep" local path = vim.fn.stdpath("data").."/site/pack/deps/opt/dep"
if vim.fn.empty(vim.fn.glob(path)) > 0 then if not vim.uv.fs_stat(path) then
vim.fn.system({ "git", "clone", "--depth=1", "https://git.squi.bid/dep", path }) vim.fn.system({ "git", "clone", "--depth=1", "https://git.squi.bid/squibid/dep",
"--branch=lazy", path })
end end
vim.opt.rtp:prepend(path)
vim.cmd("packadd dep") vim.cmd("packadd dep")
_G.dep_short = require("dep.lazy.loader.short")
-- 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
-- load plugins -- load plugins
require("dep") { require("dep") {
{ "squibid/dep", { "squibid/dep",
url = "https://git.squi.bid/dep", url = "https://git.squi.bid/squibid/dep",
branch = "dev" branch = "lazy"
}, },
load = function() modules = {
-- aquire all plugin specs prefix = "conf.plugins"
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
} }

View File

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

View File

@@ -1,62 +1,76 @@
local misc = require("core.misc") local map, lz = core.misc.map, core.misc.lz
local map = misc.map
--- 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 binds
vim.g.mapleader = " " -- set leader key vim.g.mapleader = " " -- set leader key
map("x", "<leader>p", [["_dP]], { desc = "Greatest remap of all time." }) map("x", "<leader>p", [["_dP]], { desc = "Greatest remap of all time." })
map("n", "<esc>", ":nohlsearch<Bar>:echo<CR>", { desc = "Clear search." }) map("n", "<esc>", "<cmd>noh<Bar>:ec<CR>", { desc = "Clear search." })
-- move selected text up/down map("n", "<leader>a", lz "<cmd>e #<CR>zz", { desc = "swap to alt file" })
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." })
-- the cursor STAYS IN THE MIDDLE -- the cursor STAYS IN THE MIDDLE
map("n", "<S-j>", "mzJ`z<cmd>delm z<CR>") -- when combining lines map("n", "<S-j>", lz "mzJ`z<cmd>delm z<CR>") -- when combining lines
map("n", "n", "nzzzv") -- when searching map("n", "n", lz "nzzzv") -- when searching
map("n", "N", "Nzzzv") map("n", "N", lz "Nzzzv")
map("n", "<C-d>", "<C-d>zzzv") -- half page jumping map("n", "<C-d>", lz "<C-d>zz") -- half page jumping
map("n", "<C-u>", "<C-u>zzzv") 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>") -- trigger completion menu
-- (stolen from https://gist.github.com/MariaSolOs/2e44a86f569323c478e5a078d0cf98cc)
map("n", "<leader>x", function() -- execute order 111 map("i", "<C-n>", function()
local fn = vim.fn.expand("%:p") -- if the completion menu is already visible just go to the next item
if vim.fn.getftype(fn) == "file" then if vim.fn.pumvisible() ~= 0 then
local perm = vim.fn.getfperm(fn) feedkeys("<C-n>")
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 else
vim.notify("Add executable flags", vim.log.levels.INFO, { title = misc.appid }) if #vim.lsp.get_clients({ bufnr = 0 }) > 0 then
vim.fn.setfperm(fn, string.sub(fn, 1, 2).."x"..string.sub(fn, 4, 5).."x"..string.sub(fn, 7, 8).."x") vim.lsp.completion.get()
end
else else
vim.notify("File doesn't exist", vim.log.levels.INFO, { title = misc.appid }) if vim.bo.omnifunc == "" then
feedkeys("<C-x><C-n>")
else
feedkeys("<C-x><C-o>")
end 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
end)
if vim.v.count > 0 then
spell_on_choice(nil, vim.v.count)
return
end end
local cword = vim.fn.expand("<cword>") end, { desc = "Trigger/select next completion" })
local prompt = "Change "..vim.inspect(cword).." to:" map("i", "<CR>", function()
vim.ui.select(vim.fn.spellsuggest(cword, vim.o.lines), { prompt = prompt }, spell_on_choice) if vim.fn.pumvisible() ~= 0 then
end, { desc = "Shows spelling suggestions" }) 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 -- quickfix
map("n", "<M-j>", "<cmd>cnext<CR>") map("n", "<M-j>", lz "<cmd>cnext<CR>zz", { desc = "qf next" })
map("n", "<M-k>", "<cmd>cprev<CR>") map("n", "<M-k>", lz "<cmd>cprev<CR>zz", { desc = "qf prev" })
map("n", "<M-c>", "<cmd>cclose<CR>") 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 -- man pages
map("n", "<C-k>", "<cmd>Man<CR>") 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,144 +1,78 @@
local misc = require("core.misc") -- make .h files default to c code
local auto = misc.auto vim.filetype.add({ extension = { h = "c", }, })
-- color stuff
if vim.fn.has("termguicolors") then
vim.opt.termguicolors = true
end
vim.opt.laststatus = 3
-- numbers -- numbers
vim.opt.number = true vim.o.nu = true
vim.opt.relativenumber = true vim.o.rnu = true
-- buffer -- buffer
vim.opt.scrolloff = 5 vim.o.lbr = true -- fix where line is wraped
vim.opt.wrap = true -- wraping lines vim.o.cul = true
vim.opt.linebreak = true -- fix where line is wraped vim.o.cc = "80"
vim.opt.cursorline = true
vim.opt.colorcolumn = { 80 }
-- indents + tabs -- indents + tabs
local tabwidth = 2 local tabwidth = 2
vim.opt.expandtab = true vim.o.et = true
vim.opt.smarttab = true vim.o.ts = tabwidth
vim.opt.cindent = true vim.o.sw = tabwidth
vim.opt.autoindent = true vim.o.sts = -1
vim.opt.tabstop = tabwidth
vim.opt.shiftwidth = tabwidth
vim.opt.softtabstop = tabwidth
-- Schedule the setting after `UiEnter` because it can increase startup-time. -- Schedule the setting after `UiEnter` because it can increase startup-time.
-- (yoinked from kickstart.nvim) -- (yoinked from kickstart.nvim)
vim.schedule(function() vim.schedule(function()
vim.opt.clipboard = "unnamedplus" -- system clipboard vim.o.cb = "unnamedplus" -- system clipboard
end) end)
vim.opt.updatetime = 200
-- file saving -- file saving
vim.opt.swapfile = false vim.o.swf = false
vim.opt.undofile = true vim.o.udf = true
vim.opt.confirm = true
-- searching -- searching
vim.opt.ignorecase = true vim.o.ic = true
vim.opt.smartcase = true
vim.opt.wrapscan = true -- make windows look nice
vim.opt.showmatch = true vim.o.winborder = "solid"
vim.opt.incsearch = true
-- wild menus -- wild menus
vim.opt.wildoptions = "pum" vim.o.ph = 20
vim.opt.pumblend = 3 vim.o.wic = true
vim.opt.pumheight = 20 vim.o.wop = "fuzzy,pum"
vim.o.wim = "noselect:lastused,full"
vim.opt.wildignorecase = true -- completion
vim.opt.wildignore = "*.o" 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 do -- statusline
vim.g.netrw_banner = 0 ---@return string out formatted status line
vim.g.netrw_winsize = 30 function _G.Status()
vim.g.netrw_liststyle = 1 --- get the percentage through the file
vim.g.netrw_sizestyle = "H" ---@return string out the formatted percentage
vim.g.netrw_hide = 1
-- 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"
-- 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
-- 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"
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
}
}
}
}
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 function percentage()
local percent, line, lines local percent, line, lines
-- get the current and total # of lines
line = vim.api.nvim_win_get_cursor(0)[1] line = vim.api.nvim_win_get_cursor(0)[1]
lines = vim.api.nvim_buf_line_count(0) lines = vim.api.nvim_buf_line_count(0)
-- calculate the percentage through the file
percent = math.floor((line / lines) * 100) percent = math.floor((line / lines) * 100)
if percent == 0 then if percent == 0 or line == 1 then
return "Top" return "Top"
elseif percent == 100 then elseif percent == 100 or line == lines then
return "Bot" return "Bot"
end end
return percent.."%%" return percent.."%%"
end end
-- this is my statusline:
--
-- opts.lua [+] λ1 163,61-60 88%
--
return table.concat { return table.concat {
"%t", -- file name "%t", -- file name
" %h", -- help buffer tag " %h", -- help buffer tag
@@ -147,12 +81,14 @@ function _G.Status()
"%=", -- seperate left and right side "%=", -- seperate left and right side
-- print out the number of lsp clients attached -- print out the number of lsp clients attached
"λ"..#vim.lsp.get_clients({ bufnr = 0 }).." ", "λ"..#vim.lsp.get_clients({ bufnr = 0 }), " ",
"%<", -- we can start truncating here (I want to keep the file name) "%<", -- we can start truncating here (I want to keep the file name)
"%l,%c%V", -- line, column-virtual column "%l,%c%V", -- line, column-virtual column
"%<", -- we can start truncating here "%<", -- we can start truncating here
" "..percentage() -- percentage through the buffer " "..percentage() -- percentage through the buffer
} }
end
vim.o.stl = "%!v:lua.Status()"
vim.o.ls = 3
end 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 = core.misc.map
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 keymap_restore = {} local keymap_restore = {}
--- make the default hover binding work for nvim-dap instead of lsp --- make the default hover binding work for nvim-dap instead of lsp
local function set_hover_bind() local function set_hover_bind()
for _, buf in pairs(vim.api.nvim_list_bufs()) do 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 for _, keymap in pairs(keymaps) do
if keymap.lhs == "K" then if keymap.lhs == "K" then
table.insert(keymap_restore, keymap) 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 end
end end
vim.keymap.set('n', 'K', require("dap.ui.widgets").hover, map("n", "K", function()
{ silent = true }) require("dap.ui.widgets").hover(nil, {
border = vim.g.border_style
})
end, { silent = true })
end end
--- revert the hover bind back to whatever it was --- revert the hover bind back to whatever it was
@@ -44,20 +33,31 @@ local function unset_hover_bind()
keymap_restore = {} keymap_restore = {}
end end
return { "mfussenegger/nvim-dap", return {
requires = { { "mfussenegger/nvim-dap",
reqs = {
"mason-org/mason.nvim", "mason-org/mason.nvim",
"nvim-telescope/telescope.nvim" "nvim-telescope/telescope.nvim"
}, },
disable = not vim.fn.has("nvim-0.9.5"), deps = "theHamsta/nvim-dap-virtual-text",
branch = "0.10.0", branch = "0.10.0",
function() 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") local dap = require("dap")
-- define codelldb -- define codelldb
dap.adapters.codelldb = { dap.adapters.codelldb = {
type = "executable", type = "executable",
command = "codelldb", command = "codelldb"
} }
-- define the c configuration for codelldb -- define the c configuration for codelldb
@@ -66,7 +66,9 @@ return { "mfussenegger/nvim-dap",
name = "Launch file", name = "Launch file",
type = "codelldb", type = "codelldb",
request = "launch", request = "launch",
program = select_program, program = function()
return vim.fn.input("Path to executable: ", vim.fn.getcwd().."/", "file")
end,
cwd = "${workspaceFolder}", cwd = "${workspaceFolder}",
stopOnEntry = false stopOnEntry = false
@@ -79,20 +81,61 @@ return { "mfussenegger/nvim-dap",
dap.configurations.rust = dap.configurations.c dap.configurations.rust = dap.configurations.c
-- keybinds -- keybinds
map("n", "<Leader>ec", dap.continue, { desc = "dap continue " }) map("n", "<leader>ec", dap.continue, { desc = "dap continue" })
map("n", "<Leader>el", dap.run_last, { desc = "dap run last" }) map("n", "<leader>el", dap.run_last, { desc = "dap run last" })
map("n", "<Leader>et", function() map("n", "<leader>et", function()
dap.terminate() dap.terminate()
unset_hover_bind() unset_hover_bind()
end, { desc = "dap terminate " }) end, { desc = "dap terminate " })
map("n", "<Leader>eb", require("dap.breakpoints").toggle, { desc = "dap toggle breakpoint" }) map("n", "<leader>eb", require("dap.breakpoints").toggle, {
map("n", "<Leader>e]", dap.step_over, { desc = "dap step over" }) desc = "dap toggle breakpoint"
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>e]", dap.step_over, { desc = "dap step over" })
map("n", "<Leader>eR", dap.restart, { desc = "dap restart" }) 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 -- events
dap.listeners.after['event_initialized']['me'] = set_hover_bind dap.listeners.after["event_initialized"]["me"] = set_hover_bind
dap.listeners.after['event_terminated']['me'] = unset_hover_bind dap.listeners.after["event_terminated"]["me"] = unset_hover_bind
end 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 = core.misc.map
local map = misc.map
return { "lewis6991/gitsigns.nvim", return { "lewis6991/gitsigns.nvim",
disable = not vim.fn.has("nvim-0.9.0"), lazy = function(load)
function() 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") local gs = require("gitsigns")
gs.setup { gs.setup {
@@ -40,7 +49,6 @@ return { "lewis6991/gitsigns.nvim",
return "]c" return "]c"
end end
vim.schedule(function() gs.next_hunk() end) vim.schedule(function() gs.next_hunk() end)
return "<Ignore>"
end, { expr = true, buffer = bufnr }) end, { expr = true, buffer = bufnr })
map("n", "[c", function() map("n", "[c", function()
@@ -48,7 +56,6 @@ return { "lewis6991/gitsigns.nvim",
return "[c" return "[c"
end end
vim.schedule(function() gs.prev_hunk() end) vim.schedule(function() gs.prev_hunk() end)
return "<Ignore>"
end, { expr = true, buffer = bufnr }) end, { expr = true, buffer = bufnr })
-- Actions -- Actions
@@ -64,7 +71,7 @@ return { "lewis6991/gitsigns.nvim",
map("n", "<leader>hu", gs.undo_stage_hunk, opts) map("n", "<leader>hu", gs.undo_stage_hunk, opts)
map("n", "<leader>hR", gs.reset_buffer, opts) map("n", "<leader>hR", gs.reset_buffer, opts)
map("n", "<leader>hp", gs.preview_hunk, 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>tb", gs.toggle_current_line_blame, opts)
map("n", "<leader>hd", gs.diffthis, opts) map("n", "<leader>hd", gs.diffthis, opts)
map("n", "<leader>hD", function() gs.diffthis("~") end, 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,66 +1,48 @@
local misc = require("core.misc") local map = core.misc.map
local map = misc.map
return { "L3MON4D3/LuaSnip", return { "L3MON4D3/LuaSnip",
branch = "v2.4.0", branch = "v2.*",
disable = not vim.fn.has("nvim-0.7.0"),
config = function() config = function()
vim.cmd("make install_jsregexp") vim.cmd("make install_jsregexp")
end, end,
function() lazy = function(load)
local luasnip = require("luasnip") load:keymap({"i", "s"}, "<c-a>")
local types = require("luasnip.util.types") 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 { -- replace the builtin snippet handler with luasnip so I get all my fancy
history = true, -- return back into snippet -- stuff
enable_autosnippets = true, vim.snippet.expand = ls.lsp_expand
-- update on text insert and cursor hold ls.config.setup {
updateevents = { "TextChanged", "TextChangedI", "CursorHold" }, keep_roots = true,
ext_opts = { link_roots = true,
[types.choiceNode] = { link_children = true,
active = { exit_roots = not true
virt_text = {{ "", "@boolean" }}
}
},
[types.insertNode] = {
active = {
virt_text = {{ "", "@constant" }}
}
}
}
} }
map({"i", "s"}, "<c-a>", function() map({"i", "s"}, "<C-e>", ls.expand)
if luasnip.choice_active() then map({"i", "s"}, "<C-j>", function() ls.jump(1) end)
luasnip.change_choice(1) 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
end) end)
map({"i", "s"}, "<c-e>", function() -- collect all snippets and add them
if luasnip.expandable() then for _, file in ipairs(vim.api.nvim_get_runtime_file("lua/snippets/*.lua",
luasnip.expand() true)) do
end
end)
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 fn = file:gsub("^.*/", ""):gsub("%.lua$", "")
local ret = misc.include("snippets."..fn)
local ret = require("snippets."..fn)
if type(ret) ~= "boolean" then if type(ret) ~= "boolean" then
luasnip.add_snippets(fn, ret, { key = fn }) ls.add_snippets(fn, ret, { key = fn })
end end
end 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", return { "mellow-theme/mellow.nvim",
disable = not vim.fn.has("nvim-0.8.0"), reqs = "nvim-treesitter/nvim-treesitter",
requires = "nvim-treesitter/nvim-treesitter", load = function()
function()
vim.g.mellow_variant = "dark" vim.g.mellow_variant = "dark"
local c = require("mellow.colors")[vim.g.mellow_variant] local c = require("mellow.colors")[vim.g.mellow_variant]
if vim.g.mellow_variant == "dark" then
vim.g.mellow_highlight_overrides = { vim.g.mellow_highlight_overrides = {
-- stop inactive windows from having a darker bg -- stop inactive windows from having a darker bg
["NormalNC"] = { link = "Normal" }, ["NormalNC"] = { link = "Normal" },
-- revert change with statusline coloring
["StatusLine"] = { fg = c.white, bg = c.gray01 },
["StatusLineNC"] = { fg = c.bg_dark },
-- make splits look cleaner
["WinSeparator"] = { fg = c.gray01 },
-- make floats darker -- make floats darker
["NormalFloat"] = { fg = c.fg, bg = "#111111" }, ["NormalFloat"] = { fg = c.fg, bg = "#111111" },
["FloatBorder"] = { link = "NormalFloat" }, ["FloatBorder"] = { link = "NormalFloat" },
-- 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 -- make diagnostics have an undercurl
["DiagnosticUnderlineError"] = { fg = c.red, undercurl = true }, ["DiagnosticUnderlineError"] = { fg = c.red, undercurl = true },
["DiagnosticUnderlineWarn"] = { fg = c.yellow, undercurl = true }, ["DiagnosticUnderlineWarn"] = { fg = c.yellow, undercurl = true },
["DiagnosticUnderlineInfo"] = { fg = c.blue, undercurl = true }, ["DiagnosticUnderlineInfo"] = { fg = c.blue, undercurl = true },
["DiagnosticUnderlineHint"] = { fg = c.cyan, undercurl = true }, ["DiagnosticUnderlineHint"] = { fg = c.cyan, undercurl = true },
["DiagnosticHint"] = { fg = c.cyan }, -- revert
-- make blink actually look nice -- telescope styling so I can see when coding outside (real)
["BlinkCmpMenu"] = { link = "NormalFloat" }, ["TelescopeResultsNormal"] = { bg = c.bg_dark },
["BlinkCmpMenuBorder"] = { link = "BlinkCmpMenu" }, ["TelescopeResultsBorder"] = { link = "TelescopeResultsNormal" },
["BlinkCmpMenuSelection"] = { bg = c.gray01 }, ["TelescopeResultsTitle"] = { bg = c.bg, fg = c.bg },
["BlinkCmpLabelDeprecated"] = { link = "CmpItemAbbrDeprecated" } ["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
end
} }

View File

@@ -1,12 +1,12 @@
local misc = require("core.misc") local map = core.misc.map
local map = misc.map
return { "danymat/neogen", return { "danymat/neogen",
requires = { reqs = {
"nvim-treesitter/nvim-treesitter", "nvim-treesitter/nvim-treesitter",
"L3MON4D3/LuaSnip" "L3MON4D3/LuaSnip"
}, },
function() lazy = dep_short.keymap("n", "<leader>d"),
load = function()
local neogen = require("neogen") local neogen = require("neogen")
neogen.setup { neogen.setup {
enabled = true, 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 = core.misc.map
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",
}
return { "stevearc/oil.nvim", return { "stevearc/oil.nvim",
disable = not vim.fn.has("nvim-0.8.0"), lazy = dep_short.keymap("n", "-"),
deps = { load = function()
{ "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
require("oil").setup { require("oil").setup {
-- ID is automatically added at the beginning, and name at the end -- ID is automatically added at the beginning, and name at the end
-- See :help oil-columns -- See :help oil-columns
@@ -90,7 +13,12 @@ return { "stevearc/oil.nvim",
local hls = {} local hls = {}
for i = 1, #permission_str do for i = 1, #permission_str do
local char = permission_str:sub(i, i) 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 end
return hls return hls
end, end,
@@ -98,135 +26,11 @@ return { "stevearc/oil.nvim",
{ "size", highlight = "@number" } { "size", highlight = "@number" }
}, },
-- Window-local options to use for oil buffers -- fix the damn border
win_options = { confirmation = { border = vim.o.winborder },
number = false, progress = { border = vim.o.winborder },
relativenumber = false, ssh = { border = vim.o.winborder },
wrap = false, keymaps_help = { border = vim.o.winborder }
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
}
} }
map("n", "-", "<cmd>Oil<CR>") map("n", "-", "<cmd>Oil<CR>")

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,128 @@
local misc = require("core.misc") local map = core.misc.map
local map = 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", return { "nvim-telescope/telescope.nvim",
disable = not vim.fn.has("nvim-0.9.0"), reqs = {
requires = {
"nvim-lua/plenary.nvim", "nvim-lua/plenary.nvim",
{ "nvim-telescope/telescope-fzf-native.nvim", { "nvim-telescope/telescope-fzf-native.nvim",
config = function() config = function()
vim.cmd("make") vim.cmd("make")
end end
}, },
"mollerhoj/telescope-recent-files.nvim",
"nvim-telescope/telescope-ui-select.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>tc")
load:keymap("n", "<leader>tp")
end,
load = function()
local telescope = require("telescope") local telescope = require("telescope")
local actions = require("telescope.actions") 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 { telescope.setup {
defaults = { defaults = {
borderchars = { layout_strategy = "bottom_pane",
prompt = { " ", " ", " ", " ", " ", " ", " ", " " }, borderchars = { " ", " ", " ", " ", " ", " ", " ", " " },
results = { " ", " ", " ", " ", " ", " ", " ", " " },
preview = { " ", " ", " ", " ", " ", " ", " ", " " },
},
winblend = 0,
layout_strategy = "horizontal",
sorting_strategy = "descending",
scroll_strategy = "limit",
layout_config = {
horizontal = {
height = 20,
prompt_position = "bottom",
anchor = "N",
}
},
mappings = { mappings = {
i = { i = {
["<esc>"] = actions.close, ["<esc>"] = actions.close,
["<C-j>"] = actions.move_selection_next, ["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous, ["<C-k>"] = actions.move_selection_previous,
["<C-u>"] = actions.preview_scrolling_up, ["<CR>"] = send_limited_to_qflist_and_open,
["<C-d>"] = actions.preview_scrolling_down,
} }
} }
}, },
pickers = {
colorscheme = {
enable_preview = true
}
},
extensions = { extensions = {
fzf = {} fzf = {}
} }
@@ -53,37 +130,28 @@ return { "nvim-telescope/telescope.nvim",
-- load in the fzf extension -- load in the fzf extension
telescope.load_extension("fzf") telescope.load_extension("fzf")
telescope.load_extension("recent-files")
telescope.load_extension("ui-select") telescope.load_extension("ui-select")
-- keymaps -- keymaps
local telebuilt = require("telescope.builtin") local telebuilt = require("telescope.builtin")
map("n", "<leader>f", function() map("n", "<leader>f", telebuilt_picker(telebuilt.find_files), {
telescope.extensions["recent-files"].recent_files { follow = true } desc = "Find files."
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>i", telebuilt.help_tags, { map("n", "<leader>s", telebuilt_picker(telebuilt.live_grep), {
desc = "find help tags.", desc = "Find strings."
}) })
map("n", "<leader>i", telebuilt.help_tags, { desc = "find help tags." })
-- find over specific directories -- find over specific directories
map("n", "<leader>tc", function() map("n", "<leader>tc", function()
require("telescope.builtin").find_files { telebuilt.find_files { cwd = vim.fn.stdpath("config") }
cwd = vim.fn.stdpath("config")
}
end, { desc = "find config files" }) end, { desc = "find config files" })
map("n", "<leader>tp", function() 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") cwd = vim.fs.joinpath(vim.fn.stdpath("data"), "site/pack/deps/opt")
} }
end, { desc = "find files in plugin directory" }) end, { desc = "find files in plugin directory" })
-- enable previewing in the default colorscheme switcher map("n", "<leader>tt", "<cmd>Telescope<CR>")
telebuilt.colorscheme = function()
require("telescope.builtin.__internal").colorscheme { enable_preview = true }
end
end 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,18 +1,11 @@
table.contains = function(self, string) local map = core.misc.map
for _, v in pairs(self) do
if v == string then
return true
end
end
return false
end
return { "nvim-treesitter/nvim-treesitter", return {
disable = not vim.fn.has("nvim-0.10.0"), { "nvim-treesitter/nvim-treesitter",
config = function() config = function()
vim.cmd("TSUpdate") vim.cmd("TSUpdate")
end, end,
function() load = function()
require("nvim-treesitter.configs").setup { require("nvim-treesitter.configs").setup {
-- good default parsers -- good default parsers
ensure_installed = { "c", "lua", "vim", "vimdoc", "markdown", ensure_installed = { "c", "lua", "vim", "vimdoc", "markdown",
@@ -47,13 +40,47 @@ return { "nvim-treesitter/nvim-treesitter",
end end
-- disable in big files -- disable in big files
-- TODO: update before nvim 1.0 when vim.loop is removed local ok, stats = pcall(vim.uv.fs_stat,
local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) vim.api.nvim_buf_get_name(buf))
if ok and stats and stats.size > (1024 * 100 * 10) --[[1MB]] then if ok and stats and stats.size > (1024 * 100 * 10) --[[1MB]] then
return true 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 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 --- vim.notify title
M.appid = "Nvim Config" 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 --- extend vim.kemap.set
---@param mode string|table mode for the keymap ---@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 cmd function|string command to run
---@param opts vim.keymap.set.Opts? keymap options ---@param opts vim.keymap.set.Opts? keymap options
function M.map(mode, bind, cmd, opts) function M.map(mode, bind, cmd, opts)
@@ -47,19 +24,12 @@ function M.map(mode, bind, cmd, opts)
end end
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) vim.keymap.set(mode, bind, cmd, opts)
end
end end
--- a small map wrapper to easily create local buffer mappings --- a small map wrapper to easily create local buffer mappings
---@param mode string|table mode for the keymap ---@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 cmd function|string command to run
---@param opts table? keymap options ---@param opts table? keymap options
function M.map_local(mode, bind, cmd, opts) function M.map_local(mode, bind, cmd, opts)
@@ -68,122 +38,35 @@ function M.map_local(mode, bind, cmd, opts)
M.map(mode, bind, cmd, opts) M.map(mode, bind, cmd, opts)
end end
--- extend vim.api.nvim_create_autocmd --- shorten vim.api.nvim_create_autocmd call
---@param event string|table event or events M.auto = vim.api.nvim_create_autocmd
---@param opts vim.api.keyset.create_autocmd options
function M.auto(event, opts)
vim.api.nvim_create_autocmd(event, opts)
end
--- extend auto group --- extend auto group
---@param name string name of the autogroup ---@param name string name of the autogroup
---@param opts table? table of options ---@param opts table? table of options
---@return integer
function M.augroup(name, opts) function M.augroup(name, opts)
opts = opts or {} opts = opts or {}
vim.api.nvim_create_augroup(name, opts) return vim.api.nvim_create_augroup(name, opts)
end end
--- extend vim.api.nvim_set_hl --- Make an action lazy. This is mostly useful for keybinds which do a lot and
---@param group string|table highlight group --- you want to make sure the screen doesn't flash
---@param opts table highlight options ---@param txt string|function the action
---@param namespace? number highlight space ---@return string|function lazified
function M.highlight(group, opts, namespace) ---@nodiscard
namespace = namespace or 0 function M.lz(txt)
if type(txt) == "string" then
if type(group) == "table" then return "<cmd>se lz<CR>"..txt.."<cmd>se lz!<CR>"
for i in pairs(group) do elseif type(txt) == "function" then
vim.api.nvim_set_hl(namespace, group[i], opts) return function()
vim.cmd.se("lz")
-- gotta make sure we can always unset lz
pcall(txt)
vim.cmd.se("lz!")
end end
elseif type(group) == "string" then else
vim.api.nvim_set_hl(namespace, group, opts) return txt
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 end
end end

View File

@@ -21,3 +21,7 @@ conds_expand = require("luasnip.extras.conditions.expand")
ts_postfix = require("luasnip.extras.treesitter_postfix").treesitter_postfix ts_postfix = require("luasnip.extras.treesitter_postfix").treesitter_postfix
postfix = require("luasnip.extras.postfix").postfix postfix = require("luasnip.extras.postfix").postfix
ms = ls.multi_snippet 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") dofile(core.snippets)
--- 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
return { return {
-- function snippet -- function snippet
@@ -82,19 +40,4 @@ return {
i(0), i(0),
t({ "", "}" }) 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") dofile(core.snippets)
require("core.snippets.functions")
--- shortcut to choose between java access modifiers --- shortcut to choose between java access modifiers
---@param idx number index of the node ---@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 { return {
-- translate snippet -- translate snippet

View File

@@ -1,4 +1,4 @@
require("core.snippets.shorthands") dofile(core.snippets)
return { return {
s("php", { 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") dofile(core.snippets)
require("core.snippets.functions")
return { return {
-- document snippet -- document snippet