multi_buffer: Typed MultiBufferOffset (#42707)
This PR introduces a new `MultiBufferOffset` new type wrapping size. The goal of this is to make it clear at the type level when we are interacting with offsets of a multi buffer versus offsets of a language / text buffer. This improves readability of things quite a bit by making it clear what kind of offsets one is working with while also reducing accidental bugs by using the wrong kin of offset for the wrong API. This PR also uncovered two minor bugs due to that. Does not yet introduce the MultiBufferPoint equivalent, that is for a follow up PR. Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
@@ -14,13 +14,12 @@ use collections::IndexMap;
|
||||
use dap::adapters::DebugAdapterName;
|
||||
use dap::{DapRegistry, StartDebuggingRequestArguments};
|
||||
use dap::{client::SessionId, debugger_settings::DebuggerSettings};
|
||||
use editor::Editor;
|
||||
use editor::{Editor, MultiBufferOffset, ToPoint};
|
||||
use gpui::{
|
||||
Action, App, AsyncWindowContext, ClipboardItem, Context, DismissEvent, Entity, EntityId,
|
||||
EventEmitter, FocusHandle, Focusable, MouseButton, MouseDownEvent, Point, Subscription, Task,
|
||||
WeakEntity, anchored, deferred,
|
||||
};
|
||||
use text::ToPoint as _;
|
||||
|
||||
use itertools::Itertools as _;
|
||||
use language::Buffer;
|
||||
@@ -1216,11 +1215,11 @@ impl DebugPanel {
|
||||
let mut last_offset = None;
|
||||
while let Some(mat) = matches.next() {
|
||||
if let Some(pos) = mat.captures.first().map(|m| m.node.byte_range().end) {
|
||||
last_offset = Some(pos)
|
||||
last_offset = Some(MultiBufferOffset(pos))
|
||||
}
|
||||
}
|
||||
let mut edits = Vec::new();
|
||||
let mut cursor_position = 0;
|
||||
let mut cursor_position = MultiBufferOffset(0);
|
||||
|
||||
if let Some(pos) = last_offset {
|
||||
edits.push((pos..pos, format!(",\n{new_scenario}")));
|
||||
@@ -1234,24 +1233,25 @@ impl DebugPanel {
|
||||
|
||||
if let Some(mat) = matches.next() {
|
||||
if let Some(pos) = mat.captures.first().map(|m| m.node.byte_range().end - 1) {
|
||||
edits.push((pos..pos, format!("\n{new_scenario}\n")));
|
||||
cursor_position = pos + "\n ".len();
|
||||
edits.push((
|
||||
MultiBufferOffset(pos)..MultiBufferOffset(pos),
|
||||
format!("\n{new_scenario}\n"),
|
||||
));
|
||||
cursor_position = MultiBufferOffset(pos) + "\n ".len();
|
||||
}
|
||||
} else {
|
||||
edits.push((0..0, format!("[\n{}\n]", new_scenario)));
|
||||
cursor_position = "[\n ".len();
|
||||
edits.push((
|
||||
MultiBufferOffset(0)..MultiBufferOffset(0),
|
||||
format!("[\n{}\n]", new_scenario),
|
||||
));
|
||||
cursor_position = MultiBufferOffset("[\n ".len());
|
||||
}
|
||||
}
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.edit(edits, cx);
|
||||
let snapshot = editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
.as_singleton()
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
.snapshot();
|
||||
let snapshot = editor.buffer().read(cx).read(cx);
|
||||
let point = cursor_position.to_point(&snapshot);
|
||||
drop(snapshot);
|
||||
editor.go_to_singleton_buffer_point(point, window, cx);
|
||||
});
|
||||
Ok(editor.save(SaveOptions::default(), project, window, cx))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::any::TypeId;
|
||||
|
||||
use debugger_panel::DebugPanel;
|
||||
use editor::Editor;
|
||||
use editor::{Editor, MultiBufferOffsetUtf16};
|
||||
use gpui::{Action, App, DispatchPhase, EntityInputHandler, actions};
|
||||
use new_process_modal::{NewProcessModal, NewProcessMode};
|
||||
use onboarding_modal::DebuggerOnboardingModal;
|
||||
@@ -390,11 +390,14 @@ pub fn init(cx: &mut App) {
|
||||
maybe!({
|
||||
let text = editor
|
||||
.update(cx, |editor, cx| {
|
||||
let range = editor
|
||||
.selections
|
||||
.newest::<MultiBufferOffsetUtf16>(
|
||||
&editor.display_snapshot(cx),
|
||||
)
|
||||
.range();
|
||||
editor.text_for_range(
|
||||
editor
|
||||
.selections
|
||||
.newest(&editor.display_snapshot(cx))
|
||||
.range(),
|
||||
range.start.0.0..range.end.0.0,
|
||||
&mut None,
|
||||
window,
|
||||
cx,
|
||||
|
||||
@@ -8,7 +8,7 @@ use collections::HashMap;
|
||||
use dap::{CompletionItem, CompletionItemType, OutputEvent};
|
||||
use editor::{
|
||||
Bias, CompletionProvider, Editor, EditorElement, EditorMode, EditorStyle, ExcerptId,
|
||||
SizingBehavior,
|
||||
MultiBufferOffset, SizingBehavior,
|
||||
};
|
||||
use fuzzy::StringMatchCandidate;
|
||||
use gpui::{
|
||||
@@ -161,7 +161,9 @@ impl Console {
|
||||
) -> Task<Result<()>> {
|
||||
self.console.update(cx, |_, cx| {
|
||||
cx.spawn_in(window, async move |console, cx| {
|
||||
let mut len = console.update(cx, |this, cx| this.buffer().read(cx).len(cx))?;
|
||||
let mut len = console
|
||||
.update(cx, |this, cx| this.buffer().read(cx).len(cx))?
|
||||
.0;
|
||||
let (output, spans, background_spans) = cx
|
||||
.background_spawn(async move {
|
||||
let mut all_spans = Vec::new();
|
||||
@@ -227,8 +229,8 @@ impl Console {
|
||||
for (range, color) in spans {
|
||||
let Some(color) = color else { continue };
|
||||
let start_offset = range.start;
|
||||
let range =
|
||||
buffer.anchor_after(range.start)..buffer.anchor_before(range.end);
|
||||
let range = buffer.anchor_after(MultiBufferOffset(range.start))
|
||||
..buffer.anchor_before(MultiBufferOffset(range.end));
|
||||
let style = HighlightStyle {
|
||||
color: Some(terminal_view::terminal_element::convert_color(
|
||||
&color,
|
||||
@@ -247,8 +249,8 @@ impl Console {
|
||||
for (range, color) in background_spans {
|
||||
let Some(color) = color else { continue };
|
||||
let start_offset = range.start;
|
||||
let range =
|
||||
buffer.anchor_after(range.start)..buffer.anchor_before(range.end);
|
||||
let range = buffer.anchor_after(MultiBufferOffset(range.start))
|
||||
..buffer.anchor_before(MultiBufferOffset(range.end));
|
||||
console.highlight_background_key::<ConsoleAnsiHighlight>(
|
||||
start_offset,
|
||||
&[range],
|
||||
@@ -961,7 +963,7 @@ fn color_fetcher(color: ansi::Color) -> fn(&Theme) -> Hsla {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::tests::init_test;
|
||||
use editor::test::editor_test_context::EditorTestContext;
|
||||
use editor::{MultiBufferOffset, test::editor_test_context::EditorTestContext};
|
||||
use gpui::TestAppContext;
|
||||
use language::Point;
|
||||
|
||||
@@ -993,8 +995,8 @@ mod tests {
|
||||
cx.update_editor(|editor, _, cx| {
|
||||
editor.edit(
|
||||
vec![(
|
||||
snapshot.offset_for_anchor(&replace_range.start)
|
||||
..snapshot.offset_for_anchor(&replace_range.end),
|
||||
MultiBufferOffset(snapshot.offset_for_anchor(&replace_range.start))
|
||||
..MultiBufferOffset(snapshot.offset_for_anchor(&replace_range.end)),
|
||||
replacement,
|
||||
)],
|
||||
cx,
|
||||
|
||||
Reference in New Issue
Block a user