KronicDeth

KronicDeth

IntelliJ Elixir - Elixir plugin for JetBrain's IntelliJ Platform

Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine)

This is a plugin that adds support for Elixir to JetBrains IntelliJ IDEA platform IDEs (DataGrip, AppCode, IntelliJ IDEA, PHPStorm, PyCharm, Rubymine, WebStorm).

It works with the free, open source Community edition of IntelliJ IDEA in addition to the paid JetBrains IDEs like Ultimate edition of IntelliJ. No feature is locked to a the paid version of the IDEs, but the plugin works best in IntelliJ because only IntelliJ supports projects with different languages than the default (Java for IntelliJ, Ruby for Rubymine, etc).

The plugin itself is free. Once you have your IDE of choice installed, you can install this plugin.

https://github.com/KronicDeth/intellij-elixir

289 36128 110

Most Liked

KronicDeth

KronicDeth

v4.5.0 was a canary release, so it’s release notes are included in this general release in case you didn’t run the canary

Thanks

  • Thanks to Matt Briggs (@mbriggs) and Andrei Dziahel (@develop7) for reporting the NullPointerException from org.elixir_lang.psi.scope.call_definition_clause.Variants.getLookupElementCollection.
  • Thanks to Sergey Zubtsovskiy (@szubtsovskiy) for reporting StackOverflowErrors from certain forms of with and helping me narrow down specific minimal reproduction cases.
  • Thanks to @mdhirsch for finding a parser bug (!) after all this time: newlines weren’t allowed before do for do blocks.
  • Thanks to Scott Bennett (sbennett33) for finding a case that triggered the ElixirNoParenthesesStrict error handling, which revealed that isVariable didn’t handle it correctly.
  • Thanks to Andrei Dziahel (@develop7) for reporting an error that while I couldn’t reproduce did lead to an improved error reporter, so I can figure it out if it happens again.
  • Thanks to Danni Friedland (BlueHotDog) for reporting a bug that led me to find that Prefix.primaryArguments wasn’t using Normalized and still was using basic asserts.
  • Thanks to Aaron Foster (AnimalRepellentGranules) for reporting that the do end matching was too aggressive and incorrectly matched on one liners starting at the do:.

Changelog

v4.6.0

Enhancements

Bug Fixes

  • #454 - Return emptySet when lookupElementByPsiElement is null. - @KronicDeth
  • #455 - @KronicDeth
    • Don’t do a naked assert that there are 2 children because this can fail during error recovery on the operand, instead use the prefix.Normalized.operand() through prefix.operand().

      WARNING: This changes the @NotNull array so that its sole element changes from @NotNull to @Nullable. It may trigger new bugs.

  • #461 - Use shipped GeneratedParserUtilBase.DUMMY_BLOCK because the DUMMY_BLOCK MUST match the GeneratedParserUtilBase to detect dummy blocks inserted for error handling. - @KronicDeth
  • #465 - Skip over ElixirNoParenthesesStrict for isVariable - @KronicDeth
  • #466 - Allow newlines before do in doBlock - @KronicDeth
  • #467 - Don’t match do or fn to end when used as a keyword key. - @KronicDeth
  • #474 - @KronicDeth
    • Check if iterator.atEnd() before calling iterator.getTokenType() to avoid IndexOutOfBounds exception.
    • Don’t add current call definition clause being written to completion
  • #476 - When#leftOperand will return null (because it’s normalized) if there are left-hand error elements, but when stripping guards we want best-effort to match human expectations, so don’t use normalized null, but use left, non-error element if it is unique. - @KronicDeth
  • #477 - Highlight types in QualifiedNoParenthesesCall - @KronicDeth
  • #478 - Still not obvious why name for a CallDefinitionClause lookup renderer can be longer than presentableText, so still log an error, but with Logger.error, so we get name, presentableText, and the original element. - @KronicDeth
  • #479 - @KronicDeth
    • Skip Arguments elements in previousParentExpresion to eliminate an unnecessary level of processing declarations since calls will enter their arguments.
    • Only put new ENTRANCE in ResolveState in variable.MultiResolve.resolveResultList, so that caller can override the default value.
    • Set ENTRANCE to matchAncestor instead of previous expression to eliminate the looping that occurred when a variable was unbound (or a function) because the check for with (and for) was expecting the ENTRANCE to be the previous child expression instead of the with clause as a whole (or the Arguments element as had been the case before 6fcc19b).
  • #483 - @KronicDeth
    • Resolves functions qualified by Aliases that are either direct Module references or one-step aliases.
    • Remove Call#resolvedFunctionName because import can’t rename functions.
  • #484 - Don’t type-highlight BracketOperations as they occur when putting maps or structs in front of lists. - @KronicDeth
  • #485 - Treat Enum.each the same as Enum.map around def - @KronicDeth
  • #486 - Increase resolvedFinalArity by 1 for piping. - @KronicDeth
  • #498 - @KronicDeth
    • Go To Declaration resolves through import
      • for import MyModule
        • the import statement
        • the call definition clause in the imported Module.
      • for import MyModule, only: [name: arity]
        • the import statement
        • the call definition clause in the imported Module.
      • for import MyModule, except: [name: arity] if reference is not name/arity.
        • the import statement
        • the call definition clause in the imported Module.

v4.5.0

Enhancements

  • #452 - @KronicDeth
    • Go To Declaration for functions and macros (only those defined in parseable-Elixir source. References to Erlang functions or only those available in .beam file, such as the standard library will not resolve.)
    • Completion for functions and macros (only those defined in parseable-Elixir source. Erlang functions and Elixir function only in compiled .beam file, such as the standard library will not complete.)
      • Completion uses the same presentation as Structure View, so the you can tell whether the name is a function/macro, whether it is public/private, and the Module where it is defined.
      • Completed functions/macro insert () after the name in preparation for Elixir 1.4 where it is an error to have bare function calls. It also makes it more obvious that you inserted a function and not a variable.
      • Completion works for all functions when a bare identifier is used. For a qualified identifier, only functions/macros under than Module are shown.

README Changes

Completion

Function and Macro Calls

Completion uses the same presentation as Structure, so you can tell whether the name is function/macro (Time), whether it is public/private (Visibility) and the Module where it is defined. Between the icons and the Modules is the name itself, which is highlighted in bold, the parameters for the call definition follow, so that you can preview the patterns required for the different clauses.

Qualified

Qualified functions and macro calls will complete using those functions and macros defined in the qualifying Module (defmodule), Implementation (defimpl) or Protocol (defprotocol). Completion starts as shown as . is typed after a qualifying Alias.

Unqualified

Function and macro calls that are unqualified are completed from the index of all function and macro definitions, both public and private. (The index contains only those Elixir functions and macro defined in parsable source, such as those in the project or its dependencies. Erlang functions and Elixir functions only in compiled .beam files, such as the standard library will not complete.) Private function and macros are shown, so you can choose them and then make the chosen function or macro public if it is a remote call.

Go To Declaration

Function or Macro

You’ll know if function or macro usage is resolved and Go To Declaration will work if the call is annotated, which in the default themes will show up as italics.

Imported Functions or Macros
  1. Place the cursor over name of the function or macro call.
  2. Activate the Go to Declaration action with one of the following:
    1. Cmd+B
    2. Select Navigate > Declaration from the menu.
    3. Cmd+Click
  3. A Go To Declaration lookup menu will appear, allowing you to jump to either the import that imported the function or macro or jumping directly to the function or macro definition clause. Select which declaration you want.
    1. Use arrow keys to select and hit Enter
    2. Click
Local Functions or Macros
  1. Place the cursor over name of the function or macro call.
  2. Activate the Go to Declaration action with one of the following:
    1. Cmd+B
    2. Select Navigate > Declaration from the menu.
    3. Cmd+Click
  3. Whether a lookup a Go To Declaration lookup menu appears depends on the number of clauses in the function or macro definition:
    1. If there is only one clause in the function or macro definition, you’ll jump immediately to that clause
    2. If there is more than one clause in the function or macro definition, a Go To Declaration lookup menu will appear, allowing you to jump to either the import that imported the function or macro or jumping directly to the function or macro definition clause. Select which declaration you want.
      1. Use arrow keys to select and hit Enter
      2. Click
