mirror of
https://github.com/ThePrimeagen/harpoon.git
synced 2025-07-14 01:50:27 +00:00
feat(tmux): added option to use tmux terminals instead of nvim terminals
This commit introduces a new module of harpoon, "harpoon.tmux", which provides several functions for using tmux windows for harpoon terminals. So far, all the basic features are supported, such as creating and moving to a new terminal, deleting all terminals, and sending commands to terminals etc.
This commit is contained in:
parent
dff4fb13e4
commit
45a888ee8a
@ -17,12 +17,12 @@ local M = {}
|
|||||||
term = {
|
term = {
|
||||||
cmds = {
|
cmds = {
|
||||||
}
|
}
|
||||||
... is there antyhnig that could be options?
|
... is there anything that could be options?
|
||||||
},
|
},
|
||||||
mark = {
|
mark = {
|
||||||
marks = {
|
marks = {
|
||||||
}
|
}
|
||||||
... is there antyhnig that could be options?
|
... is there anything that could be options?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,7 @@ local function create_terminal(create_with)
|
|||||||
if not create_with then
|
if not create_with then
|
||||||
create_with = ":terminal"
|
create_with = ":terminal"
|
||||||
end
|
end
|
||||||
log.trace("_create_terminal(): Init:", create_with)
|
log.trace("term: _create_terminal(): Init:", create_with)
|
||||||
local current_id = vim.api.nvim_get_current_buf()
|
local current_id = vim.api.nvim_get_current_buf()
|
||||||
|
|
||||||
vim.cmd(create_with)
|
vim.cmd(create_with)
|
||||||
@ -32,7 +32,7 @@ local function create_terminal(create_with)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function find_terminal(args)
|
local function find_terminal(args)
|
||||||
log.trace("_find_terminal(): Terminal:", args)
|
log.trace("term: _find_terminal(): Terminal:", args)
|
||||||
if type(args) == "number" then
|
if type(args) == "number" then
|
||||||
args = { idx = args }
|
args = { idx = args }
|
||||||
end
|
end
|
||||||
@ -63,14 +63,14 @@ local function get_first_empty_slot()
|
|||||||
end
|
end
|
||||||
|
|
||||||
M.gotoTerminal = function(idx)
|
M.gotoTerminal = function(idx)
|
||||||
log.trace("gotoTerminal(): Terminal:", idx)
|
log.trace("term: gotoTerminal(): Terminal:", idx)
|
||||||
local term_handle = find_terminal(idx)
|
local term_handle = find_terminal(idx)
|
||||||
|
|
||||||
vim.api.nvim_set_current_buf(term_handle.buf_id)
|
vim.api.nvim_set_current_buf(term_handle.buf_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
M.sendCommand = function(idx, cmd, ...)
|
M.sendCommand = function(idx, cmd, ...)
|
||||||
log.trace("sendCommand(): Terminal:", idx)
|
log.trace("term: sendCommand(): Terminal:", idx)
|
||||||
local term_handle = find_terminal(idx)
|
local term_handle = find_terminal(idx)
|
||||||
|
|
||||||
if type(cmd) == "number" then
|
if type(cmd) == "number" then
|
||||||
@ -88,7 +88,7 @@ M.sendCommand = function(idx, cmd, ...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
M.clear_all = function()
|
M.clear_all = function()
|
||||||
log.trace("clear_all(): Clearing all terminals.")
|
log.trace("term: clear_all(): Clearing all terminals.")
|
||||||
for _, term in ipairs(terminals) do
|
for _, term in ipairs(terminals) do
|
||||||
vim.api.nvim_buf_delete(term.buf_id, { force = true })
|
vim.api.nvim_buf_delete(term.buf_id, { force = true })
|
||||||
end
|
end
|
||||||
|
142
lua/harpoon/tmux.lua
Executable file
142
lua/harpoon/tmux.lua
Executable file
@ -0,0 +1,142 @@
|
|||||||
|
local harpoon = require("harpoon")
|
||||||
|
local log = require("harpoon.dev").log
|
||||||
|
local global_config = harpoon.get_global_settings()
|
||||||
|
local utils = require("harpoon.utils")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
local tmux_windows = {}
|
||||||
|
|
||||||
|
local function create_terminal()
|
||||||
|
log.trace("tmux: _create_terminal())")
|
||||||
|
|
||||||
|
local window_id
|
||||||
|
|
||||||
|
-- Create a new tmux window and store the window id
|
||||||
|
local out, ret, _ = utils.get_os_command_output({
|
||||||
|
"tmux",
|
||||||
|
"new-window",
|
||||||
|
"-P",
|
||||||
|
"-F",
|
||||||
|
"#{pane_id}",
|
||||||
|
}, vim.loop.cwd())
|
||||||
|
|
||||||
|
if ret == 0 then
|
||||||
|
window_id = out[1]:sub(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if window_id == nil then
|
||||||
|
log.error("tmux: _create_terminal(): window_id is nil")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return window_id
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if the tmux window with the given window id exists
|
||||||
|
local function terminal_exists(window_id)
|
||||||
|
log.trace("_terminal_exists(): Window:", window_id)
|
||||||
|
|
||||||
|
local exists = false
|
||||||
|
|
||||||
|
local window_list, _, _ = utils.get_os_command_output({
|
||||||
|
"tmux",
|
||||||
|
"list-windows",
|
||||||
|
}, vim.loop.cwd())
|
||||||
|
|
||||||
|
for _, line in pairs(window_list) do
|
||||||
|
local window_info = utils.split_string(line, "@")[1]
|
||||||
|
|
||||||
|
if string.find(window_info, window_id) then
|
||||||
|
exists = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return exists
|
||||||
|
end
|
||||||
|
|
||||||
|
local function find_terminal(args)
|
||||||
|
log.trace("tmux: _find_terminal(): Window:", args)
|
||||||
|
|
||||||
|
if type(args) == "number" then
|
||||||
|
args = { idx = args }
|
||||||
|
end
|
||||||
|
|
||||||
|
local window_handle = tmux_windows[args.idx]
|
||||||
|
local window_exists
|
||||||
|
|
||||||
|
if window_handle then
|
||||||
|
window_exists = terminal_exists(window_handle.window_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not window_handle or not window_exists then
|
||||||
|
local window_id = create_terminal()
|
||||||
|
|
||||||
|
if window_id == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
window_handle = {
|
||||||
|
window_id = window_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmux_windows[args.idx] = window_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
return window_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
M.gotoTerminal = function(idx)
|
||||||
|
log.trace("tmux: gotoTerminal(): Window:", idx)
|
||||||
|
local window_handle = find_terminal(idx)
|
||||||
|
|
||||||
|
local _, _, _ = utils.get_os_command_output({
|
||||||
|
"tmux",
|
||||||
|
"select-window",
|
||||||
|
"-t",
|
||||||
|
"%" .. window_handle.window_id,
|
||||||
|
}, vim.loop.cwd())
|
||||||
|
end
|
||||||
|
|
||||||
|
M.sendCommand = function(idx, cmd, ...)
|
||||||
|
log.trace("tmux: sendCommand(): Window:", idx)
|
||||||
|
local window_handle = find_terminal(idx)
|
||||||
|
|
||||||
|
if type(cmd) == "number" then
|
||||||
|
cmd = harpoon.get_term_config().cmds[cmd]
|
||||||
|
end
|
||||||
|
|
||||||
|
if global_config.enter_on_sendcmd then
|
||||||
|
cmd = cmd .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
if cmd then
|
||||||
|
log.debug("sendCommand:", cmd)
|
||||||
|
|
||||||
|
-- Send the command to the given tmux window (creates it if it doesn't exist)
|
||||||
|
local _, _, _ = utils.get_os_command_output({
|
||||||
|
"tmux",
|
||||||
|
"send-keys",
|
||||||
|
"-t",
|
||||||
|
"%" .. window_handle.window_id,
|
||||||
|
string.format(cmd, ...),
|
||||||
|
}, vim.loop.cwd())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.clear_all = function()
|
||||||
|
log.trace("tmux: clear_all(): Clearing all tmux windows.")
|
||||||
|
|
||||||
|
for _, window in ipairs(tmux_windows) do
|
||||||
|
-- Delete the current tmux window
|
||||||
|
local _, _, _ = utils.get_os_command_output({
|
||||||
|
"tmux",
|
||||||
|
"kill-window",
|
||||||
|
"-t",
|
||||||
|
"%" .. window.window_id,
|
||||||
|
}, vim.loop.cwd())
|
||||||
|
end
|
||||||
|
|
||||||
|
tmux_windows = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
@ -1,11 +1,40 @@
|
|||||||
local Path = require("plenary.path")
|
local Path = require("plenary.path")
|
||||||
local data_path = vim.fn.stdpath("data")
|
local data_path = vim.fn.stdpath("data")
|
||||||
|
local Job = require("plenary.job")
|
||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
data_path = data_path,
|
data_path = data_path,
|
||||||
normalize_path = function(item)
|
normalize_path = function(item)
|
||||||
return Path:new(item):make_relative(vim.loop.cwd())
|
return Path:new(item):make_relative(vim.loop.cwd())
|
||||||
end,
|
end,
|
||||||
|
get_os_command_output = function(cmd, cwd)
|
||||||
|
if type(cmd) ~= "table" then
|
||||||
|
print("Harpoon: [get_os_command_output]: cmd has to be a table")
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local command = table.remove(cmd, 1)
|
||||||
|
local stderr = {}
|
||||||
|
local stdout, ret = Job
|
||||||
|
:new({
|
||||||
|
command = command,
|
||||||
|
args = cmd,
|
||||||
|
cwd = cwd,
|
||||||
|
on_stderr = function(_, data)
|
||||||
|
table.insert(stderr, data)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
:sync()
|
||||||
|
return stdout, ret, stderr
|
||||||
|
end,
|
||||||
|
split_string = function(str, delimiter)
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
for match in (str .. delimiter):gmatch("(.-)" .. delimiter) do
|
||||||
|
table.insert(result, match)
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
Loading…
x
Reference in New Issue
Block a user