🫙 tiny scratch terminal for Neovim
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 145 lines 3.2 kB view raw
1---@return vim.api.keyset.win_config 2local function get_winopts() 3 local horiz = vim.opt.fillchars:get().horiz or "" 4 5 local height = math.ceil(vim.o.lines * 0.3) 6 local offset = vim.o.cmdheight + 1 7 8 return { 9 relative = "editor", 10 col = 0, 11 row = vim.o.lines - height - offset - 1, 12 height = height, 13 width = vim.o.columns, 14 style = "minimal", 15 border = { horiz, horiz, horiz, "", "", "", "", "" }, 16 } 17end 18 19---@class jamjar.Terminal.proto 20---@field cmd? string 21---@field cwd? string 22---@field winoptsfn? fun(): vim.api.keyset.win_config 23---@field on_open? fun(self: jamjar.Terminal) 24 25---@class jamjar.Terminal : jamjar.Terminal.proto 26---@field cmd string 27---@field buf integer 28---@field win? integer 29local Terminal = {} 30Terminal.__index = Terminal 31 32local function get_defaultopts() 33 return { 34 cmd = vim.o.shell, 35 on_open = function(self) 36 vim.api.nvim_set_option_value( 37 "winhighlight", 38 "Normal:Normal,NormalNC:NormalNC,FloatBorder:WinSeparator", 39 { win = self.win } 40 ) 41 end, 42 } 43end 44 45---@param opts? jamjar.Terminal.proto 46function Terminal:new(opts) 47 return setmetatable(vim.tbl_extend("force", get_defaultopts(), opts or {}), self) 48end 49 50function Terminal:isbufvalid() 51 return self.buf and vim.api.nvim_buf_is_valid(self.buf) 52end 53 54function Terminal:ensurebuf() 55 if not self:isbufvalid() then 56 self:init() 57 end 58end 59 60function Terminal:init() 61 self.buf = vim.api.nvim_create_buf(true, true) 62 vim.api.nvim_set_option_value("buftype", "nofile", { buf = self.buf }) 63 64 vim._with({ buf = self.buf }, function() 65 vim.fn.jobstart(self.cmd, { 66 term = true, 67 cwd = self.cwd, 68 on_exit = function() 69 self:delete() 70 end, 71 }) 72 end) 73end 74 75function Terminal:iswinvalid() 76 return self.win and vim.api.nvim_win_is_valid(self.win) 77end 78 79function Terminal:toggle() 80 self:ensurebuf() 81 82 if not self:iswinvalid() then 83 self:open() 84 return 85 end 86 87 local wcfg = vim.api.nvim_win_get_config(self.win) 88 local hidden = wcfg.hide 89 90 if hidden then 91 self:open() 92 else 93 self:close() 94 end 95end 96 97function Terminal:open() 98 if not self:iswinvalid() then 99 self:ensurebuf() 100 self.win = vim.api.nvim_open_win(self.buf, true, vim.F.if_nil(self.winoptsfn, get_winopts)()) 101 vim.api.nvim_set_option_value("signcolumn", "no", { win = self.win }) 102 vim.api.nvim_set_option_value("foldcolumn", "0", { win = self.win }) 103 self.on_open(self) 104 else 105 vim.api.nvim_win_set_config(self.win, { 106 hide = false, 107 }) 108 vim.api.nvim_set_current_win(self.win) 109 end 110end 111 112function Terminal:close() 113 if not self:iswinvalid() then 114 return 115 end 116 117 vim.api.nvim_win_set_config(self.win, { 118 hide = true, 119 }) 120 121 if vim.api.nvim_get_current_win() == self.win then 122 vim.cmd.wincmd("p") 123 end 124end 125 126function Terminal:quit() 127 if not self:iswinvalid() then 128 return 129 end 130 131 vim.api.nvim_win_close(self.win, true) 132 self.win = nil 133end 134 135function Terminal:delete() 136 self:quit() 137 138 if self:isbufvalid() then 139 vim.bo[self.buf].buflisted = false 140 vim.api.nvim_buf_delete(self.buf, { unload = true }) 141 self.buf = nil 142 end 143end 144 145return Terminal