generated from ellisonleao/nvim-plugin-template
-
-
Notifications
You must be signed in to change notification settings - Fork 100
fix(tmux): use pane PID to find correct opencode server port #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking "Sign up for GitHub", you agree to our terms of service and privacy statement. We'll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
fix(tmux): use pane PID to find correct opencode server port #119
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -297,6 +297,19 @@ function M.get_port(launch) | |
| local Promise = require("opencode.promise") | ||
|
|
||
| return Promise.new(function(resolve, reject) | ||
| -- Check if provider can supply port directly | ||
| local provider = require("opencode.config").provider | ||
| if provider and provider.get_port then | ||
| local provider_port = provider:get_port() | ||
| if provider_port then | ||
| local ok, _ = pcall(test_port, provider_port) | ||
| if ok then | ||
| resolve(provider_port) | ||
| return | ||
| end | ||
| end | ||
| end | ||
|
|
||
| local configured_port = require("opencode.config").opts.port | ||
| local find_port_fn = configured_port and function() | ||
| return test_port(configured_port) | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,10 @@ | |
| ---Should return `true` if the provider is available, | ||
| ---else an error string and optional advice (for `vim.health.warn`). | ||
| ---@field health? fun(): boolean|string, ...string|string[] | ||
| --- | ||
| ---Get the port of the `opencode` server started by this provider. | ||
| ---Returns `nil` if the provider cannot determine the port (falls back to CWD-based discovery). | ||
| ---@field get_port? fun(self: opencode.Provider): number|nil | ||
|
|
||
| ---Configure and enable built-in providers. | ||
| ---@class opencode.provider.Opts | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -152,4 +152,9 @@ function Kitty:stop() | |
| end | ||
| end | ||
|
|
||
| ---@return number|nil | ||
| function Kitty:get_port() | ||
| return nil | ||
| end | ||
|
|
||
| return Kitty | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,4 +59,9 @@ function Snacks:stop() | |
| end | ||
| end | ||
|
|
||
| ---@return number|nil | ||
| function Snacks:get_port() | ||
| return nil | ||
| end | ||
|
|
||
| return Snacks | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,4 +72,9 @@ function Terminal:stop() | |
| end | ||
| end | ||
|
|
||
| ---@return number|nil | ||
| function Terminal:get_port() | ||
| return nil | ||
| end | ||
|
|
||
| return Terminal | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,9 @@ | |
| --- | ||
| ---The `tmux` pane ID where `opencode` is running (internal use only). | ||
| ---@field pane_id? string | ||
| --- | ||
| ---Cached port of the `opencode` server (internal use only). | ||
| ---@field port? number | ||
| local Tmux = {} | ||
| Tmux.__index = Tmux | ||
| Tmux.name = "tmux" | ||
|
|
@@ -20,6 +23,7 @@ function Tmux.new(opts) | |
| local self = setmetatable({}, Tmux) | ||
| self.opts = opts or {} | ||
| self.pane_id = nil | ||
| self.port = nil | ||
| return self | ||
| end | ||
|
|
||
|
|
@@ -85,7 +89,41 @@ function Tmux:stop() | |
| if pane_id then | ||
| vim.fn.system("tmux kill-pane -t " .. pane_id) | ||
| self.pane_id = nil | ||
| self.port = nil | ||
| end | ||
| end | ||
|
|
||
| ---Get the PID of the shell process running in the opencode pane. | ||
| ---@return number|nil pid | ||
| function Tmux:get_pane_process_pid() | ||
| local pane_id = self:get_pane_id() | ||
| if not pane_id then | ||
| return nil | ||
| end | ||
|
|
||
| local output = vim.fn.system("tmux list-panes -t " .. pane_id .. " -F '#{pane_pid}'") | ||
| local pid = tonumber(vim.trim(output)) | ||
| return pid | ||
| end | ||
|
|
||
| ---Get the port of the opencode server started in this pane. | ||
| ---Traces from pane PID through descendants to find the listening port. | ||
| ---Caches the result for subsequent calls. | ||
| ---@return number|nil port | ||
| function Tmux:get_port() | ||
| -- Return cached port if pane still exists | ||
| if self.port and self:get_pane_id() then | ||
| return self.port | ||
| end | ||
|
|
||
| local pane_pid = self:get_pane_process_pid() | ||
| if not pane_pid then | ||
| return nil | ||
| end | ||
|
|
||
| local process = require("opencode.util.process") | ||
| self.port = process.get_descendant_listening_port(pane_pid, 3) | ||
| return self.port | ||
| end | ||
|
|
||
| return Tmux | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -140,4 +140,9 @@ function Wezterm:stop() | |
| end | ||
| end | ||
|
|
||
| ---@return number|nil | ||
| function Wezterm:get_port() | ||
| return nil | ||
| end | ||
|
|
||
| return Wezterm | ||
60 changes: 60 additions & 0 deletions
lua/opencode/util/process.lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| ---Process utilities for provider implementations. | ||
| local M = {} | ||
|
|
||
| ---Get all descendant PIDs of a process (children, grandchildren, etc.) | ||
| ---@param pid number The parent process ID | ||
| ---@param max_depth? number Maximum recursion depth (default 3) | ||
| ---@return number[] pids List of descendant PIDs | ||
| function M.get_descendants(pid, max_depth) | ||
| max_depth = max_depth or 3 | ||
|
|
||
| local function recurse(current_pid, depth) | ||
| if depth > max_depth then | ||
| return {} | ||
| end | ||
|
|
||
| local children = {} | ||
| local output = vim.fn.system("pgrep -P " .. current_pid .. " 2>/dev/null") | ||
| for child_pid in output:gmatch("%d+") do | ||
| local child = tonumber(child_pid) | ||
| table.insert(children, child) | ||
| for _, descendant in ipairs(recurse(child, depth + 1)) do | ||
| table.insert(children, descendant) | ||
| end | ||
| end | ||
| return children | ||
| end | ||
|
|
||
| return recurse(pid, 1) | ||
| end | ||
|
|
||
| ---Find the TCP port a process is listening on. | ||
| ---@param pid number The process ID | ||
| ---@return number|nil port The listening port, or nil if not found | ||
| function M.get_listening_port(pid) | ||
| local lsof_output = vim.fn.system("lsof -w -iTCP -sTCP:LISTEN -P -n -a -p " .. pid .. " 2>/dev/null") | ||
| for line in lsof_output:gmatch("[^\r\n]+") do | ||
| local port = line:match(":(%d+)%s+%(LISTEN%)") | ||
| if port then | ||
| return tonumber(port) | ||
| end | ||
| end | ||
| return nil | ||
| end | ||
|
|
||
| ---Find the listening port of any descendant of a process. | ||
| ---@param pid number The ancestor process ID | ||
| ---@param max_depth? number Maximum recursion depth (default 3) | ||
| ---@return number|nil port The listening port, or nil if not found | ||
| function M.get_descendant_listening_port(pid, max_depth) | ||
| local descendants = M.get_descendants(pid, max_depth) | ||
| for _, desc_pid in ipairs(descendants) do | ||
| local port = M.get_listening_port(desc_pid) | ||
| if port then | ||
| return port | ||
| end | ||
| end | ||
| return nil | ||
| end | ||
|
|
||
| return M |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.