tui/editor.zig: add disable_selection, and make check_selection play nice with inclusive selections
This commit is contained in:
parent
80c8795c3b
commit
a0f8d33781
1 changed files with 59 additions and 23 deletions
|
@ -130,12 +130,48 @@ pub const CurSel = struct {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_selection(self: *Self) void {
|
fn disable_selection(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) void {
|
||||||
if (self.selection) |sel| if (sel.empty()) {
|
switch (tui.current().get_selection_style()) {
|
||||||
|
.normal => self.disable_selection_normal(),
|
||||||
|
.inclusive => self.disable_selection_inclusive(root, metrics),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disable_selection_normal(self: *Self) void {
|
||||||
|
self.selection = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disable_selection_inclusive(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) void {
|
||||||
|
if (self.selection) |sel| {
|
||||||
|
if (!sel.is_reversed()) self.cursor.move_left(root, metrics) catch {};
|
||||||
self.selection = null;
|
self.selection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_selection(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) void {
|
||||||
|
switch (tui.current().get_selection_style()) {
|
||||||
|
.normal => self.check_selection_normal(),
|
||||||
|
.inclusive => self.check_selection_inclusive(root, metrics),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_selection_normal(self: *Self) void {
|
||||||
|
if (self.selection) |sel| if (sel.empty()) {
|
||||||
|
self.disable_selection_normal();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_selection_inclusive(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) void {
|
||||||
|
if (self.selection) |sel| if (sel.empty()) {
|
||||||
|
self.disable_selection_inclusive(root, metrics);
|
||||||
|
};
|
||||||
|
// if (self.selection) |*sel| {
|
||||||
|
// var temp = sel;
|
||||||
|
// if (!temp.is_reversed()) temp.end.move_left(root, metrics) catch {};
|
||||||
|
// if (temp.empty()) self.disable_selection_inclusive(root, metrics);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
fn expand_selection_to_line(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) !*Selection {
|
fn expand_selection_to_line(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) !*Selection {
|
||||||
const sel = try self.enable_selection(root, metrics);
|
const sel = try self.enable_selection(root, metrics);
|
||||||
sel.normalize();
|
sel.normalize();
|
||||||
|
@ -1603,7 +1639,7 @@ pub const Editor = struct {
|
||||||
|
|
||||||
fn cancel_all_selections(self: *Self) void {
|
fn cancel_all_selections(self: *Self) void {
|
||||||
var primary = self.get_primary().*;
|
var primary = self.get_primary().*;
|
||||||
primary.selection = null;
|
primary.disable_selection(self.buf_root() catch return, self.metrics);
|
||||||
self.cursels.clearRetainingCapacity();
|
self.cursels.clearRetainingCapacity();
|
||||||
self.cursels.addOneAssumeCapacity().* = primary;
|
self.cursels.addOneAssumeCapacity().* = primary;
|
||||||
for (self.matches.items) |*match_| if (match_.*) |*match| {
|
for (self.matches.items) |*match_| if (match_.*) |*match| {
|
||||||
|
@ -1632,7 +1668,7 @@ pub const Editor = struct {
|
||||||
|
|
||||||
fn with_cursors_const(self: *Self, root: Buffer.Root, move: cursor_operator_const) error{Stop}!void {
|
fn with_cursors_const(self: *Self, root: Buffer.Root, move: cursor_operator_const) error{Stop}!void {
|
||||||
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||||
cursel.selection = null;
|
cursel.disable_selection(root, self.metrics);
|
||||||
try with_cursor_const(root, move, cursel, self.metrics);
|
try with_cursor_const(root, move, cursel, self.metrics);
|
||||||
};
|
};
|
||||||
self.collapse_cursors();
|
self.collapse_cursors();
|
||||||
|
@ -1644,7 +1680,7 @@ pub const Editor = struct {
|
||||||
|
|
||||||
fn with_cursors_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: Context) error{Stop}!void {
|
fn with_cursors_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: Context) error{Stop}!void {
|
||||||
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||||
cursel.selection = null;
|
cursel.disable_selection(root, self.metrics);
|
||||||
try with_cursor_const_arg(root, move, cursel, ctx, self.metrics);
|
try with_cursor_const_arg(root, move, cursel, ctx, self.metrics);
|
||||||
};
|
};
|
||||||
self.collapse_cursors();
|
self.collapse_cursors();
|
||||||
|
@ -1671,7 +1707,7 @@ pub const Editor = struct {
|
||||||
fn with_cursors(self: *Self, root_: Buffer.Root, move: cursor_operator, allocator: Allocator) error{Stop}!Buffer.Root {
|
fn with_cursors(self: *Self, root_: Buffer.Root, move: cursor_operator, allocator: Allocator) error{Stop}!Buffer.Root {
|
||||||
var root = root_;
|
var root = root_;
|
||||||
for (self.cursels.items) |*cursel| {
|
for (self.cursels.items) |*cursel| {
|
||||||
cursel.selection = null;
|
self.selection(root, self.metrics);
|
||||||
root = try with_cursor(root, move, cursel, allocator);
|
root = try with_cursor(root, move, cursel, allocator);
|
||||||
}
|
}
|
||||||
self.collapse_cursors();
|
self.collapse_cursors();
|
||||||
|
@ -1682,7 +1718,7 @@ pub const Editor = struct {
|
||||||
const sel = try cursel.enable_selection(root, metrics);
|
const sel = try cursel.enable_selection(root, metrics);
|
||||||
try move(root, &sel.end, metrics);
|
try move(root, &sel.end, metrics);
|
||||||
cursel.cursor = sel.end;
|
cursel.cursor = sel.end;
|
||||||
cursel.check_selection();
|
cursel.check_selection(root, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_selections_const(self: *Self, root: Buffer.Root, move: cursor_operator_const) error{Stop}!void {
|
fn with_selections_const(self: *Self, root: Buffer.Root, move: cursor_operator_const) error{Stop}!void {
|
||||||
|
@ -1699,7 +1735,7 @@ pub const Editor = struct {
|
||||||
const sel = try cursel.enable_selection(root, metrics);
|
const sel = try cursel.enable_selection(root, metrics);
|
||||||
try move(root, &sel.end, ctx, metrics);
|
try move(root, &sel.end, ctx, metrics);
|
||||||
cursel.cursor = sel.end;
|
cursel.cursor = sel.end;
|
||||||
cursel.check_selection();
|
cursel.check_selection(root, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_selections_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: Context) error{Stop}!void {
|
fn with_selections_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: Context) error{Stop}!void {
|
||||||
|
@ -1796,7 +1832,7 @@ pub const Editor = struct {
|
||||||
var sel: Selection = cursel.selection orelse return error.Stop;
|
var sel: Selection = cursel.selection orelse return error.Stop;
|
||||||
sel.normalize();
|
sel.normalize();
|
||||||
cursel.cursor = sel.begin;
|
cursel.cursor = sel.begin;
|
||||||
cursel.selection = null;
|
cursel.disable_selection(root, self.metrics);
|
||||||
var size: usize = 0;
|
var size: usize = 0;
|
||||||
const root_ = try root.delete_range(sel, allocator, &size, self.metrics);
|
const root_ = try root.delete_range(sel, allocator, &size, self.metrics);
|
||||||
self.nudge_delete(sel, cursel, size);
|
self.nudge_delete(sel, cursel, size);
|
||||||
|
@ -2032,7 +2068,7 @@ pub const Editor = struct {
|
||||||
self.cancel_all_selections();
|
self.cancel_all_selections();
|
||||||
}
|
}
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
primary.selection = null;
|
primary.disable_selection(root, self.metrics);
|
||||||
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;
|
||||||
|
@ -2043,9 +2079,9 @@ pub const Editor = struct {
|
||||||
|
|
||||||
pub fn primary_double_click(self: *Self, y: c_int, x: c_int) !void {
|
pub fn primary_double_click(self: *Self, y: c_int, x: c_int) !void {
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
primary.selection = null;
|
|
||||||
self.selection_mode = .word;
|
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
|
primary.disable_selection(root, self.metrics);
|
||||||
|
self.selection_mode = .word;
|
||||||
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.clamp_mouse();
|
self.clamp_mouse();
|
||||||
|
@ -2053,9 +2089,9 @@ pub const Editor = struct {
|
||||||
|
|
||||||
pub fn primary_triple_click(self: *Self, y: c_int, x: c_int) !void {
|
pub fn primary_triple_click(self: *Self, y: c_int, x: c_int) !void {
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
primary.selection = null;
|
|
||||||
self.selection_mode = .line;
|
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
|
primary.disable_selection(root, self.metrics);
|
||||||
|
self.selection_mode = .line;
|
||||||
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(primary);
|
try self.select_line_at_cursor(primary);
|
||||||
self.clamp_mouse();
|
self.clamp_mouse();
|
||||||
|
@ -2082,7 +2118,7 @@ pub const Editor = struct {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
primary.cursor = sel.end;
|
primary.cursor = sel.end;
|
||||||
primary.check_selection();
|
primary.check_selection(root, self.metrics);
|
||||||
self.clamp_mouse();
|
self.clamp_mouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2758,7 +2794,7 @@ pub const Editor = struct {
|
||||||
fn dupe_cursel_up(self: *Self, root_: Buffer.Root, cursel: *CurSel, allocator: Allocator) error{Stop}!Buffer.Root {
|
fn dupe_cursel_up(self: *Self, root_: Buffer.Root, cursel: *CurSel, allocator: Allocator) error{Stop}!Buffer.Root {
|
||||||
var root = root_;
|
var root = root_;
|
||||||
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.metrics);
|
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.metrics);
|
||||||
cursel.selection = null;
|
cursel.disable_selection(root, self.metrics);
|
||||||
var sfa = std.heap.stackFallback(4096, self.allocator);
|
var sfa = std.heap.stackFallback(4096, self.allocator);
|
||||||
const text = copy_selection(root, sel, sfa.get(), self.metrics) catch return error.Stop;
|
const text = copy_selection(root, sel, sfa.get(), self.metrics) catch return error.Stop;
|
||||||
defer allocator.free(text);
|
defer allocator.free(text);
|
||||||
|
@ -2780,7 +2816,7 @@ pub const Editor = struct {
|
||||||
fn dupe_cursel_down(self: *Self, root_: Buffer.Root, cursel: *CurSel, allocator: Allocator) error{Stop}!Buffer.Root {
|
fn dupe_cursel_down(self: *Self, root_: Buffer.Root, cursel: *CurSel, allocator: Allocator) error{Stop}!Buffer.Root {
|
||||||
var root = root_;
|
var root = root_;
|
||||||
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.metrics);
|
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.metrics);
|
||||||
cursel.selection = null;
|
cursel.disable_selection(root, self.metrics);
|
||||||
var sfa = std.heap.stackFallback(4096, self.allocator);
|
var sfa = std.heap.stackFallback(4096, self.allocator);
|
||||||
const text = copy_selection(root, sel, sfa.get(), self.metrics) catch return error.Stop;
|
const text = copy_selection(root, sel, sfa.get(), self.metrics) catch return error.Stop;
|
||||||
defer allocator.free(text);
|
defer allocator.free(text);
|
||||||
|
@ -3248,7 +3284,7 @@ pub const Editor = struct {
|
||||||
fn select_word_at_cursor(self: *Self, cursel: *CurSel) !*Selection {
|
fn select_word_at_cursor(self: *Self, cursel: *CurSel) !*Selection {
|
||||||
const root = try self.buf_root();
|
const root = try self.buf_root();
|
||||||
const sel = try cursel.enable_selection(root, self.metrics);
|
const sel = try cursel.enable_selection(root, self.metrics);
|
||||||
defer cursel.check_selection();
|
defer cursel.check_selection(root, self.metrics);
|
||||||
sel.normalize();
|
sel.normalize();
|
||||||
try move_cursor_word_begin(root, &sel.begin, self.metrics);
|
try move_cursor_word_begin(root, &sel.begin, self.metrics);
|
||||||
try move_cursor_word_end(root, &sel.end, self.metrics);
|
try move_cursor_word_end(root, &sel.end, self.metrics);
|
||||||
|
@ -3298,7 +3334,7 @@ pub const Editor = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_node_at_cursor(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
fn select_node_at_cursor(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
cursel.selection = null;
|
cursel.disable_selection(root, self.metrics);
|
||||||
const sel = (try cursel.enable_selection(root, self.metrics)).*;
|
const sel = (try cursel.enable_selection(root, self.metrics)).*;
|
||||||
return cursel.select_node(try self.node_at_selection(sel, root, metrics), root, metrics);
|
return cursel.select_node(try self.node_at_selection(sel, root, metrics), root, metrics);
|
||||||
}
|
}
|
||||||
|
@ -3316,7 +3352,7 @@ pub const Editor = struct {
|
||||||
try self.send_editor_jump_source();
|
try self.send_editor_jump_source();
|
||||||
const root = try self.buf_root();
|
const root = try self.buf_root();
|
||||||
const cursel = self.get_primary();
|
const cursel = self.get_primary();
|
||||||
cursel.check_selection();
|
cursel.check_selection(root, self.metrics);
|
||||||
try if (cursel.selection) |_|
|
try if (cursel.selection) |_|
|
||||||
self.expand_selection_to_parent_node(root, cursel, self.metrics)
|
self.expand_selection_to_parent_node(root, cursel, self.metrics)
|
||||||
else
|
else
|
||||||
|
@ -3350,7 +3386,7 @@ pub const Editor = struct {
|
||||||
try self.send_editor_jump_source();
|
try self.send_editor_jump_source();
|
||||||
const root = try self.buf_root();
|
const root = try self.buf_root();
|
||||||
const cursel = self.get_primary();
|
const cursel = self.get_primary();
|
||||||
cursel.check_selection();
|
cursel.check_selection(root, self.metrics);
|
||||||
if (cursel.selection) |_|
|
if (cursel.selection) |_|
|
||||||
try if (unnamed)
|
try if (unnamed)
|
||||||
self.shrink_selection_to_child_node(root, cursel, self.metrics)
|
self.shrink_selection_to_child_node(root, cursel, self.metrics)
|
||||||
|
@ -3385,7 +3421,7 @@ pub const Editor = struct {
|
||||||
try self.send_editor_jump_source();
|
try self.send_editor_jump_source();
|
||||||
const root = try self.buf_root();
|
const root = try self.buf_root();
|
||||||
const cursel = self.get_primary();
|
const cursel = self.get_primary();
|
||||||
cursel.check_selection();
|
cursel.check_selection(root, self.metrics);
|
||||||
if (cursel.selection) |_|
|
if (cursel.selection) |_|
|
||||||
try if (unnamed)
|
try if (unnamed)
|
||||||
self.select_next_sibling_node(root, cursel, self.metrics)
|
self.select_next_sibling_node(root, cursel, self.metrics)
|
||||||
|
@ -3420,7 +3456,7 @@ pub const Editor = struct {
|
||||||
try self.send_editor_jump_source();
|
try self.send_editor_jump_source();
|
||||||
const root = try self.buf_root();
|
const root = try self.buf_root();
|
||||||
const cursel = self.get_primary();
|
const cursel = self.get_primary();
|
||||||
cursel.check_selection();
|
cursel.check_selection(root, self.metrics);
|
||||||
if (cursel.selection) |_|
|
if (cursel.selection) |_|
|
||||||
try if (unnamed)
|
try if (unnamed)
|
||||||
self.select_prev_sibling_node(root, cursel, self.metrics)
|
self.select_prev_sibling_node(root, cursel, self.metrics)
|
||||||
|
|
Loading…
Add table
Reference in a new issue