on master help sign in
Replace incorrect usages of tab_width with indent_width. (#5918)
commita1a6d5f3340ba8a587bbf8c178fe65589f36a51a authorTriton171 <daniel.ebert@protonmail.com> dateThu 16 Feb 2023, 15:47 (4 years ago) parentd27e808
4 files changed+48−23
helix-core/src/indent.rs+32−7 helix-core/tests/indent.rs+4−2 helix-term/src/commands.rs+6−13 helix-view/src/document.rs+6−1
helix-core/src/indent.rs+32−7
@@ -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}
helix-core/tests/indent.rs+4−2
@@ -46,11 +46,13 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
4646 for i in 0..doc.len_lines() {
4747 let line = text.line(i);
4848 if let Some(pos) = helix_core::find_first_non_whitespace_char(line) {
49+ let tab_and_indent_width: usize = 4;
4950 let suggested_indent = treesitter_indent_for_pos(
5051 indent_query,
5152 &syntax,
52− &IndentStyle::Spaces(4),
53− 4,
53+ &IndentStyle::Spaces(tab_and_indent_width as u8),
54+ tab_and_indent_width,
55+ tab_and_indent_width,
5456 text,
5557 i,
5658 text.line_to_char(i) + pos,
helix-term/src/commands.rs+6−13
@@ -3364,8 +3364,8 @@ pub mod insert {
33643364 let count = cx.count();
33653365 let (view, doc) = current_ref!(cx.editor);
33663366 let text = doc.text().slice(..);
3367− let indent_unit = doc.indent_style.as_str();
3368− let tab_size = doc.tab_width();
3367+ let tab_width = doc.tab_width();
3368+ let indent_width = doc.indent_width();
33693369 let auto_pairs = doc.auto_pairs(cx.editor);
33703370
33713371 let transaction =
@@ -3386,18 +3386,11 @@ pub mod insert {
33863386 None,
33873387 )
33883388 } else {
3389− let unit_len = indent_unit.chars().count();
3390− // NOTE: indent_unit always contains 'only spaces' or 'only tab' according to `IndentStyle` definition.
3391− let unit_size = if indent_unit.starts_with('\t') {
3392− tab_size * unit_len
3393− } else {
3394− unit_len
3395− };
33963389 let width: usize = fragment
33973390 .chars()
33983391 .map(|ch| {
33993392 if ch == '\t' {
3400− tab_size
3393+ tab_width
34013394 } else {
34023395 // it can be none if it still meet control characters other than '\t'
34033396 // here just set the width to 1 (or some value better?).
@@ -3405,9 +3398,9 @@ pub mod insert {
34053398 }
34063399 })
34073400 .sum();
3408− let mut drop = width % unit_size; // round down to nearest unit
3401+ let mut drop = width % indent_width; // round down to nearest unit
34093402 if drop == 0 {
3410− drop = unit_size
3403+ drop = indent_width
34113404 }; // if it's already at a unit, consume a whole unit
34123405 let mut chars = fragment.chars().rev();
34133406 let mut start = pos;
@@ -3949,7 +3942,7 @@ fn unindent(cx: &mut Context) {
39493942 let lines = get_lines(doc, view.id);
39503943 let mut changes = Vec::with_capacity(lines.len());
39513944 let tab_width = doc.tab_width();
3952− let indent_width = count * tab_width;
3945+ let indent_width = count * doc.indent_width();
39533946
39543947 for line_idx in lines {
39553948 let line = doc.text().line(line_idx);
helix-view/src/document.rs+6−1
@@ -1122,13 +1122,18 @@ impl Document {
11221122 self.syntax.as_ref()
11231123 }
11241124
1125− /// Tab size in columns.
1125+ /// The width that the tab character is rendered at
11261126 pub fn tab_width(&self) -> usize {
11271127 self.language_config()
11281128 .and_then(|config| config.indent.as_ref())
11291129 .map_or(4, |config| config.tab_width) // fallback to 4 columns
11301130 }
11311131
1132+ // The width (in spaces) of a level of indentation.
1133+ pub fn indent_width(&self) -> usize {
1134+ self.indent_style.indent_width(self.tab_width())
1135+ }
1136+
11321137 pub fn changes(&self) -> &ChangeSet {
11331138 &self.changes
11341139 }