From 8b24f158f75e4496cfc7f8edf9aa41b10dbac9b3 Mon Sep 17 00:00:00 2001 From: Aleksander Vognild Burkow Date: Sat, 29 Dec 2018 20:09:42 +0100 Subject: Add support for formatting entire document with rustfmt Attempting to format a document when rustfmt isn't installed will result in an error being returned to the frontend. An alternative implementation would be returning zero replacements. --- crates/ra_lsp_server/src/main_loop/handlers.rs | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'crates/ra_lsp_server/src/main_loop') diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index d6f3dbe28..07579be12 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -6,13 +6,16 @@ use languageserver_types::{ DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind, FoldingRangeParams, Location, MarkupContent, MarkupKind, MarkedString, Position, PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, + Range, WorkspaceEdit, ParameterInformation, ParameterLabel, SignatureInformation, Hover, HoverContents, + DocumentFormattingParams, }; use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FileRange, FilePosition, Severity}; use ra_syntax::{TextUnit, text_utils::intersect}; use ra_text_edit::text_utils::contains_offset_nonstrict; use rustc_hash::FxHashMap; use serde_json::to_value; +use std::io::Write; use crate::{ conv::{to_location, Conv, ConvWith, MapConvWith, TryConvWith}, @@ -601,6 +604,36 @@ pub fn handle_references( )) } +pub fn handle_formatting( + world: ServerWorld, + params: DocumentFormattingParams, +) -> Result>> { + let file_id = params.text_document.try_conv_with(&world)?; + let file = world.analysis().file_text(file_id); + + let file_line_index = world.analysis().file_line_index(file_id); + let end_position = TextUnit::of_str(&file).conv_with(&file_line_index); + + use std::process; + let mut rustfmt = process::Command::new("rustfmt") + .stdin(process::Stdio::piped()) + .stdout(process::Stdio::piped()) + .spawn()?; + + rustfmt.stdin.as_mut().unwrap().write_all(file.as_bytes())?; + + let output = rustfmt.wait_with_output()?; + let captured_stdout = String::from_utf8(output.stdout)?; + if !output.status.success() { + return Err(failure::err_msg(captured_stdout)); + } + + Ok(Some(vec![TextEdit { + range: Range::new(Position::new(0, 0), end_position), + new_text: captured_stdout, + }])) +} + pub fn handle_code_action( world: ServerWorld, params: req::CodeActionParams, -- cgit v1.2.3