Skip to content

Commit

Permalink
use parsed output in buffer output
Browse files Browse the repository at this point in the history
  • Loading branch information
oysandvik94 committed Nov 29, 2024
1 parent d0ba8c5 commit eeabb87
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 138 deletions.
6 changes: 6 additions & 0 deletions lua/curl/api.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local M = {}

local parser = require("curl.parser")
local state = require("curl.state")
local config = require("curl.config")
local cache = require("curl.cache")
local buffers = require("curl.buffers")
Expand Down Expand Up @@ -127,6 +128,11 @@ M.execute_curl = function()
end

local parsed_output = output_parser.parse_curl_output(output)

if curl_command.variable ~= nil then
state.store_value(curl_command.variable, parsed_output.response)
end

buffers.set_output_buffer_content(executed_from_win, parsed_output)
end,
on_stdout = function(_, data, _)
Expand Down
184 changes: 100 additions & 84 deletions lua/curl/buffers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,131 +6,147 @@ TAB_ID = "curl.nvim.tab"
RESULT_BUF_NAME = "Curl output"

local buf_is_open = function(buffer_name)
local bufnr = vim.fn.bufnr(buffer_name, false)
local bufnr = vim.fn.bufnr(buffer_name, false)

return bufnr ~= -1 and vim.fn.bufloaded(bufnr) == 1
return bufnr ~= -1 and vim.fn.bufloaded(bufnr) == 1
end

local close_curl_buffer = function(buffer, force)
if buffer == -1 or vim.fn.bufexists(buffer) ~= 1 then
return
end
if buffer == -1 or vim.fn.bufexists(buffer) ~= 1 then
return
end

vim.api.nvim_buf_delete(buffer, { force = force })
vim.api.nvim_buf_delete(buffer, { force = force })
end

local function find_curl_tab_windid()
for _, tab in ipairs(vim.api.nvim_list_tabpages()) do
local success, tab_id = pcall(function() ---@type any,integer
return vim.api.nvim_tabpage_get_var(tab, "id")
end)

if success and tab_id == TAB_ID then
vim.api.nvim_set_current_tabpage(tab)
local win_id = vim.api.nvim_tabpage_get_win(tab)
vim.api.nvim_set_current_win(win_id)
return win_id
end
end
for _, tab in ipairs(vim.api.nvim_list_tabpages()) do
local success, tab_id = pcall(function() ---@type any,integer
return vim.api.nvim_tabpage_get_var(tab, "id")
end)

if success and tab_id == TAB_ID then
vim.api.nvim_set_current_tabpage(tab)
local win_id = vim.api.nvim_tabpage_get_win(tab)
vim.api.nvim_set_current_win(win_id)
return win_id
end
end
end

local function open_or_goto_curl_tab()
local config = require("curl.config")
local open_with = config.get("open_with")

if open_with == "split" then
vim.cmd("botright split | wincmd j")
else
local tab_win_id = find_curl_tab_windid()
if tab_win_id ~= nil then
return tab_win_id
end

vim.cmd("tabnew")
vim.api.nvim_tabpage_set_var(0, "id", TAB_ID)
end
local config = require("curl.config")
local open_with = config.get("open_with")

if open_with == "split" then
vim.cmd("botright split | wincmd j")
else
local tab_win_id = find_curl_tab_windid()
if tab_win_id ~= nil then
return tab_win_id
end

vim.cmd("tabnew")
vim.api.nvim_tabpage_set_var(0, "id", TAB_ID)
end
end

local open_command_buffer = function(command_file)
vim.cmd.edit(command_file)
local new_bufnr = vim.fn.bufnr(command_file, false)
local new_win = vim.api.nvim_get_current_win()
vim.cmd.edit(command_file)
local new_bufnr = vim.fn.bufnr(command_file, false)
local new_win = vim.api.nvim_get_current_win()

return new_bufnr, new_win
return new_bufnr, new_win
end

local result_open_in_current_tab = function(res_buf_name)
local buffer = vim.fn.bufnr(res_buf_name, false)
local buffer = vim.fn.bufnr(res_buf_name, false)

