-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
Feature request: prettier.getFileInfo(path) API and CLI option #4253
Comments
What's the difference between |
@ikatyang Given that formally any file is supported until #2884 is closed, the result could also contain some flag indicating that a fallback JS parser is being used. In this case, an editor extension would not format on save. Additionally, the result could tell if the file is in Having said that, I'm open to alternative solutions that would help resolve prettier/prettier-atom#395 (comment) 😉 |
What about |
Also, I guess that means its return value would be |
@suchipi the problem with two separate API calls is that they will require Prettier process spawning two times before an editor can make an attempt to prettify a given file. So how about interface FileInfo {
path: string;
parser?: string;
ignored: boolean;
} or until 2.0: interface FileInfo {
path: string;
parser: string;
parserIsFallback: boolean;
ignored: boolean;
} In this case a Prettier editor extension could call |
This Maybe this is stating the obvious, but we'd also need to make sure that parsers coming from plugins are properly picked up when returning the file info results. |
That should not be a problem as long as the plugins are shown in |
Seems reasonable; that said, you might consider bundling prettier_d with the plugin to avoid spin-up costs. Is the |
Yep, that's just an absolute path of a file. It may be useful when someone calls As of |
@suchipi will you be happy if I submit a PR that adds this API? getFileInfo(filePatterns: string[]): FileInfo[]
// before 2.0
interface FileInfo {
filename: string;
parser: string;
parserIsFallback: boolean;
ignored: boolean;
}
// after 2.0
interface FileInfo {
filename: string;
parser?: string;
ignored: boolean;
}
@robwise will this API solve the concerns you raised in prettier/prettier-atom#395 (comment)? |
Yup, looks good to me 👍 |
Hmm... Now I'm wondering: at what point should |
I think that if the pattern matches multiple files, it should omit ignored entries. If it matches only one file, include it even if it's ignored (and the ignored boolean will be present). That way, |
That creates interface modality, which can be pretty dangerous. I'm now tending to think that getting rid of If we do output an object for a single file and a pre-filtered array for a glob, then what do we do a glob resolves to just one file? What about two file paths given as two arguments? The appropriate output format for these edge cases is not easy to guess unless we're 100% consistent. I remember struggling with an issue in remarkjs, which was also caused by the interface modality for one and several files. Excluding modality in the behaviour of Updated spec: getFileInfo(filePatterns: string[]): FileInfo[]
// before 2.0
interface FileInfo {
filename: string;
parser: string;
parserIsFallback: boolean;
}
// after 2.0
interface FileInfo {
filename: string;
parser?: string;
} prettier --file-info filePattern1 [...filePatternN]
prettier --file-info "**/*.*"
# FileInfo[] for files that are not excluded by prettierignore
prettier --file-info single/path.ext
# FileInfo[] of length 1 of the given file exists and is not in prettierginore
# [] otherwise
prettier --file-info some/path.ext other/path.ext
# array with 0, 1 or 2 members, depending on file existence and prettierignore
prettier --file-info non/existing/path1 non/existing/path2
# [] |
Sorry, I didn't mean that we would sometimes not return an array, I just meant that the array would sometimes be of length 1, and sometimes have more entries. Aside from removing the ignored property, it looks like that's still what you're doing in your code block...? |
Oh, I see, you're always filtering out ignored files. 🤷♀️ Feels kinda 6-in-the-one, half-dozen-in-the-other to me. |
Yep, I propose to always exclude non-existing and ignored files from Once we've agreed, I'm happy to proceed with a PR – really want to help @robwise with his Atom package simplification! |
Sounds good to me |
Yes, but just in case this wasn't clear, most plugins do not use prettier via the CLI, we use it programmatically so it needs to be a part of the API, not the CLI (or I guess you could do both). Also, for the pre-2.0 version, is the idea that prettier-atom would check for
Referring to |
Yeah that's my plan.
Yep, you could do that. Editor plugin can have a checkbox, allowing people to either not format unknown files at all or format them with a fallback parser.
Sorry I meant const fileInfos = prettier.getFileInfo([pathToFile]);
if (fileInfos.length /* check against prettierignore picked by the prettier instance (and file existence) */
&& !fileInfos[0].parserIsFallback /* optional check before 2.0 */) {
formatBeforeSave();
} I know this API may look a bit strange for a single file, but this is to open more opportunities when @robwise are you OK with this design? Shall I kick off the PR? UPD: It should probably be |
It's a bit unintuitive that a file being prettierignored means the file doesn't show up in the array, but a file not having an appropriate parser does show up. It seems to me that it would be more consistent if we represented both cases consistently, such as using flags for both as originally suggested.
This is breaking the YAGNI principle IMO—we're making the API for the thing we actually need (determining if we're able to format a given, single file) very strange in order to support something we're not even sure will ever be useful. With this proposed array API, in order to determine what I want, I will have to check for 3 things and (somewhat unintuitvely), do so only for the first item of the array. This is going to seem very strange to those reading the code ("What about the other elements in the array?" or "Why is it called file info but is actually an array?"): const fileInfo = getFileInfo(file);
if (fileInfo[0] && !fileInfo[0].parserIsFallback && fileInfo[0].parser) {
format(file)
} I suggest we solve the problem at hand; determining whether we should format a file or not. If we want to return an object instead of a simple boolean so we can add additional info later, that's fine, but let's still have a simple boolean flag like That way I can just do: if (getFileInfo(file).formattable) {
format(file)
} Oh that reminds me of something— |
@robwise I take your argument about simplicity – indeed, let's start with just I'll work on a PR this afternoon and will let know about the results. |
➡️ #4341 |
I've read this thread an the PR superficially, so excuse me if I say something wrong, but I tried to give the most attention I could. @kachkaev and @robwise, with #2884, we'd only need an additional API for Now maybe the editor integration wants to be smart: when an user opens a file, check if a parser can be inferred and cache that information to prevent ever calling Prettier. Now a I think Let me know what you think! |
Yep, I guess so. The main reason for #4341 is an assumption that a fallback If |
I don't think we need to wait for that. TBH the main reason we haven't done is nobody did the work yet. Otherwise, we'd have already reached out to understand better if that'd break anything important.
To clarify,
I'm on board 👍 |
Let's see if removing default parser can be fast-tracked.
Agree. But would not calling
👍 One more thing I'm trying to get through is #4192. It'd be great if you could give a hand there. |
@kachkaev Fair enough. 👍 I'm convinced this is a good api (Sorry I deleted the previous comment as I noticed it didn't make any sense) |
Not sure it will help. Here are the usual workflows in an editor as I see them:
—
I’m not sure how avoid getFileInfo() or getParser() + isIgnored() here. We can’t hit a file system in the first case and we don’t want to send prettier large csvs or simply unsupported formats for a dummy run in the second case. |
I'm really amazed to see this one and #4000 fixed! ❤️
|
We were discussing Prettier plugin support in Atom with @robwise and faced the default parser problem.
Until Prettier stops parsing unsupported files as suggested in #2884, its editor extensions need to be fed with a whitelist of supported scopes. Without this list, Prettier would throw an exception when a user presses
cmd+s
for an unsupported file type or silently fail on real parse errors, which is also undesired. Because #2884 cannot be resolved until Prettier 2.0 and this might take a while, is there any room for a new API call likeprettier.isFileSupported(file)
and a corresponding CLI option? This feature could be used by the editor extensions before applying format on safe, and as a consequence, save a user from maintaining a whitelist of scopes.How do you see the exterior of this feature look like? I can help with a PR if it has a potential to land to Prettier < 2.0.
The text was updated successfully, but these errors were encountered: