Skip to content

Commit 8fa3776

Browse files
authored
Weekly updates (#659)
* feat(lsp): allow LSP in js buffers to complete request/response/client * feat(cmd): add `before_request` hook * fix(oauth): show error if Auth key is not found * feat(ui): add highlight opts for status icons * fix(bug_report): schedule in fast event * fix(async): error reporting * feat(cmd): add `# @env-stdin-cmd-pre` and `# @stdin-cmd-pre` * fix(parser): allow spaces in Authorization header * feat(cmd): add # #delay to delay request execution ---------
1 parent 1695bdf commit 8fa3776

File tree

23 files changed

+202
-50
lines changed

23 files changed

+202
-50
lines changed

NEWS.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Version 5.3.3
44

5+
### Feature: add `# @delay` to delay request execution
6+
### Feature: add `# @env-stdin-cmd-pre` and `# @stdin-cmd-pre` to run shell commands before requests
7+
### Feature: support Kulala LSP auto completion in external scripts
58
### Feature: support variables in redirect response path
69
### Feature: do not display big responses + `max_response_size` config option
710
### Feature: format json response on redirect
@@ -19,7 +22,7 @@
1922
### Feature: support `kulala_http` parser in markdown code blocks
2023
### Enhancement: update syntax highlighting for `kulala_http` parser
2124
### Enhancement: add sorting options to [Formatter](getting-started/configuration-options.mdx)
22-
### Enhancement: allow variables in curl and grpc flags
25+
### Enhancement: allow variables in Curl and GRPC flags
2326
### Feature: add LSP diagnostics
2427

2528
## Version 5.3.1

docs/docs/getting-started/configuration-options.mdx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,17 @@ Format json response when redirecting to file
454454

455455
Default: `true`
456456

457+
### before_request
458+
459+
Enable/disable/customize before_request hook. Default hook is request highlight.
460+
461+
```lua
462+
{
463+
opts = {
464+
before_request = true, ---@type boolean|fun(request: DocumentRequest):boolean - return true to continue request execution, false to stop
465+
}
466+
}
467+
```
457468
## Scripts
458469

459470
### scripts.node_path_resolver
@@ -926,15 +937,19 @@ pickers = {
926937

927938
### lsp.enable
928939

929-
Enable/disable Kulala LSP server.
940+
Enable/disable Kulala LSP server
941+
942+
### lsp.filetypes
943+
944+
Filetypes to attach Kulala LSP to
930945

931946
### lsp.keymaps
932947

933948
Enable/disable/customize Kulala LSP keymaps
934949

935950
### lsp.formatter
936951

937-
Enable/disable/customize HTTP formatter.
952+
Enable/disable/customize HTTP formatter
938953

939954
### lsp.on_attach
940955

@@ -944,6 +959,7 @@ Function called when Kulala LSP attaches to the buffer
944959
{
945960
lsp = {
946961
enable = true,
962+
filetypes = { "http", "rest", "json", "yaml", "bruno" },
947963
keymaps = false, -- disabled by default, as Kulala relies on default Neovim LSP keymaps
948964
formatter = {
949965
sort = { -- enable/disable alphabetical sorting

docs/docs/scripts/overview.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ Mixing inline Lua scripts with JavaScript scripts in the same request is not sup
6060

6161
:::
6262

63+
### LSP support for auto completion
64+
65+
For external scripts, you can use the `kulala` LSP to get auto completion for the `client`, `request`, `response`, `test` and `assert` objects.
66+
67+
To do this, add `javascript`/`lua` to `lsp.filetypes` in your [Configuration options](../getting-started/configuration-options.mdx):
68+
69+
```lua
70+
{
71+
opts = {
72+
lsp = {
73+
filetypes = { "http", "rest", "json", "yaml", "bruno", "javascript" }
74+
},
75+
},
76+
}
77+
```
78+
6379
### Using node modules
6480

6581
You can use any Node.js module in your scripts.

docs/docs/usage/basic-usage.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Kulala includes a built-in in-process LSP server that provides the following fea
5757
- Hover information for requests: equivalent to Kulala's inspect command - `K`.
5858
- Code actions: a list of all available Kulala commands - `gra/<leader>ca`.
5959
- Formatting: format buffer/range - `gq/<leader>cf/<leader>lf`.
60+
- Folding
6061
6162
- In `json/yaml/bruno` files, code actions will be available to convert collections into HTTP format.
6263
@@ -101,14 +102,17 @@ require("nvim-lightbulb").setup({
101102
- `# @accept chunked` allows you to accept Transfer-Encoding: chunked responses and streamed responses.
102103
- `# @curl-global-...` and `# @curl-...` allows you to set global and per-request flags for curl requests.
103104
- `# @grpc-global-...` and `# @grpc-...` allows you to set global and per-request flags for gRPC requests.
105+
- `# @stdin-cmd-pre` allows you to execute an external command before the request is sent.
104106
- `# @stdin-cmd` allows you to execute an external command
105107
- `# @jq` allows you to filter the response body using jq.
108+
- `# @delay` allows you to set a delay (in milliseconds) before sending the request.
106109
107110
#### Variables
108111
109112
- `@variable-name=variable-value` is used to define variables that can be used in request URL, headers and body.
110113
- `{{variable}}` allows you to use variables defined in `metadata`, `system environment` variables, `http-client.env.json` file or `.env` file.
111114
- `{{$dynamic-variable}}` allows you to use predefined dynamic, aka `magic` variables.
115+
- `# @env-stdin-cmd-pre` allows you to set environment variables using an external command, before the request is sent.
112116
- `# @env-stdin-cmd` allows you to set environment variables using an external command.
113117
- `# @env-json-key` allows you to set environment variables using a JSON path on the response body.
114118
- `# @env-header-key` allows you to set environment variables from the response headers.

docs/docs/usage/dynamically-setting-environment-variables-based-on-response-json.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ Authorization: Bearer {{REQUEST_ONE.response.body.$.json.token}}
3838

3939
## With external command
4040

41-
If the response is a *complex* JSON object,
42-
you can use the `@env-stdin-cmd` directive to
41+
If the response is a *complex* JSON object, you can use the `@env-stdin-cmd` directive to
4342
set environment variables using an external command (e.g., `jq`).
4443

44+
Response is passed to the command via standard input (stdin) and the result is assigned to a variable,
45+
which can be used in subsequent requests.
46+
4547
JSON Web Tokens (JWT) are a common example where the response JSON is complex.
4648

4749
In this example `jq` is used to extract the `ctx` string from a JWT token.

lua/kulala/cmd/init.lua

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,35 @@ local function received_unbffured(request, response)
303303
return unbuffered and response:find("Connected") and FS.file_exists(GLOBALS.BODY_FILE)
304304
end
305305

306-
local function parse_request(requests, request, variables)
306+
local function process_pre_request_commands(request)
307307
if not process_prompt_vars(request) then
308308
return Logger.warn("Prompt failed. Skipping this and all following requests.")
309309
end
310310

311+
local int_meta_processors = {
312+
["delay"] = "delay",
313+
}
314+
315+
local ext_meta_processors = {
316+
["stdin-cmd-pre"] = "stdin_cmd",
317+
["env-stdin-cmd-pre"] = "env_stdin_cmd",
318+
}
319+
320+
local processor
321+
for _, metadata in ipairs(request.metadata) do
322+
processor = int_meta_processors[metadata.name]
323+
_ = processor and INT_PROCESSING[processor](metadata.value, response)
324+
end
325+
326+
for _, metadata in ipairs(request.metadata) do
327+
processor = ext_meta_processors[metadata.name]
328+
_ = processor and EXT_PROCESSING[processor](metadata.value, response)
329+
end
330+
end
331+
332+
local function parse_request(requests, request, variables)
333+
process_pre_request_commands(request)
334+
311335
local parsed_request, status = REQUEST_PARSER.parse(requests, variables, request)
312336
if not parsed_request then
313337
status = status == "skipped" and "is skipped" or "could not be parsed"
@@ -386,6 +410,20 @@ function process_request(requests, request, variables, callback)
386410
end)
387411
end
388412

413+
---@param request DocumentRequest
414+
---@return boolean
415+
local function execute_before_request(request)
416+
local before_request = CONFIG.get().before_request
417+
if not before_request then return true end
418+
419+
if type(before_request) == "function" then
420+
return before_request(request)
421+
else
422+
UI_utils.highlight_request(request)
423+
return true
424+
end
425+
end
426+
389427
---Parses and executes DocumentRequest/s:
390428
---if requests is nil then it parses the current document
391429
---if line_nr is nil then runs the first request in the list
@@ -411,9 +449,10 @@ M.run_parser = function(requests, variables, line_nr, callback)
411449
INLAY.show(DB.current_buffer, "loading", request.show_icon_line_number)
412450

413451
M.queue:add(function()
414-
UI_utils.highlight_request(request)
415-
initialize()
416-
process_request(requests, request, variables, callback)
452+
if execute_before_request(request) then
453+
initialize()
454+
process_request(requests, request, variables, callback)
455+
end
417456
end)
418457
end
419458

lua/kulala/cmd/lsp.lua

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ local function source_type(params)
414414
{ ">", "snippets" },
415415
}
416416

417+
if state.current_ft == "javascript" then return { "scripts" } end
418+
417419
for _, match in ipairs(matches) do
418420
if line:match(match[1]) then return match[2] end
419421
end
@@ -663,19 +665,13 @@ end
663665

664666
local function initialize(params)
665667
local ft = params.rootPath:sub(2)
666-
local server_info = {
667-
name = "Kulala LSP",
668-
version = Globals.VERSION,
669-
}
670-
if ft ~= "http" and ft ~= "rest" then
671-
return {
672-
serverInfo = server_info,
673-
capabilities = { codeActionProvider = true },
674-
}
675-
end
668+
local capabilities
676669

677-
return {
678-
serverInfo = server_info,
670+
if ft == "javascript" then
671+
capabilities = { completionProvider = { triggerCharacters = trigger_chars } }
672+
elseif ft ~= "http" and ft ~= "rest" then
673+
capabilities = { codeActionProvider = true }
674+
else
679675
capabilities = {
680676
codeActionProvider = true,
681677
documentSymbolProvider = true,
@@ -687,7 +683,12 @@ local function initialize(params)
687683
dynamicRegistration = false,
688684
lineFoldingOnly = true,
689685
},
690-
},
686+
}
687+
end
688+
689+
return {
690+
server_info = { name = "Kulala LSP", version = Globals.VERSION },
691+
capabilities = capabilities,
691692
}
692693
end
693694

lua/kulala/cmd/lsp_sources.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,13 @@ M.metadata = {
314314
{ "grpc", "grpc", "Grpc flag" },
315315
{ "grpc-global", "Grpc-global", "Grpc global flag" },
316316
{ "accept", "accept chunked", "Accept chunked responses" },
317+
{ "env-stdin-cmd-pre", "env-stdin-cmd-pre ", "Set env variable with external cmd before request" },
317318
{ "env-stdin-cmd", "env-stdin-cmd ", "Set env variable with external cmd" },
318319
{ "env-json-key", "env-json-key ", "Set env variable with json key" },
319-
{ "stdin-cmd", "env-stdin-cmd ", "Run external command" },
320+
{ "stdin-cmd-pre", "stdin-cmd-pre ", "Run external command before request" },
321+
{ "stdin-cmd", "stdin-cmd ", "Run external command" },
320322
{ "jq", "jq ", "Filter response body with jq" },
323+
{ "delay", "delay ", "Delay running request for .. ms" },
321324
}
322325

323326
---@type SourceTable

lua/kulala/cmd/oauth.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,8 @@ end
627627
---Grant Type - all
628628
---Entry point to get the token for the given config_id
629629
M.get_token = function(type, config_id)
630+
if not config_id then return Logger.error("Auth config key not found.") end
631+
630632
local config = get_auth_config(config_id)
631633

632634
local token_type = (type == "idToken" or config["Use ID Token"]) and "id_token" or "access_token"

lua/kulala/config/defaults.lua

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,11 @@ local M = {
6767
-- format json response when redirecting to file
6868
format_json_on_redirect = true,
6969

70+
-- enable/disable/customize before_request hook. Default hook is request highlight.
71+
before_request = true, ---@type boolean|fun(request: DocumentRequest):boolean - return true to continue request execution, false to stop
72+
7073
scripts = {
71-
-- Resolves "NODE_PATH" environment variable for node scripts. Defaults to the first "node_modules" directory found upwards from "script_file_dir".
74+
-- resolves "NODE_PATH" environment variable for node scripts. Defaults to the first "node_modules" directory found upwards from "script_file_dir".
7275
node_path_resolver = nil, ---@type fun(http_file_dir: string, script_file_dir: string, script_data: ScriptData): string|nil
7376
},
7477

@@ -101,6 +104,9 @@ local M = {
101104
},
102105
lualine = "🐼",
103106
textHighlight = "WarningMsg", -- highlight group for request elapsed time
107+
loadingHighlight = "Normal",
108+
doneHighlight = "String",
109+
errorHighlight = "ErrorMsg",
104110
},
105111

106112
-- highlight groups for http syntax highlighting
@@ -178,6 +184,9 @@ local M = {
178184
-- enable/disable built-in LSP server
179185
enable = true,
180186

187+
-- filetypes to attach Kulala LSP to
188+
filetypes = { "http", "rest", "json", "yaml", "bruno" },
189+
181190
--enable/disable/customize LSP keymaps
182191
---@type boolean|table
183192
keymaps = false, -- disabled by default, as Kulala relies on default Neovim LSP keymaps

0 commit comments

Comments
 (0)