From 95dd54336a2b0bc46713bd761906db24cf19461d Mon Sep 17 00:00:00 2001 From: Asger Gitz-Johansen Date: Tue, 16 Jun 2026 21:11:20 +0200 Subject: [PATCH] feat: add 'location' config option --- README.md | 13 ++++++++++--- doc/opencode.nvim.txt | 16 ++++++++++++---- lua/opencode.lua | 43 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f7a87f0..632937b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # opencode.nvim -Neovim plugin that toggles an `opencode` terminal in a right-side split. +Neovim plugin that toggles an `opencode` terminal in a configurable split. The terminal buffer is kept alive when hidden, so your `opencode` session remains available across toggles. @@ -25,6 +25,7 @@ Using `lazy.nvim`: "agj/opencode.nvim", opts = { width = 0.3, + location = "right", }, } ``` @@ -57,11 +58,17 @@ show the same session. ```lua require("opencode").setup({ width = 0.3, + location = "right", }) ``` -`width` is the fraction of the screen width used by the terminal window. The -default is `0.3`. It must be greater than `0` and less than or equal to `1`. +`width` is the fraction of the screen width used by the terminal window for +`left` and `right` locations, or the screen height for `top` and `bottom` +locations. The default is `0.3`. It must be greater than `0` and less than or +equal to `1`. + +`location` controls where the terminal window opens. The default is `"right"`. +It must be one of `"left"`, `"right"`, `"top"`, or `"bottom"`. ## Help diff --git a/doc/opencode.nvim.txt b/doc/opencode.nvim.txt index 6aeb5e7..b82ad96 100644 --- a/doc/opencode.nvim.txt +++ b/doc/opencode.nvim.txt @@ -13,7 +13,7 @@ CONTENTS *opencode.nvim-contents* =============================================================================== INTRODUCTION *opencode.nvim* -opencode.nvim toggles an `opencode` terminal in a right-side split. +opencode.nvim toggles an `opencode` terminal in a configurable split. The terminal buffer is hidden instead of deleted when closed, so the same `opencode` session is shown the next time the window is toggled open. @@ -38,6 +38,7 @@ Using lazy.nvim: >lua "agj/opencode.nvim", opts = { width = 0.3, + location = "right", }, } < @@ -55,7 +56,7 @@ USAGE *opencode.nvim-usage* *:OpenCodeToggle* :OpenCodeToggle - Toggle the right-side opencode terminal window. + Toggle the opencode terminal window. If the terminal window is visible, this closes only the window. The terminal buffer and running `opencode` process remain alive. If the @@ -67,6 +68,7 @@ CONFIGURATION *opencode.nvim-configuration* Call setup with an optional table: >lua require("opencode").setup({ width = 0.3, + location = "right", }) < @@ -74,8 +76,14 @@ Options: *opencode.nvim-options* *opencode.nvim-width* width number, default: 0.3 - Fraction of the screen width used by the terminal split. Must be - greater than 0 and less than or equal to 1. + Fraction of the screen width used by the terminal split for left and + right locations, or the screen height for top and bottom locations. + Must be greater than 0 and less than or equal to 1. + + *opencode.nvim-location* +location string, default: "right" + Side of the screen where the terminal split opens. Must be one of + "left", "right", "top", or "bottom". =============================================================================== LICENSE *opencode.nvim-license* diff --git a/lua/opencode.lua b/lua/opencode.lua index a4af0a4..8f1f807 100644 --- a/lua/opencode.lua +++ b/lua/opencode.lua @@ -21,6 +21,14 @@ local state = { local config = { width = 0.3, + location = "right", +} + +local valid_locations = { + left = true, + right = true, + top = true, + bottom = true, } local function is_valid_window(win) @@ -35,10 +43,28 @@ local function terminal_width() return math.max(1, math.floor(vim.o.columns * config.width)) end -local function open_side_window() - vim.cmd("botright vertical " .. terminal_width() .. "new") +local function terminal_height() + return math.max(1, math.floor(vim.o.lines * config.width)) +end + +local function open_terminal_window() + if config.location == "left" then + vim.cmd("topleft vertical " .. terminal_width() .. "new") + elseif config.location == "right" then + vim.cmd("botright vertical " .. terminal_width() .. "new") + elseif config.location == "top" then + vim.cmd("topleft " .. terminal_height() .. "new") + else + vim.cmd("botright " .. terminal_height() .. "new") + end + state.win = vim.api.nvim_get_current_win() - vim.api.nvim_set_option_value("winfixwidth", true, { win = state.win }) + + if config.location == "left" or config.location == "right" then + vim.api.nvim_set_option_value("winfixwidth", true, { win = state.win }) + else + vim.api.nvim_set_option_value("winfixheight", true, { win = state.win }) + end end local function start_terminal() @@ -62,7 +88,7 @@ function M.toggle() return end - open_side_window() + open_terminal_window() if is_valid_buffer(state.buf) then vim.api.nvim_win_set_buf(state.win, state.buf) @@ -85,6 +111,15 @@ function M.setup(opts) config.width = opts.width end + if opts.location ~= nil then + assert( + type(opts.location) == "string" and valid_locations[opts.location], + "opencode.nvim: location must be one of: left, right, top, bottom" + ) + + config.location = opts.location + end + vim.api.nvim_create_user_command("OpenCodeToggle", function() M.toggle() end, { force = true })