aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/typing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/typing.rs')
-rw-r--r--crates/ra_ide/src/typing.rs25
1 files changed, 10 insertions, 15 deletions
diff --git a/crates/ra_ide/src/typing.rs b/crates/ra_ide/src/typing.rs
index f55cd3bf5..2a8b4327f 100644
--- a/crates/ra_ide/src/typing.rs
+++ b/crates/ra_ide/src/typing.rs
@@ -21,7 +21,7 @@ use ra_ide_db::RootDatabase;
21use ra_syntax::{ 21use ra_syntax::{
22 algo::find_node_at_offset, 22 algo::find_node_at_offset,
23 ast::{self, AstToken}, 23 ast::{self, AstToken},
24 AstNode, SourceFile, TextRange, TextUnit, 24 AstNode, SourceFile, TextRange, TextSize,
25}; 25};
26use ra_text_edit::TextEdit; 26use ra_text_edit::TextEdit;
27 27
@@ -45,7 +45,7 @@ pub(crate) fn on_char_typed(
45 45
46fn on_char_typed_inner( 46fn on_char_typed_inner(
47 file: &SourceFile, 47 file: &SourceFile,
48 offset: TextUnit, 48 offset: TextSize,
49 char_typed: char, 49 char_typed: char,
50) -> Option<SingleFileChange> { 50) -> Option<SingleFileChange> {
51 assert!(TRIGGER_CHARS.contains(char_typed)); 51 assert!(TRIGGER_CHARS.contains(char_typed));
@@ -60,7 +60,7 @@ fn on_char_typed_inner(
60/// Returns an edit which should be applied after `=` was typed. Primarily, 60/// Returns an edit which should be applied after `=` was typed. Primarily,
61/// this works when adding `let =`. 61/// this works when adding `let =`.
62// FIXME: use a snippet completion instead of this hack here. 62// FIXME: use a snippet completion instead of this hack here.
63fn on_eq_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange> { 63fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<SingleFileChange> {
64 assert_eq!(file.syntax().text().char_at(offset), Some('=')); 64 assert_eq!(file.syntax().text().char_at(offset), Some('='));
65 let let_stmt: ast::LetStmt = find_node_at_offset(file.syntax(), offset)?; 65 let let_stmt: ast::LetStmt = find_node_at_offset(file.syntax(), offset)?;
66 if let_stmt.semicolon_token().is_some() { 66 if let_stmt.semicolon_token().is_some() {
@@ -86,7 +86,7 @@ fn on_eq_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange>
86} 86}
87 87
88/// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. 88/// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
89fn on_dot_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange> { 89fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<SingleFileChange> {
90 assert_eq!(file.syntax().text().char_at(offset), Some('.')); 90 assert_eq!(file.syntax().text().char_at(offset), Some('.'));
91 let whitespace = 91 let whitespace =
92 file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?; 92 file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?;
@@ -96,34 +96,29 @@ fn on_dot_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange>
96 let newline = text.rfind('\n')?; 96 let newline = text.rfind('\n')?;
97 &text[newline + 1..] 97 &text[newline + 1..]
98 }; 98 };
99 let current_indent_len = TextUnit::of_str(current_indent); 99 let current_indent_len = TextSize::of(current_indent);
100 100
101 // Make sure dot is a part of call chain 101 // Make sure dot is a part of call chain
102 let field_expr = ast::FieldExpr::cast(whitespace.syntax().parent())?; 102 let field_expr = ast::FieldExpr::cast(whitespace.syntax().parent())?;
103 let prev_indent = leading_indent(field_expr.syntax())?; 103 let prev_indent = leading_indent(field_expr.syntax())?;
104 let target_indent = format!(" {}", prev_indent); 104 let target_indent = format!(" {}", prev_indent);
105 let target_indent_len = TextUnit::of_str(&target_indent); 105 let target_indent_len = TextSize::of(&target_indent);
106 if current_indent_len == target_indent_len { 106 if current_indent_len == target_indent_len {
107 return None; 107 return None;
108 } 108 }
109 109
110 Some(SingleFileChange { 110 Some(SingleFileChange {
111 label: "reindent dot".to_string(), 111 label: "reindent dot".to_string(),
112 edit: TextEdit::replace( 112 edit: TextEdit::replace(TextRange::new(offset - current_indent_len, offset), target_indent),
113 TextRange::from_to(offset - current_indent_len, offset), 113 cursor_position: Some(offset + target_indent_len - current_indent_len + TextSize::of('.')),
114 target_indent,
115 ),
116 cursor_position: Some(
117 offset + target_indent_len - current_indent_len + TextUnit::of_char('.'),
118 ),
119 }) 114 })
120} 115}
121 116
122/// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }` 117/// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }`
123fn on_arrow_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChange> { 118fn on_arrow_typed(file: &SourceFile, offset: TextSize) -> Option<SingleFileChange> {
124 let file_text = file.syntax().text(); 119 let file_text = file.syntax().text();
125 assert_eq!(file_text.char_at(offset), Some('>')); 120 assert_eq!(file_text.char_at(offset), Some('>'));
126 let after_arrow = offset + TextUnit::of_char('>'); 121 let after_arrow = offset + TextSize::of('>');
127 if file_text.char_at(after_arrow) != Some('{') { 122 if file_text.char_at(after_arrow) != Some('{') {
128 return None; 123 return None;
129 } 124 }