Skip to content

v25.0.0-pre-1

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 27 Aug 21:49
8fdeb8d

Enhancements

  • #3925 @sh41
    • File and line are now linked inside an inspected stack trace. A crash report often carries
      its trace as a term rather than a formatted trace, putting each frame's location in a keyword
      list - [file: 'lib/gald/phase.ex', line: 75]. Only the formatted (app) path:line: frames
      were clickable, so the frame that named the failing call had to be found by hand. Every location
      on the line is linked now, and a path inspected as a ~c sigil is read the same as a plain
      charlist. Where inspect wrapped the entry so the number sits on its own line, the path still
      navigates to that line in the Mix, Elixir, Distillery and test-runner consoles; in the IEx
      consoles it opens the file, because a filter there is given one line at a time with no way to
      reach the next. Refs #510.
    • Stack traces are now linked in the Terminal tool window as well. iex -S mix, mix test
      and mix phx.server run from the Terminal had no Elixir linking at all, because the filters
      were only ever attached to consoles the plugin's own run configurations built. They are now
      contributed to every console the IDE builds for a project with an Elixir module or SDK, and on
      the reworked terminal engine a wrapped entry links to its exact line rather than to the top of
      the file.
    • Erlang, HEEx and LEEx locations in a trace are now linked too. A stack trace mixes them with
      Elixir freely, but only .ex, .exs and .eex were recognised, so an Erlang dependency's frame
      stayed plain text beside the Elixir frames around it. Whether a path then opens still depends on
      the file being indexed - see the Erlang SDK source roots below.
    • An Erlang SDK now exposes its own sources. OTP ships them beside the compiled beams, in
      lib/<app>-<version>/src, but only the ebin directories were registered, so an OTP frame in a
      stack trace named a file nothing indexed could find and gen_server.erl was not navigable.
      Existing SDKs pick the roots up on the next refresh.
    • External Libraries now shows an SDK application's source beside its beams. A tree node for an
      application that ships both is now the application itself, holding ebin and the lib or src
      next to it; one shipping only beams is unchanged. An SDK node's children are its class roots
      alone, so the source directory has to be put there deliberately - registering it as a source root
      makes it searchable, not visible.
  • #3923 @sh41
    • Elixir and Erlang SDKs under /usr/lib64 are now detected automatically. Gentoo builds both
      with the multilib libdir, and Fedora does for Erlang, so the SDK had to be selected by hand on
      those distributions even though the path was valid. Refs
      #312.
    • Elixir SDKs under /usr/share/elixir/<version> are now detected automatically. Fedora and
      RHEL package Elixir there rather than under a libdir; the version is read from the directory
      name, so several installed versions are offered separately.
    • Homebrew Elixir installed since 2024-09-22 is now detected and accepted. Homebrew changed to
      the Makefile's install target, which nests the SDK home in lib/elixir instead of placing it
      directly in the version directory. Installs predating the change keep working. Refs
      #3670.
    • Homebrew SDKs on Apple Silicon are now detected. Only the Intel /usr/local/Cellar prefix
      was scanned, never /opt/homebrew/Cellar.
    • Selecting an install prefix in the SDK chooser now finds the home inside it. A prefix such
      as a Homebrew version directory, /usr or /usr/local holds the SDK in lib/<tool> and only
      symlinks in bin, so picking the directory a user naturally lands on was rejected as an invalid
      home with no hint of where the real one was. Erlang had no adjustment at all. Refs
      #3670,
      #312.
    • Version-pinned Homebrew formulae are now detected. erlang@25 through erlang@28 live
      under their own Cellar directory rather than beside the unpinned versions, so a pinned OTP
      release - the usual way to hold an OTP version for a given Elixir - was never offered.
    • macOS now detects SDKs installed by the elixir-install script. Every platform now scans
      the same set of sources, so a source can no longer be present on one platform and missing on
      another.
    • Homebrew SDKs on Linux and WSL are now detected. Homebrew's Linux prefix
      (/home/linuxbrew/.linuxbrew) was never scanned on any platform, and a Homebrew home there is
      now labelled as such in the SDK list.
  • #3914 @sh41
    • Elixir 1.13 through 1.20 are now fully supported. Code written for any Elixir from 1.13.4 to
      1.20.2 parses without spurious errors, including syntax whose meaning changed between releases.
    • .beam files compiled by OTP 24 through 29 decompile to valid Elixir.
  • #3696 @mwnciau, @sh41
    • .heex files are now recognized as HEEx, with dedicated syntax highlighting for {@assigns}/
      {expressions}, <% %>/<%= %> tags, and <%!-- ... --%> HEEx comments.
    • ~H sigils now use the same HEEx language as .heex files, with separate HTML and Elixir
      PSI roots, instead of being treated as plain HTML text. Opt-in via Settings → Languages &
      Frameworks → Elixir → Experimental → "Enable ~H Sigil HEEx language injection".
    • <.component> and <Module.component> tags now resolve to their def/defp definition -
      local components, components brought in via an explicit import, and components brought in via
      use MyAppWeb, :html all navigate to their definition. A dotted name that is not valid component
      syntax is flagged by HtmlUnknownTagInspection like any other unknown tag.
    • Find Usages and Rename on a def/defp include its HEEx component tags, in .heex files
      and inside ~H sigils; a renamed tag keeps its ./module-alias prefix.
    • Rename works with the caret on a component tag, not only on the def/defp.
    • Quick Docs and hover on a component tag show the function's documentation, including inside
      a ~H sigil.
    • Find Usages finds a plain Elixir call embedded in a ~H sigil, e.g. {some_function()}.

