Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nextls command not found when installing with Nix #283

Merged
merged 3 commits into from
Oct 16, 2023

Conversation

goofansu
Copy link
Contributor

@goofansu goofansu commented Oct 10, 2023

Solve #278.

  • Rename burrito_out/next_ls_<system>_<arch> to burrito_out/nextls, which is the command to install.
  • Remove the original bin directory containing the next_ls app that isn't expected to be installed, then rename burrito_out directory to bin.

Try

gh repo clone elixir-tools/next-ls
gh co 283
nix profile install .
nextls --version

CleanShot 2023-10-11 at 01 45 32

It works in Doom Emacs to format a buffer after saving it.
  • config.el
(use-package! elixir-mode
  :hook (before-save . elixir-format-before-save)
  :config
  (defun elixir-format-before-save ()
    (when (derived-mode-p 'elixir-mode)
      (eglot-format-buffer))))
  • Eglot events log
[client-request] (id:9) Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :id 9 :method "textDocument/formatting" :params
          (:textDocument
           (:uri "file:///Users/james/src/req/lib/req.ex")
           :options
           (:tabSize 2 :insertSpaces t :insertFinalNewline t :trimFinalNewlines t)))
[server-reply] (id:9) Wed Oct 11 00:02:12 2023:
(:id 9 :jsonrpc "2.0" :result
     [(:newText "defmodule Req do\n  @moduledoc \"\"\"\n  The high-level API.\n\n  Req is composed of three main pieces:\n\n    * `Req` - the high-level API (you're here!)\n\n    * `Req.Request` - the low-level API and the request struct\n\n    * `Req.Steps` - the collection of built-in steps\n\n  The high-level API is what most users of Req will use most of the time.\n\n  ## Examples\n\n  Making a GET request with `Req.get!/1`:\n\n      iex> Req.get!(\"https://api.github.com/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  Same, but by explicitly building request struct first:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.get!(req, url: \"/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  Making a POST request with `Req.post!/2`:\n\n      iex> Req.post!(\"https://httpbin.org/post\", form: [comments: \"hello!\"]).body[\"form\"]\n      %{\"comments\" => \"hello!\"}\n  \"\"\"\n\n  @type url() :: URI.t() | String.t()\n\n  @doc \"\"\"\n  Returns a new request struct with built-in steps.\n\n  See `request/1` for a list of available options. See `Req.Request` module documentation\n  for more information on the underlying request struct.\n\n  ## Examples\n\n      iex> req = Req.new(url: \"https://elixir-lang.org\")\n      iex> req.method\n      :get\n      iex> URI.to_string(req.url)\n      \"https://elixir-lang.org\"\n\n  \"\"\"\n  @spec new(options :: keyword()) :: Req.Request.t()\n  def new(options \\\\ []) do\n    options = Keyword.merge(default_options(), options)\n    {plugins, options} = Keyword.pop(options, :plugins, [])\n\n    %Req.Request{\n      registered_options:\n        MapSet.new([\n          :user_agent,\n          :compressed,\n          :range,\n          :http_errors,\n          :base_url,\n          :params,\n          :auth,\n          :form,\n          :json,\n          :compress_body,\n          :compressed,\n          :raw,\n          :decode_body,\n          :output,\n          :follow_redirects,\n          :location_trusted,\n          :max_redirects,\n          :retry,\n          :retry_delay,\n          :max_retries,\n          :cache,\n          :cache_dir,\n          :plug,\n          :finch,\n          :finch_request,\n          :connect_options,\n          :receive_timeout,\n          :pool_timeout,\n          :unix_socket\n        ])\n    }\n    |> update(options)\n    |> Req.Request.prepend_request_steps(\n      put_user_agent: &Req.Steps.put_user_agent/1,\n      compressed: &Req.Steps.compressed/1,\n      encode_body: &Req.Steps.encode_body/1,\n      put_base_url: &Req.Steps.put_base_url/1,\n      auth: &Req.Steps.auth/1,\n      put_params: &Req.Steps.put_params/1,\n      put_range: &Req.Steps.put_range/1,\n      cache: &Req.Steps.cache/1,\n      put_plug: &Req.Steps.put_plug/1,\n      compress_body: &Req.Steps.compress_body/1\n    )\n    |> Req.Request.prepend_response_steps(\n      retry: &Req.Steps.retry/1,\n      follow_redirects: &Req.Steps.follow_redirects/1,\n      decompress_body: &Req.Steps.decompress_body/1,\n      decode_body: &Req.Steps.decode_body/1,\n      handle_http_errors: &Req.Steps.handle_http_errors/1,\n      output: &Req.Steps.output/1\n    )\n    |> Req.Request.prepend_error_steps(retry: &Req.Steps.retry/1)\n    |> run_plugins(plugins)\n  end\n\n  @doc \"\"\"\n  Updates a request struct.\n\n  See `request/1` for a list of available options. See `Req.Request` module documentation\n  for more information on the underlying request struct.\n\n  ## Examples\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> req = Req.update(req, auth: {\"alice\", \"secret\"})\n      iex> req.options\n      %{auth: {\"alice\", \"secret\"}, base_url: \"https://httpbin.org\"}\n\n  Passing `:headers` will automatically encode and merge them:\n\n      iex> req = Req.new(headers: [point_x: 1])\n      iex> req = Req.update(req, headers: [point_y: 2])\n      iex> req.headers\n      [{\"point-x\", \"1\"}, {\"point-y\", \"2\"}]\n\n  \"\"\"\n  @spec update(Req.Request.t(), options :: keyword()) :: Req.Request.t()\n  def update(%Req.Request{} = request, options) when is_list(options) do\n    request_option_names = [:method, :url, :headers, :body, :adapter]\n\n    {request_options, options} = Keyword.split(options, request_option_names)\n\n    registered =\n      MapSet.union(\n        request.registered_options,\n        MapSet.new(request_option_names)\n      )\n\n    Req.Request.validate_options(options, registered)\n\n    request_options =\n      if request_options[:headers] do\n        update_in(request_options[:headers], &encode_headers/1)\n      else\n        request_options\n      end\n\n    request =\n      Map.merge(request, Map.new(request_options), fn\n        :url, _, url ->\n          URI.parse(url)\n\n        :headers, old, new ->\n          old ++ new\n\n        _, _, value ->\n          value\n      end)\n\n    request = update_in(request.options, &Map.merge(&1, Map.new(options)))\n\n    if request.options[:output] do\n      update_in(request.options, &Map.put(&1, :decode_body, false))\n    else\n      request\n    end\n  end\n\n  @doc \"\"\"\n  Makes a GET request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.get!(\"https://api.github.com/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.get!(req, url: \"/repos/elixir-lang/elixir\").status\n      200\n\n  \"\"\"\n  @spec get!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def get!(url_or_request, options \\\\ []) do\n    case get(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a GET request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.get(\"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> res.body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> {:ok, res} = Req.get(req, url: \"/repos/elixir-lang/elixir\")\n      iex> res.status\n      200\n\n  \"\"\"\n  @spec get(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def get(url_or_request, options \\\\ [])\n\n  def get(%Req.Request{} = request, options) do\n    request(%{request | method: :get}, options)\n  end\n\n  def get(url, options) do\n    request([method: :get, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a HEAD request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.head!(\"https://httpbin.org/status/201\").status\n      201\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> Req.head!(req, url: \"/status/201\").status\n      201\n\n  \"\"\"\n  @spec head!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def head!(url_or_request, options \\\\ []) do\n    case head(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a HEAD request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.head(\"https://httpbin.org/status/201\")\n      iex> res.status\n      201\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> {:ok, res} = Req.head(req, url: \"/status/201\")\n      iex> res.status\n      201\n\n  \"\"\"\n  @spec head(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def head(url_or_request, options \\\\ [])\n\n  def head(%Req.Request{} = request, options) do\n    request(%{request | method: :head}, options)\n  end\n\n  def head(url, options) do\n    request([method: :head, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a POST request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.post!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n      iex> Req.post!(\"https://httpbin.org/anything\", form: [x: 1]).body[\"form\"]\n      %{\"x\" => \"1\"}\n\n      iex> Req.post!(\"https://httpbin.org/anything\", json: %{x: 2}).body[\"json\"]\n      %{\"x\" => 2}\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.post!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec post!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def post!(url_or_request, options \\\\ []) do\n    if Keyword.keyword?(options) do\n      case post(url_or_request, options) do\n        {:ok, response} -> response\n        {:error, exception} -> raise exception\n      end\n    else\n      case options do\n        {:form, data} ->\n          IO.warn(\n            \"Req.post!(url, {:form, data}) is deprecated in favour of \" <>\n              \"Req.post!(url, form: data)\"\n          )\n\n          request!(method: :post, url: URI.parse(url_or_request), form: data)\n\n        {:json, data} ->\n          IO.warn(\n            \"Req.post!(url, {:json, data}) is deprecated in favour of \" <>\n              \"Req.post!(url, json: data)\"\n          )\n\n          request!(method: :post, url: URI.parse(url_or_request), json: data)\n\n        data ->\n          IO.warn(\"Req.post!(url, body) is deprecated in favour of Req.post!(url, body: body)\")\n          request!(method: :post, url: URI.parse(url_or_request), body: data)\n      end\n    end\n  end\n\n  @doc false\n  def post!(url, body, options) do\n    case body do\n      {:form, data} ->\n        IO.warn(\n          \"Req.post!(url, {:form, data}, options) is deprecated in favour of \" <>\n            \"Req.post!(url, [form: data] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), form: data] ++ options)\n\n      {:json, data} ->\n        IO.warn(\n          \"Req.post!(url, {:json, data}) is deprecated in favour of \" <>\n            \"Req.post!(url, [json: data] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), json: data] ++ options)\n\n      data ->\n        IO.warn(\n          \"Req.post!(url, body) is deprecated in favour of \" <>\n            \"Req.post!(url, [body: body] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), body: data] ++ options)\n    end\n  end\n\n  @doc \"\"\"\n  Makes a POST request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", form: [x: 1])\n      iex> res.body[\"form\"]\n      %{\"x\" => \"1\"}\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", json: %{x: 2})\n      iex> res.body[\"json\"]\n      %{\"x\" => 2}\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.post(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec post(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def post(url_or_request, options \\\\ [])\n\n  def post(%Req.Request{} = request, options) do\n    request(%{request | method: :post}, options)\n  end\n\n  def post(url, options) do\n    request([method: :post, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a PUT request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.put!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.put!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec put!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def put!(url_or_request, options \\\\ []) do\n    case put(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc false\n  def put!(%URI{} = url, {type, _} = body, options) when type in [:form, :json] do\n    IO.warn(\n      \"Req.put!(url, {:#{type}, #{type}}, options) is deprecated in favour of \" <>\n        \"Req.put!(url, [#{type}: #{type}] ++ options)\"\n    )\n\n    request!([method: :put, url: url, body: body] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a PUT request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.put(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.put(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec put(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def put(url_or_request, options \\\\ [])\n\n  def put(%Req.Request{} = request, options) do\n    request(%{request | method: :put}, options)\n  end\n\n  def put(url, options) do\n    if Keyword.keyword?(options) do\n      request([method: :put, url: URI.parse(url)] ++ options)\n    else\n      IO.warn(\"Req.put!(url, body) is deprecated in favour of Req.put!(url, body: body)\")\n      request(url: URI.parse(url), body: options)\n    end\n  end\n\n  @doc \"\"\"\n  Makes a PATCH request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.patch!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.patch!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec patch!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def patch!(url_or_request, options \\\\ []) do\n    case patch(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a PATCH request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.patch(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.patch(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec patch(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def patch(url_or_request, options \\\\ [])\n\n  def patch(%Req.Request{} = request, options) do\n    request(%{request | method: :patch}, options)\n  end\n\n  def patch(url, options) do\n    request([method: :patch, url: url] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a DELETE request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.delete!(\"https://httpbin.org/anything\").body[\"method\"]\n      \"DELETE\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.delete!(req).body[\"method\"]\n      \"DELETE\"\n  \"\"\"\n  @spec delete!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def delete!(url_or_request, options \\\\ []) do\n    case delete(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a DELETE request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.delete(\"https://httpbin.org/anything\")\n      iex> res.body[\"method\"]\n      \"DELETE\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.delete(req)\n      iex> res.body[\"method\"]\n      \"DELETE\"\n  \"\"\"\n  @spec delete(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def delete(url_or_request, options \\\\ [])\n\n  def delete(%Req.Request{} = request, options) do\n    request(%{request | method: :delete}, options)\n  end\n\n  def delete(url, options) do\n    request([method: :delete, url: url] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request.\n\n  `request/1` and `request/2` functions give three ways of making requests:\n\n    1. With a list of options, for example:\n\n       ```\n       iex> Req.request(url: url)\n       ```\n\n    2. With a request struct, for example:\n\n       ```\n       iex> Req.new(url: url) |> Req.request()\n       ```\n\n    3. With a request struct and more options, for example:\n\n       ```\n       iex> Req.new(base_url: base_url) |> Req.request(url: url)\n       ```\n\n  This function as well as all the other ones in this module accept the same set of options described below.\n\n  ## Options\n\n  Basic request options:\n\n    * `:method` - the request method, defaults to `:get`.\n\n    * `:url` - the request URL.\n\n    * `:headers` - the request headers.\n\n      The headers are automatically encoded using these rules:\n\n        * atom header names are turned into strings, replacing `_` with `-`. For example,\n          `:user_agent` becomes `\"user-agent\"`\n\n        * string header names are left as is. Because header keys are case-insensitive\n          in both HTTP/1.1 and HTTP/2, it is recommended for header keys to be in\n          lowercase, to avoid sending duplicate keys in a request.\n\n        * `NaiveDateTime` and `DateTime` header values are encoded as \"HTTP date\". Otherwise,\n          the header value is encoded with `String.Chars.to_string/1`.\n\n      If you set `:headers` options both in `Req.new/1` and `request/2`, the header lists are merged.\n\n    * `:body` - the request body.\n\n  Additional URL options:\n\n    * `:base_url` - if set, the request URL is prepended with this base URL (via\n      [`put_base_url`](`Req.Steps.put_base_url/1`) step).\n\n    * `:params` - if set, appends parameters to the request query string (via\n      [`put_params`](`Req.Steps.put_params/1`) step).\n\n  Authentication options:\n\n    * `:auth` - sets request authentication (via [`auth`](`Req.Steps.auth/1`) step).\n\n  Request body options:\n\n    * `:form` - if set, encodes the request body as form data ([`encode_body`](`Req.Steps.encode_body/1`) step).\n\n    * `:json` - if set, encodes the request body as JSON ([`encode_body`](`Req.Steps.encode_body/1`) step).\n\n    * `:compress_body` - if set to `true`, compresses the request body using gzip (via [`compress_body`](`Req.Steps.compress_body/1`) step).\n      Defaults to `false`.\n\n  Response body options:\n\n    * `:compressed` - if set to `true`, asks the server to return compressed response.\n      (via [`compressed`](`Req.Steps.compressed/1`) step). Defaults to `true`.\n\n    * `:raw` - if set to `true`, disables automatic body decompression\n      ([`decompress_body`](`Req.Steps.decompress_body/1`) step) and decoding\n      ([`decode_body`](`Req.Steps.decode_body/1`) step). Defaults to `false`.\n\n    * `:decode_body` - if set to `false`, disables automatic response body decoding.\n      Defaults to `true`.\n\n    * `:output` - if set, writes the response body to a file (via\n      [`output`](`Req.Steps.output/1`) step). Can be set to a string path or an atom\n      `:remote_name` which would use the remote name as the filename in the current working\n      directory. Once the file is written, the response body is replaced with `\"\"`.\n\n      Setting `:output` also sets the `decode_body: false` option to prevent decoding the\n      response before writing it to the file.\n\n  Response redirect options ([`follow_redirects`](`Req.Steps.follow_redirects/1`) step):\n\n    * `:follow_redirects` - if set to `false`, disables automatic response redirects. Defaults to `true`.\n\n    * `:location_trusted` - by default, authorization credentials are only sent\n      on redirects with the same host, scheme and port. If `:location_trusted` is set to `true`, credentials\n      will be sent to any host.\n\n    * `:max_redirects` - the maximum number of redirects, defaults to `10`.\n\n  Retry options ([`retry`](`Req.Steps.retry/1`) step):\n\n    * `:retry`: can be set to: `:safe` (default) to only retry GET/HEAD requests on HTTP 408/5xx\n      responses or exceptions, `false` to never retry, and `fun` - a 1-arity function that accepts\n      either a `Req.Response` or an exception struct and returns boolean whether to retry\n\n    * `:retry_delay` - a function that receives the retry count (starting at 0) and returns the delay, the\n      number of milliseconds to sleep before making another attempt.\n      Defaults to a simple exponential backoff: 1s, 2s, 4s, 8s, ...\n\n    * `:max_retries` - maximum number of retry attempts, defaults to `3` (for a total of `4`\n      requests to the server, including the initial one.)\n\n  Caching options ([`cache`](`Req.Steps.cache/1`) step):\n\n    * `:cache` - if `true`, performs HTTP caching. Defaults to `false`.\n\n    * `:cache_dir` - the directory to store the cache, defaults to `<user_cache_dir>/req`\n      (see: `:filename.basedir/3`)\n\n  Request adapters:\n\n    * `:adapter` - adapter to use to make the actual HTTP request. See `:adapter` field description\n      in the `Req.Request` module documentation for more information. Defaults to calling [`run_finch`](`Req.Steps.run_finch/1`).\n\n    * `:plug` - if set, calls the given Plug instead of making an HTTP request over the network (via [`put_plug`](`Req.Steps.put_plug/1`) step).\n\n  Finch options ([`run_finch`](`Req.Steps.run_finch/1`) step)\n\n    * `:finch` - the Finch pool to use. Defaults to pool automatically started by `Req`.\n\n    * `:connect_options` - dynamically starts (or re-uses already started) Finch pool with\n      the given connection options:\n\n        * `:timeout` - socket connect timeout in milliseconds, defaults to `30_000`.\n\n        * `:protocol` - the HTTP protocol to use, defaults to `:http1`.\n\n        * `:hostname` - Mint explicit hostname\n\n        * `:transport_opts` - Mint transport options\n\n        * `:proxy_headers` - Mint proxy headers\n\n        * `:proxy` - Mint HTTP/1 proxy settings, a `{schema, address, port, options}` tuple.\n\n        * `:client_settings` - Mint HTTP/2 client settings\n\n    * `:pool_timeout` - pool checkout timeout in milliseconds, defaults to `5000`.\n\n    * `:receive_timeout` - socket receive timeout in milliseconds, defaults to `15_000`.\n\n    * `:unix_socket` - if set, connect through the given UNIX domain socket\n    \n    * `:finch_request` - a function to modify the built Finch request before execution. This function takes a \n       Finch request and returns a Finch request. If not provided, the finch request will not be modified\n\n  ## Examples\n\n  With options keywords list:\n\n      iex> {:ok, response} = Req.request(url: \"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> response.status\n      200\n      iex> response.body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> {:ok, response} = Req.request(req)\n      iex> response.status\n      200\n\n  With request struct and options:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> {:ok, response} = Req.request(req, url: \"/repos/elixir-lang/elixir\")\n      iex> response.status\n      200\n\n  With mock adapter:\n\n      iex> adapter = fn request ->\n      ...>   response = %Req.Response{status: 200, body: \"it works!\"}\n      ...>   {request, response}\n      ...> end\n      iex>\n      iex> {:ok, response} = Req.request(adapter: adapter, url: \"http://example\")\n      iex> response.body\n      \"it works!\"\n  \"\"\"\n  @spec request(Req.Request.t() | keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def request(request_or_options)\n\n  def request(%Req.Request{} = request) do\n    request(request, [])\n  end\n\n  def request(options) do\n    request(Req.new(options), [])\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request.\n\n  See `request/1` for more information.\n  \"\"\"\n  @spec request(Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def request(request, options) when is_list(options) do\n    {plugins, options} = Keyword.pop(options, :plugins, [])\n\n    request\n    |> Req.update(options)\n    |> run_plugins(plugins)\n    |> Req.Request.run()\n  end\n\n  @doc false\n  def request(method, url, options) do\n    IO.warn(\n      \"Req.request(method, url, options) is deprecated in favour of \" <>\n        \"Req.request!([method: method, url: url] ++ options)\"\n    )\n\n    request([method: method, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request and returns a response or raises an error.\n\n  See `request/1` for more information.\n\n  ## Examples\n\n      iex> Req.request!(url: \"https://api.github.com/repos/elixir-lang/elixir\").status\n      200\n  \"\"\"\n  @spec request!(Req.Request.t() | keyword()) :: Req.Response.t()\n  def request!(request_or_options) do\n    case request(request_or_options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request and returns a response or raises an error.\n\n  See `request/1` for more information.\n\n  ## Examples\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.request!(req, url: \"/repos/elixir-lang/elixir\").status\n      200\n  \"\"\"\n  @spec request!(Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def request!(request, options) do\n    case request(request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Returns default options.\n\n  See `default_options/1` for more information.\n  \"\"\"\n  @spec default_options() :: keyword()\n  def default_options() do\n    Application.get_env(:req, :default_options, [])\n  end\n\n  @doc \"\"\"\n  Sets default options for `Req.new/1`.\n\n  Avoid setting default options in libraries as they are global.\n\n  ## Examples\n\n      iex> Req.default_options(base_url: \"https://httpbin.org\")\n      iex> Req.get!(\"/statuses/201\").status\n      201\n      iex> Req.new() |> Req.get!(url: \"/statuses/201\").status\n      201\n  \"\"\"\n  @spec default_options(keyword()) :: :ok\n  def default_options(options) do\n    Application.put_env(:req, :default_options, options)\n  end\n\n  defp encode_headers(headers) do\n    for {name, value} <- headers do\n      name =\n        case name do\n          atom when is_atom(atom) ->\n            atom |> Atom.to_string() |> String.replace(\"_\", \"-\")\n\n          binary when is_binary(binary) ->\n            binary\n        end\n\n      value =\n        case value do\n          %NaiveDateTime{} = naive_datetime ->\n            Req.Steps.format_http_datetime(naive_datetime)\n\n          %DateTime{} = datetime ->\n            datetime |> DateTime.shift_zone!(\"Etc/UTC\") |> Req.Steps.format_http_datetime()\n\n          _ ->\n            String.Chars.to_string(value)\n        end\n\n      {name, value}\n    end\n  end\n\n  # Plugins support is experimental, undocumented, and likely won't make the new release.\n  defp run_plugins(request, [plugin | rest]) when is_atom(plugin) do\n    if Code.ensure_loaded?(plugin) and function_exported?(plugin, :attach, 1) do\n      run_plugins(plugin.attach(request), rest)\n    else\n      run_plugins(plugin.run(request), rest)\n    end\n  end\n\n  defp run_plugins(request, [plugin | rest]) when is_function(plugin, 1) do\n    run_plugins(plugin.(request), rest)\n  end\n\n  defp run_plugins(request, []) do\n    request\n  end\n\n  @doc false\n  @deprecated \"Manually build Req.Request struct instead\"\n  def build(method, url, options \\\\ []) do\n    %Req.Request{\n      method: method,\n      url: URI.parse(url),\n      headers: Keyword.get(options, :headers, []),\n      body: Keyword.get(options, :body, \"\")\n    }\n  end\nend\n" :range
                (:end
                 (:character 0 :line 962)
                 :start
                 (:character 0 :line 0)))])
[client-notification] Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
          (:textDocument
           (:uri "file:///Users/james/src/req/lib/req.ex" :version 7)
           :contentChanges
           [(:text "defmodule Req do\n  @moduledoc \"\"\"\n  The high-level API.\n\n  Req is composed of three main pieces:\n\n    * `Req` - the high-level API (you're here!)\n\n    * `Req.Request` - the low-level API and the request struct\n\n    * `Req.Steps` - the collection of built-in steps\n\n  The high-level API is what most users of Req will use most of the time.\n\n  ## Examples\n\n  Making a GET request with `Req.get!/1`:\n\n      iex> Req.get!(\"https://api.github.com/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  Same, but by explicitly building request struct first:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.get!(req, url: \"/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  Making a POST request with `Req.post!/2`:\n\n      iex> Req.post!(\"https://httpbin.org/post\", form: [comments: \"hello!\"]).body[\"form\"]\n      %{\"comments\" => \"hello!\"}\n  \"\"\"\n\n  @type url() :: URI.t() | String.t()\n\n  @doc \"\"\"\n  Returns a new request struct with built-in steps.\n\n  See `request/1` for a list of available options. See `Req.Request` module documentation\n  for more information on the underlying request struct.\n\n  ## Examples\n\n      iex> req = Req.new(url: \"https://elixir-lang.org\")\n      iex> req.method\n      :get\n      iex> URI.to_string(req.url)\n      \"https://elixir-lang.org\"\n\n  \"\"\"\n  @spec new(options :: keyword()) :: Req.Request.t()\n  def new(options \\\\ []) do\n    options = Keyword.merge(default_options(), options)\n    {plugins, options} = Keyword.pop(options, :plugins, [])\n\n    %Req.Request{\n      registered_options:\n        MapSet.new([\n          :user_agent,\n          :compressed,\n          :range,\n          :http_errors,\n          :base_url,\n          :params,\n          :auth,\n          :form,\n          :json,\n          :compress_body,\n          :compressed,\n          :raw,\n          :decode_body,\n          :output,\n          :follow_redirects,\n          :location_trusted,\n          :max_redirects,\n          :retry,\n          :retry_delay,\n          :max_retries,\n          :cache,\n          :cache_dir,\n          :plug,\n          :finch,\n          :finch_request,\n          :connect_options,\n          :receive_timeout,\n          :pool_timeout,\n          :unix_socket\n        ])\n    }\n    |> update(options)\n    |> Req.Request.prepend_request_steps(\n      put_user_agent: &Req.Steps.put_user_agent/1,\n      compressed: &Req.Steps.compressed/1,\n      encode_body: &Req.Steps.encode_body/1,\n      put_base_url: &Req.Steps.put_base_url/1,\n      auth: &Req.Steps.auth/1,\n      put_params: &Req.Steps.put_params/1,\n      put_range: &Req.Steps.put_range/1,\n      cache: &Req.Steps.cache/1,\n      put_plug: &Req.Steps.put_plug/1,\n      compress_body: &Req.Steps.compress_body/1\n    )\n    |> Req.Request.prepend_response_steps(\n      retry: &Req.Steps.retry/1,\n      follow_redirects: &Req.Steps.follow_redirects/1,\n      decompress_body: &Req.Steps.decompress_body/1,\n      decode_body: &Req.Steps.decode_body/1,\n      handle_http_errors: &Req.Steps.handle_http_errors/1,\n      output: &Req.Steps.output/1\n    )\n    |> Req.Request.prepend_error_steps(retry: &Req.Steps.retry/1)\n    |> run_plugins(plugins)\n  end\n\n  @doc \"\"\"\n  Updates a request struct.\n\n  See `request/1` for a list of available options. See `Req.Request` module documentation\n  for more information on the underlying request struct.\n\n  ## Examples\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> req = Req.update(req, auth: {\"alice\", \"secret\"})\n      iex> req.options\n      %{auth: {\"alice\", \"secret\"}, base_url: \"https://httpbin.org\"}\n\n  Passing `:headers` will automatically encode and merge them:\n\n      iex> req = Req.new(headers: [point_x: 1])\n      iex> req = Req.update(req, headers: [point_y: 2])\n      iex> req.headers\n      [{\"point-x\", \"1\"}, {\"point-y\", \"2\"}]\n\n  \"\"\"\n  @spec update(Req.Request.t(), options :: keyword()) :: Req.Request.t()\n  def update(%Req.Request{} = request, options) when is_list(options) do\n    request_option_names = [:method, :url, :headers, :body, :adapter]\n\n    {request_options, options} = Keyword.split(options, request_option_names)\n\n    registered =\n      MapSet.union(\n        request.registered_options,\n        MapSet.new(request_option_names)\n      )\n\n    Req.Request.validate_options(options, registered)\n\n    request_options =\n      if request_options[:headers] do\n        update_in(request_options[:headers], &encode_headers/1)\n      else\n        request_options\n      end\n\n    request =\n      Map.merge(request, Map.new(request_options), fn\n        :url, _, url ->\n          URI.parse(url)\n\n        :headers, old, new ->\n          old ++ new\n\n        _, _, value ->\n          value\n      end)\n\n    request = update_in(request.options, &Map.merge(&1, Map.new(options)))\n\n    if request.options[:output] do\n      update_in(request.options, &Map.put(&1, :decode_body, false))\n    else\n      request\n    end\n  end\n\n  @doc \"\"\"\n  Makes a GET request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.get!(\"https://api.github.com/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.get!(req, url: \"/repos/elixir-lang/elixir\").status\n      200\n\n  \"\"\"\n  @spec get!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def get!(url_or_request, options \\\\ []) do\n    case get(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a GET request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.get(\"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> res.body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> {:ok, res} = Req.get(req, url: \"/repos/elixir-lang/elixir\")\n      iex> res.status\n      200\n\n  \"\"\"\n  @spec get(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def get(url_or_request, options \\\\ [])\n\n  def get(%Req.Request{} = request, options) do\n    request(%{request | method: :get}, options)\n  end\n\n  def get(url, options) do\n    request([method: :get, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a HEAD request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.head!(\"https://httpbin.org/status/201\").status\n      201\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> Req.head!(req, url: \"/status/201\").status\n      201\n\n  \"\"\"\n  @spec head!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def head!(url_or_request, options \\\\ []) do\n    case head(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a HEAD request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.head(\"https://httpbin.org/status/201\")\n      iex> res.status\n      201\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> {:ok, res} = Req.head(req, url: \"/status/201\")\n      iex> res.status\n      201\n\n  \"\"\"\n  @spec head(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def head(url_or_request, options \\\\ [])\n\n  def head(%Req.Request{} = request, options) do\n    request(%{request | method: :head}, options)\n  end\n\n  def head(url, options) do\n    request([method: :head, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a POST request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.post!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n      iex> Req.post!(\"https://httpbin.org/anything\", form: [x: 1]).body[\"form\"]\n      %{\"x\" => \"1\"}\n\n      iex> Req.post!(\"https://httpbin.org/anything\", json: %{x: 2}).body[\"json\"]\n      %{\"x\" => 2}\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.post!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec post!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def post!(url_or_request, options \\\\ []) do\n    if Keyword.keyword?(options) do\n      case post(url_or_request, options) do\n        {:ok, response} -> response\n        {:error, exception} -> raise exception\n      end\n    else\n      case options do\n        {:form, data} ->\n          IO.warn(\n            \"Req.post!(url, {:form, data}) is deprecated in favour of \" <>\n              \"Req.post!(url, form: data)\"\n          )\n\n          request!(method: :post, url: URI.parse(url_or_request), form: data)\n\n        {:json, data} ->\n          IO.warn(\n            \"Req.post!(url, {:json, data}) is deprecated in favour of \" <>\n              \"Req.post!(url, json: data)\"\n          )\n\n          request!(method: :post, url: URI.parse(url_or_request), json: data)\n\n        data ->\n          IO.warn(\"Req.post!(url, body) is deprecated in favour of Req.post!(url, body: body)\")\n          request!(method: :post, url: URI.parse(url_or_request), body: data)\n      end\n    end\n  end\n\n  @doc false\n  def post!(url, body, options) do\n    case body do\n      {:form, data} ->\n        IO.warn(\n          \"Req.post!(url, {:form, data}, options) is deprecated in favour of \" <>\n            \"Req.post!(url, [form: data] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), form: data] ++ options)\n\n      {:json, data} ->\n        IO.warn(\n          \"Req.post!(url, {:json, data}) is deprecated in favour of \" <>\n            \"Req.post!(url, [json: data] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), json: data] ++ options)\n\n      data ->\n        IO.warn(\n          \"Req.post!(url, body) is deprecated in favour of \" <>\n            \"Req.post!(url, [body: body] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), body: data] ++ options)\n    end\n  end\n\n  @doc \"\"\"\n  Makes a POST request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", form: [x: 1])\n      iex> res.body[\"form\"]\n      %{\"x\" => \"1\"}\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", json: %{x: 2})\n      iex> res.body[\"json\"]\n      %{\"x\" => 2}\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.post(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec post(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def post(url_or_request, options \\\\ [])\n\n  def post(%Req.Request{} = request, options) do\n    request(%{request | method: :post}, options)\n  end\n\n  def post(url, options) do\n    request([method: :post, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a PUT request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.put!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.put!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec put!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def put!(url_or_request, options \\\\ []) do\n    case put(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc false\n  def put!(%URI{} = url, {type, _} = body, options) when type in [:form, :json] do\n    IO.warn(\n      \"Req.put!(url, {:#{type}, #{type}}, options) is deprecated in favour of \" <>\n        \"Req.put!(url, [#{type}: #{type}] ++ options)\"\n    )\n\n    request!([method: :put, url: url, body: body] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a PUT request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.put(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.put(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec put(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def put(url_or_request, options \\\\ [])\n\n  def put(%Req.Request{} = request, options) do\n    request(%{request | method: :put}, options)\n  end\n\n  def put(url, options) do\n    if Keyword.keyword?(options) do\n      request([method: :put, url: URI.parse(url)] ++ options)\n    else\n      IO.warn(\"Req.put!(url, body) is deprecated in favour of Req.put!(url, body: body)\")\n      request(url: URI.parse(url), body: options)\n    end\n  end\n\n  @doc \"\"\"\n  Makes a PATCH request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.patch!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.patch!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec patch!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def patch!(url_or_request, options \\\\ []) do\n    case patch(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a PATCH request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.patch(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.patch(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec patch(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def patch(url_or_request, options \\\\ [])\n\n  def patch(%Req.Request{} = request, options) do\n    request(%{request | method: :patch}, options)\n  end\n\n  def patch(url, options) do\n    request([method: :patch, url: url] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a DELETE request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.delete!(\"https://httpbin.org/anything\").body[\"method\"]\n      \"DELETE\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.delete!(req).body[\"method\"]\n      \"DELETE\"\n  \"\"\"\n  @spec delete!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def delete!(url_or_request, options \\\\ []) do\n    case delete(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a DELETE request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.delete(\"https://httpbin.org/anything\")\n      iex> res.body[\"method\"]\n      \"DELETE\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.delete(req)\n      iex> res.body[\"method\"]\n      \"DELETE\"\n  \"\"\"\n  @spec delete(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def delete(url_or_request, options \\\\ [])\n\n  def delete(%Req.Request{} = request, options) do\n    request(%{request | method: :delete}, options)\n  end\n\n  def delete(url, options) do\n    request([method: :delete, url: url] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request.\n\n  `request/1` and `request/2` functions give three ways of making requests:\n\n    1. With a list of options, for example:\n\n       ```\n       iex> Req.request(url: url)\n       ```\n\n    2. With a request struct, for example:\n\n       ```\n       iex> Req.new(url: url) |> Req.request()\n       ```\n\n    3. With a request struct and more options, for example:\n\n       ```\n       iex> Req.new(base_url: base_url) |> Req.request(url: url)\n       ```\n\n  This function as well as all the other ones in this module accept the same set of options described below.\n\n  ## Options\n\n  Basic request options:\n\n    * `:method` - the request method, defaults to `:get`.\n\n    * `:url` - the request URL.\n\n    * `:headers` - the request headers.\n\n      The headers are automatically encoded using these rules:\n\n        * atom header names are turned into strings, replacing `_` with `-`. For example,\n          `:user_agent` becomes `\"user-agent\"`\n\n        * string header names are left as is. Because header keys are case-insensitive\n          in both HTTP/1.1 and HTTP/2, it is recommended for header keys to be in\n          lowercase, to avoid sending duplicate keys in a request.\n\n        * `NaiveDateTime` and `DateTime` header values are encoded as \"HTTP date\". Otherwise,\n          the header value is encoded with `String.Chars.to_string/1`.\n\n      If you set `:headers` options both in `Req.new/1` and `request/2`, the header lists are merged.\n\n    * `:body` - the request body.\n\n  Additional URL options:\n\n    * `:base_url` - if set, the request URL is prepended with this base URL (via\n      [`put_base_url`](`Req.Steps.put_base_url/1`) step).\n\n    * `:params` - if set, appends parameters to the request query string (via\n      [`put_params`](`Req.Steps.put_params/1`) step).\n\n  Authentication options:\n\n    * `:auth` - sets request authentication (via [`auth`](`Req.Steps.auth/1`) step).\n\n  Request body options:\n\n    * `:form` - if set, encodes the request body as form data ([`encode_body`](`Req.Steps.encode_body/1`) step).\n\n    * `:json` - if set, encodes the request body as JSON ([`encode_body`](`Req.Steps.encode_body/1`) step).\n\n    * `:compress_body` - if set to `true`, compresses the request body using gzip (via [`compress_body`](`Req.Steps.compress_body/1`) step).\n      Defaults to `false`.\n\n  Response body options:\n\n    * `:compressed` - if set to `true`, asks the server to return compressed response.\n      (via [`compressed`](`Req.Steps.compressed/1`) step). Defaults to `true`.\n\n    * `:raw` - if set to `true`, disables automatic body decompression\n      ([`decompress_body`](`Req.Steps.decompress_body/1`) step) and decoding\n      ([`decode_body`](`Req.Steps.decode_body/1`) step). Defaults to `false`.\n\n    * `:decode_body` - if set to `false`, disables automatic response body decoding.\n      Defaults to `true`.\n\n    * `:output` - if set, writes the response body to a file (via\n      [`output`](`Req.Steps.output/1`) step). Can be set to a string path or an atom\n      `:remote_name` which would use the remote name as the filename in the current working\n      directory. Once the file is written, the response body is replaced with `\"\"`.\n\n      Setting `:output` also sets the `decode_body: false` option to prevent decoding the\n      response before writing it to the file.\n\n  Response redirect options ([`follow_redirects`](`Req.Steps.follow_redirects/1`) step):\n\n    * `:follow_redirects` - if set to `false`, disables automatic response redirects. Defaults to `true`.\n\n    * `:location_trusted` - by default, authorization credentials are only sent\n      on redirects with the same host, scheme and port. If `:location_trusted` is set to `true`, credentials\n      will be sent to any host.\n\n    * `:max_redirects` - the maximum number of redirects, defaults to `10`.\n\n  Retry options ([`retry`](`Req.Steps.retry/1`) step):\n\n    * `:retry`: can be set to: `:safe` (default) to only retry GET/HEAD requests on HTTP 408/5xx\n      responses or exceptions, `false` to never retry, and `fun` - a 1-arity function that accepts\n      either a `Req.Response` or an exception struct and returns boolean whether to retry\n\n    * `:retry_delay` - a function that receives the retry count (starting at 0) and returns the delay, the\n      number of milliseconds to sleep before making another attempt.\n      Defaults to a simple exponential backoff: 1s, 2s, 4s, 8s, ...\n\n    * `:max_retries` - maximum number of retry attempts, defaults to `3` (for a total of `4`\n      requests to the server, including the initial one.)\n\n  Caching options ([`cache`](`Req.Steps.cache/1`) step):\n\n    * `:cache` - if `true`, performs HTTP caching. Defaults to `false`.\n\n    * `:cache_dir` - the directory to store the cache, defaults to `<user_cache_dir>/req`\n      (see: `:filename.basedir/3`)\n\n  Request adapters:\n\n    * `:adapter` - adapter to use to make the actual HTTP request. See `:adapter` field description\n      in the `Req.Request` module documentation for more information. Defaults to calling [`run_finch`](`Req.Steps.run_finch/1`).\n\n    * `:plug` - if set, calls the given Plug instead of making an HTTP request over the network (via [`put_plug`](`Req.Steps.put_plug/1`) step).\n\n  Finch options ([`run_finch`](`Req.Steps.run_finch/1`) step)\n\n    * `:finch` - the Finch pool to use. Defaults to pool automatically started by `Req`.\n\n    * `:connect_options` - dynamically starts (or re-uses already started) Finch pool with\n      the given connection options:\n\n        * `:timeout` - socket connect timeout in milliseconds, defaults to `30_000`.\n\n        * `:protocol` - the HTTP protocol to use, defaults to `:http1`.\n\n        * `:hostname` - Mint explicit hostname\n\n        * `:transport_opts` - Mint transport options\n\n        * `:proxy_headers` - Mint proxy headers\n\n        * `:proxy` - Mint HTTP/1 proxy settings, a `{schema, address, port, options}` tuple.\n\n        * `:client_settings` - Mint HTTP/2 client settings\n\n    * `:pool_timeout` - pool checkout timeout in milliseconds, defaults to `5000`.\n\n    * `:receive_timeout` - socket receive timeout in milliseconds, defaults to `15_000`.\n\n    * `:unix_socket` - if set, connect through the given UNIX domain socket\n\n    * `:finch_request` - a function to modify the built Finch request before execution. This function takes a\n       Finch request and returns a Finch request. If not provided, the finch request will not be modified\n\n  ## Examples\n\n  With options keywords list:\n\n      iex> {:ok, response} = Req.request(url: \"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> response.status\n      200\n      iex> response.body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> {:ok, response} = Req.request(req)\n      iex> response.status\n      200\n\n  With request struct and options:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> {:ok, response} = Req.request(req, url: \"/repos/elixir-lang/elixir\")\n      iex> response.status\n      200\n\n  With mock adapter:\n\n      iex> adapter = fn request ->\n      ...>   response = %Req.Response{status: 200, body: \"it works!\"}\n      ...>   {request, response}\n      ...> end\n      iex>\n      iex> {:ok, response} = Req.request(adapter: adapter, url: \"http://example\")\n      iex> response.body\n      \"it works!\"\n  \"\"\"\n  @spec request(Req.Request.t() | keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def request(request_or_options)\n\n  def request(%Req.Request{} = request) do\n    request(request, [])\n  end\n\n  def request(options) do\n    request(Req.new(options), [])\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request.\n\n  See `request/1` for more information.\n  \"\"\"\n  @spec request(Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def request(request, options) when is_list(options) do\n    {plugins, options} = Keyword.pop(options, :plugins, [])\n\n    request\n    |> Req.update(options)\n    |> run_plugins(plugins)\n    |> Req.Request.run()\n  end\n\n  @doc false\n  def request(method, url, options) do\n    IO.warn(\n      \"Req.request(method, url, options) is deprecated in favour of \" <>\n        \"Req.request!([method: method, url: url] ++ options)\"\n    )\n\n    request([method: method, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request and returns a response or raises an error.\n\n  See `request/1` for more information.\n\n  ## Examples\n\n      iex> Req.request!(url: \"https://api.github.com/repos/elixir-lang/elixir\").status\n      200\n  \"\"\"\n  @spec request!(Req.Request.t() | keyword()) :: Req.Response.t()\n  def request!(request_or_options) do\n    case request(request_or_options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request and returns a response or raises an error.\n\n  See `request/1` for more information.\n\n  ## Examples\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.request!(req, url: \"/repos/elixir-lang/elixir\").status\n      200\n  \"\"\"\n  @spec request!(Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def request!(request, options) do\n    case request(request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Returns default options.\n\n  See `default_options/1` for more information.\n  \"\"\"\n  @spec default_options() :: keyword()\n  def default_options() do\n    Application.get_env(:req, :default_options, [])\n  end\n\n  @doc \"\"\"\n  Sets default options for `Req.new/1`.\n\n  Avoid setting default options in libraries as they are global.\n\n  ## Examples\n\n      iex> Req.default_options(base_url: \"https://httpbin.org\")\n      iex> Req.get!(\"/statuses/201\").status\n      201\n      iex> Req.new() |> Req.get!(url: \"/statuses/201\").status\n      201\n  \"\"\"\n  @spec default_options(keyword()) :: :ok\n  def default_options(options) do\n    Application.put_env(:req, :default_options, options)\n  end\n\n  defp encode_headers(headers) do\n    for {name, value} <- headers do\n      name =\n        case name do\n          atom when is_atom(atom) ->\n            atom |> Atom.to_string() |> String.replace(\"_\", \"-\")\n\n          binary when is_binary(binary) ->\n            binary\n        end\n\n      value =\n        case value do\n          %NaiveDateTime{} = naive_datetime ->\n            Req.Steps.format_http_datetime(naive_datetime)\n\n          %DateTime{} = datetime ->\n            datetime |> DateTime.shift_zone!(\"Etc/UTC\") |> Req.Steps.format_http_datetime()\n\n          _ ->\n            String.Chars.to_string(value)\n        end\n\n      {name, value}\n    end\n  end\n\n  # Plugins support is experimental, undocumented, and likely won't make the new release.\n  defp run_plugins(request, [plugin | rest]) when is_atom(plugin) do\n    if Code.ensure_loaded?(plugin) and function_exported?(plugin, :attach, 1) do\n      run_plugins(plugin.attach(request), rest)\n    else\n      run_plugins(plugin.run(request), rest)\n    end\n  end\n\n  defp run_plugins(request, [plugin | rest]) when is_function(plugin, 1) do\n    run_plugins(plugin.(request), rest)\n  end\n\n  defp run_plugins(request, []) do\n    request\n  end\n\n  @doc false\n  @deprecated \"Manually build Req.Request struct instead\"\n  def build(method, url, options \\\\ []) do\n    %Req.Request{\n      method: method,\n      url: URI.parse(url),\n      headers: Keyword.get(options, :headers, []),\n      body: Keyword.get(options, :body, \"\")\n    }\n  end\nend\n")]))
