-
-
Notifications
You must be signed in to change notification settings - Fork 43
feat: improved reformat edits #87
Changes from all commits
fbbdfc1
9f515db
78a0800
67d4840
51a8128
d79a372
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
use lsp_types::*; | ||
use nixpkgs_fmt::AtomEdit; | ||
use rnix::{types::*, SyntaxNode, TextRange, TextSize, TokenAtOffset}; | ||
use std::{ | ||
collections::HashMap, | ||
convert::TryFrom, | ||
fmt::{Debug, Display, Formatter, Result}, | ||
ops, | ||
path::PathBuf, | ||
rc::Rc, | ||
}; | ||
|
@@ -323,9 +325,30 @@ pub fn selection_ranges(root: &SyntaxNode, content: &str, pos: Position) -> Opti | |
root.map(|b| *b) | ||
} | ||
|
||
/// Convert an AtomEdit to a tuple whose first element is `atom_edit`'s delete range, and whose | ||
/// second element is a String with the same contents as `atom_edit`'s insert value. | ||
pub fn atom_edit_to_tuple(atom_edit: AtomEdit) -> (ops::Range<usize>, String) { | ||
let r: std::ops::Range<usize> = atom_edit.delete.start().into()..atom_edit.delete.end().into(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are the two dots really needed here or is that a Rust feature I'm not aware of? :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
(r, atom_edit.insert.to_string()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be nice to document what this is doing and also to add a test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea, done in 4cc254a. |
||
} | ||
|
||
pub fn tuple_to_text_edit(tup: (ops::Range<usize>, String), code: &str) -> TextEdit { | ||
TextEdit { | ||
range: range( | ||
code, | ||
TextRange::new( | ||
TextSize::from(tup.0.start as u32), | ||
TextSize::from(tup.0.end as u32), | ||
), | ||
), | ||
new_text: tup.1, | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use smol_str::SmolStr; | ||
|
||
#[test] | ||
fn test_get_offset_from_nix_expr() { | ||
|
@@ -467,4 +490,34 @@ mod tests { | |
let ident_ = ident.unwrap(); | ||
assert_eq!(vec!["a"], ident_.path); | ||
} | ||
|
||
#[test] | ||
fn test_atom_edit_to_tuple() { | ||
let atom_edits = vec![ | ||
AtomEdit { | ||
delete: TextRange::new(TextSize::from(5), TextSize::from(9)), | ||
insert: SmolStr::from("hello world"), | ||
}, | ||
AtomEdit { | ||
delete: TextRange::new(TextSize::from(11), TextSize::from(11)), | ||
insert: SmolStr::from("the quick brown fox"), | ||
}, | ||
AtomEdit { | ||
delete: TextRange::new(TextSize::from(115698), TextSize::from(126498)), | ||
insert: SmolStr::from("a string"), | ||
}, | ||
]; | ||
let expected = vec![ | ||
(5..9, String::from("hello world")), | ||
(11..11, String::from("the quick brown fox")), | ||
(115698..126498, String::from("a string")), | ||
]; | ||
assert_eq!( | ||
atom_edits | ||
.into_iter() | ||
.map(atom_edit_to_tuple) | ||
.collect::<Vec<(ops::Range<usize>, String)>>(), | ||
expected | ||
); | ||
} | ||
} |
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'm not sure why this is needed, but I guess this can be answered with nix-community/nixpkgs-fmt#296 (comment)
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.
Yeah, like I mentioned in nix-community/nixpkgs-fmt#296 (comment), the delete ranges in the spacing edits apply to the original document, and the indent edits apply to the document after the spacing edits have been applied. Since the language server protocol expects a single set of edits in response to a reformat request, I believe merging the two sequential sets of edits into a single set of edits is necessary.