Skip to content

Commit 163c0de

Browse files
cameronrsudo-tee
authored andcommitted
feat(picker): keymap for starting a new session
1 parent 51a47a1 commit 163c0de

File tree

2 files changed

+119
-15
lines changed

2 files changed

+119
-15
lines changed

lua/opencode/config.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ M.defaults = {
7171
},
7272
session_picker = {
7373
delete_session = { '<C-d>' },
74+
new_session = { '<C-n>' },
7475
},
7576
},
7677
ui = {

lua/opencode/ui/session_picker.lua

Lines changed: 118 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ local function format_session(session)
2828
return table.concat(parts, ' ~ ')
2929
end
3030

31-
local function telescope_ui(sessions, callback, on_delete)
31+
local function telescope_ui(sessions, callback, on_delete, on_new)
3232
local pickers = require('telescope.pickers')
3333
local finders = require('telescope.finders')
3434
local conf = require('telescope.config').values
@@ -106,14 +106,38 @@ local function telescope_ui(sessions, callback, on_delete)
106106
end
107107
end
108108

109+
-- Add new session mapping using shared callback
110+
local new_config = require('opencode.config').keymap.session_picker.new_session
111+
if new_config and new_config[1] then
112+
local key = new_config[1]
113+
local modes = new_config.mode or { 'i', 'n' }
114+
if type(modes) == 'string' then
115+
modes = { modes }
116+
end
117+
local new_fn = function()
118+
if on_new then
119+
local new_session = on_new()
120+
if new_session then
121+
actions.close(prompt_bufnr)
122+
if callback then
123+
callback(new_session)
124+
end
125+
end
126+
end
127+
end
128+
for _, mode in ipairs(modes) do
129+
map(mode, key, new_fn)
130+
end
131+
end
132+
109133
return true
110134
end,
111135
})
112136

113137
current_picker:find()
114138
end
115139

116-
local function fzf_ui(sessions, callback, on_delete)
140+
local function fzf_ui(sessions, callback, on_delete, on_new)
117141
local fzf_lua = require('fzf-lua')
118142
local config = require('opencode.config')
119143

@@ -150,6 +174,24 @@ local function fzf_ui(sessions, callback, on_delete)
150174
}
151175
end
152176

177+
-- New session action (shared on_new)
178+
local new_config = config.keymap.session_picker.new_session
179+
if new_config and new_config[1] then
180+
local key = require('fzf-lua.utils').neovim_bind_to_fzf(new_config[1])
181+
actions_config[key] = {
182+
fn = function()
183+
if on_new then
184+
local new_session = on_new()
185+
if new_session then
186+
table.insert(sessions, 1, new_session)
187+
end
188+
end
189+
end,
190+
header = 'new',
191+
reload = true,
192+
}
193+
end
194+
153195
fzf_lua.fzf_exec(function(fzf_cb)
154196
for _, session in ipairs(sessions) do
155197
fzf_cb(format_session(session))
@@ -172,7 +214,7 @@ local function fzf_ui(sessions, callback, on_delete)
172214
})
173215
end
174216

175-
local function mini_pick_ui(sessions, callback, on_delete)
217+
local function mini_pick_ui(sessions, callback, on_delete, on_new)
176218
local mini_pick = require('mini.pick')
177219
local config = require('opencode.config')
178220

@@ -209,6 +251,29 @@ local function mini_pick_ui(sessions, callback, on_delete)
209251
}
210252
end
211253

254+
-- New session mapping using shared on_new
255+
local new_config = config.keymap.session_picker.new_session
256+
if new_config and new_config[1] then
257+
mappings.new_session = {
258+
char = new_config[1],
259+
func = function()
260+
if on_new then
261+
local new_session = on_new()
262+
if new_session then
263+
table.insert(sessions, 1, new_session)
264+
items = vim.tbl_map(function(session)
265+
return {
266+
text = format_session(session),
267+
session = session,
268+
}
269+
end, sessions)
270+
mini_pick.set_picker_items(items)
271+
end
272+
end
273+
end,
274+
}
275+
end
276+
212277
mini_pick.start({
213278
source = {
214279
items = items,
@@ -224,7 +289,7 @@ local function mini_pick_ui(sessions, callback, on_delete)
224289
})
225290
end
226291

227-
local function snacks_picker_ui(sessions, callback, on_delete)
292+
local function snacks_picker_ui(sessions, callback, on_delete, on_new)
228293
local Snacks = require('snacks')
229294
local config = require('opencode.config')
230295

@@ -256,13 +321,9 @@ local function snacks_picker_ui(sessions, callback, on_delete)
256321
local key = delete_config[1]
257322
local mode = delete_config.mode or 'i'
258323

259-
opts.win = {
260-
input = {
261-
keys = {
262-
[key] = { 'session_delete', mode = mode },
263-
},
264-
},
265-
}
324+
opts.win = opts.win or {}
325+
opts.win.input = opts.win.input or { keys = {} }
326+
opts.win.input.keys[key] = { 'session_delete', mode = mode }
266327

267328
opts.actions.session_delete = function(picker, item)
268329
if item and on_delete then
@@ -278,6 +339,32 @@ local function snacks_picker_ui(sessions, callback, on_delete)
278339
end
279340
end
280341

342+
-- New session key using shared on_new
343+
local new_config = config.keymap.session_picker.new_session
344+
if new_config and new_config[1] then
345+
local key = new_config[1]
346+
local mode = new_config.mode or 'i'
347+
348+
opts.win = opts.win or {}
349+
opts.win.input = opts.win.input or { keys = {} }
350+
opts.win.input.keys[key] = { 'session_new', mode = mode }
351+
352+
opts.actions.session_new = function(picker)
353+
vim.schedule(function()
354+
if on_new then
355+
local new_session = on_new()
356+
if new_session then
357+
table.insert(sessions, 1, new_session)
358+
picker:close()
359+
if callback then
360+
callback(new_session)
361+
end
362+
end
363+
end
364+
end)
365+
end
366+
end
367+
281368
Snacks.picker.pick(opts)
282369
end
283370

@@ -305,15 +392,31 @@ function M.pick(sessions, callback)
305392
end)
306393
end
307394

395+
local function on_new()
396+
local parent_id
397+
for _, s in ipairs(sessions or {}) do
398+
if s.parentID ~= nil then
399+
parent_id = s.parentID
400+
break
401+
end
402+
end
403+
local state = require('opencode.state')
404+
local created = state.api_client:create_session(parent_id and { parentID = parent_id } or false):wait()
405+
if created and created.id then
406+
return require('opencode.session').get_by_id(created.id)
407+
end
408+
return nil
409+
end
410+
308411
vim.schedule(function()
309412
if picker_type == 'telescope' then
310-
telescope_ui(sessions, callback, on_delete)
413+
telescope_ui(sessions, callback, on_delete, on_new)
311414
elseif picker_type == 'fzf' then
312-
fzf_ui(sessions, callback, on_delete)
415+
fzf_ui(sessions, callback, on_delete, on_new)
313416
elseif picker_type == 'mini.pick' then
314-
mini_pick_ui(sessions, callback, on_delete)
417+
mini_pick_ui(sessions, callback, on_delete, on_new)
315418
elseif picker_type == 'snacks' then
316-
snacks_picker_ui(sessions, callback, on_delete)
419+
snacks_picker_ui(sessions, callback, on_delete, on_new)
317420
else
318421
callback(nil)
319422
end

0 commit comments

Comments
 (0)