A bag of tricks for developing with Elm. (Atom package)
JavaScript Elm CSS

README.md

Elmjutsu

A bag of tricks for developing with Elm.

https://atom.io/packages/elmjutsu

Setup

Related Atom packages:

Features Overview

Note: Features marked with * are disabled by default. You may enable them in the Settings view.

Feature Details

This package parses your projects' source files to extract information, and downloads documentation of 3rd-party Elm packages. The downloaded documentation files will be saved to the path set in Cache Directory in the Settings view. If Cache Directory is blank, a temporary directory will be used. Take note that most operating systems delete temporary directories at bootup or at regular intervals.

Autocomplete

This provides suggestions for imports, project symbols, and 3rd-party package symbols.

  • It's recommended to uncheck Enable autocomplete of the language-elm package to prevent duplicate suggestions.

autocomplete

Global Autocomplete *

  • Check Enable Global Autocomplete if you want to include unimported project symbols.
    • This will also allow ⚡️Auto import completion (which works like Add Import).
    • Take note that you may experience lag if you have a large project.

auto-import

Filtering suggestions

  • Fuzzy Filtering *

    You can check Enable Autocomplete Fuzzy Filtering to filter suggestions using fuzz-aldrin-plus.

    autocomplete-fuzzy-filtering

  • Regex Filtering

    If the typed text starts with a slash (/), the rest of the characters will be used as a regular expression to filter the suggestions by name.

    autocomplete-regex-filtering

  • Type Filtering

    If the typed text starts with a colon (:), the rest of the characters will be used as a regular expression to filter the suggestions by type signature.

    autocomplete-type-filtering

    • If you want to filter by name and type signature, put two underscores (__) in between. For example, :cons__String will suggest String.cons (Char -> String -> String) and String.uncons (String -> Maybe.Maybe ( Char, String )).

    • Use underscores in lieu of spaces (e.g. to match List a, type List_a).

    • Remember to escape dots, vertical bars, braces (for records), parentheses (for tuples), etc.

Autocomplete Snippets *

  • You can also check Enable Autocomplete Snippets if you prefer.

autocomplete-snippet

Special Completions ⚡️

Press tab to go to the next tab stop (similar to how snippets work). Special completions can be disabled individually in the package settings.

  • ⚡️Insert program

    Type "html", "Html.program", "platform", or "Platform.program" in an empty editor to insert skeleton code.

construct-html-program

  • ⚡️Insert module
  • ⚡️Insert let/in
  • ⚡️Insert if/then/else

construct-basic

  • ⚡️Insert case/of

construct-case-of

  • ⚡️Insert default arguments

construct-default-arguments

  • ⚡️Replace type with default

construct-default-value-for-type

  • ⚡️Define from type annotation

construct-from-type-annotation-1

construct-from-type-annotation-2

construct-from-type-annotation-3

Type-Aware Autocomplete *

  • Check Enable Type-Aware Autocomplete if you want to prioritize suggestions matching the expected type at cursor position.
    • The type can be inferred via the Infer Type command, but it's recommended to check Infer Expected Type At Cursor On The Fly in the package settings instead.
    • WARNING: This is highly experimental and may cause lag, especially if Enable Global Autocomplete is also checked.

type-aware-autocomplete

Performance Tuning

  • It's recommended to uncheck Enable autocomplete of the language-elm. No need to install elm-oracle.

  • If you are experiencing lag while typing, you can set the value of Max Number of Autocomplete Suggestions to a small number such as 50 so that Atom will have less items to render.

  • Enabling both Global Autocomplete and Type-Aware Autocomplete will usually result to lag because there will be lots of computations involved. This may be improved in the future.

Navigation

  • Elmjutsu: Go To Definition

    go-to-definition

    • If the hyperclick package is installed, you can also check Enable Hyperclick to jump to definition using Ctrl + click / Cmd + click (Mac).
  • Elmjutsu: Go To Symbol

    go-to-symbol

    • You can type a : (colon) in the text box to also filter by type.
  • Elmjutsu: Find Usages

    find-usages

  • Elmjutsu: Go To Next Usage

    Moves the cursor to the position of the next usage.

  • Elmjutsu: Go To Previous Usage

    Moves the cursor to the position of the previous usage.

  • Elmjutsu: Go Back

    The current cursor position is added to a navigation stack before jumping via:

    • Go To Definition
    • Go To Symbol
    • Go To Next Usage
    • Go To Previous Usage
    • Clicking on a source path link (Sidekick and Datatip).

    Invoke this command to jump back to the previous position.

  • Elmjutsu: Hide Usages Panel

    Closes the Usages panel (the panel is shown after invoking Find Usages or Rename Symbol).

Datatips

Provides support for Datatips. The atom-ide-ui package should be installed for this to work.

datatips

Signature Help

Provides support for Signature Help. The atom-ide-ui package should be installed for this to work.

signature-help

