Compare commits
25 commits
master
...
helix-refa
| Author | SHA1 | Date | |
|---|---|---|---|
| b5e1cce4b3 | |||
| a779c590bd | |||
| f964296051 | |||
| c65a4af30a | |||
| 0ca1d372f6 | |||
| d410fabf1b | |||
| eba444c6fc | |||
| faa54afb8b | |||
| 839f1b8e38 | |||
| 2b27ef3332 | |||
| 0cba416ec4 | |||
| 5f242d6cf2 | |||
| 66f8819a19 | |||
| 8d8f4b82cb | |||
| dd88be893e | |||
| c65583b1ae | |||
| 0ab260a165 | |||
| 7bf532bdfd | |||
| 1755ecb3dd | |||
| a15ceeb4a7 | |||
| 1615cd37e8 | |||
| bb53ba0fc1 | |||
| 3db11a43c9 | |||
| 77b2afdd0c | |||
| 7410435c4f |
13 changed files with 773 additions and 697 deletions
|
|
@ -193,10 +193,39 @@ pub fn egc_at(self: *const Self, root: Buffer.Root, metrics: Metrics) error{NotF
|
|||
return root.egc_at(self.row, self.col, metrics);
|
||||
}
|
||||
|
||||
pub fn char_at(self: *const Self, root: Buffer.Root, metrics: Metrics) []const u8 {
|
||||
const char, _, _ = root.egc_at(self.row, self.col, metrics) catch return &.{};
|
||||
return char;
|
||||
}
|
||||
|
||||
pub fn char_left(self: *const Self, root: Buffer.Root, metrics: Metrics) []const u8 {
|
||||
var tmp = self.*;
|
||||
tmp.move_left(root, metrics) catch return &.{};
|
||||
return tmp.char_at(root, metrics);
|
||||
}
|
||||
|
||||
pub fn char_right(self: *const Self, root: Buffer.Root, metrics: Metrics) []const u8 {
|
||||
var tmp = self.*;
|
||||
tmp.move_right(root, metrics) catch return &.{};
|
||||
return tmp.char_at(root, metrics);
|
||||
}
|
||||
|
||||
pub fn test_at(self: *const Self, root: Buffer.Root, pred: *const fn (c: []const u8) bool, metrics: Metrics) bool {
|
||||
return root.test_at(pred, self.row, self.col, metrics);
|
||||
}
|
||||
|
||||
pub fn test_left(self: *const Self, root: Buffer.Root, pred: *const fn (c: []const u8) bool, metrics: Metrics) bool {
|
||||
var tmp = self.*;
|
||||
tmp.move_left(root, metrics) catch return false;
|
||||
return root.test_at(pred, tmp.row, tmp.col, metrics);
|
||||
}
|
||||
|
||||
pub fn test_right(self: *const Self, root: Buffer.Root, pred: *const fn (c: []const u8) bool, metrics: Metrics) bool {
|
||||
var tmp = self.*;
|
||||
tmp.move_right(root, metrics) catch return false;
|
||||
return root.test_at(pred, tmp.row, tmp.col, metrics);
|
||||
}
|
||||
|
||||
pub fn write(self: *const Self, writer: *std.Io.Writer) !void {
|
||||
try cbor.writeValue(writer, .{
|
||||
self.row,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ end: Cursor = Cursor{},
|
|||
|
||||
const Self = @This();
|
||||
|
||||
pub const Style = enum { normal, inclusive };
|
||||
|
||||
pub inline fn eql(self: Self, other: Self) bool {
|
||||
return self.begin.eql(other.begin) and self.end.eql(other.end);
|
||||
}
|
||||
|
|
@ -19,6 +17,12 @@ 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 = .{
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
["ctrl+shift+p", "open_command_palette"],
|
||||
["ctrl+shift+q", "quit_without_saving"],
|
||||
["ctrl+shift+f", "find_in_files"],
|
||||
["ctrl+shift+l", "toggle_panel"],
|
||||
["alt+shift+p", "open_command_palette"],
|
||||
["alt+n", "goto_next_file_or_diagnostic"],
|
||||
["alt+p", "goto_prev_file_or_diagnostic"],
|
||||
|
|
@ -410,8 +409,6 @@
|
|||
["ctrl+shift+p", "palette_menu_down"],
|
||||
["ctrl+shift+q", "quit_without_saving"],
|
||||
["ctrl+shift+w", "close_file_without_saving"],
|
||||
["ctrl+shift+l", "overlay_toggle_panel"],
|
||||
["ctrl+shift+i", "overlay_toggle_inputview"],
|
||||
["alt+shift+p", "palette_menu_down"],
|
||||
["alt+p", "palette_menu_up"],
|
||||
["alt+l", "toggle_panel"],
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
"name": "NOR",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"selection": "inclusive",
|
||||
"press": [
|
||||
["ctrl+b", "move_scroll_page_up"],
|
||||
["ctrl+f", "move_scroll_page_down"],
|
||||
|
|
@ -22,29 +21,29 @@
|
|||
["ctrl+i", "jump_forward"],
|
||||
["ctrl+o", "jump_back"],
|
||||
["ctrl+s", "save_selection"],
|
||||
["ctrl+a", "increment"],
|
||||
["ctrl+x", "decrement"],
|
||||
["ctrl+a", "increment-NOIMPL"],
|
||||
["ctrl+x", "decrement-NOIMPL"],
|
||||
|
||||
["ctrl+^", "open_previous_file"],
|
||||
["ctrl+w v", "add_split"],
|
||||
["ctrl+w c", "toggle_centered_view"],
|
||||
["ctrl+w h", "goto_left_split"],
|
||||
["ctrl+w l", "goto_right_split"],
|
||||
["ctrl+w H", "swap_left_split"],
|
||||
["ctrl+w L", "swap_right_split"],
|
||||
["ctrl+w F", "goto_file_split"],
|
||||
["ctrl+w h", "goto_left_split-NOIMPL"],
|
||||
["ctrl+w l", "goto_right_split-NOIMPL"],
|
||||
["ctrl+w H", "swap_left_split-NOIMPL"],
|
||||
["ctrl+w L", "swap_right_split-NOIMPL"],
|
||||
["ctrl+w F", "goto_file_split-NOIMPL"],
|
||||
["ctrl+w q", "close_split"],
|
||||
["ctrl+w o", "close_other_splits"],
|
||||
["ctrl+w o", "close_other_splits-NOIMPL"],
|
||||
|
||||
["alt+.", "repeat_last_motion"],
|
||||
["alt+.", "repeat_last_motion-NOIMPL"],
|
||||
["alt+d", "delete_backward"],
|
||||
["alt+c", "change_backward_helix"],
|
||||
["alt+c", "change_backward_helix-NOIMPL"],
|
||||
|
||||
["alt+s", "split_selection_on_newline"],
|
||||
["alt+-", "merge_selections"],
|
||||
["alt+_", "merge_consecutive_selections"],
|
||||
["alt+-", "merge_selections-NOIMPL"],
|
||||
["alt+_", "merge_consecutive_selections-NOIMPL"],
|
||||
|
||||
["alt+;", "flip_selections"],
|
||||
["alt+;", "flip_selections-NOIMPL"],
|
||||
["alt+o", "expand_selection"],
|
||||
["alt+up", "expand_selection"],
|
||||
["alt+kp_up", "expand_selection"],
|
||||
|
|
@ -58,22 +57,23 @@
|
|||
["alt+right", "select_next_sibling"],
|
||||
["alt+kp_right", "select_next_sibling"],
|
||||
|
||||
["alt+e", "move_parent_node_end"],
|
||||
["alt+b", "move_parent_node_start"],
|
||||
["alt+a", "select_all_siblings"],
|
||||
["alt+e", "move_parent_node_end-NOIMPL"],
|
||||
["alt+b", "move_parent_node_start-NOIMPL"],
|
||||
["alt+a", "select_all_siblings-NOIMPL"],
|
||||
|
||||
["alt+x", "shrink_to_line_bounds"],
|
||||
["alt+x", "shrink_to_line_bounds-NOIMPL"],
|
||||
["alt+u", "undo"],
|
||||
["alt+,", "remove_primary_selection"],
|
||||
["alt+,", "remove_primary_selection-NOIMPL"],
|
||||
|
||||
["alt+C", "copy_selection_on_next_line"],
|
||||
["alt+I", "select_all_children"],
|
||||
["alt+shift+down", "select_all_children"],
|
||||
["alt+C", "copy_selection_on_next_line-NOIMPL"],
|
||||
["alt+I", "select_all_children-NOIMPL"],
|
||||
["alt+shift+down", "select_all_children-NOIMPL"],
|
||||
["alt+U", "redo"],
|
||||
["alt+J", "join_selections_space"],
|
||||
["alt+(", "rotate_selection_contents_backward"], ["alt+)", "rotate_selection_contents_forward"],
|
||||
["alt+|", "shell_pipe_to"],
|
||||
["alt+!", "shell_append_output"],
|
||||
["alt+J", "join_selections_space-NOIMPL"],
|
||||
["alt+(", "rotate_selection_contents_backward-NOIMPL"],
|
||||
["alt+)", "rotate_selection_contents_forward-NOIMPL"],
|
||||
["alt+|", "shell_pipe_to-NOIMPL"],
|
||||
["alt+!", "shell_append_output-NOIMPL"],
|
||||
|
||||
["F", "move_to_char", "select_to_char_left_helix"],
|
||||
["T", "move_to_char", "select_till_char_left_helix"],
|
||||
|
|
@ -93,10 +93,10 @@
|
|||
["C", "add_cursor_down"],
|
||||
|
||||
["S", "split_selection"],
|
||||
["X", "extend_to_line_bounds"],
|
||||
["?", "rfind"],
|
||||
["X", "extend_to_line_bounds-NOIMPL"],
|
||||
["?", "rfind-NOIMPL"],
|
||||
["N", "goto_prev_match"],
|
||||
["*", "search_selection"],
|
||||
["*", "search_selection-NOIMPL"],
|
||||
|
||||
["~", "switch_case"],
|
||||
["`", "to_lower"],
|
||||
|
|
@ -110,20 +110,20 @@
|
|||
[">", "indent"],
|
||||
["<", "unindent"],
|
||||
|
||||
["J", "join_selections"],
|
||||
["J", "join_selections-NOIMPL"],
|
||||
|
||||
[":", "open_command_palette"],
|
||||
|
||||
["&", "align_selections"],
|
||||
["_", "trim_selections"],
|
||||
["&", "align_selections-NOIMPL"],
|
||||
["_", "trim_selections-NOIMPL"],
|
||||
|
||||
["(", "rotate_selections_backward"],
|
||||
[")", "rotate_selections_forward"],
|
||||
["(", "rotate_selections_backward-NOIMPL"],
|
||||
[")", "rotate_selections_forward-NOIMPL"],
|
||||
|
||||
["\"", "select_register"],
|
||||
["|", "shell_pipe"],
|
||||
["!", "shell_insert_output"],
|
||||
["$", "shell_keep_pipe"],
|
||||
["\"", "select_register-NOIMPL"],
|
||||
["|", "shell_pipe-NOIMPL"],
|
||||
["!", "shell_insert_output-NOIMPL"],
|
||||
["$", "shell_keep_pipe-NOIMPL"],
|
||||
|
||||
["h", "move_left"],
|
||||
["j", "move_down"],
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
["v", "enter_mode", "select"],
|
||||
|
||||
["G", "goto_line"],
|
||||
["g g", "goto_line_vim"],
|
||||
["g g", "goto_line_helix"],
|
||||
["g e", "move_buffer_end"],
|
||||
["g f", "goto_file"],
|
||||
["g h", "move_begin"],
|
||||
|
|
@ -281,8 +281,7 @@
|
|||
"name": "SEL",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"selection": "inclusive",
|
||||
"init_command": ["enable_selection"],
|
||||
"init_command": ["init_helix_select_mode"],
|
||||
"press": [
|
||||
|
||||
["ctrl+b", "select_page_up"],
|
||||
|
|
@ -431,9 +430,9 @@
|
|||
["kp_end", "extend_to_line_end"],
|
||||
["v", "enter_mode", "normal"],
|
||||
|
||||
["g g", "goto_line_vim"],
|
||||
["g g", "goto_line_helix"],
|
||||
["g e", "move_buffer_end"],
|
||||
["g f", "goto_file"],
|
||||
["g f", "goto_file-NOIMPL"],
|
||||
["g h", "move_begin"],
|
||||
["g l", "select_end"],
|
||||
["g s", "smart_move_begin"],
|
||||
|
|
@ -441,16 +440,16 @@
|
|||
["g y", "goto_type_definition"],
|
||||
["g r", "references"],
|
||||
["g i", "goto_implementation"],
|
||||
["g t", "goto_window_top"],
|
||||
["g c", "goto_window_center"],
|
||||
["g b", "goto_window_bottom"],
|
||||
["g t", "goto_window_top-NOIMPL"],
|
||||
["g c", "goto_window_center-NOIMPL"],
|
||||
["g b", "goto_window_bottom-NOIMPL"],
|
||||
["g a", "open_previous_file"],
|
||||
["g m", "open_most_recent_file"],
|
||||
["g n", "goto_next_buffer"],
|
||||
["g p", "goto_previous_buffer"],
|
||||
["g k", "goto_previous_buffer"],
|
||||
["g .", "goto_last_modification"],
|
||||
["g w", "goto_word"],
|
||||
["g n", "goto_next_buffer-NOIMPL"],
|
||||
["g p", "goto_previous_buffer-NOIMPL"],
|
||||
["g k", "goto_previous_buffer-NOIMPL"],
|
||||
["g .", "goto_last_modification-NOIMPL"],
|
||||
["g w", "goto_word-NOIMPL"],
|
||||
["g D", "goto_declaration"],
|
||||
|
||||
["i", "enter_mode", "insert"],
|
||||
|
|
@ -460,8 +459,8 @@
|
|||
["d", ["cut"], ["enter_mode", "normal"]],
|
||||
["c", ["enter_mode", "insert"], ["cut"]],
|
||||
|
||||
["s", "select_regex"],
|
||||
[";", "collapse_selections"],
|
||||
["s", "select_regex-NOIMPL"],
|
||||
[";", "collapse_selections-NOIMPL"],
|
||||
|
||||
["x", "extend_line_below"],
|
||||
|
||||
|
|
@ -472,32 +471,32 @@
|
|||
["m r", "match", "surround_replace"],
|
||||
["m s", "match", "surround_add"],
|
||||
|
||||
["[ D", "goto_first_diag"],
|
||||
["[ G", "goto_first_change"],
|
||||
["[ T", "goto_prev_test"],
|
||||
["[ D", "goto_first_diag-NOIMPL"],
|
||||
["[ G", "goto_first_change-NOIMPL"],
|
||||
["[ T", "goto_prev_test-NOIMPL"],
|
||||
|
||||
["[ d", "goto_prev_diagnostic"],
|
||||
["[ g", "goto_prev_change"],
|
||||
["[ f", "goto_prev_function"],
|
||||
["[ t", "goto_prev_class"],
|
||||
["[ a", "goto_prev_parameter"],
|
||||
["[ c", "goto_prev_comment"],
|
||||
["[ e", "goto_prev_entry"],
|
||||
["[ p", "goto_prev_paragraph"],
|
||||
["[ space", "add_newline_above"],
|
||||
["[ g", "goto_prev_change-NOIMPL"],
|
||||
["[ f", "goto_prev_function-NOIMPL"],
|
||||
["[ t", "goto_prev_class-NOIMPL"],
|
||||
["[ a", "goto_prev_parameter-NOIMPL"],
|
||||
["[ c", "goto_prev_comment-NOIMPL"],
|
||||
["[ e", "goto_prev_entry-NOIMPL"],
|
||||
["[ p", "goto_prev_paragraph-NOIMPL"],
|
||||
["[ space", "add_newline_above-NOIMPL"],
|
||||
|
||||
["] d", "goto_last_diag"],
|
||||
["] g", "goto_last_change"],
|
||||
["] t", "goto_next_test"],
|
||||
["] d", "goto_last_diag-NOIMPL"],
|
||||
["] g", "goto_last_change-NOIMPL"],
|
||||
["] t", "goto_next_test-NOIMPL"],
|
||||
["] d", "goto_next_diagnostic"],
|
||||
["] g", "goto_next_change"],
|
||||
["] f", "goto_next_function"],
|
||||
["] t", "goto_next_class"],
|
||||
["] a", "goto_next_parameter"],
|
||||
["] c", "goto_next_comment"],
|
||||
["] e", "goto_next_entry"],
|
||||
["] p", "goto_next_paragraph"],
|
||||
["] space", "add_newline_below"],
|
||||
["] g", "goto_next_change-NOIMPL"],
|
||||
["] f", "goto_next_function-NOIMPL"],
|
||||
["] t", "goto_next_class-NOIMPL"],
|
||||
["] a", "goto_next_parameter-NOIMPL"],
|
||||
["] c", "goto_next_comment-NOIMPL"],
|
||||
["] e", "goto_next_entry-NOIMPL"],
|
||||
["] p", "goto_next_paragraph-NOIMPL"],
|
||||
["] space", "add_newline_below-NOIMPL"],
|
||||
|
||||
["/", "find"],
|
||||
["n", "goto_next_match"],
|
||||
|
|
@ -507,35 +506,35 @@
|
|||
|
||||
["y", ["copy_helix"], ["enter_mode", "normal"]],
|
||||
|
||||
["q", "record_macro"],
|
||||
["Q", "replay_macro"],
|
||||
["q", "record_macro-NOIMPL"],
|
||||
["Q", "replay_macro-NOIMPL"],
|
||||
|
||||
["=", "format_selections"],
|
||||
["=", "format_selections-NOIMPL"],
|
||||
|
||||
[",", "keep_primary_selection"],
|
||||
[",", "keep_primary_selection-NOIMPL"],
|
||||
|
||||
["escape", "enter_mode", "normal"],
|
||||
|
||||
["space F", "file_picker_in_current_directory"],
|
||||
["space S", "workspace_symbol_picker"],
|
||||
["space D", "workspace_diagnostics_picker"],
|
||||
["space F", "file_picker_in_current_directory-NOIMPL"],
|
||||
["space S", "workspace_symbol_picker-NOIMPL"],
|
||||
["space D", "workspace_diagnostics_picker-NOIMPL"],
|
||||
["space P", "system_paste"],
|
||||
["space R", "replace_selections_with_clipboard"],
|
||||
["space ?", "open_command_palette"],
|
||||
|
||||
["space f", "find_file"],
|
||||
["space b", "switch_buffers"],
|
||||
["space j", "jumplist_picker"],
|
||||
["space s", "symbol_picker"],
|
||||
["space j", "jumplist_picker-NOIMPL"],
|
||||
["space s", "symbol_picker-NOIMPL"],
|
||||
["space d", "show_diagnostics"],
|
||||
["space a", "code_action"],
|
||||
["space '", "last_picker"],
|
||||
["space a", "code_action-NOIMPL"],
|
||||
["space '", "last_picker-NOIMPL"],
|
||||
["space y", "copy"],
|
||||
["space p", "system_paste_after"],
|
||||
["space p", "system_paste_after-NOIMPL"],
|
||||
["space /", "find_in_files"],
|
||||
["space k", "hover"],
|
||||
["space r", "rename_symbol"],
|
||||
["space h", "select_references_to_symbol_under_cursor"],
|
||||
["space h", "select_references_to_symbol_under_cursor-NOIMPL"],
|
||||
["space c", "toggle_comment"],
|
||||
|
||||
["0", "add_integer_argument_digit", 0],
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
"name": "NORMAL",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"selection": "normal",
|
||||
"press": [
|
||||
["b", "move_word_left_vim"],
|
||||
["w", "move_word_right_vim"],
|
||||
|
|
@ -76,8 +75,8 @@
|
|||
|
||||
["yy", ["copy_line_internal_vim"], ["cancel"]],
|
||||
|
||||
["<C-u>", "move_scroll_half_page_up_vim"],
|
||||
["<C-d>", "move_scroll_half_page_down_vim"],
|
||||
["<C-u>", "move_scroll_half_page_up"],
|
||||
["<C-d>", "move_scroll_half_page_down"],
|
||||
|
||||
["zz", "scroll_view_center"],
|
||||
|
||||
|
|
@ -121,7 +120,6 @@
|
|||
"name": "VISUAL",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"selection": "normal",
|
||||
"init_command": ["enable_selection"],
|
||||
"press": [
|
||||
["<Esc>", ["cancel"], ["enter_mode", "normal"]],
|
||||
|
|
@ -151,8 +149,8 @@
|
|||
["p", ["paste_internal_vim"], ["enter_mode", "normal"]],
|
||||
["P", ["paste_internal_vim"], ["enter_mode", "normal"]],
|
||||
|
||||
["<C-u>", "move_scroll_half_page_up_vim"],
|
||||
["<C-d>", "move_scroll_half_page_down_vim"],
|
||||
["<C-u>", "move_scroll_half_page_up"],
|
||||
["<C-d>", "move_scroll_half_page_down"],
|
||||
|
||||
["zz", "scroll_view_center"],
|
||||
["<S-.>", "indent"],
|
||||
|
|
@ -186,7 +184,6 @@
|
|||
"name": "VISUAL LINE",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"selection": "normal",
|
||||
"press": [
|
||||
["<Esc>", ["cancel"], ["enter_mode", "normal"]],
|
||||
["k", "select_up"],
|
||||
|
|
@ -199,8 +196,8 @@
|
|||
["p", ["paste_internal_vim"], ["enter_mode", "normal"]],
|
||||
["P", ["paste_internal_vim"], ["enter_mode", "normal"]],
|
||||
|
||||
["<C-u>", "move_scroll_half_page_up_vim"],
|
||||
["<C-d>", "move_scroll_half_page_down_vim"],
|
||||
["<C-u>", "move_scroll_half_page_up"],
|
||||
["<C-d>", "move_scroll_half_page_down"],
|
||||
|
||||
["<S-.>", "indent"],
|
||||
["<S-,>", "unindent"],
|
||||
|
|
@ -234,7 +231,6 @@
|
|||
"inherit": "visual",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"selection": "normal",
|
||||
"init_command": ["enable_selection"],
|
||||
"press": [
|
||||
["k", "add_cursor_up"],
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ const input = @import("input");
|
|||
const command = @import("command");
|
||||
const EventHandler = @import("EventHandler");
|
||||
const KeyEvent = input.KeyEvent;
|
||||
const SelectionStyle = @import("Buffer").Selection.Style;
|
||||
pub const CursorShape = @import("config").CursorShape;
|
||||
|
||||
const log = std.log.scoped(.keybind);
|
||||
|
|
@ -87,7 +86,6 @@ const Handler = struct {
|
|||
.name = self.bindings.name,
|
||||
.line_numbers = self.bindings.line_numbers,
|
||||
.cursor_shape = self.bindings.cursor_shape,
|
||||
.selection_style = self.bindings.selection_style,
|
||||
.init_command = self.bindings.init_command,
|
||||
.deinit_command = self.bindings.deinit_command,
|
||||
.insert_command = try allocator.dupe(u8, insert_command),
|
||||
|
|
@ -112,7 +110,6 @@ const Handler = struct {
|
|||
mode_.name = self.bindings.name;
|
||||
mode_.line_numbers = self.bindings.line_numbers;
|
||||
mode_.cursor_shape = self.bindings.cursor_shape;
|
||||
mode_.selection_style = self.bindings.selection_style;
|
||||
mode_.init_command = self.bindings.init_command;
|
||||
mode_.deinit_command = self.bindings.deinit_command;
|
||||
if (mode_.init_command) |init_command| init_command.execute_const();
|
||||
|
|
@ -136,7 +133,6 @@ pub const Mode = struct {
|
|||
bindings: *const BindingSet,
|
||||
keybind_hints: *const KeybindHints,
|
||||
cursor_shape: ?CursorShape = null,
|
||||
selection_style: SelectionStyle,
|
||||
init_command: ?Command = null,
|
||||
deinit_command: ?Command = null,
|
||||
initialized: bool = false,
|
||||
|
|
@ -172,7 +168,6 @@ pub const Mode = struct {
|
|||
self.line_numbers = .inherit;
|
||||
self.keybind_hints = &.{};
|
||||
self.cursor_shape = null;
|
||||
self.selection_style = .normal;
|
||||
self.init_command = null;
|
||||
self.deinit_command = null;
|
||||
self.initialized = false;
|
||||
|
|
@ -468,7 +463,6 @@ const BindingSet = struct {
|
|||
config_section: []const u8,
|
||||
line_numbers: LineNumbers = .inherit,
|
||||
cursor_shape: ?CursorShape = null,
|
||||
selection_style: SelectionStyle,
|
||||
insert_command: []const u8 = "",
|
||||
hints_map: KeybindHints = .{},
|
||||
init_command: ?Command = null,
|
||||
|
|
@ -478,7 +472,7 @@ const BindingSet = struct {
|
|||
const OnMatchFailure = enum { insert, ignore };
|
||||
|
||||
fn load(allocator: std.mem.Allocator, namespace_name: []const u8, config_section: []const u8, mode_bindings: std.json.Value, fallback: ?*const BindingSet, namespace: *Namespace) (error{ OutOfMemory, WriteFailed } || parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError)!@This() {
|
||||
var self: @This() = .{ .name = undefined, .config_section = config_section, .selection_style = undefined };
|
||||
var self: @This() = .{ .name = undefined, .config_section = config_section };
|
||||
|
||||
const JsonConfig = struct {
|
||||
press: []const []const std.json.Value = &[_][]std.json.Value{},
|
||||
|
|
@ -490,7 +484,6 @@ const BindingSet = struct {
|
|||
cursor: ?CursorShape = null,
|
||||
inherit: ?[]const u8 = null,
|
||||
inherits: ?[][]const u8 = null,
|
||||
selection: ?SelectionStyle = null,
|
||||
init_command: ?[]const std.json.Value = null,
|
||||
deinit_command: ?[]const std.json.Value = null,
|
||||
};
|
||||
|
|
@ -503,7 +496,6 @@ const BindingSet = struct {
|
|||
self.name = try allocator.dupe(u8, parsed.value.name orelse namespace_name);
|
||||
self.line_numbers = parsed.value.line_numbers;
|
||||
self.cursor_shape = parsed.value.cursor;
|
||||
self.selection_style = parsed.value.selection orelse .normal;
|
||||
if (parsed.value.init_command) |cmd| self.init_command = try Command.load(allocator, cmd);
|
||||
if (parsed.value.deinit_command) |cmd| self.deinit_command = try Command.load(allocator, cmd);
|
||||
try self.load_event(allocator, &self.press, input.event.press, parsed.value.press);
|
||||
|
|
@ -575,7 +567,7 @@ const BindingSet = struct {
|
|||
}
|
||||
|
||||
fn copy(allocator: std.mem.Allocator, config_section: []const u8, fallback: *const BindingSet) error{OutOfMemory}!@This() {
|
||||
var self: @This() = .{ .name = fallback.name, .config_section = config_section, .selection_style = fallback.selection_style };
|
||||
var self: @This() = .{ .name = fallback.name, .config_section = config_section };
|
||||
self.on_match_failure = fallback.on_match_failure;
|
||||
for (fallback.press.items) |binding| try self.press.append(allocator, binding);
|
||||
for (fallback.release.items) |binding| try self.release.append(allocator, binding);
|
||||
|
|
@ -971,7 +963,7 @@ test "match" {
|
|||
}
|
||||
|
||||
test "json" {
|
||||
var bindings: BindingSet = .{ .name = "test", .config_section = "test_section", .selection_style = .normal };
|
||||
var bindings: BindingSet = .{ .name = "test", .config_section = "test_section" };
|
||||
_ = try bindings.process_key_event(input.KeyEvent.from_key('j'));
|
||||
_ = try bindings.process_key_event(input.KeyEvent.from_key('k'));
|
||||
_ = try bindings.process_key_event(input.KeyEvent.from_key('g'));
|
||||
|
|
|
|||
|
|
@ -115,63 +115,38 @@ pub const CurSel = struct {
|
|||
self.* = .{};
|
||||
}
|
||||
|
||||
pub fn enable_selection(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) *Selection {
|
||||
self.selection = self.to_selection(root, metrics);
|
||||
pub fn enable_selection(self: *Self) *Selection {
|
||||
self.selection = self.to_selection();
|
||||
return if (self.selection) |*sel| sel else unreachable;
|
||||
}
|
||||
|
||||
pub fn enable_selection_normal(self: *Self) *Selection {
|
||||
self.selection = self.to_selection_normal();
|
||||
pub fn enable_selection_inclusive(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) *Selection {
|
||||
self.selection = self.to_selection_inclusive(root, metrics);
|
||||
return if (self.selection) |*sel| sel else unreachable;
|
||||
}
|
||||
|
||||
fn to_selection(self: *const Self, root: Buffer.Root, metrics: Buffer.Metrics) Selection {
|
||||
return switch (tui.get_selection_style()) {
|
||||
.normal => self.to_selection_normal(),
|
||||
.inclusive => self.to_selection_inclusive(root, metrics),
|
||||
};
|
||||
pub fn to_selection(self: *const Self) Selection {
|
||||
return self.selection orelse Selection.from_cursor(&self.cursor);
|
||||
}
|
||||
|
||||
fn to_selection_normal(self: *const Self) Selection {
|
||||
return if (self.selection) |sel| sel else Selection.from_cursor(&self.cursor);
|
||||
pub fn to_selection_inclusive(self: *const Self, root: Buffer.Root, metrics: Buffer.Metrics) Selection {
|
||||
return self.selection orelse Selection.from_cursor_inclusive(&self.cursor, root, metrics);
|
||||
}
|
||||
|
||||
fn to_selection_inclusive(self: *const Self, root: Buffer.Root, metrics: Buffer.Metrics) Selection {
|
||||
return if (self.selection) |sel|
|
||||
sel
|
||||
else cod: {
|
||||
var sel = Selection.from_cursor(&self.cursor);
|
||||
sel.end.move_right(root, metrics) catch {};
|
||||
break :cod sel;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn disable_selection(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) void {
|
||||
switch (tui.get_selection_style()) {
|
||||
.normal => self.disable_selection_normal(),
|
||||
.inclusive => self.disable_selection_inclusive(root, metrics),
|
||||
}
|
||||
pub fn disable_selection(self: *Self) void {
|
||||
self.selection = null;
|
||||
}
|
||||
|
||||
pub 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;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_selection(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) void {
|
||||
if (self.selection) |sel| if (sel.empty()) {
|
||||
self.disable_selection(root, metrics);
|
||||
};
|
||||
pub fn check_selection(self: *Self) void {
|
||||
self.selection = if (self.selection) |sel| if (sel.empty()) null else sel else null;
|
||||
}
|
||||
|
||||
fn expand_selection_to_line(self: *Self, root: Buffer.Root, metrics: Buffer.Metrics) *Selection {
|
||||
const sel = self.enable_selection(root, metrics);
|
||||
const sel = self.enable_selection();
|
||||
sel.normalize();
|
||||
sel.begin.move_begin();
|
||||
if (!(sel.end.row > sel.begin.row and sel.end.col == 0)) {
|
||||
|
|
@ -1658,7 +1633,7 @@ pub const Editor = struct {
|
|||
return row < sel.begin.row or (row == sel.begin.row and col < sel.begin.col);
|
||||
}
|
||||
|
||||
inline fn screen_cursor(self: *const Self, cursor: *const Cursor) ?Cursor {
|
||||
pub inline fn screen_cursor(self: *const Self, cursor: *const Cursor) ?Cursor {
|
||||
return if (self.view.is_visible(cursor)) .{
|
||||
.row = cursor.row - self.view.row,
|
||||
.col = cursor.col - self.view.col,
|
||||
|
|
@ -1771,7 +1746,7 @@ pub const Editor = struct {
|
|||
try self.send_editor_cursel_msg("jump_source", self.get_primary());
|
||||
}
|
||||
|
||||
fn send_editor_jump_destination(self: *Self) !void {
|
||||
pub fn send_editor_jump_destination(self: *Self) !void {
|
||||
try self.send_editor_cursel_msg("jump_destination", self.get_primary());
|
||||
}
|
||||
|
||||
|
|
@ -1901,7 +1876,7 @@ pub const Editor = struct {
|
|||
|
||||
fn cancel_all_selections(self: *Self) void {
|
||||
var primary = self.get_primary().*;
|
||||
primary.disable_selection(self.buf_root() catch return, self.metrics);
|
||||
primary.disable_selection();
|
||||
self.cursels.clearRetainingCapacity();
|
||||
self.cursels.addOneAssumeCapacity().* = primary;
|
||||
for (self.matches.items) |*match_| if (match_.*) |*match| {
|
||||
|
|
@ -1955,7 +1930,7 @@ pub const Editor = struct {
|
|||
|
||||
fn with_cursors_const_once(self: *Self, root: Buffer.Root, move: cursor_operator_const) error{Stop}!void {
|
||||
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
try with_cursor_const(root, move, cursel, self.metrics);
|
||||
};
|
||||
self.collapse_cursors();
|
||||
|
|
@ -1966,7 +1941,7 @@ pub const Editor = struct {
|
|||
_ = ctx.args.match(.{tp.extract(&repeat)}) catch false;
|
||||
while (repeat > 0) : (repeat -= 1) {
|
||||
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
try with_cursor_const(root, move, cursel, self.metrics);
|
||||
};
|
||||
self.collapse_cursors();
|
||||
|
|
@ -1979,7 +1954,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 {
|
||||
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
try with_cursor_const_arg(root, move, cursel, ctx, self.metrics);
|
||||
};
|
||||
self.collapse_cursors();
|
||||
|
|
@ -1989,7 +1964,7 @@ pub const Editor = struct {
|
|||
try move(root, &cursel.cursor, view, metrics);
|
||||
}
|
||||
|
||||
fn with_cursors_and_view_const(self: *Self, root: Buffer.Root, move: cursor_view_operator_const, view: *const View) error{Stop}!void {
|
||||
pub fn with_cursors_and_view_const(self: *Self, root: Buffer.Root, move: cursor_view_operator_const, view: *const View) error{Stop}!void {
|
||||
var someone_stopped = false;
|
||||
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel|
|
||||
with_cursor_and_view_const(root, move, cursel, view, self.metrics) catch {
|
||||
|
|
@ -2004,10 +1979,10 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
pub fn with_selection_const(root: Buffer.Root, move: cursor_operator_const, cursel: *CurSel, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
const sel = cursel.enable_selection(root, metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
try move(root, &sel.end, metrics);
|
||||
cursel.cursor = sel.end;
|
||||
cursel.check_selection(root, metrics);
|
||||
cursel.check_selection();
|
||||
}
|
||||
|
||||
pub fn with_selections_const_once(self: *Self, root: Buffer.Root, move: cursor_operator_const) error{Stop}!void {
|
||||
|
|
@ -2036,10 +2011,10 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
fn with_selection_const_arg(root: Buffer.Root, move: cursor_operator_const_arg, cursel: *CurSel, ctx: Context, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
const sel = cursel.enable_selection(root, metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
try move(root, &sel.end, ctx, metrics);
|
||||
cursel.cursor = sel.end;
|
||||
cursel.check_selection(root, metrics);
|
||||
cursel.check_selection();
|
||||
}
|
||||
|
||||
fn with_selections_const_arg(self: *Self, root: Buffer.Root, move: cursor_operator_const_arg, ctx: Context) error{Stop}!void {
|
||||
|
|
@ -2053,12 +2028,12 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
fn with_selection_and_view_const(root: Buffer.Root, move: cursor_view_operator_const, cursel: *CurSel, view: *const View, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
const sel = cursel.enable_selection(root, metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
try move(root, &sel.end, view, metrics);
|
||||
cursel.cursor = sel.end;
|
||||
}
|
||||
|
||||
fn with_selections_and_view_const(self: *Self, root: Buffer.Root, move: cursor_view_operator_const, view: *const View) error{Stop}!void {
|
||||
pub fn with_selections_and_view_const(self: *Self, root: Buffer.Root, move: cursor_view_operator_const, view: *const View) error{Stop}!void {
|
||||
var someone_stopped = false;
|
||||
for (self.cursels.items) |*cursel_| if (cursel_.*) |*cursel|
|
||||
with_selection_and_view_const(root, move, cursel, view, self.metrics) catch {
|
||||
|
|
@ -2214,48 +2189,60 @@ pub const Editor = struct {
|
|||
const cursor_operator_const_arg = *const fn (root: Buffer.Root, cursor: *Cursor, ctx: Context, metrics: Buffer.Metrics) error{Stop}!void;
|
||||
pub const cursel_operator_mut_once_arg = *const fn (root: Buffer.Root, cursel: *CurSel, ctx: Context, metrics: Buffer.Metrics) error{Stop}!void;
|
||||
const cursor_view_operator_const = *const fn (root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) error{Stop}!void;
|
||||
const cursel_operator_const = *const fn (root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) error{Stop}!void;
|
||||
pub const cursel_operator_const = *const fn (root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) error{Stop}!void;
|
||||
const cursor_operator = *const fn (root: Buffer.Root, cursor: *Cursor, allocator: Allocator) error{Stop}!Buffer.Root;
|
||||
const cursel_operator = *const fn (root: Buffer.Root, cursel: *CurSel, allocator: Allocator) error{Stop}!Buffer.Root;
|
||||
const cursel_operator_mut = *const fn (self: *Self, root: Buffer.Root, cursel: *CurSel, allocator: Allocator) error{Stop}!Buffer.Root;
|
||||
const cursel_operator_mut_arg = *const fn (self: *Self, root: Buffer.Root, cursel: *CurSel, allocator: Allocator, ctx: Context) error{Stop}!Buffer.Root;
|
||||
|
||||
pub fn is_not_word_char(c: []const u8) bool {
|
||||
if (c.len == 0) return true;
|
||||
pub const CharClass = enum {
|
||||
whitespace,
|
||||
word,
|
||||
non_word,
|
||||
eol,
|
||||
end,
|
||||
};
|
||||
|
||||
pub fn char_class(c: []const u8) CharClass {
|
||||
if (c.len == 0) return .end;
|
||||
return switch (c[0]) {
|
||||
' ' => true,
|
||||
'=' => true,
|
||||
'"' => true,
|
||||
'\'' => true,
|
||||
'\t' => true,
|
||||
'\n' => true,
|
||||
'/' => true,
|
||||
'\\' => true,
|
||||
'*' => true,
|
||||
':' => true,
|
||||
'.' => true,
|
||||
',' => true,
|
||||
'(' => true,
|
||||
')' => true,
|
||||
'{' => true,
|
||||
'}' => true,
|
||||
'[' => true,
|
||||
']' => true,
|
||||
';' => true,
|
||||
'|' => true,
|
||||
'!' => true,
|
||||
'?' => true,
|
||||
'&' => true,
|
||||
'@' => true,
|
||||
'-' => true,
|
||||
'<' => true,
|
||||
'>' => true,
|
||||
else => false,
|
||||
'=' => .non_word,
|
||||
'"' => .non_word,
|
||||
'\'' => .non_word,
|
||||
'/' => .non_word,
|
||||
'\\' => .non_word,
|
||||
'*' => .non_word,
|
||||
':' => .non_word,
|
||||
'.' => .non_word,
|
||||
',' => .non_word,
|
||||
'(' => .non_word,
|
||||
')' => .non_word,
|
||||
'{' => .non_word,
|
||||
'}' => .non_word,
|
||||
'[' => .non_word,
|
||||
']' => .non_word,
|
||||
';' => .non_word,
|
||||
'|' => .non_word,
|
||||
'!' => .non_word,
|
||||
'?' => .non_word,
|
||||
'&' => .non_word,
|
||||
'@' => .non_word,
|
||||
'-' => .non_word,
|
||||
'<' => .non_word,
|
||||
'>' => .non_word,
|
||||
' ' => .whitespace,
|
||||
'\t' => .whitespace,
|
||||
'\n' => .eol,
|
||||
else => .word,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn is_not_word_char(c: []const u8) bool {
|
||||
return char_class(c) != .word;
|
||||
}
|
||||
|
||||
pub fn is_word_char(c: []const u8) bool {
|
||||
return !is_not_word_char(c);
|
||||
return char_class(c) == .word;
|
||||
}
|
||||
|
||||
fn is_word_char_at_cursor(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
|
|
@ -2279,11 +2266,17 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
pub fn is_whitespace(c: []const u8) bool {
|
||||
return (c.len == 0) or (c[0] == ' ') or (c[0] == '\t');
|
||||
return switch (char_class(c)) {
|
||||
.whitespace, .end => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn is_whitespace_or_eol(c: []const u8) bool {
|
||||
return is_whitespace(c) or c[0] == '\n';
|
||||
return switch (char_class(c)) {
|
||||
.whitespace, .end, .eol => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn is_whitespace_at_cursor(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
|
|
@ -2358,7 +2351,7 @@ pub const Editor = struct {
|
|||
return false;
|
||||
}
|
||||
|
||||
fn is_eol_left(_: Buffer.Root, cursor: *const Cursor, _: Buffer.Metrics) bool {
|
||||
pub fn is_eol_left(_: Buffer.Root, cursor: *const Cursor, _: Buffer.Metrics) bool {
|
||||
if (cursor.col == 0)
|
||||
return true;
|
||||
return false;
|
||||
|
|
@ -2371,22 +2364,6 @@ pub const Editor = struct {
|
|||
return false;
|
||||
}
|
||||
|
||||
fn is_eol_right_vim(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
const line_width = root.line_width(cursor.row, metrics) catch return true;
|
||||
if (line_width == 0) return true;
|
||||
if (cursor.col >= line_width - 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
fn is_eol_vim(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
const line_width = root.line_width(cursor.row, metrics) catch return true;
|
||||
if (line_width == 0) return true;
|
||||
if (cursor.col >= line_width)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn move_cursor_left(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
try cursor.move_left(root, metrics);
|
||||
}
|
||||
|
|
@ -2396,7 +2373,7 @@ pub const Editor = struct {
|
|||
move_cursor_left(root, cursor, metrics) catch return;
|
||||
}
|
||||
|
||||
fn move_cursor_left_unless(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, metrics: Buffer.Metrics) void {
|
||||
pub fn move_cursor_left_unless(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, metrics: Buffer.Metrics) void {
|
||||
if (!pred(root, cursor, metrics))
|
||||
move_cursor_left(root, cursor, metrics) catch return;
|
||||
}
|
||||
|
|
@ -2419,7 +2396,7 @@ pub const Editor = struct {
|
|||
move_cursor_right(root, cursor, metrics) catch return;
|
||||
}
|
||||
|
||||
fn move_cursor_right_unless(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, metrics: Buffer.Metrics) void {
|
||||
pub fn move_cursor_right_unless(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, metrics: Buffer.Metrics) void {
|
||||
if (!pred(root, cursor, metrics))
|
||||
move_cursor_right(root, cursor, metrics) catch return;
|
||||
}
|
||||
|
|
@ -2428,32 +2405,18 @@ pub const Editor = struct {
|
|||
cursor.move_end(root, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_end_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
move_cursor_right_until(root, cursor, is_eol_vim, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_up(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_up(root, metrics) catch |e| switch (e) {
|
||||
error.Stop => cursor.move_begin(),
|
||||
};
|
||||
}
|
||||
|
||||
fn move_cursor_up_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
try cursor.move_up(root, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
pub fn move_cursor_down(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_down(root, metrics) catch |e| switch (e) {
|
||||
error.Stop => cursor.move_end(root, metrics),
|
||||
};
|
||||
}
|
||||
|
||||
fn move_cursor_down_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
try cursor.move_down(root, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_buffer_begin(_: Buffer.Root, cursor: *Cursor, _: Buffer.Metrics) !void {
|
||||
cursor.move_buffer_begin();
|
||||
}
|
||||
|
|
@ -2470,24 +2433,6 @@ pub const Editor = struct {
|
|||
cursor.move_page_down(root, view, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_half_page_up(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_half_page_up(root, view, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_half_page_up_vim(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_half_page_up(root, view, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_half_page_down(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_half_page_down(root, view, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_half_page_down_vim(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_half_page_down(root, view, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
pub fn primary_click(self: *Self, y: c_int, x: c_int) !void {
|
||||
const root = self.buf_root() catch return;
|
||||
if (self.fast_scroll) {
|
||||
|
|
@ -2500,7 +2445,7 @@ pub const Editor = struct {
|
|||
self.cancel_all_selections();
|
||||
}
|
||||
const primary = self.get_primary();
|
||||
primary.disable_selection(root, self.metrics);
|
||||
primary.disable_selection();
|
||||
self.selection_mode = .char;
|
||||
try self.send_editor_jump_source();
|
||||
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return;
|
||||
|
|
@ -2514,7 +2459,7 @@ pub const Editor = struct {
|
|||
pub fn primary_double_click(self: *Self, y: c_int, x: c_int) !void {
|
||||
const primary = self.get_primary();
|
||||
const root = self.buf_root() catch return;
|
||||
primary.disable_selection(root, self.metrics);
|
||||
primary.disable_selection();
|
||||
self.selection_mode = .word;
|
||||
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.metrics) catch return;
|
||||
_ = try self.select_word_at_cursor(primary);
|
||||
|
|
@ -2526,7 +2471,7 @@ pub const Editor = struct {
|
|||
pub fn primary_triple_click(self: *Self, y: c_int, x: c_int) !void {
|
||||
const primary = self.get_primary();
|
||||
const root = self.buf_root() catch return;
|
||||
primary.disable_selection(root, self.metrics);
|
||||
primary.disable_selection();
|
||||
self.selection_mode = .line;
|
||||
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);
|
||||
|
|
@ -2540,7 +2485,7 @@ pub const Editor = struct {
|
|||
const x_ = if (x < 0) 0 else x;
|
||||
const primary = self.get_primary();
|
||||
const root = self.buf_root() catch return;
|
||||
const sel = primary.enable_selection(root, self.metrics);
|
||||
const sel = primary.enable_selection();
|
||||
sel.end.move_abs(root, &self.view, @intCast(y_), @intCast(x_), self.metrics) catch return;
|
||||
const initial = self.selection_drag_initial orelse sel.*;
|
||||
switch (self.selection_mode) {
|
||||
|
|
@ -2568,7 +2513,7 @@ pub const Editor = struct {
|
|||
},
|
||||
}
|
||||
primary.cursor = sel.end;
|
||||
primary.check_selection(root, self.metrics);
|
||||
primary.check_selection();
|
||||
self.collapse_cursors();
|
||||
self.clamp_mouse();
|
||||
}
|
||||
|
|
@ -2758,7 +2703,7 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
pub fn insert(self: *Self, root: Buffer.Root, cursel: *CurSel, s: []const u8, allocator: Allocator) !Buffer.Root {
|
||||
cursel.check_selection(root, self.metrics);
|
||||
cursel.check_selection();
|
||||
var root_ = if (cursel.selection) |_| try self.delete_selection(root, cursel, allocator) else root;
|
||||
const cursor = &cursel.cursor;
|
||||
const begin = cursel.cursor;
|
||||
|
|
@ -2911,7 +2856,7 @@ pub const Editor = struct {
|
|||
const primary = self.get_primary();
|
||||
const root = self.buf_root() catch return;
|
||||
if (primary.selection) |_| {} else {
|
||||
const sel = primary.enable_selection(root, self.metrics);
|
||||
const sel = primary.enable_selection();
|
||||
try move_cursor_begin(root, &sel.begin, self.metrics);
|
||||
try move_cursor_end(root, &sel.end, self.metrics);
|
||||
try move_cursor_right(root, &sel.end, self.metrics);
|
||||
|
|
@ -3202,14 +3147,6 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const delete_line_meta: Meta = .{ .description = "Delete current line", .arguments = &.{.integer} };
|
||||
|
||||
pub fn cut_to_end_vim(self: *Self, _: Context) Result {
|
||||
const b = try self.buf_for_update();
|
||||
const root = try self.cut_to(move_cursor_end_vim, b.root);
|
||||
try self.update_buf(root);
|
||||
self.clamp();
|
||||
}
|
||||
pub const cut_to_end_vim_meta: Meta = .{ .description = "Cut to end of line (vim)" };
|
||||
|
||||
pub fn join_next_line(self: *Self, ctx: Context) Result {
|
||||
const b = try self.buf_for_update();
|
||||
try self.with_cursors_const_repeat(b.root, move_cursor_end, ctx);
|
||||
|
|
@ -3237,7 +3174,7 @@ pub const Editor = struct {
|
|||
.left => if (sel.is_reversed()) sel.end else sel.begin,
|
||||
.right => if (sel.is_reversed()) sel.begin else sel.end,
|
||||
};
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
} else {
|
||||
try with_cursor_const(root, switch (direction) {
|
||||
.left => move_cursor_left,
|
||||
|
|
@ -3260,28 +3197,6 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const move_right_meta: Meta = .{ .description = "Move cursor right", .arguments = &.{.integer} };
|
||||
|
||||
fn move_cursor_left_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
move_cursor_left_unless(root, cursor, is_eol_left, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_right_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
move_cursor_right_unless(root, cursor, is_eol_right_vim, metrics);
|
||||
}
|
||||
|
||||
pub fn move_left_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_left_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_left_vim_meta: Meta = .{ .description = "Move cursor left (vim)", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_right_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_right_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_right_vim_meta: Meta = .{ .description = "Move cursor right (vim)", .arguments = &.{.integer} };
|
||||
|
||||
fn move_cursor_word_begin(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
if (is_non_word_char_at_cursor(root, cursor, metrics)) {
|
||||
move_cursor_left_until(root, cursor, is_word_boundary_right, metrics);
|
||||
|
|
@ -3568,13 +3483,6 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const move_up_meta: Meta = .{ .description = "Move cursor up", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_up_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_up_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_up_vim_meta: Meta = .{ .description = "Move cursor up (vim)", .arguments = &.{.integer} };
|
||||
|
||||
pub fn add_cursor_up(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
var repeat: usize = 1;
|
||||
|
|
@ -3595,13 +3503,6 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const move_down_meta: Meta = .{ .description = "Move cursor down", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_down_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_down_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_down_vim_meta: Meta = .{ .description = "Move cursor down (vim)", .arguments = &.{.integer} };
|
||||
|
||||
pub fn add_cursor_down(self: *Self, ctx: Context) Result {
|
||||
var repeat: usize = 1;
|
||||
_ = ctx.args.match(.{tp.extract(&repeat)}) catch false;
|
||||
|
|
@ -3657,7 +3558,7 @@ pub const Editor = struct {
|
|||
pub const add_cursor_all_matches_meta: Meta = .{ .description = "Add cursors to all highlighted matches" };
|
||||
|
||||
fn add_cursors_to_cursel_line_ends(self: *Self, root: Buffer.Root, cursel: *CurSel) !void {
|
||||
const sel = cursel.enable_selection(root, self.metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
sel.normalize();
|
||||
var row = sel.begin.row;
|
||||
while (row <= sel.end.row) : (row += 1) {
|
||||
|
|
@ -3751,7 +3652,7 @@ pub const Editor = struct {
|
|||
cursel.cursor = sel.begin;
|
||||
var add_eol = false;
|
||||
if (cursel.selection) |_| {
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
} else {
|
||||
var test_eof = sel.end;
|
||||
test_eof.move_right(root, self.metrics) catch { // test for EOF
|
||||
|
|
@ -3786,7 +3687,7 @@ pub const Editor = struct {
|
|||
|
||||
cursel.cursor = sel.end;
|
||||
if (cursel.selection) |_| {
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
} else {
|
||||
var test_eof = sel.end;
|
||||
test_eof.move_right(root, self.metrics) catch { // test for EOF
|
||||
|
|
@ -3840,7 +3741,7 @@ pub const Editor = struct {
|
|||
|
||||
cursel.cursor = sel.end;
|
||||
if (cursel.selection) |_| {
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
} else {
|
||||
var test_eof = sel.end;
|
||||
test_eof.move_right(root, self.metrics) catch { // test for EOF
|
||||
|
|
@ -3944,7 +3845,7 @@ pub const Editor = struct {
|
|||
if (first == 0) return root;
|
||||
const off = first % self.indent_size;
|
||||
const cols = if (off == 0) self.indent_size else off;
|
||||
const sel = cursel.enable_selection(root, self.metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
try sel.begin.move_to(root, sel.begin.row, first, self.metrics);
|
||||
try sel.end.move_to(root, sel.end.row, first - cols, self.metrics);
|
||||
var saved = false;
|
||||
|
|
@ -4039,54 +3940,6 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const move_scroll_page_down_meta: Meta = .{ .description = "Move and scroll page down" };
|
||||
|
||||
pub fn move_scroll_half_page_up(self: *Self, _: Context) Result {
|
||||
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_and_view_const(root, move_cursor_half_page_up, &self.view) catch {};
|
||||
const new_cursor_row = self.get_primary().cursor.row;
|
||||
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
|
||||
} else {
|
||||
return self.move_half_page_up(.{});
|
||||
}
|
||||
}
|
||||
pub const move_scroll_half_page_up_meta: Meta = .{ .description = "Move and scroll half a page up" };
|
||||
|
||||
pub fn move_scroll_half_page_up_vim(self: *Self, _: Context) Result {
|
||||
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_and_view_const(root, move_cursor_half_page_up_vim, &self.view) catch {};
|
||||
const new_cursor_row = self.get_primary().cursor.row;
|
||||
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
|
||||
} else {
|
||||
return self.move_half_page_up(.{});
|
||||
}
|
||||
}
|
||||
pub const move_scroll_half_page_up_vim_meta: Meta = .{ .description = "Move and scroll half a page up (vim)" };
|
||||
|
||||
pub fn move_scroll_half_page_down(self: *Self, _: Context) Result {
|
||||
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_and_view_const(root, move_cursor_half_page_down, &self.view) catch {};
|
||||
const new_cursor_row = self.get_primary().cursor.row;
|
||||
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
|
||||
} else {
|
||||
return self.move_half_page_down(.{});
|
||||
}
|
||||
}
|
||||
pub const move_scroll_half_page_down_meta: Meta = .{ .description = "Move and scroll half a page down" };
|
||||
|
||||
pub fn move_scroll_half_page_down_vim(self: *Self, _: Context) Result {
|
||||
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_and_view_const(root, move_cursor_half_page_down_vim, &self.view) catch {};
|
||||
const new_cursor_row = self.get_primary().cursor.row;
|
||||
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
|
||||
} else {
|
||||
return self.move_half_page_down(.{});
|
||||
}
|
||||
}
|
||||
pub const move_scroll_half_page_down_vim_meta: Meta = .{ .description = "Move and scroll half a page down (vim)" };
|
||||
|
||||
pub fn smart_move_begin(self: *Self, _: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
try self.with_cursors_const_once(root, smart_move_cursor_begin);
|
||||
|
|
@ -4169,8 +4022,7 @@ pub const Editor = struct {
|
|||
pub const cancel_meta: Meta = .{ .description = "Cancel current action" };
|
||||
|
||||
pub fn enable_selection(self: *Self, _: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
_ = self.get_primary().enable_selection(root, self.metrics);
|
||||
_ = self.get_primary().enable_selection();
|
||||
}
|
||||
pub const enable_selection_meta: Meta = .{ .description = "Enable selection" };
|
||||
|
||||
|
|
@ -4376,30 +4228,12 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const select_page_down_meta: Meta = .{ .description = "Select page down" };
|
||||
|
||||
pub fn select_half_page_up(self: *Self, _: Context) Result {
|
||||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
try self.with_selections_and_view_const(root, move_cursor_half_page_up, &self.view);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const select_half_page_up_meta: Meta = .{ .description = "Select half a page up" };
|
||||
|
||||
pub fn select_half_page_down(self: *Self, _: Context) Result {
|
||||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
try self.with_selections_and_view_const(root, move_cursor_half_page_down, &self.view);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const select_half_page_down_meta: Meta = .{ .description = "Select half a page down" };
|
||||
|
||||
pub fn select_all(self: *Self, _: Context) Result {
|
||||
try self.send_editor_jump_source();
|
||||
self.cancel_all_selections();
|
||||
const primary = self.get_primary();
|
||||
const root = try self.buf_root();
|
||||
const sel = primary.enable_selection(root, self.metrics);
|
||||
const sel = primary.enable_selection();
|
||||
try expand_selection_to_all(root, sel, self.metrics);
|
||||
primary.cursor = sel.end;
|
||||
self.clamp();
|
||||
|
|
@ -4409,8 +4243,8 @@ pub const Editor = struct {
|
|||
|
||||
fn select_word_at_cursor(self: *Self, cursel: *CurSel) !*Selection {
|
||||
const root = try self.buf_root();
|
||||
const sel = cursel.enable_selection(root, self.metrics);
|
||||
defer cursel.check_selection(root, self.metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
defer cursel.check_selection();
|
||||
sel.normalize();
|
||||
try move_cursor_word_begin(root, &sel.begin, self.metrics);
|
||||
move_cursor_word_end(root, &sel.end, self.metrics) catch {};
|
||||
|
|
@ -4419,7 +4253,7 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
pub fn select_line_at_cursor(self: *Self, root: Buffer.Root, cursel: *CurSel, mode: enum { include_eol, exclude_eol, hold_cursor }) !void {
|
||||
const sel = cursel.enable_selection(root, self.metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
sel.normalize();
|
||||
try move_cursor_begin(root, &sel.begin, self.metrics);
|
||||
move_cursor_end(root, &sel.end, self.metrics) catch {};
|
||||
|
|
@ -4483,12 +4317,12 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
fn top_node_at_cursel(self: *const Self, cursel: *const CurSel, root: Buffer.Root, metrics: Buffer.Metrics) error{Stop}!syntax.Node {
|
||||
const sel = cursel.to_selection(root, metrics);
|
||||
const sel = cursel.to_selection();
|
||||
return try self.top_node_at_selection(sel, root, metrics);
|
||||
}
|
||||
|
||||
fn expand_selection_to_parent_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection(root, metrics).*;
|
||||
const sel = cursel.enable_selection().*;
|
||||
var node = try self.top_node_at_selection(sel, root, metrics);
|
||||
if (node.isNull()) return error.Stop;
|
||||
var node_sel = CurSel.selection_from_node(node, root, metrics);
|
||||
|
|
@ -4502,7 +4336,7 @@ pub const Editor = struct {
|
|||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection(root, self.metrics);
|
||||
cursel.check_selection();
|
||||
try if (cursel.selection) |_|
|
||||
self.expand_selection_to_parent_node(root, cursel, self.metrics)
|
||||
else
|
||||
|
|
@ -4513,7 +4347,7 @@ pub const Editor = struct {
|
|||
pub const expand_selection_meta: Meta = .{ .description = "Expand selection to AST parent node" };
|
||||
|
||||
fn shrink_selection_to_child_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection(root, metrics).*;
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull() or node.getChildCount() == 0) return error.Stop;
|
||||
const child = node.getChild(0);
|
||||
|
|
@ -4522,7 +4356,7 @@ pub const Editor = struct {
|
|||
}
|
||||
|
||||
fn shrink_selection_to_named_child_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection(root, metrics).*;
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull() or node.getNamedChildCount() == 0) return error.Stop;
|
||||
const child = node.getNamedChild(0);
|
||||
|
|
@ -4536,7 +4370,7 @@ pub const Editor = struct {
|
|||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection(root, self.metrics);
|
||||
cursel.check_selection();
|
||||
if (cursel.selection) |_| {
|
||||
try if (unnamed)
|
||||
self.shrink_selection_to_child_node(root, cursel, self.metrics)
|
||||
|
|
@ -4570,7 +4404,7 @@ pub const Editor = struct {
|
|||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection(root, self.metrics);
|
||||
cursel.check_selection();
|
||||
if (cursel.selection) |_| {
|
||||
try if (unnamed)
|
||||
self.select_next_sibling_node(root, cursel, self.metrics)
|
||||
|
|
@ -4604,7 +4438,7 @@ pub const Editor = struct {
|
|||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection(root, self.metrics);
|
||||
cursel.check_selection();
|
||||
try if (unnamed)
|
||||
self.select_prev_sibling_node(root, cursel, self.metrics)
|
||||
else
|
||||
|
|
@ -4680,7 +4514,7 @@ pub const Editor = struct {
|
|||
root_ = self.collapse_trailing_ws_line(root_, row, b_allocator);
|
||||
const leading_ws_ = find_first_non_ws(root_, cursel.cursor.row, self.metrics);
|
||||
if (leading_ws_ > leading_ws and leading_ws_ > cursel.cursor.col) {
|
||||
const sel = cursel.enable_selection(root_, self.metrics);
|
||||
const sel = cursel.enable_selection();
|
||||
sel.* = .{
|
||||
.begin = .{ .row = cursel.cursor.row, .col = cursel.cursor.col },
|
||||
.end = .{ .row = cursel.cursor.row, .col = leading_ws_ },
|
||||
|
|
@ -4866,7 +4700,7 @@ pub const Editor = struct {
|
|||
root = try self.insert(root, &begin, chars_begin, b.allocator);
|
||||
var end: CurSel = .{ .cursor = sel.end };
|
||||
root = try self.insert(root, &end, chars_end, b.allocator);
|
||||
cursel.disable_selection(root, self.metrics);
|
||||
cursel.disable_selection();
|
||||
} else blk: {
|
||||
const egc, _, _ = cursel.cursor.egc_at(root, self.metrics) catch {
|
||||
root = try self.insert(root, cursel, chars_right, b.allocator);
|
||||
|
|
@ -5469,10 +5303,7 @@ pub const Editor = struct {
|
|||
const col = cursor.col;
|
||||
for (self.matches.items) |*match_| if (match_.*) |*match| {
|
||||
if (match.has_selection) continue;
|
||||
switch (tui.get_selection_style()) {
|
||||
.normal => if (cursor.within(match.to_selection())) return match,
|
||||
.inclusive => {},
|
||||
}
|
||||
if (cursor.within(match.to_selection())) return match;
|
||||
if (row < match.begin.row or (row == match.begin.row and col < match.begin.col)) return match;
|
||||
};
|
||||
return null;
|
||||
|
|
@ -5634,18 +5465,6 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const goto_line_meta: Meta = .{ .arguments = &.{.integer} };
|
||||
|
||||
pub fn goto_line_vim(self: *Self, ctx: Context) Result {
|
||||
try self.send_editor_jump_source();
|
||||
var line: usize = 0;
|
||||
_ = ctx.args.match(.{tp.extract(&line)}) catch false;
|
||||
const root = self.buf_root() catch return;
|
||||
const primary = self.get_primary();
|
||||
try primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.metrics);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const goto_line_vim_meta: Meta = .{ .arguments = &.{.integer} };
|
||||
|
||||
pub fn goto_column(self: *Self, ctx: Context) Result {
|
||||
const root = self.buf_root() catch return;
|
||||
const primary = self.get_primary();
|
||||
|
|
@ -6161,7 +5980,7 @@ pub const Editor = struct {
|
|||
state.chunks = 1;
|
||||
primary.cursor = state.old_primary.cursor;
|
||||
} else {
|
||||
const sel = primary.enable_selection(root, self.metrics);
|
||||
const sel = primary.enable_selection();
|
||||
sel.begin = state.begin;
|
||||
sel.end = state.pos.cursor;
|
||||
if (state.old_primary_reversed) sel.reverse();
|
||||
|
|
@ -6190,7 +6009,7 @@ pub const Editor = struct {
|
|||
var root = root_;
|
||||
const saved = cursel.*;
|
||||
const sel = if (cursel.selection) |*sel| sel else ret: {
|
||||
var sel = cursel.enable_selection(root, self.metrics);
|
||||
var sel = cursel.enable_selection();
|
||||
move_cursor_word_begin(root, &sel.begin, self.metrics) catch return error.Stop;
|
||||
move_cursor_word_end(root, &sel.end, self.metrics) catch return error.Stop;
|
||||
break :ret sel;
|
||||
|
|
@ -6219,7 +6038,7 @@ pub const Editor = struct {
|
|||
var root = root_;
|
||||
const saved = cursel.*;
|
||||
const sel = if (cursel.selection) |*sel| sel else ret: {
|
||||
var sel = cursel.enable_selection(root, self.metrics);
|
||||
var sel = cursel.enable_selection();
|
||||
move_cursor_word_begin(root, &sel.begin, self.metrics) catch return error.Stop;
|
||||
move_cursor_word_end(root, &sel.end, self.metrics) catch return error.Stop;
|
||||
break :ret sel;
|
||||
|
|
@ -6248,7 +6067,7 @@ pub const Editor = struct {
|
|||
var root = root_;
|
||||
var saved = cursel.*;
|
||||
const sel = if (cursel.selection) |*sel| sel else ret: {
|
||||
var sel = cursel.enable_selection(root, self.metrics);
|
||||
var sel = cursel.enable_selection();
|
||||
move_cursor_right(root, &sel.end, self.metrics) catch return error.Stop;
|
||||
saved.cursor = sel.end;
|
||||
break :ret sel;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -405,16 +405,6 @@ const cmds = struct {
|
|||
}
|
||||
pub const overlay_insert_bytes_meta: Meta = .{ .arguments = &.{.string} };
|
||||
|
||||
pub fn overlay_toggle_panel(self: *Self, _: Ctx) Result {
|
||||
return self.cmd_async("toggle_panel");
|
||||
}
|
||||
pub const overlay_toggle_panel_meta: Meta = .{};
|
||||
|
||||
pub fn overlay_toggle_inputview(self: *Self, _: Ctx) Result {
|
||||
return self.cmd_async("toggle_inputview");
|
||||
}
|
||||
pub const overlay_toggle_inputview_meta: Meta = .{};
|
||||
|
||||
pub fn overlay_next_widget_style(self: *Self, _: Ctx) Result {
|
||||
tui.set_next_style(widget_type);
|
||||
self.do_resize();
|
||||
|
|
|
|||
|
|
@ -598,16 +598,6 @@ pub fn Create(options: type) type {
|
|||
}
|
||||
pub const overlay_insert_bytes_meta: Meta = .{ .arguments = &.{.string} };
|
||||
|
||||
pub fn overlay_toggle_panel(self: *Self, _: Ctx) Result {
|
||||
return self.cmd_async("toggle_panel");
|
||||
}
|
||||
pub const overlay_toggle_panel_meta: Meta = .{};
|
||||
|
||||
pub fn overlay_toggle_inputview(self: *Self, _: Ctx) Result {
|
||||
return self.cmd_async("toggle_inputview");
|
||||
}
|
||||
pub const overlay_toggle_inputview_meta: Meta = .{};
|
||||
|
||||
pub fn overlay_next_widget_style(self: *Self, _: Ctx) Result {
|
||||
tui.set_next_style(widget_type);
|
||||
const padding = tui.get_widget_style(widget_type).padding;
|
||||
|
|
|
|||
|
|
@ -366,16 +366,6 @@ const cmds = struct {
|
|||
}
|
||||
pub const overlay_insert_bytes_meta: Meta = .{ .arguments = &.{.string} };
|
||||
|
||||
pub fn overlay_toggle_panel(self: *Self, _: Ctx) Result {
|
||||
return self.cmd_async("toggle_panel");
|
||||
}
|
||||
pub const overlay_toggle_panel_meta: Meta = .{};
|
||||
|
||||
pub fn overlay_toggle_inputview(self: *Self, _: Ctx) Result {
|
||||
return self.cmd_async("toggle_inputview");
|
||||
}
|
||||
pub const overlay_toggle_inputview_meta: Meta = .{};
|
||||
|
||||
pub fn overlay_next_widget_style(self: *Self, _: Ctx) Result {
|
||||
tui.set_next_style(widget_type);
|
||||
self.do_resize();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
const std = @import("std");
|
||||
const command = @import("command");
|
||||
const tp = @import("thespian");
|
||||
const cmd = command.executeName;
|
||||
|
||||
const tui = @import("../tui.zig");
|
||||
const Editor = @import("../editor.zig").Editor;
|
||||
const Buffer = @import("Buffer");
|
||||
const Cursor = Buffer.Cursor;
|
||||
const View = Buffer.View;
|
||||
|
||||
var commands: Commands = undefined;
|
||||
const Self = Editor;
|
||||
|
||||
pub fn init() !void {
|
||||
var v: void = {};
|
||||
try commands.init(&v);
|
||||
const mv = tui.mainview() orelse return;
|
||||
const ed = mv.get_active_editor() orelse return;
|
||||
try commands.init(ed);
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
|
|
@ -14,74 +23,75 @@ pub fn deinit() void {
|
|||
}
|
||||
|
||||
const Commands = command.Collection(cmds_);
|
||||
const cmds_ = struct {
|
||||
pub const Target = void;
|
||||
const Ctx = command.Context;
|
||||
const Meta = command.Metadata;
|
||||
const Result = command.Result;
|
||||
const Context = command.Context;
|
||||
const Meta = command.Metadata;
|
||||
const Result = command.Result;
|
||||
|
||||
pub fn w(_: *void, _: Ctx) Result {
|
||||
const cmds_ = struct {
|
||||
pub const Target = Self;
|
||||
|
||||
pub fn w(_: *Self, _: Context) Result {
|
||||
try cmd("save_file", .{});
|
||||
}
|
||||
pub const w_meta: Meta = .{ .description = "w (write file)" };
|
||||
|
||||
pub fn q(_: *void, _: Ctx) Result {
|
||||
pub fn q(_: *Self, _: Context) Result {
|
||||
try cmd("quit", .{});
|
||||
}
|
||||
pub const q_meta: Meta = .{ .description = "q (quit)" };
|
||||
|
||||
pub fn @"q!"(_: *void, _: Ctx) Result {
|
||||
pub fn @"q!"(_: *Self, _: Context) Result {
|
||||
try cmd("quit_without_saving", .{});
|
||||
}
|
||||
pub const @"q!_meta": Meta = .{ .description = "q! (quit without saving)" };
|
||||
|
||||
pub fn @"qa!"(_: *void, _: Ctx) Result {
|
||||
pub fn @"qa!"(_: *Self, _: Context) Result {
|
||||
try cmd("quit_without_saving", .{});
|
||||
}
|
||||
pub const @"qa!_meta": Meta = .{ .description = "qa! (quit without saving anything)" };
|
||||
|
||||
pub fn wq(_: *void, _: Ctx) Result {
|
||||
pub fn wq(_: *Self, _: Context) Result {
|
||||
try cmd("save_file", command.fmt(.{ "then", .{ "quit", .{} } }));
|
||||
}
|
||||
pub const wq_meta: Meta = .{ .description = "wq (write file and quit)" };
|
||||
|
||||
pub fn @"wq!"(_: *void, _: Ctx) Result {
|
||||
pub fn @"wq!"(_: *Self, _: Context) Result {
|
||||
cmd("save_file", .{}) catch {};
|
||||
try cmd("quit_without_saving", .{});
|
||||
}
|
||||
pub const @"wq!_meta": Meta = .{ .description = "wq! (write file and quit without saving)" };
|
||||
|
||||
pub fn @"e!"(_: *void, _: Ctx) Result {
|
||||
pub fn @"e!"(_: *Self, _: Context) Result {
|
||||
try cmd("reload_file", .{});
|
||||
}
|
||||
pub const @"e!_meta": Meta = .{ .description = "e! (force reload current file)" };
|
||||
|
||||
pub fn bd(_: *void, _: Ctx) Result {
|
||||
pub fn bd(_: *Self, _: Context) Result {
|
||||
try cmd("close_file", .{});
|
||||
}
|
||||
pub const bd_meta: Meta = .{ .description = "bd (Close file)" };
|
||||
|
||||
pub fn bw(_: *void, _: Ctx) Result {
|
||||
pub fn bw(_: *Self, _: Context) Result {
|
||||
try cmd("delete_buffer", .{});
|
||||
}
|
||||
pub const bw_meta: Meta = .{ .description = "bw (Delete buffer)" };
|
||||
|
||||
pub fn bnext(_: *void, _: Ctx) Result {
|
||||
pub fn bnext(_: *Self, _: Context) Result {
|
||||
try cmd("next_tab", .{});
|
||||
}
|
||||
pub const bnext_meta: Meta = .{ .description = "bnext (Next buffer/tab)" };
|
||||
|
||||
pub fn bprevious(_: *void, _: Ctx) Result {
|
||||
pub fn bprevious(_: *Self, _: Context) Result {
|
||||
try cmd("next_tab", .{});
|
||||
}
|
||||
pub const bprevious_meta: Meta = .{ .description = "bprevious (Previous buffer/tab)" };
|
||||
|
||||
pub fn ls(_: *void, _: Ctx) Result {
|
||||
pub fn ls(_: *Self, _: Context) Result {
|
||||
try cmd("switch_buffers", .{});
|
||||
}
|
||||
pub const ls_meta: Meta = .{ .description = "ls (List/switch buffers)" };
|
||||
|
||||
pub fn move_begin_or_add_integer_argument_zero(_: *void, _: Ctx) Result {
|
||||
pub fn move_begin_or_add_integer_argument_zero(_: *Self, _: Context) Result {
|
||||
return if (@import("keybind").current_integer_argument()) |_|
|
||||
command.executeName("add_integer_argument_digit", command.fmt(.{0}))
|
||||
else
|
||||
|
|
@ -89,7 +99,7 @@ const cmds_ = struct {
|
|||
}
|
||||
pub const move_begin_or_add_integer_argument_zero_meta: Meta = .{ .description = "Move cursor to beginning of line (vim)" };
|
||||
|
||||
pub fn enter_mode_at_next_char(self: *void, ctx: Ctx) Result {
|
||||
pub fn enter_mode_at_next_char(self: *Self, ctx: Context) Result {
|
||||
_ = self; // autofix
|
||||
_ = ctx; // autofix
|
||||
//TODO
|
||||
|
|
@ -98,7 +108,7 @@ const cmds_ = struct {
|
|||
|
||||
pub const enter_mode_at_next_char_meta: Meta = .{ .description = "Move forward one char and change mode" };
|
||||
|
||||
pub fn enter_mode_on_newline_down(self: *void, ctx: Ctx) Result {
|
||||
pub fn enter_mode_on_newline_down(self: *Self, ctx: Context) Result {
|
||||
_ = self; // autofix
|
||||
_ = ctx; // autofix
|
||||
//TODO
|
||||
|
|
@ -107,7 +117,7 @@ const cmds_ = struct {
|
|||
|
||||
pub const enter_mode_on_newline_down_meta: Meta = .{ .description = "Insert a newline and change mode" };
|
||||
|
||||
pub fn enter_mode_on_newline_up(self: *void, ctx: Ctx) Result {
|
||||
pub fn enter_mode_on_newline_up(self: *Self, ctx: Context) Result {
|
||||
_ = self; // autofix
|
||||
_ = ctx; // autofix
|
||||
//TODO
|
||||
|
|
@ -115,7 +125,7 @@ const cmds_ = struct {
|
|||
}
|
||||
pub const enter_mode_on_newline_up_meta: Meta = .{ .description = "Insert a newline above the current line and change mode" };
|
||||
|
||||
pub fn enter_mode_at_line_begin(self: *void, ctx: Ctx) Result {
|
||||
pub fn enter_mode_at_line_begin(self: *Self, ctx: Context) Result {
|
||||
_ = self; // autofix
|
||||
_ = ctx; // autofix
|
||||
//TODO
|
||||
|
|
@ -124,7 +134,7 @@ const cmds_ = struct {
|
|||
|
||||
pub const enter_mode_at_line_begin_meta: Meta = .{ .description = "Goto line begin and change mode" };
|
||||
|
||||
pub fn enter_mode_at_line_end(self: *void, ctx: Ctx) Result {
|
||||
pub fn enter_mode_at_line_end(self: *Self, ctx: Context) Result {
|
||||
_ = self; // autofix
|
||||
_ = ctx; // autofix
|
||||
//TODO
|
||||
|
|
@ -132,7 +142,7 @@ const cmds_ = struct {
|
|||
}
|
||||
pub const enter_mode_at_line_end_meta: Meta = .{ .description = "Goto line end and change mode" };
|
||||
|
||||
pub fn copy_line(self: *void, ctx: Ctx) Result {
|
||||
pub fn copy_line(self: *Self, ctx: Context) Result {
|
||||
_ = self; // autofix
|
||||
_ = ctx; // autofix
|
||||
//TODO
|
||||
|
|
@ -140,4 +150,124 @@ const cmds_ = struct {
|
|||
}
|
||||
|
||||
pub const copy_line_meta: Meta = .{ .description = "Copies the current line" };
|
||||
|
||||
pub fn move_scroll_half_page_up(self: *Self, _: Context) Result {
|
||||
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_and_view_const(root, move_cursor_half_page_up, &self.view) catch {};
|
||||
const new_cursor_row = self.get_primary().cursor.row;
|
||||
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
|
||||
} else {
|
||||
return self.move_half_page_up(.{});
|
||||
}
|
||||
}
|
||||
pub const move_scroll_half_page_up_meta: Meta = .{ .description = "Move and scroll half a page up" };
|
||||
|
||||
pub fn move_scroll_half_page_down(self: *Self, _: Context) Result {
|
||||
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_and_view_const(root, move_cursor_half_page_down, &self.view) catch {};
|
||||
const new_cursor_row = self.get_primary().cursor.row;
|
||||
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
|
||||
} else {
|
||||
return self.move_half_page_down(.{});
|
||||
}
|
||||
}
|
||||
pub const move_scroll_half_page_down_meta: Meta = .{ .description = "Move and scroll half a page down" };
|
||||
|
||||
pub fn move_left_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_left_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_left_vim_meta: Meta = .{ .description = "Move cursor left (vim)", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_right_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_right_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_right_vim_meta: Meta = .{ .description = "Move cursor right (vim)", .arguments = &.{.integer} };
|
||||
|
||||
pub fn cut_to_end_vim(self: *Self, _: Context) Result {
|
||||
const b = try self.buf_for_update();
|
||||
const root = try self.cut_to(move_cursor_end_vim, b.root);
|
||||
try self.update_buf(root);
|
||||
self.clamp();
|
||||
}
|
||||
pub const cut_to_end_vim_meta: Meta = .{ .description = "Cut to end of line (vim)" };
|
||||
|
||||
pub fn move_up_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_up_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_up_vim_meta: Meta = .{ .description = "Move cursor up (vim)", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_down_vim(self: *Self, ctx: Context) Result {
|
||||
const root = try self.buf_root();
|
||||
self.with_cursors_const_repeat(root, move_cursor_down_vim, ctx) catch {};
|
||||
self.clamp();
|
||||
}
|
||||
pub const move_down_vim_meta: Meta = .{ .description = "Move cursor down (vim)", .arguments = &.{.integer} };
|
||||
|
||||
pub fn goto_line_vim(self: *Self, ctx: Context) Result {
|
||||
try self.send_editor_jump_source();
|
||||
var line: usize = 0;
|
||||
_ = ctx.args.match(.{tp.extract(&line)}) catch false;
|
||||
const root = self.buf_root() catch return;
|
||||
const primary = self.get_primary();
|
||||
try primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.metrics);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const goto_line_vim_meta: Meta = .{ .arguments = &.{.integer} };
|
||||
};
|
||||
|
||||
fn is_eol_right_vim(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
const line_width = root.line_width(cursor.row, metrics) catch return true;
|
||||
if (line_width == 0) return true;
|
||||
if (cursor.col >= line_width - 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
fn is_eol_vim(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
const line_width = root.line_width(cursor.row, metrics) catch return true;
|
||||
if (line_width == 0) return true;
|
||||
if (cursor.col >= line_width)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
fn move_cursor_half_page_up(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_half_page_up(root, view, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_half_page_down(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
|
||||
cursor.move_half_page_down(root, view, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_up_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
try cursor.move_up(root, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_down_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
try cursor.move_down(root, metrics);
|
||||
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_end_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
|
||||
Editor.move_cursor_right_until(root, cursor, is_eol_vim, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_left_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
Editor.move_cursor_left_unless(root, cursor, Editor.is_eol_left, metrics);
|
||||
}
|
||||
|
||||
fn move_cursor_right_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
Editor.move_cursor_right_unless(root, cursor, is_eol_right_vim, metrics);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const syntax = @import("syntax");
|
|||
|
||||
const Widget = @import("Widget.zig");
|
||||
const MessageFilter = @import("MessageFilter.zig");
|
||||
const MainView = @import("mainview.zig");
|
||||
pub const MainView = @import("mainview.zig");
|
||||
|
||||
// exports for unittesting
|
||||
pub const exports = struct {
|
||||
|
|
@ -1850,10 +1850,6 @@ pub fn is_cursor_beam() bool {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn get_selection_style() @import("Buffer").Selection.Style {
|
||||
return if (current().input_mode_) |mode| mode.selection_style else .normal;
|
||||
}
|
||||
|
||||
pub fn message(comptime fmt: anytype, args: anytype) void {
|
||||
var buf: [256]u8 = undefined;
|
||||
tp.self_pid().send(.{ "message", std.fmt.bufPrint(&buf, fmt, args) catch @panic("too large") }) catch {};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue