How to new a terminal and send to run command with lua?


  vim.cmd('vsplit')

  -- Open a terminal in the new buffer
  vim.cmd('terminal')

  -- Run the echo hello command
  vim.fn.feedkeys('echo hello\\<CR>')

terminal is open but echo hello not execute,how to make it right

After a little bit of digging I found a solution that fully works in lua:

vim.keymap.set('n', '<F10>', function()
  vim.cmd('below split')
  vim.cmd('terminal')
  vim.fn.feedkeys('a')
  local enter = vim.api.nvim_replace_termcodes("<CR>", true, true, true)
  vim.fn.feedkeys('clear' .. enter)
  vim.fn.feedkeys('echo hello world' .. enter)
end)

what this does is create a keymap (which further is just to run the function) that first splits the window, then it creates the terminal. This is still exactly how you did it. The mistake you made was that when a terminal is opened like this, you’re in normal mode, so before you can insert any keys, you need to get into terminal mode (which to my knowledge is just insert mode, but in a terminal).
To do that, the first vim.fn.feedkey feeds an a (insert after) I think an A, I or i would also work but this is what I chose.
Next, I define enter, what the help file for nvim_replace_termcodes said was that it creates the internal representation of in this case enter.
Then for mainly aesthetic reasons I clear the terminal. If you don’t do this the command will still run but for some reason I don’t understand it pastes the text twice and I don’t like that. An important bit to notice is that to press an enter after the clear command, thus running it, I need to append an enter to the string using .. enter.
After that I simply run the command, again appending .. enter.

Here’s another solution:

vim.cmd.vsplit()
vim.cmd.terminal()
-- send the command to the terminal buffer
vim.api.nvim_chan_send(vim.bo.channel, "echo hello\r")
-- enter insert mode
vim.api.nvim_feedkeys("a", "t", false)
1 Like

This is my implementation:

terminal_send_cmd = function(cmd_text)
	local function get_first_terminal()
		local terminal_chans = {}
		for _, chan in pairs(api.nvim_list_chans()) do
			if chan["mode"] == "terminal" and chan["pty"] ~= "" then
				table.insert(terminal_chans, chan)
			end
		end
		table.sort(terminal_chans, function(left, right)
			return left["buffer"] < right["buffer"]
		end)
		if #terminal_chans == 0 then
			return nil
		end
		return terminal_chans[1]["id"]
	end

	local send_to_terminal = function(terminal_chan, term_cmd_text)
		api.nvim_chan_send(terminal_chan, term_cmd_text .. "\n")
	end

	local terminal = get_first_terminal()
	if not terminal then
		return nil
	end

	if not cmd_text then
		ui.input({ prompt = "Send to terminal: " }, function(input_cmd_text)
			if not input_cmd_text then
				return nil
			end
			send_to_terminal(terminal, input_cmd_text)
		end)
	else
		send_to_terminal(terminal, cmd_text)
	end
	return true
end