on master help sign in
Allow any indent size from 1 to 16 (#7429)
93ac706Scott Driggers
helix-core/src/indent.rs+32−19
@@ -19,6 +19,10 @@ pub enum IndentStyle {
19 Spaces(u8),
19 Spaces(u8),
20}
20}
21
21
22+// 16 spaces
23+const INDENTS: &str = " ";
24+const MAX_INDENT: u8 = 16;
25+
22impl IndentStyle {
26impl IndentStyle {
23 /// Creates an `IndentStyle` from an indentation string.
27 /// Creates an `IndentStyle` from an indentation string.
24 ///
28 ///
@@ -27,10 +31,10 @@ impl IndentStyle {
27 #[inline]
31 #[inline]
28 pub fn from_str(indent: &str) -> Self {
32 pub fn from_str(indent: &str) -> Self {
29 // XXX: do we care about validating the input more than this? Probably not...?
33 // XXX: do we care about validating the input more than this? Probably not...?
30− debug_assert!(!indent.is_empty() && indent.len() <= 8);
34+ debug_assert!(!indent.is_empty() && indent.len() <= MAX_INDENT as usize);
31
35
32 if indent.starts_with(' ') {
36 if indent.starts_with(' ') {
33− IndentStyle::Spaces(indent.len() as u8)
37+ IndentStyle::Spaces(indent.len().clamp(1, MAX_INDENT as usize) as u8)
34 } else {
38 } else {
35 IndentStyle::Tabs
39 IndentStyle::Tabs
36 }
40 }
@@ -40,20 +44,13 @@ impl IndentStyle {
40 pub fn as_str(&self) -> &'static str {
44 pub fn as_str(&self) -> &'static str {
41 match *self {
45 match *self {
42 IndentStyle::Tabs => "\t",
46 IndentStyle::Tabs => "\t",
43− IndentStyle::Spaces(1) => " ",
44− IndentStyle::Spaces(2) => " ",
45− IndentStyle::Spaces(3) => " ",
46− IndentStyle::Spaces(4) => " ",
47− IndentStyle::Spaces(5) => " ",
48− IndentStyle::Spaces(6) => " ",
49− IndentStyle::Spaces(7) => " ",
50− IndentStyle::Spaces(8) => " ",
51−
52− // Unsupported indentation style. This should never happen,
53− // but just in case fall back to two spaces.
54 IndentStyle::Spaces(n) => {
47 IndentStyle::Spaces(n) => {
48+ // Unsupported indentation style. This should never happen,
55− debug_assert!(n > 0 && n <= 8); // Always triggers. `debug_panic!()` wanted.
49+ debug_assert!(n > 0 && n <= MAX_INDENT);
56− " "
50+
51+ // Either way, clamp to the nearest supported value
52+ let closest_n = n.clamp(1, MAX_INDENT) as usize;
53+ &INDENTS[0..closest_n]
57 }
54 }
58 }
55 }
59 }
56 }
@@ -75,9 +72,9 @@ pub fn auto_detect_indent_style(document_text: &Rope) -> Option<IndentStyle> {
75 // Build a histogram of the indentation *increases* between
72 // Build a histogram of the indentation *increases* between
76 // subsequent lines, ignoring lines that are all whitespace.
73 // subsequent lines, ignoring lines that are all whitespace.
77 //
74 //
78− // Index 0 is for tabs, the rest are 1-8 spaces.
75+ // Index 0 is for tabs, the rest are 1-MAX_INDENT spaces.
79− let histogram: [usize; 9] = {
76+ let histogram: [usize; MAX_INDENT as usize + 1] = {
80− let mut histogram = [0; 9];
77+ let mut histogram = [0; MAX_INDENT as usize + 1];
81 let mut prev_line_is_tabs = false;
78 let mut prev_line_is_tabs = false;
82 let mut prev_line_leading_count = 0usize;
79 let mut prev_line_leading_count = 0usize;
83
80
@@ -136,7 +133,7 @@ pub fn auto_detect_indent_style(document_text: &Rope) -> Option<IndentStyle> {
136 histogram[0] += 1;
133 histogram[0] += 1;
137 } else {
134 } else {
138 let amount = leading_count - prev_line_leading_count;
135 let amount = leading_count - prev_line_leading_count;
139− if amount <= 8 {
136+ if amount <= MAX_INDENT as usize {
140 histogram[amount] += 1;
137 histogram[amount] += 1;
141 }
138 }
142 }
139 }
@@ -797,4 +794,20 @@ mod test {
797 3
794 3
798 );
795 );
799 }
796 }
797+
798+ #[test]
799+ fn test_large_indent_level() {
800+ let tab_width = 16;
801+ let indent_width = 16;
802+ let line = Rope::from(" fn new"); // 16 spaces
803+ assert_eq!(
804+ indent_level_for_line(line.slice(..), tab_width, indent_width),
805+ 1
806+ );
807+ let line = Rope::from(" fn new"); // 32 spaces
808+ assert_eq!(
809+ indent_level_for_line(line.slice(..), tab_width, indent_width),
810+ 2
811+ );
812+ }
800}
813}