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
This commit is contained in:
2025-06-11 03:21:25 -04:00
parent e830931ff4
commit 9ea9d9f516
14 changed files with 352 additions and 43 deletions

View File

@ -47,3 +47,5 @@ auto("BufWritePre", {
vim.fn.mkdir(dir, "p")
end
})
core.color.setup_termbg_sync()

View File

@ -23,22 +23,16 @@ map("n", "<leader>x", function() -- execute order 111
if vim.fn.getftype(fn) == "file" then
local perm = vim.fn.getfperm(fn)
if string.match(perm, "x", 3) then
vim.notify("Removed executable flags", vim.log.levels.INFO, {
title = core.misc.appid
})
vim.notify("Removed executable flags")
vim.fn.setfperm(fn, string.sub(fn, 1, 2).."-"..string.sub(fn, 4, 5).."-"
..string.sub(fn, 7, 8).."-")
else
vim.notify("Add executable flags", vim.log.levels.INFO, {
title = core.misc.appid
})
vim.notify("Add executable flags")
vim.fn.setfperm(fn, string.sub(fn, 1, 2).."x"..string.sub(fn, 4, 5).."x"
..string.sub(fn, 7, 8).."x")
end
else
vim.notify("File doesn't exist", vim.log.levels.INFO, {
title = core.misc.appid
})
vim.notify("File doesn't exist")
end
end, { desc = "toggle executable flag of the file" })

View File

@ -0,0 +1,7 @@
return { "mfussenegger/nvim-dap-python",
requires = "mfussenegger/nvim-dap",
function()
local debugpy = core.mason.get_pkg_path("debugpy", "/venv/bin/python3")
require("dap-python").setup(debugpy)
end
}

View File

@ -15,8 +15,7 @@ return { "ThePrimeagen/harpoon",
map("n", "<leader>a", function()
harpoon:list():add()
vim.notify("added "..vim.fn.expand("%:t").." to quickmarks",
vim.log.levels.INFO, { title = core.misc.appid })
vim.notify("added "..vim.fn.expand("%:t").." to quickmarks")
end, { desc = "add current file to quickmarks" })
map("n", "<C-e>", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end)

View File

@ -9,8 +9,19 @@ return { "neovim/nvim-lspconfig",
require("mason-lspconfig").setup {
ensure_added = {
"clangd",
"mesonlsp",
"bashls",
"jdtls",
"lua_ls",
"jdtls"
"stylua",
-- python
"basedpyright",
"mypy",
"black",
"debugpy"
}
}
end

View File

@ -23,7 +23,17 @@ return { "mellow-theme/mellow.nvim",
["BlinkCmpMenu"] = { link = "NormalFloat" },
["BlinkCmpMenuBorder"] = { link = "BlinkCmpMenu" },
["BlinkCmpMenuSelection"] = { bg = c.gray01 },
["BlinkCmpLabelDeprecated"] = { link = "CmpItemAbbrDeprecated" }
["BlinkCmpLabelDeprecated"] = { link = "CmpItemAbbrDeprecated" },
-- telescope styling so I can see when coding outside (real)
["TelescopeResultsNormal"] = { bg = c.bg_dark },
["TelescopeResultsBorder"] = { link = "TelescopeResultsNormal" },
["TelescopeResultsTitle"] = {
bg = core.color.copyhl("TelescopeResultsNormal").background,
fg = core.color.copyhl("TelescopeResultsNormal").background
},
["TelescopePreviewNormal"] = { link = "NormalFloat" },
["TelescopePreviewBorder"] = { link = "TelescopePreviewNormal" }
}
end
}

View File

@ -0,0 +1,31 @@
local augroup = core.misc.augroup("nullls formatting")
return { "nvimtools/none-ls.nvim",
function()
local null_ls = require("null-ls")
null_ls.setup {
sources = {
null_ls.builtins.formatting.stylua,
null_ls.builtins.formatting.black,
null_ls.builtins.diagnostics.mypy
},
on_attach = function(client, bufnr)
if client.supports_method("textDocument/formatting") then
vim.api.nvim_clear_autocmds({
group = augroup,
buffer = bufnr
})
core.misc.auto("BufWritePre", {
group = augroup,
buffer = bufnr,
callback = function()
vim.lsp.buf.format({ bufnr = bufnr })
end
})
end
end
}
end
}

View File

@ -6,21 +6,162 @@ local M = {}
---@return table
function M.copyhl(hlgroup, namespace)
namespace = namespace or 0
local res = {}
local ok, hl = pcall(vim.api.nvim_get_hl, namespace, {
name = hlgroup,
create = false
})
if not ok then
return {}
-- return default
return {
["foreground"] = "#000000",
["background"] = "#000000",
["special"] = "#000000"
}
end
for _, key in pairs({ "foreground", "background", "special" }) do
if hl[key] then
hl[key] = string.format("#%06x", hl[key])
res[key] = string.format("#%06x", hl[key])
end
end
return hl
return res
end
--- Taken from https://github.com/rachartier/tiny-inline-diagnostic.nvim
---@param hex string
---@return table rgb
function M.hex_to_rgb(hex)
if hex == nil or hex == 'None' then
return {0, 0, 0}
end
hex = hex:gsub('#', '')
hex = string.lower(hex)
return {
tonumber(hex:sub(1, 2), 16),
tonumber(hex:sub(3, 4), 16),
tonumber(hex:sub(5, 6), 16)
}
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,12 +1,16 @@
-- inspired by (and partially yoinked from): github.com/gonstoll/dotfiles
local M = {
misc = require("core.misc"),
folding = require("core.folding"),
lsp = require("core.lsp"),
color = require("core.color"),
snippets = vim.fs.joinpath(vim.fn.stdpath("config"), "lua/core/snippets.lua"),
}
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
@ -23,6 +27,14 @@ table.contains = function(self, item)
return false
end
local M = {
misc = require("core.misc"),
folding = require("core.folding"),
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
@ -30,9 +42,11 @@ M.mason = {
---@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
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")
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

View File

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

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()" })
})
}