forked from sudo-tee/opencode.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession_picker.lua
More file actions
135 lines (122 loc) · 4.32 KB
/
session_picker.lua
File metadata and controls
135 lines (122 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
local M = {}
local config = require('opencode.config')
local base_picker = require('opencode.ui.base_picker')
local util = require('opencode.util')
local api = require('opencode.api')
local Promise = require('opencode.promise')
---Format session parts for session picker
---@param session Session object
---@return PickerItem
function format_session_item(session, width)
local debug_text = 'ID: ' .. (session.id or 'N/A')
local updated_time = (session.time and session.time.updated) or 'N/A'
return base_picker.create_time_picker_item(session.title, updated_time, debug_text, width)
end
function M.pick(sessions, callback)
local actions = {
rename = {
key = config.keymap.session_picker.rename_session,
label = 'rename',
fn = function(selected, opts)
local promise = require('opencode.promise').new()
api
.rename_session(selected)
:and_then(function(updated_session)
if not updated_session then
promise:resolve(nil)
return
end
local idx = util.find_index_of(opts.items, function(item)
return item.id == updated_session.id
end)
if idx > 0 then
opts.items[idx] = updated_session
end
promise:resolve(opts.items)
end)
:catch(function(err)
vim.schedule(function()
vim.notify('Failed to rename session: ' .. vim.inspect(err), vim.log.levels.ERROR)
promise:resolve(nil)
end)
end)
return promise
end,
reload = true,
},
delete = {
key = config.keymap.session_picker.delete_session,
label = 'delete',
multi_selection = true,
fn = Promise.async(function(selected, opts)
local state = require('opencode.state')
local sessions_to_delete = type(selected) == 'table' and selected.id == nil and selected or { selected }
local to_delete_ids = {}
for _, s in ipairs(sessions_to_delete) do
to_delete_ids[s.id] = true
end
local deleting_current = state.active_session and to_delete_ids[state.active_session.id] or false
if deleting_current then
local core = require('opencode.core')
local remaining = vim.tbl_filter(function(item)
return not to_delete_ids[item.id]
end, opts.items or {})
if #remaining > 0 then
core.switch_session(remaining[1].id):await()
else
vim.notify('deleting current session, creating new session')
state.session.set_active(core.create_new_session():await())
end
end
for _, session in ipairs(sessions_to_delete) do
state.api_client:delete_session(session.id):catch(function(err)
vim.schedule(function()
vim.notify('Failed to delete session ' .. session.id .. ': ' .. vim.inspect(err), vim.log.levels.ERROR)
end)
end)
local idx = util.find_index_of(opts.items, function(item)
return item.id == session.id
end)
if idx > 0 then
table.remove(opts.items, idx)
end
end
vim.notify('Deleted ' .. #sessions_to_delete .. ' session(s)', vim.log.levels.INFO)
return opts.items
end),
reload = true,
},
new = {
key = config.keymap.session_picker.new_session,
label = 'new',
fn = Promise.async(function(selected, opts)
local parent_id
for _, s in ipairs(opts.items or {}) do
if s.parentID ~= nil then
parent_id = s.parentID
break
end
end
local state = require('opencode.state')
local created = state.api_client:create_session(parent_id and { parentID = parent_id } or false):await()
if created and created.id then
local new_session = require('opencode.session').get_by_id(created.id):await()
table.insert(opts.items, 1, new_session)
return opts.items
end
return nil
end),
reload = true,
},
}
return base_picker.pick({
items = sessions,
format_fn = format_session_item,
actions = actions,
callback = callback,
title = 'Select A Session',
width = config.ui.picker_width or 100,
layout_opts = config.ui.picker,
})
end
return M