Show Types in Tooltip *

This is disabled by default. To turn it on, check Show Types in Tooltip in the package settings. You can also change the placement of the tooltip (Types Tooltip Position).

show-types-in-tooltip

Elmjutsu: Toggle Sidekick

Shows the type hints and documentation for the symbol at cursor position. The size, position of the panel, and amount of information to show can be modified in the package settings.

  • Example #1 (default): Sidekick Position = "bottom", Sidekick Size = 0 (Automatically resizes to fit content.)

sidekick1

  • Example #2: Sidekick Position = "right", Sidekick Size = 300

sidekick3

  • Example #3: Sidekick Position = "bottom", Show Types in Sidekick is checked, Show Doc Comments in Sidekick and Show Source Paths in Sidekick are unchecked.

sidekick2

Elmjutsu: Infer Type

  • Select some text or make sure that the cursor is between whitespaces or before a closing parenthesis before invoking this command. If nothing is selected and the cursor is not between whitespaces, the word under the cursor will be selected.
  • Make sure that Elm Make Path is properly configured in the package settings. The default works for most cases.
  • To be able to see the inferred types, at least one of these should be true:
    • Show Types in Tooltip is checked
    • Show Datatips is checked
    • The Sidekick panel is visible
  • This uses similar tricks as those described in Type Bombs in Elm, which may sometimes fail or give incorrect results.

Infer Types on the Fly *

  • You can also check the Infer Expected Type At Cursor On The Fly and Infer Type Of Selection On The Fly options in the package settings.
  • WARNING: Infer Type Of Selection On The Fly currently has bad interactions with some packages that decorate the markers (e.g. Find And Replace) 😢 This will be fixed in the future.

infer-types-on-the-fly

Elmjutsu: Add Import

Quickly adds an import without scrolling to the top of the file. Also sorts the imports, removes duplicates, and removes defaults automatically.

  • ProTip: There's no "Sort Imports" command, but you can achieve the same result by invoking Add Import and choosing an already imported symbol (like +, for example).

add-import

Package Management

  • Elmjutsu: Install Package

    Quickly installs a package.

    • This runs elm-package install --yes <name> <version> (or elm-package install --yes <name> if the selected version is "Auto").
    • Make sure that Elm Package Path is properly configured in the package settings. The default works for most cases.
  • Elmjutsu: Uninstall Package

    Removes an installed package.

    • This removes the dependency from elm-package.json, then runs elm-package install --yes to clean up.

Refactoring

  • Elmjutsu: Rename Symbol

    Renames the symbol across the whole project. Take note that this is not an undoable operation.

    • Press enter to rename or escape to cancel.
    • Uncheck usages to exclude.
    • Modified modules with open editors will not be saved automatically.
    • Renaming a module will not rename the associated file.
    • Currently, this also modifies the symbol name inside comments.

    rename-symbol

  • Elmjutsu: Surround With Let

    • Press escape when you're done naming your variable.

    surround-with-let

  • Elmjutsu: Lift To Let

    • Press escape when you're done naming your variable.
    • There are still cases where this will not work properly. There will be a better implementation in the future.

    lift-to-let

  • Elmjutsu: Lift To Top Level

    • Press escape when you're done naming your function.
    • This does not compute the needed function arguments (yet?), so you also have to type those in with the function name.

    lift-to-top-level

Keybindings

Here is an example:

'atom-text-editor:not([mini])[data-grammar^="source elm"]':
  'f12': 'elmjutsu:go-to-definition'
  'ctrl-r': 'elmjutsu:go-to-symbol'
  'shift-f12': 'elmjutsu:find-usages'
  'f8': 'elmjutsu:go-to-next-usage'
  'shift-f8': 'elmjutsu:go-to-previous-usage'
  'ctrl-f12': 'elmjutsu:go-back'
  'alt-insert': 'elmjutsu:add-import'
  'f2': 'elmjutsu:rename-symbol'
  'alt-shift-l': 'elmjutsu:surround-with-let'
  'alt-l': 'elmjutsu:lift-to-let'
  'alt-t': 'elmjutsu:lift-to-top-level'
  'alt-i': 'elmjutsu:infer-type'

'atom-workspace':
  'f1': 'elmjutsu:toggle-sidekick'
  'ctrl-shift-f12': 'elmjutsu:hide-usages-panel'

Add them to your keymap.cson or bind them from Settings > Keybindings.

Notes

  • Be sure to check out the settings for this package to find out about the available options.
  • It's highly recommended to read CHANGELOG.md before upgrading to a newer version to check for breaking changes.
  • The commands only work for top-level values for now.
  • This package may fail to activate (when starting Atom) if you don't have elm-package.json files in your Elm project directories. This issue will be handled properly in the future.
  • You may encounter weird behaviors if multiple files are using the same module name in your project.
  • Major parts of this will be rewritten when a way to get the AST becomes available. Also, more features :)

Credits