1 files changed,
62 insertions(+),
58 deletions(-)
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)