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
INSP: add attach file to module quick fix #5490
Conversation
I think no. At least for now.
Let's convert it into inspection that produces file-level warning. See #5481 as example |
Just to be sure, you want me to convert the whole |
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.
Looks cool!
Personally I think that the "Add file to a module" message is not enough informative. I'd want to see a filename where the module declaration will be inserted. Maybe "Add the file to mod.rs"? Omm, sounds too confusing. "Declare the module in mod.rs"? Hmmm
Instead of hardcoding main.rs/lib.rs you could use
project.cargoProjects.findPackageForFile(virtualFIle) // CargoProjectsService.findPackageForFile
and then iterate over Package.targets
crateRoot
s. If Package/Target terminology is confusing for you, you can read our ARCHITECTURE.md
(I think our explanation is even better then Cargo's official docs =D)
If a package for a file is not found, we probably should not try to find any module for inclusion.
Also, if mod.rs is not found, we can check edition
of the package, and if it is 2018
, we can try to find a file in the upper directory with the same name as the directory (see no more mod.rs).
src/main/kotlin/org/rust/ide/notifications/DetachedFileNotificationProvider.kt
Outdated
Show resolved
Hide resolved
Updated module search and created a dialog for choosing the module. If there is a single module, the action button will say "Attach file to $modname", otherwise it says "Attach to a module". Should I convert the whole |
@Kobzol yep. It will be more consistent now |
@Kobzol Oops, you are about |
Yeah, that's what I meant, sorry. |
I converted the provider to an inspection with a quick fix, however if I try to use a GUI dialog inside the quickfix, it complaints: How should I handle module selection if there are multiple modules to select? |
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 converted the provider to an inspection with a quick fix, however if I try to use a GUI dialog inside the quickfix, it complaints:
Wow, it's a great warning!
You shouldn't show dialogs in write action because it's unpredictable how long this dialog will be shown. And all time it's shown, it blocks all other operations that require even read action.
By default, a quick fix is started in write action to avoid boilerplate in most of the cases. But if you need to show UI, you should control it yourself. Just override startInWriteAction method and start write action only when you need to apply the corresponding changes to PSI (or any other platform model)
Ah-ha! That was the missing piece, thanks. Indeed the exception message was very informative, I just forgot that it's possible to "turn off" write action in quick fixes. |
Well, yes, but
I think we should have the ability to disable the inspection in a particular file. It's because we still often can't find a parent module because of macros or something. So, the inspection is useful in general, but in some files, it can be very annoying. Including external library files. |
src/main/kotlin/org/rust/ide/inspections/RsDetachedFileInspection.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/org/rust/ide/inspections/fixes/AttachFileToModuleFix.kt
Outdated
Show resolved
Hide resolved
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.
Is there a way to modify the notification bar without creating an additional quick fix just for disabling the inspection? I tried overriding |
Hmm, I'm not sure how to do this better. But it seems that a new quick fix is the easiest way. It can be an inline class btw. |
@Kobzol JFYI it creates panel for inspection settings. See |
Hmm. Also, maybe we should just navigate a user to the inserted |
I wanted to do that, but wasn't sure how to get an |
Hmm, why do you need an editor instance? |
Good question :D I wanted to do something like |
|
src/main/kotlin/org/rust/ide/inspections/fixes/AttachFileToModuleFix.kt
Outdated
Show resolved
Hide resolved
It's perfect now! Could you please squash the commits? @Undin, would you like to take a look? |
96fc06e
to
7feecda
Compare
src/main/kotlin/org/rust/ide/inspections/fixes/AttachFileToModuleFix.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/org/rust/ide/inspections/fixes/AttachFileToModuleFix.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/org/rust/ide/inspections/fixes/AttachFileToModuleFix.kt
Outdated
Show resolved
Hide resolved
src/test/kotlin/org/rust/ide/inspections/RsDetachedFileInspectionTest.kt
Outdated
Show resolved
Hide resolved
src/test/kotlin/org/rust/ide/inspections/RsDetachedFileInspectionTest.kt
Outdated
Show resolved
Hide resolved
@vlad20012 @Kobzol I have some doubts about it. Looks like it may be quite annoying. I imagine the following user case: I created a new rust module to write some new code in it but forgot to create mod declaration for it (or did it intentionally because of existence of the corresponding quick fix). I apply quick fix to get proper code insight in the file and IDE moves me into another file. Why? What should a user get from this navigation? I wanted to write new code in new file. But after navigation, I have to move back. |
Now that I think about it, the navigation was mainly useful before there was the UI dialog, for the user to see where was the However, inserting a Regarding new file creation, maybe we should offer a similar dialog when the user creates a new Rust file, so that it will be added to some module right away? |
@Undin I know a lot of people (mostly newbies in Rust) who asked "what does this message mean" ("File is not included in module tree") because they don't understand the Rust module system. I think it's necessary to show an inserted mod declaration because otherwise, they will not understand what's happened. |
@Undin One more point - I think that this quick fix is mostly for newbies because professional users should write module declarations prior to creating files (then files can be created with another provided quick fix). So this quick fix should be rather obvious and transparent than handy for everyday usage. |
But what's about a situation when I've already known how the module system works?
You don't know because currently, this quick fix doesn't exist and no one can use it in development workflow. |
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.
LGHM
Thanks!
Could you squash commit please?
I just came up with another option: we can show a balloon as before, but with a button that navigates to an inserted module declaration. But ok, let's leave it as is for now |
57215b7
to
9eac58f
Compare
bors r+ |
5660: COMP: offer only struct fields in struct pat r=mchernyavsky a=Kobzol This PR filters out unnecessary completions offered in struct pats. It also adds `..` to completion, but I'm not sure if that's the right way to do it, so it's in a separate commit. Fixes third part of #4448 5766: INSP: attach module without a parent to a parent module in AttachFileToModuleFix r=mchernyavsky a=Kobzol #5490 added a quick fix to attach a file to a nearby module. However, for `mod.rs` files it offered only crate root files (`lib.rs`, `main.rs`) and not parent modules. So in this case: ```rust //- foo/mod.rs /* nothing to see here */ //- foo/bar/mod.rs /* caret*/ ``` The quick fix wasn't offered at `/*caret*/`. After this PR, the quick fix is offered and the example code is transformed into this: ```rust //- foo/mod.rs mod bar; //- foo/bar/mod.rs ``` 5811: INSP: add support for trait refs in RsWrongTypeArgumentsNumberInspection r=undin a=Kobzol `RsWrongTypeArgumentsNumberInspection` previously did not work for trait refs, for example `dyn Trait` or `impl Trait`. This PR adds support for these cases. TODO: - [x] run `RsRealProjectAnalysisTest` 5816: Refactoring of auto-import related code r=mchernyavsky a=Undin These changes extract auto-import related code from `AutoImportFix` into `org.rust.ide.utils.import` package since this code widely used in different IDE features. Also, this code is split into several separate files As a result, a lot of code doesn't depend on `AutoImportFix` 5819: REF: add unsafe modifier to functions extracted from unsafe functions r=mchernyavsky a=Kobzol This PR adds `unsafe` to functions extracted from `unsafe` functions. Currently the `unsafe` is added unconditionally, should I improve that? The extracted statements would have to be scanned for unsafe operations that are not inside an `unsafe` block. Since pretty much the same code is already in `RsUnsafeExpressionAnnotator`, it should be refactored somehow to share the logic. Fixes: #5814 Co-authored-by: Jakub Beránek <berykubik@gmail.com> Co-authored-by: Arseniy Pendryak <a.pendryak@yandex.ru>
5660: COMP: offer only struct fields in struct pat r=mchernyavsky a=Kobzol This PR filters out unnecessary completions offered in struct pats. It also adds `..` to completion, but I'm not sure if that's the right way to do it, so it's in a separate commit. Fixes third part of #4448 5766: INSP: attach module without a parent to a parent module in AttachFileToModuleFix r=mchernyavsky a=Kobzol #5490 added a quick fix to attach a file to a nearby module. However, for `mod.rs` files it offered only crate root files (`lib.rs`, `main.rs`) and not parent modules. So in this case: ```rust //- foo/mod.rs /* nothing to see here */ //- foo/bar/mod.rs /* caret*/ ``` The quick fix wasn't offered at `/*caret*/`. After this PR, the quick fix is offered and the example code is transformed into this: ```rust //- foo/mod.rs mod bar; //- foo/bar/mod.rs ``` Co-authored-by: Jakub Beránek <berykubik@gmail.com>
5766: INSP: attach module without a parent to a parent module in AttachFileToModuleFix r=mchernyavsky a=Kobzol #5490 added a quick fix to attach a file to a nearby module. However, for `mod.rs` files it offered only crate root files (`lib.rs`, `main.rs`) and not parent modules. So in this case: ```rust //- foo/mod.rs /* nothing to see here */ //- foo/bar/mod.rs /* caret*/ ``` The quick fix wasn't offered at `/*caret*/`. After this PR, the quick fix is offered and the example code is transformed into this: ```rust //- foo/mod.rs mod bar; //- foo/bar/mod.rs ``` Co-authored-by: Jakub Beránek <berykubik@gmail.com>
This PR adds an action to
DetachedFileNotificationProvider
that adds the file to some module so that it will be present in the module tree. The current implementation is not yet complete because I'm not sure about the UI.The directory of the file is checked for
mod.rs
,lib.rs
ormain.rs
files and if they are valid and exist, they will be used as candidates for insertion. Currently if there is only one available module, I just insert the file into it, if there are more, some UI/dialog could show up - a select box with available modules?Should it offer modules recursively, i.e. in grandparent modules? That would be pretty complicated if the parent module would already exist, but it would allow to include very deeply nested files (
a/b/c/foo.rs
, where neithera
,b
norc
are modules yet).Is it possible to test this? I tried to access the intention action from the notification provider and trigger it, but that seems pretty hacky and I don't have access to an editor in the current notification provider test suite.
Fixes: #5488