all the languages!

This commit is contained in:
RingOfStorms (Joshua Bell) 2024-05-03 18:56:57 -05:00
parent 1eb427a6dc
commit eb7f522795
14 changed files with 630 additions and 548 deletions

View file

@ -61,9 +61,7 @@ rm -rf ~/.local/state/nvim
## NOTES/TODOS
- h/l movement broken in insert mode, probably due to cmp hotkeys
- h/l in telescope
- arrows still work in insert mode and telescope, need to remove trying to break arrow key habit
- See what linters/formaters to add or are the LSP's enough?
FUTURE

View file

@ -87,7 +87,14 @@
"nvim_plugin-saadparwaiz1/cmp_luasnip" = cmp_luasnip;
"nvim_plugin-hrsh7th/cmp-nvim-lsp" = cmp-nvim-lsp;
"nvim_plugin-hrsh7th/cmp-path" = cmp-path;
"nvim_plugin-hrsh7th/cmp-buffer" = cmp-buffer;
"nvim_plugin-zbirenbaum/copilot-cmp" = copilot-cmp;
"nvim_plugin-zbirenbaum/copilot.lua" = copilot-lua;
"nvim_plugin-folke/neodev.nvim" = neodev-nvim;
"nvim_plugin-mrcjkb/rustaceanvim" = rustaceanvim;
"nvim_plugin-Saecki/crates.nvim" = crates-nvim;
"nvim_plugin-lvimuser/lsp-inlayhints.nvim" = lsp-inlayhints-nvim;
"nvim_plugin-rafamadriz/friendly-snippets" = friendly-snippets;
};
# This will be how we put any nix related stuff into our lua config
luaNixGlobal =
@ -113,6 +120,11 @@
fzf # search fuzzy
tree-sitter
glow # markdown renderer
# curl # http requests TODO
# nodePackages.cspell TODO
];
defaultRuntimeDependencies = with pkgs; [
# linters
markdownlint-cli
luajitPackages.luacheck
@ -121,14 +133,23 @@
stylua
nixfmt-rfc-style
nodePackages.prettier
rustywind
markdownlint-cli2
# LSPs
nil # nix
lua-language-server
vscode-langservers-extracted # HTML/CSS/JSON/ESLint
nodePackages.typescript-language-server
tailwindcss-language-server
nodePackages.pyright
# curl # http requests TODO
# nodePackages.cspell TODO
rust-analyzer
marksman # markdown
taplo #toml
yaml-language-server
lemminx # xml
# Other
# typescript
nodejs_20
];
in
{
@ -152,6 +173,11 @@
"PATH"
":"
"${lib.makeBinPath runtimeDependencies}"
# Some we will suffix so we pick up the local dev shell intead and default to these otherwise
"--suffix"
"PATH"
":"
"${lib.makeBinPath defaultRuntimeDependencies}"
# Set the LAZY env path to the nix store, see init.lua for how it is used
"--set"
"LAZY"

View file

@ -45,6 +45,13 @@ local function getSpec()
-- Convert plugins to use nix store, this auto sets the `dir` property for us on all plugins.
local function convertPluginToNixStore(plugin)
local p = ensure_table(plugin)
if U.isArray(p) and #p > 1 then
local plugins = {}
table.foreachi(p, function(i, inner)
table.insert(plugins, convertPluginToNixStore(inner))
end)
return plugins
end
if p.enabled == false then
return plugin
end
@ -69,14 +76,11 @@ local function getSpec()
local plugins_path = debug.getinfo(2, "S").source:sub(2):match("(.*/)") .. "lua/plugins"
for _, file in ipairs(vim.fn.readdir(plugins_path, [[v:val =~ '\.lua$']])) do
local plugin = string.sub(file, 0, -5)
table.insert(plugins, convertPluginToNixStore(require("plugins." .. plugin)))
local converted = convertPluginToNixStore(require("plugins." .. plugin))
table.insert(plugins, converted)
end
return plugins
else
-- TODO I want this to work in the nixos versionhttps://github.com/RingOfStorms/nvim/blob/nix-flake/init.lua#L39-L55
-- but it is not resolving properly to the nix store.
-- Will revisit at some point, instead we manually pull them
-- in above with a directory scan.
return { { import = "plugins" } }
end
end

View file

@ -1,4 +1,4 @@
local group = vim.api.nvim_create_augroup("myconfig-autocommands-group", { clear = true });
local group = vim.api.nvim_create_augroup("myconfig-autocommands-group", { clear = true })
-- Highlight when yanking (copying) text
-- Try it with `yap` in normal mode
-- See `:help vim.highlight.on_yank()`
@ -10,7 +10,9 @@ vim.api.nvim_create_autocmd("TextYankPost", {
end,
})
-- TODO is there a better way for these?
-- https://www.youtube.com/watch?v=NecszftvMFI vim.filetype.add
vim.api.nvim_create_autocmd("BufRead", {
group = group,
pattern = ".env*",

View file

@ -84,7 +84,7 @@ U.keymaps({
-- Editor
{ "J", "mzJ`z", desc = "Move line below onto this line" },
{ -- TODO stay here, are these already mapped?
{
"]d",
vim.diagnostic.goto_next,
desc = "Go to next diagnostic message",
@ -107,13 +107,12 @@ U.keymaps({
{ "<C-6>", "<Home>", mode = { "i", "c" }, desc = "Movements in insert/command mode" },
-- Tabs
-- TODO revisit, do I even need these tab things?
{ "<leader>tn", "<cmd>tabnew<cr>", desc = "Create new tab", mode = nvx },
{ "<leader>tq", "<cmd>tabclose<cr>", desc = "Close current tab", mode = nvx },
{ "H", "<cmd>tabprevious<cr>", desc = "Move to previous tab" },
{ "L", "<cmd>tabnext<cr>", desc = "Move to next tab" },
-- LSP/IDE/etc TODO move to lsp config file
-- LSP/IDE/
{
"<leader>ld",
vim.diagnostic.open_float,

View file

@ -53,14 +53,12 @@ vim.opt.undofile = true
-- and `:help 'listchars'`
vim.opt.list = true
vim.opt.listchars = { tab = "", trail = "·", nbsp = "", eol = "" }
-- TODO REVISIT IF I WANT THESE
-- Search settings
vim.opt.hlsearch = true
vim.opt.incsearch = true
-- Preview substitutions live, as you type
-- TODO revisit, what does this actually do
vim.opt.inccommand = "split"
-- Show which line your cursor is on

View file

@ -6,16 +6,12 @@ return {
{
"L3MON4D3/LuaSnip",
dependencies = {
-- TODO use or remove this?
-- `friendly-snippets` contains a variety of premade snippets.
-- See the README about individual language/framework/plugin snippets:
-- https://github.com/rafamadriz/friendly-snippets
-- {
-- 'rafamadriz/friendly-snippets',
-- config = function()
-- require('luasnip.loaders.from_vscode').lazy_load()
-- end,
-- },
{
"rafamadriz/friendly-snippets",
config = function()
require("luasnip.loaders.from_vscode").lazy_load()
end,
},
},
},
"saadparwaiz1/cmp_luasnip",
@ -24,7 +20,19 @@ return {
-- nvim-cmp does not ship with all sources by default. They are split
-- into multiple repos for maintenance purposes.
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-path",
{
"zbirenbaum/copilot.lua",
cmd = "Copilot",
event = "InsertEnter",
opts = {
-- suggestion = { enabled = false, auto_trigger = false },
-- panel = { enabled = false, auto_trigger = false },
},
main = "copilot",
},
{ "zbirenbaum/copilot-cmp", opts = {}, main = "copilot_cmp" },
},
config = function()
-- See `:help cmp`
@ -40,64 +48,80 @@ return {
},
completion = { completeopt = "menu,menuone,noinsert" },
-- For an understanding of why these mappings were
-- chosen, you will need to read `:help ins-completion`
--
-- No, but seriously. Please read `:help ins-completion`, it is really good!
mapping = cmp.mapping.preset.insert({
-- Select the [n]ext item
["<C-j>"] = cmp.mapping.select_next_item(),
-- Select the [p]revious item
["<C-k>"] = cmp.mapping.select_prev_item(),
-- Scroll the documentation window [b]ack / [f]orward
["<C-u>"] = cmp.mapping.scroll_docs(-4),
["<C-d>"] = cmp.mapping.scroll_docs(4),
["<esc>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.abort()
fallback()
else
fallback()
end
end),
-- Accept ([y]es) the completion.
-- This will auto-import if your LSP supports it.
-- This will expand snippets if the LSP sent a snippet.
-- Select the [n]ext item
["<C-j>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
-- elseif luasnip.expand_or_jumpable() then
elseif luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { "i", "s" }),
-- Select the [p]revious item
["<C-k>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" }),
["<C-y>"] = cmp.mapping.confirm({ select = true }),
-- If you prefer more traditional completion keymaps,
-- you can uncomment the following lines
--['<CR>'] = cmp.mapping.confirm { select = true },
--['<Tab>'] = cmp.mapping.select_next_item(),
--['<S-Tab>'] = cmp.mapping.select_prev_item(),
-- Manually trigger a completion from nvim-cmp.
-- Generally you don't need this, because nvim-cmp will display
-- completions whenever it has completion options available.
["<C-c>"] = cmp.mapping.complete({}),
-- TODO remove these or make them soemthing else, this collided with my normal movements in insert mode
-- Think of <c-l> as moving to the right of your snippet expansion.
-- So if you have a snippet that's like:
-- function $name($args)
-- $body
-- end
--
-- <c-l> will move you to the right of each of the expansion locations.
-- <c-h> is similar, except moving you backwards.
-- ["<C-l>"] = cmp.mapping(function()
-- if luasnip.expand_or_locally_jumpable() then
-- luasnip.expand_or_jump()
-- end
-- end, { "i", "s" }),
-- ["<C-h>"] = cmp.mapping(function()
-- if luasnip.locally_jumpable(-1) then
-- luasnip.jump(-1)
-- end
-- end, { "i", "s" }),
-- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
-- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
["<C-space>"] = cmp.mapping.complete({}),
}),
sources = {
{ name = "nvim_lsp" },
{ name = "luasnip" },
{ name = "path" },
{
name = "copilot",
priority = 9,
keyword_length = 1,
filter = function(keyword)
-- Check if keyword length is some number and not just whitespace
if #keyword < 2 or keyword:match("^%s*$") then
return false
end
return true
end,
},
{ name = "nvim_lsp", priority = 8, max_item_count = 100 },
{ name = "luasnip", priority = 7 },
-- This source provides file path completions, helping you to complete file paths in your code
{ name = "path", priority = 7 },
-- This source provides completion items from the current buffer, meaning it suggests words that have already been typed in the same file.
{ name = "buffer", priority = 6 },
-- Rust crates.io integration
{ name = "crates" },
},
-- TODO revisit if I want these or not
-- sorting = {
-- priority_weight = 1,
-- comparators = {
-- cmp.config.compare.locality,
-- cmp.config.compare.recently_used,
-- cmp.config.compare.score,
-- cmp.config.compare.offset,
-- cmp.config.compare.order,
-- },
-- },
-- window = { -- also? https://github.com/RingOfStorms/nvim/blob/master/lua/plugins/lsp.lua#L330-L347
-- completion = cmp.config.window.bordered(),
-- documentation = cmp.config.window.bordered(),
-- },
})
end,
}

View file

@ -1,16 +1,8 @@
-- TODO checkout https://github.com/nvim-lua/lsp-status.nvim
-- https://www.reddit.com/r/neovim/comments/o4bguk/comment/h2kcjxa/
local function lsp_clients()
local clients = {}
for _, client in pairs(vim.lsp.buf_get_clients(0)) do
local name = client.name
-- TODO revisit this doesn't work
if not client.initialized then
name = name .. " (loading)"
clients[#clients + 1] = client.name
end
clients[#clients + 1] = name
end
table.sort(clients)
return table.concat(clients, ""), ""
end
@ -65,9 +57,13 @@ return {
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diff", "diagnostics" },
lualine_b = {
"branch",
"filename",
},
lualine_c = {
{ "filename", separator = { right = "" } },
"diff",
"diagnostics",
{ "reg_recording", icon = { "󰻃" }, color = { fg = "#D37676" } },
{ gitblame, color = { fg = "#696969" } },
},

View file

@ -7,11 +7,6 @@ return {
},
event = "VeryLazy",
opts = {
routes = {
-- I want telescope-ui-select to trigger here not noice
{ filter = { event = "lsp", kind = "search_count" }, opts = { skip = true } },
{ filter = { event = "lsp" }, opts = { skip = true } }, -- TODO come back to this, im having weird issues with insert mode getting broken.
},
messages = {
view = "mini", -- default view for messages
view_error = "notify", -- view for errors
@ -26,6 +21,8 @@ return {
["vim.lsp.util.stylize_markdown"] = true,
["cmp.entry.get_documentation"] = true, -- requires hrsh7th/nvim-cmp
},
-- I had an issue with auto_open kicking me out of insert mode when entering insert mode
signature = { auto_open = { trigger = false } },
},
},
config = function(_, opts)

View file

@ -1,3 +1,20 @@
local function formatCurrent(retry)
require("conform").format({ async = true, lsp_fallback = true }, function(err, edited)
if edited then
print("Formatted!")
elseif err then
-- Sometimes I am too fast and vim is saving from my InsertExit and this fails so
-- I give it one retry
if not retry and string.find(err, "concurrent modification") then
return formatCurrent(true)
end
print(err)
else
print("Nothing to format!")
end
end)
end
return {
"stevearc/conform.nvim",
opts = {
@ -7,30 +24,22 @@ return {
formatters_by_ft = {
lua = { "stylua" },
nix = { "nixfmt" },
typescript = { { "prettierd", "prettier" } },
typescriptreact = { { "prettierd", "prettier" } },
javascript = { { "prettierd", "prettier" } },
javascriptreact = { { "prettierd", "prettier" } },
typescript = { { "prettierd", "prettier" }, "rustywind" },
typescriptreact = { { "prettierd", "prettier" }, "rustywind" },
javascript = { { "prettierd", "prettier" }, "rustywind" },
javascriptreact = { { "prettierd", "prettier" }, "rustywind" },
-- TODO revisit these I'd like to use them but they are not in nixpkgs yet
-- https://nixos.org/guides/nix-pills/
-- markdown = { "mdslw", "mdsf"},
markdown = { "markdownlint-cli2" },
-- rust = { "rustfmt" },
},
},
keys = {
{
"<leader>l<leader>",
function()
require("conform").format({ async = true, lsp_fallback = true }, function(err, edited)
if edited then
print("Formatted!")
elseif err then
print(err)
else
print("Nothing to format!")
end
end)
end,
formatCurrent,
mode = { "n", "v", "x" },
desc = "Format buffer",
},

View file

@ -1,20 +1,39 @@
return {
-- LSP helper plugins for various languages
{ "folke/neodev.nvim", event = { "BufRead *.lua", "BufRead *.vim" }, opts = {}, main = "neodev" },
{ "mrcjkb/rustaceanvim", lazy = false }, -- uses ftplugins to enable itself lazily already
-- TODO add some hotkeys for opening the popup menus on crates
{ "Saecki/crates.nvim", event = "BufRead Cargo.toml", tag = "stable", opts = {}, main = "crates" },
{
"neovim/nvim-lspconfig",
event = "BufEnter",
dependencies = {
{
"lvimuser/lsp-inlayhints.nvim",
init = function()
vim.api.nvim_create_augroup("LspAttach_inlayhints", { clear = true })
vim.api.nvim_create_autocmd("LspAttach", {
group = "LspAttach_inlayhints",
callback = function(args)
if not (args.data and args.data.client_id) then
return
end
local bufnr = args.buf
local client = vim.lsp.get_client_by_id(args.data.client_id)
require("lsp-inlayhints").on_attach(client, bufnr)
end,
})
end,
opts = {
type_hints = { prefix = " ::" },
},
main = "lsp-inlayhints",
},
-- Automatically install LSPs and related tools to stdpath for Neovim
{ "williamboman/mason.nvim", enabled = not NIX, config = true }, -- NOTE: Must be loaded before dependants
{ "williamboman/mason-lspconfig.nvim", enabled = not NIX },
{ "WhoIsSethDaniel/mason-tool-installer.nvim", enabled = not NIX },
-- TODO revisit if I want this or not, is this already solved?
-- Useful status updates for LSP.
-- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})`
-- { "j-hui/fidget.nvim", opts = {} },
-- `neodev` configures Lua LSP for your Neovim config, runtime and plugins
-- used for completion, annotations and signatures of Neovim apis
{ "folke/neodev.nvim", opts = {}, main = "neodev" },
},
config = function()
vim.api.nvim_create_autocmd("LspAttach", {
@ -26,21 +45,10 @@ return {
map("gd", require("telescope.builtin").lsp_definitions, "Goto Definition")
map("gr", require("telescope.builtin").lsp_references, "Goto References")
map("gI", require("telescope.builtin").lsp_implementations, "Goto Implementation")
-- TODO do I want these?
-- map("<leader>D", require("telescope.builtin").lsp_type_definitions, "Type Definition")
-- map("<leader>ds", require("telescope.builtin").lsp_document_symbols, "Document Symbols")
-- map("<leader>ws", require("telescope.builtin").lsp_dynamic_workspace_symbols, "Workspace Symbols")
map("<leader>lr", vim.lsp.buf.rename, "Rename")
map("<leader>la", vim.lsp.buf.code_action, "Code Action")
map("K", vim.lsp.buf.hover, "Hover Documentation")
map("gD", vim.lsp.buf.declaration, "Goto Declaration")
local client = vim.lsp.get_client_by_id(event.data.client_id)
if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
map("<leader>lth", function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
end, "Toggle Inlay Hints")
end
end,
})
@ -59,29 +67,12 @@ return {
-- TODO finish porting over lsp configs: https://github.com/RingOfStorms/nvim/blob/master/lua/plugins/lsp.lua
local servers = {
-- clangd = {},
-- gopls = {},
-- pyright = {},
-- rust_analyzer = {},
-- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs
--
-- Some languages (like typescript) have entire language plugins that can be useful:
-- https://github.com/pmizio/typescript-tools.nvim
--
-- But for many setups, the LSP (`tsserver`) will work just fine
tsserver = {
-- typescript/javascript
implicitProjectConfiguration = {
checkJs = true,
},
},
pyright = {
-- python
},
-- Note that `rust-analyzer` is done via mrcjkb/rustaceanvim plugin above, do not register it here.
lua_ls = {
-- cmd = { ... },
-- filetypes = { ...},
-- capabilities = {},
settings = {
Lua = {
runtime = {
@ -107,24 +98,62 @@ return {
"require",
"NIX",
"U",
-- Hammerspoon
-- Hammerspoon for macos
"hs",
},
},
},
-- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings
-- diagnostics = { disable = { 'missing-fields' } },
},
},
},
nil_ls = {},
tsserver = {
-- typescript/javascript
implicitProjectConfiguration = {
checkJs = true,
},
},
tailwindcss = {
-- tailwind css
-- https://www.tailwind-variants.org/docs/getting-started#intellisense-setup-optional
tailwindCSS = {
experimental = {
classRegex = {
{ "tv\\((([^()]*|\\([^()]*\\))*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]" },
},
},
},
},
cssls = {
-- css
},
jsonls = {
-- json
},
pyright = {
-- python
},
marksman = {
-- markdown
},
taplo = {
-- toml
},
yamlls = {
-- yaml
},
lemminx = {
-- xml
},
}
if NIX then
local servers = vim.tbl_keys(servers or {})
for _, server_name in ipairs(servers) do
local lsp_servers = vim.tbl_keys(servers or {})
for _, server_name in ipairs(lsp_servers) do
local server_opts = servers[server_name] or {}
require("lspconfig")[server_name].setup(server_opts)
end
else
-- TODO test this out on a non nix setup...
require("mason").setup()
local ensure_installed = vim.tbl_keys(servers or {})
vim.list_extend(ensure_installed, {
@ -135,11 +164,13 @@ return {
handlers = {
function(server_name)
local server = servers[server_name] or {}
server.capabilities = vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {})
server.capabilities =
vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {})
require("lspconfig")[server_name].setup(server)
end,
},
})
end
end,
},
}

View file

@ -11,7 +11,6 @@ return {
"<leader>,c",
function()
if next(vim.lsp.get_active_clients()) ~= nil then
-- TODO test that this works
vim.cmd("TextCaseOpenTelescopeLSPChange")
else
vim.cmd("TextCaseOpenTelescope")

View file

@ -15,15 +15,15 @@ return {
local wk = require("which-key")
wk.setup(opts)
wk.register({
["<leader>b"] = { name = "Buffers", mode = { "n", "x", "v", "c" } },
["<leader>t"] = { name = "Tabs", mode = { "n", "x", "v", "c" } },
["<leader>,"] = { name = "Miscellaneous Tools", mode = { "n", "x", "v", "c" } },
["<leader>b"] = { name = "Buffers", mode = { "n", "x", "v" } },
["<leader>t"] = { name = "Tabs", mode = { "n", "x", "v" } },
["<leader>,"] = { name = "Miscellaneous Tools", mode = { "n", "x", "v" } },
-- ["<leader>c"] = { name = "Copilot" },
["<leader>f"] = { name = "Find [Telescope]", mode = { "n", "x", "v", "c" } },
["<leader>f"] = { name = "Find [Telescope]", mode = { "n", "x", "v" } },
-- ["<leader>fs"] = { name = "Find in Scratches [Telescope]" },
["<leader>g"] = { name = "Git", mode = { "n", "x", "v", "c" } },
["<leader>l"] = { name = "LSP", mode = { "n", "x", "v", "c" } },
["<leader>lf"] = { name = "LSP Find", mode = { "n", "x", "v", "c" } },
["<leader>g"] = { name = "Git", mode = { "n", "x", "v" } },
["<leader>l"] = { name = "LSP", mode = { "n", "x", "v" } },
["<leader>lf"] = { name = "LSP Find", mode = { "n", "x", "v" } },
-- ["<leader>Q"] = { name = "+Q Quit and remove session" },
-- ["<leader>s"] = { name = "Scratch Files" },
-- ["<leader>x"] = { name = "Generative AI, Ollama" },

View file

@ -1,5 +1,16 @@
local M = {}
function M.isArray(table)
local i = 0
for _ in pairs(table) do
i = i + 1
if table[i] == nil then
return false
end
end
return true
end
function M.cmd_executable(cmd, callback)
local executable = vim.fn.executable(cmd) == 1
-- Check if a callback is provided and it is a function
@ -128,18 +139,6 @@ function M.safeRequire(module, func, errorFunc)
return nil
end
-- TODO remove if not needed
-- local startup_time = vim.loop.now()
-- function M.delayFromStartup(delay, func)
-- local current_time = vim.loop.now()
-- local diff = current_time - startup_time
-- if diff >= delay then
-- func()
-- else
-- vim.defer_fn(func, (delay - diff))
-- end
-- end
function M.fnFalse()
return false
end