[client-notification] Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :method "textDocument/didSave" :params
          (:text "defmodule Req do\n  @moduledoc \"\"\"\n  The high-level API.\n\n  Req is composed of three main pieces:\n\n    * `Req` - the high-level API (you're here!)\n\n    * `Req.Request` - the low-level API and the request struct\n\n    * `Req.Steps` - the collection of built-in steps\n\n  The high-level API is what most users of Req will use most of the time.\n\n  ## Examples\n\n  Making a GET request with `Req.get!/1`:\n\n      iex> Req.get!(\"https://api.github.com/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  Same, but by explicitly building request struct first:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.get!(req, url: \"/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  Making a POST request with `Req.post!/2`:\n\n      iex> Req.post!(\"https://httpbin.org/post\", form: [comments: \"hello!\"]).body[\"form\"]\n      %{\"comments\" => \"hello!\"}\n  \"\"\"\n\n  @type url() :: URI.t() | String.t()\n\n  @doc \"\"\"\n  Returns a new request struct with built-in steps.\n\n  See `request/1` for a list of available options. See `Req.Request` module documentation\n  for more information on the underlying request struct.\n\n  ## Examples\n\n      iex> req = Req.new(url: \"https://elixir-lang.org\")\n      iex> req.method\n      :get\n      iex> URI.to_string(req.url)\n      \"https://elixir-lang.org\"\n\n  \"\"\"\n  @spec new(options :: keyword()) :: Req.Request.t()\n  def new(options \\\\ []) do\n    options = Keyword.merge(default_options(), options)\n    {plugins, options} = Keyword.pop(options, :plugins, [])\n\n    %Req.Request{\n      registered_options:\n        MapSet.new([\n          :user_agent,\n          :compressed,\n          :range,\n          :http_errors,\n          :base_url,\n          :params,\n          :auth,\n          :form,\n          :json,\n          :compress_body,\n          :compressed,\n          :raw,\n          :decode_body,\n          :output,\n          :follow_redirects,\n          :location_trusted,\n          :max_redirects,\n          :retry,\n          :retry_delay,\n          :max_retries,\n          :cache,\n          :cache_dir,\n          :plug,\n          :finch,\n          :finch_request,\n          :connect_options,\n          :receive_timeout,\n          :pool_timeout,\n          :unix_socket\n        ])\n    }\n    |> update(options)\n    |> Req.Request.prepend_request_steps(\n      put_user_agent: &Req.Steps.put_user_agent/1,\n      compressed: &Req.Steps.compressed/1,\n      encode_body: &Req.Steps.encode_body/1,\n      put_base_url: &Req.Steps.put_base_url/1,\n      auth: &Req.Steps.auth/1,\n      put_params: &Req.Steps.put_params/1,\n      put_range: &Req.Steps.put_range/1,\n      cache: &Req.Steps.cache/1,\n      put_plug: &Req.Steps.put_plug/1,\n      compress_body: &Req.Steps.compress_body/1\n    )\n    |> Req.Request.prepend_response_steps(\n      retry: &Req.Steps.retry/1,\n      follow_redirects: &Req.Steps.follow_redirects/1,\n      decompress_body: &Req.Steps.decompress_body/1,\n      decode_body: &Req.Steps.decode_body/1,\n      handle_http_errors: &Req.Steps.handle_http_errors/1,\n      output: &Req.Steps.output/1\n    )\n    |> Req.Request.prepend_error_steps(retry: &Req.Steps.retry/1)\n    |> run_plugins(plugins)\n  end\n\n  @doc \"\"\"\n  Updates a request struct.\n\n  See `request/1` for a list of available options. See `Req.Request` module documentation\n  for more information on the underlying request struct.\n\n  ## Examples\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> req = Req.update(req, auth: {\"alice\", \"secret\"})\n      iex> req.options\n      %{auth: {\"alice\", \"secret\"}, base_url: \"https://httpbin.org\"}\n\n  Passing `:headers` will automatically encode and merge them:\n\n      iex> req = Req.new(headers: [point_x: 1])\n      iex> req = Req.update(req, headers: [point_y: 2])\n      iex> req.headers\n      [{\"point-x\", \"1\"}, {\"point-y\", \"2\"}]\n\n  \"\"\"\n  @spec update(Req.Request.t(), options :: keyword()) :: Req.Request.t()\n  def update(%Req.Request{} = request, options) when is_list(options) do\n    request_option_names = [:method, :url, :headers, :body, :adapter]\n\n    {request_options, options} = Keyword.split(options, request_option_names)\n\n    registered =\n      MapSet.union(\n        request.registered_options,\n        MapSet.new(request_option_names)\n      )\n\n    Req.Request.validate_options(options, registered)\n\n    request_options =\n      if request_options[:headers] do\n        update_in(request_options[:headers], &encode_headers/1)\n      else\n        request_options\n      end\n\n    request =\n      Map.merge(request, Map.new(request_options), fn\n        :url, _, url ->\n          URI.parse(url)\n\n        :headers, old, new ->\n          old ++ new\n\n        _, _, value ->\n          value\n      end)\n\n    request = update_in(request.options, &Map.merge(&1, Map.new(options)))\n\n    if request.options[:output] do\n      update_in(request.options, &Map.put(&1, :decode_body, false))\n    else\n      request\n    end\n  end\n\n  @doc \"\"\"\n  Makes a GET request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.get!(\"https://api.github.com/repos/elixir-lang/elixir\").body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.get!(req, url: \"/repos/elixir-lang/elixir\").status\n      200\n\n  \"\"\"\n  @spec get!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def get!(url_or_request, options \\\\ []) do\n    case get(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a GET request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.get(\"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> res.body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> {:ok, res} = Req.get(req, url: \"/repos/elixir-lang/elixir\")\n      iex> res.status\n      200\n\n  \"\"\"\n  @spec get(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def get(url_or_request, options \\\\ [])\n\n  def get(%Req.Request{} = request, options) do\n    request(%{request | method: :get}, options)\n  end\n\n  def get(url, options) do\n    request([method: :get, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a HEAD request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.head!(\"https://httpbin.org/status/201\").status\n      201\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> Req.head!(req, url: \"/status/201\").status\n      201\n\n  \"\"\"\n  @spec head!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def head!(url_or_request, options \\\\ []) do\n    case head(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a HEAD request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.head(\"https://httpbin.org/status/201\")\n      iex> res.status\n      201\n\n  With request struct:\n\n      iex> req = Req.new(base_url: \"https://httpbin.org\")\n      iex> {:ok, res} = Req.head(req, url: \"/status/201\")\n      iex> res.status\n      201\n\n  \"\"\"\n  @spec head(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def head(url_or_request, options \\\\ [])\n\n  def head(%Req.Request{} = request, options) do\n    request(%{request | method: :head}, options)\n  end\n\n  def head(url, options) do\n    request([method: :head, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a POST request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.post!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n      iex> Req.post!(\"https://httpbin.org/anything\", form: [x: 1]).body[\"form\"]\n      %{\"x\" => \"1\"}\n\n      iex> Req.post!(\"https://httpbin.org/anything\", json: %{x: 2}).body[\"json\"]\n      %{\"x\" => 2}\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.post!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec post!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def post!(url_or_request, options \\\\ []) do\n    if Keyword.keyword?(options) do\n      case post(url_or_request, options) do\n        {:ok, response} -> response\n        {:error, exception} -> raise exception\n      end\n    else\n      case options do\n        {:form, data} ->\n          IO.warn(\n            \"Req.post!(url, {:form, data}) is deprecated in favour of \" <>\n              \"Req.post!(url, form: data)\"\n          )\n\n          request!(method: :post, url: URI.parse(url_or_request), form: data)\n\n        {:json, data} ->\n          IO.warn(\n            \"Req.post!(url, {:json, data}) is deprecated in favour of \" <>\n              \"Req.post!(url, json: data)\"\n          )\n\n          request!(method: :post, url: URI.parse(url_or_request), json: data)\n\n        data ->\n          IO.warn(\"Req.post!(url, body) is deprecated in favour of Req.post!(url, body: body)\")\n          request!(method: :post, url: URI.parse(url_or_request), body: data)\n      end\n    end\n  end\n\n  @doc false\n  def post!(url, body, options) do\n    case body do\n      {:form, data} ->\n        IO.warn(\n          \"Req.post!(url, {:form, data}, options) is deprecated in favour of \" <>\n            \"Req.post!(url, [form: data] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), form: data] ++ options)\n\n      {:json, data} ->\n        IO.warn(\n          \"Req.post!(url, {:json, data}) is deprecated in favour of \" <>\n            \"Req.post!(url, [json: data] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), json: data] ++ options)\n\n      data ->\n        IO.warn(\n          \"Req.post!(url, body) is deprecated in favour of \" <>\n            \"Req.post!(url, [body: body] ++ options)\"\n        )\n\n        request!([method: :post, url: URI.parse(url), body: data] ++ options)\n    end\n  end\n\n  @doc \"\"\"\n  Makes a POST request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", form: [x: 1])\n      iex> res.body[\"form\"]\n      %{\"x\" => \"1\"}\n\n      iex> {:ok, res} = Req.post(\"https://httpbin.org/anything\", json: %{x: 2})\n      iex> res.body[\"json\"]\n      %{\"x\" => 2}\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.post(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec post(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def post(url_or_request, options \\\\ [])\n\n  def post(%Req.Request{} = request, options) do\n    request(%{request | method: :post}, options)\n  end\n\n  def post(url, options) do\n    request([method: :post, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a PUT request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.put!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.put!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec put!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def put!(url_or_request, options \\\\ []) do\n    case put(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc false\n  def put!(%URI{} = url, {type, _} = body, options) when type in [:form, :json] do\n    IO.warn(\n      \"Req.put!(url, {:#{type}, #{type}}, options) is deprecated in favour of \" <>\n        \"Req.put!(url, [#{type}: #{type}] ++ options)\"\n    )\n\n    request!([method: :put, url: url, body: body] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a PUT request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.put(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.put(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec put(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def put(url_or_request, options \\\\ [])\n\n  def put(%Req.Request{} = request, options) do\n    request(%{request | method: :put}, options)\n  end\n\n  def put(url, options) do\n    if Keyword.keyword?(options) do\n      request([method: :put, url: URI.parse(url)] ++ options)\n    else\n      IO.warn(\"Req.put!(url, body) is deprecated in favour of Req.put!(url, body: body)\")\n      request(url: URI.parse(url), body: options)\n    end\n  end\n\n  @doc \"\"\"\n  Makes a PATCH request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.patch!(\"https://httpbin.org/anything\", body: \"hello!\").body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.patch!(req, body: \"hello!\").body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec patch!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def patch!(url_or_request, options \\\\ []) do\n    case patch(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a PATCH request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.patch(\"https://httpbin.org/anything\", body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.patch(req, body: \"hello!\")\n      iex> res.body[\"data\"]\n      \"hello!\"\n  \"\"\"\n  @spec patch(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def patch(url_or_request, options \\\\ [])\n\n  def patch(%Req.Request{} = request, options) do\n    request(%{request | method: :patch}, options)\n  end\n\n  def patch(url, options) do\n    request([method: :patch, url: url] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes a DELETE request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> Req.delete!(\"https://httpbin.org/anything\").body[\"method\"]\n      \"DELETE\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> Req.delete!(req).body[\"method\"]\n      \"DELETE\"\n  \"\"\"\n  @spec delete!(url() | Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def delete!(url_or_request, options \\\\ []) do\n    case delete(url_or_request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes a DELETE request.\n\n  See `request/1` for a list of supported options.\n\n  ## Examples\n\n  With URL:\n\n      iex> {:ok, res} = Req.delete(\"https://httpbin.org/anything\")\n      iex> res.body[\"method\"]\n      \"DELETE\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://httpbin.org/anything\")\n      iex> {:ok, res} = Req.delete(req)\n      iex> res.body[\"method\"]\n      \"DELETE\"\n  \"\"\"\n  @spec delete(url() | Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def delete(url_or_request, options \\\\ [])\n\n  def delete(%Req.Request{} = request, options) do\n    request(%{request | method: :delete}, options)\n  end\n\n  def delete(url, options) do\n    request([method: :delete, url: url] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request.\n\n  `request/1` and `request/2` functions give three ways of making requests:\n\n    1. With a list of options, for example:\n\n       ```\n       iex> Req.request(url: url)\n       ```\n\n    2. With a request struct, for example:\n\n       ```\n       iex> Req.new(url: url) |> Req.request()\n       ```\n\n    3. With a request struct and more options, for example:\n\n       ```\n       iex> Req.new(base_url: base_url) |> Req.request(url: url)\n       ```\n\n  This function as well as all the other ones in this module accept the same set of options described below.\n\n  ## Options\n\n  Basic request options:\n\n    * `:method` - the request method, defaults to `:get`.\n\n    * `:url` - the request URL.\n\n    * `:headers` - the request headers.\n\n      The headers are automatically encoded using these rules:\n\n        * atom header names are turned into strings, replacing `_` with `-`. For example,\n          `:user_agent` becomes `\"user-agent\"`\n\n        * string header names are left as is. Because header keys are case-insensitive\n          in both HTTP/1.1 and HTTP/2, it is recommended for header keys to be in\n          lowercase, to avoid sending duplicate keys in a request.\n\n        * `NaiveDateTime` and `DateTime` header values are encoded as \"HTTP date\". Otherwise,\n          the header value is encoded with `String.Chars.to_string/1`.\n\n      If you set `:headers` options both in `Req.new/1` and `request/2`, the header lists are merged.\n\n    * `:body` - the request body.\n\n  Additional URL options:\n\n    * `:base_url` - if set, the request URL is prepended with this base URL (via\n      [`put_base_url`](`Req.Steps.put_base_url/1`) step).\n\n    * `:params` - if set, appends parameters to the request query string (via\n      [`put_params`](`Req.Steps.put_params/1`) step).\n\n  Authentication options:\n\n    * `:auth` - sets request authentication (via [`auth`](`Req.Steps.auth/1`) step).\n\n  Request body options:\n\n    * `:form` - if set, encodes the request body as form data ([`encode_body`](`Req.Steps.encode_body/1`) step).\n\n    * `:json` - if set, encodes the request body as JSON ([`encode_body`](`Req.Steps.encode_body/1`) step).\n\n    * `:compress_body` - if set to `true`, compresses the request body using gzip (via [`compress_body`](`Req.Steps.compress_body/1`) step).\n      Defaults to `false`.\n\n  Response body options:\n\n    * `:compressed` - if set to `true`, asks the server to return compressed response.\n      (via [`compressed`](`Req.Steps.compressed/1`) step). Defaults to `true`.\n\n    * `:raw` - if set to `true`, disables automatic body decompression\n      ([`decompress_body`](`Req.Steps.decompress_body/1`) step) and decoding\n      ([`decode_body`](`Req.Steps.decode_body/1`) step). Defaults to `false`.\n\n    * `:decode_body` - if set to `false`, disables automatic response body decoding.\n      Defaults to `true`.\n\n    * `:output` - if set, writes the response body to a file (via\n      [`output`](`Req.Steps.output/1`) step). Can be set to a string path or an atom\n      `:remote_name` which would use the remote name as the filename in the current working\n      directory. Once the file is written, the response body is replaced with `\"\"`.\n\n      Setting `:output` also sets the `decode_body: false` option to prevent decoding the\n      response before writing it to the file.\n\n  Response redirect options ([`follow_redirects`](`Req.Steps.follow_redirects/1`) step):\n\n    * `:follow_redirects` - if set to `false`, disables automatic response redirects. Defaults to `true`.\n\n    * `:location_trusted` - by default, authorization credentials are only sent\n      on redirects with the same host, scheme and port. If `:location_trusted` is set to `true`, credentials\n      will be sent to any host.\n\n    * `:max_redirects` - the maximum number of redirects, defaults to `10`.\n\n  Retry options ([`retry`](`Req.Steps.retry/1`) step):\n\n    * `:retry`: can be set to: `:safe` (default) to only retry GET/HEAD requests on HTTP 408/5xx\n      responses or exceptions, `false` to never retry, and `fun` - a 1-arity function that accepts\n      either a `Req.Response` or an exception struct and returns boolean whether to retry\n\n    * `:retry_delay` - a function that receives the retry count (starting at 0) and returns the delay, the\n      number of milliseconds to sleep before making another attempt.\n      Defaults to a simple exponential backoff: 1s, 2s, 4s, 8s, ...\n\n    * `:max_retries` - maximum number of retry attempts, defaults to `3` (for a total of `4`\n      requests to the server, including the initial one.)\n\n  Caching options ([`cache`](`Req.Steps.cache/1`) step):\n\n    * `:cache` - if `true`, performs HTTP caching. Defaults to `false`.\n\n    * `:cache_dir` - the directory to store the cache, defaults to `<user_cache_dir>/req`\n      (see: `:filename.basedir/3`)\n\n  Request adapters:\n\n    * `:adapter` - adapter to use to make the actual HTTP request. See `:adapter` field description\n      in the `Req.Request` module documentation for more information. Defaults to calling [`run_finch`](`Req.Steps.run_finch/1`).\n\n    * `:plug` - if set, calls the given Plug instead of making an HTTP request over the network (via [`put_plug`](`Req.Steps.put_plug/1`) step).\n\n  Finch options ([`run_finch`](`Req.Steps.run_finch/1`) step)\n\n    * `:finch` - the Finch pool to use. Defaults to pool automatically started by `Req`.\n\n    * `:connect_options` - dynamically starts (or re-uses already started) Finch pool with\n      the given connection options:\n\n        * `:timeout` - socket connect timeout in milliseconds, defaults to `30_000`.\n\n        * `:protocol` - the HTTP protocol to use, defaults to `:http1`.\n\n        * `:hostname` - Mint explicit hostname\n\n        * `:transport_opts` - Mint transport options\n\n        * `:proxy_headers` - Mint proxy headers\n\n        * `:proxy` - Mint HTTP/1 proxy settings, a `{schema, address, port, options}` tuple.\n\n        * `:client_settings` - Mint HTTP/2 client settings\n\n    * `:pool_timeout` - pool checkout timeout in milliseconds, defaults to `5000`.\n\n    * `:receive_timeout` - socket receive timeout in milliseconds, defaults to `15_000`.\n\n    * `:unix_socket` - if set, connect through the given UNIX domain socket\n\n    * `:finch_request` - a function to modify the built Finch request before execution. This function takes a\n       Finch request and returns a Finch request. If not provided, the finch request will not be modified\n\n  ## Examples\n\n  With options keywords list:\n\n      iex> {:ok, response} = Req.request(url: \"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> response.status\n      200\n      iex> response.body[\"description\"]\n      \"Elixir is a dynamic, functional language designed for building scalable and maintainable applications\"\n\n  With request struct:\n\n      iex> req = Req.new(url: \"https://api.github.com/repos/elixir-lang/elixir\")\n      iex> {:ok, response} = Req.request(req)\n      iex> response.status\n      200\n\n  With request struct and options:\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> {:ok, response} = Req.request(req, url: \"/repos/elixir-lang/elixir\")\n      iex> response.status\n      200\n\n  With mock adapter:\n\n      iex> adapter = fn request ->\n      ...>   response = %Req.Response{status: 200, body: \"it works!\"}\n      ...>   {request, response}\n      ...> end\n      iex>\n      iex> {:ok, response} = Req.request(adapter: adapter, url: \"http://example\")\n      iex> response.body\n      \"it works!\"\n  \"\"\"\n  @spec request(Req.Request.t() | keyword()) :: {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def request(request_or_options)\n\n  def request(%Req.Request{} = request) do\n    request(request, [])\n  end\n\n  def request(options) do\n    request(Req.new(options), [])\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request.\n\n  See `request/1` for more information.\n  \"\"\"\n  @spec request(Req.Request.t(), options :: keyword()) ::\n          {:ok, Req.Response.t()} | {:error, Exception.t()}\n  def request(request, options) when is_list(options) do\n    {plugins, options} = Keyword.pop(options, :plugins, [])\n\n    request\n    |> Req.update(options)\n    |> run_plugins(plugins)\n    |> Req.Request.run()\n  end\n\n  @doc false\n  def request(method, url, options) do\n    IO.warn(\n      \"Req.request(method, url, options) is deprecated in favour of \" <>\n        \"Req.request!([method: method, url: url] ++ options)\"\n    )\n\n    request([method: method, url: URI.parse(url)] ++ options)\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request and returns a response or raises an error.\n\n  See `request/1` for more information.\n\n  ## Examples\n\n      iex> Req.request!(url: \"https://api.github.com/repos/elixir-lang/elixir\").status\n      200\n  \"\"\"\n  @spec request!(Req.Request.t() | keyword()) :: Req.Response.t()\n  def request!(request_or_options) do\n    case request(request_or_options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Makes an HTTP request and returns a response or raises an error.\n\n  See `request/1` for more information.\n\n  ## Examples\n\n      iex> req = Req.new(base_url: \"https://api.github.com\")\n      iex> Req.request!(req, url: \"/repos/elixir-lang/elixir\").status\n      200\n  \"\"\"\n  @spec request!(Req.Request.t(), options :: keyword()) :: Req.Response.t()\n  def request!(request, options) do\n    case request(request, options) do\n      {:ok, response} -> response\n      {:error, exception} -> raise exception\n    end\n  end\n\n  @doc \"\"\"\n  Returns default options.\n\n  See `default_options/1` for more information.\n  \"\"\"\n  @spec default_options() :: keyword()\n  def default_options() do\n    Application.get_env(:req, :default_options, [])\n  end\n\n  @doc \"\"\"\n  Sets default options for `Req.new/1`.\n\n  Avoid setting default options in libraries as they are global.\n\n  ## Examples\n\n      iex> Req.default_options(base_url: \"https://httpbin.org\")\n      iex> Req.get!(\"/statuses/201\").status\n      201\n      iex> Req.new() |> Req.get!(url: \"/statuses/201\").status\n      201\n  \"\"\"\n  @spec default_options(keyword()) :: :ok\n  def default_options(options) do\n    Application.put_env(:req, :default_options, options)\n  end\n\n  defp encode_headers(headers) do\n    for {name, value} <- headers do\n      name =\n        case name do\n          atom when is_atom(atom) ->\n            atom |> Atom.to_string() |> String.replace(\"_\", \"-\")\n\n          binary when is_binary(binary) ->\n            binary\n        end\n\n      value =\n        case value do\n          %NaiveDateTime{} = naive_datetime ->\n            Req.Steps.format_http_datetime(naive_datetime)\n\n          %DateTime{} = datetime ->\n            datetime |> DateTime.shift_zone!(\"Etc/UTC\") |> Req.Steps.format_http_datetime()\n\n          _ ->\n            String.Chars.to_string(value)\n        end\n\n      {name, value}\n    end\n  end\n\n  # Plugins support is experimental, undocumented, and likely won't make the new release.\n  defp run_plugins(request, [plugin | rest]) when is_atom(plugin) do\n    if Code.ensure_loaded?(plugin) and function_exported?(plugin, :attach, 1) do\n      run_plugins(plugin.attach(request), rest)\n    else\n      run_plugins(plugin.run(request), rest)\n    end\n  end\n\n  defp run_plugins(request, [plugin | rest]) when is_function(plugin, 1) do\n    run_plugins(plugin.(request), rest)\n  end\n\n  defp run_plugins(request, []) do\n    request\n  end\n\n  @doc false\n  @deprecated \"Manually build Req.Request struct instead\"\n  def build(method, url, options \\\\ []) do\n    %Req.Request{\n      method: method,\n      url: URI.parse(url),\n      headers: Keyword.get(options, :headers, []),\n      body: Keyword.get(options, :body, \"\")\n    }\n  end\nend\n" :textDocument
                 (:uri "file:///Users/james/src/req/lib/req.ex")))
