diff options
Diffstat (limited to 'helix-core/src')
-rw-r--r-- | helix-core/src/indent.rs | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 3aa59fa3..950a7f65 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -56,6 +56,14 @@ impl IndentStyle { } } } + + #[inline] + pub fn indent_width(&self, tab_width: usize) -> usize { + match *self { + IndentStyle::Tabs => tab_width, + IndentStyle::Spaces(width) => width as usize, + } + } } /// Attempts to detect the indentation style used in a document. @@ -177,7 +185,7 @@ pub fn auto_detect_indent_style(document_text: &Rope) -> Option<IndentStyle> { /// To determine indentation of a newly inserted line, figure out the indentation at the last col /// of the previous line. -pub fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize { +pub fn indent_level_for_line(line: RopeSlice, tab_width: usize, indent_width: usize) -> usize { let mut len = 0; for ch in line.chars() { match ch { @@ -187,7 +195,7 @@ pub fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize { } } - len / tab_width + len / indent_width } /// Computes for node and all ancestors whether they are the first node on their line. @@ -466,6 +474,7 @@ fn extend_nodes<'a>( text: RopeSlice, line: usize, tab_width: usize, + indent_width: usize, ) { let mut stop_extend = false; @@ -490,10 +499,12 @@ fn extend_nodes<'a>( if deepest_preceding.end_position().row == line { extend_node = true; } else { - let cursor_indent = indent_level_for_line(text.line(line), tab_width); + let cursor_indent = + indent_level_for_line(text.line(line), tab_width, indent_width); let node_indent = indent_level_for_line( text.line(deepest_preceding.start_position().row), tab_width, + indent_width, ); if cursor_indent > node_indent { extend_node = true; @@ -562,6 +573,7 @@ pub fn treesitter_indent_for_pos( syntax: &Syntax, indent_style: &IndentStyle, tab_width: usize, + indent_width: usize, text: RopeSlice, line: usize, pos: usize, @@ -622,6 +634,7 @@ pub fn treesitter_indent_for_pos( text, line, tab_width, + indent_width, ); } let mut first_in_line = get_first_in_line(node, new_line.then_some(byte_pos)); @@ -709,6 +722,7 @@ pub fn indent_for_newline( line_before_end_pos: usize, current_line: usize, ) -> String { + let indent_width = indent_style.indent_width(tab_width); if let (Some(query), Some(syntax)) = ( language_config.and_then(|config| config.indent_query()), syntax, @@ -718,6 +732,7 @@ pub fn indent_for_newline( syntax, indent_style, tab_width, + indent_width, text, line_before, line_before_end_pos, @@ -726,7 +741,7 @@ pub fn indent_for_newline( return indent; }; } - let indent_level = indent_level_for_line(text.line(current_line), tab_width); + let indent_level = indent_level_for_line(text.line(current_line), tab_width, indent_width); indent_style.as_str().repeat(indent_level) } @@ -763,12 +778,22 @@ mod test { #[test] fn test_indent_level() { let tab_width = 4; + let indent_width = 4; let line = Rope::from(" fn new"); // 8 spaces - assert_eq!(indent_level_for_line(line.slice(..), tab_width), 2); + assert_eq!( + indent_level_for_line(line.slice(..), tab_width, indent_width), + 2 + ); let line = Rope::from("\t\t\tfn new"); // 3 tabs - assert_eq!(indent_level_for_line(line.slice(..), tab_width), 3); + assert_eq!( + indent_level_for_line(line.slice(..), tab_width, indent_width), + 3 + ); // mixed indentation let line = Rope::from("\t \tfn new"); // 1 tab, 4 spaces, tab - assert_eq!(indent_level_for_line(line.slice(..), tab_width), 3); + assert_eq!( + indent_level_for_line(line.slice(..), tab_width, indent_width), + 3 + ); } } |