├── .gitignore ├── Build Systems └── Elm Make.sublime-build ├── Commands ├── Elm Format.sublime-commands ├── Open In Browser.sublime-commands ├── Project.sublime-commands ├── REPL.sublime-commands └── Show Type.sublime-commands ├── Elm Languange Support.tmPreferences ├── Keymaps └── Default.sublime-keymap ├── LICENSE ├── Menus ├── Context.sublime-menu └── Main.sublime-menu ├── Preferences ├── Metadata.YAML-tmLanguage └── Metadata.tmPreferences ├── README.md ├── Settings ├── Elm Language Support.sublime-settings ├── Elm User Strings.sublime-settings └── Elm.sublime-settings ├── Snippets ├── case_of.sublime-snippet ├── case_of_maybe.sublime-snippet ├── case_of_result.sublime-snippet ├── debug.sublime-snippet ├── function.sublime-snippet ├── function_2_aguments.sublime-snippet ├── function_3_aguments.sublime-snippet ├── function_4_aguments.sublime-snippet ├── import.sublime-snippet ├── import_as.sublime-snippet ├── let.sublime-snippet ├── module.sublime-snippet ├── type.sublime-snippet └── type_alias.sublime-snippet ├── Syntaxes ├── Elm Compile Messages.sublime-syntax ├── Elm Documentation.sublime-syntax └── Elm.sublime-syntax ├── beta-repository.json ├── elm_format.py ├── elm_generate.py ├── elm_make.py ├── elm_open_in_browser.py ├── elm_plugin.py ├── elm_project.py ├── elm_show_type.py ├── images ├── completions.png ├── elm_format.png ├── elm_make.jpg ├── elm_project.jpg ├── elm_repl.jpg ├── elm_types.png ├── logo.png └── type_panel.png ├── messages.json └── messages ├── 0.15.0.md ├── 0.16.1.md ├── 0.16.2.md ├── 0.16.3.md ├── 0.17.0.md ├── 0.17.1.txt ├── 0.18.0.txt ├── 0.19.0.txt ├── 0.20.0.txt ├── 0.21.0.txt ├── 0.21.1.txt ├── 0.22.0.txt ├── 0.22.1.txt ├── 0.22.2.txt ├── 0.22.3.txt ├── 0.22.4.txt └── 0.22.5.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.cache 2 | *.pyc 3 | -------------------------------------------------------------------------------- /Build Systems/Elm Make.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "target": "elm_make", 3 | "selector": "source.elm", 4 | "cmd": 5 | [ 6 | "elm-make", 7 | "$file", 8 | "--output={null}", 9 | "--report=json", 10 | "--yes" 11 | ], 12 | "working_dir": "$project_path", 13 | "file_regex": "^\\-\\- \\w+: (?=.+ \\- (.+?):(\\d+):(\\d+))(.+) \\- .*$", 14 | "error_format": "-- $type: $tag - $file:$line:$column\n$message\n", 15 | "info_format": ":: $info\n", 16 | "syntax": "Packages/Elm Language Support/Syntaxes/Elm Compile Messages.sublime-syntax", 17 | "null_device": "/dev/null", 18 | "warnings": "true", 19 | "osx": 20 | { 21 | "path": "/usr/local/bin:$PATH" 22 | }, 23 | "linux": 24 | { 25 | "path": "$HOME/.cabal/bin:/usr/local/bin:$PATH" 26 | }, 27 | "variants": 28 | [ 29 | { 30 | "name": "Run", 31 | "cmd": 32 | [ 33 | "elm-make", 34 | "$file", 35 | "--output={output}", 36 | "--report=json", 37 | "--yes" 38 | ] 39 | }, 40 | { 41 | "name": "Ignore Warnings", 42 | "warnings": "false" 43 | }, 44 | { 45 | "name": "Run - debug", 46 | "cmd": 47 | [ 48 | "elm-make", 49 | "$file", 50 | "--output={output}", 51 | "--report=json", 52 | "--debug", 53 | "--yes" 54 | ] 55 | }, 56 | { 57 | "name": "Run - Ignore Warnings", 58 | "warnings": "false", 59 | "cmd": 60 | [ 61 | "elm-make", 62 | "$file", 63 | "--output={output}", 64 | "--report=json", 65 | "--yes" 66 | ] 67 | } 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /Commands/Elm Format.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Elm Language Support: Run elm-format", 4 | "command": "elm_format" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /Commands/Open In Browser.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Elm Build System: Open in Browser", 4 | "command": "elm_open_in_browser" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /Commands/Project.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Elm Build System: View elm-package.json", 4 | "command": "elm_project" 5 | }, 6 | { 7 | "caption": "Elm Build System: Set Main Path", 8 | "command": "elm_project", "args": 9 | { 10 | "prop_name": "main_path", 11 | "caption": "Enter main path to build from: " 12 | } 13 | }, 14 | { 15 | "caption": "Elm Build System: Set HTML Path", 16 | "command": "elm_project", "args": 17 | { 18 | "prop_name": "html_path", 19 | "caption": "Enter HTML path to open in browser: " 20 | } 21 | }, 22 | { 23 | "caption": "Elm Build System: Set Output Path", 24 | "command": "elm_project", "args": 25 | { 26 | "prop_name": "output_path", 27 | "caption": "Enter path to build output to: " 28 | } 29 | }, 30 | { 31 | "caption": "Elm Build System: Set Output Directory", 32 | "command": "elm_project", "args": 33 | { 34 | "prop_name": "output_dir", 35 | "caption": "Enter directory to build output to: " 36 | } 37 | }, 38 | { 39 | "caption": "Elm Build System: Set Output Base Name", 40 | "command": "elm_project", "args": 41 | { 42 | "prop_name": "output_name", 43 | "caption": "Enter base name to build output with: " 44 | } 45 | }, 46 | { 47 | "caption": "Elm Build System: Set Output Extension", 48 | "command": "elm_project", "args": 49 | { 50 | "prop_name": "output_ext", 51 | "choices": 52 | [ 53 | "HTML", 54 | "JS" 55 | ] 56 | } 57 | } 58 | ] 59 | -------------------------------------------------------------------------------- /Commands/REPL.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "SublimeREPL: Elm", 4 | "command": "repl_open", "args": 5 | { 6 | "type": "subprocess", 7 | "encoding": "utf8", 8 | "cmd": ["elm-repl"], 9 | "cwd": "$file_path", 10 | "syntax": "Packages/Elm Language Support/Syntaxes/Elm.sublime-syntax", 11 | "external_id": "elm", 12 | "extend_env": 13 | { 14 | "osx": {"PATH": "{PATH}:/usr/local/bin"}, 15 | "linux": {"PATH": "{PATH}:/usr/local/bin:{HOME}/.cabal/bin"}, 16 | "windows": {} 17 | } 18 | } 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /Commands/Show Type.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Elm Language Support: Show type", 4 | "command": "elm_show_type", 5 | "args": { "panel": true } 6 | }, 7 | { 8 | "caption": "Elm Language Support: Open type panel", 9 | "command": "elm_show_type_panel" 10 | } 11 | ] -------------------------------------------------------------------------------- /Elm Languange Support.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Symbol List 7 | scope 8 | hide.from.goto_symbol 9 | settings 10 | 11 | showInSymbolList 12 | 0 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Keymaps/Default.sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["alt+up"], "command": "elm_show_type_panel", 3 | "context": 4 | [ { "key": "selector", "operator": "equal", "operand": "source.elm" } ] 5 | }, 6 | { "keys": ["alt+down"], "command": "hide_panel" 7 | } 8 | ] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2014 Alex Neslusan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Menus/Context.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "elmlanguagesupport", 4 | "caption": "Elm Language Support", 5 | "children": 6 | [ 7 | { 8 | "caption": "Open Type Panel", 9 | "command": "elm_show_type_panel" 10 | } 11 | ] 12 | } 13 | ] -------------------------------------------------------------------------------- /Menus/Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "tools", 4 | "children": 5 | [{ 6 | "id": "SublimeREPL", 7 | "caption": "SublimeREPL", 8 | "mnemonic": "R", 9 | "children": 10 | [ 11 | { 12 | "caption": "Elm", 13 | "id": "repl_elm", 14 | "command": "repl_open", "args": 15 | { 16 | "type": "subprocess", 17 | "encoding": "utf8", 18 | "cmd": ["elm-repl"], 19 | "cwd": "$file_path", 20 | "syntax": "Packages/Elm Language Support/Syntaxes/Elm.sublime-syntax", 21 | "external_id": "elm", 22 | "extend_env": 23 | { 24 | "osx": {"PATH": "{PATH}:/usr/local/bin"}, 25 | "linux": {"PATH": "{PATH}:/usr/local/bin:{HOME}/.cabal/bin"}, 26 | "windows": {} 27 | } 28 | } 29 | } 30 | ] 31 | }] 32 | }, 33 | { 34 | "id": "preferences", 35 | "children": 36 | [{ 37 | "id": "package-settings", 38 | "children": 39 | [ 40 | { 41 | "caption": "Elm Language Support", 42 | "children": 43 | [ 44 | { 45 | "caption": "Settings", 46 | "command": "edit_settings", 47 | "args": { 48 | "base_file": "${packages}/Elm Language Support/Settings/Elm Language Support.sublime-settings", 49 | "default": "// Settings in here override those in \"Elm Language Support/Settings/Elm Language Support.sublime-settings\",\n\n{\n\t$0\n}\n" 50 | } 51 | } 52 | ] 53 | } 54 | ] 55 | }] 56 | } 57 | ] 58 | -------------------------------------------------------------------------------- /Preferences/Metadata.YAML-tmLanguage: -------------------------------------------------------------------------------- 1 | # [PackageDev] target_format: plist, ext: tmPreferences 2 | name: Metadata 3 | uuid: 64598216-cf92-4b00-961f-2b1478921c3e 4 | scope: source.elm 5 | settings: 6 | increaseIndentPattern: |- 7 | (?x) 8 | ^.* 9 | (= 10 | |[|!%$?~+:\-.=&\\*^]+ 11 | |\bthen 12 | |\belse 13 | |\bof 14 | ) 15 | \s*$ 16 | shellVariables: 17 | - name: TM_COMMENT_START 18 | value: -- 19 | - name: TM_COMMENT_START_2 20 | value: '{-' 21 | - name: TM_COMMENT_END_2 22 | value: -} 23 | -------------------------------------------------------------------------------- /Preferences/Metadata.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Metadata 7 | scope 8 | source.elm 9 | settings 10 | 11 | increaseIndentPattern 12 | (?x) 13 | ^.* 14 | (= 15 | |[|!%$?~+:\-.=</>&\\*^]+ 16 | |\bthen 17 | |\belse 18 | |\bof 19 | ) 20 | \s*$ 21 | shellVariables 22 | 23 | 24 | name 25 | TM_COMMENT_START 26 | value 27 | -- 28 | 29 | 30 | name 31 | TM_COMMENT_START_2 32 | value 33 | {- 34 | 35 | 36 | name 37 | TM_COMMENT_END_2 38 | value 39 | -} 40 | 41 | 42 | 43 | uuid 44 | 64598216-cf92-4b00-961f-2b1478921c3e 45 | 46 | 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **This project is deprecated.** The official Elm language support package for Sublime Text is [evancz/elm-syntax-highlighting](https://github.com/evancz/elm-syntax-highlighting), with elm-format support available via [evancz/elm-format-on-save](https://github.com/evancz/elm-format-on-save). 2 | 3 | ![Elm Language Support logo](images/logo.png) 4 | # The Sublime Elm Language Package 5 | 6 | > ### Note: Elm 0.19 and Elm Language Support 7 | > 8 | > Elm 0.19 was [recently released][elm-0.19]. It makes major, breaking changes 9 | > to the compiler's interface with packages like this one. It is likely the 10 | > next release of Elm Language Support will break compatibility with Elm 0.18. 11 | > 12 | > If you plan to remain on Elm 0.18 for now, you should configure Package 13 | > Control to ignore updates to this package until you are ready to upgrade. 14 | > In Sublime Text, choose **Preferences > Package Settings > Package Control > 15 | > Settings – User**, then add this setting to your 16 | > **Package Control.sublime-settings** file: 17 | > 18 | > ```json 19 | > { 20 | > "auto_upgrade_ignore": [ 21 | > "Elm Language Support" 22 | > ], 23 | > } 24 | > ``` 25 | > 26 | > #### Upgrading to Elm 0.19 27 | > 28 | > A pre-release version of this package with experimental support for Elm 0.19 29 | > is available. If you're using Elm 0.19 already, we'd value your feedback! 30 | > 31 | > **Warning:** This new version does not support Elm 0.18! 32 | > 33 | > To upgrade, configure Package Control to install pre-release versions of this 34 | > package. In Sublime Text, choose **Preferences > Package Settings > Package 35 | > Control > Settings – User**, then add this setting to your 36 | > **Package Control.sublime-settings** file: 37 | > 38 | > ```json 39 | > { 40 | > "install_prereleases": 41 | > [ 42 | > "Elm Language Support" 43 | > ], 44 | > } 45 | > ``` 46 | > 47 | > Then use the **Package Control: Upgrade Package** command in the Command 48 | > Palette to upgrade. Make sure to read the release notes that are displayed 49 | > following the upgrade! 50 | 51 | ## Installation 52 | 53 | 1. Install [Package Control][] 54 | 2. Run `Package Control: Install Package` in the Command Palette (Super+Shift+P) 55 | 3. Install [Elm][] or use [NPM][] (`npm i -g elm`) 56 | 57 | ### Manual 58 | 59 | 1. Go to Packages directory 60 | 2. Clone the repository `git clone https://github.com/elm-community/SublimeElmLanguageSupport.git 'Elm Language Support'` 61 | 62 | ## Features 63 | 64 | - Compatible with [Sublime Text 2] and [Sublime Text 3] 65 | - Syntax highlighting 66 | - Snippets for common Elm syntax (function, `case` … `of`, `let` … `in`, etc.) 67 | 68 | | Tab Trigger | Description | 69 | |----------------|--------------------------------------------------| 70 | | cof | ``case … of`` | 71 | | cofm | ``case … of (Maybe)`` | 72 | | cofr | ``case … of (Result)`` | 73 | | debug | ``Debug.log`` | 74 | | fn | ``Function (a -> b)`` | 75 | | fn2 | ``Function (a -> b -> c)`` | 76 | | fn3 | ``Function (a -> b -> c -> d)`` | 77 | | fn4 | ``Function (a -> b -> c -> d -> e)`` | 78 | | imp | ``import`` | 79 | | impas | ``import … as`` | 80 | | let | ``let … in …`` | 81 | | mod | ``module`` | 82 | | type | ``type`` | 83 | | typea | ``type alias (Record)`` | 84 | 85 | - Autocompletions plus type signature and documentation display for all functions inside packages in your `elm-package.json` file (requires [elm-oracle](https://www.npmjs.com/package/elm-oracle), which you can install with `npm install -g elm-oracle`) 86 | 1. Bring up the type panel with `alt+up` or through the right-click context menu 87 | 2. Close the type panel with `alt+down` 88 | 3. If you don't like these keybindings, rebind them in your User packages directory 89 | ![autocompletions screenshot](images/completions.png)![type signature screenshot](images/elm_types.png)![type panel screenshot](images/type_panel.png) 90 | - Four standard build commands (Super+[Shift]+B or Super+[Shift]+F7) 91 | 1. `Build` just checks errors. Kudos to this [tweet][]! 92 | 2. `Run` additionally outputs your compiled program to an inferred path. 93 | 3. The same as the above two, but ignoring warnings 94 | 4. Output path is configurable in `elm-package.json` or `Elm Build System: …` in the Command Palette. Elm build system only requires a valid config in any ancestor directory of the active file. ![compile messages screenshot](images/elm_project.jpg) 95 | - Compile messages 96 | 1. Navigate errors and warnings (Super+[Shift]+F4). 97 | 2. Formatted for build output panel. 98 | 3. Compile message highlighting, embedded code highlighting, and color scheme for output panel. ![compile messages screenshot](images/elm_make.jpg) 99 | - Integration with popular plugins (installed separately) 100 | 1. [SublimeREPL][] — Run `elm-repl` in an editor tab with syntax highlighting. ![SublimeREPL screenshot](images/elm_repl.jpg) 101 | 2. [Highlight Build Errors][] — Does what it says on the box … usually. 102 | - Integration with [elm format](https://github.com/avh4/elm-format) 103 | 1. Make sure `elm-format` is in your PATH 104 | 2. Run the "Elm Language Support: Run elm-format" command from the Command Palette to run elm-format on the current file 105 | 3. To enable automatic formatting on every save, Go to Preferences -> Package Settings -> Elm Language Support -> Settings and add this setting: 106 | `"elm_format_on_save": true` 107 | 4. If there are certain Elm source files you don't want to automatically run `elm-format` on, for example elm-css based files, you can set a regex filter which will search the full filename (including the path to the file). If the regex matches, then it will not automatically run `elm-format` on the file when you save. For example, the following filter would prevent automatic `elm-format` on a file named `elm-css/src/Css/TopBar.elm`: 108 | `"elm_format_filename_filter": "elm-css/src/Css/.*\\.elm$"`![elm-format screenshot](images/elm_format.png) 109 | 110 | ## Troubleshooting 111 | 112 | - I have `elm-oracle` installed, but completions, type signature display, and the type panel don't work 113 | 1. Make sure `elm-oracle` is on your PATH, or 114 | 2. Add the absolute path of the directory containing `elm-oracle` to the `elm_paths` setting in your Elm Language Support User settings 115 | - I have `elm-format` installed, but it's not working 116 | 1. Make sure `elm-format` is on your PATH, or 117 | 2. If using an alternate name for the binary (`elm-format-0.17` or `elm-format-0.18`) add it to the `elm_format_binary` setting in your Elm Language Support User settings; an example might be `"elm_format_binary": "elm-format-0.18",`, or 118 | 3. Add the absolute path of the directory containing `elm-format` to the `elm_paths` setting in your Elm Language Support User settings. Note that you can combine paths with the above, so an example might be `"elm_paths": "/users/alex/elm-format:/users/alex/elm-oracle"` 119 | - Elm format automatically runs every time I save a file, but there are some files I don't want it to run on 120 | 1. If there are certain Elm source files you don't want to automatically run `elm-format` on, for example elm-css based files, you can set a regex filter which will search the full filename (including the path to the file). If the regex matches, then it will not automatically run `elm-format` on the file when you save. For example, the following filter would prevent automatic `elm-format` on a file named `elm-css/src/Css/TopBar.elm`: 121 | `"elm_format_filename_filter": "elm-css/src/Css/.*\\.elm$"` 122 | 123 | ## Learning 124 | 125 | Don't know Elm? Great first step! 126 | 127 | - [Elm Website][] 128 | - [elm-discuss group][] 129 | - [Pragmatic Studio: Building Web Apps with Elm][pragmatic] 130 | - [Elm Town Podcast][] 131 | 132 | [elm-discuss group]: https://groups.google.com/d/forum/elm-discuss 133 | [Elm]: http://elm-lang.org/install 134 | [Elm Town Podcast]: https://elmtown.github.io 135 | [Elm Website]: http://elm-lang.org 136 | [Highlight Build Errors]: https://packagecontrol.io/packages/Highlight%20Build%20Errors 137 | [NPM]: https://nodejs.org 138 | [Package Control]: https://packagecontrol.io/installation 139 | [pragmatic]: https://pragmaticstudio.com/elm 140 | [SublimeREPL]: https://packagecontrol.io/packages/SublimeREPL 141 | [Sublime Text 2]: http://www.sublimetext.com/2 142 | [Sublime Text 3]: http://www.sublimetext.com/3 143 | [tweet]: https://twitter.com/rtfeldman/status/624026168652660740 144 | [elm-0.19]: https://elm-lang.org/blog/small-assets-without-the-headache 145 | -------------------------------------------------------------------------------- /Settings/Elm Language Support.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "debug": false, 3 | "enabled": true, 4 | "elm_format_binary": "elm-format", 5 | "elm_format_on_save": true, 6 | "elm_format_filename_filter": "", 7 | "elm_paths": "", 8 | "build_error_color_scheme": "Packages/Color Scheme - Default/Sunburst.tmTheme" 9 | } 10 | -------------------------------------------------------------------------------- /Settings/Elm User Strings.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "logging.prefix": "[Elm says]: ", 3 | "logging.missing_plugin": "Missing plugin: {0}", 4 | 5 | "make.missing_plugin": "To highlight build errors: Install with Package Control: Highlight Build Errors", 6 | "make.logging.invalid_json": "Invalid JSON from elm-make: {0}", 7 | 8 | "open_in_browser.not_found": "HTML file NOT found to open: {0}", 9 | 10 | "project.not_found": "Valid elm-package.json NOT found to update", 11 | "project.updated": "elm-package.json updated: {0} = {1}", 12 | "project.logging.invalid_choice": "Invalid choice in elm-package.json: {0}", 13 | "project.logging.invalid_json": "Invalid elm-package.json: {0}", 14 | "project.logging.settings": "Detected settings: {0}" 15 | } 16 | -------------------------------------------------------------------------------- /Settings/Elm.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "word_separators": "/\\()\"-:,.;<>!@#$%^&*|+=[]{}`~?", 3 | "translate_tabs_to_spaces": true 4 | } 5 | -------------------------------------------------------------------------------- /Snippets/case_of.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | $3 6 | ${4:_} -> 7 | $5 8 | ]]> 9 | 10 | case … of 11 | cof 12 | source.elm 13 | 14 | -------------------------------------------------------------------------------- /Snippets/case_of_maybe.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | $3 6 | Nothing -> 7 | $4 8 | ]]> 9 | 10 | case … of (Maybe) 11 | cofm 12 | source.elm 13 | 14 | -------------------------------------------------------------------------------- /Snippets/case_of_result.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | $3 6 | Error ${4:error} -> 7 | $5 8 | ]]> 9 | 10 | case … of (Result) 11 | cofr 12 | source.elm 13 | 14 | -------------------------------------------------------------------------------- /Snippets/debug.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | Debug.log 6 | debug 7 | source.elm 8 | 9 | -------------------------------------------------------------------------------- /Snippets/function.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ${2:Int} 4 | ${1:fn} ${4:count} = 5 | ${5:-- body} 6 | ]]> 7 | Function (a -> b) 8 | fn 9 | source.elm 10 | 11 | -------------------------------------------------------------------------------- /Snippets/function_2_aguments.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ${4:Int} -> ${2:Int} 4 | ${1:fn} ${5:a} ${6:a} = 5 | ${7:-- body} 6 | ]]> 7 | Function (a -> b -> c) 8 | fn2 9 | source.elm 10 | 11 | -------------------------------------------------------------------------------- /Snippets/function_3_aguments.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ${4:Int} -> ${5:Int} -> ${2:Int} 4 | ${1:fn} ${6:a} ${7:b} ${8:c} = 5 | ${9:-- body} 6 | ]]> 7 | Function (a -> b -> c -> d) 8 | fn3 9 | source.elm 10 | 11 | -------------------------------------------------------------------------------- /Snippets/function_4_aguments.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ${4:Int} -> ${5:Int} -> ${6:Int} -> ${2:Int} 4 | ${1:fn} ${7:a} ${8:b} ${9:c} ${10:d}= 5 | ${11:-- body} 6 | ]]> 7 | Function (a -> b -> c -> d -> e) 8 | fn4 9 | source.elm 10 | 11 | -------------------------------------------------------------------------------- /Snippets/import.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | import 7 | imp 8 | source.elm 9 | 10 | -------------------------------------------------------------------------------- /Snippets/import_as.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | import … as 7 | impas 8 | source.elm 9 | 10 | -------------------------------------------------------------------------------- /Snippets/let.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | let … in … 11 | let 12 | source.elm 13 | 14 | -------------------------------------------------------------------------------- /Snippets/module.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | module 7 | mod 8 | source.elm 9 | 10 | -------------------------------------------------------------------------------- /Snippets/type.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | type 9 | type 10 | source.elm 11 | 12 | -------------------------------------------------------------------------------- /Snippets/type_alias.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | type alias (Record) 10 | typea 11 | source.elm 12 | 13 | -------------------------------------------------------------------------------- /Syntaxes/Elm Compile Messages.sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/3/syntax.html 4 | name: Elm Compile Messages 5 | hidden: true 6 | file_extensions: [] 7 | scope: text.html.mediawiki.elm-build-output 8 | contexts: 9 | main: 10 | - match: "^(::) " 11 | comment: "|> Unparsed Compile Message" 12 | push: 13 | - meta_scope: comment.line.heading.3.elm-build-output 14 | - match: ^\n$ 15 | pop: true 16 | - match: '\S+[/\.]\S+' 17 | comment: elm-lang/core OR build\index.html 18 | scope: markup.underline.link.elm-build-output 19 | - match: (?i)\bsuccess\w+ 20 | comment: Successfully generated 21 | scope: constant.language.boolean.true.elm-build-output 22 | - match: |- 23 | (?x) # Minimally modified `file_regex` from `Elm Make.sublime-build` 24 | ^\-\-[ ] # Leading delimiter 25 | ((error) # \2: error 26 | |(warning) # \3: warning 27 | |\w+ # \1: any $type 28 | )[:][ ] # separator 29 | (.+) # \4: tag 30 | [ ][-][ ] # separator 31 | (.+?): # \5: $file 32 | (\d+): # \6: $line 33 | (\d+) # \7: $column 34 | \n$ # End 35 | comment: '-- TAG - file:line:column\nOverview\nDetail\n' 36 | captures: 37 | 0: markup.heading.4.elm-build-output 38 | 1: support.constant.type.elm-build-output 39 | 2: invalid.illegal.error.elm-build-output 40 | 3: invalid.deprecated.warning.elm-build-output 41 | 4: support.constant.type.elm-build-output 42 | 5: markup.underline.link.elm-build-output 43 | 6: constant.numeric.elm-build-output 44 | 7: constant.numeric.elm-build-output 45 | push: 46 | - meta_scope: meta.report.elm-build-output 47 | - meta_content_scope: string.unquoted.elm-build-output 48 | - match: ^\n$ 49 | captures: 50 | 0: meta.separator.elm-build-output 51 | pop: true 52 | - match: (`)(?!`) 53 | comment: Inline `variable` 54 | captures: 55 | 0: punctuation.definition.raw.elm-build-output 56 | push: 57 | - meta_scope: markup.raw.inline.elm-build-output 58 | - meta_content_scope: variable.other.elm.elm-build-output 59 | - match: \1 60 | captures: 61 | 0: punctuation.definition.raw.elm-build-output 62 | pop: true 63 | - match: "(?m)^ {4}" 64 | comment: Code Block 65 | push: 66 | - meta_scope: markup.raw.block.elm-build-output 67 | - match: '\n+(?!^ {4})' 68 | pop: true 69 | - include: scope:source.elm 70 | - match: ^\[ 71 | comment: '[Finished in 4.2s]' 72 | push: 73 | - meta_scope: comment.line.brackets.elm-build-output 74 | - match: \b\d+\.\d+(s)\b 75 | scope: constant.numeric.elm-build-output 76 | captures: 77 | 1: keyword.other.unit.elm-build-output 78 | - match: \] 79 | pop: true 80 | -------------------------------------------------------------------------------- /Syntaxes/Elm Documentation.sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/3/syntax.html 4 | name: Elm Documentation 5 | hidden: true 6 | file_extensions: [] 7 | scope: text.html.mediawiki.elm-documentation 8 | contexts: 9 | main: 10 | - match: '\x{FEFF}' 11 | comment: Code Block 12 | push: 13 | - meta_scope: markup.raw.block.elm-documentation 14 | - meta_content_scope: markup.raw.block.elm-documentation 15 | - match: '\x{FEFF}' 16 | pop: true 17 | - include: scope:source.elm 18 | -------------------------------------------------------------------------------- /Syntaxes/Elm.sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/3/syntax.html 4 | name: Elm 5 | file_extensions: 6 | - elm 7 | scope: source.elm 8 | contexts: 9 | main: 10 | - match: "(`)[a-zA-Z_']*?(`)" 11 | scope: keyword.operator.function.infix.elm 12 | captures: 13 | 1: punctuation.definition.entity.elm 14 | 2: punctuation.definition.entity.elm 15 | - match: \(\) 16 | scope: constant.language.unit.elm 17 | - match: ^\b((effect|port)\s+)?(module)\s+ 18 | captures: 19 | 1: keyword.other.elm 20 | 3: keyword.other.elm 21 | push: 22 | - meta_scope: meta.declaration.module.elm 23 | - match: $|; 24 | captures: 25 | 1: keyword.other.elm 26 | pop: true 27 | - include: module_name 28 | - match: '(where)\s*\{' 29 | captures: 30 | 1: keyword.other.elm 31 | push: 32 | - match: '\}' 33 | pop: true 34 | - include: type_signature 35 | - match: (exposing) 36 | scope: keyword.other.elm 37 | - include: module_exports 38 | - match: (where) 39 | scope: keyword.other.elm 40 | - match: "[a-z]+" 41 | scope: invalid 42 | - match: ^\b(import)\s+((open)\s+)? 43 | captures: 44 | 1: keyword.other.elm 45 | 3: invalid 46 | push: 47 | - meta_scope: meta.import.elm 48 | - match: ($|;) 49 | pop: true 50 | - match: (as|exposing) 51 | scope: keyword.import.elm 52 | - include: module_name 53 | - include: module_exports 54 | - match: '(\[)(glsl)(\|)' 55 | captures: 56 | 1: keyword.other.elm 57 | 2: support.function.prelude.elm 58 | 3: keyword.other.elm 59 | push: 60 | - meta_scope: entity.glsl.elm 61 | - match: '(\|\])' 62 | captures: 63 | 1: keyword.other.elm 64 | pop: true 65 | - include: scope:source.glsl 66 | - match: type( alias)? (\w+) 67 | scope: keyword.other.elm 68 | captures: 69 | 2: entity.name.type.elm 70 | - match: \b(case|of|let|in|as)\s+ 71 | scope: keyword.other.elm 72 | - match: \b(if|then|else)\s+ 73 | scope: keyword.control.elm 74 | - match: '\b([0-9]+\.[0-9]+([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)\b' 75 | comment: Floats are always decimal 76 | scope: constant.numeric.float.elm 77 | - match: '\b([0-9]+)\b' 78 | scope: constant.numeric.elm 79 | - match: '"""' 80 | captures: 81 | 0: punctuation.definition.string.begin.elm 82 | push: 83 | - meta_scope: string.quoted.double.elm 84 | - match: '"""' 85 | captures: 86 | 0: punctuation.definition.string.end.elm 87 | pop: true 88 | - match: '\\(NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|[abfnrtv\\''\&])' 89 | scope: constant.character.escape.elm 90 | - match: '\^[A-Z@\[\]\\\^_]' 91 | scope: constant.character.escape.control.elm 92 | - match: '"' 93 | captures: 94 | 0: punctuation.definition.string.begin.elm 95 | push: 96 | - meta_scope: string.quoted.double.elm 97 | - match: '"' 98 | captures: 99 | 0: punctuation.definition.string.end.elm 100 | pop: true 101 | - match: '\\(NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|[abfnrtv\\\"''\&])' 102 | scope: constant.character.escape.elm 103 | - match: '\^[A-Z@\[\]\\\^_]' 104 | scope: constant.character.escape.control.elm 105 | - match: |- 106 | (?x) 107 | (') 108 | (?: 109 | [\ -\[\]-~] # Basic Char 110 | | (\\(?:NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE 111 | |DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS 112 | |US|SP|DEL|[abfnrtv\\\"'\&])) # Escapes 113 | | (\^[A-Z@\[\]\\\^_]) # Control Chars 114 | ) 115 | (') 116 | scope: string.quoted.single.elm 117 | captures: 118 | 1: punctuation.definition.string.begin.elm 119 | 2: constant.character.escape.elm 120 | 3: punctuation.definition.string.end.elm 121 | - match: '^(port\s+)?([a-z_][a-zA-Z0-9_'']*|\([|!%$+\-.,=]+\))\s*((:)([:]+)?)' 122 | captures: 123 | 1: keyword.other.port.elm 124 | 2: entity.name.function.elm hide.from.goto_symbol 125 | 4: keyword.other.colon.elm 126 | 5: invalid 127 | push: 128 | - meta_scope: meta.function.type-declaration.elm 129 | - match: $\n? 130 | pop: true 131 | - include: type_signature 132 | - match: \bport\s+ 133 | scope: keyword.other.port.elm 134 | - match: '\b[A-Z]\w*\b' 135 | scope: constant.other.elm 136 | - include: comments 137 | - match: '^[a-z][A-Za-z0-9_'']*\s+' 138 | scope: entity.name.function.elm 139 | - include: infix_op 140 | - match: '[|!%$?~+:\-.=&\\*^]+' 141 | scope: keyword.operator.elm 142 | - match: '([\[\]\{\},])' 143 | scope: constant.language.delimiter.elm 144 | captures: 145 | 1: support.function.delimiter.elm 146 | - match: '([\(\)])' 147 | scope: keyword.other.parenthesis.elm 148 | block_comment: 149 | - match: '\{-(?!#)' 150 | captures: 151 | 0: punctuation.definition.comment.elm 152 | push: 153 | - meta_scope: comment.block.elm 154 | - include: block_comment 155 | - match: '-\}' 156 | captures: 157 | 0: punctuation.definition.comment.elm 158 | pop: true 159 | comments: 160 | - match: (--).*$\n? 161 | scope: comment.line.double-dash.elm 162 | captures: 163 | 1: punctuation.definition.comment.elm 164 | - include: block_comment 165 | infix_op: 166 | - match: '(\([|!%$+:\-.=]+\)|\(,+\))' 167 | scope: entity.name.function.infix.elm 168 | module_exports: 169 | - match: \( 170 | push: 171 | - meta_scope: meta.declaration.exports.elm 172 | - match: \) 173 | pop: true 174 | - match: '\b[a-z][a-zA-Z_''0-9]*' 175 | scope: entity.name.function.elm 176 | - match: '\b[A-Z][A-Za-z_''0-9]*' 177 | scope: storage.type.elm 178 | - match: "," 179 | scope: punctuation.separator.comma.elm 180 | - include: infix_op 181 | - match: \(.*?\) 182 | comment: So named because I don't know what to call this. 183 | scope: meta.other.unknown.elm 184 | module_name: 185 | - match: "[A-Z][A-Za-z._'0-9]*" 186 | scope: support.other.module.elm 187 | type_signature: 188 | - match: '\(\s*([A-Z][A-Za-z]*)\s+([a-z][A-Za-z_'']*)\)\s*(=>)' 189 | scope: meta.class-constraint.elm 190 | captures: 191 | 1: entity.other.inherited-class.elm 192 | 2: variable.other.generic-type.elm 193 | 3: keyword.other.big-arrow.elm 194 | - match: "->" 195 | scope: keyword.other.arrow.elm 196 | - match: "=>" 197 | scope: keyword.other.big-arrow.elm 198 | - match: '\b[a-z][a-zA-Z0-9_'']*\b' 199 | scope: variable.other.generic-type.elm 200 | - match: '\b[A-Z][a-zA-Z0-9_'']*\b' 201 | scope: storage.type.elm 202 | - match: \(\) 203 | scope: support.constant.unit.elm 204 | - include: comments 205 | -------------------------------------------------------------------------------- /beta-repository.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "3.0.0", 3 | "packages": [ 4 | { 5 | "name": "Elm Language Support", 6 | "details": "https://github.com/deadfoxygrandpa/Elm.tmLanguage", 7 | "releases": [ 8 | { 9 | "sublime_text": "*", 10 | "branch": "beta" 11 | } 12 | ] 13 | } 14 | ], 15 | "dependencies": [ 16 | ], 17 | "includes": [ 18 | ] 19 | } -------------------------------------------------------------------------------- /elm_format.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import subprocess 4 | import os, os.path 5 | import re 6 | import sublime, sublime_plugin 7 | 8 | 9 | class ElmFormatCommand(sublime_plugin.TextCommand): 10 | def run(self, edit): 11 | 12 | # Hide the console window on Windows 13 | shell = False 14 | path_separator = ':' 15 | if os.name == "nt": 16 | shell = True 17 | path_separator = ';' 18 | 19 | settings = sublime.load_settings('Elm Language Support.sublime-settings') 20 | binary = settings.get('elm_format_binary', 'elm-format') 21 | path = settings.get('elm_paths', '') 22 | if path: 23 | old_path = os.environ['PATH'] 24 | os.environ['PATH'] = os.path.expandvars(path + path_separator + '$PATH') 25 | 26 | command = [binary, self.view.file_name(), '--yes'] 27 | p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell) 28 | 29 | if path: 30 | os.environ['PATH'] = old_path 31 | 32 | output, errors = p.communicate() 33 | 34 | if errors.strip(): 35 | # If there is a error while running it. It should show the syntax errors 36 | panel_view = self.view.window().create_output_panel("elm_format") 37 | panel_view.set_read_only(False) 38 | panel_view.run_command('erase_view') 39 | 40 | # elm-format should have a --no-color option https://github.com/avh4/elm-format/issues/372 41 | errors = re.sub('\x1b\[\d{1,2}m', '', errors.strip().decode()) 42 | 43 | panel_view.run_command('append', {'characters': errors}) 44 | panel_view.set_read_only(True) 45 | self.view.window().run_command("show_panel", {"panel": "output.elm_format"}) 46 | else: 47 | self.view.window().run_command("hide_panel", {"panel": "output.elm_format"}) 48 | 49 | 50 | if settings.get('debug', False): 51 | string_settings = sublime.load_settings('Elm User Strings.sublime-settings') 52 | print(string_settings.get('logging.prefix', '') + '(' + binary + ') ' + str(output.strip()), '\nerrors: ' + str(errors.strip())) 53 | if str(errors.strip()): 54 | print('Your PATH is: ', os.environ['PATH']) 55 | 56 | 57 | class ElmFormatOnSave(sublime_plugin.EventListener): 58 | def on_post_save(self, view): 59 | sel = view.sel()[0] 60 | region = view.word(sel) 61 | scope = view.scope_name(region.b) 62 | if scope.find('source.elm') != -1: 63 | settings = sublime.load_settings('Elm Language Support.sublime-settings') 64 | if settings.get('elm_format_on_save', True): 65 | regex = settings.get('elm_format_filename_filter', '') 66 | if not (len(regex) > 0 and re.search(regex, view.file_name()) is not None): 67 | view.run_command('elm_format') 68 | -------------------------------------------------------------------------------- /elm_generate.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import sys 4 | 5 | class Module(object): 6 | def __init__(self, data): 7 | self.name = data['name'] 8 | self.values = [name(v['raw']) + ' : ' + signature(v['raw']) for v in data['values']] 9 | self.valueNames = [name(v) for v in self.values] 10 | self.datatypes = [v['name'] for v in data['datatypes']] 11 | self.constructors = [[v['name'] for v in x['constructors']] for x in data['datatypes']] 12 | self.aliases = [v['name'] for v in data['aliases']] 13 | 14 | def include_text(self): 15 | s = '\n\tinclude\n\t#{}\n'.format(self.name.lower()) 16 | return s 17 | 18 | def moduleText(self): 19 | s = '{nameLower}\n\n\tcaptures\n\t\n\t\t1\n\t\t\n\t\t\tname\n\t\t\tvariable.parameter\n\t\t\n\t\t2\n\t\t\n\t\t\tname\n\t\t\tvariable.parameter\n\t\t\n\t\t3\n\t\t\n\t\t\tname\n\t\t\tsupport.function.elm\n\t\t\n\t\n\tmatch\n\t\\b({name})(.)({values})\\b\n\tname\n\tvariable.parameter\n' 20 | values = '|'.join([n for n in self.valueNames if not n.startswith('(')]) 21 | if self.aliases: 22 | values += '|' + '|'.join(self.aliases) 23 | if self.datatypes: 24 | values += '|' + '|'.join(self.datatypes) 25 | return s.format(nameLower=self.name.lower(), name=self.name, values=values) 26 | 27 | def snippets(self): 28 | base = 'Snippets' 29 | s = '\n\t\n\t\n\t{name}\n\t\n\tsource.elm\n\t{signature}\n' 30 | for v in [func for func in self.values if not name(func).startswith('(')]: 31 | subdirectories = self.name.split('.') 32 | path = '{}' + '\\{}'*(len(subdirectories)) 33 | path = path.format(base, *subdirectories) 34 | 35 | if not os.path.exists(path): 36 | os.makedirs(path) 37 | 38 | path += '\\{}' 39 | 40 | with open(path.format(name(v) + '.sublime-snippet'), 'w') as f: 41 | f.write(s.format(autocomplete=make_autocomplete(v), name=name(v), signature=signature(v))) 42 | 43 | print('Wrote {}'.format(path.format(name(v) + '.sublime-snippet'))) 44 | 45 | def name(t): 46 | return t.split(' : ')[0].strip() 47 | 48 | def signature(t): 49 | return t.split(' : ')[1].strip() 50 | 51 | def hintize(t): 52 | first = t[0].lower() 53 | t = t.replace(' ', '') 54 | return first + ''.join(t[1:]) 55 | 56 | def typeFormat(t): 57 | if t[0] == '[': 58 | return 'ListOf' + typeFormat(t[1:-1]) 59 | elif t[0] == '(': 60 | return ''.join([unicode(v.strip()) for v in t[1:-1].split(',')]) + 'Tuple' 61 | else: 62 | if len(t.split(' ')) == 1: 63 | return t 64 | else: 65 | x = t.split(' ') 66 | return x[0] + ''.join([typeFormat(v) for v in x[1:]]) 67 | 68 | def tokenize(t): 69 | return [v.strip() for v in t.split('->')] 70 | 71 | def print_type(t): 72 | print(name(t)) 73 | print([typeFormat(v) for v in tokenize(signature(t))]) 74 | 75 | def make_autocomplete(t): 76 | s = '{}'.format(name(t)) 77 | args = arguments(signature(t)) 78 | for n, arg in enumerate(args): 79 | s += ' ${{{n}:{arg}}}'.format(n=n+1, arg=arg) 80 | return s 81 | 82 | def arguments(signature): 83 | args = [v.strip() for v in signature.split('->')][:-1] 84 | new_args = [] 85 | open_parens = 0 86 | for arg in args: 87 | parens = arg.count('(') - arg.count(')') 88 | if parens and not open_parens: 89 | new_args.append('function') 90 | elif open_parens != 0: 91 | open_parens += parens 92 | continue 93 | else: 94 | new_args.append(argify(arg)) 95 | open_parens += parens 96 | return new_args 97 | 98 | def argify(s): 99 | if s.startswith('('): 100 | return 'tuple' 101 | elif s.startswith('['): 102 | return 'list' 103 | elif len(s.split(' ')) > 1: 104 | return s.split(' ')[0].lower() 105 | else: 106 | return s.lower() 107 | 108 | def loadDocs(path): 109 | with open(path) as f: 110 | return json.load(f) 111 | 112 | 113 | if __name__ == '__main__': 114 | ## Usage: pass in docs.json from cabal's elm directory 115 | path = sys.argv[1] 116 | prelude = ['Basics', 'List', 'Signal', 'Text', 'Maybe', 'Time', 'Graphics.Element', 'Color', 'Graphics.Collage'] 117 | 118 | modules = [Module(m) for m in loadDocs(path)] 119 | 120 | print('Prelude:') 121 | print('show|') 122 | for m in modules: 123 | if m.name in prelude: 124 | print('|'.join([n for n in m.valueNames if not n.startswith('(')])) 125 | 126 | print('\n'*5) 127 | 128 | print('Prelude Aliases and Datatypes:') 129 | print('Int|Float|Char|Bool|String|True|False') 130 | for m in modules: 131 | if m.name in prelude: 132 | print('|'.join([n for n in (m.datatypes + m.aliases) if not n.startswith('(')]) + '|') 133 | 134 | print('\n'*5) 135 | 136 | print('Includes:') 137 | for m in modules: 138 | print(m.include_text()) 139 | 140 | print('\n'*5) 141 | 142 | print('Includes Continued:') 143 | for m in modules: 144 | print(m.moduleText()) 145 | 146 | print('\n'*5) 147 | 148 | print('Constructors:') 149 | print('\(\)|\[\]|True|False|Int|Char|Bool|String|') 150 | for m in modules: 151 | if m.name in prelude: 152 | for c in m.constructors: 153 | print('|'.join(c) + '|') 154 | 155 | print('\n'*5) 156 | 157 | print('Writing Autocompletion Snippets...:') 158 | for m in modules: 159 | if m.name in prelude: 160 | m.snippets() 161 | print('\n'*2) 162 | 163 | with open('Snippets\\Basics\\markdown.sublime-snippet', 'w') as f: 164 | f.write('\n\n\nmarkdown\n\nsource.elm\nA markdown block\n') 165 | print('Wrote markdown.sublime-snippet') 166 | -------------------------------------------------------------------------------- /elm_make.py: -------------------------------------------------------------------------------- 1 | import json 2 | import re 3 | import string 4 | import sublime 5 | 6 | try: # ST3 7 | from .elm_plugin import * 8 | from .elm_project import ElmProject 9 | except: # ST2 10 | from elm_plugin import * 11 | from elm_project import ElmProject 12 | default_exec = import_module('Default.exec') 13 | 14 | @replace_base_class('Highlight Build Errors.HighlightBuildErrors.ExecCommand') 15 | class ElmMakeCommand(default_exec.ExecCommand): 16 | 17 | # inspired by: http://www.sublimetext.com/forum/viewtopic.php?t=12028 18 | def run(self, error_format, info_format, syntax, null_device, warnings, **kwargs): 19 | self.buffer = '' 20 | self.data_in_bytes = False # ST3 r3153 changed ExecCommand from bytes to str so we must detect which we get and handle appropriately: https://github.com/elm-community/SublimeElmLanguageSupport/issues/48 21 | self.warnings = warnings == "true" 22 | self.error_format = string.Template(error_format) 23 | self.info_format = string.Template(info_format) 24 | self.run_with_project(null_device=null_device, **kwargs) 25 | self.style_output(syntax) 26 | 27 | def run_with_project(self, cmd, working_dir, null_device, **kwargs): 28 | file_arg, output_arg = cmd[1:3] 29 | project = ElmProject(file_arg) 30 | log_string('project.logging.settings', repr(project)) 31 | if '{output}' in output_arg: 32 | cmd[1] = fs.expanduser(project.main_path) 33 | output_path = fs.expanduser(project.output_path) 34 | cmd[2] = output_arg.format(output=output_path) 35 | else: 36 | # cmd[1] builds active file rather than project main 37 | cmd[2] = output_arg.format(null=null_device) 38 | project_dir = project.working_dir or working_dir 39 | # ST2: TypeError: __init__() got an unexpected keyword argument 'syntax' 40 | super(ElmMakeCommand, self).run(cmd, working_dir=project_dir, **kwargs) 41 | 42 | def style_output(self, syntax): 43 | self.output_view.set_syntax_file(syntax) 44 | elm_setting = sublime.load_settings('Elm Language Support.sublime-settings') 45 | user_setting = sublime.load_settings('Preferences.sublime-settings') 46 | color_scheme = elm_setting.get('build_error_color_scheme') or user_setting.get('color_scheme') 47 | self.output_view.settings().set('color_scheme', color_scheme) 48 | if self.is_patched: 49 | self.debug_text = '' 50 | else: 51 | self.debug_text = get_string('make.missing_plugin') 52 | 53 | def on_data(self, proc, data): 54 | if isinstance(data, str): 55 | self.buffer += data 56 | else: 57 | # ST3 r3153 changed ExecCommand from bytes to str so we must detect which we get and handle appropriately: https://github.com/elm-community/SublimeElmLanguageSupport/issues/48 58 | self.data_in_bytes = True 59 | self.buffer += data.decode(self.encoding) 60 | 61 | def on_finished(self, proc): 62 | result_strs = self.buffer.split('\n') 63 | flat_map = lambda f, xss: sum(map(f, xss), []) 64 | output_strs = flat_map(self.format_result, result_strs) + [''] 65 | output_data = '\n'.join(output_strs) 66 | # ST3 r3153 changed ExecCommand from bytes to str so we must detect which we get and handle appropriately: https://github.com/elm-community/SublimeElmLanguageSupport/issues/48 67 | output_data = output_data.encode(self.encoding) if self.data_in_bytes else output_data 68 | super(ElmMakeCommand, self).on_data(proc, output_data) 69 | super(ElmMakeCommand, self).on_finished(proc) 70 | 71 | def format_result(self, result_str): 72 | decode_error = lambda dict: self.format_error(**dict) if 'type' in dict else dict 73 | try: 74 | data = json.loads(result_str, object_hook=decode_error) 75 | return [s for s in data if s is not None] 76 | except ValueError: 77 | log_string('make.logging.invalid_json', result_str) 78 | info_str = result_str.strip() 79 | return [self.info_format.substitute(info=info_str)] if info_str else [] 80 | 81 | def format_error(shelf, type, file, region, tag, overview, details, **kwargs): 82 | if type == 'warning' and not shelf.warnings: 83 | return None 84 | line = region['start']['line'] 85 | column = region['start']['column'] 86 | message = overview 87 | if details: 88 | message += '\n' + re.sub(r'(\n)+', r'\1', details) 89 | # TypeError: substitute() got multiple values for argument 'self' 90 | # https://bugs.python.org/issue23671 91 | return shelf.error_format.substitute(**locals()) 92 | -------------------------------------------------------------------------------- /elm_open_in_browser.py: -------------------------------------------------------------------------------- 1 | import webbrowser 2 | 3 | try: # ST3 4 | import urllib.parse as urlparse 5 | import urllib.request as urllib 6 | 7 | from .elm_plugin import * 8 | from .elm_project import ElmProject 9 | except: # ST2 10 | import urlparse 11 | import urllib 12 | 13 | from elm_plugin import * 14 | from elm_project import ElmProject 15 | 16 | class ElmOpenInBrowserCommand(sublime_plugin.TextCommand): 17 | 18 | def is_enabled(self): 19 | self.project = ElmProject(self.view.file_name()) 20 | return self.project.exists 21 | 22 | def run(self, edit): 23 | norm_path = fs.join(self.project.working_dir, fs.expanduser(self.project.html_path)) 24 | file_path = fs.abspath(norm_path) 25 | if fs.isfile(file_path): 26 | # http://stackoverflow.com/questions/11687478/convert-a-filename-to-a-file-url#comment32679033_14298190 27 | file_url = urlparse.urljoin('file:', urllib.pathname2url(file_path)) 28 | # inspired by https://github.com/noahcoad/open-url 29 | webbrowser.open_new_tab(file_url) 30 | else: 31 | sublime.status_message(get_string('open_in_browser.not_found', html_path)) 32 | -------------------------------------------------------------------------------- /elm_plugin.py: -------------------------------------------------------------------------------- 1 | import sublime 2 | import sublime_plugin 3 | import os.path as fs 4 | 5 | def is_ST2(): 6 | return sublime.version().startswith('2') 7 | 8 | def get_string(key, *args): 9 | strings = sublime.load_settings('Elm User Strings.sublime-settings') 10 | return strings.get('logging.prefix') + strings.get(key).format(*args) 11 | 12 | def log_string(key, *args): 13 | def log_string_with_retry(retry): 14 | try: 15 | # ST2: RuntimeError: Must call on main thread 16 | settings = sublime.load_settings('Elm Language Support.sublime-settings') 17 | except RuntimeError: 18 | if retry: 19 | sublime.set_timeout(lambda: log_string_with_retry(False), 0) 20 | else: 21 | import traceback 22 | traceback.print_exc() 23 | else: 24 | if settings.get('debug'): 25 | print(get_string(key, *args)) 26 | 27 | log_string_with_retry(True) 28 | 29 | def import_module(path): 30 | names = path.split('.') 31 | index = 1 if is_ST2() else 0 32 | base = __import__(names[index]) 33 | for name in names[index + 1:]: 34 | base = getattr(base, name) 35 | return base 36 | 37 | # defer import as long as possible in case plugin not loaded 38 | def replace_base_class(path): 39 | def splice_bases(old_base, *extra_bases): 40 | try: 41 | new_base = import_module(path) 42 | except ImportError: 43 | module_name = path[:path.index('.')] 44 | log_string('logging.missing_plugin', module_name) 45 | return None 46 | else: 47 | return (new_base,) + extra_bases 48 | 49 | def monkey_patch(target_cls): 50 | if not hasattr(target_cls, 'is_patched'): 51 | new_bases = splice_bases(target_cls.__bases__) 52 | target_cls.is_patched = bool(new_bases) 53 | if new_bases: 54 | target_cls.__bases__ = new_bases 55 | 56 | def decorator(target_cls): 57 | def new(cls, *args, **kwargs): 58 | monkey_patch(target_cls) 59 | super_ = super(target_cls, cls).__new__ 60 | # TypeError: object() takes no parameters 61 | return super_(cls) if super_ is object.__new__ else super_(cls, *args, **kwargs) 62 | 63 | assert '__new__' not in target_cls.__dict__ 64 | # ST2: TypeError: unbound method new() 65 | target_cls.__new__ = classmethod(new) 66 | return target_cls 67 | 68 | return decorator 69 | -------------------------------------------------------------------------------- /elm_project.py: -------------------------------------------------------------------------------- 1 | import collections 2 | import json 3 | 4 | try: # ST3 5 | from .elm_plugin import * 6 | except: # ST2 7 | from elm_plugin import * 8 | 9 | class ElmProjectCommand(sublime_plugin.TextCommand): 10 | 11 | def is_enabled(self): 12 | self.project = ElmProject(self.view.file_name()) 13 | return self.project.exists 14 | 15 | def run(self, edit, prop_name=None, choices=None, caption=None): 16 | self.window = self.view.window() 17 | if not prop_name: 18 | self.window.open_file(self.project.json_path, sublime.TRANSIENT) 19 | return 20 | self.prop_name = prop_name 21 | initial_value = getattr(self.project, prop_name) 22 | if choices: 23 | self.show_choices(choices, initial_value) 24 | else: 25 | self.window.show_input_panel(caption, initial_value, self.on_finished, None, None) 26 | 27 | def show_choices(self, choices, initial_value): 28 | self.norm_choices = [choice.lower() for choice in choices] 29 | try: 30 | # ValueError: $initial_value is not in list 31 | initial_index = self.norm_choices.index(initial_value.lower()) 32 | # ST2: Boost.Python.ArgumentError: Python argument types 33 | self.window.show_quick_panel(choices, self.on_choice, selected_index=initial_index) 34 | except: # simplest control flow 35 | if not is_ST2(): 36 | log_string('project.logging.invalid_choice', initial_value) 37 | self.window.show_quick_panel(choices, self.on_choice) 38 | 39 | def on_choice(self, index): 40 | if index != -1: 41 | self.on_finished(self.norm_choices[index]) 42 | 43 | def on_finished(self, value): 44 | setattr(self.project, self.prop_name, value) 45 | keys = self.project._last_updated_key_path 46 | if keys: 47 | sublime.status_message(get_string('project.updated', '.'.join(keys), value)) 48 | 49 | BUILD_KEY = ('sublime-build',) 50 | MAIN_KEY = BUILD_KEY + ('main',) 51 | HTML_KEY = BUILD_KEY + ('html',) 52 | OUTPUT_KEY = BUILD_KEY + ('output',) 53 | OUTPUT_PATH_KEY = OUTPUT_KEY + ('path',) 54 | OUTPUT_COMP_KEY = OUTPUT_KEY + ('components',) 55 | OUTPUT_DIR_KEY = OUTPUT_COMP_KEY + ('dir',) 56 | OUTPUT_NAME_KEY = OUTPUT_COMP_KEY + ('name',) 57 | OUTPUT_EXT_KEY = OUTPUT_COMP_KEY + ('ext',) 58 | 59 | class ElmProject(object): 60 | 61 | @classmethod 62 | def find_json(cls, dir_path): 63 | if not fs.isdir(fs.abspath(dir_path)): 64 | return None 65 | file_path = fs.abspath(fs.join(dir_path, 'elm-package.json')) 66 | if fs.isfile(file_path): 67 | return file_path 68 | parent_path = fs.join(dir_path, fs.pardir) 69 | if fs.abspath(parent_path) == fs.abspath(dir_path): 70 | return None 71 | return cls.find_json(parent_path) 72 | 73 | def __init__(self, file_path): 74 | self.file_path = file_path 75 | self.json_path = self.find_json(fs.dirname(file_path or '')) 76 | self.data_dict = self.load_json() 77 | 78 | def __getitem__(self, keys): 79 | if not self.exists: 80 | return None 81 | item = self.data_dict 82 | for key in keys: 83 | item = item.get(key) 84 | if not item: 85 | break 86 | return item 87 | 88 | def __setitem__(self, keys, value): 89 | self._last_updated_key_path = None 90 | if not self.exists: 91 | sublime.error_message(get_string('project.not_found')) 92 | return 93 | item = self.data_dict 94 | for key in keys[0:-1]: 95 | item = item.setdefault(key, {}) 96 | item[keys[-1]] = value 97 | self.save_json() 98 | self._last_updated_key_path = keys 99 | 100 | def __repr__(self): 101 | members = [(name, getattr(self, name), ' ' * 4) 102 | for name in dir(self) if name[0] != '_'] 103 | properties = ["{indent}{name}={value},".format(**locals()) 104 | for name, value, indent in members if not callable(value)] 105 | return "{0}(\n{1}\n)".format(self.__class__.__name__, '\n'.join(properties)) 106 | 107 | def load_json(self): 108 | try: 109 | with open(self.json_path) as json_file: 110 | if is_ST2(): # AttributeError: 'module' object has no attribute 'OrderedDict' 111 | return json.load(json_file) 112 | else: 113 | return json.load(json_file, object_pairs_hook=collections.OrderedDict) 114 | except TypeError: # self.json_path == None 115 | pass 116 | except ValueError: 117 | log_string('project.logging.invalid_json', self.json_path) 118 | return None 119 | 120 | def save_json(self): 121 | with open(self.json_path, 'w') as json_file: 122 | json.dump(self.data_dict, json_file, 123 | indent=4, 124 | separators=(',', ': '), 125 | sort_keys=is_ST2()) 126 | 127 | @property 128 | def exists(self): 129 | return bool(self.data_dict) 130 | 131 | @property 132 | def working_dir(self): 133 | return fs.dirname(self.json_path) if self.json_path else None 134 | 135 | @property 136 | def main_path(self): 137 | return self[MAIN_KEY] or fs.relpath(self.file_path, self.working_dir) 138 | 139 | @main_path.setter 140 | def main_path(self, value): 141 | self[MAIN_KEY] = value 142 | 143 | @property 144 | def html_path(self): 145 | return self[HTML_KEY] or self.output_path 146 | 147 | @html_path.setter 148 | def html_path(self, value): 149 | self[HTML_KEY] = value 150 | 151 | @property 152 | def output_path(self): 153 | output_path = fs.join(self.output_dir, self.output_name + '.' + self.output_ext) 154 | return self[OUTPUT_PATH_KEY] or fs.normpath(output_path) 155 | 156 | @output_path.setter 157 | def output_path(self, value): 158 | self[OUTPUT_PATH_KEY] = value 159 | 160 | @property 161 | def output_dir(self): 162 | return self[OUTPUT_DIR_KEY] or 'build' 163 | 164 | @output_dir.setter 165 | def output_dir(self, value): 166 | self[OUTPUT_DIR_KEY] = value 167 | 168 | @property 169 | def output_name(self): 170 | return self[OUTPUT_NAME_KEY] or fs.splitext(fs.basename(self.main_path))[0] 171 | 172 | @output_name.setter 173 | def output_name(self, value): 174 | self[OUTPUT_NAME_KEY] = value 175 | 176 | @property 177 | def output_ext(self): 178 | return self[OUTPUT_EXT_KEY] or 'html' 179 | 180 | @output_ext.setter 181 | def output_ext(self, value): 182 | self[OUTPUT_EXT_KEY] = value 183 | -------------------------------------------------------------------------------- /elm_show_type.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import webbrowser 4 | import os, os.path 5 | import subprocess 6 | import json 7 | import re 8 | from difflib import SequenceMatcher 9 | 10 | import sublime, sublime_plugin 11 | 12 | try: # ST3 13 | from .elm_project import ElmProject 14 | except: # ST2 15 | from elm_project import ElmProject 16 | 17 | LOOKUPS = {} 18 | 19 | def join_qualified(region, view): 20 | """ 21 | Given a region, expand outward on periods to return a new region defining 22 | the entire word, in the context of Elm syntax. 23 | 24 | For example, when the region encompasses the 'map' part of a larger 25 | 'Dict.map' word, this function will return the entire region encompassing 26 | 'Dict.map'. The same is true if the region is encompassing 'Dict'. 27 | 28 | Recursively expands outward in both directions, correctly returning longer 29 | constructions such as 'Graphics.Input.button' 30 | """ 31 | starting_region = region 32 | prefix = view.substr(region.a - 1) 33 | suffix = view.substr(region.b) 34 | if prefix == '.': 35 | region = region.cover(view.word(region.a - 2)) 36 | if suffix == '.': 37 | region = region.cover(view.word(region.b + 1)) 38 | 39 | if region == starting_region: 40 | return region 41 | else: 42 | return join_qualified(region, view) 43 | 44 | def get_word_under_cursor(view): 45 | sel = view.sel()[0] 46 | region = join_qualified(view.word(sel), view) 47 | return view.substr(region).strip() 48 | 49 | def get_type(view, panel): 50 | """ 51 | Given a view, return the type signature of the word under the cursor, 52 | if found. If no type is found, return an empty string. Write the info 53 | to an output panel. 54 | """ 55 | sel = view.sel()[0] 56 | region = join_qualified(view.word(sel), view) 57 | scope = view.scope_name(region.b) 58 | if scope.find('source.elm') != -1 and scope.find('string') == -1 and scope.find('comment') == -1: 59 | filename = view.file_name() 60 | word = view.substr(region).strip() 61 | sublime.set_timeout_async(lambda: search_and_set_status_message(filename, word, panel, 0), 0) 62 | 63 | def search_and_set_status_message(filename, query, panel, tries): 64 | """ 65 | Given a filename and a query, look up in the in-memory dict of values 66 | pulled from elm oracle to find a match. If a match is found, display 67 | the type signature in the status bar and set it in the output panel. 68 | """ 69 | global LOOKUPS 70 | if len(query) == 0: 71 | return None 72 | if filename not in LOOKUPS.keys(): 73 | if tries >= 10: 74 | return None 75 | else: 76 | # if the filename is not found loaded into memory, it's probably being 77 | # loaded into memory right now. Try 10 more times at 100ms intervals 78 | # and if it still isn't loaded, there's likely a problem we can't fix 79 | # here. 80 | sublime.set_timeout_async(search_and_set_status_message(filename, query, panel, tries + 1), 100) 81 | else: 82 | data = LOOKUPS[filename] 83 | if len(data) > 0: 84 | matches = [item for item in data if item['name'] == query.split('.')[-1]] 85 | if len(matches) == 0: 86 | return None 87 | else: 88 | # sort matches by similarity to query 89 | matches.sort(key=lambda x: SequenceMatcher(None, query, x['fullName']).ratio(), reverse=True) 90 | item = matches[0] 91 | type_signature = item['fullName'] + ' : ' + item['signature'] 92 | sublime.status_message(type_signature) 93 | panel.run_command('erase_view') 94 | # add full name and type annotation 95 | panel_output = '`' + type_signature + '`' + '\n\n' + item['comment'][1:] 96 | # replace backticks with no-width space for syntax highlighting 97 | panel_output = panel_output.replace('`', '\uFEFF') 98 | # add no-width space to beginning and end of code blocks for syntax highlighting 99 | panel_output = re.sub('\n( {4}[\s\S]+?)((?=\n\S)\n|\Z)', '\uFEFF\n\\1\uFEFF\n', panel_output) 100 | # remove first four spaces on each line from code blocks 101 | panel_output = re.sub('\n {4}', '\n', panel_output) 102 | panel.run_command('append', {'characters': panel_output}) 103 | return None 104 | 105 | def get_matching_names(filename, prefix): 106 | """ 107 | Given a file name and a search prefix, return a list of matching 108 | completions from elm oracle. 109 | """ 110 | def skip_chars(full_name): 111 | # Sublime Text seems to have odd behavior on completions. If the full 112 | # name is at the same "path level" as the prefix, then the completion 113 | # will replace the entire entry, otherwise it will only replace after 114 | # the final period separator 115 | full_name_path = full_name.split('.')[:-1] 116 | prefix_path = prefix.split('.')[:-1] 117 | if full_name_path == prefix_path: 118 | return full_name 119 | else: 120 | # get the characters to remove from the completion to avoid duplication 121 | # of paths. If it's 0, then stay at 0, otherwise add a period back 122 | chars_to_skip = len('.'.join(prefix_path)) 123 | if chars_to_skip > 0: 124 | chars_to_skip += 1 125 | return full_name[chars_to_skip:] 126 | 127 | global LOOKUPS 128 | if filename not in LOOKUPS.keys(): 129 | return None 130 | else: 131 | data = LOOKUPS[filename] 132 | completions = {(v['fullName'] + '\t' + v['signature'], skip_chars(v['fullName'])) 133 | for v in data 134 | if v['fullName'].startswith(prefix) or v['name'].startswith(prefix)} 135 | return [[v[0], v[1]] for v in completions] 136 | 137 | def explore_package(filename, package_name): 138 | global LOOKUPS 139 | if filename not in LOOKUPS.keys() or len(package_name) == 0: 140 | return None 141 | elif package_name[0].upper() != package_name[0]: 142 | sublime.status_message('This is not a package!') 143 | return None 144 | else: 145 | def open_link(items, i): 146 | if i == -1: 147 | return None 148 | else: 149 | open_in_browser(items[i][3]) 150 | data = [[v['fullName'], v['signature'], v['comment'], v['href']] 151 | for v in LOOKUPS[filename] 152 | if v['fullName'].startswith(package_name)] 153 | # all items must be the same number of rows 154 | n = 75 155 | panel_items = [v[:2] + [v[2][:n]] + [v[2][n:2*n]] + [v[2][2*n:]] for v in data] 156 | sublime.active_window().show_quick_panel(panel_items, lambda i: open_link(data, i)) 157 | 158 | def open_in_browser(url): 159 | webbrowser.open_new_tab(url) 160 | 161 | def load_from_oracle(filename): 162 | """ 163 | Loads all data about the current file from elm oracle and adds it 164 | to the LOOKUPS global dictionary. 165 | """ 166 | global LOOKUPS 167 | project = ElmProject(filename) 168 | if project.working_dir is None: 169 | return 170 | os.chdir(project.working_dir) 171 | 172 | # Hide the console window on Windows 173 | shell = False 174 | path_separator = ':' 175 | if os.name == "nt": 176 | shell = True 177 | path_separator = ';' 178 | 179 | settings = sublime.load_settings('Elm Language Support.sublime-settings') 180 | path = settings.get('elm_paths', '') 181 | if path: 182 | old_path = os.environ['PATH'] 183 | os.environ["PATH"] = os.path.expandvars(path + path_separator + '$PATH') 184 | 185 | p = subprocess.Popen(['elm-oracle', filename, ''], stdout=subprocess.PIPE, 186 | stderr=subprocess.PIPE, shell=shell) 187 | 188 | if path: 189 | os.environ['PATH'] = old_path 190 | 191 | output, errors = p.communicate() 192 | output = output.strip() 193 | if settings.get('debug', False): 194 | string_settings = sublime.load_settings('Elm User Strings.sublime-settings') 195 | print(string_settings.get('logging.prefix', '') + '(elm-oracle) ' + str(output), '\nerrors: ' + errors.strip().decode('UTF-8')) 196 | if errors.strip(): 197 | print('Your PATH is: ', os.environ['PATH']) 198 | try: 199 | data = json.loads(output.decode('utf-8')) 200 | except ValueError: 201 | return None 202 | LOOKUPS[filename] = data 203 | 204 | def view_load(view): 205 | """ 206 | Selectively calls load_from_oracle based on the current scope. 207 | """ 208 | 209 | if view.file_name() is None: 210 | return; 211 | 212 | sel = view.sel()[0] 213 | region = join_qualified(view.word(sel), view) 214 | scope = view.scope_name(region.b) 215 | if scope.find('source.elm') != -1: 216 | load_from_oracle(view.file_name()) 217 | 218 | 219 | class ElmOracleListener(sublime_plugin.EventListener): 220 | """ 221 | An event listener to load and search through data from elm oracle. 222 | """ 223 | 224 | def on_selection_modified_async(self, view): 225 | sel = view.sel()[0] 226 | region = join_qualified(view.word(sel), view) 227 | scope = view.scope_name(region.b) 228 | if scope.find('source.elm') != -1: 229 | view.run_command('elm_show_type') 230 | 231 | def on_activated_async(self, view): 232 | view_load(view) 233 | 234 | def on_post_save_async(self, view): 235 | view_load(view) 236 | 237 | def on_query_completions(self, view, prefix, locations): 238 | word = get_word_under_cursor(view) 239 | return get_matching_names(view.file_name(), word) 240 | 241 | 242 | class ElmShowType(sublime_plugin.TextCommand): 243 | """ 244 | A text command to lookup the type signature of the function under the 245 | cursor, and display it in the status bar if found. 246 | """ 247 | type_panel = None 248 | 249 | def run(self, edit, panel=False): 250 | if self.type_panel is None: 251 | self.type_panel = self.view.window().create_output_panel('elm_type') 252 | self.type_panel.set_syntax_file('Packages/Elm Language Support/Syntaxes/Elm Documentation.sublime-syntax') 253 | get_type(self.view, self.type_panel) 254 | if panel: 255 | self.view.window().run_command('elm_show_type_panel') 256 | 257 | 258 | class ElmShowTypePanel(sublime_plugin.WindowCommand): 259 | """ 260 | Turns on the type output panel 261 | """ 262 | def run(self): 263 | self.window.run_command("show_panel", {"panel": "output.elm_type"}) 264 | 265 | 266 | class ElmOracleExplore(sublime_plugin.TextCommand): 267 | def run(self, edit): 268 | word = get_word_under_cursor(self.view) 269 | parts = [part for part in word.split('.') if part[0].upper() == part[0]] 270 | package_name = '.'.join(parts) 271 | explore_package(self.view.file_name(), package_name) 272 | 273 | 274 | class EraseView(sublime_plugin.TextCommand): 275 | """ 276 | Erases a view 277 | """ 278 | def run(self, edit): 279 | self.view.erase(edit, sublime.Region(0, self.view.size())) 280 | -------------------------------------------------------------------------------- /images/completions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/completions.png -------------------------------------------------------------------------------- /images/elm_format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/elm_format.png -------------------------------------------------------------------------------- /images/elm_make.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/elm_make.jpg -------------------------------------------------------------------------------- /images/elm_project.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/elm_project.jpg -------------------------------------------------------------------------------- /images/elm_repl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/elm_repl.jpg -------------------------------------------------------------------------------- /images/elm_types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/elm_types.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/logo.png -------------------------------------------------------------------------------- /images/type_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elm-community/SublimeElmLanguageSupport/e266d279c8074aa342f106554cfa87ebe839a782/images/type_panel.png -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "install": "README.md", 3 | "0.15.0": "messages/0.15.0.md", 4 | "0.16.1": "messages/0.16.1.md", 5 | "0.16.2": "messages/0.16.2.md", 6 | "0.16.3": "messages/0.16.3.md", 7 | "0.17.0": "messages/0.17.0.md", 8 | "0.17.1": "messages/0.17.1.txt", 9 | "0.18.0": "messages/0.18.0.txt", 10 | "0.19.0": "messages/0.19.0.txt", 11 | "0.20.0": "messages/0.20.0.txt", 12 | "0.21.0": "messages/0.21.0.txt", 13 | "0.21.1": "messages/0.21.1.txt", 14 | "0.22.0": "messages/0.22.0.txt", 15 | "0.22.1": "messages/0.22.1.txt", 16 | "0.22.2": "messages/0.22.2.txt", 17 | "0.22.3": "messages/0.22.3.txt", 18 | "0.22.4": "messages/0.22.4.txt", 19 | "0.22.5": "messages/0.22.5.txt" 20 | } 21 | -------------------------------------------------------------------------------- /messages/0.15.0.md: -------------------------------------------------------------------------------- 1 | Thank you for continuing to use Elm Language Support. We've been busy lately. Here are a few features since we last checked in: 2 | 3 | ## What's New 4 | 5 | - This message ;) 6 | - Improved ST3 compatibility 7 | - Two build commands 8 | - Compile messages 9 | - Integration with four (4!) external plugins 10 | - One new contributor — @dnalot aka "Texas" 11 | - A brand new [README][] with further details 12 | 13 | [README]: https://github.com/deadfoxygrandpa/Elm.tmLanguage/blob/master/README.md 14 | -------------------------------------------------------------------------------- /messages/0.16.1.md: -------------------------------------------------------------------------------- 1 | ## What's new 2 | 3 | Added support for elm-format, the new tool for automatically formatting your Elm source code (you need to install this separately. Check here for details: https://github.com/avh4/elm-format) 4 | - elm-format needs to be installed and in your PATH in order to work 5 | - There is a new command on the command palette named `Elm Language Support: Run elm-format`. This command will run elm-format on the currently open file. 6 | - There is also a new User setting, which you can set by going to Preferences -> Package Settings -> Elm Language Support -> User and adding `"elm_format_on_save": true`. This will automatically run elm-format on your Elm source files before they are saved. 7 | - If there are some Elm source files you want to exclude from auto-formatting, you can set a regex-based filename filter with the "elm_format_filename_filter" User setting. Enter a regex and any file names, including their paths, the regex matches against will be excluded from the "elm_format_on_save" setting previously mentioned. 8 | -------------------------------------------------------------------------------- /messages/0.16.2.md: -------------------------------------------------------------------------------- 1 | ## What's new 2 | 3 | This is just a small update to fix an issue where the Elm Make command was no longer compatible with the elm-make command line utility on Windows. This update will not change anything on Linux or Mac. 4 | -------------------------------------------------------------------------------- /messages/0.16.3.md: -------------------------------------------------------------------------------- 1 | ## What's new 2 | 3 | Added support for elm-oracle to add autocompletions, type information, and in-editor documentation for external packages (you need to install this separately, npm install -g elm-oracle) 4 | - Moving the cursor over any function imported from an external package defined in your elm-package.json file will show the type signature in the status bar 5 | - Bring up the type panel with alt+up or through the right click context menu, or by running the `Elm Language Support: Show type` command from the command palette 6 | - Shrinking the type panel to a height of 1 line will show just an enhanced type signature, better than the status bar, while expanding its height will show you documentation 7 | - Close the type panel with Escape or alt+down 8 | - If the elm-oracle features aren't working, elm-oracle needs to either be on your PATH, or you can add additional directories to the Elm Language Support > "elm_paths" setting 9 | 10 | Other than that: 11 | - elm_format_on_save now defaults to true. If you have elm-format installed, you probably want to be using it more often than not. You can still disable it by changing elm_format_on_save to false 12 | - Fixed a couple minor bugs, the most notable being Elm Make was broken on Windows with the most recent version of Elm 13 | -------------------------------------------------------------------------------- /messages/0.17.0.md: -------------------------------------------------------------------------------- 1 | ## What's new 2 | 3 | - Added support for new Elm 0.17 module declaration syntax. 4 | - Package adopted by elm-community. 5 | -------------------------------------------------------------------------------- /messages/0.17.1.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.17.1 (January 19, 2017) 2 | 3 | - New: New build output format, with support for new inline build error 4 | indicators (phantoms) introduced in Sublime Text 3 build 3118 5 | (see: https://forum.sublimetext.com/t/dev-build-3118/21270). 6 | - Fixed: F4/Shift-F4 navigation for build errors. 7 | - Fixed: Double-click build error heading to jump to location in editor. 8 | - New maintainer: Kevin Yank (@sentience) 9 | -------------------------------------------------------------------------------- /messages/0.18.0.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.18.0 (May 13, 2017) 2 | 3 | - New: Snippets that provide shortcuts for typing common Elm syntax: case … of, 4 | case … of (Maybe), case … of (Result), function (1-4 arguments), import, 5 | import … as, let … in, module, type, and type alias. 6 | 7 | See http://docs.sublimetext.info/en/latest/extensibility/snippets.html for 8 | more info on using snippets in Sublime Text. 9 | 10 | - Improvement: Option to specify the name of the elm-format binary, for systems 11 | where the version number is included in the filename (e.g. elm-format-0.18). 12 | -------------------------------------------------------------------------------- /messages/0.19.0.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.19.0 (May 28, 2017) 2 | 3 | - Improvement: Side-by-side editing of package user settings (requires Sublime 4 | Text 3 Build 3124). (Thanks, @stoivo!) 5 | 6 | - Fix: Blank menu item when SublimeREPL is not installed. (Thanks, @Bernardoow!) 7 | -------------------------------------------------------------------------------- /messages/0.20.0.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.20.0 (June 10, 2017) 2 | 3 | - New: elm-format errors display in a pop-up panel at the bottom of the Sublime 4 | Text window, which disappears again once you correct the issue and re-run 5 | elm-format. (Thanks, @stoivo!) 6 | 7 | - Improvement: README.md lists snippets supported by this package. (Thanks, 8 | @Bernardoow!) 9 | -------------------------------------------------------------------------------- /messages/0.21.0.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.21.0 (Nov 5, 2017) 2 | 3 | - Improvement: Elm language syntax files are now implemented using 4 | Sublime Text's new .sublime-syntax format, and supports Goto Symbol properly 5 | (listing each function only once, instead of including the type annotations). 6 | (Thanks, @stoivo!) 7 | 8 | - New: ‘debug’ snippet that makes using `Debug.log` to output values to the 9 | console very convenient. (Thanks, @Bernardoow!) 10 | -------------------------------------------------------------------------------- /messages/0.21.1.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.21.1 (Nov 8, 2017) 2 | 3 | - Fix: Syntax definition now allows for numbers in module names. 4 | (Thanks, @ianmackenzie!) 5 | -------------------------------------------------------------------------------- /messages/0.22.0.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.22.0 (Jan 22, 2018) 2 | 3 | - New: Build option ‘Run - debug’ to run the project with the Elm debugger enabled. (Thanks, @stoivo!) 4 | 5 | - New: `build_error_color_scheme` setting to control build output color scheme. (Thanks, @stoivo!) 6 | 7 | - Improvement: Manual installation instructions in README. (Thanks, @stoivo, @guillett!) 8 | 9 | - Improvement: Allow Sublime Text to install Elm Language Support as a single .sublime-package file. (Thanks, @stoivo!) 10 | 11 | - Fix: Elm syntax highlighting in several panels. (Thanks, @stoivo!) 12 | 13 | - Fix: Obsolete reference to docs.json file. (Thanks, @stoivo!) 14 | -------------------------------------------------------------------------------- /messages/0.22.1.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.22.1 (Mar 20, 2018) 2 | 3 | - Fix: On some system configurations, Elm build fails with no output. (Thanks, @rtxm!) 4 | -------------------------------------------------------------------------------- /messages/0.22.2.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.22.2 (Mar 24, 2018) 2 | 3 | - Fix: Restore build system compatibility with Sublime Text 3 releases prior to r3153. 4 | -------------------------------------------------------------------------------- /messages/0.22.3.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.22.3 (Mar 30, 2018) 2 | 3 | - Fix: Properly display build errors on Sublime Text 3 releases prior to r3153. 4 | -------------------------------------------------------------------------------- /messages/0.22.4.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.22.4 (August 22, 2018) 2 | 3 | Nothing, except this VERY IMPORTANT message: 4 | 5 | Elm 0.19 was recently released: 6 | https://elm-lang.org/blog/small-assets-without-the-headache 7 | 8 | It makes major, breaking changes to the compiler's interface with packages 9 | like this one. It is likely the next release of Elm Language Support will 10 | break compatibility with Elm 0.18. 11 | 12 | If you plan to remain on Elm 0.18 for now, you should configure Package 13 | Control to ignore updates to this package until you are ready to upgrade. 14 | In Sublime Text, choose Preferences > Package Settings > Package Control > 15 | Settings – User, then add this setting to your 16 | Package Control.sublime-settings file: 17 | 18 | { 19 | "auto_upgrade_ignore": [ 20 | "Elm Language Support" 21 | ], 22 | } 23 | 24 | 25 | Upgrading to Elm 0.19 26 | 27 | A pre-release version of this package with experimental support for Elm 0.19 28 | is available. If you're using Elm 0.19 already, we'd value your feedback! 29 | 30 | WARNING: This new version does not support Elm 0.18! 31 | 32 | To upgrade, configure Package Control to install pre-release versions of this 33 | package. In Sublime Text, choose Preferences > Package Settings > Package 34 | Control > Settings – User, then add this setting to your 35 | Package Control.sublime-settings file: 36 | 37 | { 38 | "install_prereleases": 39 | [ 40 | "Elm Language support" 41 | ], 42 | } 43 | 44 | Then use the Package Control: Upgrade Package command in the Command 45 | Palette to upgrade. Make sure to read the release notes that are displayed 46 | following the upgrade! 47 | -------------------------------------------------------------------------------- /messages/0.22.5.txt: -------------------------------------------------------------------------------- 1 | New in Elm Language Support 0.22.5 (August 25, 2018) 2 | 3 | Nothing, except fixing a typo in this VERY IMPORTANT message: 4 | 5 | Elm 0.19 was recently released: 6 | https://elm-lang.org/blog/small-assets-without-the-headache 7 | 8 | It makes major, breaking changes to the compiler's interface with packages 9 | like this one. It is likely the next release of Elm Language Support will 10 | break compatibility with Elm 0.18. 11 | 12 | If you plan to remain on Elm 0.18 for now, you should configure Package 13 | Control to ignore updates to this package until you are ready to upgrade. 14 | In Sublime Text, choose Preferences > Package Settings > Package Control > 15 | Settings – User, then add this setting to your 16 | Package Control.sublime-settings file: 17 | 18 | { 19 | "auto_upgrade_ignore": [ 20 | "Elm Language Support" 21 | ], 22 | } 23 | 24 | 25 | Upgrading to Elm 0.19 26 | 27 | A pre-release version of this package with experimental support for Elm 0.19 28 | is available. If you're using Elm 0.19 already, we'd value your feedback! 29 | 30 | WARNING: This new version does not support Elm 0.18! 31 | 32 | To upgrade, configure Package Control to install pre-release versions of this 33 | package. In Sublime Text, choose Preferences > Package Settings > Package 34 | Control > Settings – User, then add this setting to your 35 | Package Control.sublime-settings file: 36 | 37 | { 38 | "install_prereleases": 39 | [ 40 | "Elm Language Support" 41 | ], 42 | } 43 | 44 | Then use the Package Control: Upgrade Package command in the Command 45 | Palette to upgrade. Make sure to read the release notes that are displayed 46 | following the upgrade! 47 | --------------------------------------------------------------------------------