@@ -56,6 +56,14 @@ impl IndentStyle {
5656 }
5757 }
5858 }
59+
60+ #[inline]
61+ pub fn indent_width(&self, tab_width: usize) -> usize {
62+ match *self {
63+ IndentStyle::Tabs => tab_width,
64+ IndentStyle::Spaces(width) => width as usize,
65+ }
66+ }
5967}
6068
6169/// 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> {
177185
178186/// To determine indentation of a newly inserted line, figure out the indentation at the last col
179187/// of the previous line.
180−pub fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize {
188+pub fn indent_level_for_line(line: RopeSlice, tab_width: usize, indent_width: usize) -> usize {
181189 let mut len = 0;
182190 for ch in line.chars() {
183191 match ch {
@@ -187,7 +195,7 @@ pub fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize {
187195 }
188196 }
189197
190− len / tab_width
198+ len / indent_width
191199}
192200
193201/// Computes for node and all ancestors whether they are the first node on their line.
@@ -466,6 +474,7 @@ fn extend_nodes<'a>(
466474 text: RopeSlice,
467475 line: usize,
468476 tab_width: usize,
477+ indent_width: usize,
469478) {
470479 let mut stop_extend = false;
471480
@@ -490,10 +499,12 @@ fn extend_nodes<'a>(
490499 if deepest_preceding.end_position().row == line {
491500 extend_node = true;
492501 } else {
493− let cursor_indent = indent_level_for_line(text.line(line), tab_width);
502+ let cursor_indent =
503+ indent_level_for_line(text.line(line), tab_width, indent_width);
494504 let node_indent = indent_level_for_line(
495505 text.line(deepest_preceding.start_position().row),
496506 tab_width,
507+ indent_width,
497508 );
498509 if cursor_indent > node_indent {
499510 extend_node = true;
@@ -562,6 +573,7 @@ pub fn treesitter_indent_for_pos(
562573 syntax: &Syntax,
563574 indent_style: &IndentStyle,
564575 tab_width: usize,
576+ indent_width: usize,
565577 text: RopeSlice,
566578 line: usize,
567579 pos: usize,
@@ -622,6 +634,7 @@ pub fn treesitter_indent_for_pos(
622634 text,
623635 line,
624636 tab_width,
637+ indent_width,
625638 );
626639 }
627640 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(
709722 line_before_end_pos: usize,
710723 current_line: usize,
711724) -> String {
725+ let indent_width = indent_style.indent_width(tab_width);
712726 if let (Some(query), Some(syntax)) = (
713727 language_config.and_then(|config| config.indent_query()),
714728 syntax,
@@ -718,6 +732,7 @@ pub fn indent_for_newline(
718732 syntax,
719733 indent_style,
720734 tab_width,
735+ indent_width,
721736 text,
722737 line_before,
723738 line_before_end_pos,
@@ -726,7 +741,7 @@ pub fn indent_for_newline(
726741 return indent;
727742 };
728743 }
729− let indent_level = indent_level_for_line(text.line(current_line), tab_width);
744+ let indent_level = indent_level_for_line(text.line(current_line), tab_width, indent_width);
730745 indent_style.as_str().repeat(indent_level)
731746}
732747
@@ -763,12 +778,22 @@ mod test {
763778 #[test]
764779 fn test_indent_level() {
765780 let tab_width = 4;
781+ let indent_width = 4;
766782 let line = Rope::from(" fn new"); // 8 spaces
767− assert_eq!(indent_level_for_line(line.slice(..), tab_width), 2);
783+ assert_eq!(
784+ indent_level_for_line(line.slice(..), tab_width, indent_width),
785+ 2
786+ );
768787 let line = Rope::from("\t\t\tfn new"); // 3 tabs
769− assert_eq!(indent_level_for_line(line.slice(..), tab_width), 3);
788+ assert_eq!(
789+ indent_level_for_line(line.slice(..), tab_width, indent_width),
790+ 3
791+ );
770792 // mixed indentation
771793 let line = Rope::from("\t \tfn new"); // 1 tab, 4 spaces, tab
772− assert_eq!(indent_level_for_line(line.slice(..), tab_width), 3);
794+ assert_eq!(
795+ indent_level_for_line(line.slice(..), tab_width, indent_width),
796+ 3
797+ );
773798 }
774799}