Skip to content

Commit

Permalink
Environment Scope (#216)
Browse files Browse the repository at this point in the history
* Environment Scope

* rework(DB): naming like in prisma.io

The reasoning behind this is to make it easier to
find code that does updates, or just fetches a single item,
or fetches the whole dataset.

Additionally add global data which is currently only used for
.replay().

.replay() should enable the user to run the last command in any buffer,
not only in .http or .rest buffers.

* rework(DB): naming like in prisma.io

The reasoning behind this is to make it easier to
find code that does updates, or just fetches a single item,
or fetches the whole dataset.

Additionally add global data which is currently only used for
.replay().

.replay() should enable the user to run the last command in any buffer,
not only in .http or .rest buffers.

* move db_spec.lua

---------

Co-authored-by: Jan Stocker <Jan.Stocker@cosmoconsult.com>
Co-authored-by: Marco Kellershoff <marco@kellershoff.net>
  • Loading branch information
3 people authored Sep 7, 2024
1 parent 09d7b94 commit e01f764
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 38 deletions.
26 changes: 26 additions & 0 deletions docs/docs/getting-started/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ Here is a full example of setting up the Kulala plugin with the available `opts`
-- disable the vim.print output of the scripts
-- they will be still written to disk, but not printed immediately
disable_script_print_output = false,
-- set scope for environment and request variables
-- possible values: b = buffer, g = global
environment_scope = "b",
},
}
```
Expand Down Expand Up @@ -511,3 +514,26 @@ Example:
},
}
```
### environment_scope

While using request variables the results will be stored for later use.
As usual variables they are file relevant and should be stored in the buffer.
If you want to share the variables between buffers you can use the global scope.

Possible values:

- `"b"` (buffer)
- `"g"` (global)

Default: `"b"`

Example:

```lua
{
"mistweaverco/kulala.nvim",
opts = {
environment_scope = "b",
},
}
```
5 changes: 4 additions & 1 deletion lua/kulala/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ M.defaults = {
-- disable the vim.print output of the scripts
-- they will be still written to disk, but not printed immediately
disable_script_print_output = false,
-- set scope for environment and request variables
-- possible values: b = buffer, g = global
environment_scope = "b",
}

M.default_contenttype = {
Expand All @@ -76,7 +79,7 @@ M.default_contenttype = {
pathresolver = nil,
}

M.options = {}
M.options = M.defaults

M.setup = function(config)
M.options = vim.tbl_deep_extend("force", M.defaults, config or {})
Expand Down
80 changes: 74 additions & 6 deletions lua/kulala/db/init.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,78 @@
local CONFIG = require("kulala.config")

local M = {}

M.data = {
selected_env = nil, -- string - name of selected env
http_client_env = nil, -- table of envs from http-client.env.json
http_client_env_base = nil, -- table of base env values which should be applied to all requests
env = {}, -- table of envs from document sources
}
M.data = nil
M.global_data = {}

local function default_data()
return {
selected_env = nil, -- string - name of selected env
http_client_env = nil, -- table of envs from http-client.env.json
http_client_env_base = nil, -- table of base env values which should be applied to all requests
env = {}, -- table of envs from document sources
scope_nr = nil, -- number - buffer number of the current scope
}
end

local function get_current_scope_nr()
if CONFIG.get().environment_scope == "b" then
return vim.fn.bufnr()
elseif CONFIG.get().environment_scope == "g" then
return 0
end
end

local function load_data()
if CONFIG.get().environment_scope == "b" then
M.data = vim.b.kulala_data or default_data()
elseif CONFIG.get().environment_scope == "g" then
-- keep in lua only
if not M.data then
M.data = default_data()
end
end
M.data.scope_nr = get_current_scope_nr()
end

local function save_data()
if CONFIG.get().environment_scope == "b" then
if vim.fn.bufexists(M.data.scope_nr) ~= -1 then
vim.b[M.data.scope_nr].kulala_data = M.data
end
elseif CONFIG.get().environment_scope == "g" then
-- keep in lua only
end
end

M.global_find_many = function()
return M.global_data
end

M.global_find_unique = function(key)
return M.global_data[key]
end

M.global_update = function()
return M.global_data
end

M.find_many = function()
if not M.data or not M.data.scope_nr then
load_data()
elseif M.data.scope_nr ~= get_current_scope_nr() then
save_data()
load_data()
end
return M.data
end

M.update = function()
return M.find_many()
end

M.find_unique = function(key)
return M.find_many()[key]
end

return M
2 changes: 1 addition & 1 deletion lua/kulala/external_processing/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ M.env_stdin_cmd = function(cmdstring, contents)
end

-- save the result to the environment variable
DB.data.env[env_name] = M.stdin_cmd(cmd_string, contents)
DB.update().env[env_name] = M.stdin_cmd(cmd_string, contents)
end

return M
12 changes: 6 additions & 6 deletions lua/kulala/internal_processing/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ M.set_env_for_named_request = function(name, body)
cookies = get_cookies_as_table(),
},
request = {
headers = DB.data.current_request.headers,
body = DB.data.current_request.body,
headers = DB.find_unique("current_request").headers,
body = DB.find_unique("current_request").body,
},
}
DB.data.env[name] = named_request
DB.update().env[name] = named_request
end