Bug Fixes

  • #3925 @sh41
    • A console path written with backslashes now links on Windows. A compile error prints the
      path the way the platform writes it, while the virtual file system holds forward slashes, and
      the two were compared without normalising either - so on the one platform where every console
      path looks like that, the frame resolved to nothing.
  • #3924 @sh41
    • Variable completion no longer shows a parameter's name twice. A parameter that is not bound
      by a match is its own enclosing match, so the match appended after the name only repeated it.
      Variables bound by a match still show that match, which is what makes the tail text useful.
      Fixes #496.
  • #3923 @sh41
    • Homebrew Erlang SDKs no longer report an unknown version. The version was read from the
      home path after the Homebrew layout adjustment had been applied, so every Homebrew Erlang was
      keyed on the literal string erlang instead of its version, leaving them unsorted and
      unlabelled in the SDK list.
  • #3696 @mwnciau, @sh41
    • \{ and \} in HEEx are now literal braces instead of affecting {...} expression nesting.
    • A component tag's attribute after a {...}-valued one no longer gets swallowed into that
      value
      , e.g. <.tag one={""} class=""/> now parses class as its own attribute.
    • { inside <script>/<style> stays literal after an embedded <% %> tag, and
      </script>/</style> still close the tag.
    • A self-closing <script .../> or <style .../> no longer swallows the rest of the file as
      script or style content.
    • <% %> tags that produce no output (comments, <% if %>) no longer inject placeholder text
      into the HTML tree.
    • Other HTML-based template languages are no longer affected by HEEx's outer-language patcher,
      which ran for every HTML-data template language in the IDE.
    • HEEx's special attributes and phx- bindings are no longer reported as "not allowed here"
      on HTML tags
      : :let, :if, :for, :key, :type and every phx-* binding.
    • <:slot> tags are no longer validated as HTML elements. <:col> was checked against HTML's
      <col> and <:action> reported as an unknown tag.
    • A component tag that doesn't resolve no longer shows "Cannot resolve symbol".
    • Components brought into scope by a use nested inside use MyAppWeb, :html now resolve,
      such as Phoenix.Component's <.link> and <.live_title>: use resolution now follows a
      __using__ whose body ends in a list of fragments, a quote bound to a variable, or another
      use.
    • Rename and Find Usages on a component tag could miss the tag, varying between IDE sessions:
      at a tag's offset the Elixir root of a .heex file or ~H sigil could win over the HTML root.
    • An unqualified call inside a ~H sigil now resolves to a def in the surrounding module.
  • #3914 @sh41
    • Reformat Code no longer changes what a capture expression means. Since Elixir 1.15,
      &1 and & 1 are different expressions; the formatter was inserting that space, silently
      turning &(&1 + &2) into code meaning &(&(1 + &2)).
    • & 1 now parses the way the containing module/project's configured Elixir SDK parses it. The
      plugin previously always used the pre-1.15 meaning.
      • On Elixir 1.15 and higher: & applied to the whole following expression.
      • On Elixir 1.14 and lower: the single capture argument &1.
    • The stepped-range atom :..// no longer shows a parse error. It was previously read as
      :.. followed by a stray //.
    • Decompiled .beam files no longer show a parse error when a cond or case clause condition
      ends in end
      . This fixes decompilation of Mix.Project, Mix.Release, and Mix.Task on
      Elixir 1.20+.
  • #3919 @sh41
    • New Elixir projects get the right compiler output directory. Leaving --app blank in the
      New Project wizard - which is allowed, and is what most people do - configured the module with
      _build/dev/lib/ebin instead of _build/dev/lib/<app>/ebin. It now falls back to the project
      name, which is what mix new itself uses.
    • --sup is no longer offered for umbrella projects. mix new ignores it at an umbrella root
      without reporting anything, so ticking it appeared to work and silently did nothing.
    • New umbrella projects no longer get a stray empty lib/ or a compiler output directory that
      never exists.
      An umbrella root has no application of its own, so neither applies to it.
    • New Elixir projects and modules are no longer reported as having "an outdated format". Every
      project the plugin created was offered for conversion the next time it was opened, because the
      module was written with compiler-output exclusion switched on - the exact setting the plugin's
      converter exists to remove. Elixir compiles to _build, so the setting never applied.
    • Umbrella sub-apps now get their lib/ and test/ marked. mix new writes an app from an
      external process, so the IDE could hold a stale view of the directory that did not include its
      mix.exs - and every folder-mark scan skipped the app in silence because of it. The New Project
      wizard, Reconfigure Elixir Module Setup and the module-setup check now refresh first.
  • #3921 @sh41
    • Variables bound by a macro call in a match now resolve. session(id, user) = raw binds all
      of the macro's arguments, but every use of them was reported as unresolved: only three Kernel
      names were recognised as binding, and any other parenthesised call was assumed to be a function,
      whose arguments are values. The call is now resolved to decide whether it is a macro. Calls that
      resolve to a function are unaffected, as are macros that cannot be resolved at all.
  • #3918 @sh41
    • Saved run configurations no longer record the module twice. Every Elixir run configuration
      wrote a second module element on top of the one the IDE already writes, which the platform
      logs as "Module serialized more than one time".
    • "Include system environment variables" is now remembered. The setting was accepted in the
      run configuration editor but silently discarded when the configuration was saved.
    • A run configuration whose module is not loaded yet keeps it. Reading a saved configuration
      before its module exists no longer clears the module instead of leaving the IDE to resolve it.
  • #3915 @sh41
    • The IDE no longer starts every WSL distro that hosts a registered Erlang or Elixir SDK, and
      will no longer freeze if WSL is slow or hangs while starting.
      Checking whether two WSL-hosted
      SDKs are the same no longer touches the distro's filesystem.

Build / CI

  • #3913 @sh41
    • Quoter tests now respect the quoting rules for the Elixir version under test. Six quoted-form
      divergences are gated on the release that introduced each, so the same fixtures pass on every
      Elixir/OTP pair CI tests.
    • A quoter that fails to build no longer blocks the whole test suite. Tests that require the
      quoter fail immediately with the recorded reason; all other tests run as normal.
      -PquoterRequired=true restores the hard stop for anyone debugging the quoter itself.
    • CI gets the quoter cache paths from the build (a quoterCachePaths task) instead of
      re-deriving them in bash, so the workflow can no longer disagree with Gradle about where the
      cache lives.
    • The quoter is pinned to a commit of sh41/intellij_elixir which can be built without warnings
      on all Elixir versions 1.13-1.20
      , pending merge/tagging of the
      PR.
    • The quoter builds with an explicit MIX_ENV=prod, and only prod dependencies are fetched. An exported MIX_ENV still overrides it.
  • #3914 @sh41
    • All Elixir/OTP test legs now pass and are required for merge. Getting there also gated two
      more quoted-form divergences by version (1.20's __block__ line metadata, pre-1.17 parens
      metadata) and froze copies of stdlib files that newer Elixirs deleted, so the parsing corpus no
      longer shifts underneath the tests.
  • #3916 @sh41
    • testUI builds and runs again. kodein-di-jvm and kotlinx-coroutines-core-jvm were
      silently dropped from its dependencies by an earlier commit; both are genuinely required.
    • The released plugin now compiles against 2025.3, its declared minimum supported version,
      instead of a newer platform - closing a gap where only the post-release Plugin Verifier check
      stood between an incompatibility and a real user's install.
    • The shipped plugin no longer accidentally bundles its own copy of kotlin-stdlib.
    • Bumped gradle-wrapper to 9.7.0 (with its distribution checksum now verified),
      org.jetbrains.changelog to 2.5.0, and migrated com.github.ben-manes.versions to the
      maintained io.github.ben-manes.versions id at 0.61.0. Dropped the unused qodana version
      catalog entry (qodana.yml's linter tag is the only declaration now, bumped to 2026.2).
  • #3887, #3917 @dependabot
    • Bumped kodein-di-jvm to 7.33.0 and gradle-wrapper to 9.7.1.