Skip to content
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

Add config file for editor integration #358

Closed
dochang opened this issue Feb 16, 2019 · 6 comments
Closed

Add config file for editor integration #358

dochang opened this issue Feb 16, 2019 · 6 comments

Comments

@dochang
Copy link

dochang commented Feb 16, 2019

I use shfmt in Emacs for several projects with different indentations. It's hard to let Emacs append options to shfmt based on projects.

I've read #234, I know you recommend a wrapper script. But I think a project-wide config file would be better for editor integration. Could you please add config file support?

@mvdan
Copy link
Owner

mvdan commented Feb 17, 2019

It's hard to let Emacs append options to shfmt based on projects.

Wouldn't you have the same issue with lots of other tools and plugins?

I know you recommend a wrapper script.

Can you clarify why a script is not enough?

But I think a project-wide config file would be better for editor integration.

Please clarify what you mean by project-wide. It's still unclear to me why an editor would have an easier time integrating with a config file than a script file or a set of string arguments.

@dochang
Copy link
Author

dochang commented Feb 19, 2019

For example, the editor runs shfmt <file> every time I save a shell file. shfmt will indent the file with tabs (-i 0) by default.

Now I'm working on two projects. One indents files with -i 0, the other one indents files with -i 2. How to configure the editor? We may write wrappers for these projects. But some editors cannot run different commands for different projects, that means we have to use a universal wrapper, and store the indent settings in a project-wide config file, e.g. .shfmtrc.toml.

When the editor formats a file, the wrapper will look for .shfmtrc.toml in the same directory or parent directories of that file. Once .shfmtrc.toml is found, the wrapper will read its content, then append options to shfmt.

So, why not let shfmt read the config file?

For instance, there is a project called foobar:

$ find
.
./bin
./bin/foobar
./.shfmtrc.toml
$ cat .shfmtrc.toml
indent = 2

When the editor runs shfmt bin/foobar, shfmt will find and read .shfmtrc.toml, then format bin/foobar like shfmt -i 2 bin/foobar.


A lot of formatters support project-wide config files:

@mvdan
Copy link
Owner

mvdan commented Feb 22, 2019

If your IDE cannot apply different settings for different projects, that seems like the root of the problem to me. I realise that's just placing the blame elsewhere, but please realise that shfmt is meant to be a simple tool with a very simple purpose. Should every tool that you depend on have its own custom and separate config file per-project?

I think that's backwards; each project shouldn't need a dozen config files to set up each of the tools. That makes the tools more complex, and clutters the git repositories with tiny config files.

In particular, this tool only has six flags that could fit into a config file. Supporting config files adds a lot more complexity in the long run than you'd expect, so I don't think it's worth it. To name a few:

  • What format do we pick? For example, if we pick TOML, we are suddenly pulling in a third-party TOML parser. We currently have zero third-party dependencies.
  • What paths do we try? Should we support $HOME/.config/shfmt/config.toml? What about Windows and Mac systems? What if multiple config files exist?
  • What if the config file contains settings that we don't understand - should that be ignored, or be an error?
  • What if command-line flags are given, and a config file exists? Do the settings get layered?
  • Do we also want a flag to specify a config file path?
  • Reading config files starting from $PWD would mean that the tool changes behavior depending on where it's run from. That's never been the case, so one could argue it's a breaking change.

All in all, if passing different flags per project from the IDE is impossible, I still don't see why scripts are not an option. You could even make them pretty like a config file:

$ cat tools/shfmt
#!/bin/sh

flags=""
flags+="-i 2" # indent with two spaces
flags+="-bn" # etc etc

shfmt $flags "$@"

Then you can configure your IDE to run ./tools/shfmt if it exists, or otherwise shfmt directly. You could also accomplish this by setting PATH="$PWD/tools:$PATH" whenever a project is opened.

Something also worth mentioning is that there are "meta-formatters" out there which support formatting many languages, and unify all of their settings into one per-project config file. I think that would be the cleanest approach, if one of those tools was well written.

@mvdan mvdan removed the needs info label Feb 22, 2019
@dochang
Copy link
Author

dochang commented Feb 24, 2019

Many formatters have config file support because their languages don't have a unified style and have lots of legacy code.

The problem of scripts is that there's no "standard" location: every project will have its own location for scripts. Actually, letting the editor read a config file also have this problem. In my opinion, the editor should not access scripts or config files at all. What it should do is just running a simple command like <formatter> <file>.

I see you want to keep shfmt simple. Yes we should. But, at least, a formatter should allow the users to customize the indentation in config file. We often work on projects with different indentations.

An acceptable approach is a universal wrapper or a meta formatter, as you suggest. But they are dependencies too (for users). And what about the users who use shfmt only?

@mvdan
Copy link
Owner

mvdan commented Feb 24, 2019

Actually, letting the editor read a config file also have this problem. In my opinion, the editor should not access scripts or config files at all.

Correct; this is why command line flags are a dumb, but simple and reasonable approach.

But, at least, a formatter should allow the users to customize the indentation in config file.

I'm getting mixed signals. Yes, the settings are configurable (via flags). At the same time you don't want to add yet another config file. But you want shfmt to support its own config file?

An acceptable approach is a universal wrapper or a meta formatter, as you suggest. But they are dependencies too (for users). And what about the users who use shfmt only?

I personally think this is the tradeoff decision a user must make. They can use the language tools directly; each will have their own ways to be configured, and the user will have to use scripts or custom IDE configuration to set them up.

On the other hand is something higher-level and more powerful like a multi-language formatter. Sure, they're an extra dependency, but they abstract all this away. If you have many languages and want to keep the formatting settings in a single config file, it sounds like the simplest approach to me.

@dochang
Copy link
Author

dochang commented Mar 5, 2019

I see your idea. You want to make shfmt do one thing and do it well, but I want to do all things by one command. It's about philosophy of tool design. I'm not sure which one is right though I still prefer the latter.

You're the maintainer, so I respect your decision. I will write a wrapper to support config file. Now I close the issue here. Thank you for your patience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants