-
Notifications
You must be signed in to change notification settings - Fork 256
Conversation
src/actions/format.rs
Outdated
fn gen_config_file(config: &Config) -> Result<(File, PathBuf), String> { | ||
let (mut file, path) = random_file()?; | ||
let toml = config.used_options().to_toml()?; | ||
let toml = config.all_options().to_toml()?; |
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.
Well, that was easier than expected!
The drawback to using the external Rustfmt is that we have to pass the entire config via file, so here it's done by creating a temporary file. It might be a good idea to just use the statically linked Rustfmt for the tooltips, since most of the time there's almost null work to be done there and any minor difference in indenting might be worth avoiding the overhead and creating these temp files all the time. |
cc @sunshowers |
I think the specific formatting only matters if its persisted in a file. I agree the precise formatting of transient output is less important. |
Thanks, this is definitely the direction I was envisioning.
What sorts of configs could the LSP pass in here? To some extent, using an external formatter means that you want that to determine what to do. In particular, for the Facebook use case we want a single consistent format result controlled entirely by Could potential version skew be a problem wrt formatter configs? e.g. RLS is newer and passes in a config that an older rustfmt doesn't understand. |
Agreed, however the LSP provides
That's technically possible now, since we use the statically linked Rustfmt config/capabilities and encode it for the external Rustfmt to use. |
895488d
to
454d013
Compare
We should add some CLI API to Rustfmt to get around this, e.g., passing a top-level config as an env var |
We should only pass stable options to external Rustfmt, since we can't promise that it was built using nightly and therefore might not accept unstable options. Given that, we should only have a problem if we pass new args to an old rustfmt, but I think we should be very conservative about what we pass, so should be OK. |
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.
Code looks good. Please remember to add the new option to the VSCode extension too.
Cargo.toml
Outdated
@@ -12,6 +12,9 @@ categories = ["development-tools"] | |||
|
|||
build = "build.rs" | |||
|
|||
[patch.crates-io] | |||
rustfmt-nightly = { git = "https://github.com/Xanewok/rustfmt", branch = "file-lines-ser-json" } |
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.
Can we remove this now?
src/actions/format.rs
Outdated
} | ||
|
||
|
||
pub trait Formatter { |
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.
This trait seems like over-abstraction. Since we have the enum why not just use an inherent function on the enum and call different functions. Alternatively, keep the trait but dump the enum, since they are basically doing the same thing.
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.
It somehow felt cleaner doing this this way than writing two bare format_internal(String, Config) -> ..
and format_external(PathBuf, PathBuf, String, Config) -> ...
to be called from inherent function but you're right that there's no benefit apart from being able to implement the same function signature for different variants; I'll change that.
Looks like we're still waiting on this? Should I land this and follow up or do you want to wait? |
When trying to use rustfmt 0.99.3 instead of the branch:
@nrc I believe we need the |
Wait, no, this error happens because of latest rustc EDIT: Still blocked on rust-lang/rustfmt#2965 (comment) |
FIXME: It would be clean to support formatting options passed via Formatter:format() trait method rather than relying on it to 'just' work for now.
External ones have to create temporary files to pass configs and whatnot and we can technically issue a lot of these hover requests fast - these will be short and the exact formatting does not matter, so we'll just use the internal one instead.
454d013
to
3dc4592
Compare
Also bump Racer to use single version of rustc-ap-* libs (v370)
@nrc this should be ready to review now |
.map_err(|_| "Config file could not be created".to_string())?) | ||
} | ||
|
||
fn gen_config_file(config: &Config) -> Result<(File, PathBuf), String> { |
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.
Could you open an issue for passing a config file as an env var please? And maybe stick a FIXME in here.
Thanks, looks good! |
Update RLS and Rustfmt RLS * Allow project model to download crates ([#1020](rust-lang/rls#1020)) * Support simple external builds ([#988](rust-lang/rls#988)) * Support using external Rustfmt ([#990](rust-lang/rls#990)) Rustfmt (0.99.4) * Format chains with comment ([#2899](https://github.com/rust-lang-nursery/rls/pull/2899)) * Do not show wildcard pattern in slice pattern ([#2912](https://github.com/rust-lang-nursery/rls/pull/2912)) * Impl only use ([#2951](https://github.com/rust-lang-nursery/rls/pull/2951)) * ... and [more](rust-lang/rustfmt@5c9a2b6...1c40881) Bumped in tandem to pull a single version of `rustc-ap-*` libs. r? @nrc
Fixes #812. (Uses https://github.com/Xanewok/rustfmt/tree/file-lines-ser-json)
High-level overview:
trait Formatter { fn format(&self, String, rustfmt::Config) -> Result<String, String>; }
Rustfmt
enum as a convenient interface which implements the trait, accessible viactx.formatter()
Rustfmt::Internal
variant implementation is what was currently used, running included Rustfmt in-processRustfmt::External
spawns the provided command, using the Rustfmt stdin/stdout mode.Assuming that Rust input should be a valid UTF-8 and so Rustfmt should also reformat it to a valid UTF-8, returning
Err
if that's not the case.This is not entirely correct yet, since we should pass full Config in a file to executed Rustfmt, since LSP may request additional formatting options and this currently just uses default Rustfmt configuration either via
rustfmt.toml
or by using default, but with some RLS-specific options.Have to finish this one bit, but in general this should be ready for a review!