aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_editor/src
diff options
context:
space:
mode:
authorSimon Vandel Sillesen <[email protected]>2019-01-05 23:58:03 +0000
committerSimon Vandel Sillesen <[email protected]>2019-01-05 23:58:03 +0000
commitf99398d9d5e47e28f3749c7903df67b9030ac6e0 (patch)
tree64168a90441da3d19ad725b1b80513deef5864f4 /crates/ra_editor/src
parent3e42a158787955ff9f2e81be43479dbe8f2b1bb6 (diff)
indent on typing dot. fixes #439
Diffstat (limited to 'crates/ra_editor/src')
-rw-r--r--crates/ra_editor/src/lib.rs2
-rw-r--r--crates/ra_editor/src/typing.rs54
2 files changed, 52 insertions, 4 deletions
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs
index ac283e2e0..a3c85ed5d 100644
--- a/crates/ra_editor/src/lib.rs
+++ b/crates/ra_editor/src/lib.rs
@@ -16,7 +16,7 @@ pub use self::{
16 line_index::{LineCol, LineIndex}, 16 line_index::{LineCol, LineIndex},
17 line_index_utils::translate_offset_with_edit, 17 line_index_utils::translate_offset_with_edit,
18 structure::{file_structure, StructureNode}, 18 structure::{file_structure, StructureNode},
19 typing::{join_lines, on_enter, on_eq_typed}, 19 typing::{join_lines, on_enter, on_dot_typed, on_eq_typed},
20 diagnostics::diagnostics 20 diagnostics::diagnostics
21}; 21};
22use ra_text_edit::TextEditBuilder; 22use ra_text_edit::TextEditBuilder;
diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs
index 1b568e96c..aaea858ea 100644
--- a/crates/ra_editor/src/typing.rs
+++ b/crates/ra_editor/src/typing.rs
@@ -1,5 +1,6 @@
1use std::mem; 1use std::mem;
2 2
3use itertools::Itertools;
3use ra_syntax::{ 4use ra_syntax::{
4 algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset}, 5 algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset},
5 ast, 6 ast,
@@ -9,9 +10,8 @@ use ra_syntax::{
9 SyntaxNodeRef, TextRange, TextUnit, 10 SyntaxNodeRef, TextRange, TextUnit,
10}; 11};
11use ra_text_edit::text_utils::contains_offset_nonstrict; 12use ra_text_edit::text_utils::contains_offset_nonstrict;
12use itertools::Itertools;
13 13
14use crate::{find_node_at_offset, TextEditBuilder, LocalEdit}; 14use crate::{find_node_at_offset, LocalEdit, TextEditBuilder};
15 15
16pub fn join_lines(file: &SourceFileNode, range: TextRange) -> LocalEdit { 16pub fn join_lines(file: &SourceFileNode, range: TextRange) -> LocalEdit {
17 let range = if range.is_empty() { 17 let range = if range.is_empty() {
@@ -136,6 +136,27 @@ pub fn on_eq_typed(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit>
136 }) 136 })
137} 137}
138 138
139pub fn on_dot_typed(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit> {
140 let before_dot_offset = offset - TextUnit::of_char('.');
141
142 let whitespace = find_leaf_at_offset(file.syntax(), before_dot_offset)
143 .left_biased()
144 .and_then(ast::Whitespace::cast)?;
145
146 // whitespace found just left of the dot
147 // TODO: indent is always 4 spaces now. A better heuristic could look on the previous line(s)
148 let indent = " ".to_string();
149
150 let cursor_position = offset + TextUnit::of_str(&indent);;
151 let mut edit = TextEditBuilder::default();
152 edit.insert(before_dot_offset, indent);
153 Some(LocalEdit {
154 label: "indent dot".to_string(),
155 edit: edit.finish(),
156 cursor_position: Some(cursor_position),
157 })
158}
159
139fn remove_newline( 160fn remove_newline(
140 edit: &mut TextEditBuilder, 161 edit: &mut TextEditBuilder,
141 node: SyntaxNodeRef, 162 node: SyntaxNodeRef,
@@ -283,7 +304,9 @@ fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str {
283#[cfg(test)] 304#[cfg(test)]
284mod tests { 305mod tests {
285 use super::*; 306 use super::*;
286 use crate::test_utils::{add_cursor, check_action, extract_offset, extract_range, assert_eq_text}; 307 use crate::test_utils::{
308 add_cursor, assert_eq_text, check_action, extract_offset, extract_range,
309 };
287 310
288 fn check_join_lines(before: &str, after: &str) { 311 fn check_join_lines(before: &str, after: &str) {
289 check_action(before, after, |file, offset| { 312 check_action(before, after, |file, offset| {
@@ -615,6 +638,31 @@ fn foo() {
615 } 638 }
616 639
617 #[test] 640 #[test]
641 fn test_on_dot_typed() {
642 fn do_check(before: &str, after: &str) {
643 let (offset, before) = extract_offset(before);
644 let file = SourceFileNode::parse(&before);
645 let result = on_dot_typed(&file, offset).unwrap();
646 let actual = result.edit.apply(&before);
647 assert_eq_text!(after, &actual);
648 }
649 do_check(
650 r"
651 pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
652 self.child_impl(db, name)
653 .<|>
654 }
655",
656 r"
657 pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
658 self.child_impl(db, name)
659 .
660 }
661",
662 );
663 }
664
665 #[test]
618 fn test_on_enter() { 666 fn test_on_enter() {
619 fn apply_on_enter(before: &str) -> Option<String> { 667 fn apply_on_enter(before: &str) -> Option<String> {
620 let (offset, before) = extract_offset(before); 668 let (offset, before) = extract_offset(before);