-- Terminal helper -- from: https://github.com/jmbuhr/nvim-config -- -- ---@module 'utils.term' -- local M = { -- ---Map of buffers to a terminals -- ---@type table -- buf_term_map = {}, -- } -- -- ---A terminal has a buffer number, a type and a channel id -- ---@class Terminal -- ---@field bufnr integer -- ---@field type string? -- ---@field channel_id integer -- -- ---Get the channel id of a terminal buffer -- ---@param bufnr integer -- ---@return integer|nil -- local function get_channel_id(bufnr) -- return vim.api.nvim_get_option_value('channel', { buf = bufnr }) -- end -- -- ---Get the type of the terminal buffer -- ---like ipython, R, bash, etc. -- ---based on the buffer name -- ---@param buf integer -- ---@return string|nil -- local function get_term_type(buf) -- local name = vim.api.nvim_buf_get_name(buf) -- local term_type = name:match 'term://.*/%d+:(.*)' -- if not term_type then -- return nil -- end -- -- drop flags like --no-confirm-exit -- term_type = term_type:match '([^%s]+)' -- -- drop the path to the executable -- term_type = term_type:match '([^/]+)$' -- return term_type -- end -- -- ---Find nvim terminal buffers -- local function list_terminals() -- local terms = {} -- for _, buf in ipairs(vim.api.nvim_list_bufs()) do -- if vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_get_option_value('buftype', { buf = buf }) == 'terminal' then -- local chan_id = get_channel_id(buf) -- if not chan_id then -- goto continue -- end -- ---@type Terminal -- local term = { -- bufnr = buf, -- type = get_term_type(buf), -- channel_id = chan_id, -- } -- table.insert(terms, term) -- end -- ::continue:: -- end -- return terms -- end -- -- ---For ipython sending -- local cpaste_start = '%cpaste -q\n' -- local cpaste_end = '--\n' -- local cpaste_pause = 10 -- -- ---Send lines to a terminal -- ---@param lines string[] -- ---@param term Terminal -- ---@return nil -- local send_lines = function(lines, term) -- local chan_id = term.channel_id -- local text = table.concat(lines, '\n') .. '\n' -- if term.type == 'ipython' then -- vim.fn.chansend(chan_id, cpaste_start) -- vim.uv.sleep(cpaste_pause) -- end -- vim.fn.chansend(chan_id, text) -- if term.type == 'ipython' then -- vim.fn.chansend(chan_id, cpaste_end) -- end -- end -- -- local s = [[ -- print("hello world!") -- def hello(): -- print("hello") -- hello() -- ]] -- -- local ls = { s } -- -- ---Connect current buffer to a terminal -- local connect = function() -- local bufnr = vim.api.nvim_get_current_buf() -- local terms = list_terminals() -- vim.ui.select(terms, { -- prompt = 'Select terminal', -- format_item = function(item) -- return item.type .. ' ' .. item.bufnr -- end, -- }, function(choice) -- if choice == nil then -- return -- end -- M.buf_term_map[bufnr] = choice -- end) -- end -- -- M.send = function(lines) -- local bufnr = vim.api.nvim_get_current_buf() -- local term = M.buf_term_map[bufnr] -- if not term then -- connect() -- return -- end -- send_lines(lines, term) -- -- scroll to the bottom -- local term_win = vim.fn.bufwinid(term.bufnr) -- local n = vim.api.nvim_buf_line_count(term.bufnr) -- vim.api.nvim_win_set_cursor(term_win, { n, 0 }) -- end -- -- M.send_visual = function() -- -- get the selected text -- vim.cmd.normal { '"zy', bang = true } -- local selection = vim.fn.getreg 'z' -- M.send { selection } -- end -- -- vim.keymap.set('v', '', function() -- M.send_visual() -- end, { noremap = true, silent = true }) -- -- -- connect -- vim.keymap.set('n', 'ct', function() -- connect() -- end, { noremap = true, silent = true }) local M = {} local function new_terminal(lang) vim.cmd('vsplit term://' .. lang) end function M.new_terminal_python() new_terminal 'python' end function M.new_terminal_r() new_terminal 'R --no-save' end function M.new_terminal_ipython() new_terminal 'ipython --no-confirm-exit --no-autoindent' end function M.new_terminal_julia() new_terminal 'julia' end function M.new_terminal_shell() new_terminal '$SHELL' end return M -- The line beneath this is called `modeline`. See `:help modeline` -- vim: ts=2 sts=2 sw=2 et