summary refs log tree commit diff
path: root/.vim/lua/job.lua
blob: c14e978ddefd38ea22dbb5843469f180c2d81402 (plain) (blame)
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
125
126
127
128
129
local Job = require ('plenary.job')
local List = require('plenary.collections.py_list')
local spinner = require('spinner.core')

local M = {
  current_jobs = {}
}

--create a new job and register
--@return ~/.local/share/nvim/site/pack/packer/start/plenary.nvim/lua/plenary/job.lua
function M.jobstart(opts)
  opts = opts or {}

  local title
  if opts.format_title then
    title = opts.format_title(opts.command, opts.args)
    opts.format_title = nil
  else
    title = opts.command
  end

  if opts.populate_quickfix == nil then
    opts.populate_quickfix = true
  end

  opts.enable_recording = true -- enable job:result()

  opts.on_exit = vim.schedule_wrap(function(j, code)
    spinner.on_progress('end', j.pid, j.pid)
    spinner.on_exit(nil, nil, j.pid)

    local lines
    if code == 0 then
      lines = j:result()
    else
      lines = j:stderr_result()
    end

    -- strip ansi terminal color codes
    for i = 1, #lines do
      lines[i] = (lines[i]):gsub(string.char(27) .. '[[0-9;]*m', '')
    end

    -- only show quickfix if there is output
    if opts.populate_quickfix and #lines > 0 then
      vim.bo.errorformat = '%m'
      vim.fn.setqflist({}, 'r', {
        title = title,
        items = lines,
      })
      vim.api.nvim_command('doautocmd QuickFixCmdPost')
    end

    for k, v in ipairs(M.current_jobs) do
      if v.pid == j.pid then
        table.remove(M.current_jobs, k)
        break
      end
    end
  end)

  local j = Job:new(opts)
  j:start()
  table.insert(M.current_jobs, j)

  spinner.on_attach(j.pid, title, vim.fn.bufnr())
  spinner.on_progress('begin', j.pid, j.pid)

  return j
end

function M.make(extra_args)
  local makeprg = vim.fn.expandcmd(vim.opt.makeprg:get())
  local args = vim.split(makeprg, ' ')
  local command = args[1]
  table.remove(args, 1)

  local extra_args = extra_args or {}
  table.foreach(extra_args, function(_, v) table.insert(args, v) end)

  return M.jobstart {
    command = command,
    args = args,
  }
end

function M.sh(command_string)
  return M.jobstart {
    command = vim.env.SHELL,
    args = {'-c', command_string},

    format_title = function(_, args)
      return List(args):slice(2,#args):join(' ')
    end
  }
end


function M.gen_entry_from_job()
  return function(entry)
    return {
      value = entry,
      ordinal = entry.pid,
      display = entry.command .. ' ' .. table.concat(entry.args, ' '),
    }
  end
end

function M.cancel_job()
  if #M.current_jobs < 1 then return end
  require('telescope.pickers').new({}, {
    prompt_title = 'Jobs',
    finder = require('telescope.finders').new_table {
      results = M.current_jobs,
      entry_maker = M.gen_entry_from_job(),
    },
    sorter = require('telescope.sorters').fuzzy_with_index_bias(),
    attach_mappings = function(bufnr)
      require('telescope.actions.set').select:replace(function(bufnr, type)
        local entry = require('telescope.actions.state').get_selected_entry()
        require('telescope.actions').close(bufnr)
        entry.value:shutdown(1, 'SIGKILL')
      end)
      return true
    end
  }):find()
end

return M