-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathopen.lua
More file actions
124 lines (110 loc) · 3.92 KB
/
open.lua
File metadata and controls
124 lines (110 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
---@diagnostic disable: invisible
---@module "ergoterm.utils"
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"
local M = {}
---@param term Terminal
---@param layout layout?
function M.open(term, layout)
if not term:is_started() then term:start() end
return M.show(term, layout)
end
---@param term Terminal
function M.is_open(term)
if not term._state.window then return false end
for _, tab in pairs(vim.api.nvim_list_tabpages()) do
for _, win in pairs(vim.api.nvim_tabpage_list_wins(tab)) do
if vim.api.nvim_win_get_buf(win) == term._state.bufnr then
return true
end
end
end
return false
end
---@param term Terminal
---@param layout layout?
function M.show(term, layout)
if not M.is_open(term) and term._state.bufnr and vim.api.nvim_buf_is_valid(term._state.bufnr) then
layout = layout or term._state.layout
local window = nil
if vim.tbl_contains(NEW_WINDOW_LAYOUTS, layout) then
window = M._open_in_new_window(term, layout)
elseif layout == TAB_LAYOUT then
window = M._open_in_tab(term)
elseif layout == CURRENT_WINDOW_LAYOUT then
window = M._open_in_current_window(term)
else
utils.notify(
string.format("Invalid layout option: %s", tostring(layout)),
"error"
)
return term
end
term._state.layout = layout
term._state.window = window
term._state.tabpage = vim.api.nvim_win_get_tabpage(window)
M._set_win_options(term)
term:on_open()
end
return term
end
---@private
---@param term Terminal
---@param layout layout
function M._open_in_new_window(term, layout)
local win_config = term:_compute_win_config(layout)
return vim.api.nvim_open_win(term._state.bufnr, false, win_config)
end
---@private
---@param term Terminal
function M._open_in_tab(term)
local current_window = vim.api.nvim_get_current_win()
vim.cmd("tabnew")
vim.bo.bufhidden = "wipe"
vim.cmd("noautocmd call nvim_set_current_buf(" .. term._state.bufnr .. ")")
local window = vim.api.nvim_get_current_win()
vim.api.nvim_set_current_win(current_window)
vim.defer_fn(function() vim.cmd("stopinsert") end, 100)
return window
end
---@private
---@param term Terminal
function M._open_in_current_window(term)
vim.api.nvim_set_current_buf(term._state.bufnr)
return vim.api.nvim_get_current_win()
end
---@private
---@param term Terminal
function M._set_win_options(term)
local window = term._state.window
vim.api.nvim_set_option_value("number", false, { scope = "local", win = window })
vim.api.nvim_set_option_value("signcolumn", "no", { scope = "local", win = window })
vim.api.nvim_set_option_value("relativenumber", false, { scope = "local", win = window })
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
end
---@private
function M._set_float_options(term)
local window = term._state.window
vim.api.nvim_set_option_value("sidescrolloff", 0, { scope = "local", win = window })
vim.api.nvim_set_option_value("winblend", term.float_winblend, { scope = "local", win = window })
end
return setmetatable(M, {
__call = function(_, ...)
return M.open(...)
end
})