if not buf_is_open(res_buf_name) then
return
end
if not buf_is_open(res_buf_name) then
return
end

local open_windows = vim.api.nvim_tabpage_list_wins(0)
local windows_containing_buffer = vim.fn.win_findbuf(buffer)
local open_windows = vim.api.nvim_tabpage_list_wins(0)
local windows_containing_buffer = vim.fn.win_findbuf(buffer)

local set = {}
for _, win_id in pairs(open_windows) do
set[win_id] = true ---@type boolean
end
local set = {}
for _, win_id in pairs(open_windows) do
set[win_id] = true ---@type boolean
end

for _, win_id in pairs(windows_containing_buffer) do
if set[win_id] then
return true
end
end
for _, win_id in pairs(windows_containing_buffer) do
if set[win_id] then
return true
end
end

return false
return false
end

local open_result_buffer = function(called_from_win_id)
local open_resbuf_name = RESULT_BUF_NAME .. "_" .. called_from_win_id ---@type string

vim.api.nvim_set_current_win(called_from_win_id)
if result_open_in_current_tab(open_resbuf_name) then
return
end

if buf_is_open(open_resbuf_name) then
local bufnr = vim.fn.bufnr(open_resbuf_name, false)
vim.cmd("vert belowright sb" .. bufnr .. " | wincmd p")
OUTPUT_BUF_ID = bufnr
return
end

local new_bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(new_bufnr, open_resbuf_name)
vim.api.nvim_set_option_value("filetype", "json", { buf = new_bufnr })
vim.api.nvim_set_option_value("buftype", "nofile", { buf = new_bufnr })
vim.cmd("vert belowright sb" .. new_bufnr .. " | wincmd p")
OUTPUT_BUF_ID = new_bufnr
local open_resbuf_name = RESULT_BUF_NAME .. "_" .. called_from_win_id ---@type string

vim.api.nvim_set_current_win(called_from_win_id)
if result_open_in_current_tab(open_resbuf_name) then
return
end

if buf_is_open(open_resbuf_name) then
local bufnr = vim.fn.bufnr(open_resbuf_name, false)
vim.cmd("vert belowright sb" .. bufnr .. " | wincmd p")
OUTPUT_BUF_ID = bufnr
return
end

local new_bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(new_bufnr, open_resbuf_name)
vim.api.nvim_set_option_value("filetype", "json", { buf = new_bufnr })
vim.api.nvim_set_option_value("buftype", "nofile", { buf = new_bufnr })
vim.cmd("vert belowright sb" .. new_bufnr .. " | wincmd p")
OUTPUT_BUF_ID = new_bufnr
end

M.setup_curl_tab_for_file = function(filename)
open_or_goto_curl_tab()
open_or_goto_curl_tab()

local new_buf_id, current_win = open_command_buffer(filename)
COMMAND_BUF_ID = new_buf_id
local new_buf_id, current_win = open_command_buffer(filename)
COMMAND_BUF_ID = new_buf_id
end

M.close_curl_tab = function(force)
close_curl_buffer(COMMAND_BUF_ID, force)
close_curl_buffer(OUTPUT_BUF_ID, force)
COMMAND_BUF_ID, OUTPUT_BUF_ID = -1, -1, -1
close_curl_buffer(COMMAND_BUF_ID, force)
close_curl_buffer(OUTPUT_BUF_ID, force)
COMMAND_BUF_ID, OUTPUT_BUF_ID = -1, -1, -1
end

M.get_command_buffer_and_pos = function()
local left_buf = vim.api.nvim_get_current_buf()
local lines = vim.api.nvim_buf_get_lines(left_buf, 0, -1, false)
local left_buf = vim.api.nvim_get_current_buf()
local lines = vim.api.nvim_buf_get_lines(left_buf, 0, -1, false)

local cursor_pos = vim.api.nvim_win_get_cursor(0)[1]
local cursor_pos = vim.api.nvim_win_get_cursor(0)[1]

return cursor_pos, lines
return cursor_pos, lines
end

---comment
---@param executed_from_win number
---@param content CurlOutput
M.set_output_buffer_content = function(executed_from_win, content)
open_result_buffer(executed_from_win)
vim.api.nvim_buf_set_lines(OUTPUT_BUF_ID, 0, -1, false, content)
open_result_buffer(executed_from_win)

local flattened = {}

vim.print("headers")
vim.print(content.headers)
for _, value in ipairs(content.headers) do
table.insert(flattened, value)
end

for _, value in ipairs(content.response) do
table.insert(flattened, value)
end

vim.api.nvim_buf_set_lines(OUTPUT_BUF_ID, 0, -1, false, flattened)
end

return M
106 changes: 56 additions & 50 deletions lua/curl/output_parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,71 +7,77 @@ local notify = require("curl.notifications")
---@param unformatted_json string
---@return table
local function run_jq(unformatted_json)
local result = {}

Job:new({
command = "jq",
args = { "." },
writer = unformatted_json,
on_stdout = function(_, line)
table.insert(result, line)
end,
on_exit = function(_, return_val)
if return_val ~= 0 then
vim.schedule(function()
notify.error("Failed to parse JSON")
end)

result = { unformatted_json }
end
end,
}):sync()

return result
local result = {}

Job:new({
command = "jq",
args = { "." },
writer = unformatted_json,
on_stdout = function(_, line)
table.insert(result, line)
end,
on_exit = function(_, return_val)
if return_val ~= 0 then
vim.schedule(function()
notify.error("Failed to parse JSON")
end)

result = { unformatted_json }
end
end,
}):sync()

return result
end

local function trim(s)
local from = s:match("^%s*()")
return from > #s and "" or s:match(".*%S", from)
local from = s:match("^%s*()")
return from > #s and "" or s:match(".*%S", from)
end

local function is_json_start(line)
return line:match("^[%[%{]") ~= nil
local function no_headers(line)
return line:match("^[%[%{]") ~= nil
end

local function extract_json(output_lines)
local header_lines = {}
local json_string = nil

for _, line in ipairs(output_lines) do
local trimmed_line = trim(line)
if is_json_start(trimmed_line) then
json_string = trimmed_line
break
end
table.insert(header_lines, trimmed_line)
end

return header_lines, json_string
local header_lines = {}
local json_string = nil

for _, line in ipairs(output_lines) do
local trimmed_line = trim(line)
if no_headers(trimmed_line) then
json_string = trimmed_line
break
end
table.insert(header_lines, trimmed_line)
end

return header_lines, json_string
end

---@class CurlOutput
---@field response table
---@field headers table

---
---@param curl_standard_out string
---@return table
---@return CurlOutput
M.parse_curl_output = function(curl_standard_out)
if is_json_start(curl_standard_out) then
return run_jq(curl_standard_out)
end
---@class CurlOutput
local curl_output = {}

if no_headers(curl_standard_out) then
curl_output.response = run_jq(curl_standard_out)
end

local output_table = vim.split(curl_standard_out, "\r")
local header_lines, json_string = extract_json(output_table)
local output_table = vim.split(curl_standard_out, "\r")
local header_lines, json_string = extract_json(output_table)
curl_output.headers = header_lines

if json_string == nil then
return output_table
end
if json_string ~= nil then
curl_output.response = run_jq(json_string)
end

local json_lines = run_jq(json_string)
table.move(json_lines, 1, #json_lines, #header_lines + 1, header_lines)
return header_lines
return curl_output
end
return M
17 changes: 17 additions & 0 deletions lua/curl/state.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
local M = {}

local variable_map = {}

---comment
---@param key string
---@param value table
M.store_value = function(key, value)
local json_string = table.concat(value, "\n")
local decoded_json = vim.json.decode(json_string)
variable_map[key] = decoded_json
end

M.get_value = function(key)
return variable_map[key]
end
return M
Loading

0 comments on commit eeabb87

Please sign in to comment.