all repos

curl.nvim @ a19a0b35cb91e25cac652c7ef54996e3506ee887

use curl within neovim
1 files changed, 62 insertions(+), 58 deletions(-)
clanker did some bug fixing
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-05-16 13:42:02 +0300
Authored at: 2026-05-16 13:23:11 +0300
Change ID: lpmlwmtlyswpknrvrnqzouwskzutylwo
Parent: 3b9e8b5
M lua/curl.lua
···
        32
        32
               pattern = "*.curl",

      
        33
        33
               callback = function(args) H.attach_curl_buffer(args.buf) end,

      
        34
        34
             })

      
        
        35
        +    vim.api.nvim_create_autocmd("BufDelete", {

      
        
        36
        +      group = vim.api.nvim_create_augroup("curl_nvim_cache_cleanup", { clear = true }),

      
        
        37
        +      pattern = "*.curl",

      
        
        38
        +      callback = function(args)

      
        
        39
        +        H.query_buffers[vim.api.nvim_buf_get_name(args.buf)] = nil

      
        
        40
        +      end,

      
        
        41
        +    })

      
        35
        42
             for _, buf in ipairs(vim.api.nvim_list_bufs()) do

      
        36
        43
               H.attach_curl_buffer(buf)

      
        37
        44
             end

      ···
        79
        86
             H.running_request = nil

      
        80
        87
           end

      
        81
        88
         

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

      
        
        89
        +  H.running_request = vim.system({ vim.o.shell, "-c", command }, { text = true }, function(result)

      
        83
        90
             H.running_request = nil

      
        84
        91
             local output = result.stdout or ""

      
        85
        92
             if result.stderr and result.stderr ~= "" then

      ···
        102
        109
         function H.save_query_buffer(buf, file)

      
        103
        110
           if not H.is_valid_buf(buf) then return end

      
        104
        111
           file = file or vim.api.nvim_buf_get_name(buf)

      
        105
        
        -  if not H.is_curl_file(file) then return end

      
        
        112
        +  if not file or file == "" then return end

      
        
        113
        +  if not H.is_curl_file(file) then

      
        
        114
        +    vim.notify("[curl.nvim] cannot save: buffer is not a .curl file", vim.log.levels.WARN)

      
        
        115
        +    return

      
        
        116
        +  end

      
        106
        117
         

      
        107
        118
           local ok = pcall(vim.fn.writefile, vim.api.nvim_buf_get_lines(buf, 0, -1, false), file, "b")

      
        108
        119
           if ok then

      ···
        118
        129
             return nil

      
        119
        130
           end

      
        120
        131
         

      
        121
        
        -  local cwd = vim.fn.getcwd()

      
        122
        
        -  local base = vim.fn.fnamemodify(cwd, ":t")

      
        123
        
        -  if base == "" then base = "root" end

      
        124
        
        -  return vim.fs.joinpath(H.cache_dir, base .. "_" .. vim.fn.sha256(cwd):sub(1, 8) .. ".curl")

      
        
        132
        +  return vim.fs.joinpath(H.cache_dir, vim.fn.sha256(vim.fn.getcwd()) .. ".curl")

      
        125
        133
         end

      
        126
        134
         

      
        127
        135
         function H.attach_curl_buffer(buf)

      ···
        215
        223
               start_line = i

      
        216
        224
               break

      
        217
        225
             end

      
        218
        
        -    if vim.trim(lines[i]) == "" then break end

      
        219
        226
           end

      
        220
        227
           if not start_line then return nil end

      
        221
        228
         

      
        222
        229
           local end_line = #lines

      
        223
        230
           for i = start_line + 1, #lines do

      
        224
        
        -    if H.is_query_start(lines[i]) or vim.trim(lines[i]) == "" then

      
        
        231
        +    if H.is_query_start(lines[i]) then

      
        225
        232
               end_line = i - 1

      
        226
        233
               break

      
        227
        234
             end

      ···
        231
        238
           return start_line, end_line

      
        232
        239
         end

      
        233
        240
         

      
        234
        
        -function H.shell_split(input)

      
        235
        
        -  local args, current, quote = {}, {}, nil

      
        236
        
        -  local i = 1

      
        237
        
        -  while i <= #input do

      
        238
        
        -    local ch = input:sub(i, i)

      
        239
        
        -    if quote == "'" then

      
        240
        
        -      if ch == "'" then

      
        241
        
        -        quote = nil

      
        242
        
        -      else

      
        243
        
        -        table.insert(current, ch)

      
        244
        
        -      end

      
        245
        
        -    elseif quote == '"' then

      
        246
        
        -      if ch == '"' then

      
        247
        
        -        quote = nil

      
        248
        
        -      elseif ch == "\\" and i < #input then

      
        249
        
        -        i = i + 1

      
        250
        
        -        table.insert(current, input:sub(i, i))

      
        251
        
        -      else

      
        252
        
        -        table.insert(current, ch)

      
        253
        
        -      end

      
        254
        
        -    else

      
        255
        
        -      if ch == "'" or ch == '"' then

      
        256
        
        -        quote = ch

      
        257
        
        -      elseif ch:match "%s" then

      
        258
        
        -        if #current > 0 then

      
        259
        
        -          table.insert(args, table.concat(current))

      
        260
        
        -          current = {}

      
        
        241
        +function H.quote_json_bodies(lines)

      
        
        242
        +  local result = {}

      
        
        243
        +  local json_open

      
        
        244
        +  local stack_depth = 0

      
        
        245
        +  local in_json = false

      
        
        246
        +  for _, line in ipairs(lines) do

      
        
        247
        +    local s = line

      
        
        248
        +    local trimmed = vim.trim(s)

      
        
        249
        +

      
        
        250
        +    if not in_json and trimmed:match("^[%[%{]") then

      
        
        251
        +      json_open = trimmed:sub(1, 1)

      
        
        252
        +      in_json = true

      
        
        253
        +      s = "'" .. s

      
        
        254
        +    end

      
        
        255
        +

      
        
        256
        +    if in_json then

      
        
        257
        +      for ch in s:gmatch(".") do

      
        
        258
        +        if ch == json_open then

      
        
        259
        +          stack_depth = stack_depth + 1

      
        
        260
        +        elseif (json_open == "{" and ch == "}") or (json_open == "[" and ch == "]") then

      
        
        261
        +          stack_depth = stack_depth - 1

      
        
        262
        +          if stack_depth == 0 then

      
        
        263
        +            s = s .. "'"

      
        
        264
        +            in_json = false

      
        
        265
        +            break

      
        
        266
        +          end

      
        261
        267
                 end

      
        262
        
        -      elseif ch == "\\" and i < #input then

      
        263
        
        -        i = i + 1

      
        264
        
        -        table.insert(current, input:sub(i, i))

      
        265
        
        -      else

      
        266
        
        -        table.insert(current, ch)

      
        267
        268
               end

      
        268
        269
             end

      
        269
        
        -    i = i + 1

      
        
        270
        +

      
        
        271
        +    table.insert(result, s)

      
        270
        272
           end

      
        271
        
        -

      
        272
        
        -  if quote then return nil, "unterminated quote in query" end

      
        273
        
        -  if #current > 0 then table.insert(args, table.concat(current)) end

      
        274
        
        -  return args

      
        
        273
        +  return result

      
        275
        274
         end

      
        276
        275
         

      
        277
        276
         function H.build_command(query_lines)

      
        278
        
        -  local body_parts = {}

      
        279
        
        -  for _, line in ipairs(query_lines) do

      
        
        277
        +  local parts = {}

      
        
        278
        +  for _, line in ipairs(H.quote_json_bodies(query_lines)) do

      
        280
        279
             local s = vim.trim(line)

      
        281
        
        -    if s ~= "" and not s:match "^#" then table.insert(body_parts, (s:gsub("\\%s*$", ""))) end

      
        
        280
        +    if s ~= "" and not s:match("^#") then

      
        
        281
        +      table.insert(parts, (s:gsub("\\%s*$", "")))

      
        
        282
        +    end

      
        282
        283
           end

      
        283
        284
         

      
        284
        
        -  local body = vim.trim(table.concat(body_parts, " "))

      
        
        285
        +  local body = vim.trim(table.concat(parts, " "))

      
        285
        286
           if body == "" then return nil, "empty query" end

      
        286
        287
         

      
        287
        
        -  local parsed, err = H.shell_split(body)

      
        288
        
        -  if not parsed or #parsed == 0 then return nil, err end

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

      
        
        288
        +  body = body:gsub("^curl%s+", "", 1)

      
        
        289
        +

      
        
        290
        +  local flag_parts = {}

      
        
        291
        +  for _, f in ipairs(curl.config.default_flags or {}) do

      
        
        292
        +    table.insert(flag_parts, f)

      
        
        293
        +  end

      
        290
        294
         

      
        291
        
        -  local cmd = { curl.config.curl or "curl", "--silent", "--show-error" }

      
        292
        
        -  vim.list_extend(cmd, curl.config.default_flags or {})

      
        293
        
        -  vim.list_extend(cmd, parsed)

      
        294
        
        -  return cmd

      
        
        295
        +  return (curl.config.curl or "curl") .. " " .. table.concat(flag_parts, " ") .. " -sSL " .. body

      
        295
        296
         end

      
        296
        297
         

      
        297
        298
         function H.write_output(query_buf, text)

      ···
        330
        331
         

      
        331
        332
           local headers = {}

      
        332
        333
           for i = 1, json_index - 1 do

      
        333
        
        -    table.insert(headers, vim.trim(lines[i]))

      
        
        334
        +    local trimmed = vim.trim(lines[i])

      
        
        335
        +    if trimmed ~= "" then

      
        
        336
        +      table.insert(headers, trimmed)

      
        
        337
        +    end

      
        334
        338
           end

      
        335
        339
           local json_body = table.concat(vim.list_slice(lines, json_index, #lines), "\n")

      
        336
        340
         

      
        337
        341
           vim.system({ "jq", "." }, { text = true, stdin = json_body }, function(result)

      
        338
        342
             if result.code == 0 and result.stdout and result.stdout ~= "" then

      
        339
        
        -      output = #headers > 0 and (table.concat(headers, "\n") .. "\n" .. result.stdout) or result.stdout

      
        
        343
        +      output = #headers > 0 and (table.concat(headers, "\n") .. "\n\n" .. result.stdout) or result.stdout

      
        340
        344
             end

      
        341
        345
             vim.schedule(function() H.write_output(query_buf, output) end)

      
        342
        346
           end)