Skip to content

Commit

Permalink
feat!: implement scoped custom buffers
Browse files Browse the repository at this point in the history
custom buffers can now be opened either scoped globally, or scoped to
cwd

The old method has been deprecated, and you should now use the explicit
custom global method instead. See issue #20
  • Loading branch information
oysandvik94 committed Jul 16, 2024
1 parent 109b386 commit 11912cc
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 107 deletions.
74 changes: 55 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ curl.nvim allows you to run HTTP requests with curl from a scratchpad, and displ
- Introduces the ".curl" filetype, where pressing enter will execute a curl request under the cursor
- Quality of life formatting features, so that writing out curl commands is a *little* less tedious
- Output is formatted using JQ
- Persist a collections of curl request using various methods of persistence, such as a global file,
named files, or a file that is stored per working directory
- Open a curl command buffer that is either persisted globally or per working directory
- Store collections (named files) that are etiher persisted globally or per working directory
- It's just curl, so all the headers and auth flags you already know works

See [the features section](<README#✨ Features>) for more information.
Expand All @@ -27,11 +27,9 @@ still using the knowledge of curl you already have.

## Installation and requirements

The plugin requires you to have curl on your system, which you most likely have.

If you dont have [jq](https://jqlang.github.io/jq/), you can most likely download it on your system
through your preferred package manager. _curl.nvim_ uses jq to format JSON, but it's an amazing tool
that I recommend you experiment with.
- [Curl](https://curl.se)
- [jq](https://jqlang.github.io/jq/),
- Linux/Mac (I dont have a windows machine to test, feel free to create a PR)

Installation example for [Lazy](https://github.com/folke/lazy.nvim):

Expand All @@ -40,12 +38,38 @@ Installation example for [Lazy](https://github.com/folke/lazy.nvim):
"oysandvik94/curl.nvim",
cmd = { "CurlOpen" },
dependencies = {
"nvim-lua/plenary.nvim",
},
config = true,
"nvim-lua/plenary.nvim",
},
config = true,
}
```

Below follows some example keymaps, but you should find a setup that works for you:

```lua
local curl = require("curl")

vim.keymap.set("n", "<leader>cc", function()
curl.open_curl_tab()
end, { desc = "Open a curl tab scoped to the current working directory" })

vim.keymap.set("n", "<leader>co", function()
curl.open_global_tab()
end, { desc = "Open a curl tab with gloabl scope" })

vim.keymap.set("n", "<leader>csc", function()
vim.ui.input({ prompt = "Collection name: " }, function(input)
curl.open_scoped_collection(input)
end)
end, { desc = "Create or open a collection with a name from user input" })

vim.keymap.set("n", "<leader>cgc", function()
vim.ui.input({ prompt = "Collection name: " }, function(input)
curl.open_global_collection(input)
end)
end, { desc = "Create or open a global collection with a name from user input" })
```

To verify the installation run `:checkhealth curl`.

## Configuration
Expand All @@ -71,7 +95,7 @@ Or if you use [Lazy](https://github.com/folke/lazy.nvim), just pass the table in

## Usage

You can open curl.nvim in three ways:
You can open curl.nvim in four ways:

```vim
" A buffer that is scoped to the current working directory
Expand All @@ -81,15 +105,19 @@ You can open curl.nvim in three ways:
:CurlOpen global
" A buffer with a custom name that can be opened from any Neovim instance
:CurlOpen custom {any_name}
:CurlOpen collection global {any_name}
" A buffer with a custom name that is scoped to the curren working directory
:CurlOpen collection scoped {any_name}
```

or using the lua api:

```lua
require("curl").open_curl_tab()
require("curl").open_global_tab()
require("curl").open_custom_tab("my_curls")
require("curl").open_global_collection("my_curls")
require("curl").open_scoped_collection("my_curls")
```

Any of these commands will open a new tab containing two buffers split vertically.
Expand Down Expand Up @@ -214,19 +242,26 @@ use the global option.
require("curl").open_global_tab()
```

#### Custom buffers
#### Collections

If you want more control, or would like to organize your curl commands in logical collections,
you can use the custom option to give names to your collections.
you can use the "collection" option to give names to your collections.

This will create a new collection, or open a collection if it exists with the given name

Next time you run `CurlOpen` with that given names, you will find your commands again.
You can either open a global collection, which is accessible from any Neovim instance,
or a scoped collection which belongs to the current working directory. This means that if you
have two collections with the same name created from different directories, the correct one
will open from the given directory

```vim
:CurlOpen custom mycoolcurls
:CurlOpen collection global mycoolcurls
:CurlOpen collection scoped mycoolcurls
```

```lua
require("curl").open_custom_tab("mycoolcurls")
require("curl").open_global_collection("mycoolcurls")
require("curl").open_scoped_collection("mycoolcurls")
```

## Lua api
Expand All @@ -242,7 +277,8 @@ local curl = require('curl')
-- See ### Persistence under ## Features
curl.open_curl_tab()
curl.open_global_tab()
curl.open_custom_tab()
curl.open_scoped_collection()
curl.open_global_collection()

-- Close the tab containing curl buffers
curl.close_curl_tab()
Expand Down
32 changes: 25 additions & 7 deletions lua/curl/api.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
local M = {}

local parser = require("curl.parser")
local cache = require("curl.cache")
local buffers = require("curl.buffers")
local output_parser = require("curl.output_parser")
local notify = require("curl.notifications")

M.open_global_collection = function(collection_name)
local filename = cache.load_custom_command_file(collection_name, true)
buffers.setup_curl_tab_for_file(filename)
end

M.open_scoped_collection = function(collection_name)
local filename = cache.load_custom_command_file(collection_name)
buffers.setup_curl_tab_for_file(filename)
end

M.open_custom_tab = function(custom_buf_name)
buffers.open_custom_curl_tab(custom_buf_name)
local filename = cache.load_custom_command_file(custom_buf_name, true)
buffers.setup_curl_tab_for_file(filename)
vim.deprecate(
"open_custom_tab | CurlOpen custom {name} (see issue #20 in curl.nvim)",
"open_global_collection | CurlOpen collection scoped",
"soon",
"curl.nvim"
)
end

M.open_global_tab = function()
buffers.open_global_curl_tab()
local filename = cache.load_global_command_file()
buffers.setup_curl_tab_for_file(filename)
end

M.open_curl_tab = function()
buffers.open_curl_tab()
local filename = cache.load_command_file()
buffers.setup_curl_tab_for_file(filename)
end

---comment
Expand All @@ -35,18 +55,16 @@ M.execute_curl = function()
local output = ""
local error = ""

local output_bufnr = buffers.open_result_buffer()
OUTPUT_BUF_ID = output_bufnr
local _ = vim.fn.jobstart(curl_command, {
on_exit = function(_, exit_code, _)
if exit_code ~= 0 then
notify.error("Curl failed")
buffers.set_output_buffer_content(vim.split(error, "\n"), output_bufnr)
buffers.set_output_buffer_content(vim.split(error, "\n"))
return
end

local parsed_output = output_parser.parse_curl_output(output)
buffers.set_output_buffer_content(parsed_output, output_bufnr)
buffers.set_output_buffer_content(parsed_output)
end,
on_stdout = function(_, data, _)
output = output .. vim.fn.join(data)
Expand Down
113 changes: 68 additions & 45 deletions lua/curl/buffers.lua
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
local M = {}
local cache = require("curl.cache")

OUTPUT_BUF_ID = -1
COMMAND_BUF_ID = -1
CURL_WINDOW_ID = -1
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)

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

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

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

Expand All @@ -27,7 +34,8 @@ local function find_curl_tab_windid()
end
end
end
local function open_curl_tab_if_created()

local function open_or_goto_curl_tab()
local tab_win_id = find_curl_tab_windid()
if tab_win_id ~= nil then
return tab_win_id
Expand All @@ -38,69 +46,82 @@ local function open_curl_tab_if_created()
return vim.api.nvim_tabpage_get_win(0)
end

local create_command_buffer = function(command_file)
local command_bufnr = vim.fn.bufnr(command_file, false)
vim.api.nvim_win_set_buf(CURL_WINDOW_ID, command_bufnr)
return command_bufnr
end

local replace_command_buffer = function(command_file)
close_curl_buffer(COMMAND_BUF_ID, false)
vim.cmd.edit(command_file)
local new_bufnr = vim.fn.bufnr(command_file, false)

return new_bufnr
end

local open_command_buffer = function(command_file)
local bufnr = vim.fn.bufnr(command_file, false)
if buf_is_open(command_file) then
return create_command_buffer(command_file)
end

if bufnr == -1 then
vim.cmd.edit(command_file)
local new_bufnr = vim.fn.bufnr(command_file, false)
return replace_command_buffer(command_file)
end

if COMMAND_BUF_ID ~= new_bufnr then
close_curl_buffer(COMMAND_BUF_ID, false)
end
local result_open_in_current_tab = function()
local buffer = vim.fn.bufnr(RESULT_BUF_NAME, false)

return new_bufnr
if not buf_is_open(RESULT_BUF_NAME) then
return
end

vim.api.nvim_win_set_buf(CURL_WINDOW_ID, bufnr)
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

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

return false
end

local get_result_bufnr = function()
return vim.fn.bufnr(RESULT_BUF_NAME, false)
end

M.open_result_buffer = function()
local bufnr = vim.fn.bufnr("Curl output", false)
local open_result_buffer = function()
if result_open_in_current_tab() then
return
end

if bufnr ~= -1 then
local curl_tab_winid = vim.fn.win_findbuf(bufnr)
local open_windows = vim.api.nvim_tabpage_list_wins(0)
if vim.tbl_contains(open_windows, function(v)
return vim.tbl_contains(curl_tab_winid, v)
end, { predicate = true }) == false then
vim.cmd("vert belowright sb" .. bufnr .. " | wincmd p")
end
return bufnr
if buf_is_open(RESULT_BUF_NAME) then
local bufnr = vim.fn.bufnr(RESULT_BUF_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, "Curl output")
vim.api.nvim_buf_set_name(new_bufnr, RESULT_BUF_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
return new_bufnr
end

local setup_curl_tab_for_file = function(filename)
CURL_WINDOW_ID = open_curl_tab_if_created()
M.setup_curl_tab_for_file = function(filename)
CURL_WINDOW_ID = open_or_goto_curl_tab()

COMMAND_BUF_ID = open_command_buffer(filename)

M.open_result_buffer()
end

M.open_global_curl_tab = function()
local filename = cache.load_global_command_file()
setup_curl_tab_for_file(filename)
end

M.open_curl_tab = function()
local filename = cache.load_command_file()
setup_curl_tab_for_file(filename)
end

M.open_custom_curl_tab = function(curl_buf_name)
local filename = cache.load_custom_command_file(curl_buf_name)
setup_curl_tab_for_file(filename)
open_result_buffer()
end

M.close_curl_tab = function(force)
Expand All @@ -122,7 +143,9 @@ M.get_command_buffer_and_pos = function()
return cursor_pos, lines
end

M.set_output_buffer_content = function(content, buf_id)
M.set_output_buffer_content = function(content)
open_result_buffer()
local buf_id = get_result_bufnr()
vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, content)
end

Expand Down
Loading

0 comments on commit 11912cc

Please sign in to comment.