Repository navigation
Add window/{did,will}{Create,Rename,Delete}Files - #1074
Conversation
|
Have not forgotten you, however I need to push this to the beginning of next week. We have endgame. |
|
Dirk Bäumer (@dbaeumer) understood, np! |
| */ | ||
| renameFiles?: { | ||
| /** | ||
| * The client has support for didRenameFiles notifications. |
There was a problem hiding this comment.
Maybe something like: "The client supports sending didRenameFiles notifications." so it's obvious which direction the communication flows?
There was a problem hiding this comment.
I would simply call the property files since the sub properties are already very descriptive and are in line with the other capability flags.
There was a problem hiding this comment.
To be consistent we should also consider adding a dynamicRegistration property. But one for all three is enough. It is the same as for text document synchronization.
There was a problem hiding this comment.
Assuming that we will add support for create and delete as well (Danny Tuppeny (@DanTup) would you be willing to do so) to make this a complete story we can either do
files: {
willCreate: boolean;
willCreateWaitUntil: boolean;
didCreate: boolean;
willRename: boolean;
willRename: boolean;
willRenameWaitUntil: boolean;
willDelete: boolean;
willDeleteWaitUntil: boolean;
didDelete: boolean;
}or we could do
files: {
create: {
...
},
rename: {
....
},
delete: {
}
}I am actually for the first option.
|
Dirk Bäumer (@dbaeumer) I don't suppose you've had chance to look at this yet? |
| */ | ||
| renameFiles?: { | ||
| /** | ||
| * The client has support for didRenameFiles notifications. |
There was a problem hiding this comment.
I would simply call the property files since the sub properties are already very descriptive and are in line with the other capability flags.
| */ | ||
| renameFiles?: { | ||
| /** | ||
| * The client has support for didRenameFiles notifications. |
There was a problem hiding this comment.
To be consistent we should also consider adding a dynamicRegistration property. But one for all three is enough. It is the same as for text document synchronization.
| * | ||
| * @since 3.16.0 | ||
| */ | ||
| renameFiles?: { |
There was a problem hiding this comment.
Same name change to files
There was a problem hiding this comment.
and same structure of the literal.
| */ | ||
| renameFiles?: { | ||
| /** | ||
| * The client has support for didRenameFiles notifications. |
There was a problem hiding this comment.
Assuming that we will add support for create and delete as well (Danny Tuppeny (@DanTup) would you be willing to do so) to make this a complete story we can either do
files: {
willCreate: boolean;
willCreateWaitUntil: boolean;
didCreate: boolean;
willRename: boolean;
willRename: boolean;
willRenameWaitUntil: boolean;
willDelete: boolean;
willDeleteWaitUntil: boolean;
didDelete: boolean;
}or we could do
files: {
create: {
...
},
rename: {
....
},
delete: {
}
}I am actually for the first option.
|
Danny Tuppeny (@DanTup) actually was on my list for this week. Added my comments. |
d10dcbe to
0489b37
Compare
|
Thanks! I've done the renames and added create/delete, though I have a few questions:
Is there actually any difference between these? Since it's all async, it seems like
The text doc registrations are scoped to text documents (eg. by language ID) but it wasn't clear how this would work here. For example if I say I want renames for just a Dart file, what happens when a I rename a folder? Should it always be sent, or only if it has child Dart files? |
9313fb2 to
6b3478d
Compare
|
That is a good point. It is very unlikely that someone is interested in What we could do have one property |
|
Regarding
I think that should be consistent with file events. There a rename of a folder doesn't generate renames for the child files. |
Right - but what advantage is there having I'm thinking that we only need
But would it be sent to the server if the server only asked for events for Dart files? (I think it has to - so I'm wondering if we need to specify that folder events will always be sent, regardless of the file/pattern filters on the registration? or there needs to be some way to register for them including folders?) |
|
Regarding dynamic registration: I think there is a misunderstanding. Dynamic registration means that a server later on can register for these events and not only through the initialize result. It doesn't mean that it needs a document filter for registration. For these event I would argue that we either
These events WILL ONLY be fired if a new file is created, rename, deleted using a user action in the UI. They are not a replacement for normal file events. Regarding which events we need: I agree that a If we make the registration file pattern sensitive (please note that the VS Code API is not that way so we need to implement this ourselves) then I would do the following:
If we make it global I would argue that we should not make all I am actually leaning towards the registration on a file pattern and then make the |
Sorry - I misunderstood your comment about copying text document synchronisation.
I think the first could be a little confusing - if I say I want just "*.dart" and the user renames a folder with a dart file nested inside it, it's not clear whether I should get the notification or not? Also - would the pattern be applied to the old URI or new URI in the case of renames?
Should this say case-sensitive? (this might be a can of worms 😬)
So if I understand correctly, we will drop the current So we're left with:
(and the same for create/delete)? |
|
I think this is not that easy because of
If we make In the VS Code API this is different since VS Code talks to one extension host and then calls in memory 5 listeners. If we go for a registration with a pattern we could clearly spec that:
Unclear is whether we need to allow to specify a pattern denoting a directory. |
Fair point. Though I think most language servers would use
I'm not sure if this means "do we need directory support" or "does it need to be a pattern"? I think directories could probably be just a flag (I suspect most servers will just want them all), but in the interest of allowing it to be controlled (for the same perf reasons mentioned above), maybe it should be two patterns (a file pattern, and a directory pattern)? For Dart, I think what I'm interested in is files: **/*.dart - any Dart file rename How about something like this? files?: {
// Req/Resp returning TextEdit[] | null
willCreate?: FileOperationRegistrationOptions;
// Notification
didCreate?: FileOperationRegistrationOptions;
// Req/Resp returning TextEdit[] | null
willRename?: FileOperationRegistrationOptions;
// Notification
didRename?: FileOperationRegistrationOptions;
// Req/Resp returning TextEdit[] | null
willDelete?: FileOperationRegistrationOptions;
// Notification
didDelete?: FileOperationRegistrationOptions;
}
interface FileOperationRegistrationOptions {
documentSelector?: DocumentSelector;
directorySelector?: DirectorySelector;
}
export type DirectorySelector = DirectoryFilter[];
export interface DirectoryFilter {
pattern?: string;
} |
|
Dirk Bäumer (@dbaeumer) any thoughts on the comment above? |
|
Danny Tuppeny (@DanTup) was on vacation. Will have a look today. |
|
Dirk Bäumer (@dbaeumer) np! Wasn't sure if the notification may have been overlooked. Thanks! |
|
Danny Tuppeny (@DanTup) I do like the API. However IMO we should not talk about document selectors / filters. At least in VS Code to correctly determine a document selector you need to Then we could say a pattern with a slash at the end matches a directory only. |
|
Dirk Bäumer (@dbaeumer) got it - I'll use
Just to make sure I understand correctly, to support "all .dart files and any folder" I would therefore send two globs, like:
Is that right? If so, I'll update the Pr to match my previous comment above with this change for a proper review. Thanks! |
|
Danny Tuppeny (@DanTup) you can use two registrations or some OR pattern. Something like |
|
Ah cool, even better. I'll get this updated today. Thanks! |
6b3478d to
7b297be
Compare
|
Dirk Bäumer (@dbaeumer) I think this is good for a proper look now. Thanks! |
52de799 to
f5f2a84
Compare
|
Dirk Bäumer (@dbaeumer) are there any notes on how you usually work on changes that span protocol/client? It looks like I need to put the type changes into Edit: Oops, had been looking in the wrong readme. Found this now:
😄 |
|
Dirk Bäumer (@dbaeumer) I've made a start at trying to implement one of the 6 requests ( DanTup/vscode-languageserver-node@498507a Hopefully I'm going in the right direction, but I have some questions:
|
|
Dirk Bäumer (@dbaeumer) I know you're busy (and I'm not helping that 😬), but interested in your thoughts on the above - would love to get more done on this. Thanks! :-) |
|
Really busy week :-). Regarding your questions: 1.) the only thing that is enabled for the Node repository is code action on save. Could it be that you have an extension installed (e.g. prettier) that does this and is not happy with how the Node repository is formatted. |
|
Dirk Bäumer (@dbaeumer) np, I understand - thank you! I'll work on 2-4. I also figured 1 out (it happened with every extension disabled). It's the TS "Organize Imports" action - raised here. |
|
Dirk Bäumer (@dbaeumer) as far as I can tell, that pattern matcher doesn't support slashes or stars inside braces: https://github.com/microsoft/vscode-eslint/blob/master/client/src/utils.ts#L128 Is this something we need to extend it to support, or should I do this another way? (I'm not sure whether this (edit: also, I'm now wondering why have a custom pattern syntax instead of just using the JS regex syntax directly?) (edit2: passing |
|
I try to stay away from Regexp in LSP (we have them for snippets but because they are in Textmate). If we start to use them we need to spec which features we support in RegExp in LSP. Glob patterns are well specified. Actually the eslint matcher only needs to match directories no files. So it might not be a good candidate to use. We have one in VSCode here: https://github.com/microsoft/vscode/blob/master/src/vs/base/common/glob.ts#L446 May be we should just use https://www.npmjs.com/package/glob. |
Ah, that makes sense. I had started to modify it to support what I needed (including full nesting for the braces), though I'll take a look through the VS Code code to see if that's more easily reusable and does everything required (and if not, I'll try glob). Thanks! |
|
I was unable to make the VS Code matching or minimatch (which glob uses) behave as I believe we wanted (trailing slashes deciding whether to include only files or only folders), however I (think I) was able to get your es-lint code working with some changes: DanTup/vscode-languageserver-node@d494cd0 I'll proceed using that for now, but if you think we should do it another way let me know.
Let's assume a server says it wants Looking at the WillSaveWaitUntil, the middleware is called only if the original event matches the selectors, and any changes it made go straight to the server (so if the middleware changed the document details, it would still go to the server). To be consistent with this, I think we would filter the event before sending it to the middleware, then always send it on to the server (though I don't know if it's strange to filter the files in the event for the middleware?). |
|
Dirk Bäumer (@dbaeumer) I've opened a PR at microsoft/vscode-languageserver-node#687 as a better place to discus the code. It's very incomplete, but I have questions about how best to test so looking for some pointers. Thanks! |
* Progress towards willCreateFiles * Fix default glob * Copy PatternParser from eslint Copied as suggested here: microsoft/language-server-protocol#1074 (comment) * Adapt PatternParser to support folders when ending /, nested patterns and blank segments * Begin tests... * WIP * Minor fixes + intial On Will Create Files test * Add a TODO about middleware * Review tweaks * Remove custom error * Change workspace->window and begin extracting feature from Connection * Fix FileOperationsFeature signature * Code cleanup to allign with coding rules. * Remove "window" from filename * Implement WillRename + WillDelete * Add Did Create/Rename/Delete notifications * Add abstract class for file operations & move file operations into workspace namespace * Tweak exception text * Fix client capabilities window -> workspace * More client capabilities from window -> workspace * Fix up URIs for directories to have trailing slashes * Remove access to waitUntil from middleware + call at top level * Fix test * Simplify handling of directories * Update test to ensure waitUntil is called synchronously * Some code cleanup * Make sure waitUntil is not exposed to next handler. * Separate file/folder patterns and switch custom pattern parsing for minimatch * Fix typos * Introduce FileOperationPatternKind * Add minimatch to third party notice * Switch back to ensure folders have trailing slash for improved matching Co-authored-by: Dirk Baeumer <[email protected]>
Dirk Bäumer (@dbaeumer) this is a first go at #984 using
WaitUntilrequests. It currently only includes rename, but we can duplicate for create/delete once these are good if required.Some things I wasn't sure about:
boolean | {/*...*/}?workspacethe right place for these? Save etc. are intextDocument/but these could be folder renames so there's no specific document.(I haven't tried to generate my code from these changes yet, but I'd like to do so before this is merged - but I figured there may be some iteration first)