-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement EditorConfig support #1777
base: master
Are you sure you want to change the base?
Conversation
Currently disabled, see the use of Document::open_with_editorconfig in editor.rs. More fields in Document will be needed for some of the properties. Currently, in theory, only line ending, indent style, and encoding are supported.
I'm not familiar with EditorConfig, but I think that it makes more sense to deserialize into a Rust struct (maybe one of the existing |
I'm similarly unfamiliar with Helix's internals, so please correct me if any of my assumptions about them are wrong.
That sort of configuration is out-of-scope for EditorConfig, which is more about declaring properties of individual files in a project, such as their encoding, line endings, indent style, maximum line length, formatting, and so on. The idea is that a project can put an From what I could find, most of the variables that an EditorConfig file would call for changes to, in Helix, are in Of course, if generalizing to other ways of setting these variables per-file is still important, that could still be done. I could define an object-safe trait and a couple of implementors for different forms of per-file editor configuration. It would probably keep the code of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that since we're already creating a Config
type for Document
, it might make more sense to encapsulate the already existing configuration fields for Document
in Config
. While this would make it so that Config
is not EditorConfig-specific, I think it makes the code a lot cleaner.
What I would also do is make it so that, like is already done with language_loader
, we could fill in Config
from an EditorConfig
if it exists (maybe from an Arc<EditorConfig>
?). And then if using EditorConfig is undesirable, then it would just never fill in from an EditorConfig
.
I'll think about this some more. I feel like there is a much better solution than what I proposed, using the Loader
type to lazily load EditorConfig
s.
That sounds good to me. One small quirk: Currently the fields of
Alright, I'll hold off on implementing any of these ideas for now. |
I think for now just lazily loading the configs based on the Unless there's a reason it's not possible, I think it would be better to choose the config based on the language the |
Alright! I can finally prioritize this again! Apologies, I know it's been a while.
I think something got lost in communication. EditorConfig's purpose is to automate reconfiguring one's editor to match the style guidelines of a project, at least for certain common settings. It has no concept of language, and any concept of language it gains in the future would likely (speculation on my part) be in the form of a new key-value pair to specify that files matching a certain pattern are in a certain language. After all, language detection (and naming!) varies significantly from editor to editor. In short, what you're proposing is no longer EditorConfig. Sorry!
Alright, noted. I'll take a look at what's changed and try see how much of what I wrote can be adapted. I still need to finish ec4rs |
EditorConfig has globs for file extensions, and the Language config contains the extension as well. In retrospect, it would only make sense to look at the config if the buffer wasn't saved to a file yet. But I suppose it doesn't matter and goes against the config's model as it is only working on file extensions. |
From the latest run:
Is Rust EDIT: It's been two weeks. I'm going to assume the answer is "yes". I'll try and push changes this weekend and mark this as ready for review so that this feature can get merged in some form. |
Yep sry, we use 1.57 as an MSRV because it makes builds easier for distros like Void that might be a bit behind on their rust version: #1881 |
EditorConfig specifies properties for inserting a newline at the end of the file if there isn't one already, If not, let me know and I can just implement them. Otherwise, marking this for review. |
Yeah, implementing those can be separate 👍 We probably want to add commands for both of those things - they're definitely useful even if they aren't automatic/on-save |
ec4rs 1.0.0 requires a later version of Rust than Helix is made for at this time. ec4rs 1.0.1 (and later versions in the 1.0.x series) do not. The version requirement has been updated to reflect this.
Fantastic to see an update here! 🎉 Are the code style concerns the same things commented inline, or could someone add comments if they're not? If @TheDaemoness isn't available for it I might be able to work on remaining touchups. |
As far as I'm aware, the other maintainers aside from Pascal have yet to comment on this PR so it definitely would be good to speak with them. |
I agree with @pascalkuthe and I believe @archseer was thinking the same last time we discussed this |
If I'm understanding the agreement correctly, that means the overall maintainer opinion is "it is a very invasive change pulling in a significant dependency and not an essential enough feature to warrant being implemented in core; would prefer to see this implemented as a plugin". Is there a rough estimate of when users can expect the plugin architecture to be in a state where it is capable of changing document options, including the encoding? |
I believe it is already able to, but cc @mattwparas |
FWIW it'd be very surprising to me to include language server support in core but not support for standard editor settings config. Or would language servers be moving into plugins as well...? |
From my understanding, Pascal preferred to add any options covered by editorconfig into Helix's config system if it didn't already exist. |
This (emphasis mine) doesn't sound like expression of a preference to load It would be helpful if @pascalkuthe could clarify his preferences in this PR. |
What Pascal is saying is that if there are missing config options that editorconfig exposes then we can add config options for those. For example |
Ok so, I understand a multiple PR approach:
There must be a way to not delay this feature any longer for affected users, while still preserving the legit long term interests of the maintainers. Or so I hope! |
Point 1 sounds good regardless of editorconfig support. Though I think we have config options at least for what Vim / Neovim supports and what features we have. Point 2 is not what I had in mind though. We use feature flags for things like git that can be turned off to help compile to different targets like WASM: it's not meant to support features or dependencies we wouldn't otherwise support in core or to incubate / graduate features. If you want to use a feature that isn't supported in core (i.e. merged) you should run a branch from a PR or merge a PR's branch into a fork. |
I assume the planned plugin system is https://github.com/mattwparas/helix/tree/steel-event-system (#8675) which appears to embed a novel Scheme interpreter to allow plugins to be written in Steel (a Scheme dialect). As far as I know there is no EditorConfig core in any dialect of Scheme, so it seems it would be necessary (or at least more practical) to make a Steel module out of an existing core. I leave it to the maintainers to close this PR if it's decided this is the route they wish to go with. Best of luck to whoever opts to implement this plugin, and if I can be of assistance to that individual, I encourage them to reach out to me. |
Should definitely not require a plugin or anything. The most essential feature when contributing to upstream project. I'm a Linux kernel maintainer so thus I did a workaround to [[language]]
name = "c"
indent = { tab-width = 8, unit = "\t" } For any other C based project I continue to use vim because otherwise I would have to constantly edit this file :-) |
Can live with a plugin and as a open source contributor I get the free time part. Just want to remind that Rust is an exception on having only single coding convention. Most languages have multiple that are used depending on project you are working at... And editorconfig is the standard for fixing up that. For me personally it is more important feature than e.g. LSP. |
For me the core reason for ending up to try out Helix is that it does not have plugins :-) In vim (I use the regular vim) I have only few plugins mostly from tpope. I looked for something more modern and in terminal and Helix hit me because it has almost all I need but no plugins. So definitely a bummer if this ends up to be a plugin (when there is even a plugin system in the first place) but having to install a single plugin is still sustainable :-) Would be better if not having to do that tho... |
(this isn't a reply, just something I think it's worth mentioning, for anyone to read):
Each one of those approaches has its trade-offs, and it depends on the type of project. Anyone, please let me know if there are more I haven't thought |
It would be probably more effective to have one of these (not sure if XOR or OR):
Please consider all my comments not requirements. As said I fully get the "free time" aspect. So e.g. here if this was done in the first place, these refinements could make it better... |
It already exists! Full name is |
I'd love to see this implemented as a core feature. nixpkgs is a massive project that uses them for example |
Re: (btw. the linux kernel already has a I don't have enough contact with editorconfig myself to put in the effort, but I had the idea of a CLI that "transpiles" Those who want a maximally smooth experience may write a shell hook that automatically calls this CLI if a I'm not sure how complicated of a task it is, but I'm guessing the pareto principle applies. |
Regarding .gitignore, there's a better option: global git ignore ( |
Regarding the CLI idea, one issue is that arbitrary globs for which files a config applies to doesn't nicely match helix' languages.toml format, because that assumes "one config per language". e.g. from the linux kernel: [*.{json,py,rs}]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
# this must be below the general *.py to overwrite it
[tools/{perf,power,rcu,testing/kunit}/**.py,]
indent_style = tab
indent_size = 8 I think this is probably extremely rare, having different formatting configs for the same language in a single project. IMO it would be fine to extract only "top-level" file extensions from the section headers and translate that into a helix languages.toml, ignoring complicated globs. I guess it's technically possible to define a completely new language that only applies to the project-specific glob, but is otherwise identical to the real language. e.g. [[language]]
name = "tools-python"
# ... duplicate entire config from python ...
file-types = [{ glob = "tools/{perf,power,rcu,testing/kunit}/**.py" }]
indent = { tab-width = 4, unit = "\t" } but that seems hacky, brittle and generally not worth the effort. |
If a sufficiently large number of people end up doing this, wouldn't it be nice if Helix did this for them? After all, Helix is known as a batteries-included editor! |
Highly agree. Most editors with any noteworthy userbase bundle EC support into core. A few (perhaps most relevantly, Emacs, Micro, Sublime, and VSCode) require a plugin. None that I can tell require me to also set up shell hooks (or direnv, or whatever) to compile EC files into some editor-specific config format I ALSO need to remember to set up Git ignores for... and by the way, what happens if Helix ever splits into a core and GUIs, and now there's not a shell hook running on Just to keep it honest: that solution feels kludgey enough to me it'd be approximately like not having support at all. I consider myself a terminal power user but I have no interest in setting up stuff like that to fix a decision made by a text editor, it's less friction to just change my text editor at that point. Thankfully, most projects I work on have auto-formatting linters and so EC support isn't critical for most of them, but for the remaining projects... yowza. |
I like "batteries-included" too, but I also understand the maintainers here. It is reasonable to leave editorconfig support up to a (future) plugin system. As mentioned, other popular editors have made that same choice, probably for the same reasons. Editorconfig is not that simple. (I find the linux kernel setup pretty deranged.)
No, the CLI can generate a If you don't like the shell-hook idea, don't add them. Run the CLI manually whenever you clone a repo, which doesn't happen that often.
This exageration is contradictory. If not having editorconfig support is that terrible, running a single command once after cloning a repo would be worth it. I understand you want the 100% solution, but that's not an argument against the 90% solution. |
My pushback was solely against the out-of-band CLI option, not the plugin system option. |
I couldn't resist and cooked something up 🙂 Check it out if you're interested, I hope others find it useful. Issue reports welcome. 👉 ec2hx repo Installation using binstall works: cargo binstall ec2hx
|
Update from The current |
Closes #279.
This changeset currently implements partial support for EditorConfig. Here's what it includes:
indent_size
,indent_style
,tab_width
,charset
, andend_of_line
properties.Here's what it doesn't include:
charset
values.insert_final_newline
ortrim_whitespace
. Both of these should be possible to do with some changes toDocument::save_impl
, but a good implementation would allow these to be controlled from outside EditorConfig as well, and I think it would be better to do this in a separate PR.max_line_length
for doing hard wrapping. Helix does not.