Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions lua/opencode/provider/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,43 @@

local M = {}

---Get the project root directory using smart detection.
---Priority: 1) git root, 2) LSP workspace, 3) nvim directory argument, 4) current buffer dir, 5) cwd
---@return string
function M.get_project_root()
local cwd = vim.fn.getcwd()

local git_cmd = "git -C " .. vim.fn.shellescape(cwd) .. " rev-parse --show-toplevel 2>/dev/null"
local git_root = vim.fn.systemlist(git_cmd)[1]
if vim.v.shell_error == 0 and git_root and git_root ~= "" then
return git_root
end

local clients = vim.lsp.get_clients({ bufnr = 0 })
for _, client in ipairs(clients) do
if client.config.root_dir then
return client.config.root_dir
end
end

local arg = vim.fn.argv(0)
---@cast arg string
if arg and arg ~= "" and vim.fn.isdirectory(arg) == 1 then
local path = vim.fn.fnamemodify(arg, ":p"):gsub("/$", "")
return path
end

local buf_name = vim.api.nvim_buf_get_name(0)
if buf_name and buf_name ~= "" then
local buf_dir = vim.fn.fnamemodify(buf_name, ":p:h")
if vim.fn.isdirectory(buf_dir) == 1 then
return buf_dir
end
end

return cwd
end

local function subscribe_to_sse()
if not require("opencode.config").opts.events.enabled then
return
Expand Down
3 changes: 2 additions & 1 deletion lua/opencode/provider/kitty.lua
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ function Kitty:start()
end

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

-- Input validation for `location` option
local VALID_LOCATIONS = {
Expand Down
32 changes: 30 additions & 2 deletions lua/opencode/provider/snacks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,41 @@ function Snacks:get()
return win
end

---@param current_cwd string
---@return boolean
---@private
function Snacks:hide_other_visible_terminals(current_cwd)
local terminals = require("snacks.terminal").list()
local did_hide = false
for _, term in ipairs(terminals) do
if term.buf and vim.api.nvim_buf_is_valid(term.buf) then
local term_info = vim.b[term.buf].snacks_terminal
local is_opencode = term_info and term_info.cmd == self.cmd
local is_other_cwd = term_info and term_info.cwd ~= current_cwd
local is_visible = term.win and vim.api.nvim_win_is_valid(term.win)
if is_opencode and is_other_cwd and is_visible then
term:hide()
did_hide = true
end
end
end
return did_hide
end

function Snacks:toggle()
require("snacks.terminal").toggle(self.cmd, self.opts)
local cwd = require("opencode.provider").get_project_root()
if self:hide_other_visible_terminals(cwd) then
return
end
local opts = vim.tbl_deep_extend("force", self.opts, { cwd = cwd })
require("snacks.terminal").toggle(self.cmd, opts)
end

function Snacks:start()
if not self:get() then
require("snacks.terminal").open(self.cmd, self.opts)
local cwd = require("opencode.provider").get_project_root()
local opts = vim.tbl_deep_extend("force", self.opts, { cwd = cwd })
require("snacks.terminal").open(self.cmd, opts)
end
end

Expand Down
1 change: 1 addition & 0 deletions lua/opencode/provider/terminal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function Terminal:start()
-- FIX: There's a few empty columns on the right side of the terminal until it's redrawn, at least for me.
vim.fn.jobstart(self.cmd, {
term = true,
cwd = require("opencode.provider").get_project_root(),
on_exit = function()
self.winid = nil
self.bufnr = nil
Expand Down
5 changes: 3 additions & 2 deletions lua/opencode/provider/tmux.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ end
function Tmux:start()
local pane_id = self:get_pane_id()
if not pane_id then
-- Create new pane
local cwd = require("opencode.provider").get_project_root()
local options = self.opts.options or ""
self.pane_id =
vim.fn.system(string.format("tmux split-window -d -P -F '#{pane_id}' %s '%s'", self.opts.options, self.cmd))
vim.fn.system(string.format("tmux split-window -d -P -F '#{pane_id}' -c '%s' %s '%s'", cwd, options, self.cmd))
end
end

Expand Down
3 changes: 3 additions & 0 deletions lua/opencode/provider/wezterm.lua
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ function Wezterm:start()
if not pane_id then
local cmd_parts = { "wezterm", "cli", "split-pane" }

table.insert(cmd_parts, "--cwd")
table.insert(cmd_parts, require("opencode.provider").get_project_root())

if self.opts.direction then
table.insert(cmd_parts, "--" .. self.opts.direction)
end
Expand Down