Merge pull request #1404 from zed-industries/html-support
Basic html support
This commit is contained in:
commit
51fa06cc8d
29 changed files with 1538 additions and 623 deletions
|
@ -95,14 +95,15 @@ pub struct BufferSnapshot {
|
|||
parse_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
pub struct IndentSize {
|
||||
pub len: u32,
|
||||
pub kind: IndentKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
pub enum IndentKind {
|
||||
#[default]
|
||||
Space,
|
||||
Tab,
|
||||
}
|
||||
|
@ -247,7 +248,6 @@ pub enum AutoindentMode {
|
|||
struct AutoindentRequest {
|
||||
before_edit: BufferSnapshot,
|
||||
entries: Vec<AutoindentRequestEntry>,
|
||||
indent_size: IndentSize,
|
||||
is_block_mode: bool,
|
||||
}
|
||||
|
||||
|
@ -260,6 +260,7 @@ struct AutoindentRequestEntry {
|
|||
/// only be adjusted if the suggested indentation level has *changed*
|
||||
/// since the edit was made.
|
||||
first_line_is_new: bool,
|
||||
indent_size: IndentSize,
|
||||
original_indent_column: Option<u32>,
|
||||
}
|
||||
|
||||
|
@ -719,6 +720,16 @@ impl Buffer {
|
|||
self.language.as_ref()
|
||||
}
|
||||
|
||||
pub fn language_at<D: ToOffset>(&self, position: D) -> Option<Arc<Language>> {
|
||||
let offset = position.to_offset(self);
|
||||
self.syntax_map
|
||||
.lock()
|
||||
.layers_for_range(offset..offset, &self.text)
|
||||
.last()
|
||||
.map(|info| info.language.clone())
|
||||
.or_else(|| self.language.clone())
|
||||
}
|
||||
|
||||
pub fn parse_count(&self) -> usize {
|
||||
self.parse_count
|
||||
}
|
||||
|
@ -866,10 +877,13 @@ impl Buffer {
|
|||
// buffer before this batch of edits.
|
||||
let mut row_ranges = Vec::new();
|
||||
let mut old_to_new_rows = BTreeMap::new();
|
||||
let mut language_indent_sizes_by_new_row = Vec::new();
|
||||
for entry in &request.entries {
|
||||
let position = entry.range.start;
|
||||
let new_row = position.to_point(&snapshot).row;
|
||||
let new_end_row = entry.range.end.to_point(&snapshot).row + 1;
|
||||
language_indent_sizes_by_new_row.push((new_row, entry.indent_size));
|
||||
|
||||
if !entry.first_line_is_new {
|
||||
let old_row = position.to_point(&request.before_edit).row;
|
||||
old_to_new_rows.insert(old_row, new_row);
|
||||
|
@ -883,6 +897,8 @@ impl Buffer {
|
|||
let mut old_suggestions = BTreeMap::<u32, IndentSize>::default();
|
||||
let old_edited_ranges =
|
||||
contiguous_ranges(old_to_new_rows.keys().copied(), max_rows_between_yields);
|
||||
let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
|
||||
let mut language_indent_size = IndentSize::default();
|
||||
for old_edited_range in old_edited_ranges {
|
||||
let suggestions = request
|
||||
.before_edit
|
||||
|
@ -891,6 +907,17 @@ impl Buffer {
|
|||
.flatten();
|
||||
for (old_row, suggestion) in old_edited_range.zip(suggestions) {
|
||||
if let Some(suggestion) = suggestion {
|
||||
let new_row = *old_to_new_rows.get(&old_row).unwrap();
|
||||
|
||||
// Find the indent size based on the language for this row.
|
||||
while let Some((row, size)) = language_indent_sizes.peek() {
|
||||
if *row > new_row {
|
||||
break;
|
||||
}
|
||||
language_indent_size = *size;
|
||||
language_indent_sizes.next();
|
||||
}
|
||||
|
||||
let suggested_indent = old_to_new_rows
|
||||
.get(&suggestion.basis_row)
|
||||
.and_then(|from_row| old_suggestions.get(from_row).copied())
|
||||
|
@ -899,9 +926,8 @@ impl Buffer {
|
|||
.before_edit
|
||||
.indent_size_for_line(suggestion.basis_row)
|
||||
})
|
||||
.with_delta(suggestion.delta, request.indent_size);
|
||||
old_suggestions
|
||||
.insert(*old_to_new_rows.get(&old_row).unwrap(), suggested_indent);
|
||||
.with_delta(suggestion.delta, language_indent_size);
|
||||
old_suggestions.insert(new_row, suggested_indent);
|
||||
}
|
||||
}
|
||||
yield_now().await;
|
||||
|
@ -922,6 +948,8 @@ impl Buffer {
|
|||
|
||||
// Compute new suggestions for each line, but only include them in the result
|
||||
// if they differ from the old suggestion for that line.
|
||||
let mut language_indent_sizes = language_indent_sizes_by_new_row.iter().peekable();
|
||||
let mut language_indent_size = IndentSize::default();
|
||||
for new_edited_row_range in new_edited_row_ranges {
|
||||
let suggestions = snapshot
|
||||
.suggest_autoindents(new_edited_row_range.clone())
|
||||
|
@ -929,13 +957,22 @@ impl Buffer {
|
|||
.flatten();
|
||||
for (new_row, suggestion) in new_edited_row_range.zip(suggestions) {
|
||||
if let Some(suggestion) = suggestion {
|
||||
// Find the indent size based on the language for this row.
|
||||
while let Some((row, size)) = language_indent_sizes.peek() {
|
||||
if *row > new_row {
|
||||
break;
|
||||
}
|
||||
language_indent_size = *size;
|
||||
language_indent_sizes.next();
|
||||
}
|
||||
|
||||
let suggested_indent = indent_sizes
|
||||
.get(&suggestion.basis_row)
|
||||
.copied()
|
||||
.unwrap_or_else(|| {
|
||||
snapshot.indent_size_for_line(suggestion.basis_row)
|
||||
})
|
||||
.with_delta(suggestion.delta, request.indent_size);
|
||||
.with_delta(suggestion.delta, language_indent_size);
|
||||
if old_suggestions
|
||||
.get(&new_row)
|
||||
.map_or(true, |old_indentation| {
|
||||
|
@ -1266,7 +1303,6 @@ impl Buffer {
|
|||
let edit_id = edit_operation.local_timestamp();
|
||||
|
||||
if let Some((before_edit, mode)) = autoindent_request {
|
||||
let indent_size = before_edit.single_indent_size(cx);
|
||||
let (start_columns, is_block_mode) = match mode {
|
||||
AutoindentMode::Block {
|
||||
original_indent_columns: start_columns,
|
||||
|
@ -1315,6 +1351,7 @@ impl Buffer {
|
|||
AutoindentRequestEntry {
|
||||
first_line_is_new,
|
||||
original_indent_column: start_column,
|
||||
indent_size: before_edit.language_indent_size_at(range.start, cx),
|
||||
range: self.anchor_before(new_start + range_of_insertion_to_indent.start)
|
||||
..self.anchor_after(new_start + range_of_insertion_to_indent.end),
|
||||
}
|
||||
|
@ -1324,7 +1361,6 @@ impl Buffer {
|
|||
self.autoindent_requests.push(Arc::new(AutoindentRequest {
|
||||
before_edit,
|
||||
entries,
|
||||
indent_size,
|
||||
is_block_mode,
|
||||
}));
|
||||
}
|
||||
|
@ -1642,8 +1678,8 @@ impl BufferSnapshot {
|
|||
indent_size_for_line(self, row)
|
||||
}
|
||||
|
||||
pub fn single_indent_size(&self, cx: &AppContext) -> IndentSize {
|
||||
let language_name = self.language().map(|language| language.name());
|
||||
pub fn language_indent_size_at<T: ToOffset>(&self, position: T, cx: &AppContext) -> IndentSize {
|
||||
let language_name = self.language_at(position).map(|language| language.name());
|
||||
let settings = cx.global::<Settings>();
|
||||
if settings.hard_tabs(language_name.as_deref()) {
|
||||
IndentSize::tab()
|
||||
|
@ -1713,6 +1749,8 @@ impl BufferSnapshot {
|
|||
if capture.index == config.indent_capture_ix {
|
||||
start.get_or_insert(Point::from_ts_point(capture.node.start_position()));
|
||||
end.get_or_insert(Point::from_ts_point(capture.node.end_position()));
|
||||
} else if Some(capture.index) == config.start_capture_ix {
|
||||
start = Some(Point::from_ts_point(capture.node.end_position()));
|
||||
} else if Some(capture.index) == config.end_capture_ix {
|
||||
end = Some(Point::from_ts_point(capture.node.start_position()));
|
||||
}
|
||||
|
@ -1902,8 +1940,14 @@ impl BufferSnapshot {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn language(&self) -> Option<&Arc<Language>> {
|
||||
self.language.as_ref()
|
||||
pub fn language_at<D: ToOffset>(&self, position: D) -> Option<&Arc<Language>> {
|
||||
let offset = position.to_offset(self);
|
||||
self.syntax
|
||||
.layers_for_range(offset..offset, &self.text)
|
||||
.filter(|l| l.node.end_byte() > offset)
|
||||
.last()
|
||||
.map(|info| info.language)
|
||||
.or(self.language.as_ref())
|
||||
}
|
||||
|
||||
pub fn surrounding_word<T: ToOffset>(&self, start: T) -> (Range<usize>, Option<CharKind>) {
|
||||
|
@ -1938,8 +1982,8 @@ impl BufferSnapshot {
|
|||
pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
|
||||
let range = range.start.to_offset(self)..range.end.to_offset(self);
|
||||
let mut result: Option<Range<usize>> = None;
|
||||
'outer: for (_, _, node) in self.syntax.layers_for_range(range.clone(), &self.text) {
|
||||
let mut cursor = node.walk();
|
||||
'outer: for layer in self.syntax.layers_for_range(range.clone(), &self.text) {
|
||||
let mut cursor = layer.node.walk();
|
||||
|
||||
// Descend to the first leaf that touches the start of the range,
|
||||
// and if the range is non-empty, extends beyond the start.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue