Replace incorrect usages of tab_width with indent_width. (#5918)
This commit is contained in:
parent
d27e808fb3
commit
a1a6d5f334
4 changed files with 48 additions and 23 deletions
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,11 +46,13 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
|
|||
for i in 0..doc.len_lines() {
|
||||
let line = text.line(i);
|
||||
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(
|
||||
indent_query,
|
||||
&syntax,
|
||||
&IndentStyle::Spaces(4),
|
||||
4,
|
||||
&IndentStyle::Spaces(tab_and_indent_width as u8),
|
||||
tab_and_indent_width,
|
||||
tab_and_indent_width,
|
||||
text,
|
||||
i,
|
||||
text.line_to_char(i) + pos,
|
||||
|
|
|
@ -3364,8 +3364,8 @@ pub mod insert {
|
|||
let count = cx.count();
|
||||
let (view, doc) = current_ref!(cx.editor);
|
||||
let text = doc.text().slice(..);
|
||||
let indent_unit = doc.indent_style.as_str();
|
||||
let tab_size = doc.tab_width();
|
||||
let tab_width = doc.tab_width();
|
||||
let indent_width = doc.indent_width();
|
||||
let auto_pairs = doc.auto_pairs(cx.editor);
|
||||
|
||||
let transaction =
|
||||
|
@ -3386,18 +3386,11 @@ pub mod insert {
|
|||
None,
|
||||
)
|
||||
} 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
|
||||
.chars()
|
||||
.map(|ch| {
|
||||
if ch == '\t' {
|
||||
tab_size
|
||||
tab_width
|
||||
} else {
|
||||
// it can be none if it still meet control characters other than '\t'
|
||||
// here just set the width to 1 (or some value better?).
|
||||
|
@ -3405,9 +3398,9 @@ pub mod insert {
|
|||
}
|
||||
})
|
||||
.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 {
|
||||
drop = unit_size
|
||||
drop = indent_width
|
||||
}; // if it's already at a unit, consume a whole unit
|
||||
let mut chars = fragment.chars().rev();
|
||||
let mut start = pos;
|
||||
|
@ -3949,7 +3942,7 @@ fn unindent(cx: &mut Context) {
|
|||
let lines = get_lines(doc, view.id);
|
||||
let mut changes = Vec::with_capacity(lines.len());
|
||||
let tab_width = doc.tab_width();
|
||||
let indent_width = count * tab_width;
|
||||
let indent_width = count * doc.indent_width();
|
||||
|
||||
for line_idx in lines {
|
||||
let line = doc.text().line(line_idx);
|
||||
|
|
|
@ -1122,13 +1122,18 @@ impl Document {
|
|||
self.syntax.as_ref()
|
||||
}
|
||||
|
||||
/// Tab size in columns.
|
||||
/// The width that the tab character is rendered at
|
||||
pub fn tab_width(&self) -> usize {
|
||||
self.language_config()
|
||||
.and_then(|config| config.indent.as_ref())
|
||||
.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 {
|
||||
&self.changes
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue