Skip to content

Commit 29e90c3

Browse files
committed
feat: implement project root detection for terminal providers
1 parent dfca5bb commit 29e90c3

6 files changed

Lines changed: 47 additions & 5 deletions

File tree

lua/opencode/provider/init.lua

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,38 @@
5252

5353
local M = {}
5454

55+
---Get the project root directory using smart detection.
56+
---Priority: 1) nvim directory argument, 2) git root, 3) current buffer dir, 4) LSP workspace, 5) cwd
57+
---@return string
58+
function M.get_project_root()
59+
local arg = vim.fn.argv(0)
60+
if arg and arg ~= "" and vim.fn.isdirectory(arg) == 1 then
61+
return vim.fn.fnamemodify(arg, ":p"):gsub("/$", "")
62+
end
63+
64+
local git_root = vim.fn.systemlist("git rev-parse --show-toplevel 2>/dev/null")[1]
65+
if vim.v.shell_error == 0 and git_root and git_root ~= "" then
66+
return git_root
67+
end
68+
69+
local buf_name = vim.api.nvim_buf_get_name(0)
70+
if buf_name and buf_name ~= "" then
71+
local buf_dir = vim.fn.fnamemodify(buf_name, ":p:h")
72+
if vim.fn.isdirectory(buf_dir) == 1 then
73+
return buf_dir
74+
end
75+
end
76+
77+
local clients = vim.lsp.get_clients({ bufnr = 0 })
78+
for _, client in ipairs(clients) do
79+
if client.config.root_dir then
80+
return client.config.root_dir
81+
end
82+
end
83+
84+
return vim.fn.getcwd()
85+
end
86+
5587
local function subscribe_to_sse()
5688
if not require("opencode.config").opts.events.enabled then
5789
return

lua/opencode/provider/kitty.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ function Kitty:start()
103103
end
104104

105105
local location = self.opts.location
106-
local launch_cmd = { "launch", "--cwd=current", "--hold", "--dont-take-focus" }
106+
local cwd = require("opencode.provider").get_project_root()
107+
local launch_cmd = { "launch", "--cwd=" .. cwd, "--hold", "--dont-take-focus" }
107108

108109
-- Input validation for `location` option
109110
local VALID_LOCATIONS = {

lua/opencode/provider/snacks.lua

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,16 @@ function Snacks:get()
4343
end
4444

4545
function Snacks:toggle()
46-
require("snacks.terminal").toggle(self.cmd, self.opts)
46+
local cwd = require("opencode.provider").get_project_root()
47+
local opts = vim.tbl_deep_extend("force", self.opts, { cwd = cwd })
48+
require("snacks.terminal").toggle(self.cmd, opts)
4749
end
4850

4951
function Snacks:start()
5052
if not self:get() then
51-
require("snacks.terminal").open(self.cmd, self.opts)
53+
local cwd = require("opencode.provider").get_project_root()
54+
local opts = vim.tbl_deep_extend("force", self.opts, { cwd = cwd })
55+
require("snacks.terminal").open(self.cmd, opts)
5256
end
5357
end
5458

lua/opencode/provider/terminal.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ function Terminal:start()
5151
-- FIX: There's a few empty columns on the right side of the terminal until it's redrawn, at least for me.
5252
vim.fn.jobstart(self.cmd, {
5353
term = true,
54+
cwd = require("opencode.provider").get_project_root(),
5455
on_exit = function()
5556
self.winid = nil
5657
self.bufnr = nil

lua/opencode/provider/tmux.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ end
7373
function Tmux:start()
7474
local pane_id = self:get_pane_id()
7575
if not pane_id then
76-
-- Create new pane
76+
local cwd = require("opencode.provider").get_project_root()
77+
local options = self.opts.options or ""
7778
self.pane_id =
78-
vim.fn.system(string.format("tmux split-window -d -P -F '#{pane_id}' %s '%s'", self.opts.options, self.cmd))
79+
vim.fn.system(string.format("tmux split-window -d -P -F '#{pane_id}' -c '%s' %s '%s'", cwd, options, self.cmd))
7980
end
8081
end
8182

lua/opencode/provider/wezterm.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ function Wezterm:start()
108108
if not pane_id then
109109
local cmd_parts = { "wezterm", "cli", "split-pane" }
110110

111+
table.insert(cmd_parts, "--cwd")
112+
table.insert(cmd_parts, require("opencode.provider").get_project_root())
113+
111114
if self.opts.direction then
112115
table.insert(cmd_parts, "--" .. self.opts.direction)
113116
end

0 commit comments

Comments
 (0)