mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	 7cd5356a6f
			
		
	
	7cd5356a6f
	
	
	
		
			
			Problem:
Nvim depends on netrw to download/request URL contents.
Solution:
- Add `vim.net.request()` as a thin curl wrapper:
  - Basic GET with --silent, --show-error, --fail, --location, --retry
  - Optional `opts.outpath` to save to a file
  - Operates asynchronously. Pass an `on_response` handler to get the result.
- Add integ tests (requires NVIM_TEST_INTEG to be set) to test success
  and 404 failure.
- Health check for missing `curl`.
- Handle `:edit https://…` using `vim.net.request()`.
API Usage:
1. Asynchronous request:
    vim.net.request('https://httpbingo.org/get', { retry = 2 }, function(err, response)
      if err then
        print('Fetch failed:', err)
      else
        print('Got body of length:', #response.body)
      end
    end)
2. Download to file:
    vim.net.request('https://httpbingo.org/get', { outpath = 'out_async.txt' }, function(err)
      if err then print('Error:', err) end
    end)
3. Remote :edit integration (in runtime/plugin/net.lua) fetches into buffer:
    :edit https://httpbingo.org/get
		
	
		
			
				
	
	
		
			64 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local M = {}
 | |
| 
 | |
| --- Makes an HTTP GET request to the given URL (asynchronous).
 | |
| ---
 | |
| --- This function operates in one mode:
 | |
| ---   - Asynchronous (non-blocking): Returns immediately and passes the response object to the
 | |
| ---   provided `on_response` handler on completetion.
 | |
| ---
 | |
| --- @param url string The URL for the request.
 | |
| --- @param opts? table Optional parameters:
 | |
| ---   - `verbose` (boolean|nil): Enables verbose output.
 | |
| ---   - `retry`   (integer|nil): Number of retries on transient failures (default: 3).
 | |
| ---   - `outpath`  (string|nil): File path to save the response body to. If set, the `body` value in the Response Object will be `true` instead of the response body.
 | |
| --- @param on_response fun(err?: string, response?: { body: string|boolean }) Callback invoked on request
 | |
| --- completetion. The `body` field in the response object contains the raw response data (text or binary).
 | |
| --- Called with (err, nil) on failure, or (nil, { body = string|boolean }) on success.
 | |
| function M.request(url, opts, on_response)
 | |
|   vim.validate({
 | |
|     url = { url, 'string' },
 | |
|     opts = { opts, 'table', true },
 | |
|     on_response = { on_response, 'function' },
 | |
|   })
 | |
| 
 | |
|   opts = opts or {}
 | |
|   local retry = opts.retry or 3
 | |
| 
 | |
|   -- Build curl command
 | |
|   local args = { 'curl' }
 | |
|   if opts.verbose then
 | |
|     table.insert(args, '--verbose')
 | |
|   else
 | |
|     vim.list_extend(args, { '--silent', '--show-error', '--fail' })
 | |
|   end
 | |
|   vim.list_extend(args, { '--location', '--retry', tostring(retry) })
 | |
| 
 | |
|   if opts.outpath then
 | |
|     vim.list_extend(args, { '--output', opts.outpath })
 | |
|   end
 | |
| 
 | |
|   table.insert(args, url)
 | |
| 
 | |
|   local function on_exit(res)
 | |
|     local err_msg = nil
 | |
|     local response = nil
 | |
| 
 | |
|     if res.code ~= 0 then
 | |
|       err_msg = (res.stderr ~= '' and res.stderr)
 | |
|         or string.format('Request failed with exit code %d', res.code)
 | |
|     else
 | |
|       response = {
 | |
|         body = opts.outpath and true or res.stdout,
 | |
|       }
 | |
|     end
 | |
| 
 | |
|     if on_response then
 | |
|       on_response(err_msg, response)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   vim.system(args, {}, on_exit)
 | |
| end
 | |
| 
 | |
| return M
 |