Skip to content

Commit d6721a7

Browse files
committed
feat(ui): add keymap and cmd to rename current session
The new keymap is `<leader>oR`
1 parent 504678f commit d6721a7

File tree

4 files changed

+72
-21
lines changed

4 files changed

+72
-21
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ require('opencode').setup({
109109
['<leader>oT'] = { 'timeline' }, -- Display timeline picker to navigate/undo/redo/fork messages
110110
['<leader>oq'] = { 'close' }, -- Close UI windows
111111
['<leader>os'] = { 'select_session' }, -- Select and load a opencode session
112+
['<leader>oR'] = { 'rename_session' }, -- Rename current session
112113
['<leader>op'] = { 'configure_provider' }, -- Quick provider and model switch from predefined list
113114
['<leader>oz'] = { 'toggle_zoom' }, -- Zoom in/out on the Opencode windows
114115
['<leader>od'] = { 'diff_open' }, -- Opens a diff tab of a modified file since the last opencode prompt
@@ -330,6 +331,7 @@ The plugin provides the following actions that can be triggered via keymaps, com
330331
| Open input window (new session) | `<leader>oI` | `:Opencode open input_new_session` | `require('opencode.api').open_input_new_session()` |
331332
| Open output window | `<leader>oo` | `:Opencode open output` | `require('opencode.api').open_output()` |
332333
| Create and switch to a named session | - | `:Opencode session new <name>` | `:Opencode session new <name>` (user command) |
334+
| Rename current session | `<leader>oR` | `:Opencode session rename <name>` | `:Opencode session rename <name>` (user command) |
333335
| Toggle focus opencode / last window | `<leader>ot` | `:Opencode toggle focus` | `require('opencode.api').toggle_focus()` |
334336
| Close UI windows | `<leader>oq` | `:Opencode close` | `require('opencode.api').close()` |
335337
| Select and load session | `<leader>os` | `:Opencode session select` | `require('opencode.api').select_session()` |

lua/opencode/api.lua

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,54 @@ function M.fork_session(message_id)
741741
end)
742742
end
743743

744+
---@param current_session? Session
745+
--- @param new_title? string
746+
function M.rename_session(current_session, new_title)
747+
local promise = require('opencode.promise').new()
748+
current_session = current_session or vim.deepcopy(state.active_session) --[[@as Session]]
749+
if not current_session then
750+
vim.notify('No active session to rename', vim.log.levels.WARN)
751+
promise:resolve(nil)
752+
return promise
753+
end
754+
local function rename_session_with_title(title)
755+
state.api_client
756+
:update_session(current_session.id, { title = title })
757+
:catch(function(err)
758+
vim.schedule(function()
759+
vim.notify('Failed to rename session: ' .. vim.inspect(err), vim.log.levels.ERROR)
760+
end)
761+
end)
762+
:and_then(function()
763+
current_session.title = title
764+
if state.active_session and state.active_session.id == current_session.id then
765+
local session_obj = session.get_by_id(current_session.id)
766+
if session_obj then
767+
session_obj.title = title
768+
state.active_session = vim.deepcopy(session_obj)
769+
end
770+
end
771+
promise:resolve(current_session)
772+
end)
773+
end
774+
775+
if new_title and new_title ~= '' then
776+
rename_session_with_title(new_title)
777+
return promise
778+
end
779+
780+
vim.schedule(function()
781+
vim.ui.input({ prompt = 'New session name: ', default = current_session.title or '' }, function(input)
782+
if input and input ~= '' then
783+
rename_session_with_title(input)
784+
else
785+
promise:resolve(nil)
786+
end
787+
end)
788+
end)
789+
return promise
790+
end
791+
744792
-- Returns the ID of the next user message after the current undo point
745793
-- This is a port of the opencode tui logic
746794
-- https://github.com/sst/opencode/blob/dev/packages/tui/internal/components/chat/messages.go#L1199
@@ -913,8 +961,8 @@ M.commands = {
913961
},
914962

915963
session = {
916-
desc = 'Manage sessions (new/select/child/compact/share/unshare)',
917-
completions = { 'new', 'select', 'child', 'compact', 'share', 'unshare', 'agents_init' },
964+
desc = 'Manage sessions (new/select/child/compact/share/unshare/rename)',
965+
completions = { 'new', 'select', 'child', 'compact', 'share', 'unshare', 'agents_init', 'rename' },
918966
fn = function(args)
919967
local subcmd = args[1]
920968
if subcmd == 'new' then
@@ -942,6 +990,9 @@ M.commands = {
942990
M.unshare()
943991
elseif subcmd == 'agents_init' then
944992
M.initialize()
993+
elseif subcmd == 'rename' then
994+
local title = table.concat(vim.list_slice(args, 2), ' ')
995+
M.rename_session(state.active_session, title)
945996
else
946997
local valid_subcmds = table.concat(M.commands.session.completions, ', ')
947998
vim.notify('Invalid session subcommand. Use: ' .. valid_subcmds, vim.log.levels.ERROR)

lua/opencode/config.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ M.defaults = {
2222
['<leader>oT'] = { 'timeline', desc = 'Session timeline' },
2323
['<leader>oq'] = { 'close', desc = 'Close Opencode window' },
2424
['<leader>os'] = { 'select_session', desc = 'Select session' },
25+
['<leader>oR'] = { 'rename_session', desc = 'Rename session' },
2526
['<leader>op'] = { 'configure_provider', desc = 'Configure provider' },
2627
['<leader>oz'] = { 'toggle_zoom', desc = 'Toggle zoom' },
2728
['<leader>od'] = { 'diff_open', desc = 'Open diff view' },

lua/opencode/ui/session_picker.lua

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ local M = {}
22
local config = require('opencode.config')
33
local base_picker = require('opencode.ui.base_picker')
44
local util = require('opencode.util')
5+
local api = require('lua.opencode.api')
56

67
---Format session parts for session picker
78
---@param session Session object
@@ -18,28 +19,24 @@ function M.pick(sessions, callback)
1819
label = 'rename',
1920
fn = function(selected, opts)
2021
local promise = require('opencode.promise').new()
21-
local state = require('opencode.state')
22-
23-
vim.schedule(function()
24-
vim.ui.input({ prompt = 'New session name: ', default = selected.title or '' }, function(input)
25-
if input and input ~= '' then
26-
state.api_client:update_session(selected.id, { title = input }):catch(function(err)
27-
vim.schedule(function()
28-
vim.notify('Failed to rename session: ' .. vim.inspect(err), vim.log.levels.ERROR)
29-
end)
30-
end)
31-
selected.title = input
32-
local idx = util.find_index_of(opts.items, function(item)
33-
return item.id == selected.id
34-
end)
35-
36-
if idx > 0 then
37-
opts.items[idx].title = input
38-
end
22+
api
23+
.rename_session(selected)
24+
:and_then(function(updated_session)
25+
local idx = util.find_index_of(opts.items, function(item)
26+
return item.id == updated_session.id
27+
end)
28+
if idx > 0 then
29+
opts.items[idx] = updated_session
3930
end
4031
promise:resolve(opts.items)
4132
end)
42-
end)
33+
:catch(function(err)
34+
vim.schedule(function()
35+
vim.notify('Failed to rename session: ' .. vim.inspect(err), vim.log.levels.ERROR)
36+
promise:resolve(nil)
37+
end)
38+
end)
39+
4340
return promise
4441
end,
4542
reload = true,

0 commit comments

Comments
 (0)