Remote Functions or Macros
  1. Place the cursor over name of the function or macro call that is qualified by an Alias.
  2. Activate the Go to Declaration action with one of the following:
    1. Cmd+B
    2. Select Navigate > Declaration from the menu.
    3. Cmd+Click
    1. If there is only one clause in the function or macro definition, you’ll jump immediately to that clause
    2. If there is more than one clause in the function or macro definition, a Go To Declaration lookup menu will appear, allowing you to jump to either the import that imported the function or macro or jumping directly to the function or macro definition clause. Select which declaration you want.
      1. Use arrow keys to select and hit Enter
      2. Click

Installation

Inside IDE using JetBrains repository

  1. Preferences
  2. Plugins
  3. Browse Repositories
  4. Select Elixir
  5. Install plugin
  6. Apply
  7. Restart the IDE

Inside IDE using Github releases

In browser

  1. Go to releases.
  2. Download the lastest zip.

In IDE

  1. Preferences
  2. Plugins
  3. Install plugin from disk…
  4. Select the downloaded zip.
  5. Apply
  6. Restart the IDE.
14
Post #5
KronicDeth

KronicDeth

Thanks

  • Thanks to Jake Becker (@JakeBecker) for adding Mix ExUnit Run Configurations and create from context.
  • Thanks to @andyl for requesting Navigate > Test and Navigate > Test Subject as it was a good complement to Jake Becker’s new Mix ExUnit Run Configurations
  • Thanks to Alexander Merkulov (@merqlove) for outline the testing workflow that Jack Becker ended up implementing
  • Thanks to @davit55 and Matt Briggs (@mbriggs) for confirming that lookup name could exceed the element text and it wasn’t just an artifact of my development environment
  • Thanks to @taorg for a full test case to show how MultipleAliases would need to be supported in isVariable
  • Thanks to Josh Taylor (@joshuataylor for posting a screenshot of the bad lookup formatting for variables.
  • Thanks to Matt Briggs (@mbriggs) for posting an error about the error reporter :squinting_face_with_tongue:
  • Thanks to Josh Taylor (@joshuataylor, Matt Briggs (@mbriggs), Cris (@crisonyx), @sngyai, @lucdang, Cris (@crisonyx), Sven Marquardt (@Eiamnacken), and Aaron Eikenberry (@aeikenberry) for reporting that CallDefinitionClause(Call) needed between error handling to avoid a NullPointerException
  • Thanks to Matt Briggs (@mbriggs) for posting the source for a reproduction-case for the StackOverflow that was plaguing @andshape, Robert Hencke (@rhencke), Alexander Merkulov (@merqlove), @fieldinrain, Roman (@roman462), Andrei Dziahel (@develop7), and Josué Henrique Ferreira da Silva (@josuehenrique)
  • Thanks to Tiziano Puppi (@tizpuppi) for demonstrating how a typing a typo could cause an error in variable use scope.
  • Thanks to nsm (@nsmuffin) for posting that working directory being null wasn’t treated the same as not being a directory.
  • Thanks to Ryan Scheel (@Havvy for showing how missing a : in type specs could break the highlighting, which led to the inspections and quick fixes in this release.

Changelog

v4.7.0

Enhancements

  • #523 - Use the CommonProgramParametersPanel to get the working directory and environment variables the same way the JUnit form does. Replace the custom “Command” input with the “Program arguments” input built into the CommonProgramParametersPanel. CommonProgramParametersPanel expects to store the “Program Arguments” in a “ProgramParameters” field, so old run configurations will lose their “Command” option value and it will be migrated to the new “ProgramParameters”. - @KronicDeth
  • #482 - @JakeBecker, @KronicDeth
    • Create / Run Mix ExUnit Run Configurations
      • Run Configuration from Directory
      • Run Configuration from File
      • Run Configuration from LIne
    • Run Configurations support Common Program Parameters
      • Program Arguments
      • Working directory
      • Environment variables
  • #531 - @KronicDeth
    • enclosingMacroCall returns enclosing macro call when parent is ElixirDoBlock, so that end element goes to the macro call.
    • Navigate > Test will go to the Module that has the same canonical name as the current defimpl, defmodule, defprotocol , or quote with a Test suffix added
    • Navigate > Test Subject will go to the defimpl, defmodule, defprotocol, or quote that has the same canonical name as the current Module with the Test suffix removed.
  • #533 - Regression test for #500 - @KronicDeth
  • #545 - Regression test for #517 - @KronicDeth
  • #548 - Regression test for #521 - @KronicDeth
  • #549 - @KronicDeth
    • Regression test for #525
    • If : is used instead of :: for a type specification, mark it as an error with a Quick Fix to convert : to ::.
    • Highlight = operands the same as :: operands in type specifications.
    • If = is used instead of :: in a type specification, mark it as an error with a Quick Fix to convert = to ::.

Bug Fixes

  • #523 - Fix typo: myRunInModuleChekcBox => myRunInModuleCheckBox - @KronicDeth
  • #532 - Don’t log error when name length exceeds presentable text length because it appears to be common for normal users and not a development environment artifact. - @KronicDeth
  • #533 - Check parent of ElixirMultipleAliases for isVariable because ElixirMultipleAliases can be hit in isVariable when MyAlias. is added on a line above a pre-existing tuple, such as when typing a new qualified call. - @KronicDeth
  • #534 - Add space between variable and match in lookup element presentation - @KronicDeth
  • #535 - Check VirtualFile is not null before creating attachment because PsiFile can lack a VirtualFile if the PsiFile only exists in memory. - @KronicDeth
  • #537 - Convert CallDefinitionClause(Call) to CallDefinitionClause.fromCall(Call), so that null can be returned when CallDefinitionClause.enclosingModular(Call) returns null. - @KronicDeth
  • #539 - @KronicDeth
    • Use functionName instead of getName when multiresolving unqualified functions because getName will return the Alias when called on defmodule.
    • maybeQualifiedCallToModular returned null BOTH (1) if the call was unqualified OR (2) if the call was qualified, but its modular could not be resolved, so qualified calls to .beam-only modules, like File.read! returned null because File could not be resolved to a modular. Remove maybeqQualifiedToModular and call qualifiedToModular when myElement is qualified. If the modular is null, then return an empty ResolveResult[] instead of looking for unqualified matches.
    • Pass maxScope to Module reference. maxScope is generally the containing file for the element, but when using Module to resolve imports, it is the import call’s parent element, so that the resolve doesn’t ricochet between the defmodule and its child, the import call until StackOverflowError.
  • #545 - A variable cannot be declared in update arguments, so return LocalSearchScope.EMPTY, the same as interpolation. - @KronicDeth
  • #548 - ElixirSystemUtil.getProcessOutput already allowed for an empty, invalid ProcessOutput when the workDir wasn’t a directory, so allow it to also be null and return the empty ProcessOutput. - @KronicDeth
  • #549 - @KronicDeth
    • If a single keyword pair is used for a type spec, treat : as a type for ::
    • Limit variable use scope for variables “declared” in module attributes to the module attribute because the variable can’t be declared there and it is really a variable usage without declaration.

README Changes

Inspections

Keyword pair colon (:) used in type spec instead of type operator (::)

Type specifications separate the name from the definition using ::.

@type name: definition

Replace the : with ::

@type name :: definition

Match operator (=) used in type spec instead of type operator (::)

Type specifications separate the name from the definition using ::.

@type name = definition

Replace the = with ::

@type name :: definition

Quick Fixes

Convert : to :: in type specs

If a type specification uses a single : instead of ::, then hit Alt+Enter on the : to change it to :: and fix the type spec.

Convert = to :: in type specs

If a type specification uses = instead of ::, then hit Alt+Enter on the = to change it to :: and fix the type spec.

Run Configurations

mix test

The mix test task gets a special type of Run Configuration, Elixir Mix ExUnit. Using this Run Configuration type instead, of the basic Elixir Mix Run Configuration will cause the IDE to attach a special formatter to mix test, so that you get the standard graphical tree of Test Results

Creating mix test Run Configurations Manually
  1. Run > Edit Configurations…
  2. Click +
  3. Select “Elixir Mix ExUnit”
  4. Fill in the “Program arguments” with the argument(s) to pass to mix test. Normally, this will be a directory like test, relative to the “Working directory”
  5. Fill in the “Working directory”
  • Type the absolute path to the directory.
  • Select the path using directory picker by clicking the ... button
  1. (Optionally) click the ... button on the “Environment variables” line to add environment variables.
  2. Click “OK” to save the Run Configuration and close the dialog
  3. Click the RUn arrow in the Toolbar to run the mix test task
  4. The Run pane will open showing the Test Results

While you can create Elixir Mix ExUnit run configurations manually using the Run > Edit Configurations... menu, it is probably more convenient to use the context menu.

Creating mix test Run Configurations from context

The context menu must know that the the directory, file, or line you are right-clicking is a test. It does this by checking if the current directory or an ancestor is marked as a Test Sources Root.

  1. In the Project pane, ensure your OTP application’s test directory is marked as a Test Sources Root
  2. Check if the test directory is green. If it is, it is likely a Test Sources Root. This color may differ in different themes, so to be sure you can check the context menu
  3. Right-click the test directory.
  4. Hover over “Mark Directory As >”
    * If “Unmark as Test Sources Root” is shown, then the directory is already configured correctly, and create from context will work.
    * If “Test Sources Root” is shown, then the directory need to be configured by clicking that entry
Creating/Running mix test Run Configurations from directory
  1. Right-click the directory in the Project pane
  2. Click “Run Mix ExUnit”, which will both create the Run Configuration and Run it.
  • If you want to only create the Run Configuration, select “Create Mix ExUnit” instead

Alternatively, you can use keyboard shortcuts

  1. Select the directory in the Project pane.
  2. Ctrl+Shift+R will create the Run Configuration and Run it.
Creating/Running mix test Run Configurations from file
  1. Right-click the file in the Project pane
  2. Click “Run Mix ExUnit”, which will both create the Run Configuration and Run it.
  • If you want to only create the Run Configuration, select “Create Mix ExUnit” instead

Alternatively, you can use keyboard shortcuts

  1. Select the directory in the Project pane.
  2. Ctrl+Shift+R will create the Run Configuration and Run it.

Finally, you can use the editor tabs

  1. Right-click the editor tab for the test file you want to run
  2. Click “Run Mix ExUnit”, which will both create the Run Configuration and Run it.
  • If you want to only create the Run Configuration, select “Create Mix ExUnit” instead
Creating/Running mix test Run Configurations from line

If you want to be able to run a single test, you can create a Run Configuration for a line in that test

  1. Right-click a line in the test file
  2. Click “Run Mix ExUnit”, which will both create the Run Configuration and Run it.
  • If you want to only create the Run Configuration, select “Create Mix ExUnit” instead

Alternatively, you can use keyboard shortcuts

  1. Place the cursor on the line you want to test
  2. Ctrl+Shift+R will create the Run Configuration and Run it.

Installation

Inside IDE using JetBrains repository

  1. Preferences
  2. Plugins
  3. Browse Repositories
  4. Select Elixir
  5. Install plugin
  6. Apply
  7. Restart the IDE

Inside IDE using Github releases

In browser

  1. Go to releases.
  2. Download the lastest zip.

In IDE

  1. Preferences
  2. Plugins
  3. Install plugin from disk…
  4. Select the downloaded zip.
  5. Apply
  6. Restart the IDE.
12
Post #2
KronicDeth

KronicDeth

With both the contribution of ExUnit Mix Tasks in 4.7.0 and the conversion of the build to Gradle for 5.0.0, I’ve added Jake Becker (@JakeBecker) as a Collaborator to the repo.

Thanks

  • Reporting the AssertionError in org.elixir_lang.code_insight.lookup.element_renderer.CallDefinitionClause.renderElement
  • Reporting examples where ElixirVariable could not be determined if it was a variable.
  • Reporting examples where ElixirMultipleAliases could not resolve variable in match.
  • Reporting examples of the annotator highlighting in the wrong file due to the call definition offset always being assumed to be in the same file.
  • Reporting Parameter variable style being incorrectly applied
  • Working with me to figure out that the template tags in the color preview were messed up
  • Reporting mismatch between inspection resource and class due to a copy-and-paste error
    • Markus Fischer (@mfn)
  • Reporting incorrect highlighting of functions with guards
  • Requesting configurable code-folding for module attributes
  • Pointing out it makes no sense for context menus for ExUnit to appear in non-Elixir projects
  • Reporting an example where MatchedUnqualifiedParenthesesCall could not be type highlighted
  • Reporting that function complete didn’t take into account the already typed prefix
  • Requesting completion of Aliases to .beam-only Module, which is what inspired me to attempt decompilation

Changelog

v5.0.0

Enhancements

  • #574 - @KronicDeth
    • Decompile .beam files
      • Structure view for decompiled .beam files
      • Index modules, functions, and macros exported by .beam files
      • Go To Symbol for Modules defined in .beam files (both SDK and deps)
        • Erlang using atoms (like :idna)
        • Elixir using Alias (like Enum)
      • Completion for Modules defined in .beam files (both SDK and deps)
        • Elixir using Alias (like Enum)
      • Completion for functions and macros exported by .beam files
      • Syntax highlighting
  • #579 - Regression test for #575 - @KronicDeth
  • #583 - @KronicDeth
    • Macros appear before functions in decompiled .beam files
      • Header for macro and function sections
  • #585 - @KronicDeth
    • Update ELIXIR_VERSION for 1.2.* from 1.2.3 to 1.2.6
    • Add ELIXIR_VERSION 1.3.4
    • Add ELIXIR_VERSION 1.4.0
    • Update IDEA for 2016.* to 2016.3.1
    • Show OtpErlangBitStr (and therefore OtpErlangBinary contents when tests fail
    • Quote binaries as to_charlist instead of to_char_list for Elixir >= 1.3. Depends on Elixir version of project SDK.
    • Use elixir instead of java VM, so now Erlang and Elixir don’t need to be built on travis-ci, but ant and the jdk need to be installed, but unlike Erlang and Elixir, there are tarballs for that, so this way is faster than the old method without depending on travis-ci cache.
  • #609 - @KronicDeth
    • If multiResolve causes a StackOverflow for org.elixir_lang.annotator.Callable.visitCall, then catch it and use errorreport logger to log the element.
    • Include file path in errorreport excerpt
    • Log element for StackOverflow related to imports
    • Regression test for #605.
    • Log LookupElement#getObject when LookupElement#getPsiElement is null to track down how it was null in #563.
  • #614 - Regression test for #559 - @KronicDeth
  • #504 - @JakeBecker
    • Switch to Gradle for builds.
      • ./gradlew runIde (or the runIde (VERSION) Run Configurations) will run IDEA in a sandbox with the development version of the plugin.
      • ./gradlew test (or the test (VERSION) Run Configurations) will run the main plugin and jps-builder tests.
      • The plugin can now be published with ./gradlew publishPlugin, BUT you’ll need to fill in publish* properties in gradle.properties. This will eventually allow for automated “nightlies” from successful Travis-CI builds on master.
  • #638 - The Callable annotator is meant for variables, parameters, and macro and function calls and declarations. The ModuleAttribute annotator handles module attribute declaration and usage, so we can save reference resolution time by skipping module attributes in Callable. - @KronicDeth
  • #640 - Allow module attribute folding to be configured. - @KronicDeth
  • #662 - @KronicDeth
    • Allow call definition heads to resolves to themselves for consistency with Aliases of defmodule.
    • Generalize Callable.callDefinitionClauseDefiner(Call): in addition to the current CallDefinitionClause, make it work for Implementation, Module, and Protocol.

Bug Fixes

  • #574 - Fix copy-paste errors in MatchOperatorInsteadOfTypeOperator - @KronicDeth
  • #579 - @KronicDeth
    • Subtract 1 from arity in .beam file when decompiling to defmacro calls because the Erlang function for Elixir macros has one addition argument: the first argument is the Caller of the macro.
    • If the name of the decompiled macro/function is an infix operator, then decompile the head as a binary operation instead of a normal prefix name as infix operators aren’t valid prefix names and led to parsing errors, which was the root cause of #575.
    • Fix IntelliJ warnings in BeamFileImpl
    • Remove unused VirtualFile argument to BeamFileImpl#buildFileStub.
  • #583 - @KronicDeth
    • Add ++, =~, and in to INFIX_OPERATOR_SET.
    • Only render infix operators if arity is 2.
    • Prefix operator decompilation: + and - are both binary and unary operators. When a unary operator they need to be wrapped in parentheses, so that the call definition clause is parsed correctly.
  • #585 - @KronicDeth
    • Ignore JFLex jar
    • Don’t check for elixir-lang/elixr files remove in 1.3
    • Allow nil as a keyword key. nil was being lexed as a potential keyword key, but NIL was missing from the token list in the keywordKey grammar rule.
  • #599 - Some SpecialForms don’t work as literals as they would be interpreted as metaprogramming, so their name needs to be wrapped as an atom to unquote. - @KronicDeth
  • #600 - @KronicDeth
    • Check children of MultipleAliases for variable declarations.
    • Treat any variable declared in a MultipleAliases as invalid.
  • #609 - @KronicDeth
    • Skip import Kernel in kernel.ex to prevent stack overflow due to recursive import
    • Strip all outer parentheses for left type operand, so that (+value) can be see as + operator type spec.
    • Use advice from IndexNotReadyException documentation and check DumbService.isDumb(Project) before calling StubIndex.getElements in Module and module.MultiResolve.indexNameElements.
    • Don’t assert that LookupElement#getPsiElement is not null in CallDefinitionCluase.renderElement
    • Update to ant 1.10.1 because 1.10.0 is no longer hosted.
  • #612 - Yeah, it sounds weird, but an ElixirVariable isn’t necessarily a variable if it doesn’t occur in a declaration context. It could just be a no-parentheses function call in the wrong spot, so check the parent PsiElement to determine if ElixirVariable is a variable. - @KronicDeth
  • #614 - Highlight parameterized type head (maybe(t) in @type maybe(t)) the same as a full type definition (maybe(t) in @type maybe(t) :: t | nil) - @KronicDeth
  • #616 - Only show Mix ExUnit Run in context when the module, or when the module is not a available, the project SDK is Elixir. If there is no SDK configured, show “Mix ExUnit Run” in the menu. - @KronicDeth
  • #617 - Mark do: as atom in demo text - @KronicDeth
  • #627 - Annotations can only be applied to the single, active file, which belongs to the referrer Callable. The resolved may be outside the file if it is a cross-file function or macro usage, in which case it’s TextRange should not be highlighted because it is referring to offsets in a different file. - @KronicDeth
  • #634 - @KronicDeth
    • Variable scope for QualifiedMultipleAliases, which occurs when qualified call occurs over a line with assignment to a tuple, such as Qualifier.\n{:ok, value} = call()
    • Remove call definition clauses (function or macro) completion for bare words as it had a detrimental impact on typing feedback (the editor still took input, but it wasn’t rendered until the completion returned OR ESC was hit to cancel the completion, which became excessive once the index of call definition clauses was expanded by the decompilation of the Elixir standard library .beams, so disable it. If bare-words completion is restored. It will either (1) need to not use the Reference#getVariants() API because it generates too many objects that need to be thrown away or (2) need to only complete call definition clauses that are provably in-scope from imports or other macros.
  • #636 - @KronicDeth
    • Both intellij-erlang and intellij-community are Apache 2.0 licensed and its the default license for Elixir projects, so seems like a good choice for LICENSE.md
    • Add CODE_OF_CONDUCT.md
  • #638 - @KronicDeth
    • The run configurations I put together in #504 didn’t allow for the debugger to work properly: neither pause nor breakpoints had any effect, so regenerate them from the Gradle pane.
    • Check parent of when operation in case it’s a guarded function head in org.elixir_lang.annonator.Parameter.putParameterized(Parameter, PsiElement)
    • Instead of highlighting call definition clauses when they are referred to, which only works if it is in the same file, highlight all function and macro declarations when the def* call is encountered.
    • Only increment arity for right pipe operand instead of all operands, so that left operands resolve to correct arity or as variable/parameter.
  • #662 - @KronicDeth
    • Override ModuleImpl#getProject() to prevent StackOverflowError. Without overriding #getProject(), IdentifierHighlighterPass gets stuck in a loop between getManager and getProject on the target (the ModuleImpl) when clicking on the space between defs or defmacros in the decompiled .beam files.
    • Fix source formatting
    • Skip looking for variables unless 0-arity AND no arguments
    • Highlight unresolved macros as macro calls. Anything with a do keyword or a do block will be treated like a macro call even if it can’t be resolved. No resolved is either no resolve results or an empty list
    • Implicit imports at top of file in addition to top of Module.
  • #663 - @KronicDeth
    • CallDefinitionClause completion provider is unexpectedly invoked both when . is typed, but continues to be invoked after a letter is typed after the .; however, once the letter is typed, the letter becomes the default prefix instead, so the prefix should only be reset to "" when it ends in ..
    • Disable Callable#getVariants unless Unqualified to prevents local functions and macros being shown as completions for qualified names.
  • #651 - @StabbyMcDuck
    • Among many other tweaks, the String color is now green, so that Atom and String are no longer close to one another, which was the original issue in #569
      • Alias now has underscored effect
      • Brackets are now greenish instead of brownish
      • Callbacks are now a lighter blue and has underscored effect
      • CharList is little lighter
      • CharToken is dark yellow now instead of dark purple
      • Dot is now purple instead of dark red
      • Expression Substitution Mark is a little lighter
      • Interpolation is now lime green
      • Kernel Macros are a burnt orange
      • Map is now a dark blue instead of a dark yellow
      • Operation Sign is a little lighter
      • Parameters are a little darker
      • Parentheses are redder
      • Predefined is orange instead of blue
      • Specification is now red instead of purple
      • Struct is now purple instead of yellow
      • Type is now green instead of dark purple
      • Variable is more tealish
  • #650 - @StabbyMcDuck
    • Fix indentation to fix sub-lists in CONTRIBUTING.md
    • Fix pluralization in CONTRIBUTING.md
  • #664 - @KronicDeth
    • Check if resolve results are null for For.resolveResultList
    • Check if Protocol.resolveResultList is null
  • #665 - Check match Call is an UnqualifiedNoArgumentCall, in addition to being 0 resolved final arity, before checking if the name matches. - @KronicDeth

Incompatible Changes

  • #585 - Move ^^^ to its own three-operator precedence level to match 1.2. This does mean the parsing will be wrong for Elixir 1.1, but is simpler than maintaining two grammars for those that are still using Elixir 1.1 - @KronicDeth
  • #504 - The ant build files have been removed. To build the build plugin (for Install From Disk), use the ./gradlew buildPlugin. - @JakeBecker
  • #640 - Change to module attribute folding to off by default. - @KronicDeth

README Updates

Decompilation

.beam files, such as those in the Elixir SDK and in your project’s build directory will be decompiled to equivalent def and defmacro calls. The bodies will not be decompiled, only the call definition head and placeholder parameters. These decompiled call definition heads are enough to allow Go To Declaration, the Structure pane, and Completion to work with the decompiled .beam files.

Installation

Inside IDE using JetBrains repository

  1. Preferences
  2. Plugins
  3. Browse Repositories
  4. Select Elixir
  5. Install plugin
  6. Apply
  7. Restart the IDE

Inside IDE using Github releases

In browser

  1. Go to releases.
  2. Download the lastest zip.

In IDE

  1. Preferences
  2. Plugins
  3. Install plugin from disk…
  4. Select the downloaded zip.
  5. Apply
  6. Restart the IDE.

Where Next?

Popular in Announcing Top

tmbb
PhoenixWS - Websockets over Phoenix Channels Source code on Github here: GitHub - tmbb/phoenix_ws: Websockets implemented over Phoenix Ch...
New
pkrawat1
Presenting Aviacommerce, open source e-commerce platform in Elixir Aviacommerce is an open source e-commerce platform in Elixir. We at...
New
restlessronin
The repo is at GitHub - cyberchitta/openai_ex: Community maintained Elixir library for OpenAI API · GitHub. Docs are at OpenaiEx User Gu...
152 10167 134
New
alisinabh
Hey everyone i’ve developed a library for Jalaali calendar for elixir which supports converting Gregorian dates to Jalaali and vice vers...
New
woutdp
Hi! I wanted to introduce my latest project LiveSvelte. It allows you to render Svelte inside LiveView with end-to-end reactivity. It’s ...
New
tmbb
I’ve been working on two packages (not on hex.pm yet) to build admin interfaces for phoenix apps: bureaucrat - which contains a bunch ...
New
RobertDober
Earmark is a pure-Elixir Markdown converter. It is intended to be used as a library (just call Earmark.as_html), but can also be used as...
239 12560 134
New
michalmuskala
Another small library today. PersistentEts Hex: persistent_ets | Hex GitHub: GitHub - michalmuskala/persistent_ets · GitHub Ets table ...
New
michalmuskala
Hello everybody. I have just released Jason - a new JSON library. You might be wondering, why do we need a new library? The primary foc...
New
zachdaniel
Ash Framework What is Ash? Ash Framework is a declarative, resource-oriented application development framework for Elixir. A resource can...
New

Other popular topics Top

malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New

We're in Beta

About us Mission Statement