<!--
  SPDX-License-Identifier: Apache-2.0
  SPDX-FileCopyrightText: 2020 The Gleam contributors
-->

# Changelog

## Unreleased

### Compiler

- The compiler now issues a friendlier error when attempting to pattern match
  on both the prefix and suffix of a string:

  ```
  error: Syntax error
    ┌─ /src/parse/error.gleam:2:23
    │
  2 │     "prefix" <> infix <> "suffix" -> infix
    │                       ^^^^^^^^^^^ This pattern is not allowed

  A string pattern can only match on a literal string prefix.

  Matching on a literal suffix is not possible, because `infix` would have an
  unknown size.
  ```

  ([Gavin Morrow](https://github.com/gavinmorrow))

- Improved the error message shown when using an invalid discard name for
  functions, constants, module names, and `as` patterns.
  ([Giacomo Cavalieri](https://github.com/giacomocavalieri))

- The compiler now generates singleton values for variants with no fields on the
  JavaScript target, allowing for faster comparison in most cases.
  ([Surya Rose](https://github.com/GearsDatapacks))

### Build tool

- The build tool now generates Hexdocs URLs using the new format of
  `package.hexdocs.pm` rather than `hexdocs.pm/package`.
  ([Surya Rose](https://github.com/GearsDatapacks))

- More readable error message when trying to revert an old release.
  ([Moritz Böhme](https://github.com/MoritzBoehme))

### Language server

- The language server now supports go-to-definition, find-references and rename
  for record fields. These work on the field declaration, on labelled arguments,
  on labelled patterns, on record updates and on `record.field` accesses, both
  within a module and across modules. For example:

  ```gleam
  pub type Person {
    Person(name: String, age: Int)
  }

  pub fn main() {
    let lucy = Person(name: "Lucy", age: 10)
    lucy.name
    //   ^ Go-to-definition jumps to the `name` field, and renaming it here
    //     renames the field everywhere it is used.
  }
  ```

  ([Alistair Smith](https://github.com/alii))

- The "pattern match on value" code action can now be used to pattern match on
  values returned by function calls. For example:

  ```gleam
  pub fn main() {
    load_user()
  // ^^ Triggering the code action over here
  }

  fn load_user() -> Result(User, Nil) { todo }
  ```

  Will produce the following code:

  ```gleam
  pub fn main() {
    case load_user() {
      Ok(value) -> todo
      Error(value) -> todo
    }
  }
  ```

  ([Giacomo Cavalieri](https://github.com/giacomocavalieri))

- The "remove unreachable patterns" code action can now be triggered on
  unreachable alternative patterns of a case expression.
  ([Giacomo Cavalieri](https://github.com/giacomocavalieri))

- The language server now permits renaming type variables in functions, types,
  and constants. For example:

  ```gleam
  pub fn twice(value: a, f: fn(a) -> a) -> a {
    //                ^ Rename to "anything"
    f(f(value))
  }
  ```

  Produces:

  ```gleam
  pub fn twice(value: anything, f: fn(anything) -> anything) -> anything {
    f(f(value))
  }
  ```

  ([Surya Rose](https://github.com/GearsDatapacks))

- The language server now automatically updates imports when a Gleam module is
  renamed. For example:

  ```gleam
  import db_users

  pub fn main() -> db_users.User {
    db_users.new("username")
  }
  ```

  Renaming `db_users.gleam` to `database/user.gleam` would produce:

  ```gleam
  import database/user

  pub fn main() -> user.User {
    user.new("username")
  }
  ```

  ([Surya Rose](https://github.com/GearsDatapacks))

- The language server now offers a code action to generate a missing type
  definition when an unknown type is referenced. For example, if `Wibble`
  is not defined:

  ```gleam
  pub fn run(data: Wibble(Int)) { todo }
  ```

  The code action will generate:

  ```gleam
  pub type Wibble(a)

  pub fn run(data: Wibble(Int)) { todo }
  ```

  ([Daniele Scaratti](https://github.com/lupodevelop))

### Formatter

- Performance of the formatter has been improved.
  `gleam format` has been measured to be up to 13% faster on projects like
  `lustre`, with a 10% smaller peak memory footprint.
  ([Giacomo Cavalieri](https://github.com/giacomocavalieri))

### Bug fixes

- When using the language server to extract a function from within an anonymous
  function, the return value of the extracted function is respected.

  For example,

  ```gleam
  fn wibble() {
    let wobble = fn() {
      let random_number = 4
      random_number * 42 // <- Extracting this line
    }
  }
  ```

  is turned into

  ```gleam
  fn wibble() {
    let wobble = fn() {
      let random_number = 4
      function(random_number)
    }
  }
  fn function(random_number: Int) -> Int {
    random_number * 42
  }
  ```

  ([Gavin Morrow](https://github.com/gavinmorrow))

- Work around an ambiguity of the language server protocol that resulted in
  editors like Zed inserting the wrong text when accepting type completions.
  ([Giacomo Cavalieri](https://github.com/giacomocavalieri))

- Fixed a bug where the post-publish message for pushing a git commit was
  formatted incorrectly.
  ([Louis Pilfold](https://github.com/lpil))

- Fixed a bug where the compiler would generate invalid TypeScript type
  definitions for records with a field named `constructor`.
  ([Giacomo Cavalieri](https://github.com/giacomocavalieri))

- Fixed a bug where the compiler would raise a warning for truncated int
  segments when compiling a function with a JavaScript external.
  ([Giacomo Cavalieri](https://github.com/giacomocavalieri))

- A `gleam@@compile.erl` is no longer left in the build output of
  `gleam compile-package`.
  ([Louis Pilfold](https://github.com/lpil))

- When using the language server to extract a function from within the body of a
  use statement, only the selected statement(s) are extracted.

  For example,

  ```gleam
  pub fn wibble() {
      use wobble <- result.map(todo)
      echo wobble as "1" // <- Extracting this line
      echo wobble as "2"
  }
  ```

  is turned into

  ```gleam
  pub fn wibble() {
      use wobble <- result.map(todo)
      function(wobble)
      echo wobble as "2"
  }
  fn function(wobble: a) -> Nil {
    echo wobble as "1"
    Nil
  }
  ```

  ([Gavin Morrow](https://github.com/gavinmorrow))

- Fixed a bug where the JavaScript code generator could produce duplicate `let`
  declarations when a variable was reassigned after being shadowed inside a
  directly matching `case` branch.
  ([Eyup Can Akman](https://github.com/eyupcanakman))
