Repository: nvim-lua/plenary.nvim
Pull request #527 (2023-09-18 23:17:26)

feat(curl): change request option compressed if using Windows
I was using a plugin called [rest-nvim](https://github.com/rest-nvim/rest.nvim) in Mac, Linux and WSL, but when I tried to use it on Windows, as the curl is a little different, it failed.

![curl_not_working_on_windows](https://github.com/nvim-lua/plenary.nvim/assets/71392160/b9d0f778-dc9c-45a9-9aa0-79c1d13502a1)

As you can see, plenary's curl failed because of the compressed option. After aplying the change on the commit, it works perfectly.

As @tjdevries was one of my inspirations of using NeoVim and trying to explore more the open source world. This is my first PR, so any tips for improving would be nice and well recieved.


Patch:
diff --git a/data/plenary/filetypes/builtin.lua b/data/plenary/filetypes/builtin.lua
index 22b5138..c4b6d50 100644
--- a/data/plenary/filetypes/builtin.lua
+++ b/data/plenary/filetypes/builtin.lua
@@ -36,6 +36,8 @@ return {
     ['graphql'] = 'graphql',
     ['hbs'] = 'handlebars',
     ['hdbs'] = 'handlebars',
+    ['hlsl'] = 'hlsl',
+    ['jai'] = 'jai',
     ['janet'] = 'janet',
     ['jl'] = 'julia',
     ['jsx'] = 'javascriptreact',
diff --git a/lua/plenary/async/api.lua b/lua/plenary/async/api.lua
index 74f1895..2a4e9c0 100644
--- a/lua/plenary/async/api.lua
+++ b/lua/plenary/async/api.lua
@@ -8,7 +8,7 @@ return setmetatable({}, {
         util.scheduler()
       end
 
-      vim.api[k](...)
+      return vim.api[k](...)
     end
   end,
 })
diff --git a/lua/plenary/async/util.lua b/lua/plenary/async/util.lua
index 10b69a2..c689ba3 100644
--- a/lua/plenary/async/util.lua
+++ b/lua/plenary/async/util.lua
@@ -22,7 +22,8 @@ M.sleep = a.wrap(defer_swapped, 2)
 M.block_on = function(async_function, timeout)
   async_function = M.protected(async_function)
 
-  local stat, ret
+  local stat
+  local ret = {}
 
   a.run(async_function, function(stat_, ...)
     stat = stat_
@@ -75,14 +76,14 @@ M.join = function(async_fns)
   return results
 end
 
----Returns a future that when run will select the first async_function that finishes
----@param async_funs table: The async_function that you want to select
+---Returns a result from the future that finishes at the first
+---@param async_functions table: The futures that you want to select
 ---@return ...
-M.run_first = a.wrap(function(async_funs, step)
+M.run_first = a.wrap(function(async_functions, step)
   local ran = false
 
-  for _, future in ipairs(async_funs) do
-    assert(type(future) == "function", "type error :: future must be function")
+  for _, async_function in ipairs(async_functions) do
+    assert(type(async_function) == "function", "type error :: future must be function")
 
     local callback = function(...)
       if not ran then
@@ -91,10 +92,22 @@ M.run_first = a.wrap(function(async_funs, step)
       end
     end
 
-    future(callback)
+    async_function(callback)
   end
 end, 2)
 
+---Returns a result from the functions that finishes at the first
+---@param funcs table: The async functions that you want to select
+---@return ...
+M.race = function(funcs)
+  local async_functions = vim.tbl_map(function(func)
+    return function(callback)
+      a.run(func, callback)
+    end
+  end, funcs)
+  return M.run_first(async_functions)
+end
+
 M.run_all = function(async_fns, callback)
   a.run(function()
     M.join(async_fns)
diff --git a/lua/plenary/curl.lua b/lua/plenary/curl.lua
index 6ec5add..0086dca 100644
--- a/lua/plenary/curl.lua
+++ b/lua/plenary/curl.lua
@@ -3,15 +3,16 @@ Curl Wrapper
 
 all curl methods accepts
 
-  url     = "The url to make the request to.", (string)
-  query   = "url query, append after the url", (table)
-  body    = "The request body" (string/filepath/table)
-  auth    = "Basic request auth, 'user:pass', or {"user", "pass"}" (string/array)
-  form    = "request form" (table)
-  raw     = "any additonal curl args, it must be an array/list." (array)
-  dry_run = "whether to return the args to be ran through curl." (boolean)
-  output  = "where to download something." (filepath)
-  timeout = "request timeout in mseconds" (number)
+  url          = "The url to make the request to.", (string)
+  query        = "url query, append after the url", (table)
+  body         = "The request body" (string/filepath/table)
+  auth         = "Basic request auth, 'user:pass', or {"user", "pass"}" (string/array)
+  form         = "request form" (table)
+  raw          = "any additonal curl args, it must be an array/list." (array)
+  dry_run      = "whether to return the args to be ran through curl." (boolean)
+  output       = "where to download something." (filepath)
+  timeout      = "request timeout in mseconds" (number)
+  http_version = "HTTP version to use: 'HTTP/0.9', 'HTTP/1.0', 'HTTP/1.1', 'HTTP/2', or 'HTTP/3'" (string)
 
 and returns table:
 
@@ -179,6 +180,19 @@ parse.accept_header = function(s)
   return { "-H", "Accept: " .. s }
 end
 
+parse.http_version = function(s)
+  if not s then
+    return
+  end
+  if s == "HTTP/0.9" or s == "HTTP/1.0" or s == "HTTP/1.1" or s == "HTTP/2" or s == "HTTP/3" then
+    s = s:lower()
+    s = s:gsub("/", "")
+    return { "--" .. s }
+  else
+    error "Unknown HTTP version."
+  end
+end
+
 -- Parse Request -------------------------------------------
 ------------------------------------------------------------
 parse.request = function(opts)
@@ -215,6 +229,7 @@ parse.request = function(opts)
   append(parse.form(opts.form))
   append(parse.file(opts.in_file))
   append(parse.auth(opts.auth))
+  append(parse.http_version(opts.http_version))
   append(opts.raw)
   if opts.output then
     table.insert(result, { "-o", opts.output })
@@ -244,7 +259,7 @@ end
 local request = function(specs)
   local response = {}
   local args, opts = parse.request(vim.tbl_extend("force", {
-    compressed = true,
+    compressed = package.config:sub(1, 1) ~= "\\",
     dry_run = false,
     dump = util.gen_dump_path(),
   }, specs))
diff --git a/lua/plenary/log.lua b/lua/plenary/log.lua
index f22f954..7ef0941 100644
--- a/lua/plenary/log.lua
+++ b/lua/plenary/log.lua
@@ -79,8 +79,10 @@ local unpack = unpack or table.unpack
 log.new = function(config, standalone)
   config = vim.tbl_deep_extend("force", default_config, config)
 
-  local outfile =
-    vim.F.if_nil(config.outfile, Path:new(vim.api.nvim_call_function("stdpath", { "cache" }), config.plugin).filename)
+  local outfile = vim.F.if_nil(
+    config.outfile,
+    Path:new(vim.api.nvim_call_function("stdpath", { "cache" }), config.plugin .. ".log").filename
+  )
 
   local obj
   if standalone then


Test patch:
diff --git a/tests/plenary/async/util_spec.lua b/tests/plenary/async/util_spec.lua
index 480f860..94ae324 100644
--- a/tests/plenary/async/util_spec.lua
+++ b/tests/plenary/async/util_spec.lua
@@ -47,4 +47,31 @@ describe("async await util", function()
       eq(ret, "didnt fail")
     end)
   end)
+
+  local function sleep(msec)
+    return function()
+      a.util.sleep(msec)
+      return msec
+    end
+  end
+
+  describe("race", function()
+    a.it("should return the first result", function()
+      local funcs = vim.tbl_map(sleep, { 300, 400, 100, 200 })
+      local result = a.util.race(funcs)
+      eq(result, 100)
+    end)
+  end)
+
+  describe("run_first", function()
+    a.it("should return the first result", function()
+      local async_functions = vim.tbl_map(function(num)
+        return function(callback)
+          return a.run(sleep(num), callback)
+        end
+      end, { 300, 400, 100, 200 })
+      local result = a.util.run_first(async_functions)
+      eq(result, 100)
+    end)
+  end)
 end)