Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.

- Fix: Correctly center floating terminal when no borders are used.
- Set terminal window as `nolist`.
- Add `fixed_height` & `fixed_width` options to control whether terminal size should be preserved on new splits.

## 1.0.0 - 2025-11-21

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ require("ergoterm").setup({
| `cleanup_on_failure` | `boolean` | `false` | Cleanup terminal when process exits with non-zero code |
| `cleanup_on_success` | `boolean` | `true` | Cleanup terminal when process exits with code 0 |
| `default_action` | `function` | `function(term) term:focus() end` | Action performed when selecting terminal with default picker action |
| `fixed_height` | boolean | `true` | Keep the terminal height when new horizontal splits are opened (it depends on vim's `equalalways` being set) |
| `fixed_width` | boolean | `true` | Keep the terminal width when new vertical splits are opened (it depends on vim's `equalalways` being set) |
| `float_opts` | `table` | See below | Floating window configuration options |
| `↳ border` | `string` | `"single"` | Border style (see `:help nvim_open_win()`) |
| `↳ col` | `number` | Auto-centered | Column position |
Expand Down
10 changes: 10 additions & 0 deletions doc/ergoterm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,16 @@ default_action *ergoterm-default_action*
Default: `function(term) term:focus() end`
Action performed when selecting terminal with default picker action

fixed_height *ergoterm-fixed_height*
Type: `boolean`
Default: `true`
Keep the terminal height when new horizontal splits are opened (it depends on vim's `equalalways` being set)

fixed_width *ergoterm-fixed_width*
Type: `boolean`
Default: `true`
Keep the terminal width when new vertical splits are opened (it depends on vim's `equalalways` being set)

float_opts *ergoterm-float_opts*
Type: `table`
Floating window configuration options (see |nvim_open_win()|)
Expand Down
12 changes: 12 additions & 0 deletions lua/ergoterm/commandline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ end
---@field watch_files boolean?
---@field persist_mode boolean?
---@field persist_size boolean?
---@field fixed_width boolean?
---@field fixed_height boolean?
---@field auto_list boolean?
---@field start_in_insert boolean?
---@field sticky boolean?
Expand Down Expand Up @@ -102,6 +104,8 @@ function M.parse(args)
watch_files = true,
persist_mode = true,
persist_size = true,
fixed_width = true,
fixed_height = true,
auto_list = true,
start_in_insert = true,
sticky = true,
Expand Down Expand Up @@ -295,6 +299,10 @@ M._all_options = {

persist_size = M._boolean_options,

fixed_width = M._boolean_options,

fixed_height = M._boolean_options,

auto_list = M._boolean_options,

start_in_insert = M._boolean_options,
Expand Down Expand Up @@ -375,6 +383,8 @@ M._term_new_options = {
watch_files = M._all_options.watch_files,
persist_mode = M._all_options.persist_mode,
persist_size = M._all_options.persist_size,
fixed_width = M._all_options.fixed_width,
fixed_height = M._all_options.fixed_height,
auto_list = M._all_options.auto_list,
["env."] = M._all_options["env."],
start_in_insert = M._all_options.start_in_insert,
Expand Down Expand Up @@ -410,6 +420,8 @@ M._term_update_options = {
watch_files = M._all_options.watch_files,
persist_mode = M._all_options.persist_mode,
persist_size = M._all_options.persist_size,
fixed_width = M._all_options.fixed_width,
fixed_height = M._all_options.fixed_height,
auto_list = M._all_options.auto_list,
start_in_insert = M._all_options.start_in_insert,
sticky = M._all_options.sticky,
Expand Down
6 changes: 6 additions & 0 deletions lua/ergoterm/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ function M.new(args)
vim.validate("watch_files", parsed.watch_files, "boolean", true)
vim.validate("persist_mode", parsed.persist_mode, "boolean", true)
vim.validate("persist_size", parsed.persist_size, "boolean", true)
vim.validate("fixed_width", parsed.fixed_width, "boolean", true)
vim.validate("fixed_height", parsed.fixed_height, "boolean", true)
vim.validate("auto_list", parsed.auto_list, "boolean", true)
vim.validate("start_in_insert", parsed.start_in_insert, "boolean", true)
vim.validate("sticky", parsed.sticky, "boolean", true)
Expand All @@ -50,6 +52,8 @@ function M.new(args)
watch_files = parsed.watch_files,
persist_mode = parsed.persist_mode,
persist_size = parsed.persist_size,
fixed_width = parsed.fixed_width,
fixed_height = parsed.fixed_height,
auto_list = parsed.auto_list,
start_in_insert = parsed.start_in_insert,
sticky = parsed.sticky,
Expand Down Expand Up @@ -175,6 +179,8 @@ function M.update(args, bang, picker)
vim.validate("watch_files", parsed.watch_files, "boolean", true)
vim.validate("persist_mode", parsed.persist_mode, "boolean", true)
vim.validate("persist_size", parsed.persist_size, "boolean", true)
vim.validate("fixed_width", parsed.fixed_width, "boolean", true)
vim.validate("fixed_height", parsed.fixed_height, "boolean", true)
vim.validate("auto_list", parsed.auto_list, "boolean", true)
vim.validate("start_in_insert", parsed.start_in_insert, "boolean", true)
vim.validate("sticky", parsed.sticky, "boolean", true)
Expand Down
4 changes: 4 additions & 0 deletions lua/ergoterm/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ M.NULL_CALLBACK = function(...) end
---@field show_on_failure boolean?
---@field persist_mode boolean?
---@field persist_size boolean?
---@field fixed_width boolean?
---@field fixed_height boolean?
---@field auto_list boolean?
---@field size Size?
---@field start_in_insert boolean?
Expand Down Expand Up @@ -114,6 +116,8 @@ local config = {
float_winblend = 10,
persist_mode = false,
persist_size = true,
fixed_width = true,
fixed_height = true,
auto_list = true,
sticky = false,
size = {
Expand Down
8 changes: 6 additions & 2 deletions lua/ergoterm/instance.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ local utils = require("ergoterm.utils")
---@field float_winblend number
---@field persist_mode boolean
---@field persist_size boolean
---@field fixed_width boolean
---@field fixed_height boolean
---@field auto_list boolean
---@field size Size
---@field start_in_insert boolean
Expand Down Expand Up @@ -132,6 +134,8 @@ function Terminal:new(args)
term.float_winblend = term.float_winblend or config.get("terminal_defaults.float_winblend")
term.persist_mode = vim.F.if_nil(term.persist_mode, config.get("terminal_defaults.persist_mode"))
term.persist_size = vim.F.if_nil(term.persist_size, config.get("terminal_defaults.persist_size"))
term.fixed_width = vim.F.if_nil(term.fixed_width, config.get("terminal_defaults.fixed_width"))
term.fixed_height = vim.F.if_nil(term.fixed_height, config.get("terminal_defaults.fixed_height"))
if term.selectable ~= nil then
utils.notify(
"[ergoterm] `selectable` option is deprecated and will be removed soon. Use `auto_list` instead.",
Expand Down Expand Up @@ -533,9 +537,9 @@ function Terminal:_compute_float_win_config()
float_opts.height = float_opts.height or math.ceil(math.min(vim.o.lines, math.max(20, vim.o.lines - 5)))
float_opts.width = float_opts.width or math.ceil(math.min(vim.o.columns, math.max(80, vim.o.columns - 10)))
float_opts.row = float_opts.row or
math.ceil(vim.o.lines - float_opts.height) * 0.5 - (float_opts.border ~= 'none' and 1 or 0)
math.ceil(vim.o.lines - float_opts.height) * 0.5 - (float_opts.border ~= 'none' and 1 or 0)
float_opts.col = float_opts.col or
math.ceil(vim.o.columns - float_opts.width) * 0.5 - (float_opts.border ~= 'none' and 1 or 0)
math.ceil(vim.o.columns - float_opts.width) * 0.5 - (float_opts.border ~= 'none' and 1 or 0)
float_opts.zindex = (vim.api.nvim_win_get_config(0).zindex or 0) + 1
return float_opts
end
Expand Down
10 changes: 10 additions & 0 deletions lua/ergoterm/instance/open.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
local utils = require("ergoterm.utils")

local NEW_WINDOW_LAYOUTS = { "above", "below", "left", "right", "float" }
local HORIZONTAL_LAYOUTS = { "above", "below" }
local VERTICAL_LAYOUTS = { "left", "right" }
local TAB_LAYOUT = "tab"
local CURRENT_WINDOW_LAYOUT = "window"

Expand Down Expand Up @@ -95,6 +97,14 @@ function M._set_win_options(term)
vim.api.nvim_set_option_value("list", false, { scope = "local", win = window })
vim.api.nvim_set_option_value("foldmethod", "manual", { scope = "local", win = window })
vim.api.nvim_set_option_value("foldtext", "foldtext()", { scope = "local", win = window })

if (term.fixed_height and vim.tbl_contains(HORIZONTAL_LAYOUTS, term._state.layout)) then
vim.api.nvim_set_option_value("winfixheight", true, { scope = "local", win = window })
end
if (term.fixed_width and vim.tbl_contains(VERTICAL_LAYOUTS, term._state.layout)) then
vim.api.nvim_set_option_value("winfixwidth", true, { scope = "local", win = window })
end

if term._state.layout == "float" then
M._set_float_options(term)
end
Expand Down
8 changes: 5 additions & 3 deletions lua/ergoterm/instance/update.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ local ALLOWED_SETTINGS = {
"env",
"name",
"meta",
"fixed_width",
"fixed_height",
"float_props",
"float_winblend",
"persist_mode",
Expand Down Expand Up @@ -76,9 +78,9 @@ end
---@param deep_merge boolean
function M._update_setting(term, setting, value, deep_merge)
local should_merge = deep_merge
and type(value) == "table"
and type(term[setting]) == "table"
and not vim.islist(value)
and type(value) == "table"
and type(term[setting]) == "table"
and not vim.islist(value)

if should_merge then
term[setting] = vim.tbl_deep_extend("force", term[setting], value)
Expand Down
4 changes: 4 additions & 0 deletions spec/ergoterm/commandline_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ describe("commandline.term_new_complete", function()
assert.is_true(vim.tbl_contains(result, "float_opts.width="))
assert.is_true(vim.tbl_contains(result, "float_opts.height="))
assert.is_true(vim.tbl_contains(result, "float_opts.title="))
assert.is_true(vim.tbl_contains(result, "fixed_width="))
assert.is_true(vim.tbl_contains(result, "fixed_height="))
assert.is_true(vim.tbl_contains(result, "tags="))
assert.is_true(vim.tbl_contains(result, "meta.="))
assert.is_true(vim.tbl_contains(result, "env.="))
Expand Down Expand Up @@ -332,6 +334,8 @@ describe("commandline.term_update_complete", function()
assert.is_true(vim.tbl_contains(result, "float_opts.width="))
assert.is_true(vim.tbl_contains(result, "float_opts.height="))
assert.is_true(vim.tbl_contains(result, "float_opts.title="))
assert.is_true(vim.tbl_contains(result, "fixed_width="))
assert.is_true(vim.tbl_contains(result, "fixed_height="))
assert.is_true(vim.tbl_contains(result, "tags="))
assert.is_true(vim.tbl_contains(result, "meta.="))
end)
Expand Down
40 changes: 40 additions & 0 deletions spec/ergoterm/instance/open_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,46 @@ describe(".open", function()
assert.equal(20, vim.wo[term:get_state("window")].winblend)
end)
end)

it("sets winfixheight if layout is horizontal and fixed_height is true", function()
test_helpers.with_option("winfixheight", false, function()
local term = Terminal:new({ fixed_height = true })

open.open(term, "below")

assert.is_true(vim.wo[term:get_state("window")].winfixheight)
end)
end)

it("does not set winfixheight if fixed_height is false", function()
test_helpers.with_option("winfixheight", true, function()
local term = Terminal:new({ fixed_height = false })

open.open(term, "below")

assert.is_false(vim.wo[term:get_state("window")].winfixheight)
end)
end)

it("sets winfixwidth if layout is vertical and fixed_width is true", function()
test_helpers.with_option("winfixwidth", false, function()
local term = Terminal:new({ fixed_width = true })

open.open(term, "right")

assert.is_true(vim.wo[term:get_state("window")].winfixwidth)
end)
end)

it("does not set winfixwidth if fixed_width is false", function()
test_helpers.with_option("winfixwidth", true, function()
local term = Terminal:new({ fixed_width = false })

open.open(term, "right")

assert.is_false(vim.wo[term:get_state("window")].winfixwidth)
end)
end)
end)

describe(".is_open", function()
Expand Down
12 changes: 12 additions & 0 deletions spec/ergoterm/instance_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ describe(":new", function()
assert.is_true(term.persist_size)
end)

it("defaults to config's fixed_width", function()
local term = Terminal:new()

assert.is_true(term.fixed_width)
end)

it("defaults to config's fixed_height", function()
local term = Terminal:new()

assert.is_true(term.fixed_height)
end)

it("defaults to config's start_in_insert", function()
local term = Terminal:new()

Expand Down