Skip to content

Commit 297b2b8

Browse files
committed
Improve elm-format integration
* Run elm-format from project directory for Elm version auto-detection. * Specify elm-format command-line options with `elm_format_options` setting. * Override all settings in project settings file. Fixes #53
1 parent b15105b commit 297b2b8

File tree

4 files changed

+108
-66
lines changed

4 files changed

+108
-66
lines changed

README.md

Lines changed: 70 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
![Elm Language Support logo](images/logo.png)
2+
23
# The Sublime Elm Language Package
34

45
> This prerelease version provides experimental support for the just-released
56
> [Elm 0.19][], and **breaks compatibility** with Elm 0.18 and earlier.
6-
>
7+
>
78
> Please report issues on GitHub:
89
> <https://github.com/elm-community/SublimeElmLanguageSupport/issues>
910
>
10-
> Help Welcome
11-
> ------------
11+
> ## Help Welcome
1212
>
1313
> Are you interested in contributing to the Elm Language Support package for
14-
Sublime Text? Get in touch!
14+
> Sublime Text? Get in touch!
1515
1616
## Installation
1717

1818
1. Install [Package Control][]
1919
2. Run `Package Control: Install Package` in the Command Palette (<kbd>Super+Shift+P</kbd>)
2020
3. Install [Elm][] or use [NPM][] (`npm i -g elm`)
2121

22-
### Manual
22+
### Manual
2323

2424
1. Go to Packages directory
2525
2. Clone the repository `git clone https://github.com/elm-community/SublimeElmLanguageSupport.git 'Elm Language Support'`
@@ -30,54 +30,72 @@ Sublime Text? Get in touch!
3030
- Syntax highlighting
3131
- Snippets for common Elm syntax (function, `case``of`, `let``in`, etc.)
3232

33-
| Tab Trigger | Description |
34-
|----------------|--------------------------------------------------|
35-
| cof | ``case … of`` |
36-
| cofm | ``case … of (Maybe)`` |
37-
| cofr | ``case … of (Result)`` |
38-
| debug | ``Debug.log`` |
39-
| fn | ``Function (a -> b)`` |
40-
| fn2 | ``Function (a -> b -> c)`` |
41-
| fn3 | ``Function (a -> b -> c -> d)`` |
42-
| fn4 | ``Function (a -> b -> c -> d -> e)`` |
43-
| imp | ``import`` |
44-
| impas | ``import … as`` |
45-
| let | ``let … in …`` |
46-
| mod | ``module`` |
47-
| type | ``type`` |
48-
| typea | ``type alias (Record)`` |
33+
| Tab Trigger | Description |
34+
| ----------- | ---------------------------------- |
35+
| cof | `case … of` |
36+
| cofm | `case … of (Maybe)` |
37+
| cofr | `case … of (Result)` |
38+
| debug | `Debug.log` |
39+
| fn | `Function (a -> b)` |
40+
| fn2 | `Function (a -> b -> c)` |
41+
| fn3 | `Function (a -> b -> c -> d)` |
42+
| fn4 | `Function (a -> b -> c -> d -> e)` |
43+
| imp | `import` |
44+
| impas | `import … as` |
45+
| let | `let … in …` |
46+
| mod | `module` |
47+
| type | `type` |
48+
| typea | `type alias (Record)` |
4949

5050
- Four standard build commands (<kbd>Super+[Shift]+B</kbd> or <kbd>Super+[Shift]+F7</kbd>)
51-
1. `Build` just checks errors. Kudos to this [tweet][]!
52-
2. `Run` additionally outputs your compiled program to an inferred path.
53-
3. The same as the above two, but ignoring warnings
54-
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)
51+
1. `Build` just checks errors. Kudos to this [tweet][]!
52+
2. `Run` additionally outputs your compiled program to an inferred path.
53+
3. The same as the above two, but ignoring warnings
54+
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)
5555
- Compile messages
56-
1. Navigate errors and warnings (<kbd>Super+[Shift]+F4</kbd>).
57-
2. Formatted for build output panel.
58-
3. Compile message highlighting, embedded code highlighting, and color scheme for output panel. ![compile messages screenshot](images/elm_make.jpg)
56+
1. Navigate errors and warnings (<kbd>Super+[Shift]+F4</kbd>).
57+
2. Formatted for build output panel.
58+
3. Compile message highlighting, embedded code highlighting, and color scheme for output panel. ![compile messages screenshot](images/elm_make.jpg)
5959
- Integration with popular plugins (installed separately)
60-
1. [SublimeREPL][] — Run `elm-repl` in an editor tab with syntax highlighting. ![SublimeREPL screenshot](images/elm_repl.jpg)
60+
1. [SublimeREPL][] — Run `elm-repl` in an editor tab with syntax highlighting. ![SublimeREPL screenshot](images/elm_repl.jpg)
6161
- Integration with [elm format](https://github.com/avh4/elm-format)
62-
1. Make sure `elm-format` is in your PATH
63-
2. Run the "Elm Language Support: Run elm-format" command from the Command Palette to run elm-format on the current file
64-
3. To enable automatic formatting on every save, Go to Preferences -> Package Settings -> Elm Language Support -> Settings and add this setting:
65-
`"elm_format_on_save": true`
66-
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`:
67-
`"elm_format_filename_filter": "elm-css/src/Css/.*\\.elm$"`![elm-format screenshot](images/elm_format.png)
62+
1. Make sure `elm-format` is in your PATH
63+
2. Run the "Elm Language Support: Run elm-format" command from the Command Palette to run elm-format on the current file
64+
3. To enable automatic formatting on every save, Go to Preferences -> Package Settings -> Elm Language Support -> Settings and add this setting:
65+
`"elm_format_on_save": true`
66+
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`:
67+
`"elm_format_filename_filter": "elm-css/src/Css/.*\\.elm$"`![elm-format screenshot](images/elm_format.png)
68+
- Project-specific settings
69+
70+
Need to configure a setting (such as `elm_format_binary`) per-project? Prefix the name of the setting with `elm_language_support_` and add it to your project settings file.
71+
72+
```
73+
{
74+
"folders":
75+
[
76+
{
77+
"path": "."
78+
}
79+
],
80+
"settings":
81+
{
82+
"elm_language_support_elm_format_binary": "node_modules/elm-format/unpacked_bin/elm-format"
83+
}
84+
}
85+
```
6886

6987
## Troubleshooting
7088

7189
- I have `elm-oracle` installed, but completions, type signature display, and the type panel don't work
72-
1. Make sure `elm-oracle` is on your PATH, or
73-
2. Add the absolute path of the directory containing `elm-oracle` to the `elm_paths` setting in your Elm Language Support User settings
90+
1. Make sure `elm-oracle` is on your PATH, or
91+
2. Add the absolute path of the directory containing `elm-oracle` to the `elm_paths` setting in your Elm Language Support User settings
7492
- I have `elm-format` installed, but it's not working
75-
1. Make sure `elm-format` is on your PATH, or
76-
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
77-
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"`
93+
1. Make sure `elm-format` is on your PATH, or
94+
2. 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 `:`, for example `"elm_paths": "/users/alex/elm-format/bin:/users/alex/elm-oracle/bin"`.
95+
3. If using an alternate name for the binary (`elm-format-0.19`), adjust the `elm_format_binary` setting in your Elm Language Support User settings. This can be relative to your project directory. For example, if you want to use the NPM package version of `elm-format` installed locally in your project, use `"elm_format_binary": "node_modules/elm-format/unpacked_bin/elm-format"`.
7896
- Elm format automatically runs every time I save a file, but there are some files I don't want it to run on
79-
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`:
80-
`"elm_format_filename_filter": "elm-css/src/Css/.*\\.elm$"`
97+
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`:
98+
`"elm_format_filename_filter": "elm-css/src/Css/.*\\.elm$"`
8199

82100
## Learning
83101

@@ -89,15 +107,15 @@ Don't know Elm? Great first step!
89107
- [Elm Town Podcast][]
90108

91109
[elm-discuss group]: https://groups.google.com/d/forum/elm-discuss
92-
[Elm]: http://elm-lang.org/install
93-
[Elm Town Podcast]: https://elmtown.github.io
94-
[Elm Website]: http://elm-lang.org
95-
[Highlight Build Errors]: https://packagecontrol.io/packages/Highlight%20Build%20Errors
96-
[NPM]: https://nodejs.org
97-
[Package Control]: https://packagecontrol.io/installation
110+
[elm]: http://elm-lang.org/install
111+
[elm town podcast]: https://elmtown.github.io
112+
[elm website]: http://elm-lang.org
113+
[highlight build errors]: https://packagecontrol.io/packages/Highlight%20Build%20Errors
114+
[npm]: https://nodejs.org
115+
[package control]: https://packagecontrol.io/installation
98116
[pragmatic]: https://pragmaticstudio.com/elm
99-
[SublimeREPL]: https://packagecontrol.io/packages/SublimeREPL
100-
[Sublime Text 2]: http://www.sublimetext.com/2
101-
[Sublime Text 3]: http://www.sublimetext.com/3
117+
[sublimerepl]: https://packagecontrol.io/packages/SublimeREPL
118+
[sublime text 2]: http://www.sublimetext.com/2
119+
[sublime text 3]: http://www.sublimetext.com/3
102120
[tweet]: https://twitter.com/rtfeldman/status/624026168652660740
103-
[Elm 0.19]: https://elm-lang.org/blog/small-assets-without-the-headache
121+
[elm 0.19]: https://elm-lang.org/blog/small-assets-without-the-headache

Settings/Elm Language Support.sublime-settings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"enabled": true,
44
"elm_binary": "elm",
55
"elm_format_binary": "elm-format",
6+
"elm_format_options": "",
67
"elm_format_on_save": true,
78
"elm_format_filename_filter": "",
89
"elm_paths": ""

elm_format.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,30 @@
55
import re
66
import sublime, sublime_plugin
77

8+
from .elm_plugin import *
9+
from .elm_project import ElmProject
10+
11+
USER_SETTING_PREFIX = 'elm_language_support_'
812

913
class ElmFormatCommand(sublime_plugin.TextCommand):
1014
def run(self, edit):
11-
1215
# Hide the console window on Windows
1316
shell = False
1417
path_separator = ':'
1518
if os.name == "nt":
1619
shell = True
1720
path_separator = ';'
1821

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+
binary = self.get_setting('elm_format_binary') or 'elm-format'
23+
options = self.get_setting('elm_format_options') or ''
24+
path = self.get_setting('elm_paths') or ''
2225
if path:
2326
old_path = os.environ['PATH']
2427
os.environ['PATH'] = os.path.expandvars(path + path_separator + '$PATH')
2528

26-
command = [binary, self.view.file_name(), '--yes']
27-
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell)
29+
working_dir = self.working_dir()
30+
command = binary.split() + [self.view.file_name(), '--yes'] + options.split()
31+
p = subprocess.Popen(command, cwd=working_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell)
2832

2933
if path:
3034
os.environ['PATH'] = old_path
@@ -46,22 +50,39 @@ def run(self, edit):
4650
else:
4751
self.view.window().run_command("hide_panel", {"panel": "output.elm_format"})
4852

49-
50-
if settings.get('debug', False):
53+
if self.get_setting('debug'):
5154
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()):
55+
print(string_settings.get('logging.prefix', '') + output.strip().decode(),
56+
'\ncommand: ' + str(command),
57+
'\nworking directory: ' + working_dir,
58+
'\nerrors: ' + errors.strip().decode()
59+
)
60+
if errors.strip():
5461
print('Your PATH is: ', os.environ['PATH'])
5562

63+
def working_dir(self):
64+
vars = self.view.window().extract_variables()
65+
project = ElmProject(vars['file'])
66+
log_string('project.logging.settings', repr(project))
67+
return project.working_dir or vars['project_path'] or vars['file_path']
68+
69+
def get_setting(self, key, user_key=None):
70+
package_settings = sublime.load_settings('Elm Language Support.sublime-settings')
71+
user_settings = self.view.settings()
72+
73+
return user_settings.get(user_key or (USER_SETTING_PREFIX + key), package_settings.get(key))
74+
5675

5776
class ElmFormatOnSave(sublime_plugin.EventListener):
5877
def on_post_save(self, view):
5978
sel = view.sel()[0]
6079
region = view.word(sel)
6180
scope = view.scope_name(region.b)
6281
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', '')
82+
package_settings = sublime.load_settings('Elm Language Support.sublime-settings')
83+
on_save = 'elm_format_on_save'
84+
if view.settings().get(USER_SETTING_PREFIX + on_save, package_settings.get(on_save, True)):
85+
filename_filter = 'elm_format_filename_filter'
86+
regex = view.settings().get(USER_SETTING_PREFIX + filename_filter, package_settings.get(filename_filter, ''))
6687
if not (len(regex) > 0 and re.search(regex, view.file_name()) is not None):
6788
view.run_command('elm_format')

elm_make.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from .elm_plugin import *
1212
from .elm_project import ElmProject
1313

14+
USER_SETTING_PREFIX = 'elm_language_support_'
15+
1416
# We need a custom build command so that we can take the JSON output from the
1517
# Elm compiler and render it in a format that works with Sublime Text’s build
1618
# output panel syntax highlighting and regexp-based error navigation.
@@ -274,4 +276,4 @@ def get_setting(self, key, user_key=None):
274276
package_settings = sublime.load_settings('Elm Language Support.sublime-settings')
275277
user_settings = self.window.active_view().settings()
276278

277-
return user_settings.get(user_key or ('elm_language_support_' + key), package_settings.get(key))
279+
return user_settings.get(user_key or (USER_SETTING_PREFIX + key), package_settings.get(key))

0 commit comments

Comments
 (0)