Files
coop/crates/ui/src/input/display_map/display_map.rs
2026-07-30 08:47:30 +00:00

173 lines
5.1 KiB
Rust

use std::ops::Range;
use gpui::{App, Font, Pixels};
use ropey::Rope;
use super::text_wrapper::{LineItem, WrapDisplayPoint};
use super::wrap_map::WrapMap;
use crate::input::Point as TreeSitterPoint;
/// DisplayMap is the main interface for Input coordinate mapping.
pub struct DisplayMap {
wrap_map: WrapMap,
}
impl DisplayMap {
pub fn new(font: Font, font_size: Pixels, wrap_width: Option<Pixels>) -> Self {
Self {
wrap_map: WrapMap::new(font, font_size, wrap_width),
}
}
/// Get total number of display rows (same as wrap rows without folding)
#[inline]
pub fn display_row_count(&self) -> usize {
self.wrap_map.wrap_row_count()
}
/// Get the buffer line for a given display row
pub fn display_row_to_buffer_line(&self, display_row: usize) -> usize {
self.wrap_map.wrap_row_to_buffer_line(display_row)
}
/// Get the display row range for a buffer line: [start, end)
pub fn buffer_line_to_display_row_range(&self, line: usize) -> Option<Range<usize>> {
let range = self.wrap_map.buffer_line_to_wrap_row_range(line);
if range.is_empty() { None } else { Some(range) }
}
/// Check if a buffer line is completely hidden (never true without folding)
#[inline]
pub fn is_buffer_line_hidden(&self, _line: usize) -> bool {
false
}
/// All wrap rows are visible since there's no folding.
#[inline]
pub fn folded_ranges(&self) -> &[()] {
&[]
}
/// Adjust folds for edit (no-op without folding)
pub fn adjust_folds_for_edit(
&mut self,
_old_text: &Rope,
_range: &Range<usize>,
_new_text: &str,
) {
// No-op: no folding
}
/// Update text (incremental or full)
pub fn on_text_changed(
&mut self,
changed_text: &Rope,
range: &Range<usize>,
new_text: &Rope,
cx: &mut App,
) {
self.wrap_map
.on_text_changed(changed_text, range, new_text, cx);
}
/// Update layout parameters (wrap width or font)
pub fn on_layout_changed(&mut self, wrap_width: Option<Pixels>, cx: &mut App) {
self.wrap_map.on_layout_changed(wrap_width, cx);
}
/// Set font parameters
pub fn set_font(&mut self, font: Font, font_size: Pixels, cx: &mut App) {
self.wrap_map.set_font(font, font_size, cx);
}
/// Ensure text is prepared (initializes wrapper if needed)
pub fn ensure_text_prepared(&mut self, text: &Rope, cx: &mut App) {
self.wrap_map.ensure_text_prepared(text, cx);
}
/// Initialize with text
pub fn set_text(&mut self, text: &Rope, cx: &mut App) {
self.wrap_map.set_text(text, cx);
}
/// Convert byte offset to wrap display point (with soft wrap info).
#[inline]
pub(crate) fn offset_to_wrap_display_point(&self, offset: usize) -> WrapDisplayPoint {
self.wrap_map.wrapper().offset_to_display_point(offset)
}
/// Convert wrap display point to byte offset.
#[inline]
pub(crate) fn wrap_display_point_to_offset(&self, point: WrapDisplayPoint) -> usize {
self.wrap_map.wrapper().display_point_to_offset(point)
}
/// Convert wrap display point to TreeSitterPoint (buffer line/col).
#[inline]
pub(crate) fn wrap_display_point_to_point(&self, point: WrapDisplayPoint) -> TreeSitterPoint {
self.wrap_map.wrapper().display_point_to_point(point)
}
/// Since there's no folding, wrap row == display row.
#[inline]
pub fn wrap_row_to_display_row(&self, wrap_row: usize) -> Option<usize> {
if wrap_row < self.wrap_row_count() {
Some(wrap_row)
} else {
None
}
}
/// Since there's no folding, nearest visible row is the row itself.
#[inline]
pub fn nearest_visible_display_row(&self, wrap_row: usize) -> usize {
wrap_row.min(self.wrap_row_count().saturating_sub(1))
}
/// Since there's no folding, display row == wrap row.
#[inline]
pub fn display_row_to_wrap_row(&self, display_row: usize) -> Option<usize> {
if display_row < self.wrap_row_count() {
Some(display_row)
} else {
None
}
}
/// Get the longest row index (by byte length).
#[inline]
pub(crate) fn longest_row(&self) -> usize {
self.wrap_map.wrapper().longest_row.row
}
/// Get access to line items (for rendering)
#[inline]
pub(crate) fn lines(&self) -> &[LineItem] {
self.wrap_map.lines()
}
/// Get the rope text
#[inline]
pub fn text(&self) -> &Rope {
self.wrap_map.text()
}
/// Calculate how many wrap rows of a buffer line are visible
#[inline]
pub fn visible_wrap_row_count_for_buffer_line(&self, line: usize) -> usize {
self.wrap_map.visible_wrap_row_count_for_buffer_line(line)
}
/// Get the wrap row count
#[inline]
pub fn wrap_row_count(&self) -> usize {
self.wrap_map.wrap_row_count()
}
/// Get the buffer line count (logical lines)
#[inline]
pub fn buffer_line_count(&self) -> usize {
self.wrap_map.buffer_line_count()
}
}