Giter Site home page Giter Site logo

avh4 / elm-format Goto Github PK

View Code? Open in Web Editor NEW
1.3K 26.0 146.0 3.94 MB

elm-format formats Elm source code according to a standard set of rules based on the official Elm Style Guide

License: BSD 3-Clause "New" or "Revised" License

Haskell 55.24% Shell 1.02% Elm 21.33% JavaScript 10.79% PowerShell 0.02% Batchfile 0.04% HTML 6.73% Makefile 0.17% Python 1.21% Lua 0.97% CSS 0.01% Dockerfile 0.22% Nix 2.28%
elm formatter code-style

elm-format's Introduction

Build Status latest version: 0.8.7

elm-format

elm-format formats Elm source code according to a standard set of rules based on the official Elm Style Guide. It is inspired by the popular gofmt.

The benefits of elm-format:

  • It makes code easier to write, because you never have to worry about minor formatting concerns while powering out new code.
  • It makes code easier to read, because there are no longer distracting minor stylistic differences between different code bases. As such, your brain can map more efficiently from source to mental model.
  • It makes code easier to maintain, because you can no longer have diffs related only to formatting; every diff necessarily involves a material change.
  • It saves your team time debating how to format things, because there is a standard tool that formats everything the same way.
  • It saves you time because you don't have to nitpick over formatting details of your code.

Usage

elm-format .  # Format all *.elm files in the current directory
elm-format Main.elm  # Format a single file
elm-format Main.elm --yes  # Overwrite the file without prompting
elm-format src/ Main.elm  # Format the listed files and directories
elm-format --help  # See other command line options

Installation (latest version: 0.8.7)

To install elm-format:

npm install -g elm-format

or download the version appropriate for your OS from the release page, unzip it, and place elm-format or elm-format.exe (windows) on your PATH.

You must run elm-format from the directory that contains your elm.json (for Elm 0.19) or elm-package.json (for Elm 0.18), or else you must pass the appropriate --elm-version=0.19/--elm-version=0.18 command line argument.

Editor integration

Find your editor in the table below. The recommended plugin for each editor is indicated with ๐Ÿ† (trophy emoji).

Editor Plugin Installation Formatting Format on save Configuration Error handling
Atom ๐Ÿ† atom-elm-format โœ… 2 steps โœ… โœ… โœ… โš ๏ธ no installation instructions
atom-beautify โš ๏ธ 3 steps โœ… โš ๏ธ requires configuration โœ… โœ…
Light Table ๐Ÿ† elm-light โš ๏ธ 3 steps โœ… โš ๏ธ requires configuration โœ… โš ๏ธ no installation instructions
Vim ๐Ÿ† elm-vim โŒ 6 steps โœ… โš ๏ธ requires configuration โœ… โŒ no error message
Emacs ๐Ÿ† elm-mode โŒ 4 steps โœ… โš ๏ธ requires configuration โœ… โš ๏ธ no installation instructions
Visual Studio Code ๐Ÿ† Elm Tooling โš ๏ธ 3 steps โœ… โš ๏ธ requires configuration โœ… โŒ uninformative error message
Sublime Text ๐Ÿ† Elm Language Support โœ… 2 steps โ” TBD โœ… โ” TBD โ” TBD
JetBrains (WebStorm, etc) ๐Ÿ† intellij-elm โš ๏ธ 4 steps โœ… โš ๏ธ requires configuration โš ๏ธ requires configuration โ” TBD
TextMate ๐Ÿ† Elm.tmbundle โœ… 2 steps โ” TBD โ” TBD โ” TBD โ” TBD

Integration with other tools

These tools also integrate with elm-format:

Detailed installation instructions

If you can simplify or improve the installation instructions or add instructions for another editor, please make a pull request. The default behavior of elm-format-approved plugins is to format Elm files on save.

atom-elm-format installation

  1. Install elm-format

  2. Install atom-elm-format

    apm install elm-format
    

or use the Atom package manager in Atom's settings

atom-beautify installation

  1. Install elm-format

  2. Install atom-beautify

    apm install atom-beautify
    

or use the Atom package manager in Atom's settings

  1. Use ^โŒฅB (CTRL-ALT-B) to format a file

elm-light installation

  1. Install elm-format
  2. Install the elm-light plugin using the Light Table plugin manager
  3. To format on save, edit your user keymap by performing the following:
  • Click File -> Settings -> User Keymap to open the user keymap.
  • Copy the following line and paste it into your keymap. Anywhere is fine as long as it is whithin the outer brackets. Ensure to save the file.
[:editor.elm "ctrl-s" :save :elm-format :elm.lint]
  • Search for "App: Reload keymaps" in the Commands Window to apply the changes (or restart LightTable).

elm-mode installation

  1. Install elm-format

  2. If your Emacs has package.el (which is automatically the case for Emacs >= 24), you can install elm-mode from the package in MELPA:

    1. Ensure that you have added the MELPA source in your ~/.emacs.d/init.el:

      (require 'package)
      (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
    2. Install elm-mode (official instructions): Use M-x list-packages and choose elm-mode.

  3. Add the following to your ~/.emacs.d/init.el:

    (add-hook 'elm-mode-hook 'elm-format-on-save-mode)

elm-vim installation

If you are an advanced vim user and already have a preferred vim plugin installation method, you may prefer to refer to the official elm-vim installation instructions. The instructions below are for those who need a step-by-step walkthrough of how to get the plugin set up.

  1. Install elm-format

  2. Install vim-plug (official instructions) NOTE: if you are using neovim, you will need to refer to the official instructions.

    1. Download vim-plug:

      curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
          https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    2. Make sure ~/.vimrc exists and has a section like this:

      call plug#begin('~/.vim/plugged')
      " ... any active plugins
      call plug#end()
  3. Install elm-vim (official instructions)

    1. Add Plug 'elmcast/elm-vim' to the plug#begin plugin section in your ~/.vimrc
    2. Start vim and run :PlugInstall
  4. Add the following to your ~/.vimrc:

let g:elm_format_autosave = 1

Visual Studio Code installation

  1. Install elm-format

  2. Install the extension Elm Plugin for Visual Studio Code.

  3. Configure the extension to format on save:

    1. Find your settings.json file (instructions).
    2. Add the following key-value pair to your settings.json:
    "[elm]": {
        "editor.formatOnSave": true
    },

Sublime Text installation

  1. Install elm-format
  2. Install the Elm Language Support package.

JetBrains installation

This is for WebStorm and other JetBrains IDEs like IntelliJ and PyCharm.

  1. Install elm-format

  2. Install the intellij-elm plugin

  3. In IntelliJ, open Settings -> Languages & Frameworks -> Elm

    1. Specify the path to elm-format (try the "Auto Discover" button first)
    2. Check the "Run when file saved?" checkbox

Development info

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Use the instructions below to get started. More detailed information is available in ./dev/Documentation/.

Building from source

  1. Install Haskell ghcup following the instructions for your operating system: https://www.haskell.org/ghcup/
# check out the repo
git clone https://github.com/avh4/elm-format.git
cd elm-format

# initial setup
ghcup install ghc 9.4.4
ghcup set ghc 9.4.4
cabal install hpack

# build
dev/build.sh -- build

# run the built elm-format
./_build/bin/elm-format/O0/elm-format

See dev/Documentation for more contributor and build command documentation.

elm-format's People

Contributors

8n8 avatar ahstro avatar alicebob avatar avh4 avatar basile-henry avatar benjick avatar bobbypriam avatar brendanbenson avatar brianhicks avatar danyx23 avatar deadfoxygrandpa avatar eeue56 avatar emmabastas avatar ento avatar gyzerok avatar janiczek avatar jmandzik avatar judytuna avatar kutyel avatar lydell avatar lyuha avatar marcowahl avatar mattjbray avatar mdevlamynck avatar mgold avatar nukecoder avatar omnibs avatar robx avatar supermario avatar tac-tics avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elm-format's Issues

How to deal with spaces inside of parens

Parens are used in many different ways. Should the same rule apply to all? What should the rules be?

module Main (parens, here, And(Here)) where

import Foo exposing (moreParens, More(..))

type MyType
    = A (Int, Float)

fn (tuple,pattern) =
    (1, 2, 3)
        |> (\(a, b, c) -> a)
        |> (+) 10

Properly handle single-line records

x address = button [ onClick address (AddStatus {id=50}) ] [ text "add status" ]

becomes

x address =
    button [ onClick address (AddStatus { id = 50) ] [ text "add status" ]
                                        }

Formatting all elm files in a directory

elm-format src (src is a directory) should format all *.elm files found (recursively) in the given directory.

Using --output FILE with a directory should exit with an error message.

The following prompt should be given (unless --yes is specified):

This will overwrite the following 4 files to use Elmโ€™s preferred style:

  src/TodoMVC.elm
  src/TodoMVC/Model.elm
  src/TodoMVC/Update.elm
  src/TodoMVC/View.elm

This cannot be undone! Make sure to back up these files before proceeding.

Are you sure you want to overwrite these files with formatted versions? (y/N)

Handle comments (block comments and line comments)

Block comments and line comments anywhere in the file need to be handled reasonably.

See https://github.com/rtfeldman/dreamwriter/compare/elm-format?expand=1#diff-cd8e6cfa12c24161b452f61a98434468R52 - that block comment moved considerably from where it started out!

Top-level constructs

  • port declarations
  • infix declarations
  • type declarations
  • type alias declarations
  • definition (Expression.definition)
  • definition patterns
  • before module statement
  • module statement
  • within module export listings
  • top-level
  • around import statements
  • within import statements
  • within import listings
  • within union type listings
  • within open listings
  • within closed listings
  • type annotations

Expressions

  • unit
  • symbolic operators
  • binary operator expressions
  • function application
  • parenthesized expressions
  • tuples
  • tuple constructor functions
  • list
  • empty list
  • literal records
  • record updates
  • if statement conditions
  • if statement bodies
  • lambda arguments
  • lambda bodies
  • case subjects
  • case patterns
  • case bodies
  • let expressions
  • infix definition patterns

Types

  • unit types
  • tuple types
  • record types
  • record extension types
  • empty record types
  • type constructor arguments
  • function types
  • parenthesized types

Patterns

  • constructor patterns
  • unit pattern
  • parenthesized patterns
  • tuple patterns
  • list patterns
  • cons patterns (first::rest)
  • empty list pattern
  • record patterns
  • pattern aliases

Problems with tests on Ubuntu

@ Xubuntu 15.04

For the file tests/run-tests.sh I propose:

- mktemp -d -t elm-format-tests
+ mktemp -d -t elm-format-tests.XXX

The X's are mandatory in Ubuntu:

$ man mktemp

Create a temporary file or directory, safely, and print its name. TEMPLATE must contain at least 3 consecutive 'X's in last component. If TEMPLATE is not specified, use tmp.XXXXXXXXXX

- /def/null
+ /dev/null

Get QuickCheck set up with a trivial example test

I am not very familiar with cabal and testing in haskell, but I'd like to get QuickCheck setup so we can try to write some property tests to validate the formatter. If you can get a trivial test the to run that shows QuickCheck is working, please contribute it!

Should preserve escaped strings

Currently:

"\xA0S\xA0"

incorrectly formats as:

"ย Sย "

Should escape the following:

  • \\
  • \n except in """ strings
  • \t
  • \" in strings
  • \' in chars
  • any whitespace character except a normal space as\xNNor\xNNNN
  • any non-print character as \xNN, \xNNNN, or \xNNNNN

Characters not listed above should not be escaped.

Review TODOs in the code

  • AST/Variable.hs | Alias !String -- TODO: what is this? c82513e
  • Parse/Expression.hs try equals -- TODO: can the try break newline tracking? e55fd92
  • Parse/Expression.hs (_, _, bodyComments) <- padded (reserved "in") -- TODO: pre comments are always empty because any whitespace was consumed before padded? 25b5e2a
  • Parse/Helpers.hs option (\_ _ -> []) . commaSep1 -- TODO: use comments for empty list
  • Parse/Module.hs (++) <$> ((\x -> [x]) <$> Decl.declaration) -- TODO: can there be comments before this? 29f4860
  • Box.hs -- TODO couldn't we just run renderLine and get the length of the resulting string?
  • ElmFormat/Render/Box.hs formatExpression expr -- TODO: needs to have parens in some cases

Interactive warning when formatting a file in place

elm-format path/MyFile.elm should produce the following prompt:

This will overwrite the following files to use Elmโ€™s preferred style:

  path/MyFile.elm

This cannot be undone! Make sure to back up these files before proceeding.

Are you sure you want to overwrite these files with formatted versions? (y/N)

elm-format --yes path/MyFile.elm or elm-format path/MyFile.elm --yes should overwrite the file without prompt.

How to indent complex indented expressions inside of lists and other partially-indented contexts

For example,

multilineExpressionsInsideList =
    [ let
        x = 1
      in
        x
    , if True then
        2
      else if False then
        3
      else
        4
    , case True of
        _ ->
            5
    , [ 6
      , 7
      ]
        |> head
        |> Maybe.withDefault 8
    , \a ->
        9
    ]

The above formatting seems the most natural from the currently defined rules, but this is strange because the else is indented two spaces to line up with the if, and the body of the if is indented 4 spaces from the previous line, but the body of the else is indented 2 spaces.

The most obvious alternative is to shift the bodies another two spaces over, but this is strange because it breaks us out of the 4-space indentation grid.

This will also apply to let, case, lambdas, and probably any other expression whose second line can be indented. This also applies to multiline tuples and records. This probably also applies to tuple and record type definitions.

A real-world example:

        div
            [ classList classes ]
            [ div
                [ class "modal-backdrop" ]
                []
            , div
                [ class "school-search-modal" ]
                [ div
                    [ class "school-search-modal-header" ]
                    [ viewHeader address model ]
                , div
                    [ class "school-search-modal-body" ]
                    [ viewBody address model ]
                ]
            ]

Handle updating records

Minimal failing case:

update model = { model | x <- "abc" }

http://elm-lang.org/docs/records#updating-records

$ elm-format UpdateRecord.elm --yes
Processing file UpdateRecord.elm
ERRORS
-- SYNTAX PROBLEM --------------------------------------------------- <location>

I ran into something unexpected when parsing your code!


I am looking for one of the following things:

    =
    whitespace

Handle port definitions

AST.Declaration.PortAnnotation, AST.Declaration.PortDefinition

Verify that port declarations aren't allowed in let statements.

Handle range expressions

Includes multiline. AST.Expression.Range

single-line looks like this:

foo = [5..(9 + 6 |> (-) 2)]

multiline looks like this:

import Html

main = Html.text <| toString
    [
        if True then
            1
        else
            2
    ..
        if False then
            3
        else
            5
    ]

Sorting things alphabetically

Should import statements be sorted? Should listings in the import statements and/or module statements be sorted?

What does sorted mean? Generally alphabetical sort is locale-dependent, but we want the output of elm-format to be the same regardless of the locale.

Get rid of deprecated stuff in src/Box.hs

Everything below DEPRECATED BELOW THIS LINE should go away, and a new render :: Box -> String function should be written. The dependency on Text.PrettyPrint.Boxes should also be removed from elm-format.cabal.

Formatting a directory into other directory

Should this usage pattern be allowed?
$ elm-format DIR --output DIR2

The intention probably is copying the filenames one for one:

  • DIR/first.elm -> DIR2/first.elm
  • DIR/second.elm -> DIR2/second.elm

Handle glshader expressions

AST.Expression.GLShader.

vertexShader : Shader { position:Vec3, coord:Vec3 } { u | view:Mat4 } { vcoord:Vec2 }
vertexShader = [glsl|

attribute vec3 position;
attribute vec3 coord;
uniform   mat4 view;
varying   vec2 vcoord;

void main () {
  gl_Position = view * vec4(position, 1.0);
  vcoord = coord.xy;
}

|]

Implement "Feldman's Rule" of inner spaces

From #7.

Since we need to pick one to start, I'd say let's start with "spaces if there are commas," in other words:

( foo, bar )
(foo bar)
(foo == bar)

...or perhaps more precisely "spaces if there could be commas," so in other words:

import Foo exposing ( bar )
import Bar exposing ( baz, qux )

I've never tried that style with imports, but at first glance I like how it looks!

Missing comment

update : Action -> Model -> Model
update action model =
    case action of
        SetImage url -> model
            --{ model | image = url }

becomes

update : Action -> Model -> Model
update action model =
    case action of
        SetImage url ->
            model

Show correct filename when reporting errors

Should show the input filename instead of <location> in the following:

Processing file tests/test-files/recursive-directory/nested/invalid.elm
ERRORS
-- SYNTAX PROBLEM --------------------------------------------------- <location>

I ran into something unexpected when parsing your code!

See Main.hs#printError

Behavior when encountering errors while formatting multiple files

Let's say we format a directory with .elm files:

  • first.elm
  • second.elm
  • third.elm

The second one contains an error that will not allow us to format it. Should we (after displaying an error message) try to format the rest of the files (here third.elm)? (Right now we don't, we exit immediately.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.