tangled
alpha
login
or
join now
althaea.zone
/
candy
0
fork
atom
neovim
0
fork
atom
overview
issues
pulls
pipelines
a little llm experiementation
marshmallow.tngl.sh
9 months ago
ce9559d8
14d3918b
+175
4 changed files
expand all
collapse all
unified
split
candy
lua
marshmallow
init.lua
llm.lua
usercommand.lua
flake.nix
+1
candy/lua/marshmallow/init.lua
···
22
22
require("marshmallow.autocmd")
23
23
require("marshmallow.env")
24
24
require("marshmallow.git")
25
25
+
require("marshmallow.llm")
+40
candy/lua/marshmallow/llm.lua
···
1
1
+
require("minuet").setup({
2
2
+
virtualtext = {
3
3
+
auto_trigger_ft = { "lua" },
4
4
+
keymap = {
5
5
+
-- accept whole completion
6
6
+
accept = "<A-A>",
7
7
+
-- accept one line
8
8
+
accept_line = "<A-a>",
9
9
+
-- accept n lines (prompts for number)
10
10
+
-- e.g. "A-z 2 CR" will accept 2 lines
11
11
+
accept_n_lines = "<A-z>",
12
12
+
-- Cycle to prev completion item, or manually invoke completion
13
13
+
prev = "<A-[>",
14
14
+
-- Cycle to next completion item, or manually invoke completion
15
15
+
next = "<A-]>",
16
16
+
dismiss = "<A-e>",
17
17
+
},
18
18
+
},
19
19
+
20
20
+
provider = "openai_compatible",
21
21
+
request_timeout = 2.5,
22
22
+
throttle = 1500,
23
23
+
debounce = 600,
24
24
+
provider_options = {
25
25
+
openai_compatible = {
26
26
+
api_key = "OPENROUTER_KEY",
27
27
+
end_point = "https://openrouter.ai/api/v1/chat/completions",
28
28
+
model = "deepseek/deepseek-chat-v3-0324",
29
29
+
name = "Openrouter",
30
30
+
optional = {
31
31
+
max_tokens = 56,
32
32
+
top_p = 0.9,
33
33
+
provider = {
34
34
+
-- Prioritize throughput for faster completion
35
35
+
sort = "throughput",
36
36
+
},
37
37
+
},
38
38
+
},
39
39
+
},
40
40
+
})
+133
candy/lua/marshmallow/usercommand.lua
···
17
17
end, {
18
18
nargs = 1,
19
19
})
20
20
+
21
21
+
local namespace = vim.api.nvim_create_namespace("marsh-mods")
22
22
+
local _window = nil
23
23
+
24
24
+
local get_or_create_window = function()
25
25
+
-- if _window == nil then
26
26
+
vim.cmd.split({ mods = { vertical = true } })
27
27
+
_window = vim.api.nvim_get_current_win()
28
28
+
-- end
29
29
+
30
30
+
return _window
31
31
+
end
32
32
+
33
33
+
local mods_list = function()
34
34
+
local window = get_or_create_window()
35
35
+
local buf = vim.api.nvim_create_buf(false, true)
36
36
+
-- vim.api.nvim_buf_set_name(buf, "mods://list")
37
37
+
vim.api.nvim_win_set_buf(window, buf)
38
38
+
vim.api.nvim_set_option_value("ft", "txt", {
39
39
+
buf = buf,
40
40
+
})
41
41
+
42
42
+
local obj = vim.system({ "mods", "--list" }, {
43
43
+
text = true,
44
44
+
}):wait()
45
45
+
46
46
+
if obj.stdout == nil then
47
47
+
return
48
48
+
end
49
49
+
50
50
+
local lines = vim.split(obj.stdout, "\n", {
51
51
+
trimempty = true,
52
52
+
})
53
53
+
54
54
+
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
55
55
+
56
56
+
for key in pairs(lines) do
57
57
+
vim.api.nvim_buf_set_extmark(0, namespace, key - 1, 0, {
58
58
+
end_col = 7,
59
59
+
hl_group = "Identifier",
60
60
+
})
61
61
+
end
62
62
+
63
63
+
vim.api.nvim_set_option_value("modifiable", false, {
64
64
+
buf = buf,
65
65
+
})
66
66
+
end
67
67
+
68
68
+
local mods_prompt = function(context, arg)
69
69
+
local window = get_or_create_window()
70
70
+
71
71
+
local output = vim.fn.tempname()
72
72
+
73
73
+
local buf = vim.api.nvim_create_buf(false, true)
74
74
+
vim.api.nvim_win_set_buf(window, buf)
75
75
+
vim.api.nvim_set_option_value("ft", "markdown", {
76
76
+
buf = buf,
77
77
+
})
78
78
+
-- vim.api.nvim_set_option_value("modifiable", false, {
79
79
+
-- buf = buf,
80
80
+
-- })
81
81
+
82
82
+
local obj = vim.system({ "mods", arg }, {
83
83
+
stdin = context,
84
84
+
text = true,
85
85
+
detach = true,
86
86
+
stdout = function(err, data)
87
87
+
vim.schedule(function()
88
88
+
-- if string.find(data, "\n") then
89
89
+
-- local lines = vim.split(data, "\n")
90
90
+
-- local last_line = vim.api.nvim_buf_line_count(buf)
91
91
+
-- vim.api.nvim_buf_set_lines(buf, last_line, last_line, false, lines)
92
92
+
-- else
93
93
+
94
94
+
local lines = vim.split(data, "\n")
95
95
+
96
96
+
local first = true
97
97
+
98
98
+
for key, line in pairs(lines) do
99
99
+
local length = vim.api.nvim_buf_line_count(buf)
100
100
+
101
101
+
if not first then
102
102
+
vim.api.nvim_buf_set_lines(buf, length, length, false, { "" })
103
103
+
length = length + 1
104
104
+
end
105
105
+
106
106
+
local col = vim.fn.col({ length, "$" }) - 1
107
107
+
-- local existing_line = vim.api.nvim_buf_get_text(buf, length - 1, 0, length - 1, -1, {})[1]
108
108
+
-- local new_line = existing_line .. data
109
109
+
--
110
110
+
-- vim.api.nvim_buf_set_lines(buf, length - 1, length - 1, false, {
111
111
+
-- new_line,
112
112
+
-- })
113
113
+
vim.api.nvim_buf_set_text(buf, length - 1, col, length - 1, col, {
114
114
+
line,
115
115
+
})
116
116
+
117
117
+
first = false
118
118
+
end
119
119
+
120
120
+
-- if string.find(data, "\n") then
121
121
+
-- vim.api.nvim_buf_set_lines(buf, length, length, false, { "" })
122
122
+
-- end
123
123
+
124
124
+
-- vim.api.nvim_win_call(window, function()
125
125
+
-- vim.cmd("normal! G")
126
126
+
-- end)
127
127
+
end)
128
128
+
end,
129
129
+
stderr = function(err, data)
130
130
+
vim.schedule(function()
131
131
+
vim.notify(data, vim.log.levels.ERROR)
132
132
+
end)
133
133
+
end,
134
134
+
})
135
135
+
136
136
+
vim.print(obj)
137
137
+
end
138
138
+
139
139
+
vim.api.nvim_create_user_command("Mods", function(val)
140
140
+
if val.args == "" then
141
141
+
mods_list()
142
142
+
return
143
143
+
end
144
144
+
145
145
+
local context = vim.api.nvim_buf_get_lines(0, val.line1, val.line2, false)
146
146
+
147
147
+
mods_prompt(context, val.args)
148
148
+
end, {
149
149
+
nargs = "?",
150
150
+
range = "%",
151
151
+
bang = true,
152
152
+
})
+1
flake.nix
···
90
90
mini-nvim
91
91
colorizer
92
92
luasnip
93
93
+
minuet-ai-nvim
93
94
(opt conform-nvim)
94
95
plenary-nvim
95
96
(pkgs.vimUtils.buildVimPlugin {