Compare commits

..

5 commits

3 changed files with 90 additions and 4 deletions

View file

@ -245,3 +245,9 @@ pub fn nudge_delete(self: *Self, nudge: Selection) bool {
self.row -= nudge.end.row - nudge.begin.row; self.row -= nudge.end.row - nudge.begin.row;
return true; return true;
} }
pub fn within(self: *const Self, sel_: Selection) bool {
var sel = sel_;
sel.normalize();
return !sel.begin.right_of(self.*) and sel.end.right_of(self.*);
}

View file

@ -85,3 +85,53 @@ pub fn nudge_delete(self: *Self, nudge: Self) bool {
return false; return false;
return self.end.nudge_delete(nudge); 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;
}

View file

@ -242,6 +242,16 @@ pub const CurSel = struct {
return false; return false;
return self.cursor.nudge_delete(nudge); return self.cursor.nudge_delete(nudge);
} }
fn merge(self: *Self, other: Selection) bool {
if (self.selection) |*sel_| {
if (sel_.merge(other)) {
self.cursor = sel_.end;
return true;
}
}
return self.cursor.within(other);
}
}; };
pub const Diagnostic = struct { pub const Diagnostic = struct {
@ -1827,10 +1837,26 @@ pub const Editor = struct {
var old = self.cursels; var old = self.cursels;
defer old.deinit(self.allocator); defer old.deinit(self.allocator);
self.cursels = CurSel.List.initCapacity(self.allocator, old.items.len) catch return; self.cursels = CurSel.List.initCapacity(self.allocator, old.items.len) catch return;
for (old.items[0 .. old.items.len - 1], 0..) |*a_, i| if (a_.*) |*a| { var a_idx = old.items.len - 1;
for (old.items[i + 1 ..], i + 1..) |*b_, j| if (b_.*) |*b| { while (a_idx > 0) : (a_idx -= 1) if (old.items[a_idx]) |*a| {
if (a.cursor.eql(b.cursor)) var b_idx = a_idx - 1;
old.items[j] = null; while (true) : ({
if (b_idx == 0) break else b_idx -= 1;
}) if (old.items[b_idx]) |*b| {
const b_cursor = b.cursor;
if (b.selection) |b_sel| {
if (a.merge(b_sel)) {
old.items[b_idx] = null;
continue;
}
}
if (a.selection) |*a_sel| if (b_cursor.within(a_sel.*)) {
if (b.selection) |b_sel| a_sel.expand(b_sel);
old.items[b_idx] = null;
continue;
};
if (a.cursor.eql(b_cursor))
old.items[b_idx] = null;
}; };
}; };
for (old.items) |*item_| if (item_.*) |*item| { for (old.items) |*item_| if (item_.*) |*item| {
@ -2402,6 +2428,7 @@ pub const Editor = struct {
self.selection_mode = .char; self.selection_mode = .char;
try self.send_editor_jump_source(); try self.send_editor_jump_source();
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return; primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return;
self.collapse_cursors();
self.clamp_mouse(); self.clamp_mouse();
try self.send_editor_jump_destination(); try self.send_editor_jump_destination();
if (self.jump_mode) try self.goto_definition(.{}); if (self.jump_mode) try self.goto_definition(.{});
@ -2415,6 +2442,7 @@ pub const Editor = struct {
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return; primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return;
_ = try self.select_word_at_cursor(primary); _ = try self.select_word_at_cursor(primary);
self.selection_drag_initial = primary.selection; self.selection_drag_initial = primary.selection;
self.collapse_cursors();
self.clamp_mouse(); self.clamp_mouse();
} }
@ -2426,6 +2454,7 @@ pub const Editor = struct {
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return; primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return;
try self.select_line_at_cursor(root, primary, .exclude_eol); try self.select_line_at_cursor(root, primary, .exclude_eol);
self.selection_drag_initial = primary.selection; self.selection_drag_initial = primary.selection;
self.collapse_cursors();
self.clamp_mouse(); self.clamp_mouse();
} }
@ -2463,6 +2492,7 @@ pub const Editor = struct {
} }
primary.cursor = sel.end; primary.cursor = sel.end;
primary.check_selection(root, self.metrics); primary.check_selection(root, self.metrics);
self.collapse_cursors();
self.clamp_mouse(); self.clamp_mouse();
} }