Replace incorrect usages of tab_width with indent_width. (#5918)

pull/6018/head
Triton171 1 year ago committed by GitHub
parent d27e808fb3
commit a1a6d5f334
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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. /// 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 /// To determine indentation of a newly inserted line, figure out the indentation at the last col
/// of the previous line. /// 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; let mut len = 0;
for ch in line.chars() { for ch in line.chars() {
match ch { 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. /// 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, text: RopeSlice,
line: usize, line: usize,
tab_width: usize, tab_width: usize,
indent_width: usize,
) { ) {
let mut stop_extend = false; let mut stop_extend = false;
@ -490,10 +499,12 @@ fn extend_nodes<'a>(
if deepest_preceding.end_position().row == line { if deepest_preceding.end_position().row == line {
extend_node = true; extend_node = true;
} else { } 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( let node_indent = indent_level_for_line(
text.line(deepest_preceding.start_position().row), text.line(deepest_preceding.start_position().row),
tab_width, tab_width,
indent_width,
); );
if cursor_indent > node_indent { if cursor_indent > node_indent {
extend_node = true; extend_node = true;
@ -562,6 +573,7 @@ pub fn treesitter_indent_for_pos(
syntax: &Syntax, syntax: &Syntax,
indent_style: &IndentStyle, indent_style: &IndentStyle,
tab_width: usize, tab_width: usize,
indent_width: usize,
text: RopeSlice, text: RopeSlice,
line: usize, line: usize,
pos: usize, pos: usize,
@ -622,6 +634,7 @@ pub fn treesitter_indent_for_pos(
text, text,
line, line,
tab_width, tab_width,
indent_width,
); );
} }
let mut first_in_line = get_first_in_line(node, new_line.then_some(byte_pos)); 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, line_before_end_pos: usize,
current_line: usize, current_line: usize,
) -> String { ) -> String {
let indent_width = indent_style.indent_width(tab_width);
if let (Some(query), Some(syntax)) = ( if let (Some(query), Some(syntax)) = (
language_config.and_then(|config| config.indent_query()), language_config.and_then(|config| config.indent_query()),
syntax, syntax,
@ -718,6 +732,7 @@ pub fn indent_for_newline(
syntax, syntax,
indent_style, indent_style,
tab_width, tab_width,
indent_width,
text, text,
line_before, line_before,
line_before_end_pos, line_before_end_pos,
@ -726,7 +741,7 @@ pub fn indent_for_newline(
return indent; 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) indent_style.as_str().repeat(indent_level)
} }
@ -763,12 +778,22 @@ mod test {
#[test] #[test]
fn test_indent_level() { fn test_indent_level() {
let tab_width = 4; let tab_width = 4;
let indent_width = 4;
let line = Rope::from(" fn new"); // 8 spaces 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 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 // mixed indentation
let line = Rope::from("\t \tfn new"); // 1 tab, 4 spaces, tab 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
);
} }
} }

@ -46,11 +46,13 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
for i in 0..doc.len_lines() { for i in 0..doc.len_lines() {
let line = text.line(i); let line = text.line(i);
if let Some(pos) = helix_core::find_first_non_whitespace_char(line) { if let Some(pos) = helix_core::find_first_non_whitespace_char(line) {
let tab_and_indent_width: usize = 4;
let suggested_indent = treesitter_indent_for_pos( let suggested_indent = treesitter_indent_for_pos(
indent_query, indent_query,
&syntax, &syntax,
&IndentStyle::Spaces(4), &IndentStyle::Spaces(tab_and_indent_width as u8),
4, tab_and_indent_width,
tab_and_indent_width,
text, text,
i, i,
text.line_to_char(i) + pos, text.line_to_char(i) + pos,

@ -3364,8 +3364,8 @@ pub mod insert {
let count = cx.count(); let count = cx.count();
let (view, doc) = current_ref!(cx.editor); let (view, doc) = current_ref!(cx.editor);
let text = doc.text().slice(..); let text = doc.text().slice(..);
let indent_unit = doc.indent_style.as_str(); let tab_width = doc.tab_width();
let tab_size = doc.tab_width(); let indent_width = doc.indent_width();
let auto_pairs = doc.auto_pairs(cx.editor); let auto_pairs = doc.auto_pairs(cx.editor);
let transaction = let transaction =
@ -3386,18 +3386,11 @@ pub mod insert {
None, None,
) )
} else { } else {
let unit_len = indent_unit.chars().count();
// NOTE: indent_unit always contains 'only spaces' or 'only tab' according to `IndentStyle` definition.
let unit_size = if indent_unit.starts_with('\t') {
tab_size * unit_len
} else {
unit_len
};
let width: usize = fragment let width: usize = fragment
.chars() .chars()
.map(|ch| { .map(|ch| {
if ch == '\t' { if ch == '\t' {
tab_size tab_width
} else { } else {
// it can be none if it still meet control characters other than '\t' // it can be none if it still meet control characters other than '\t'
// here just set the width to 1 (or some value better?). // here just set the width to 1 (or some value better?).
@ -3405,9 +3398,9 @@ pub mod insert {
} }
}) })
.sum(); .sum();
let mut drop = width % unit_size; // round down to nearest unit let mut drop = width % indent_width; // round down to nearest unit
if drop == 0 { if drop == 0 {
drop = unit_size drop = indent_width
}; // if it's already at a unit, consume a whole unit }; // if it's already at a unit, consume a whole unit
let mut chars = fragment.chars().rev(); let mut chars = fragment.chars().rev();
let mut start = pos; let mut start = pos;
@ -3949,7 +3942,7 @@ fn unindent(cx: &mut Context) {
let lines = get_lines(doc, view.id); let lines = get_lines(doc, view.id);
let mut changes = Vec::with_capacity(lines.len()); let mut changes = Vec::with_capacity(lines.len());
let tab_width = doc.tab_width(); let tab_width = doc.tab_width();
let indent_width = count * tab_width; let indent_width = count * doc.indent_width();
for line_idx in lines { for line_idx in lines {
let line = doc.text().line(line_idx); let line = doc.text().line(line_idx);

@ -1122,13 +1122,18 @@ impl Document {
self.syntax.as_ref() self.syntax.as_ref()
} }
/// Tab size in columns. /// The width that the tab character is rendered at
pub fn tab_width(&self) -> usize { pub fn tab_width(&self) -> usize {
self.language_config() self.language_config()
.and_then(|config| config.indent.as_ref()) .and_then(|config| config.indent.as_ref())
.map_or(4, |config| config.tab_width) // fallback to 4 columns .map_or(4, |config| config.tab_width) // fallback to 4 columns
} }
// The width (in spaces) of a level of indentation.
pub fn indent_width(&self) -> usize {
self.indent_style.indent_width(self.tab_width())
}
pub fn changes(&self) -> &ChangeSet { pub fn changes(&self) -> &ChangeSet {
&self.changes &self.changes
} }

Loading…
Cancel
Save