summaryrefslogtreecommitdiff
path: root/neovim/lua/vimrc/term.lua
blob: 409ff724f56da036d613682ba7c4795b55365b26 (plain)
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
local api = vim.api
local cmd = vim.cmd

local M = {}
local jobid = nil
local winid = nil


local function bo(option, value)
    api.nvim_buf_set_option(0, option, value)
end

local function launch_term(cmd, opts)
  opts = opts or {}
  vim.cmd("belowright new")
  winid = vim.fn.win_getid()
  api.nvim_win_set_var(0, 'REPL', 1)
  bo('buftype', 'nofile')
  bo('bufhidden', 'wipe')
  bo('buflisted', false)
  bo('swapfile', false)
  opts = vim.tbl_extend('error', opts, {
    on_exit = function()
      jobid = nil
    end
  })
  jobid = vim.fn.termopen(cmd, opts)
end

local function close_term()
    if not jobid then return end
    vim.fn.jobstop(jobid)
    if api.nvim_win_is_valid(winid) then
        api.nvim_win_close(winid, true)
    end
    winid = nil
end

function M.toggle()
    if jobid then
        close_term()
    else
        launch_term(vim.fn.environ()['SHELL'] or 'sh')
    end
end


function M.run()
    local filepath = api.nvim_buf_get_name(0)
    close_term()
    launch_term(filepath)
end


function M.sendLine(line)
    if not jobid then return end
    vim.fn.chansend(jobid, line .. '\n')
end

function M.sendSelection()
    if not jobid then return end
    local start_row, start_col = unpack(api.nvim_buf_get_mark(0, '<'))
    local end_row, end_col = unpack(api.nvim_buf_get_mark(0, '>'))
    local mode = vim.fn.visualmode()
    local offset
    if mode == '' then -- in block mode all following lines are indented
      offset = start_col
    elseif mode == 'V' then
      end_row = end_row + 1
      offset = 0
    else
      offset = 0
    end
    local lines = api.nvim_buf_get_lines(0, start_row - 1, end_row, false)
    for idx, line in pairs(lines) do
      local l
      if idx == 1 and idx == #lines then
        l = line:sub(start_col + 1, end_col + 1)
      elseif idx == 1 then
        l = line:sub(start_col + 1)
      elseif idx == #lines then
        l = line:sub(offset + 1, end_col > #line and #line or end_col + 1)
      elseif offset > 0 then
        l = line:sub(offset + 1)
      else
        l = line
      end
      vim.fn.chansend(jobid, l .. '\n')
    end
end
return M