all the languages!
This commit is contained in:
parent
1eb427a6dc
commit
eb7f522795
14 changed files with 630 additions and 548 deletions
|
@ -61,9 +61,7 @@ rm -rf ~/.local/state/nvim
|
||||||
|
|
||||||
## NOTES/TODOS
|
## NOTES/TODOS
|
||||||
|
|
||||||
- h/l movement broken in insert mode, probably due to cmp hotkeys
|
- See what linters/formaters to add or are the LSP's enough?
|
||||||
- h/l in telescope
|
|
||||||
- arrows still work in insert mode and telescope, need to remove trying to break arrow key habit
|
|
||||||
|
|
||||||
FUTURE
|
FUTURE
|
||||||
|
|
||||||
|
|
32
flake.nix
32
flake.nix
|
@ -87,7 +87,14 @@
|
||||||
"nvim_plugin-saadparwaiz1/cmp_luasnip" = cmp_luasnip;
|
"nvim_plugin-saadparwaiz1/cmp_luasnip" = cmp_luasnip;
|
||||||
"nvim_plugin-hrsh7th/cmp-nvim-lsp" = cmp-nvim-lsp;
|
"nvim_plugin-hrsh7th/cmp-nvim-lsp" = cmp-nvim-lsp;
|
||||||
"nvim_plugin-hrsh7th/cmp-path" = cmp-path;
|
"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-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
|
# This will be how we put any nix related stuff into our lua config
|
||||||
luaNixGlobal =
|
luaNixGlobal =
|
||||||
|
@ -113,6 +120,11 @@
|
||||||
fzf # search fuzzy
|
fzf # search fuzzy
|
||||||
tree-sitter
|
tree-sitter
|
||||||
glow # markdown renderer
|
glow # markdown renderer
|
||||||
|
# curl # http requests TODO
|
||||||
|
# nodePackages.cspell TODO
|
||||||
|
];
|
||||||
|
|
||||||
|
defaultRuntimeDependencies = with pkgs; [
|
||||||
# linters
|
# linters
|
||||||
markdownlint-cli
|
markdownlint-cli
|
||||||
luajitPackages.luacheck
|
luajitPackages.luacheck
|
||||||
|
@ -121,14 +133,23 @@
|
||||||
stylua
|
stylua
|
||||||
nixfmt-rfc-style
|
nixfmt-rfc-style
|
||||||
nodePackages.prettier
|
nodePackages.prettier
|
||||||
|
rustywind
|
||||||
markdownlint-cli2
|
markdownlint-cli2
|
||||||
# LSPs
|
# LSPs
|
||||||
|
nil # nix
|
||||||
lua-language-server
|
lua-language-server
|
||||||
|
vscode-langservers-extracted # HTML/CSS/JSON/ESLint
|
||||||
nodePackages.typescript-language-server
|
nodePackages.typescript-language-server
|
||||||
|
tailwindcss-language-server
|
||||||
nodePackages.pyright
|
nodePackages.pyright
|
||||||
|
rust-analyzer
|
||||||
# curl # http requests TODO
|
marksman # markdown
|
||||||
# nodePackages.cspell TODO
|
taplo #toml
|
||||||
|
yaml-language-server
|
||||||
|
lemminx # xml
|
||||||
|
# Other
|
||||||
|
# typescript
|
||||||
|
nodejs_20
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -152,6 +173,11 @@
|
||||||
"PATH"
|
"PATH"
|
||||||
":"
|
":"
|
||||||
"${lib.makeBinPath runtimeDependencies}"
|
"${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 the LAZY env path to the nix store, see init.lua for how it is used
|
||||||
"--set"
|
"--set"
|
||||||
"LAZY"
|
"LAZY"
|
||||||
|
|
14
init.lua
14
init.lua
|
@ -45,6 +45,13 @@ local function getSpec()
|
||||||
-- Convert plugins to use nix store, this auto sets the `dir` property for us on all plugins.
|
-- Convert plugins to use nix store, this auto sets the `dir` property for us on all plugins.
|
||||||
local function convertPluginToNixStore(plugin)
|
local function convertPluginToNixStore(plugin)
|
||||||
local p = ensure_table(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
|
if p.enabled == false then
|
||||||
return plugin
|
return plugin
|
||||||
end
|
end
|
||||||
|
@ -69,14 +76,11 @@ local function getSpec()
|
||||||
local plugins_path = debug.getinfo(2, "S").source:sub(2):match("(.*/)") .. "lua/plugins"
|
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
|
for _, file in ipairs(vim.fn.readdir(plugins_path, [[v:val =~ '\.lua$']])) do
|
||||||
local plugin = string.sub(file, 0, -5)
|
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
|
end
|
||||||
return plugins
|
return plugins
|
||||||
else
|
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" } }
|
return { { import = "plugins" } }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,58 +1,60 @@
|
||||||
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
|
-- Highlight when yanking (copying) text
|
||||||
-- Try it with `yap` in normal mode
|
-- Try it with `yap` in normal mode
|
||||||
-- See `:help vim.highlight.on_yank()`
|
-- See `:help vim.highlight.on_yank()`
|
||||||
vim.api.nvim_create_autocmd("TextYankPost", {
|
vim.api.nvim_create_autocmd("TextYankPost", {
|
||||||
group = group,
|
group = group,
|
||||||
desc = "Highlight when yanking (copying) text",
|
desc = "Highlight when yanking (copying) text",
|
||||||
callback = function()
|
callback = function()
|
||||||
vim.highlight.on_yank({ timeout = 300 })
|
vim.highlight.on_yank({ timeout = 300 })
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
-- TODO is there a better way for these?
|
-- TODO is there a better way for these?
|
||||||
|
-- https://www.youtube.com/watch?v=NecszftvMFI vim.filetype.add
|
||||||
vim.api.nvim_create_autocmd("BufRead", {
|
vim.api.nvim_create_autocmd("BufRead", {
|
||||||
group = group,
|
group = group,
|
||||||
pattern = ".env*",
|
pattern = ".env*",
|
||||||
command = "set filetype=sh",
|
command = "set filetype=sh",
|
||||||
})
|
})
|
||||||
vim.api.nvim_create_autocmd("BufRead", {
|
vim.api.nvim_create_autocmd("BufRead", {
|
||||||
group = group,
|
group = group,
|
||||||
pattern = ".*rc",
|
pattern = ".*rc",
|
||||||
command = "set filetype=sh",
|
command = "set filetype=sh",
|
||||||
})
|
})
|
||||||
vim.api.nvim_create_autocmd("BufRead", {
|
vim.api.nvim_create_autocmd("BufRead", {
|
||||||
group = group,
|
group = group,
|
||||||
pattern = "Dockerfile.*",
|
pattern = "Dockerfile.*",
|
||||||
command = "set filetype=dockerfile",
|
command = "set filetype=dockerfile",
|
||||||
})
|
})
|
||||||
vim.api.nvim_create_autocmd("BufRead", {
|
vim.api.nvim_create_autocmd("BufRead", {
|
||||||
group = group,
|
group = group,
|
||||||
pattern = "*.http",
|
pattern = "*.http",
|
||||||
command = "set filetype=http",
|
command = "set filetype=http",
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Auto exit insert mode whenever we switch screens
|
-- Auto exit insert mode whenever we switch screens
|
||||||
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
|
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
|
||||||
group = group,
|
group = group,
|
||||||
callback = function()
|
callback = function()
|
||||||
if vim.bo.filetype ~= "TelescopePrompt" and vim.bo.filetype ~= nil and vim.bo.filetype ~= "" then
|
if vim.bo.filetype ~= "TelescopePrompt" and vim.bo.filetype ~= nil and vim.bo.filetype ~= "" then
|
||||||
vim.api.nvim_command("stopinsert")
|
vim.api.nvim_command("stopinsert")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("VimLeavePre", {
|
vim.api.nvim_create_autocmd("VimLeavePre", {
|
||||||
group = group,
|
group = group,
|
||||||
callback = function()
|
callback = function()
|
||||||
vim.cmd("NvimTreeClose")
|
vim.cmd("NvimTreeClose")
|
||||||
-- Close all buffers with the 'httpResult' type
|
-- Close all buffers with the 'httpResult' type
|
||||||
local close_types = { "httpResult", "noice", "help" }
|
local close_types = { "httpResult", "noice", "help" }
|
||||||
local buffers = vim.api.nvim_list_bufs()
|
local buffers = vim.api.nvim_list_bufs()
|
||||||
for _, bufnr in ipairs(buffers) do
|
for _, bufnr in ipairs(buffers) do
|
||||||
if U.table_contains(close_types, vim.bo[bufnr].filetype) then
|
if U.table_contains(close_types, vim.bo[bufnr].filetype) then
|
||||||
vim.api.nvim_buf_delete(bufnr, { force = true })
|
vim.api.nvim_buf_delete(bufnr, { force = true })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -84,7 +84,7 @@ U.keymaps({
|
||||||
|
|
||||||
-- Editor
|
-- Editor
|
||||||
{ "J", "mzJ`z", desc = "Move line below onto this line" },
|
{ "J", "mzJ`z", desc = "Move line below onto this line" },
|
||||||
{ -- TODO stay here, are these already mapped?
|
{
|
||||||
"]d",
|
"]d",
|
||||||
vim.diagnostic.goto_next,
|
vim.diagnostic.goto_next,
|
||||||
desc = "Go to next diagnostic message",
|
desc = "Go to next diagnostic message",
|
||||||
|
@ -107,13 +107,12 @@ U.keymaps({
|
||||||
{ "<C-6>", "<Home>", mode = { "i", "c" }, desc = "Movements in insert/command mode" },
|
{ "<C-6>", "<Home>", mode = { "i", "c" }, desc = "Movements in insert/command mode" },
|
||||||
|
|
||||||
-- Tabs
|
-- Tabs
|
||||||
-- TODO revisit, do I even need these tab things?
|
|
||||||
{ "<leader>tn", "<cmd>tabnew<cr>", desc = "Create new tab", mode = nvx },
|
{ "<leader>tn", "<cmd>tabnew<cr>", desc = "Create new tab", mode = nvx },
|
||||||
{ "<leader>tq", "<cmd>tabclose<cr>", desc = "Close current tab", mode = nvx },
|
{ "<leader>tq", "<cmd>tabclose<cr>", desc = "Close current tab", mode = nvx },
|
||||||
{ "H", "<cmd>tabprevious<cr>", desc = "Move to previous tab" },
|
{ "H", "<cmd>tabprevious<cr>", desc = "Move to previous tab" },
|
||||||
{ "L", "<cmd>tabnext<cr>", desc = "Move to next tab" },
|
{ "L", "<cmd>tabnext<cr>", desc = "Move to next tab" },
|
||||||
|
|
||||||
-- LSP/IDE/etc TODO move to lsp config file
|
-- LSP/IDE/
|
||||||
{
|
{
|
||||||
"<leader>ld",
|
"<leader>ld",
|
||||||
vim.diagnostic.open_float,
|
vim.diagnostic.open_float,
|
||||||
|
|
|
@ -53,14 +53,12 @@ vim.opt.undofile = true
|
||||||
-- and `:help 'listchars'`
|
-- and `:help 'listchars'`
|
||||||
vim.opt.list = true
|
vim.opt.list = true
|
||||||
vim.opt.listchars = { tab = "│ ", trail = "·", nbsp = "␣", eol = "↴" }
|
vim.opt.listchars = { tab = "│ ", trail = "·", nbsp = "␣", eol = "↴" }
|
||||||
-- TODO REVISIT IF I WANT THESE
|
|
||||||
|
|
||||||
-- Search settings
|
-- Search settings
|
||||||
vim.opt.hlsearch = true
|
vim.opt.hlsearch = true
|
||||||
vim.opt.incsearch = true
|
vim.opt.incsearch = true
|
||||||
|
|
||||||
-- Preview substitutions live, as you type
|
-- Preview substitutions live, as you type
|
||||||
-- TODO revisit, what does this actually do
|
|
||||||
vim.opt.inccommand = "split"
|
vim.opt.inccommand = "split"
|
||||||
|
|
||||||
-- Show which line your cursor is on
|
-- Show which line your cursor is on
|
||||||
|
|
|
@ -1,103 +1,127 @@
|
||||||
return {
|
return {
|
||||||
"hrsh7th/nvim-cmp",
|
"hrsh7th/nvim-cmp",
|
||||||
event = "InsertEnter",
|
event = "InsertEnter",
|
||||||
dependencies = {
|
dependencies = {
|
||||||
-- Snippet Engine & its associated nvim-cmp source
|
-- Snippet Engine & its associated nvim-cmp source
|
||||||
{
|
{
|
||||||
"L3MON4D3/LuaSnip",
|
"L3MON4D3/LuaSnip",
|
||||||
dependencies = {
|
dependencies = {
|
||||||
-- TODO use or remove this?
|
{
|
||||||
-- `friendly-snippets` contains a variety of premade snippets.
|
"rafamadriz/friendly-snippets",
|
||||||
-- See the README about individual language/framework/plugin snippets:
|
config = function()
|
||||||
-- https://github.com/rafamadriz/friendly-snippets
|
require("luasnip.loaders.from_vscode").lazy_load()
|
||||||
-- {
|
end,
|
||||||
-- 'rafamadriz/friendly-snippets',
|
},
|
||||||
-- config = function()
|
},
|
||||||
-- require('luasnip.loaders.from_vscode').lazy_load()
|
},
|
||||||
-- end,
|
"saadparwaiz1/cmp_luasnip",
|
||||||
-- },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"saadparwaiz1/cmp_luasnip",
|
|
||||||
|
|
||||||
-- Adds other completion capabilities.
|
-- Adds other completion capabilities.
|
||||||
-- nvim-cmp does not ship with all sources by default. They are split
|
-- nvim-cmp does not ship with all sources by default. They are split
|
||||||
-- into multiple repos for maintenance purposes.
|
-- into multiple repos for maintenance purposes.
|
||||||
"hrsh7th/cmp-nvim-lsp",
|
"hrsh7th/cmp-nvim-lsp",
|
||||||
"hrsh7th/cmp-path",
|
"hrsh7th/cmp-buffer",
|
||||||
},
|
"hrsh7th/cmp-path",
|
||||||
config = function()
|
{
|
||||||
-- See `:help cmp`
|
"zbirenbaum/copilot.lua",
|
||||||
local cmp = require("cmp")
|
cmd = "Copilot",
|
||||||
local luasnip = require("luasnip")
|
event = "InsertEnter",
|
||||||
luasnip.config.setup({})
|
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`
|
||||||
|
local cmp = require("cmp")
|
||||||
|
local luasnip = require("luasnip")
|
||||||
|
luasnip.config.setup({})
|
||||||
|
|
||||||
cmp.setup({
|
cmp.setup({
|
||||||
snippet = {
|
snippet = {
|
||||||
expand = function(args)
|
expand = function(args)
|
||||||
luasnip.lsp_expand(args.body)
|
luasnip.lsp_expand(args.body)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
completion = { completeopt = "menu,menuone,noinsert" },
|
completion = { completeopt = "menu,menuone,noinsert" },
|
||||||
|
|
||||||
-- For an understanding of why these mappings were
|
mapping = cmp.mapping.preset.insert({
|
||||||
-- chosen, you will need to read `:help ins-completion`
|
-- Scroll the documentation window [b]ack / [f]orward
|
||||||
--
|
["<C-u>"] = cmp.mapping.scroll_docs(-4),
|
||||||
-- No, but seriously. Please read `:help ins-completion`, it is really good!
|
["<C-d>"] = cmp.mapping.scroll_docs(4),
|
||||||
mapping = cmp.mapping.preset.insert({
|
["<esc>"] = cmp.mapping(function(fallback)
|
||||||
-- Select the [n]ext item
|
if cmp.visible() then
|
||||||
["<C-j>"] = cmp.mapping.select_next_item(),
|
cmp.abort()
|
||||||
-- Select the [p]revious item
|
fallback()
|
||||||
["<C-k>"] = cmp.mapping.select_prev_item(),
|
else
|
||||||
|
fallback()
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
|
||||||
-- Scroll the documentation window [b]ack / [f]orward
|
-- Select the [n]ext item
|
||||||
["<C-u>"] = cmp.mapping.scroll_docs(-4),
|
["<C-j>"] = cmp.mapping(function(fallback)
|
||||||
["<C-d>"] = cmp.mapping.scroll_docs(4),
|
if cmp.visible() then
|
||||||
|
cmp.select_next_item()
|
||||||
-- Accept ([y]es) the completion.
|
-- elseif luasnip.expand_or_jumpable() then
|
||||||
-- This will auto-import if your LSP supports it.
|
elseif luasnip.expand_or_locally_jumpable() then
|
||||||
-- This will expand snippets if the LSP sent a snippet.
|
luasnip.expand_or_jump()
|
||||||
["<C-y>"] = cmp.mapping.confirm({ select = true }),
|
else
|
||||||
|
fallback()
|
||||||
-- If you prefer more traditional completion keymaps,
|
end
|
||||||
-- you can uncomment the following lines
|
end, { "i", "s" }),
|
||||||
--['<CR>'] = cmp.mapping.confirm { select = true },
|
-- Select the [p]revious item
|
||||||
--['<Tab>'] = cmp.mapping.select_next_item(),
|
["<C-k>"] = cmp.mapping(function(fallback)
|
||||||
--['<S-Tab>'] = cmp.mapping.select_prev_item(),
|
if cmp.visible() then
|
||||||
|
cmp.select_prev_item()
|
||||||
-- Manually trigger a completion from nvim-cmp.
|
elseif luasnip.jumpable(-1) then
|
||||||
-- Generally you don't need this, because nvim-cmp will display
|
luasnip.jump(-1)
|
||||||
-- completions whenever it has completion options available.
|
else
|
||||||
["<C-c>"] = cmp.mapping.complete({}),
|
fallback()
|
||||||
|
end
|
||||||
-- TODO remove these or make them soemthing else, this collided with my normal movements in insert mode
|
end, { "i", "s" }),
|
||||||
-- Think of <c-l> as moving to the right of your snippet expansion.
|
["<C-y>"] = cmp.mapping.confirm({ select = true }),
|
||||||
-- So if you have a snippet that's like:
|
["<C-space>"] = cmp.mapping.complete({}),
|
||||||
-- function $name($args)
|
}),
|
||||||
-- $body
|
sources = {
|
||||||
-- end
|
{
|
||||||
--
|
name = "copilot",
|
||||||
-- <c-l> will move you to the right of each of the expansion locations.
|
priority = 9,
|
||||||
-- <c-h> is similar, except moving you backwards.
|
keyword_length = 1,
|
||||||
-- ["<C-l>"] = cmp.mapping(function()
|
filter = function(keyword)
|
||||||
-- if luasnip.expand_or_locally_jumpable() then
|
-- Check if keyword length is some number and not just whitespace
|
||||||
-- luasnip.expand_or_jump()
|
if #keyword < 2 or keyword:match("^%s*$") then
|
||||||
-- end
|
return false
|
||||||
-- end, { "i", "s" }),
|
end
|
||||||
-- ["<C-h>"] = cmp.mapping(function()
|
return true
|
||||||
-- if luasnip.locally_jumpable(-1) then
|
end,
|
||||||
-- luasnip.jump(-1)
|
},
|
||||||
-- end
|
{ name = "nvim_lsp", priority = 8, max_item_count = 100 },
|
||||||
-- end, { "i", "s" }),
|
{ name = "luasnip", priority = 7 },
|
||||||
|
-- This source provides file path completions, helping you to complete file paths in your code
|
||||||
-- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
|
{ name = "path", priority = 7 },
|
||||||
-- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
|
-- 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 },
|
||||||
sources = {
|
-- Rust crates.io integration
|
||||||
{ name = "nvim_lsp" },
|
{ name = "crates" },
|
||||||
{ name = "luasnip" },
|
},
|
||||||
{ name = "path" },
|
-- TODO revisit if I want these or not
|
||||||
},
|
-- sorting = {
|
||||||
})
|
-- priority_weight = 1,
|
||||||
end,
|
-- 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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,137 +1,133 @@
|
||||||
-- 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 function lsp_clients()
|
||||||
local clients = {}
|
local clients = {}
|
||||||
for _, client in pairs(vim.lsp.buf_get_clients(0)) do
|
for _, client in pairs(vim.lsp.buf_get_clients(0)) do
|
||||||
local name = client.name
|
clients[#clients + 1] = client.name
|
||||||
-- TODO revisit this doesn't work
|
end
|
||||||
if not client.initialized then
|
table.sort(clients)
|
||||||
name = name .. " (loading)"
|
return table.concat(clients, " • "), " "
|
||||||
end
|
|
||||||
clients[#clients + 1] = name
|
|
||||||
end
|
|
||||||
|
|
||||||
table.sort(clients)
|
|
||||||
return table.concat(clients, " • "), " "
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function langs()
|
local function langs()
|
||||||
local l = {}
|
local l = {}
|
||||||
for _, client in pairs(vim.lsp.buf_get_clients(0)) do
|
for _, client in pairs(vim.lsp.buf_get_clients(0)) do
|
||||||
local out = nil
|
local out = nil
|
||||||
if client.name == "pyright" then
|
if client.name == "pyright" then
|
||||||
out = vim.fn.system({ "python", "-V" })
|
out = vim.fn.system({ "python", "-V" })
|
||||||
elseif client.name == "tsserver" then
|
elseif client.name == "tsserver" then
|
||||||
out = "node " .. vim.fn.system({ "node", "--version" })
|
out = "node " .. vim.fn.system({ "node", "--version" })
|
||||||
end
|
end
|
||||||
if out ~= nil and out ~= "" then
|
if out ~= nil and out ~= "" then
|
||||||
l[#l + 1] = vim.trim(out)
|
l[#l + 1] = vim.trim(out)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(l)
|
table.sort(l)
|
||||||
return table.concat(l, " • "), " "
|
return table.concat(l, " • "), " "
|
||||||
end
|
end
|
||||||
|
|
||||||
local last_blame = nil
|
local last_blame = nil
|
||||||
local last_blame_time = vim.loop.now()
|
local last_blame_time = vim.loop.now()
|
||||||
local function gitblame()
|
local function gitblame()
|
||||||
local d = vim.b.gitsigns_blame_line_dict
|
local d = vim.b.gitsigns_blame_line_dict
|
||||||
|
|
||||||
if d then
|
if d then
|
||||||
last_blame = d
|
last_blame = d
|
||||||
last_blame_time = vim.loop.now()
|
last_blame_time = vim.loop.now()
|
||||||
elseif vim.loop.now() - last_blame_time <= 2000 then
|
elseif vim.loop.now() - last_blame_time <= 2000 then
|
||||||
d = last_blame
|
d = last_blame
|
||||||
end
|
end
|
||||||
|
|
||||||
if d then
|
if d then
|
||||||
local ok, res = pcall(os.date, "%d %b %y", d.committer_time)
|
local ok, res = pcall(os.date, "%d %b %y", d.committer_time)
|
||||||
return d.committer:sub(1, 12) .. " - " .. (ok and res or d.committer_time)
|
return d.committer:sub(1, 12) .. " - " .. (ok and res or d.committer_time)
|
||||||
end
|
end
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"nvim-lualine/lualine.nvim",
|
"nvim-lualine/lualine.nvim",
|
||||||
dependencies = { { "folke/noice.nvim", optional = true } },
|
dependencies = { { "folke/noice.nvim", optional = true } },
|
||||||
lazy = false,
|
lazy = false,
|
||||||
opts = function()
|
opts = function()
|
||||||
return {
|
return {
|
||||||
options = {
|
options = {
|
||||||
theme = "codedark",
|
theme = "codedark",
|
||||||
section_separators = { left = "", right = "" },
|
section_separators = { left = "", right = "" },
|
||||||
component_separators = "|",
|
component_separators = "|",
|
||||||
},
|
},
|
||||||
sections = {
|
sections = {
|
||||||
lualine_a = { "mode" },
|
lualine_a = { "mode" },
|
||||||
lualine_b = { "branch", "diff", "diagnostics" },
|
lualine_b = {
|
||||||
lualine_c = {
|
"branch",
|
||||||
{ "filename", separator = { right = "" } },
|
"filename",
|
||||||
{ "reg_recording", icon = { "" }, color = { fg = "#D37676" } },
|
},
|
||||||
{ gitblame, color = { fg = "#696969" } },
|
lualine_c = {
|
||||||
},
|
"diff",
|
||||||
lualine_x = {
|
"diagnostics",
|
||||||
lsp_clients,
|
{ "reg_recording", icon = { "" }, color = { fg = "#D37676" } },
|
||||||
langs,
|
{ gitblame, color = { fg = "#696969" } },
|
||||||
"encoding",
|
},
|
||||||
"filetype",
|
lualine_x = {
|
||||||
"filesize",
|
lsp_clients,
|
||||||
},
|
langs,
|
||||||
lualine_y = { "searchcount", "selectioncount" },
|
"encoding",
|
||||||
lualine_z = { "location" },
|
"filetype",
|
||||||
},
|
"filesize",
|
||||||
winbar = {
|
},
|
||||||
lualine_a = {
|
lualine_y = { "searchcount", "selectioncount" },
|
||||||
{
|
lualine_z = { "location" },
|
||||||
"filename",
|
},
|
||||||
symbols = {
|
winbar = {
|
||||||
modified = "", -- Text to show when the file is modified.
|
lualine_a = {
|
||||||
readonly = "[-]", -- Text to show when the file is non-modifiable or readonly.
|
{
|
||||||
unnamed = "[No Name]", -- Text to show for unnamed buffers.
|
"filename",
|
||||||
newfile = "[New]", -- Text to show for newly created file before first write
|
symbols = {
|
||||||
},
|
modified = "", -- Text to show when the file is modified.
|
||||||
},
|
readonly = "[-]", -- Text to show when the file is non-modifiable or readonly.
|
||||||
},
|
unnamed = "[No Name]", -- Text to show for unnamed buffers.
|
||||||
lualine_b = {
|
newfile = "[New]", -- Text to show for newly created file before first write
|
||||||
"mode",
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
inactive_winbar = {
|
lualine_b = {
|
||||||
lualine_a = {
|
"mode",
|
||||||
{
|
},
|
||||||
"filename",
|
},
|
||||||
symbols = {
|
inactive_winbar = {
|
||||||
modified = "", -- Text to show when the file is modified.
|
lualine_a = {
|
||||||
readonly = "[-]", -- Text to show when the file is non-modifiable or readonly.
|
{
|
||||||
unnamed = "[No Name]", -- Text to show for unnamed buffers.
|
"filename",
|
||||||
newfile = "[New]", -- Text to show for newly created file before first write
|
symbols = {
|
||||||
},
|
modified = "", -- Text to show when the file is modified.
|
||||||
},
|
readonly = "[-]", -- Text to show when the file is non-modifiable or readonly.
|
||||||
},
|
unnamed = "[No Name]", -- Text to show for unnamed buffers.
|
||||||
},
|
newfile = "[New]", -- Text to show for newly created file before first write
|
||||||
}
|
},
|
||||||
end,
|
},
|
||||||
config = function(_, opts)
|
},
|
||||||
require("lualine").setup(opts)
|
},
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
config = function(_, opts)
|
||||||
|
require("lualine").setup(opts)
|
||||||
|
|
||||||
local ref = function()
|
local ref = function()
|
||||||
require("lualine").refresh({
|
require("lualine").refresh({
|
||||||
place = { "statusline" },
|
place = { "statusline" },
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local group = vim.api.nvim_create_augroup("myconfig-lua-line-group", { clear = true })
|
local group = vim.api.nvim_create_augroup("myconfig-lua-line-group", { clear = true })
|
||||||
vim.api.nvim_create_autocmd("RecordingEnter", {
|
vim.api.nvim_create_autocmd("RecordingEnter", {
|
||||||
group = group,
|
group = group,
|
||||||
callback = ref,
|
callback = ref,
|
||||||
})
|
})
|
||||||
vim.api.nvim_create_autocmd("RecordingLeave", {
|
vim.api.nvim_create_autocmd("RecordingLeave", {
|
||||||
group = group,
|
group = group,
|
||||||
callback = function()
|
callback = function()
|
||||||
local timer = vim.loop.new_timer()
|
local timer = vim.loop.new_timer()
|
||||||
timer:start(50, 0, vim.schedule_wrap(ref))
|
timer:start(50, 0, vim.schedule_wrap(ref))
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,6 @@ return {
|
||||||
},
|
},
|
||||||
event = "VeryLazy",
|
event = "VeryLazy",
|
||||||
opts = {
|
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 = {
|
messages = {
|
||||||
view = "mini", -- default view for messages
|
view = "mini", -- default view for messages
|
||||||
view_error = "notify", -- view for errors
|
view_error = "notify", -- view for errors
|
||||||
|
@ -26,6 +21,8 @@ return {
|
||||||
["vim.lsp.util.stylize_markdown"] = true,
|
["vim.lsp.util.stylize_markdown"] = true,
|
||||||
["cmp.entry.get_documentation"] = true, -- requires hrsh7th/nvim-cmp
|
["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)
|
config = function(_, opts)
|
||||||
|
|
|
@ -1,36 +1,45 @@
|
||||||
|
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 {
|
return {
|
||||||
"stevearc/conform.nvim",
|
"stevearc/conform.nvim",
|
||||||
opts = {
|
opts = {
|
||||||
-- https://github.com/stevearc/conform.nvim?tab=readme-ov-file#setup
|
-- https://github.com/stevearc/conform.nvim?tab=readme-ov-file#setup
|
||||||
notify_on_error = true,
|
notify_on_error = true,
|
||||||
-- Note that all these need to be available at runtime, add them to flake.nix#runtimeDependencies
|
-- Note that all these need to be available at runtime, add them to flake.nix#runtimeDependencies
|
||||||
formatters_by_ft = {
|
formatters_by_ft = {
|
||||||
lua = { "stylua" },
|
lua = { "stylua" },
|
||||||
nix = { "nixfmt" },
|
nix = { "nixfmt" },
|
||||||
typescript = { { "prettierd", "prettier" } },
|
typescript = { { "prettierd", "prettier" }, "rustywind" },
|
||||||
typescriptreact = { { "prettierd", "prettier" } },
|
typescriptreact = { { "prettierd", "prettier" }, "rustywind" },
|
||||||
javascript = { { "prettierd", "prettier" } },
|
javascript = { { "prettierd", "prettier" }, "rustywind" },
|
||||||
javascriptreact = { { "prettierd", "prettier" } },
|
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/
|
-- TODO revisit these I'd like to use them but they are not in nixpkgs yet
|
||||||
-- markdown = { "mdslw", "mdsf"},
|
-- https://nixos.org/guides/nix-pills/
|
||||||
markdown = { "markdownlint-cli2" },
|
-- markdown = { "mdslw", "mdsf"},
|
||||||
|
markdown = { "markdownlint-cli2" },
|
||||||
|
-- rust = { "rustfmt" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keys = {
|
keys = {
|
||||||
{
|
{
|
||||||
"<leader>l<leader>",
|
"<leader>l<leader>",
|
||||||
function()
|
formatCurrent,
|
||||||
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,
|
|
||||||
mode = { "n", "v", "x" },
|
mode = { "n", "v", "x" },
|
||||||
desc = "Format buffer",
|
desc = "Format buffer",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,145 +1,176 @@
|
||||||
return {
|
return {
|
||||||
"neovim/nvim-lspconfig",
|
-- LSP helper plugins for various languages
|
||||||
event = "BufEnter",
|
{ "folke/neodev.nvim", event = { "BufRead *.lua", "BufRead *.vim" }, opts = {}, main = "neodev" },
|
||||||
dependencies = {
|
{ "mrcjkb/rustaceanvim", lazy = false }, -- uses ftplugins to enable itself lazily already
|
||||||
-- Automatically install LSPs and related tools to stdpath for Neovim
|
-- TODO add some hotkeys for opening the popup menus on crates
|
||||||
{ "williamboman/mason.nvim", enabled = not NIX, config = true }, -- NOTE: Must be loaded before dependants
|
{ "Saecki/crates.nvim", event = "BufRead Cargo.toml", tag = "stable", opts = {}, main = "crates" },
|
||||||
{ "williamboman/mason-lspconfig.nvim", enabled = not NIX },
|
{
|
||||||
{ "WhoIsSethDaniel/mason-tool-installer.nvim", enabled = not NIX },
|
"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
|
||||||
|
|
||||||
-- TODO revisit if I want this or not, is this already solved?
|
local bufnr = args.buf
|
||||||
-- Useful status updates for LSP.
|
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||||
-- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})`
|
require("lsp-inlayhints").on_attach(client, bufnr)
|
||||||
-- { "j-hui/fidget.nvim", opts = {} },
|
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 },
|
||||||
|
},
|
||||||
|
config = function()
|
||||||
|
vim.api.nvim_create_autocmd("LspAttach", {
|
||||||
|
group = vim.api.nvim_create_augroup("myconfig-lsp-attach", { clear = true }),
|
||||||
|
callback = function(event)
|
||||||
|
local map = function(keys, func, desc)
|
||||||
|
vim.keymap.set("n", keys, func, { buffer = event.buf, desc = "LSP: " .. desc })
|
||||||
|
end
|
||||||
|
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")
|
||||||
|
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")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
-- `neodev` configures Lua LSP for your Neovim config, runtime and plugins
|
vim.api.nvim_create_autocmd("LspDetach", {
|
||||||
-- used for completion, annotations and signatures of Neovim apis
|
group = vim.api.nvim_create_augroup("myconfig-lsp-detach", { clear = true }),
|
||||||
{ "folke/neodev.nvim", opts = {}, main = "neodev" },
|
callback = function(event)
|
||||||
},
|
vim.lsp.buf.clear_references()
|
||||||
config = function()
|
vim.api.nvim_clear_autocmds({ group = "myconfig-lsp-highlight", buffer = event.buf })
|
||||||
vim.api.nvim_create_autocmd("LspAttach", {
|
end,
|
||||||
group = vim.api.nvim_create_augroup("myconfig-lsp-attach", { clear = true }),
|
})
|
||||||
callback = function(event)
|
|
||||||
local map = function(keys, func, desc)
|
|
||||||
vim.keymap.set("n", keys, func, { buffer = event.buf, desc = "LSP: " .. desc })
|
|
||||||
end
|
|
||||||
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)
|
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||||
if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
|
U.safeRequire("cmp_nvim_lsp", function(c)
|
||||||
map("<leader>lth", function()
|
capabilities = vim.tbl_deep_extend("force", capabilities, c.default_capabilities())
|
||||||
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
|
end)
|
||||||
end, "Toggle Inlay Hints")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("LspDetach", {
|
-- TODO finish porting over lsp configs: https://github.com/RingOfStorms/nvim/blob/master/lua/plugins/lsp.lua
|
||||||
group = vim.api.nvim_create_augroup("myconfig-lsp-detach", { clear = true }),
|
local servers = {
|
||||||
callback = function(event)
|
-- Some languages (like typescript) have entire language plugins that can be useful:
|
||||||
vim.lsp.buf.clear_references()
|
-- https://github.com/pmizio/typescript-tools.nvim
|
||||||
vim.api.nvim_clear_autocmds({ group = "myconfig-lsp-highlight", buffer = event.buf })
|
--
|
||||||
end,
|
-- But for many setups, the LSP (`tsserver`) will work just fine
|
||||||
})
|
-- Note that `rust-analyzer` is done via mrcjkb/rustaceanvim plugin above, do not register it here.
|
||||||
|
lua_ls = {
|
||||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
settings = {
|
||||||
U.safeRequire("cmp_nvim_lsp", function(c)
|
Lua = {
|
||||||
capabilities = vim.tbl_deep_extend("force", capabilities, c.default_capabilities())
|
runtime = {
|
||||||
end)
|
-- Tell the language server which version of Lua you're using
|
||||||
|
-- (most likely LuaJIT in the case of Neovim)
|
||||||
-- TODO finish porting over lsp configs: https://github.com/RingOfStorms/nvim/blob/master/lua/plugins/lsp.lua
|
version = "LuaJIT",
|
||||||
local servers = {
|
},
|
||||||
-- clangd = {},
|
completion = {
|
||||||
-- gopls = {},
|
callSnippet = "Replace",
|
||||||
-- pyright = {},
|
},
|
||||||
-- rust_analyzer = {},
|
workspace = {
|
||||||
-- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs
|
checkThirdParty = false,
|
||||||
--
|
library = {
|
||||||
-- Some languages (like typescript) have entire language plugins that can be useful:
|
vim.env.VIMRUNTIME,
|
||||||
-- https://github.com/pmizio/typescript-tools.nvim
|
vim.api.nvim_get_runtime_file("", true),
|
||||||
--
|
vim.fn.expand("$VIMRUNTIME/lua"),
|
||||||
-- But for many setups, the LSP (`tsserver`) will work just fine
|
vim.fn.expand("$VIMRUNTIME/lua/vim/lsp"),
|
||||||
tsserver = {
|
},
|
||||||
-- typescript/javascript
|
telemetry = { enable = false },
|
||||||
implicitProjectConfiguration = {
|
diagnostics = {
|
||||||
checkJs = true,
|
globals = {
|
||||||
},
|
"vim",
|
||||||
},
|
"require",
|
||||||
pyright = {
|
"NIX",
|
||||||
-- python
|
"U",
|
||||||
},
|
-- Hammerspoon for macos
|
||||||
lua_ls = {
|
"hs",
|
||||||
-- cmd = { ... },
|
},
|
||||||
-- filetypes = { ...},
|
},
|
||||||
-- capabilities = {},
|
},
|
||||||
settings = {
|
},
|
||||||
Lua = {
|
},
|
||||||
runtime = {
|
},
|
||||||
-- Tell the language server which version of Lua you're using
|
nil_ls = {},
|
||||||
-- (most likely LuaJIT in the case of Neovim)
|
tsserver = {
|
||||||
version = "LuaJIT",
|
-- typescript/javascript
|
||||||
},
|
implicitProjectConfiguration = {
|
||||||
completion = {
|
checkJs = true,
|
||||||
callSnippet = "Replace",
|
},
|
||||||
},
|
},
|
||||||
workspace = {
|
tailwindcss = {
|
||||||
checkThirdParty = false,
|
-- tailwind css
|
||||||
library = {
|
-- https://www.tailwind-variants.org/docs/getting-started#intellisense-setup-optional
|
||||||
vim.env.VIMRUNTIME,
|
tailwindCSS = {
|
||||||
vim.api.nvim_get_runtime_file("", true),
|
experimental = {
|
||||||
vim.fn.expand("$VIMRUNTIME/lua"),
|
classRegex = {
|
||||||
vim.fn.expand("$VIMRUNTIME/lua/vim/lsp"),
|
{ "tv\\((([^()]*|\\([^()]*\\))*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]" },
|
||||||
},
|
},
|
||||||
telemetry = { enable = false },
|
},
|
||||||
diagnostics = {
|
},
|
||||||
globals = {
|
},
|
||||||
"vim",
|
cssls = {
|
||||||
"require",
|
-- css
|
||||||
"NIX",
|
},
|
||||||
"U",
|
jsonls = {
|
||||||
-- Hammerspoon
|
-- json
|
||||||
"hs",
|
},
|
||||||
},
|
pyright = {
|
||||||
},
|
-- python
|
||||||
},
|
},
|
||||||
-- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings
|
marksman = {
|
||||||
-- diagnostics = { disable = { 'missing-fields' } },
|
-- markdown
|
||||||
},
|
},
|
||||||
},
|
taplo = {
|
||||||
},
|
-- toml
|
||||||
}
|
},
|
||||||
if NIX then
|
yamlls = {
|
||||||
local servers = vim.tbl_keys(servers or {})
|
-- yaml
|
||||||
for _, server_name in ipairs(servers) do
|
},
|
||||||
local server_opts = servers[server_name] or {}
|
lemminx = {
|
||||||
require("lspconfig")[server_name].setup(server_opts)
|
-- xml
|
||||||
end
|
},
|
||||||
else
|
}
|
||||||
require("mason").setup()
|
if NIX then
|
||||||
local ensure_installed = vim.tbl_keys(servers or {})
|
local lsp_servers = vim.tbl_keys(servers or {})
|
||||||
vim.list_extend(ensure_installed, {
|
for _, server_name in ipairs(lsp_servers) do
|
||||||
"stylua", -- Used to format Lua code TODO come back to this, more about linter/formatter configs
|
local server_opts = servers[server_name] or {}
|
||||||
})
|
require("lspconfig")[server_name].setup(server_opts)
|
||||||
require("mason-tool-installer").setup({ ensure_installed = ensure_installed })
|
end
|
||||||
require("mason-lspconfig").setup({
|
else
|
||||||
handlers = {
|
-- TODO test this out on a non nix setup...
|
||||||
function(server_name)
|
require("mason").setup()
|
||||||
local server = servers[server_name] or {}
|
local ensure_installed = vim.tbl_keys(servers or {})
|
||||||
server.capabilities = vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {})
|
vim.list_extend(ensure_installed, {
|
||||||
require("lspconfig")[server_name].setup(server)
|
"stylua", -- Used to format Lua code TODO come back to this, more about linter/formatter configs
|
||||||
end,
|
})
|
||||||
},
|
require("mason-tool-installer").setup({ ensure_installed = ensure_installed })
|
||||||
})
|
require("mason-lspconfig").setup({
|
||||||
end
|
handlers = {
|
||||||
end,
|
function(server_name)
|
||||||
|
local server = servers[server_name] or {}
|
||||||
|
server.capabilities =
|
||||||
|
vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {})
|
||||||
|
require("lspconfig")[server_name].setup(server)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ return {
|
||||||
"<leader>,c",
|
"<leader>,c",
|
||||||
function()
|
function()
|
||||||
if next(vim.lsp.get_active_clients()) ~= nil then
|
if next(vim.lsp.get_active_clients()) ~= nil then
|
||||||
-- TODO test that this works
|
|
||||||
vim.cmd("TextCaseOpenTelescopeLSPChange")
|
vim.cmd("TextCaseOpenTelescopeLSPChange")
|
||||||
else
|
else
|
||||||
vim.cmd("TextCaseOpenTelescope")
|
vim.cmd("TextCaseOpenTelescope")
|
||||||
|
|
|
@ -15,15 +15,15 @@ return {
|
||||||
local wk = require("which-key")
|
local wk = require("which-key")
|
||||||
wk.setup(opts)
|
wk.setup(opts)
|
||||||
wk.register({
|
wk.register({
|
||||||
["<leader>b"] = { name = "Buffers", mode = { "n", "x", "v", "c" } },
|
["<leader>b"] = { name = "Buffers", mode = { "n", "x", "v" } },
|
||||||
["<leader>t"] = { name = "Tabs", mode = { "n", "x", "v", "c" } },
|
["<leader>t"] = { name = "Tabs", mode = { "n", "x", "v" } },
|
||||||
["<leader>,"] = { name = "Miscellaneous Tools", mode = { "n", "x", "v", "c" } },
|
["<leader>,"] = { name = "Miscellaneous Tools", mode = { "n", "x", "v" } },
|
||||||
-- ["<leader>c"] = { name = "Copilot" },
|
-- ["<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>fs"] = { name = "Find in Scratches [Telescope]" },
|
||||||
["<leader>g"] = { name = "Git", mode = { "n", "x", "v", "c" } },
|
["<leader>g"] = { name = "Git", mode = { "n", "x", "v" } },
|
||||||
["<leader>l"] = { name = "LSP", mode = { "n", "x", "v", "c" } },
|
["<leader>l"] = { name = "LSP", mode = { "n", "x", "v" } },
|
||||||
["<leader>lf"] = { name = "LSP Find", mode = { "n", "x", "v", "c" } },
|
["<leader>lf"] = { name = "LSP Find", mode = { "n", "x", "v" } },
|
||||||
-- ["<leader>Q"] = { name = "+Q Quit and remove session" },
|
-- ["<leader>Q"] = { name = "+Q Quit and remove session" },
|
||||||
-- ["<leader>s"] = { name = "Scratch Files" },
|
-- ["<leader>s"] = { name = "Scratch Files" },
|
||||||
-- ["<leader>x"] = { name = "Generative AI, Ollama" },
|
-- ["<leader>x"] = { name = "Generative AI, Ollama" },
|
||||||
|
|
213
lua/util.lua
213
lua/util.lua
|
@ -1,30 +1,41 @@
|
||||||
local M = {}
|
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)
|
function M.cmd_executable(cmd, callback)
|
||||||
local executable = vim.fn.executable(cmd) == 1
|
local executable = vim.fn.executable(cmd) == 1
|
||||||
-- Check if a callback is provided and it is a function
|
-- Check if a callback is provided and it is a function
|
||||||
if executable and callback and type(callback) == "function" then
|
if executable and callback and type(callback) == "function" then
|
||||||
callback()
|
callback()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if a callback is provided and it is a table
|
-- Check if a callback is provided and it is a table
|
||||||
if type(callback) == "table" then
|
if type(callback) == "table" then
|
||||||
if executable and (callback[1] or callback[true]) then
|
if executable and (callback[1] or callback[true]) then
|
||||||
-- Call the function associated with key 1 or true if the command is executable
|
-- Call the function associated with key 1 or true if the command is executable
|
||||||
local func = callback[1] or callback[true]
|
local func = callback[1] or callback[true]
|
||||||
if type(func) == "function" then
|
if type(func) == "function" then
|
||||||
func()
|
func()
|
||||||
end
|
end
|
||||||
elseif not executable and (callback[2] or callback[false]) then
|
elseif not executable and (callback[2] or callback[false]) then
|
||||||
-- Call the function associated with key 2 or false if the command is not executable
|
-- Call the function associated with key 2 or false if the command is not executable
|
||||||
local func = callback[2] or callback[false]
|
local func = callback[2] or callback[false]
|
||||||
if type(func) == "function" then
|
if type(func) == "function" then
|
||||||
func()
|
func()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return executable
|
return executable
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [1]: (string) lhs (required)
|
-- [1]: (string) lhs (required)
|
||||||
|
@ -33,127 +44,115 @@ end
|
||||||
-- ft: (string|string[]) filetype for buffer-local keymaps (optional)
|
-- ft: (string|string[]) filetype for buffer-local keymaps (optional)
|
||||||
-- any other option valid for vim.keymap.set
|
-- any other option valid for vim.keymap.set
|
||||||
function M.keymaps(keymaps)
|
function M.keymaps(keymaps)
|
||||||
-- is not an array, will pass directly to keymaps
|
-- is not an array, will pass directly to keymaps
|
||||||
if type(keymaps[1]) == "string" then
|
if type(keymaps[1]) == "string" then
|
||||||
M.keymap(keymaps)
|
M.keymap(keymaps)
|
||||||
else
|
else
|
||||||
-- is array will iterate over
|
-- is array will iterate over
|
||||||
for _, keymap in pairs(keymaps) do
|
for _, keymap in pairs(keymaps) do
|
||||||
M.keymap(keymap)
|
M.keymap(keymap)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.keymap(keymap)
|
function M.keymap(keymap)
|
||||||
local lhs = keymap[1]
|
local lhs = keymap[1]
|
||||||
local rhs = keymap[2]
|
local rhs = keymap[2]
|
||||||
local mode = keymap["mode"] or "n"
|
local mode = keymap["mode"] or "n"
|
||||||
local opts = { silent = true }
|
local opts = { silent = true }
|
||||||
for key, value in pairs(keymap) do
|
for key, value in pairs(keymap) do
|
||||||
if type(key) ~= "number" and key ~= "mode" then
|
if type(key) ~= "number" and key ~= "mode" then
|
||||||
opts[key] = value
|
opts[key] = value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local status, err = pcall(function()
|
local status, err = pcall(function()
|
||||||
vim.keymap.set(mode, lhs, rhs, opts)
|
vim.keymap.set(mode, lhs, rhs, opts)
|
||||||
end)
|
end)
|
||||||
if not status then
|
if not status then
|
||||||
vim.notify("Failed to create keymap: " .. err, 3)
|
vim.notify("Failed to create keymap: " .. err, 3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- spread({})({})
|
-- spread({})({})
|
||||||
function M.spread(template)
|
function M.spread(template)
|
||||||
local result = {}
|
local result = {}
|
||||||
for key, value in pairs(template) do
|
for key, value in pairs(template) do
|
||||||
result[key] = value
|
result[key] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
return function(table)
|
return function(table)
|
||||||
for key, value in pairs(table) do
|
for key, value in pairs(table) do
|
||||||
result[key] = value
|
result[key] = value
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- assign({}, {})
|
-- assign({}, {})
|
||||||
function M.assign(obj, assign)
|
function M.assign(obj, assign)
|
||||||
for key, value in pairs(assign) do
|
for key, value in pairs(assign) do
|
||||||
obj[key] = value
|
obj[key] = value
|
||||||
end
|
end
|
||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.table_contains(table, element)
|
function M.table_contains(table, element)
|
||||||
for _, value in pairs(table) do
|
for _, value in pairs(table) do
|
||||||
if value == element then
|
if value == element then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- From https://github.com/lukas-reineke/onedark.nvim/blob/master/lua/onedark.lua
|
-- From https://github.com/lukas-reineke/onedark.nvim/blob/master/lua/onedark.lua
|
||||||
function M.highlight(group, options)
|
function M.highlight(group, options)
|
||||||
local guifg = options.fg or "NONE"
|
local guifg = options.fg or "NONE"
|
||||||
local guibg = options.bg or "NONE"
|
local guibg = options.bg or "NONE"
|
||||||
local guisp = options.sp or "NONE"
|
local guisp = options.sp or "NONE"
|
||||||
local gui = options.gui or "NONE"
|
local gui = options.gui or "NONE"
|
||||||
local blend = options.blend or 0
|
local blend = options.blend or 0
|
||||||
local ctermfg = options.ctermfg or "NONE"
|
local ctermfg = options.ctermfg or "NONE"
|
||||||
|
|
||||||
vim.cmd(
|
vim.cmd(
|
||||||
string.format(
|
string.format(
|
||||||
"highlight %s guifg=%s ctermfg=%s guibg=%s guisp=%s gui=%s blend=%d",
|
"highlight %s guifg=%s ctermfg=%s guibg=%s guisp=%s gui=%s blend=%d",
|
||||||
group,
|
group,
|
||||||
guifg,
|
guifg,
|
||||||
ctermfg,
|
ctermfg,
|
||||||
guibg,
|
guibg,
|
||||||
guisp,
|
guisp,
|
||||||
gui,
|
gui,
|
||||||
blend
|
blend
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.safeRequire(module, func, errorFunc)
|
function M.safeRequire(module, func, errorFunc)
|
||||||
local ok, result = pcall(require, module)
|
local ok, result = pcall(require, module)
|
||||||
if ok then
|
if ok then
|
||||||
return func(result)
|
return func(result)
|
||||||
elseif errorFunc then
|
elseif errorFunc then
|
||||||
return errorFunc(result)
|
return errorFunc(result)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
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()
|
function M.fnFalse()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.fnNil()
|
function M.fnNil()
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.fnEmptyStr()
|
function M.fnEmptyStr()
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.fnZero()
|
function M.fnZero()
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue