Having inclusive mode change a few critical functions behind the sceans is not a good way to share functionality. Basically every function is broken in one or the other mode. So we remove it entirely and instead will rely on different functions for different behaviors.
152 lines
4.2 KiB
Zig
152 lines
4.2 KiB
Zig
const cbor = @import("cbor");
|
|
const Writer = @import("std").Io.Writer;
|
|
|
|
const Buffer = @import("Buffer.zig");
|
|
const Cursor = @import("Cursor.zig");
|
|
|
|
begin: Cursor = Cursor{},
|
|
end: Cursor = Cursor{},
|
|
|
|
const Self = @This();
|
|
|
|
pub inline fn eql(self: Self, other: Self) bool {
|
|
return self.begin.eql(other.begin) and self.end.eql(other.end);
|
|
}
|
|
|
|
pub fn from_cursor(cursor: *const Cursor) Self {
|
|
return .{ .begin = cursor.*, .end = cursor.* };
|
|
}
|
|
|
|
pub fn from_cursor_inclusive(cursor: *const Cursor, root: Buffer.Root, metrics: Buffer.Metrics) Self {
|
|
var sel: Self = .{ .begin = cursor.*, .end = cursor.* };
|
|
sel.end.move_right(root, metrics) catch {};
|
|
return sel;
|
|
}
|
|
|
|
pub fn from_pos(sel: Self, root: Buffer.Root, metrics: Buffer.Metrics) Self {
|
|
return .{
|
|
.begin = .{
|
|
.row = sel.begin.row,
|
|
.col = root.pos_to_width(sel.begin.row, sel.begin.col, metrics) catch root.line_width(sel.begin.row, metrics) catch 0,
|
|
},
|
|
.end = .{
|
|
.row = sel.end.row,
|
|
.col = root.pos_to_width(sel.end.row, sel.end.col, metrics) catch root.line_width(sel.end.row, metrics) catch 0,
|
|
},
|
|
};
|
|
}
|
|
|
|
pub fn from_range(range: anytype, root: Buffer.Root, metrics: Buffer.Metrics) Self {
|
|
return from_pos(from_range_raw(range), root, metrics);
|
|
}
|
|
|
|
pub fn from_range_raw(range: anytype) Self {
|
|
return .{
|
|
.begin = .{ .row = range.start_point.row, .col = range.start_point.column },
|
|
.end = .{ .row = range.end_point.row, .col = range.end_point.column },
|
|
};
|
|
}
|
|
|
|
pub fn line_from_cursor(cursor: Cursor, root: Buffer.Root, mtrx: Buffer.Metrics) Self {
|
|
var begin = cursor;
|
|
var end = cursor;
|
|
begin.move_begin();
|
|
end.move_end(root, mtrx);
|
|
end.move_right(root, mtrx) catch {};
|
|
return .{ .begin = begin, .end = end };
|
|
}
|
|
|
|
pub fn empty(self: *const Self) bool {
|
|
return self.begin.eql(self.end);
|
|
}
|
|
|
|
pub fn reverse(self: *Self) void {
|
|
const tmp = self.begin;
|
|
self.begin = self.end;
|
|
self.end = tmp;
|
|
}
|
|
|
|
pub inline fn is_reversed(self: *const Self) bool {
|
|
return self.begin.right_of(self.end);
|
|
}
|
|
|
|
pub fn normalize(self: *Self) void {
|
|
if (self.is_reversed()) self.reverse();
|
|
}
|
|
|
|
pub fn write(self: *const Self, writer: *Writer) !void {
|
|
try cbor.writeArrayHeader(writer, 2);
|
|
try self.begin.write(writer);
|
|
try self.end.write(writer);
|
|
}
|
|
|
|
pub fn extract(self: *Self, iter: *[]const u8) !bool {
|
|
var iter2 = iter.*;
|
|
const len = cbor.decodeArrayHeader(&iter2) catch return false;
|
|
if (len != 2) return false;
|
|
if (!try self.begin.extract(&iter2)) return false;
|
|
if (!try self.end.extract(&iter2)) return false;
|
|
iter.* = iter2;
|
|
return true;
|
|
}
|
|
|
|
pub fn nudge_insert(self: *Self, nudge: Self) void {
|
|
self.begin.nudge_insert(nudge);
|
|
self.end.nudge_insert(nudge);
|
|
}
|
|
|
|
pub fn nudge_delete(self: *Self, nudge: Self) bool {
|
|
if (!self.begin.nudge_delete(nudge))
|
|
return false;
|
|
return self.end.nudge_delete(nudge);
|
|
}
|
|
|
|
pub fn merge(self: *Self, other_: Self) bool {
|
|
var other = other_;
|
|
other.normalize();
|
|
if (self.is_reversed()) {
|
|
var this = self.*;
|
|
this.normalize();
|
|
if (this.merge_normal(other)) {
|
|
self.begin = this.end;
|
|
self.end = this.begin;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
return self.merge_normal(other);
|
|
}
|
|
|
|
fn merge_normal(self: *Self, other: Self) bool {
|
|
var merged = false;
|
|
if (self.begin.within(other)) {
|
|
self.begin = other.begin;
|
|
merged = true;
|
|
}
|
|
if (self.end.within(other)) {
|
|
self.end = other.end;
|
|
merged = true;
|
|
}
|
|
return merged or
|
|
(other.begin.right_of(self.begin) and
|
|
self.end.right_of(other.end));
|
|
}
|
|
|
|
pub fn expand(self: *Self, other_: Self) void {
|
|
var other = other_;
|
|
other.normalize();
|
|
if (self.is_reversed()) {
|
|
var this = self.*;
|
|
this.normalize();
|
|
this.expand_normal(other);
|
|
self.begin = this.end;
|
|
self.end = this.begin;
|
|
} else self.expand_normal(other);
|
|
}
|
|
|
|
fn expand_normal(self: *Self, other: Self) void {
|
|
if (self.begin.right_of(other.begin))
|
|
self.begin = other.begin;
|
|
if (other.end.right_of(self.end))
|
|
self.end = other.end;
|
|
}
|