diff --git a/.cargo/config b/.cargo/config
index fd32471ea43..c0be661fd60 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -3,6 +3,7 @@
 gen-syntax =    "run --package tools -- gen-syntax"
 gen-tests =    "run --package tools -- gen-tests"
 install-code = "run --package tools -- install-code"
+format =    "run --package tools -- format"
 
 render-test = "run --package ra_cli -- render-test"
 parse =       "run --package ra_cli -- parse"
diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs
index 7c5410d3c78..91c35b9e133 100644
--- a/crates/tools/src/lib.rs
+++ b/crates/tools/src/lib.rs
@@ -12,9 +12,9 @@ pub use teraron::{Mode, Verify, Overwrite};
 
 pub type Result<T> = ::std::result::Result<T, failure::Error>;
 
-pub const GRAMMAR: &str = "ra_syntax/src/grammar.ron";
-pub const SYNTAX_KINDS: &str = "ra_syntax/src/syntax_kinds/generated.rs.tera";
-pub const AST: &str = "ra_syntax/src/ast/generated.rs.tera";
+pub const GRAMMAR: &str = "crates/ra_syntax/src/grammar.ron";
+pub const SYNTAX_KINDS: &str = "crates/ra_syntax/src/syntax_kinds/generated.rs.tera";
+pub const AST: &str = "crates/ra_syntax/src/ast/generated.rs.tera";
 
 #[derive(Debug)]
 pub struct Test {
@@ -75,7 +75,8 @@ pub fn generate(mode: Mode) -> Result<()> {
 
 pub fn project_root() -> PathBuf {
     Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap())
-        .parent()
+        .ancestors()
+        .nth(2)
         .unwrap()
         .to_path_buf()
 }
diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs
index fdb443690bd..bc5ad6fa8d1 100644
--- a/crates/tools/src/main.rs
+++ b/crates/tools/src/main.rs
@@ -13,7 +13,7 @@ use std::{
     process::Command,
 };
 use tools::{
-    collect_tests, Result, Test, generate, Mode, Overwrite, Verify,
+    collect_tests, Result, Test, generate, Mode, Overwrite, Verify, project_root,
 };
 
 const GRAMMAR_DIR: &str = "./crates/ra_syntax/src/grammar";
@@ -31,6 +31,7 @@ fn main() -> Result<()> {
         .subcommand(SubCommand::with_name("gen-syntax"))
         .subcommand(SubCommand::with_name("gen-tests"))
         .subcommand(SubCommand::with_name("install-code"))
+        .subcommand(SubCommand::with_name("format"))
         .get_matches();
     let mode = if matches.is_present("verify") {
         Verify
@@ -41,6 +42,7 @@ fn main() -> Result<()> {
         ("install-code", _) => install_code_extension()?,
         ("gen-tests", _) => gen_tests(mode)?,
         ("gen-syntax", _) => generate(Overwrite)?,
+        ("format", _) => run_rustfmt()?,
         _ => unreachable!(),
     }
     Ok(())
@@ -146,12 +148,7 @@ fn install_code_extension() -> Result<()> {
 
 fn run(cmdline: &'static str, dir: &str) -> Result<()> {
     eprintln!("\nwill run: {}", cmdline);
-    let manifest_dir = env!("CARGO_MANIFEST_DIR");
-    let project_dir = Path::new(manifest_dir)
-        .ancestors()
-        .nth(2)
-        .unwrap()
-        .join(dir);
+    let project_dir = project_root().join(dir);
     let mut args = cmdline.split_whitespace();
     let exec = args.next().unwrap();
     let status = Command::new(exec)
@@ -163,3 +160,11 @@ fn run(cmdline: &'static str, dir: &str) -> Result<()> {
     }
     Ok(())
 }
+
+fn run_rustfmt() -> Result<()> {
+    // Use beta toolchain for 2018 edition.
+    run("rustup install beta", ".")?;
+    run("rustup component add rustfmt-preview --toolchain beta", ".")?;
+    run("rustup run beta -- cargo fmt", ".")?;
+    Ok(())
+}