fix: modified snippets pipeline to actually work properly with luasnip
This commit is contained in:
parent
49a7d8d098
commit
8d2c1d921e
8 changed files with 204 additions and 366 deletions
0
config/bundles/common/default.nix
Normal file
0
config/bundles/common/default.nix
Normal file
|
|
@ -33,150 +33,91 @@
|
|||
];
|
||||
|
||||
# Core snippet configuration and definitions
|
||||
extraConfigLua = ''
|
||||
local ls = require("luasnip")
|
||||
local types = require("luasnip.util.types")
|
||||
# Uses unified snippets config from ../snippets/default.nix for all LuaSnip setup.
|
||||
# Use the unified snippets config for LuaSnip
|
||||
extraConfigLua = let
|
||||
snippetDir = ../languages/snippets;
|
||||
snippetFiles =
|
||||
builtins.filter
|
||||
(name: builtins.match ".*\\.nix$" name != null)
|
||||
(builtins.attrNames (builtins.readDir snippetDir));
|
||||
snippetConfigs = map (file: (import (snippetDir + "/${file}")).extraConfigLua) snippetFiles;
|
||||
allSnippets = builtins.concatStringsSep "\n" snippetConfigs;
|
||||
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
|
||||
|
||||
-- Add visual indicators for snippet nodes
|
||||
ls.config.set_config({
|
||||
ext_opts = {
|
||||
[types.choiceNode] = {
|
||||
active = {
|
||||
virt_text = {{"●", "GruvboxOrange"}}
|
||||
}
|
||||
},
|
||||
[types.insertNode] = {
|
||||
active = {
|
||||
virt_text = {{"●", "GruvboxBlue"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
-- Get visual selection
|
||||
local function get_visual_selection()
|
||||
local visual_modes = {
|
||||
v = true,
|
||||
V = true,
|
||||
["\22"] = true -- CTRL+V
|
||||
}
|
||||
|
||||
-- Common snippet creation utilities
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
local f = ls.function_node
|
||||
local c = ls.choice_node
|
||||
local d = ls.dynamic_node
|
||||
local r = ls.restore_node
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
local rep = require("luasnip.extras").rep
|
||||
local parse = require("luasnip.util.parser").parse_snippet
|
||||
if not visual_modes[vim.api.nvim_get_mode().mode] then
|
||||
return ""
|
||||
end
|
||||
|
||||
-- Function to generate namespace interpolation at runtime
|
||||
local function namespace_interp(suffix)
|
||||
-- Uses string.char to generate the namespace interpolation
|
||||
return string.char(36) .. string.char(123) .. "namespace" .. string.char(125) .. suffix
|
||||
end
|
||||
local _, ls, cs = unpack(vim.fn.getpos("v"))
|
||||
local _, le, ce = unpack(vim.fn.getpos("."))
|
||||
|
||||
-- Nix snippets
|
||||
local nix_snippets = {
|
||||
-- Module snippet
|
||||
module = s("module", {
|
||||
-- Opening
|
||||
t({
|
||||
"{",
|
||||
" config,",
|
||||
" lib,",
|
||||
" namespace,",
|
||||
" pkgs,",
|
||||
" ...",
|
||||
"}: let",
|
||||
" inherit (lib) mkIf mkEnableOption;",
|
||||
" inherit (lib."
|
||||
}),
|
||||
f(function() return namespace_interp("") end),
|
||||
t(") getAttrByNamespace mkOptionsWithNamespace;"),
|
||||
t({"", " base = \""}),
|
||||
f(function() return namespace_interp(".") end),
|
||||
i(1, "category"),
|
||||
t("."),
|
||||
i(2, "module"),
|
||||
t({
|
||||
"\";",
|
||||
" cfg = getAttrByNamespace config base;",
|
||||
"in {",
|
||||
" options = mkOptionsWithNamespace base {",
|
||||
" enable = mkEnableOption \""
|
||||
}),
|
||||
i(3, "description"),
|
||||
t({
|
||||
"\";",
|
||||
" };",
|
||||
"",
|
||||
" config = mkIf cfg.enable {",
|
||||
" "
|
||||
}),
|
||||
i(4, "# configuration"),
|
||||
t({"", " };", "}"}),
|
||||
}),
|
||||
-- Normalize positions
|
||||
if ls > le or (ls == le and cs > ce) then
|
||||
ls, le = le, ls
|
||||
cs, ce = ce, cs
|
||||
end
|
||||
|
||||
-- Bundle module
|
||||
bundle = s("bundle", {
|
||||
t({
|
||||
"{",
|
||||
" config,",
|
||||
" lib,",
|
||||
" namespace,",
|
||||
" ...",
|
||||
"}: let",
|
||||
" inherit (lib) mkIf mkEnableOption;",
|
||||
" inherit (lib."
|
||||
}),
|
||||
f(function() return namespace_interp("") end),
|
||||
t(") getAttrByNamespace mkOptionsWithNamespace enabled;"),
|
||||
t({"", " base = \""}),
|
||||
f(function() return namespace_interp(".bundles.") end),
|
||||
i(1, "name"),
|
||||
t({
|
||||
"\";",
|
||||
" cfg = getAttrByNamespace config base;",
|
||||
"in {",
|
||||
" options = mkOptionsWithNamespace base {",
|
||||
" enable = mkEnableOption \""
|
||||
}),
|
||||
i(2, "name"),
|
||||
t({
|
||||
" bundle\";",
|
||||
" };",
|
||||
"",
|
||||
" config = mkIf cfg.enable {",
|
||||
" "
|
||||
}),
|
||||
f(function() return namespace_interp("") end),
|
||||
t(" = {"),
|
||||
t({"", " "}),
|
||||
i(3, "# enabled modules"),
|
||||
t({"", " };", " };", "}"})
|
||||
}),
|
||||
local lines = vim.api.nvim_buf_get_lines(0, ls - 1, le, false)
|
||||
if #lines == 0 then
|
||||
return ""
|
||||
end
|
||||
|
||||
-- Simple patterns using formatted strings
|
||||
enable = s("enable", fmt([[
|
||||
{} = {{
|
||||
enable = true;
|
||||
{}
|
||||
}};]], {
|
||||
i(1, "module.path"),
|
||||
i(2, "# configuration"),
|
||||
})),
|
||||
-- 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
|
||||
|
||||
enabled = s("enabled", fmt("{} = enabled;", {
|
||||
i(1, "module.path"),
|
||||
})),
|
||||
return table.concat(lines, "\n")
|
||||
end
|
||||
|
||||
home = s("home", fmt([[
|
||||
home = {{
|
||||
packages = with pkgs; [ {} ];
|
||||
{}
|
||||
}};]], {
|
||||
i(1, "# packages"),
|
||||
i(2, "# other home attributes"),
|
||||
})),
|
||||
}
|
||||
-- Format date in various ways
|
||||
local function date_format(format)
|
||||
return os.date(format)
|
||||
end
|
||||
|
||||
-- Add snippets to filetypes
|
||||
ls.add_snippets("nix", nix_snippets)
|
||||
-- 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
|
||||
}
|
||||
|
||||
${allSnippets}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@
|
|||
" ...",
|
||||
"}: let",
|
||||
" inherit (lib) mkIf mkEnableOption;",
|
||||
" inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace;", -- literal ${namespace}
|
||||
" ${"inherit (lib.\${namespace}) getAttrByNamespace mkOptionsWithNamespace;"}",
|
||||
" base = \""
|
||||
}),
|
||||
t("${"\${namespace}"}"),
|
||||
i(1, "namespace"),
|
||||
t("."),
|
||||
i(2, "category"),
|
||||
|
|
@ -56,10 +57,10 @@
|
|||
" ...",
|
||||
"}: let",
|
||||
" inherit (lib) mkIf mkEnableOption;",
|
||||
" inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace enabled;",
|
||||
" ${"inherit (lib.\${namespace}) getAttrByNamespace mkOptionsWithNamespace enabled;"}",
|
||||
" base = \""
|
||||
}),
|
||||
i(1, "namespace"),
|
||||
t("${"\${namespace}"}"),
|
||||
t(".bundles."),
|
||||
i(2, "name"),
|
||||
t({"\";",
|
||||
123
config/languages/snippets/python.nix
Normal file
123
config/languages/snippets/python.nix
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
{
|
||||
# Python-specific snippets
|
||||
extraConfigLua = ''
|
||||
local ls = require("luasnip")
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
local f = ls.function_node
|
||||
local c = ls.choice_node
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
|
||||
local python_snippets = {
|
||||
-- Import statement
|
||||
s("imp", {
|
||||
t("import "),
|
||||
i(1, "module")
|
||||
}),
|
||||
|
||||
-- From import statement
|
||||
s("fimp", fmt("from {} import {}", {
|
||||
i(1, "module"),
|
||||
i(2, "name")
|
||||
})),
|
||||
|
||||
-- Class definition
|
||||
s("class", fmt([[
|
||||
class {}:
|
||||
"""{}"""
|
||||
|
||||
def __init__(self{}):
|
||||
{}
|
||||
]], {
|
||||
i(1, "ClassName"),
|
||||
i(2, "Class docstring"),
|
||||
i(3, ""),
|
||||
i(4, "# Implementation"),
|
||||
})),
|
||||
|
||||
-- Function definition
|
||||
s("def", fmt([[
|
||||
def {}({}):
|
||||
"""{}
|
||||
|
||||
{}
|
||||
{}
|
||||
"""
|
||||
{}
|
||||
]], {
|
||||
i(1, "function_name"),
|
||||
i(2, ""),
|
||||
i(3, "Function docstring"),
|
||||
c(4, {
|
||||
t("Args:"),
|
||||
t("Parameters:"),
|
||||
}),
|
||||
i(5, " arg: Description"),
|
||||
i(6, " # Implementation"),
|
||||
})),
|
||||
|
||||
-- Main function
|
||||
s("main", fmt([[
|
||||
def main():
|
||||
{}
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
]], {
|
||||
i(1, "# Implementation"),
|
||||
})),
|
||||
|
||||
-- Try/except block
|
||||
s("try", fmt([[
|
||||
try:
|
||||
{}
|
||||
except {}:
|
||||
{}
|
||||
]], {
|
||||
i(1, "# Try block"),
|
||||
i(2, "Exception"),
|
||||
i(3, "# Exception handling"),
|
||||
})),
|
||||
|
||||
-- Context manager (with statement)
|
||||
s("with", fmt([[
|
||||
with {} as {}:
|
||||
{}
|
||||
]], {
|
||||
i(1, "context_manager"),
|
||||
i(2, "variable"),
|
||||
i(3, "# Implementation"),
|
||||
})),
|
||||
|
||||
-- List comprehension
|
||||
s("lc", fmt("[{} for {} in {}]", {
|
||||
i(1, "expression"),
|
||||
i(2, "item"),
|
||||
i(3, "iterable"),
|
||||
})),
|
||||
|
||||
-- Dictionary comprehension
|
||||
s("dc", fmt("{{{}: {} for {} in {}}}", {
|
||||
i(1, "key"),
|
||||
i(2, "value"),
|
||||
i(3, "item"),
|
||||
i(4, "iterable"),
|
||||
})),
|
||||
|
||||
-- Test function (pytest)
|
||||
s("test", fmt([[
|
||||
def test_{}():
|
||||
"""{}"""
|
||||
{}
|
||||
]], {
|
||||
i(1, "name"),
|
||||
i(2, "Test docstring"),
|
||||
i(3, "# Test implementation"),
|
||||
}))
|
||||
}
|
||||
|
||||
-- Add these snippets to Python files
|
||||
ls.add_snippets("python", python_snippets)
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
# Import all snippet files here
|
||||
imports = [
|
||||
./utils.nix
|
||||
./languages/common.nix
|
||||
./languages/rust.nix
|
||||
./languages/python.nix
|
||||
./languages/nix.nix
|
||||
];
|
||||
|
||||
# This extra config will load all our snippets
|
||||
extraConfigLua = ''
|
||||
-- Ensure LuaSnip loads all snippet definitions
|
||||
require("luasnip.loaders.from_lua").lazy_load()
|
||||
|
||||
-- This function lets us load snippets defined in Nix string
|
||||
function load_nix_snippets(snippets, filetypes)
|
||||
local ls = require("luasnip")
|
||||
|
||||
for _, ft in ipairs(filetypes) do
|
||||
ls.add_snippets(ft, snippets)
|
||||
end
|
||||
end
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
{
|
||||
# Python-specific snippets
|
||||
extraConfigLua = ''
|
||||
local ls = require("luasnip")
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
local f = ls.function_node
|
||||
local c = ls.choice_node
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
|
||||
local python_snippets = {
|
||||
-- Import statement
|
||||
s("imp", {
|
||||
t("import "),
|
||||
i(1, "module")
|
||||
}),
|
||||
|
||||
-- From import statement
|
||||
s("fimp", fmt("from {} import {}", {
|
||||
i(1, "module"),
|
||||
i(2, "name")
|
||||
})),
|
||||
|
||||
-- Class definition
|
||||
s("class", fmt([[
|
||||
class {}:
|
||||
"""{}"""
|
||||
|
||||
def __init__(self{}):
|
||||
{}
|
||||
]], {
|
||||
i(1, "ClassName"),
|
||||
i(2, "Class docstring"),
|
||||
i(3, ""),
|
||||
i(4, "# Implementation"),
|
||||
})),
|
||||
|
||||
-- Function definition
|
||||
s("def", fmt([[
|
||||
def {}({}):
|
||||
"""{}
|
||||
|
||||
{}
|
||||
{}
|
||||
"""
|
||||
{}
|
||||
]], {
|
||||
i(1, "function_name"),
|
||||
i(2, ""),
|
||||
i(3, "Function docstring"),
|
||||
c(4, {
|
||||
t("Args:"),
|
||||
t("Parameters:"),
|
||||
}),
|
||||
i(5, " arg: Description"),
|
||||
i(6, " # Implementation"),
|
||||
})),
|
||||
|
||||
-- Main function
|
||||
s("main", fmt([[
|
||||
def main():
|
||||
{}
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
]], {
|
||||
i(1, "# Implementation"),
|
||||
})),
|
||||
|
||||
-- Try/except block
|
||||
s("try", fmt([[
|
||||
try:
|
||||
{}
|
||||
except {}:
|
||||
{}
|
||||
]], {
|
||||
i(1, "# Try block"),
|
||||
i(2, "Exception"),
|
||||
i(3, "# Exception handling"),
|
||||
})),
|
||||
|
||||
-- Context manager (with statement)
|
||||
s("with", fmt([[
|
||||
with {} as {}:
|
||||
{}
|
||||
]], {
|
||||
i(1, "context_manager"),
|
||||
i(2, "variable"),
|
||||
i(3, "# Implementation"),
|
||||
})),
|
||||
|
||||
-- List comprehension
|
||||
s("lc", fmt("[{} for {} in {}]", {
|
||||
i(1, "expression"),
|
||||
i(2, "item"),
|
||||
i(3, "iterable"),
|
||||
})),
|
||||
|
||||
-- Dictionary comprehension
|
||||
s("dc", fmt("{{{}: {} for {} in {}}}", {
|
||||
i(1, "key"),
|
||||
i(2, "value"),
|
||||
i(3, "item"),
|
||||
i(4, "iterable"),
|
||||
})),
|
||||
|
||||
-- Test function (pytest)
|
||||
s("test", fmt([[
|
||||
def test_{}():
|
||||
"""{}"""
|
||||
{}
|
||||
]], {
|
||||
i(1, "name"),
|
||||
i(2, "Test docstring"),
|
||||
i(3, "# Test implementation"),
|
||||
}))
|
||||
}
|
||||
|
||||
-- Add these snippets to Python files
|
||||
ls.add_snippets("python", python_snippets)
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
{
|
||||
extraConfigLua = ''
|
||||
-- Common utility functions for snippets
|
||||
|
||||
-- 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
|
||||
}
|
||||
'';
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue