Skip to content

Commit 3f682cf

Browse files
Add clear option to send
1 parent 0179ba4 commit 3f682cf

7 files changed

Lines changed: 71 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
77
- BREAKING: `selectable` option has been deprecated in favor of `auto_list`.
88
- BREAKING: Rename `.get_last_focused()` to `.get_target_for_bang()`.
99
- Added `scrollback` setting to configure terminal scrollback buffer size.
10+
- Added `clear` option to `term:send()` to clear the terminal before sending input.
1011

1112
## 0.9.0 - 2025-11-07
1213

lua/ergoterm/commandline.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ end
4141
---@field name string?
4242
---@field target string?
4343
---@field action string?
44+
---@field clear boolean?
4445
---@field decorator string?
4546
---@field trim boolean?
4647
---@field new_line boolean?
@@ -95,6 +96,7 @@ function M.parse(args)
9596
new_line = true,
9697
auto_scroll = true,
9798
bang_target = true,
99+
clear = true,
98100
watch_files = true,
99101
persist_mode = true,
100102
persist_size = true,
@@ -283,6 +285,8 @@ M._all_options = {
283285

284286
bang_target = M._boolean_options,
285287

288+
clear = M._boolean_options,
289+
286290
watch_files = M._boolean_options,
287291

288292
persist_mode = M._boolean_options,
@@ -432,6 +436,7 @@ M._term_send_options = {
432436
decorator = M._all_options.decorator,
433437
trim = M._all_options.trim,
434438
new_line = M._all_options.new_line,
439+
clear = M._all_options.clear
435440
}
436441

437442
M._term_select_options = {

lua/ergoterm/commands.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ function M.send(args, range, bang, picker)
121121
vim.validate("decorator", parsed.decorator, "string", true)
122122
vim.validate("trim", parsed.trim, "boolean", true)
123123
vim.validate("new_line", parsed.new_line, "boolean", true)
124+
vim.validate("clear", parsed.clear, "boolean", true)
124125
local selection = range == 0 and "single_line" or
125126
(vim.fn.visualmode() == "V" and "visual_lines" or "visual_selection")
126127
local input = parsed.text and { parsed.text } or selection
@@ -130,7 +131,8 @@ function M.send(args, range, bang, picker)
130131
action = parsed.action,
131132
trim = parsed.trim,
132133
new_line = parsed.new_line,
133-
decorator = parsed.decorator
134+
decorator = parsed.decorator,
135+
clear = parsed.clear
134136
})
135137
end
136138
return M._execute_on_terminal(

lua/ergoterm/instance/send.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ local M = {}
1919
---@field action? send_action terminal interaction mode (default: "focus")
2020
---@field trim? boolean remove leading/trailing whitespace (default: true)
2121
---@field new_line? boolean append newline for command execution (default: true)
22+
---@field clear? boolean clear terminal before sending (default: false)
2223
---@field decorator? string | fun(text: string[]): string[] transform text before sending
2324

2425
---@param term Terminal
@@ -30,13 +31,15 @@ function M.send(term, input, opts)
3031
local action = opts.action or "focus"
3132
local trim = opts.trim == nil or opts.trim
3233
local new_line = opts.new_line == nil or opts.new_line
34+
local clear = opts.clear or false
3335
local decorator = M._parse_decorator(opts.decorator)
3436
if not M._validate_selection_type(input) then return term end
3537
local computed_input = M._parse_input(input, term)
3638
term._state.last_sent = vim.deepcopy(computed_input)
3739
computed_input = M._maybe_add_new_line(computed_input, new_line)
3840
computed_input = M._maybe_trim_input(computed_input, trim)
3941
computed_input = decorator(computed_input)
42+
M._maybe_clear(term, clear)
4043
M._perform_action(term, action)
4144
vim.fn.chansend(term._state.job_id, computed_input)
4245
term:_scroll_bottom()
@@ -50,6 +53,15 @@ function M.clear(term, action)
5053
return M.send(term, { clear }, { action = action })
5154
end
5255

56+
---@param term Terminal
57+
---@param clear boolean
58+
---@private
59+
function M._maybe_clear(term, clear)
60+
if clear then
61+
M.clear(term, "start")
62+
end
63+
end
64+
5365
function M._validate_selection_type(input)
5466
local valid_selection_types = { "single_line", "visual_lines", "visual_selection", "last" }
5567
if type(input) == "string" and not vim.tbl_contains(valid_selection_types, input) then

spec/ergoterm/commandline_spec.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ describe("commandline.term_send_complete", function()
103103
assert.is_true(vim.tbl_contains(result, "decorator="))
104104
assert.is_true(vim.tbl_contains(result, "trim="))
105105
assert.is_true(vim.tbl_contains(result, "new_line="))
106+
assert.is_true(vim.tbl_contains(result, "clear="))
106107
end)
107108

108109
it("completes boolean values for trim", function()
@@ -112,6 +113,20 @@ describe("commandline.term_send_complete", function()
112113
assert.is_true(vim.tbl_contains(result, "trim=false"))
113114
end)
114115

116+
it("completes boolean values for new_line", function()
117+
local result = commandline.term_send_complete("new_line=", "new_line=", 9)
118+
119+
assert.is_true(vim.tbl_contains(result, "new_line=true"))
120+
assert.is_true(vim.tbl_contains(result, "new_line=false"))
121+
end)
122+
123+
it("completes boolean values for clear", function()
124+
local result = commandline.term_send_complete("clear=", "clear=", 6)
125+
126+
assert.is_true(vim.tbl_contains(result, "clear=true"))
127+
assert.is_true(vim.tbl_contains(result, "clear=false"))
128+
end)
129+
115130
it("completes action values", function()
116131
local result = commandline.term_send_complete("action=", "action=", 7)
117132

spec/ergoterm/commands_spec.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,18 @@ describe("M.send", function()
265265
})
266266
end)
267267

268+
it("clear screehn if specified", function()
269+
local term = terms.Terminal:new():start()
270+
local spy_chansend = spy.on(vim.fn, "chansend")
271+
272+
commands.send("clear=true text='after clear'", 0, false, select_only_picker)
273+
274+
assert.spy(spy_chansend).was_called_with(
275+
term:get_state("job_id"),
276+
{ "clear", "" }
277+
)
278+
end)
279+
268280
it("uses last focused terminal when called with the bang option", function()
269281
local term = terms.Terminal:new():start()
270282
term:focus()

spec/ergoterm/instance/send_spec.lua

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,29 @@ describe(":send", function()
169169
assert.is_true(vim.tbl_contains(lines, "foo"))
170170
end)
171171

172+
it("clears before sending if clear is true", function()
173+
local original_is_windows = utils.is_windows
174+
---@diagnostic disable-next-line: duplicate-set-field
175+
utils.is_windows = function() return false end
176+
177+
local term = Terminal:new():start()
178+
local spy_chansend = spy.on(vim.fn, "chansend")
179+
180+
send.send(term, { "line" }, { clear = true })
181+
vim.wait(100)
182+
183+
assert.spy(spy_chansend).was_called_with(
184+
term:get_state("job_id"),
185+
{ "clear", "" }
186+
)
187+
assert.spy(spy_chansend).was_called_with(
188+
term:get_state("job_id"),
189+
{ "line", "" }
190+
)
191+
192+
utils.is_windows = original_is_windows
193+
end)
194+
172195
it("only starts the terminal if action is start", function()
173196
local term = Terminal:new()
174197

0 commit comments

Comments
 (0)