[server-notification] Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :method "$/progress" :params
          (:token "0IMmxrOY" :value
                  (:kind "begin" :title "Compiling ~/src/req/...")))
[server-notification] Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :method "window/logMessage" :params
          (:message "[NextLS] Compiling 1 file (.ex)" :type 4))
[server-notification] Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :method "$/progress" :params
          (:token "_Tds8WWr" :value
                  (:kind "begin" :title "Indexing!")))
[server-notification] Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :method "window/logMessage" :params
          (:message "[NextLS] Compiled ~/src/req/!" :type 4))
[server-notification] Wed Oct 11 00:02:12 2023:
(:jsonrpc "2.0" :method "$/progress" :params
          (:token "0IMmxrOY" :value
                  (:kind "end" :message "Compiled ~/src/req/!")))
[server-notification] Wed Oct 11 00:02:13 2023:
(:jsonrpc "2.0" :method "$/progress" :params
          (:token "_Tds8WWr" :value
                  (:kind "end" :message "Finished indexing!")))

@goofansu goofansu changed the title Move nextls to bin [nix] Move nextls to bin Oct 10, 2023
@mhanberg
Copy link
Collaborator

i have been formatting it with nixpkgs-fmt.

unless serokell/nixfmt is more popular, please format it with nixpkgs-fmt

