137 lines
3.7 KiB
Nix
137 lines
3.7 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
namespace,
|
|
...
|
|
}: let
|
|
inherit (builtins) readDir;
|
|
inherit (lib) mkIf mkEnableOption filter match attrNames concatStringsSep;
|
|
inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace;
|
|
base = "${namespace}.languages.luasnip";
|
|
cfg = getAttrByNamespace config base;
|
|
in {
|
|
options = mkOptionsWithNamespace base {
|
|
enable = mkEnableOption "luasnip";
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
plugins.luasnip = {
|
|
enable = true;
|
|
|
|
# Basic LuaSnip settings
|
|
settings = {
|
|
history = true;
|
|
updateevents = "TextChanged,TextChangedI";
|
|
enable_autosnippets = true;
|
|
};
|
|
};
|
|
|
|
# Add keymaps for snippet navigation
|
|
keymaps = [
|
|
{
|
|
mode = "i";
|
|
key = "<C-k>";
|
|
action = "<cmd>lua require('luasnip').expand_or_jump()<CR>";
|
|
options.desc = "Snippets Expand or jump forward";
|
|
}
|
|
{
|
|
mode = "i";
|
|
key = "<C-j>";
|
|
action = "<cmd>lua require('luasnip').jump(-1)<CR>";
|
|
options.desc = "Snippets Jump backward";
|
|
}
|
|
{
|
|
mode = "i";
|
|
key = "<C-l>";
|
|
action = "<cmd>lua require('luasnip').change_choice(1)<CR>";
|
|
options.desc = "Snippets Cycle choices";
|
|
}
|
|
];
|
|
|
|
extraConfigLua = let
|
|
snippets =
|
|
readDir ../languages/snippets
|
|
|> attrNames
|
|
|> filter (name: match ".*\\.nix$" name != null)
|
|
|> map (name: ../languages/snippets + "/${name}")
|
|
|> map (file: (import file).extraConfigLua)
|
|
|> concatStringsSep "\n";
|
|
in ''
|
|
-- Get comment string for current filetype
|
|
local function get_comment_string()
|
|
local comment_string = vim.bo.commentstring
|
|
if not comment_string or comment_string == "" then
|
|
return "-- %s" -- Default to Lua style comments
|
|
end
|
|
return comment_string
|
|
end
|
|
|
|
-- Get visual selection
|
|
local function get_visual_selection()
|
|
local visual_modes = {
|
|
v = true,
|
|
V = true,
|
|
["\22"] = true -- CTRL+V
|
|
}
|
|
|
|
if not visual_modes[vim.api.nvim_get_mode().mode] then
|
|
return ""
|
|
end
|
|
|
|
local _, ls, cs = unpack(vim.fn.getpos("v"))
|
|
local _, le, ce = unpack(vim.fn.getpos("."))
|
|
|
|
-- Normalize positions
|
|
if ls > le or (ls == le and cs > ce) then
|
|
ls, le = le, ls
|
|
cs, ce = ce, cs
|
|
end
|
|
|
|
local lines = vim.api.nvim_buf_get_lines(0, ls - 1, le, false)
|
|
if #lines == 0 then
|
|
return ""
|
|
end
|
|
|
|
-- Adjust for partial lines
|
|
lines[1] = string.sub(lines[1], cs, -1)
|
|
if #lines > 1 then
|
|
lines[#lines] = string.sub(lines[#lines], 1, ce)
|
|
else
|
|
lines[1] = string.sub(lines[1], 1, ce - cs + 1)
|
|
end
|
|
|
|
return table.concat(lines, "\n")
|
|
end
|
|
|
|
-- Format date in various ways
|
|
local function date_format(format)
|
|
return os.date(format)
|
|
end
|
|
|
|
-- Capture groups from regex matches
|
|
local function capture_match(match, group)
|
|
if match and #match > group then
|
|
return match[group + 1]
|
|
end
|
|
return ""
|
|
end
|
|
|
|
-- Check if the current buffer is a test file
|
|
local function is_test_file()
|
|
local filename = vim.fn.expand("%:t")
|
|
return string.match(filename, "[tT]est") ~= nil or string.match(filename, "_test") ~= nil or string.match(filename, "spec") ~= nil
|
|
end
|
|
|
|
-- Make these functions available to snippets
|
|
_G.snippet_utils = {
|
|
get_comment_string = get_comment_string,
|
|
get_visual_selection = get_visual_selection,
|
|
date_format = date_format,
|
|
capture_match = capture_match,
|
|
is_test_file = is_test_file
|
|
}
|
|
|
|
${snippets}
|
|
'';
|
|
};
|
|
}
|