@@ -13,6 +13,7 @@ const Mode = enum {
1313 insert ,
1414 goto ,
1515 maybe_exit_insert ,
16+ select ,
1617};
1718
1819const Event = union (enum ) {
@@ -216,6 +217,7 @@ pub fn update(ctx: Vxim.UpdateContext) !Vxim.UpdateResult {
216217 .maybe_exit_insert = > {}, // Just keep whatever cursor is currently active.
217218 .normal = > ctx .root_win .setCursorShape (.block ),
218219 .goto = > ctx .root_win .setCursorShape (.block ),
220+ .select = > ctx .root_win .setCursorShape (.block ),
219221 }
220222 }
221223
@@ -241,6 +243,8 @@ fn editor(ctx: Vxim.UpdateContext, container: vaxis.Window) !void {
241243
242244 if (key .matches ('g' , .{})) state .mode = .goto ;
243245
246+ if (key .matches ('v' , .{})) state .mode = .select ;
247+
244248 if (key .matches ('h' , .{})) state .editor .moveSelectionsLeft ();
245249 if (key .matches (vaxis .Key .left , .{})) state .editor .moveSelectionsLeft ();
246250 if (key .matches ('j' , .{})) state .editor .moveSelectionsDown ();
@@ -297,6 +301,16 @@ fn editor(ctx: Vxim.UpdateContext, container: vaxis.Window) !void {
297301 if (key .text ) | text | try state .editor .insertTextAtCursors (state .gpa , text );
298302 state .mode = .insert ;
299303 }
304+ } else if (state .mode == .select ) {
305+ if (key .matches ('h' , .{})) state .editor .extendSelectionsLeft ();
306+ if (key .matches ('j' , .{})) state .editor .extendSelectionsDown ();
307+ if (key .matches ('k' , .{})) state .editor .extendSelectionsUp ();
308+ if (key .matches ('l' , .{})) state .editor .extendSelectionsRight ();
309+
310+ if (key .matches ('d' , .{})) try state .editor .deleteInsideSelections (state .gpa );
311+
312+ if (key .matches ('v' , .{})) state .mode = .normal ;
313+ if (key .matches (vaxis .Key .escape , .{})) state .mode = .normal ;
300314 }
301315
302316 if (key .matches ('s' , .{ .super = true })) try state .editor .saveFile (state .gpa );
@@ -337,6 +351,8 @@ fn editor(ctx: Vxim.UpdateContext, container: vaxis.Window) !void {
337351 else = > {},
338352 }
339353
354+ // Draw text.
355+ // FIXME: no need to draw to the end of the file.
340356 for (state .v_scroll .. state .editor .lineCount ()) | idx | {
341357 const line = state .editor .getLine (idx );
342358
@@ -347,6 +363,54 @@ fn editor(ctx: Vxim.UpdateContext, container: vaxis.Window) !void {
347363 .{ .row_offset = @intCast (idx - | state .v_scroll ), .wrap = .none },
348364 );
349365 }
366+
367+ // Draw selections.
368+ for (state .editor .selections .items ) | s | {
369+ // If no part of this selection is visible we can skip rendering it.
370+ if ((s .cursor .row < state .v_scroll or s .cursor .row > state .v_scroll + | container .height ) and
371+ (s .anchor .row < state .v_scroll or s .anchor .row > state .v_scroll + | container .height ))
372+ {
373+ continue ;
374+ }
375+
376+ const row_start = s .toRange ().before ().row - | state .v_scroll ;
377+ const line_start = state .editor .getLine (row_start );
378+ const col_start = if (s .toRange ().before ().row < state .v_scroll )
379+ 0
380+ else
381+ @min (s .toRange ().before ().col - | state .h_scroll , line_start .len - | state .h_scroll );
382+
383+ const row_end = @min (s .toRange ().after ().row - | state .v_scroll , state .v_scroll + | container .height );
384+ const line_end = state .editor .getLine (row_end );
385+ const col_end = if (s .toRange ().after ().row > state .v_scroll + | container .height )
386+ line_end .len - | state .h_scroll
387+ else
388+ s .toRange ().after ().col - | state .h_scroll ;
389+
390+ var row_it = row_start ;
391+
392+ std .debug .assert (
393+ row_start < row_end or
394+ (row_start == row_end and col_start <= col_end ),
395+ );
396+
397+ while (row_it <= row_end ) {
398+ const line = state .editor .getLine (row_it );
399+
400+ const start = if (row_it == row_start ) col_start else 0 ;
401+ const end = if (row_it == row_end ) col_end else line .len - | state .h_scroll ;
402+
403+ for (start .. end ) | cell_col | {
404+ if (container .readCell (@intCast (cell_col ), @intCast (row_it ))) | cell | {
405+ var new_cell = cell ;
406+ new_cell .style = .{ .reverse = true };
407+ container .writeCell (@intCast (cell_col ), @intCast (row_it ), new_cell );
408+ }
409+ }
410+
411+ row_it + |= 1 ;
412+ }
413+ }
350414}
351415
352416test "refAllDecls" {
0 commit comments