i am getting a symlink permissions error when trying thid locally.

i think my nix-darwin or nix might be busted tho, will be able to look more into it next week (i'm on vacation right now)

@goofansu
Copy link
Contributor Author

goofansu commented Oct 10, 2023

@mhanberg

i have been formatting it with nixpkgs-fmt.

Ok, I use nixfmt because the Emacs nix-mode uses it by default. I’ll remove the format commit.

i think my nix-darwin or nix might be busted tho, will be able to look more into it next week (i'm on vacation right now)

I’m using nix-darwin too. Have a nice vacation!

@goofansu goofansu force-pushed the copy-nextls-to-bin branch 2 times, most recently from 052f68f to f3e466f Compare October 11, 2023 00:39
@goofansu goofansu changed the title [nix] Move nextls to bin Fix nextls command not found when installing with nix Oct 11, 2023
@goofansu goofansu changed the title Fix nextls command not found when installing with nix Fix nextls command not found when installing with Nix Oct 11, 2023
@tcoopman
Copy link

This is not entirely on topic, I'm a bit of a nix novice. I was wondering how I'd use this flake.nix file outside of nix profile, for example, what if I want to use next-ls inside a flake file that gets activated with .envrc: use flake.

@goofansu
Copy link
Contributor Author

@tcoopman The method is to use the flake outputs in your flake.nix as the input.

Show the flake outputs:

nix flake show github:elixir-tools/next-ls

Use it in your flake.nix. The example is based on the template: nix flake new -t github:nix-community/nix-direnv.

{
  description = "A basic flake with a shell";
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.next-ls.url = "github:elixir-tools/next-ls";
  # or local
  # inputs.next-ls.url = "path:/local-path-to-next-ls";

  outputs = { self, nixpkgs, flake-utils, next-ls }:
    flake-utils.lib.eachDefaultSystem (system: let
      pkgs = nixpkgs.legacyPackages.${system};
      nextls = next-ls.packages.${system}.default;
    in {
      devShells.default = pkgs.mkShell {
        packages = [ pkgs.bashInteractive nextls ];
      };
    });
}

@mhanberg
Copy link
Collaborator

I confirmed this works.

I had to completely uninstall nix from my mac first, then reinstall 😅. It was goofed up somehow.

@mhanberg mhanberg merged commit 1112525 into elixir-tools:main Oct 16, 2023
3 checks passed
@goofansu
Copy link
Contributor Author

goofansu commented Oct 16, 2023

@mhanberg Cool! It feels good because the re-installation is reliable. I’ve re-installed Nix serveral times, so the uninstallation link appears in the References of my nix-config: https://git.sr.ht/~goofansu/nix-config#references

@goofansu goofansu deleted the copy-nextls-to-bin branch October 16, 2023 14:04
@goofansu goofansu restored the copy-nextls-to-bin branch October 16, 2023 15:49
@goofansu goofansu deleted the copy-nextls-to-bin branch October 16, 2023 15:49
@goofansu
Copy link
Contributor Author

goofansu commented Oct 16, 2023

@mhanberg Just found the commit (bf7be10) that formats the flake.nix file with nixfmt was included in the force-push. If you are using nixpkgs-fmt, please re-format it, thanks.

@mhanberg
Copy link
Collaborator

Oh, good catch. thanks for that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants