all repos

curl.nvim @ 7fbfcc5

use curl within neovim
3 files changed, 506 insertions(+), 0 deletions(-)
impl
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-04-19 22:44:58 +0300
Authored at: 2026-04-19 13:36:38 +0300
Change ID: tultozytukwvtvtzyuzwxkxksspuukvk
A lua/curl.lua
···
        
        1
        +local H = {

      
        
        2
        +  cache_dir = vim.fs.joinpath(vim.fn.stdpath "data", "curl_cache"),

      
        
        3
        +  query_buf = nil,

      
        
        4
        +  query_file = nil,

      
        
        5
        +  query_buffers = {},

      
        
        6
        +  query_autocmd_set = false,

      
        
        7
        +  output_buf = nil,

      
        
        8
        +  command_created = false,

      
        
        9
        +  running_request = nil,

      
        
        10
        +}

      
        
        11
        +

      
        
        12
        +local curl = {}

      
        
        13
        +

      
        
        14
        +curl.config = {

      
        
        15
        +  curl = nil, -- path to binary

      
        
        16
        +  default_flags = { "-i" },

      
        
        17
        +  open_cmd = "vsplit",

      
        
        18
        +  map_execute = "<CR>", -- in query buffer

      
        
        19
        +}

      
        
        20
        +

      
        
        21
        +local function is_valid_buf(buf)

      
        
        22
        +  return type(buf) == "number" and buf > 0 and vim.api.nvim_buf_is_valid(buf)

      
        
        23
        +end

      
        
        24
        +

      
        
        25
        +local function is_valid_win(win)

      
        
        26
        +  return type(win) == "number" and win > 0 and vim.api.nvim_win_is_valid(win)

      
        
        27
        +end

      
        
        28
        +

      
        
        29
        +local function trim_lines(lines)

      
        
        30
        +  while #lines > 1 and lines[#lines] == "" do

      
        
        31
        +    table.remove(lines)

      
        
        32
        +  end

      
        
        33
        +  return lines

      
        
        34
        +end

      
        
        35
        +

      
        
        36
        +local function is_query_start(line)

      
        
        37
        +  if not line then return false end

      
        
        38
        +  return line:match "^%s*curl%s" or line:match "^%s*curl$" or line:match "^%s*https?://"

      
        
        39
        +end

      
        
        40
        +

      
        
        41
        +local function is_curl_file(path)

      
        
        42
        +  return type(path) == "string" and path ~= "" and path:sub(-5) == ".curl"

      
        
        43
        +end

      
        
        44
        +

      
        
        45
        +local function get_or_create_buffer(name)

      
        
        46
        +  local existing = vim.fn.bufnr("^" .. name .. "$")

      
        
        47
        +  if existing ~= -1 and is_valid_buf(existing) then return existing end

      
        
        48
        +

      
        
        49
        +  local buf = vim.api.nvim_create_buf(false, true)

      
        
        50
        +  vim.api.nvim_buf_set_name(buf, name)

      
        
        51
        +  vim.api.nvim_set_option_value("buftype", "nofile", { buf = buf })

      
        
        52
        +  vim.api.nvim_set_option_value("bufhidden", "hide", { buf = buf })

      
        
        53
        +  vim.api.nvim_set_option_value("swapfile", false, { buf = buf })

      
        
        54
        +  return buf

      
        
        55
        +end

      
        
        56
        +

      
        
        57
        +local function ensure_dir(path)

      
        
        58
        +  if vim.fn.isdirectory(path) == 1 then return true end

      
        
        59
        +  return vim.fn.mkdir(path, "p") == 1

      
        
        60
        +end

      
        
        61
        +

      
        
        62
        +local function get_workspace_id()

      
        
        63
        +  local cwd = vim.fn.getcwd()

      
        
        64
        +  local base = vim.fn.fnamemodify(cwd, ":t")

      
        
        65
        +  if base == "" then base = "root" end

      
        
        66
        +  return base .. "_" .. vim.fn.sha256(cwd):sub(1, 8)

      
        
        67
        +end

      
        
        68
        +

      
        
        69
        +local function get_cache_file()

      
        
        70
        +  if not ensure_dir(H.cache_dir) then

      
        
        71
        +    vim.notify("[curl.nvim] failed to create cache dir: " .. H.cache_dir, vim.log.levels.ERROR)

      
        
        72
        +    return nil

      
        
        73
        +  end

      
        
        74
        +

      
        
        75
        +  local cwd = vim.fn.getcwd()

      
        
        76
        +  local hash = vim.fn.sha256(cwd)

      
        
        77
        +  local new_file = vim.fs.joinpath(H.cache_dir, get_workspace_id() .. ".curl")

      
        
        78
        +  local old_file = vim.fs.joinpath(H.cache_dir, hash)

      
        
        79
        +

      
        
        80
        +  if vim.uv.fs_stat(old_file) then

      
        
        81
        +    if not vim.uv.fs_stat(new_file) then

      
        
        82
        +      vim.fn.rename(old_file, new_file)

      
        
        83
        +    else

      
        
        84
        +      vim.fn.rename(old_file, old_file .. ".archive")

      
        
        85
        +    end

      
        
        86
        +  end

      
        
        87
        +

      
        
        88
        +  return new_file

      
        
        89
        +end

      
        
        90
        +

      
        
        91
        +local function save_query_buffer(buf, file)

      
        
        92
        +  if not is_valid_buf(buf) then return end

      
        
        93
        +  file = file or vim.api.nvim_buf_get_name(buf)

      
        
        94
        +  if not is_curl_file(file) then return end

      
        
        95
        +  local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)

      
        
        96
        +  local ok = pcall(vim.fn.writefile, lines, file, "b")

      
        
        97
        +  if ok then

      
        
        98
        +    pcall(vim.api.nvim_set_option_value, "modified", false, { buf = buf })

      
        
        99
        +  else

      
        
        100
        +    vim.notify("[curl.nvim] failed to save request file: " .. file, vim.log.levels.ERROR)

      
        
        101
        +  end

      
        
        102
        +end

      
        
        103
        +

      
        
        104
        +function H.set_query_mapping(buf)

      
        
        105
        +  if not is_valid_buf(buf) then return end

      
        
        106
        +  vim.keymap.set("n", curl.config.map_execute, curl.execute, {

      
        
        107
        +    buffer = buf,

      
        
        108
        +    noremap = true,

      
        
        109
        +    silent = true,

      
        
        110
        +    desc = "Execute curl query under cursor",

      
        
        111
        +  })

      
        
        112
        +end

      
        
        113
        +

      
        
        114
        +function H.attach_curl_buffer(buf)

      
        
        115
        +  if not is_valid_buf(buf) then return false end

      
        
        116
        +  local name = vim.api.nvim_buf_get_name(buf)

      
        
        117
        +  if not is_curl_file(name) then return false end

      
        
        118
        +  vim.api.nvim_set_option_value("filetype", "curl", { buf = buf })

      
        
        119
        +  vim.api.nvim_set_option_value("syntax", "sh", { buf = buf })

      
        
        120
        +  vim.api.nvim_set_option_value("commentstring", "# %s", { buf = buf })

      
        
        121
        +  pcall(vim.treesitter.language.register, "bash", "curl")

      
        
        122
        +  H.set_query_mapping(buf)

      
        
        123
        +  H.query_buffers[name] = buf

      
        
        124
        +  return true

      
        
        125
        +end

      
        
        126
        +

      
        
        127
        +local function create_query_buffer(file)

      
        
        128
        +  local buf = vim.fn.bufadd(file)

      
        
        129
        +  vim.fn.bufload(buf)

      
        
        130
        +  vim.api.nvim_set_option_value("bufhidden", "hide", { buf = buf })

      
        
        131
        +  vim.api.nvim_set_option_value("swapfile", false, { buf = buf })

      
        
        132
        +  vim.api.nvim_set_option_value("modifiable", true, { buf = buf })

      
        
        133
        +  H.attach_curl_buffer(buf)

      
        
        134
        +

      
        
        135
        +  local group = vim.api.nvim_create_augroup("curl_nvim_cache_" .. buf, { clear = true })

      
        
        136
        +  vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI", "BufLeave", "VimLeavePre" }, {

      
        
        137
        +    group = group,

      
        
        138
        +    buffer = buf,

      
        
        139
        +    callback = function()

      
        
        140
        +      save_query_buffer(buf, file)

      
        
        141
        +    end,

      
        
        142
        +  })

      
        
        143
        +

      
        
        144
        +  return buf

      
        
        145
        +end

      
        
        146
        +

      
        
        147
        +local function find_window_in_current_tab(bufnr)

      
        
        148
        +  for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do

      
        
        149
        +    if vim.api.nvim_win_get_buf(win) == bufnr then return win end

      
        
        150
        +  end

      
        
        151
        +  return nil

      
        
        152
        +end

      
        
        153
        +

      
        
        154
        +function H.setup_filetype()

      
        
        155
        +  vim.filetype.add {

      
        
        156
        +    extension = { curl = "curl" },

      
        
        157
        +  }

      
        
        158
        +end

      
        
        159
        +

      
        
        160
        +function H.setup_command()

      
        
        161
        +  if H.command_created then return end

      
        
        162
        +  vim.api.nvim_create_user_command("Curl", function()

      
        
        163
        +    curl.open()

      
        
        164
        +  end, { desc = "Open curl.nvim query buffer" })

      
        
        165
        +  H.command_created = true

      
        
        166
        +end

      
        
        167
        +

      
        
        168
        +function H.get_query_buffer()

      
        
        169
        +  local file = get_cache_file()

      
        
        170
        +  if not file then return nil end

      
        
        171
        +

      
        
        172
        +  H.query_file = file

      
        
        173
        +  local existing = H.query_buffers[file]

      
        
        174
        +  if not is_valid_buf(existing) then

      
        
        175
        +    existing = create_query_buffer(file)

      
        
        176
        +    H.query_buffers[file] = existing

      
        
        177
        +  end

      
        
        178
        +  H.query_buf = existing

      
        
        179
        +

      
        
        180
        +  H.set_query_mapping(H.query_buf)

      
        
        181
        +

      
        
        182
        +  return H.query_buf

      
        
        183
        +end

      
        
        184
        +

      
        
        185
        +function H.setup_query_file_autocmd()

      
        
        186
        +  if H.query_autocmd_set then return end

      
        
        187
        +  local group = vim.api.nvim_create_augroup("curl_nvim_query_files", { clear = true })

      
        
        188
        +  vim.api.nvim_create_autocmd(

      
        
        189
        +    { "BufReadPost", "BufNewFile", "BufEnter", "BufWinEnter", "BufFilePost" },

      
        
        190
        +    {

      
        
        191
        +      group = group,

      
        
        192
        +      pattern = "*.curl",

      
        
        193
        +      callback = function(args)

      
        
        194
        +        H.attach_curl_buffer(args.buf)

      
        
        195
        +      end,

      
        
        196
        +    }

      
        
        197
        +  )

      
        
        198
        +  for _, buf in ipairs(vim.api.nvim_list_bufs()) do

      
        
        199
        +    H.attach_curl_buffer(buf)

      
        
        200
        +  end

      
        
        201
        +  H.query_autocmd_set = true

      
        
        202
        +end

      
        
        203
        +

      
        
        204
        +function H.get_output_buffer()

      
        
        205
        +  if not is_valid_buf(H.output_buf) then

      
        
        206
        +    H.output_buf = get_or_create_buffer "Curl output"

      
        
        207
        +    vim.api.nvim_set_option_value("filetype", "json", { buf = H.output_buf })

      
        
        208
        +    vim.api.nvim_set_option_value("modifiable", false, { buf = H.output_buf })

      
        
        209
        +  end

      
        
        210
        +  return H.output_buf

      
        
        211
        +end

      
        
        212
        +

      
        
        213
        +function H.open_output_window()

      
        
        214
        +  local output_buf = H.get_output_buffer()

      
        
        215
        +  local query_buf = H.query_buf

      
        
        216
        +  if not is_valid_buf(query_buf) then query_buf = vim.api.nvim_get_current_buf() end

      
        
        217
        +  if not is_valid_buf(query_buf) then query_buf = H.get_query_buffer() end

      
        
        218
        +  if not query_buf then return nil end

      
        
        219
        +  local query_win = find_window_in_current_tab(query_buf) or vim.api.nvim_get_current_win()

      
        
        220
        +  local output_win = find_window_in_current_tab(output_buf)

      
        
        221
        +

      
        
        222
        +  if is_valid_win(output_win) then return output_win end

      
        
        223
        +

      
        
        224
        +  vim.api.nvim_set_current_win(query_win)

      
        
        225
        +  vim.cmd(curl.config.open_cmd)

      
        
        226
        +  output_win = vim.api.nvim_get_current_win()

      
        
        227
        +  vim.api.nvim_win_set_buf(output_win, output_buf)

      
        
        228
        +  vim.api.nvim_set_current_win(query_win)

      
        
        229
        +  return output_win

      
        
        230
        +end

      
        
        231
        +

      
        
        232
        +function H.find_query_block(lines, cursor_line)

      
        
        233
        +  if not lines[cursor_line] or vim.trim(lines[cursor_line]) == "" then return nil end

      
        
        234
        +

      
        
        235
        +  local start_line = nil

      
        
        236
        +  for line_no = cursor_line, 1, -1 do

      
        
        237
        +    local line = lines[line_no]

      
        
        238
        +    if is_query_start(line) then

      
        
        239
        +      start_line = line_no

      
        
        240
        +      break

      
        
        241
        +    end

      
        
        242
        +    if vim.trim(line) == "" then break end

      
        
        243
        +  end

      
        
        244
        +  if not start_line then return nil end

      
        
        245
        +

      
        
        246
        +  local end_line = #lines

      
        
        247
        +  for line_no = start_line + 1, #lines do

      
        
        248
        +    local line = lines[line_no]

      
        
        249
        +    if is_query_start(line) or vim.trim(line) == "" then

      
        
        250
        +      end_line = line_no - 1

      
        
        251
        +      break

      
        
        252
        +    end

      
        
        253
        +  end

      
        
        254
        +

      
        
        255
        +  if cursor_line < start_line or cursor_line > end_line then return nil end

      
        
        256
        +  return start_line, end_line

      
        
        257
        +end

      
        
        258
        +

      
        
        259
        +local function shell_split(input)

      
        
        260
        +  local args = {}

      
        
        261
        +  local current = {}

      
        
        262
        +  local quote = nil

      
        
        263
        +  local i = 1

      
        
        264
        +

      
        
        265
        +  while i <= #input do

      
        
        266
        +    local ch = input:sub(i, i)

      
        
        267
        +

      
        
        268
        +    if quote == "'" then

      
        
        269
        +      if ch == "'" then

      
        
        270
        +        quote = nil

      
        
        271
        +      else

      
        
        272
        +        table.insert(current, ch)

      
        
        273
        +      end

      
        
        274
        +    elseif quote == '"' then

      
        
        275
        +      if ch == '"' then

      
        
        276
        +        quote = nil

      
        
        277
        +      elseif ch == "\\" and i < #input then

      
        
        278
        +        i = i + 1

      
        
        279
        +        table.insert(current, input:sub(i, i))

      
        
        280
        +      else

      
        
        281
        +        table.insert(current, ch)

      
        
        282
        +      end

      
        
        283
        +    else

      
        
        284
        +      if ch == "'" or ch == '"' then

      
        
        285
        +        quote = ch

      
        
        286
        +      elseif ch:match "%s" then

      
        
        287
        +        if #current > 0 then

      
        
        288
        +          table.insert(args, table.concat(current))

      
        
        289
        +          current = {}

      
        
        290
        +        end

      
        
        291
        +      elseif ch == "\\" and i < #input then

      
        
        292
        +        i = i + 1

      
        
        293
        +        table.insert(current, input:sub(i, i))

      
        
        294
        +      else

      
        
        295
        +        table.insert(current, ch)

      
        
        296
        +      end

      
        
        297
        +    end

      
        
        298
        +

      
        
        299
        +    i = i + 1

      
        
        300
        +  end

      
        
        301
        +

      
        
        302
        +  if quote then return nil, "unterminated quote in query" end

      
        
        303
        +  if #current > 0 then table.insert(args, table.concat(current)) end

      
        
        304
        +  return args

      
        
        305
        +end

      
        
        306
        +

      
        
        307
        +function H.build_command(query_lines)

      
        
        308
        +  local binary = curl.config.curl or "curl"

      
        
        309
        +  local body_parts = {}

      
        
        310
        +

      
        
        311
        +  for _, line in ipairs(query_lines) do

      
        
        312
        +    local trimmed = vim.trim(line)

      
        
        313
        +    if trimmed ~= "" and not trimmed:match "^#" then

      
        
        314
        +      trimmed = trimmed:gsub("\\%s*$", "")

      
        
        315
        +      table.insert(body_parts, trimmed)

      
        
        316
        +    end

      
        
        317
        +  end

      
        
        318
        +

      
        
        319
        +  local body = vim.trim(table.concat(body_parts, " "))

      
        
        320
        +  if body == "" then return nil, "empty query" end

      
        
        321
        +

      
        
        322
        +  local parsed, parse_err = shell_split(body)

      
        
        323
        +  if not parsed or #parsed == 0 then return nil, parse_err end

      
        
        324
        +

      
        
        325
        +  if parsed[1] == "curl" then table.remove(parsed, 1) end

      
        
        326
        +

      
        
        327
        +  local parts = { binary, "--silent", "--show-error" }

      
        
        328
        +  for _, flag in ipairs(curl.config.default_flags) do

      
        
        329
        +    table.insert(parts, flag)

      
        
        330
        +  end

      
        
        331
        +

      
        
        332
        +  for _, arg in ipairs(parsed) do

      
        
        333
        +    table.insert(parts, arg)

      
        
        334
        +  end

      
        
        335
        +

      
        
        336
        +  return parts, nil

      
        
        337
        +end

      
        
        338
        +

      
        
        339
        +local function trim(s)

      
        
        340
        +  local from = s:match "^%s*()"

      
        
        341
        +  return from > #s and "" or s:match(".*%S", from)

      
        
        342
        +end

      
        
        343
        +

      
        
        344
        +local function is_json_start_line(line)

      
        
        345
        +  return trim(line):match "^[%[%{]" ~= nil

      
        
        346
        +end

      
        
        347
        +

      
        
        348
        +local function extract_headers_and_json(output)

      
        
        349
        +  local normalized = output:gsub("\r\n", "\n"):gsub("\r", "\n")

      
        
        350
        +  local lines = vim.split(normalized, "\n", { plain = true })

      
        
        351
        +

      
        
        352
        +  if is_json_start_line(normalized) then return {}, normalized end

      
        
        353
        +

      
        
        354
        +  local json_index = nil

      
        
        355
        +  for i, line in ipairs(lines) do

      
        
        356
        +    if is_json_start_line(line) then

      
        
        357
        +      json_index = i

      
        
        358
        +      break

      
        
        359
        +    end

      
        
        360
        +  end

      
        
        361
        +

      
        
        362
        +  if not json_index then return nil, nil end

      
        
        363
        +

      
        
        364
        +  local headers = {}

      
        
        365
        +  for i = 1, json_index - 1 do

      
        
        366
        +    table.insert(headers, trim(lines[i]))

      
        
        367
        +  end

      
        
        368
        +

      
        
        369
        +  local json_lines = {}

      
        
        370
        +  for i = json_index, #lines do

      
        
        371
        +    table.insert(json_lines, lines[i])

      
        
        372
        +  end

      
        
        373
        +

      
        
        374
        +  return headers, table.concat(json_lines, "\n")

      
        
        375
        +end

      
        
        376
        +

      
        
        377
        +function H.write_formatted_output(output)

      
        
        378
        +  if output == "" or vim.fn.executable "jq" ~= 1 then

      
        
        379
        +    vim.schedule(function()

      
        
        380
        +      H.write_output(output, false)

      
        
        381
        +    end)

      
        
        382
        +    return

      
        
        383
        +  end

      
        
        384
        +

      
        
        385
        +  local headers, json_candidate = extract_headers_and_json(output)

      
        
        386
        +  if not json_candidate or json_candidate == "" then

      
        
        387
        +    vim.schedule(function()

      
        
        388
        +      H.write_output(output, false)

      
        
        389
        +    end)

      
        
        390
        +    return

      
        
        391
        +  end

      
        
        392
        +

      
        
        393
        +  vim.system({ "jq", "." }, {

      
        
        394
        +    text = true,

      
        
        395
        +    stdin = json_candidate,

      
        
        396
        +  }, function(result)

      
        
        397
        +    local text = output

      
        
        398
        +    local is_json = false

      
        
        399
        +    if result.code == 0 and result.stdout and result.stdout ~= "" then

      
        
        400
        +      is_json = true

      
        
        401
        +      if headers and #headers > 0 then

      
        
        402
        +        local merged = {}

      
        
        403
        +        for _, line in ipairs(headers) do

      
        
        404
        +          table.insert(merged, line)

      
        
        405
        +        end

      
        
        406
        +        local json_lines = vim.split(result.stdout, "\n", { plain = true })

      
        
        407
        +        for _, line in ipairs(json_lines) do

      
        
        408
        +          table.insert(merged, line)

      
        
        409
        +        end

      
        
        410
        +        text = table.concat(merged, "\n")

      
        
        411
        +      else

      
        
        412
        +        text = result.stdout

      
        
        413
        +      end

      
        
        414
        +    end

      
        
        415
        +    vim.schedule(function()

      
        
        416
        +      H.write_output(text, is_json)

      
        
        417
        +    end)

      
        
        418
        +  end)

      
        
        419
        +end

      
        
        420
        +

      
        
        421
        +function H.write_output(text, is_json)

      
        
        422
        +  local output_buf = H.get_output_buffer()

      
        
        423
        +  local lines = trim_lines(vim.split(text, "\n", { plain = true }))

      
        
        424
        +  if #lines == 0 then lines = { "" } end

      
        
        425
        +

      
        
        426
        +  vim.api.nvim_set_option_value("modifiable", true, { buf = output_buf })

      
        
        427
        +  vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, lines)

      
        
        428
        +  vim.api.nvim_set_option_value("modifiable", false, { buf = output_buf })

      
        
        429
        +  vim.api.nvim_set_option_value("filetype", is_json and "json" or "text", { buf = output_buf })

      
        
        430
        +end

      
        
        431
        +

      
        
        432
        +function curl.setup(opts)

      
        
        433
        +  curl.config = vim.tbl_deep_extend("force", curl.config, opts or {})

      
        
        434
        +  H.setup_filetype()

      
        
        435
        +  H.setup_command()

      
        
        436
        +  H.setup_query_file_autocmd()

      
        
        437
        +end

      
        
        438
        +

      
        
        439
        +function curl.open()

      
        
        440
        +  local query_buf = H.get_query_buffer()

      
        
        441
        +  if not query_buf then return end

      
        
        442
        +  local query_win = find_window_in_current_tab(query_buf)

      
        
        443
        +  if is_valid_win(query_win) then

      
        
        444
        +    vim.api.nvim_set_current_win(query_win)

      
        
        445
        +  else

      
        
        446
        +    vim.api.nvim_set_current_buf(query_buf)

      
        
        447
        +  end

      
        
        448
        +end

      
        
        449
        +

      
        
        450
        +function curl.execute()

      
        
        451
        +  local query_buf = vim.api.nvim_get_current_buf()

      
        
        452
        +  local query_file = vim.api.nvim_buf_get_name(query_buf)

      
        
        453
        +  if not is_curl_file(query_file) then

      
        
        454
        +    vim.notify("[curl.nvim] execute from a .curl request buffer", vim.log.levels.WARN)

      
        
        455
        +    return

      
        
        456
        +  end

      
        
        457
        +  H.query_buf = query_buf

      
        
        458
        +  H.query_file = query_file

      
        
        459
        +  H.query_buffers[query_file] = query_buf

      
        
        460
        +

      
        
        461
        +  local lines = vim.api.nvim_buf_get_lines(query_buf, 0, -1, false)

      
        
        462
        +  local cursor_line = vim.api.nvim_win_get_cursor(0)[1]

      
        
        463
        +  local start_line, end_line = H.find_query_block(lines, cursor_line)

      
        
        464
        +  if not start_line then

      
        
        465
        +    vim.notify("[curl.nvim] cursor is not on a query line", vim.log.levels.INFO)

      
        
        466
        +    return

      
        
        467
        +  end

      
        
        468
        +

      
        
        469
        +  local query_lines = vim.list_slice(lines, start_line, end_line)

      
        
        470
        +  local command, command_err = H.build_command(query_lines)

      
        
        471
        +  if not command then

      
        
        472
        +    vim.notify("[curl.nvim] " .. (command_err or "invalid query"), vim.log.levels.WARN)

      
        
        473
        +    return

      
        
        474
        +  end

      
        
        475
        +

      
        
        476
        +  save_query_buffer(query_buf, query_file)

      
        
        477
        +  H.open_output_window()

      
        
        478
        +

      
        
        479
        +  if H.running_request then

      
        
        480
        +    pcall(function()

      
        
        481
        +      H.running_request:kill(15)

      
        
        482
        +    end)

      
        
        483
        +    H.running_request = nil

      
        
        484
        +  end

      
        
        485
        +

      
        
        486
        +  H.running_request = vim.system(command, { text = true }, function(result)

      
        
        487
        +    H.running_request = nil

      
        
        488
        +

      
        
        489
        +    local combined = result.stdout or ""

      
        
        490
        +    if result.stderr and result.stderr ~= "" then

      
        
        491
        +      combined = combined == "" and result.stderr or (combined .. "\n\n" .. result.stderr)

      
        
        492
        +    end

      
        
        493
        +    if combined == "" then combined = "curl exited with code " .. result.code end

      
        
        494
        +

      
        
        495
        +    H.write_formatted_output(combined)

      
        
        496
        +  end)

      
        
        497
        +end

      
        
        498
        +

      
        
        499
        +return curl

      
A lua/curl/health.lua

Not showing binary file.

A stylua.toml
···
        
        1
        +column_width = 100

      
        
        2
        +line_endings = "Unix"

      
        
        3
        +indent_type = "Spaces"

      
        
        4
        +indent_width = 2

      
        
        5
        +quote_style = "AutoPreferDouble"

      
        
        6
        +no_call_parentheses = true

      
        
        7
        +collapse_simple_statement = "ConditionalOnly"