M.env_header_key = function(cmd)
Expand All @@ -122,7 +122,7 @@ M.env_header_key = function(cmd)
if value == nil then
vim.notify("env-header-key --> Header not found.", vim.log.levels.ERROR)
else
DB.data.env[variable_name] = value
DB.update().env[variable_name] = value
end
end

Expand Down Expand Up @@ -151,7 +151,7 @@ M.env_json_key = function(cmd, body)
else
local kv = vim.split(cmd, " ")
local value = get_nested_value(json, kv[2])
DB.data.env[kv[1]] = value
DB.update().env[kv[1]] = value
end
end

Expand All @@ -163,7 +163,7 @@ M.prompt_var = function(metadata_value)
if value == nil or value == "" then
return false
end
DB.data.env[key] = value
DB.update().env[key] = value
return true
end

Expand Down
26 changes: 15 additions & 11 deletions lua/kulala/parser/env.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ M.get_env = function()
env[key] = value
end

DB.data.http_client_env_base = {}
DB.data.http_client_env = {}
DB.update().http_client_env_base = {}
DB.update().http_client_env = {}

if Config.get().vscode_rest_client_environmentvars then
local vscode_dir = FS.find_file_in_parent_dirs(".vscode")
Expand All @@ -29,10 +29,11 @@ M.get_env = function()
if settings and settings["rest-client.environmentVariables"] then
local f = settings["rest-client.environmentVariables"]
if f["$shared"] then
DB.data.http_client_env_base = vim.tbl_deep_extend("force", DB.data.http_client_env_base, f["$shared"])
DB.update().http_client_env_base =
vim.tbl_deep_extend("force", DB.find_unique("http_client_env_base"), f["$shared"])
end
f["$shared"] = nil
DB.data.http_client_env = vim.tbl_deep_extend("force", DB.data.http_client_env, f)
DB.update().http_client_env = vim.tbl_deep_extend("force", DB.find_unique("http_client_env"), f)
end
end
end
Expand All @@ -43,10 +44,11 @@ M.get_env = function()
if settings and settings["rest-client.environmentVariables"] then
local f = settings["rest-client.environmentVariables"]
if f["$shared"] then
DB.data.http_client_env_base = vim.tbl_deep_extend("force", DB.data.http_client_env_base, f["$shared"])
DB.update().http_client_env_base =
vim.tbl_deep_extend("force", DB.find_unique("http_client_env_base"), f["$shared"])
end
f["$shared"] = nil
DB.data.http_client_env = vim.tbl_deep_extend("force", DB.data.http_client_env, f)
DB.update().http_client_env = vim.tbl_deep_extend("force", DB.find_unique("http_client_env"), f)
end
end
end
Expand All @@ -67,24 +69,26 @@ M.get_env = function()
if http_client_env_json then
local f = vim.fn.json_decode(vim.fn.readfile(http_client_env_json))
if f._base then
DB.data.http_client_env_base = vim.tbl_deep_extend("force", DB.data.http_client_env_base, f._base)
DB.update().http_client_env_base = vim.tbl_deep_extend("force", DB.find_unique("http_client_env_base"), f._base)
end
f._base = nil
DB.data.http_client_env = vim.tbl_deep_extend("force", DB.data.http_client_env, f)
DB.update().http_client_env = vim.tbl_deep_extend("force", DB.find_unique("http_client_env"), f)
end

for key, value in pairs(DB.data.http_client_env_base) do
local http_client_env_base = DB.find_unique("http_client_env_base") or {}
for key, value in pairs(http_client_env_base) do
if key ~= "DEFAULT_HEADERS" then
env[key] = value
end
end

local selected_env = DB.data.http_client_env[vim.g.kulala_selected_env or Config.get().default_env]
local selected_env = DB.find_unique("http_client_env")[vim.g.kulala_selected_env or Config.get().default_env]
if selected_env then
env = vim.tbl_extend("force", env, selected_env)
end

for key, value in pairs(DB.data.env) do
local db_env = DB.find_unique("env") or {}
for key, value in pairs(db_env) do
env[key] = value
end

