Add a ToPointUtf16 trait in text and multibuffer
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
16acbd2123
commit
4900019e9b
5 changed files with 144 additions and 18 deletions
|
@ -8,7 +8,7 @@ use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
|
||||||
pub use language::Completion;
|
pub use language::Completion;
|
||||||
use language::{
|
use language::{
|
||||||
Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language, Outline,
|
Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language, Outline,
|
||||||
OutlineItem, Selection, ToOffset as _, ToPoint as _, TransactionId,
|
OutlineItem, Selection, ToOffset as _, ToPoint as _, ToPointUtf16 as _, TransactionId,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Ref, RefCell},
|
cell::{Ref, RefCell},
|
||||||
|
@ -73,6 +73,10 @@ pub trait ToPoint: 'static + fmt::Debug {
|
||||||
fn to_point(&self, snapshot: &MultiBufferSnapshot) -> Point;
|
fn to_point(&self, snapshot: &MultiBufferSnapshot) -> Point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ToPointUtf16: 'static + fmt::Debug {
|
||||||
|
fn to_point_utf16(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16;
|
||||||
|
}
|
||||||
|
|
||||||
struct BufferState {
|
struct BufferState {
|
||||||
buffer: ModelHandle<Buffer>,
|
buffer: ModelHandle<Buffer>,
|
||||||
last_version: clock::Global,
|
last_version: clock::Global,
|
||||||
|
@ -1360,6 +1364,48 @@ impl MultiBufferSnapshot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn offset_to_point_utf16(&self, offset: usize) -> PointUtf16 {
|
||||||
|
if let Some(excerpt) = self.as_singleton() {
|
||||||
|
return excerpt.buffer.offset_to_point_utf16(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cursor = self.excerpts.cursor::<(usize, PointUtf16)>();
|
||||||
|
cursor.seek(&offset, Bias::Right, &());
|
||||||
|
if let Some(excerpt) = cursor.item() {
|
||||||
|
let (start_offset, start_point) = cursor.start();
|
||||||
|
let overshoot = offset - start_offset;
|
||||||
|
let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer);
|
||||||
|
let excerpt_start_point = excerpt.range.start.to_point_utf16(&excerpt.buffer);
|
||||||
|
let buffer_point = excerpt
|
||||||
|
.buffer
|
||||||
|
.offset_to_point_utf16(excerpt_start_offset + overshoot);
|
||||||
|
*start_point + (buffer_point - excerpt_start_point)
|
||||||
|
} else {
|
||||||
|
self.excerpts.summary().text.lines_utf16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn point_to_point_utf16(&self, point: Point) -> PointUtf16 {
|
||||||
|
if let Some(excerpt) = self.as_singleton() {
|
||||||
|
return excerpt.buffer.point_to_point_utf16(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cursor = self.excerpts.cursor::<(Point, PointUtf16)>();
|
||||||
|
cursor.seek(&point, Bias::Right, &());
|
||||||
|
if let Some(excerpt) = cursor.item() {
|
||||||
|
let (start_offset, start_point) = cursor.start();
|
||||||
|
let overshoot = point - start_offset;
|
||||||
|
let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer);
|
||||||
|
let excerpt_start_point_utf16 = excerpt.range.start.to_point_utf16(&excerpt.buffer);
|
||||||
|
let buffer_point = excerpt
|
||||||
|
.buffer
|
||||||
|
.point_to_point_utf16(excerpt_start_point + overshoot);
|
||||||
|
*start_point + (buffer_point - excerpt_start_point_utf16)
|
||||||
|
} else {
|
||||||
|
self.excerpts.summary().text.lines_utf16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn point_to_offset(&self, point: Point) -> usize {
|
pub fn point_to_offset(&self, point: Point) -> usize {
|
||||||
if let Some(excerpt) = self.as_singleton() {
|
if let Some(excerpt) = self.as_singleton() {
|
||||||
return excerpt.buffer.point_to_offset(point);
|
return excerpt.buffer.point_to_offset(point);
|
||||||
|
@ -2487,6 +2533,24 @@ impl ToPoint for Point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for usize {
|
||||||
|
fn to_point_utf16<'a>(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16 {
|
||||||
|
snapshot.offset_to_point_utf16(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for Point {
|
||||||
|
fn to_point_utf16<'a>(&self, snapshot: &MultiBufferSnapshot) -> PointUtf16 {
|
||||||
|
snapshot.point_to_point_utf16(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for PointUtf16 {
|
||||||
|
fn to_point_utf16<'a>(&self, _: &MultiBufferSnapshot) -> PointUtf16 {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn char_kind(c: char) -> CharKind {
|
pub fn char_kind(c: char) -> CharKind {
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
CharKind::Newline
|
CharKind::Newline
|
||||||
|
|
|
@ -7,19 +7,20 @@ pub mod proto;
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
pub use buffer::Operation;
|
|
||||||
pub use buffer::*;
|
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
pub use diagnostic_set::DiagnosticEntry;
|
|
||||||
use gpui::AppContext;
|
use gpui::AppContext;
|
||||||
use highlight_map::HighlightMap;
|
use highlight_map::HighlightMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
pub use outline::{Outline, OutlineItem};
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{cell::RefCell, ops::Range, path::Path, str, sync::Arc};
|
use std::{cell::RefCell, ops::Range, path::Path, str, sync::Arc};
|
||||||
use theme::SyntaxTheme;
|
use theme::SyntaxTheme;
|
||||||
use tree_sitter::{self, Query};
|
use tree_sitter::{self, Query};
|
||||||
|
|
||||||
|
pub use buffer::Operation;
|
||||||
|
pub use buffer::*;
|
||||||
|
pub use diagnostic_set::DiagnosticEntry;
|
||||||
|
pub use outline::{Outline, OutlineItem};
|
||||||
pub use tree_sitter::{Parser, Tree};
|
pub use tree_sitter::{Parser, Tree};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
@ -39,10 +40,6 @@ lazy_static! {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToPointUtf16 {
|
|
||||||
fn to_point_utf16(self) -> PointUtf16;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ToLspPosition {
|
pub trait ToLspPosition {
|
||||||
fn to_lsp_position(self) -> lsp::Position;
|
fn to_lsp_position(self) -> lsp::Position;
|
||||||
}
|
}
|
||||||
|
@ -386,18 +383,16 @@ impl LanguageServerConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToPointUtf16 for lsp::Position {
|
|
||||||
fn to_point_utf16(self) -> PointUtf16 {
|
|
||||||
PointUtf16::new(self.line, self.character)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToLspPosition for PointUtf16 {
|
impl ToLspPosition for PointUtf16 {
|
||||||
fn to_lsp_position(self) -> lsp::Position {
|
fn to_lsp_position(self) -> lsp::Position {
|
||||||
lsp::Position::new(self.row, self.column)
|
lsp::Position::new(self.row, self.column)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn point_from_lsp(point: lsp::Position) -> PointUtf16 {
|
||||||
|
PointUtf16::new(point.line, point.character)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn range_from_lsp(range: lsp::Range) -> Range<PointUtf16> {
|
pub fn range_from_lsp(range: lsp::Range) -> Range<PointUtf16> {
|
||||||
let start = PointUtf16::new(range.start.line, range.start.character);
|
let start = PointUtf16::new(range.start.line, range.start.character);
|
||||||
let end = PointUtf16::new(range.end.line, range.end.character);
|
let end = PointUtf16::new(range.end.line, range.end.character);
|
||||||
|
|
|
@ -13,9 +13,10 @@ use gpui::{
|
||||||
WeakModelHandle,
|
WeakModelHandle,
|
||||||
};
|
};
|
||||||
use language::{
|
use language::{
|
||||||
|
point_from_lsp,
|
||||||
proto::{deserialize_anchor, serialize_anchor},
|
proto::{deserialize_anchor, serialize_anchor},
|
||||||
range_from_lsp, Bias, Buffer, Diagnostic, DiagnosticEntry, File as _, Language,
|
range_from_lsp, Bias, Buffer, Diagnostic, DiagnosticEntry, File as _, Language,
|
||||||
LanguageRegistry, PointUtf16, ToOffset, ToPointUtf16,
|
LanguageRegistry, PointUtf16, ToOffset,
|
||||||
};
|
};
|
||||||
use lsp::{DiagnosticSeverity, LanguageServer};
|
use lsp::{DiagnosticSeverity, LanguageServer};
|
||||||
use postage::{prelude::Stream, watch};
|
use postage::{prelude::Stream, watch};
|
||||||
|
@ -1098,9 +1099,9 @@ impl Project {
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
let target_buffer = target_buffer_handle.read(cx);
|
let target_buffer = target_buffer_handle.read(cx);
|
||||||
let target_start = target_buffer
|
let target_start = target_buffer
|
||||||
.clip_point_utf16(target_range.start.to_point_utf16(), Bias::Left);
|
.clip_point_utf16(point_from_lsp(target_range.start), Bias::Left);
|
||||||
let target_end = target_buffer
|
let target_end = target_buffer
|
||||||
.clip_point_utf16(target_range.end.to_point_utf16(), Bias::Left);
|
.clip_point_utf16(point_from_lsp(target_range.end), Bias::Left);
|
||||||
definitions.push(Definition {
|
definitions.push(Definition {
|
||||||
target_buffer: target_buffer_handle,
|
target_buffer: target_buffer_handle,
|
||||||
target_range: target_buffer.anchor_after(target_start)
|
target_range: target_buffer.anchor_after(target_start)
|
||||||
|
|
|
@ -179,6 +179,19 @@ impl Rope {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn point_to_point_utf16(&self, point: Point) -> PointUtf16 {
|
||||||
|
if point >= self.summary().lines {
|
||||||
|
return self.summary().lines_utf16;
|
||||||
|
}
|
||||||
|
let mut cursor = self.chunks.cursor::<(Point, PointUtf16)>();
|
||||||
|
cursor.seek(&point, Bias::Left, &());
|
||||||
|
let overshoot = point - cursor.start().0;
|
||||||
|
cursor.start().1
|
||||||
|
+ cursor.item().map_or(PointUtf16::zero(), |chunk| {
|
||||||
|
chunk.point_to_point_utf16(overshoot)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn point_to_offset(&self, point: Point) -> usize {
|
pub fn point_to_offset(&self, point: Point) -> usize {
|
||||||
if point >= self.summary().lines {
|
if point >= self.summary().lines {
|
||||||
return self.summary().bytes;
|
return self.summary().bytes;
|
||||||
|
@ -580,6 +593,27 @@ impl Chunk {
|
||||||
offset
|
offset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn point_to_point_utf16(&self, target: Point) -> PointUtf16 {
|
||||||
|
let mut point = Point::zero();
|
||||||
|
let mut point_utf16 = PointUtf16::new(0, 0);
|
||||||
|
for ch in self.0.chars() {
|
||||||
|
if point >= target {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ch == '\n' {
|
||||||
|
point_utf16.row += 1;
|
||||||
|
point_utf16.column = 0;
|
||||||
|
point.row += 1;
|
||||||
|
point.column = 0;
|
||||||
|
} else {
|
||||||
|
point_utf16.column += ch.len_utf16() as u32;
|
||||||
|
point.column += ch.len_utf8() as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
point_utf16
|
||||||
|
}
|
||||||
|
|
||||||
fn point_utf16_to_offset(&self, target: PointUtf16) -> usize {
|
fn point_utf16_to_offset(&self, target: PointUtf16) -> usize {
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
let mut point = PointUtf16::new(0, 0);
|
let mut point = PointUtf16::new(0, 0);
|
||||||
|
|
|
@ -1512,6 +1512,10 @@ impl BufferSnapshot {
|
||||||
self.visible_text.offset_to_point_utf16(offset)
|
self.visible_text.offset_to_point_utf16(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn point_to_point_utf16(&self, point: Point) -> PointUtf16 {
|
||||||
|
self.visible_text.point_to_point_utf16(point)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn version(&self) -> &clock::Global {
|
pub fn version(&self) -> &clock::Global {
|
||||||
&self.version
|
&self.version
|
||||||
}
|
}
|
||||||
|
@ -2260,6 +2264,34 @@ impl ToPoint for Point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ToPointUtf16 {
|
||||||
|
fn to_point_utf16<'a>(&self, snapshot: &BufferSnapshot) -> PointUtf16;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for Anchor {
|
||||||
|
fn to_point_utf16<'a>(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
|
||||||
|
snapshot.summary_for_anchor(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for usize {
|
||||||
|
fn to_point_utf16<'a>(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
|
||||||
|
snapshot.offset_to_point_utf16(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for PointUtf16 {
|
||||||
|
fn to_point_utf16<'a>(&self, _: &BufferSnapshot) -> PointUtf16 {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for Point {
|
||||||
|
fn to_point_utf16<'a>(&self, snapshot: &BufferSnapshot) -> PointUtf16 {
|
||||||
|
snapshot.point_to_point_utf16(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Clip {
|
pub trait Clip {
|
||||||
fn clip(&self, bias: Bias, snapshot: &BufferSnapshot) -> Self;
|
fn clip(&self, bias: Bias, snapshot: &BufferSnapshot) -> Self;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue