221 lines
6.6 KiB
Lua
221 lines
6.6 KiB
Lua
function prereqs()
|
|
local output_cspell = vim.fn.system({
|
|
"which",
|
|
"cspell",
|
|
})
|
|
if output_cspell == nil or output_cspell == "" or output_cspell == "cspell not found" then
|
|
print("Installing cspell globally with npm")
|
|
vim.fn.system({
|
|
"npm",
|
|
"install",
|
|
"-g",
|
|
"cspell",
|
|
})
|
|
end
|
|
end
|
|
|
|
-- https://github.com/darold/pgFormatter
|
|
|
|
local rust_sqlx_f = function()
|
|
return vim.treesitter.query.parse(
|
|
"rust",
|
|
[[
|
|
; query macro
|
|
(macro_invocation
|
|
(scoped_identifier
|
|
path: (identifier) @_path (#eq? @_path "sqlx")
|
|
name: (identifier) @_name (#any-of? @_name "query" "query_scalar"))
|
|
|
|
(token_tree
|
|
. (raw_string_literal) @sql (#offset! @sql 1 0 -1 0))
|
|
)
|
|
|
|
; query_as macro
|
|
(macro_invocation
|
|
(scoped_identifier
|
|
path: (identifier) @_path (#eq? @_path "sqlx")
|
|
name: (identifier) @_name (#eq? @_name "query_as"))
|
|
|
|
(token_tree
|
|
(_) . (raw_string_literal) @sql (#offset! @sql 1 0 -1 0))
|
|
|
|
)
|
|
|
|
; query and query_as function
|
|
(call_expression
|
|
(scoped_identifier
|
|
path: (identifier) @_path (#eq? @_path "sqlx")
|
|
name: (identifier) @_name (#contains? @_name "query"))
|
|
|
|
(arguments
|
|
(raw_string_literal) @sql (#offset! @sql 1 0 -1 0))
|
|
)
|
|
]]
|
|
)
|
|
end
|
|
|
|
local get_root = function(bufnr)
|
|
local parser = vim.treesitter.get_parser(bufnr, "rust", {})
|
|
local tree = parser:parse()[1]
|
|
return tree:root()
|
|
end
|
|
|
|
local format_dat_sql = function(bufnr)
|
|
local rust_sqlx = rust_sqlx_f()
|
|
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
|
|
|
if vim.bo[bufnr].filetype ~= "rust" then
|
|
vim.notify "can only be used in rust"
|
|
return
|
|
end
|
|
|
|
local root = get_root(bufnr)
|
|
|
|
local changes = {}
|
|
for id, node in rust_sqlx:iter_captures(root, bufnr, 0, -1) do
|
|
local name = rust_sqlx.captures[id]
|
|
if name == "sql" then
|
|
-- range: { row_start [1], col_start [2], row_end [3], col_end }
|
|
local range = { node:range() }
|
|
local indentation = string.rep(" ", range[2])
|
|
|
|
local node_text = vim.treesitter.get_node_text(node, bufnr)
|
|
if node_text:match('r#"\n(.*\n)+?%s*"#$') == nil then
|
|
-- text is invalid because it does not have newlines in raw string literal
|
|
goto continue
|
|
end
|
|
|
|
local text = node_text:sub(4, -3) -- get just the inside of the raw string literal
|
|
-- TODO get current spaces for indentation and run pg_format with that indendation amount
|
|
local formatted = vim.fn.system({ "pg_format", "-L" }, text)
|
|
local lines = {}
|
|
for line in formatted:gmatch("[^\r\n]+") do
|
|
lines[#lines + 1] = line
|
|
end
|
|
|
|
for idx, line in ipairs(lines) do
|
|
lines[idx] = indentation .. line
|
|
end
|
|
|
|
-- Fix indentation of end of raw string literal as well
|
|
local last_line = vim.api.nvim_buf_get_lines(bufnr, range[3], range[3] + 1, true)[1]:match("^%s*(.*)")
|
|
-- print("LAST LINE", last_line)
|
|
lines[#lines + 1] = indentation .. last_line
|
|
|
|
table.insert(changes, 1, {
|
|
start = range[1] + 1,
|
|
final = range[3] + 1,
|
|
formatted = lines,
|
|
})
|
|
|
|
-- changes[#changes + 1] = {
|
|
-- col = 0,
|
|
-- row = range[1] + 2,
|
|
-- end_col = -1,
|
|
-- end_row = range[3] + 1,
|
|
-- text = table.concat(lines, '\n'),
|
|
-- }
|
|
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
-- return changes
|
|
|
|
print("Change", vim.inspect(changes))
|
|
for _, change in ipairs(changes) do
|
|
vim.api.nvim_buf_set_lines(bufnr, change.start, change.final, false, change.formatted)
|
|
end
|
|
end
|
|
|
|
vim.api.nvim_create_user_command("SqlMagic", function()
|
|
format_dat_sql()
|
|
end, {})
|
|
|
|
return {
|
|
{
|
|
"jose-elias-alvarez/null-ls.nvim",
|
|
dependencies = { "williamboman/mason.nvim" },
|
|
build = prereqs,
|
|
opts = function(_, config)
|
|
-- config variable is the default definitions table for the setup function call
|
|
local null_ls = require("null-ls")
|
|
|
|
-- Custom rust formatter: genemichaels first, then rustfmt, nightly if experimental
|
|
local rust_formatter_genemichaels = {
|
|
name = "rust_formatter_genemichaels",
|
|
method = null_ls.methods.FORMATTING,
|
|
filetypes = { "rust" },
|
|
generator = null_ls.formatter({
|
|
command = "genemichaels",
|
|
args = { '-q' },
|
|
to_stdin = true,
|
|
}),
|
|
}
|
|
-- ╰─ cat src/main.rs| rustfmt --emit=stdout --edition=2021 --color=never
|
|
local rust_formatter_rustfmt = {
|
|
name = "rust_formatter_rustfmt",
|
|
method = null_ls.methods.FORMATTING,
|
|
filetypes = { "rust" },
|
|
generator = null_ls.formatter({
|
|
command = "rustfmt",
|
|
args = { '--emit=stdout', "--edition=$(grep edition Cargo.toml | awk '{print substr($3,2,length($3)-2)}')",
|
|
'--color=never' },
|
|
to_stdin = true,
|
|
}),
|
|
}
|
|
|
|
-- local rust_formatter_sqlx = {
|
|
-- name = "rust_formatter_sqlx",
|
|
-- method = null_ls.methods.FORMATTING,
|
|
-- filetypes = { "rust" },
|
|
-- generator = {
|
|
-- fn = function(params)
|
|
-- local changes = format_dat_sql(params.bufnr)
|
|
-- -- print("CHANGES:\n", vim.inspect(changes))
|
|
-- -- return changes
|
|
-- end
|
|
-- },
|
|
-- }
|
|
|
|
null_ls.register(rust_formatter_genemichaels)
|
|
null_ls.register(rust_formatter_rustfmt)
|
|
-- null_ls.register(rust_formatter_sqlx)
|
|
|
|
-- Check supported formatters and linters
|
|
-- https://github.com/jose-elias-alvarez/null-ls.nvim/tree/main/lua/null-ls/builtins/formatting
|
|
-- https://github.com/jose-elias-alvarez/null-ls.nvim/tree/main/lua/null-ls/builtins/diagnostics
|
|
config.sources = {
|
|
null_ls.builtins.formatting.prettier, -- typescript/javascript
|
|
null_ls.builtins.formatting.stylua, -- lua
|
|
--null_ls.builtins.formatting.rustfmt, -- rust
|
|
rust_formatter_genemichaels, -- order matters, we run genemichaels first then rustfmt
|
|
rust_formatter_rustfmt,
|
|
rust_formatter_sqlx,
|
|
null_ls.builtins.formatting.black, -- python
|
|
-- null_ls.builtins.code_actions.proselint, -- TODO looks interesting
|
|
null_ls.builtins.code_actions.cspell.with({
|
|
config = {
|
|
find_json = function()
|
|
return vim.fn.findfile("cspell.json", vim.fn.environ().HOME .. "/.config/nvim/lua/user/;")
|
|
end,
|
|
},
|
|
}),
|
|
null_ls.builtins.diagnostics.cspell.with({
|
|
extra_args = { "--config", "~/.config/nvim/lua/user/cspell.json" },
|
|
}),
|
|
}
|
|
|
|
config.update_in_insert = true
|
|
config.debug = true
|
|
|
|
return config
|
|
end,
|
|
},
|
|
{
|
|
"jay-babu/mason-null-ls.nvim",
|
|
opts = {
|
|
ensure_installed = { "rustfmt", "stylelua", "prettier", "black" },
|
|
},
|
|
},
|
|
}
|