summaryrefslogtreecommitdiff
path: root/lua/lvim/core/builtins/terminal.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/lvim/core/builtins/terminal.lua')
-rw-r--r--lua/lvim/core/builtins/terminal.lua165
1 files changed, 165 insertions, 0 deletions
diff --git a/lua/lvim/core/builtins/terminal.lua b/lua/lvim/core/builtins/terminal.lua
new file mode 100644
index 00000000..2fc8ea9c
--- /dev/null
+++ b/lua/lvim/core/builtins/terminal.lua
@@ -0,0 +1,165 @@
+local M = {}
+local Log = require "lvim.core.log"
+
+M.config = function()
+ lvim.builtin["terminal"] = {
+ active = true,
+ -- size can be a number or function which is passed the current terminal
+ size = 20,
+ open_mapping = [[<c-\>]],
+ hide_numbers = true, -- hide the number column in toggleterm buffers
+ shade_filetypes = {},
+ shade_terminals = true,
+ shading_factor = 2, -- the degree by which to darken to terminal colour, default: 1 for dark backgrounds, 3 for light
+ start_in_insert = true,
+ insert_mappings = true, -- whether or not the open mapping applies in insert mode
+ persist_size = false,
+ -- direction = 'vertical' | 'horizontal' | 'window' | 'float',
+ direction = "float",
+ close_on_exit = true, -- close the terminal window when the process exits
+ shell = vim.o.shell, -- change the default shell
+ -- This field is only relevant if direction is set to 'float'
+ float_opts = {
+ -- The border key is *almost* the same as 'nvim_win_open'
+ -- see :h nvim_win_open for details on borders however
+ -- the 'curved' border is a custom border type
+ -- not natively supported but implemented in this plugin.
+ -- border = 'single' | 'double' | 'shadow' | 'curved' | ... other options supported by win open
+ border = "curved",
+ -- width = <value>,
+ -- height = <value>,
+ winblend = 0,
+ highlights = {
+ border = "Normal",
+ background = "Normal",
+ },
+ },
+ -- Add executables on the config.lua
+ -- { cmd, keymap, description, direction, size }
+ -- lvim.builtin.terminal.execs = {...} to overwrite
+ -- lvim.builtin.terminal.execs[#lvim.builtin.terminal.execs+1] = {"gdb", "tg", "GNU Debugger"}
+ -- TODO: pls add mappings in which key and refactor this
+ execs = {
+ { nil, "<M-1>", "Horizontal Terminal", "horizontal", 0.3 },
+ { nil, "<M-2>", "Vertical Terminal", "vertical", 0.4 },
+ { nil, "<M-3>", "Float Terminal", "float", nil },
+ },
+ }
+end
+
+--- Get current buffer size
+---@return {width: number, height: number}
+local function get_buf_size()
+ local cbuf = vim.api.nvim_get_current_buf()
+ local bufinfo = vim.tbl_filter(function(buf)
+ return buf.bufnr == cbuf
+ end, vim.fn.getwininfo(vim.api.nvim_get_current_win()))[1]
+ if bufinfo == nil then
+ return { width = -1, height = -1 }
+ end
+ return { width = bufinfo.width, height = bufinfo.height }
+end
+
+--- Get the dynamic terminal size in cells
+---@param direction number
+---@param size number
+---@return integer
+local function get_dynamic_terminal_size(direction, size)
+ size = size or lvim.builtin.terminal.size
+ if direction ~= "float" and tostring(size):find(".", 1, true) then
+ size = math.min(size, 1.0)
+ local buf_sizes = get_buf_size()
+ local buf_size = direction == "horizontal" and buf_sizes.height or buf_sizes.width
+ return buf_size * size
+ else
+ return size
+ end
+end
+
+M.setup = function()
+ local terminal = require "toggleterm"
+ terminal.setup(lvim.builtin.terminal)
+
+ for i, exec in pairs(lvim.builtin.terminal.execs) do
+ local direction = exec[4] or lvim.builtin.terminal.direction
+
+ local opts = {
+ cmd = exec[1] or lvim.builtin.terminal.shell,
+ keymap = exec[2],
+ label = exec[3],
+ -- NOTE: unable to consistently bind id/count <= 9, see #2146
+ count = i + 100,
+ direction = direction,
+ size = function()
+ return get_dynamic_terminal_size(direction, exec[5])
+ end,
+ }
+
+ M.add_exec(opts)
+ end
+
+ return terminal
+end
+
+M.add_exec = function(opts)
+ local binary = opts.cmd:match "(%S+)"
+ if vim.fn.executable(binary) ~= 1 then
+ Log:debug("Skipping configuring executable " .. binary .. ". Please make sure it is installed properly.")
+ return
+ end
+
+ vim.keymap.set({ "n", "t" }, opts.keymap, function()
+ M._exec_toggle { cmd = opts.cmd, count = opts.count, direction = opts.direction, size = opts.size() }
+ end, { desc = opts.label, noremap = true, silent = true })
+end
+
+M._exec_toggle = function(opts)
+ local Terminal = require("toggleterm.terminal").Terminal
+ local term = Terminal:new { cmd = opts.cmd, count = opts.count, direction = opts.direction }
+ term:toggle(opts.size, opts.direction)
+end
+
+---Toggles a log viewer according to log.viewer.layout_config
+---@param logfile string the fullpath to the logfile
+M.toggle_log_view = function(logfile)
+ local log_viewer = lvim.log.viewer.cmd
+ if vim.fn.executable(log_viewer) ~= 1 then
+ log_viewer = "less +F"
+ end
+ Log:debug("attempting to open: " .. logfile)
+ log_viewer = log_viewer .. " " .. logfile
+ local term_opts = vim.tbl_deep_extend("force", lvim.builtin.terminal, {
+ cmd = log_viewer,
+ open_mapping = lvim.log.viewer.layout_config.open_mapping,
+ direction = lvim.log.viewer.layout_config.direction,
+ -- TODO: this might not be working as expected
+ size = lvim.log.viewer.layout_config.size,
+ float_opts = lvim.log.viewer.layout_config.float_opts,
+ })
+
+ local Terminal = require("toggleterm.terminal").Terminal
+ local log_view = Terminal:new(term_opts)
+ log_view:toggle()
+end
+
+M.lazygit_toggle = function()
+ local Terminal = require("toggleterm.terminal").Terminal
+ local lazygit = Terminal:new {
+ cmd = "lazygit",
+ hidden = true,
+ direction = "float",
+ float_opts = {
+ border = "none",
+ width = 100000,
+ height = 100000,
+ },
+ on_open = function(_)
+ vim.cmd "startinsert!"
+ end,
+ on_close = function(_) end,
+ count = 99,
+ }
+ lazygit:toggle()
+end
+
+return M