Skip to content

Commit

Permalink
Merge pull request #19124 from jyn514/range-fmt-off-by-one
Browse files Browse the repository at this point in the history
Fix off-by-one error in RangeFormatting
  • Loading branch information
Veykril authored Feb 10, 2025
2 parents f01f900 + 66253b6 commit f5e7172
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 8 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ jobs:
run: |
rustup update --no-self-update ${{ env.RUST_CHANNEL }}
rustup default ${{ env.RUST_CHANNEL }}
rustup component add --toolchain ${{ env.RUST_CHANNEL }} rustfmt rust-src
rustup component add --toolchain ${{ env.RUST_CHANNEL }} rust-src
# We always use a nightly rustfmt, regardless of channel, because we need
# --file-lines.
rustup toolchain add nightly --profile minimal
rustup component add --toolchain nightly rustfmt
# https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/rust.json
- name: Install Rust Problem Matcher
if: matrix.os == 'ubuntu-latest'
Expand Down
4 changes: 3 additions & 1 deletion crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3798,8 +3798,10 @@ mod tests {
(config, _, _) = config.apply_change(change);

assert_eq!(config.cargo_targetDir(None), &Some(TargetDirectory::UseSubdirectory(true)));
let target =
Utf8PathBuf::from(std::env::var("CARGO_TARGET_DIR").unwrap_or("target".to_owned()));
assert!(
matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer")))
matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(target.join("rust-analyzer")))
);
}

Expand Down
3 changes: 2 additions & 1 deletion crates/rust-analyzer/src/handlers/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2284,7 +2284,8 @@ fn run_rustfmt(
cmd.arg(
json!([{
"file": "stdin",
"range": [start_line, end_line]
// LineCol is 0-based, but rustfmt is 1-based.
"range": [start_line + 1, end_line + 1]
}])
.to_string(),
);
Expand Down
74 changes: 70 additions & 4 deletions crates/rust-analyzer/tests/slow-tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ use lsp_types::{
notification::DidOpenTextDocument,
request::{
CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest,
InlayHintRequest, InlayHintResolveRequest, WillRenameFiles, WorkspaceSymbolRequest,
InlayHintRequest, InlayHintResolveRequest, RangeFormatting, WillRenameFiles,
WorkspaceSymbolRequest,
},
CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams,
DocumentFormattingParams, FileRename, FormattingOptions, GotoDefinitionParams, HoverParams,
InlayHint, InlayHintLabel, InlayHintParams, PartialResultParams, Position, Range,
RenameFilesParams, TextDocumentItem, TextDocumentPositionParams, WorkDoneProgressParams,
DocumentFormattingParams, DocumentRangeFormattingParams, FileRename, FormattingOptions,
GotoDefinitionParams, HoverParams, InlayHint, InlayHintLabel, InlayHintParams,
PartialResultParams, Position, Range, RenameFilesParams, TextDocumentItem,
TextDocumentPositionParams, WorkDoneProgressParams,
};
use rust_analyzer::lsp::ext::{OnEnter, Runnables, RunnablesParams};
use serde_json::json;
Expand Down Expand Up @@ -660,6 +662,70 @@ fn main() {}
);
}

#[test]
fn test_format_document_range() {
if skip_slow_tests() {
return;
}

let server = Project::with_fixture(
r#"
//- /Cargo.toml
[package]
name = "foo"
version = "0.0.0"
//- /src/lib.rs
fn main() {
let unit_offsets_cache = collect(dwarf.units ()) ?;
}
"#,
)
.with_config(serde_json::json!({
"rustfmt": {
"overrideCommand": [ "rustfmt", "+nightly", ],
"rangeFormatting": { "enable": true }
},
}))
.server()
.wait_until_workspace_is_loaded();

server.request::<RangeFormatting>(
DocumentRangeFormattingParams {
range: Range {
end: Position { line: 1, character: 0 },
start: Position { line: 1, character: 0 },
},
text_document: server.doc_id("src/lib.rs"),
options: FormattingOptions {
tab_size: 4,
insert_spaces: false,
insert_final_newline: None,
trim_final_newlines: None,
trim_trailing_whitespace: None,
properties: HashMap::new(),
},
work_done_progress_params: WorkDoneProgressParams::default(),
},
json!([
{
"newText": "",
"range": {
"start": { "character": 48, "line": 1 },
"end": { "character": 50, "line": 1 },
},
},
{
"newText": "",
"range": {
"start": { "character": 53, "line": 1 },
"end": { "character": 55, "line": 1 },
},
}
]),
);
}

#[test]
fn test_missing_module_code_action() {
if skip_slow_tests() {
Expand Down
9 changes: 8 additions & 1 deletion crates/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,19 @@ pub fn skip_slow_tests() -> bool {
if should_skip {
eprintln!("ignoring slow test");
} else {
let path = project_root().join("./target/.slow_tests_cookie");
let path = target_dir().join(".slow_tests_cookie");
fs::write(path, ".").unwrap();
}
should_skip
}

pub fn target_dir() -> Utf8PathBuf {
match std::env::var("CARGO_TARGET_DIR") {
Ok(target) => Utf8PathBuf::from(target),
Err(_) => project_root().join("target"),
}
}

/// Returns the path to the root directory of `rust-analyzer` project.
pub fn project_root() -> Utf8PathBuf {
let dir = env!("CARGO_MANIFEST_DIR");
Expand Down

0 comments on commit f5e7172

Please sign in to comment.