Expand Down
11 changes: 7 additions & 4 deletions lua/kulala/parser/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ function M.parse(start_request_linenr)
Scripts.javascript.run("pre_request", req.scripts.pre_request)
local env = ENV_PARSER.get_env()

DB.data.previous_request = DB.data.current_request
DB.update().previous_request = DB.find_unique("current_request")

document_variables = extend_document_variables(document_variables, req)

Expand Down Expand Up @@ -531,8 +531,8 @@ function M.parse(start_request_linenr)
end

-- Merge headers from the _base environment if it exists
if DB.data.http_client_env_base then
local default_headers = DB.data.http_client_env_base["DEFAULT_HEADERS"]
if DB.find_unique("http_client_env_base") then
local default_headers = DB.find_unique("http_client_env_base")["DEFAULT_HEADERS"]
if default_headers then
for key, value in pairs(default_headers) do
key = key:lower()
Expand Down Expand Up @@ -664,7 +664,10 @@ function M.parse(start_request_linenr)
if CONFIG.get().debug then
FS.write_file(PLUGIN_TMP_DIR .. "/request.txt", table.concat(res.cmd, " "), false)
end
DB.data.current_request = res
DB.update().current_request = res
-- Save this to global,
-- so .replay() can be triggered from any buffer or window
DB.global_update().replay = res
return res
end

Expand Down
7 changes: 4 additions & 3 deletions lua/kulala/parser/request_variables.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ local function get_config_contenttype(headers)
end

local function get_body_value_from_path(name, method, subpath)
local base_table = DB.data.env[name]
local base_table = DB.find_unique("env")[name]
if not base_table then
return nil
end
Expand Down Expand Up @@ -80,7 +80,7 @@ local function get_body_value_from_path(name, method, subpath)
end

local function get_header_value_from_path(name, method, subpath)
local base_table = DB.data.env[name]
local base_table = DB.find_unique("env")[name]
if not base_table then
return nil
end
Expand Down Expand Up @@ -110,7 +110,8 @@ local function get_header_value_from_path(name, method, subpath)
end

local function get_cookies_value_from_path(name, subpath)
local base_table = DB.data.env[name]
local db_env = DB.find_unique("env")
local base_table = db_env and db_env[name] or nil
if not base_table then
return nil
end
Expand Down
2 changes: 1 addition & 1 deletion lua/kulala/ui/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ M.show_script_output = function()
end

M.replay = function()
local result = DB.data.current_request
local result = DB.global_find_unique("replay")
if result == nil then
vim.notify("No request to replay", vim.log.levels.WARN, { title = "kulala" })
return
Expand Down
5 changes: 3 additions & 2 deletions lua/kulala/ui/selector.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ local FS = require("kulala.utils.fs")
local M = {}

function M.select_env()
if not DB.data.http_client_env then
local http_client_env = DB.find_unique("http_client_env")
if not http_client_env then
return
end

local envs = {}
for key, _ in pairs(DB.data.http_client_env) do
for key, _ in pairs(http_client_env) do
table.insert(envs, key)
end

Expand Down
7 changes: 4 additions & 3 deletions lua/telescope/_extensions/kulala.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ local function kulala_search(_)
end

local function kulala_env_select(_)
if not DB.data.http_client_env then
local http_client_env = DB.find_unique("http_client_env")
if not http_client_env then
return
end

local envs = {}
for key, _ in pairs(DB.data.http_client_env) do
for key, _ in pairs(http_client_env) do
table.insert(envs, key)
end

Expand All @@ -74,7 +75,7 @@ local function kulala_env_select(_)
previewer = previewers.new_buffer_previewer({
title = "Environment",
define_preview = function(self, entry)
local env = DB.data.http_client_env[entry.value]
local env = http_client_env[entry.value]
if env == nil then
return
end
Expand Down
24 changes: 24 additions & 0 deletions tests/db/db_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
local DB = require("kulala.db")

describe("db scoped", function()
it("should not leak into other buffers", function()
vim.cmd("new")
local buf1 = vim.api.nvim_get_current_buf()
DB.update().key1 = "value1"
assert.equal(DB.find_unique("key1"), "value1")

vim.cmd("new")
local buf2 = vim.api.nvim_get_current_buf()
DB.update().key2 = "value2"
assert.equal(DB.find_unique("key1"), nil)
assert.equal(DB.find_unique("key2"), "value2")

vim.api.nvim_set_current_buf(buf1)
assert.equal(DB.find_unique("key1"), "value1")
assert.equal(DB.find_unique("key2"), nil)

vim.api.nvim_set_current_buf(buf2)
assert.equal(DB.find_unique("key1"), nil)
assert.equal(DB.find_unique("key2"), "value2")
end)
end)

0 comments on commit e01f764

Please sign in to comment.