@@ -178,7 +178,7 @@ static const struct nv_cmd {
178178 { Ctrl_G , nv_ctrlg , 0 , 0 },
179179 { Ctrl_H , nv_ctrlh , 0 , 0 },
180180 { Ctrl_I , nv_pcmark , 0 , 0 },
181- { NL , nv_down , 0 , false },
181+ { NL , nv_win_visual_enter , 0 , false },
182182 { Ctrl_K , nv_error , 0 , 0 },
183183 { Ctrl_L , nv_clear , 0 , 0 },
184184 { CAR , nv_down , 0 , true },
@@ -190,11 +190,11 @@ static const struct nv_cmd {
190190 { Ctrl_S , nv_ignore , 0 , 0 },
191191 { Ctrl_T , nv_tagpop , NV_NCW , 0 },
192192 { Ctrl_U , nv_halfpage , 0 , 0 },
193- { Ctrl_V , nv_visual , 0 , false },
193+ { Ctrl_V , nv_win_paste , 0 , false },
194194 { 'V' , nv_visual , 0 , false },
195195 { 'v' , nv_visual , 0 , false },
196196 { Ctrl_W , nv_window , 0 , 0 },
197- { Ctrl_X , nv_addsub , 0 , 0 },
197+ { Ctrl_X , nv_win_cut , 0 , 0 },
198198 { Ctrl_Y , nv_scroll_line , 0 , false },
199199 { Ctrl_Z , nv_suspend , 0 , 0 },
200200 { ESC , nv_esc , 0 , false },
@@ -326,14 +326,14 @@ static const struct nv_cmd {
326326 { K_KINS , nv_edit , 0 , 0 },
327327 { K_BS , nv_ctrlh , 0 , 0 },
328328 { K_UP , nv_up , NV_SSS |NV_STS , false },
329- { K_S_UP , nv_page , NV_SS , BACKWARD },
329+ { K_S_UP , nv_win_shift_arrow , NV_SS , BACKWARD },
330330 { K_DOWN , nv_down , NV_SSS |NV_STS , false },
331- { K_S_DOWN , nv_page , NV_SS , FORWARD },
331+ { K_S_DOWN , nv_win_shift_arrow , NV_SS , FORWARD },
332332 { K_LEFT , nv_left , NV_SSS |NV_STS |NV_RL , 0 },
333- { K_S_LEFT , nv_bck_word , NV_SS |NV_RL , 0 },
333+ { K_S_LEFT , nv_win_shift_arrow , NV_SS |NV_RL , 0 },
334334 { K_C_LEFT , nv_bck_word , NV_SSS |NV_RL |NV_STS , 1 },
335335 { K_RIGHT , nv_right , NV_SSS |NV_STS |NV_RL , 0 },
336- { K_S_RIGHT , nv_wordcmd , NV_SS |NV_RL , false },
336+ { K_S_RIGHT , nv_win_shift_arrow , NV_SS |NV_RL , false },
337337 { K_C_RIGHT , nv_wordcmd , NV_SSS |NV_RL |NV_STS , true },
338338 { K_PAGEUP , nv_page , NV_SSS |NV_STS , BACKWARD },
339339 { K_KPAGEUP , nv_page , NV_SSS |NV_STS , BACKWARD },
@@ -6152,6 +6152,24 @@ static void nv_esc(cmdarg_T *cap)
61526152 // Brutal mode: Removed ESC detection (was unreliable)
61536153
61546154 if (cap -> arg ) { // true for CTRL-C
6155+ // EASY mode: Ctrl+C in visual mode copies to clipboard
6156+ if (VIsual_active && brutal_mode == BRUTAL_EASY ) {
6157+ // Set up yank operator - use unnamed register (0 means use default)
6158+ // This ensures yank works even without clipboard provider
6159+ cap -> oap -> regname = 0 ; // Use unnamed/default register
6160+ cap -> oap -> op_type = OP_YANK ;
6161+ cap -> cmdchar = 'y' ; // Simulate 'y' command for do_pending_operator
6162+
6163+ // Call do_pending_operator to execute the yank on the visual selection
6164+ do_pending_operator (cap , curwin -> w_curswant , false);
6165+
6166+ // Ensure clean state after operation
6167+ clearop (cap -> oap );
6168+ // Clear got_int which may have been set by Ctrl+C signal
6169+ got_int = false;
6170+ return ;
6171+ }
6172+
61556173 if (restart_edit == 0 && cmdwin_type == 0 && !VIsual_active && no_reason ) {
61566174 if (anyBufIsChanged ()) {
61576175 msg (_ ("Type :qa! and press <Enter> to abandon all changes"
@@ -6666,6 +6684,102 @@ static void nv_event(cmdarg_T *cap)
66666684 }
66676685}
66686686
6687+ /// Windows-style Ctrl+X: Cut to clipboard (EASY mode only)
6688+ static void nv_win_cut (cmdarg_T * cap )
6689+ {
6690+ if (brutal_mode != BRUTAL_EASY ) {
6691+ // Not in EASY mode, use default Ctrl+X behavior (number decrement)
6692+ nv_addsub (cap );
6693+ return ;
6694+ }
6695+
6696+ if (VIsual_active ) {
6697+ // Visual mode: cut selection to clipboard
6698+ cap -> oap -> regname = '+' ;
6699+ cap -> cmdchar = 'd' ;
6700+ nv_operator (cap );
6701+ } else {
6702+ // Normal mode: cut entire line to clipboard
6703+ cap -> oap -> regname = '+' ;
6704+ cap -> cmdchar = 'd' ;
6705+ cap -> cmdchar = 'd' ; // dd
6706+ nv_operator (cap );
6707+ }
6708+ }
6709+
6710+ /// Windows-style Ctrl+V: Paste from clipboard (EASY mode only)
6711+ static void nv_win_paste (cmdarg_T * cap )
6712+ {
6713+ if (brutal_mode != BRUTAL_EASY ) {
6714+ // Not in EASY mode, use default Ctrl+V behavior (visual block)
6715+ nv_visual (cap );
6716+ return ;
6717+ }
6718+
6719+ // Paste from clipboard register '+'
6720+ cap -> oap -> regname = '+' ;
6721+ cap -> cmdchar = 'p' ;
6722+ nv_put (cap );
6723+ }
6724+
6725+ /// Enter in visual mode: Copy and exit (EASY mode only)
6726+ static void nv_win_visual_enter (cmdarg_T * cap )
6727+ {
6728+ if (brutal_mode != BRUTAL_EASY || !VIsual_active ) {
6729+ // Not in EASY mode or not in visual - default Enter behavior
6730+ nv_down (cap );
6731+ return ;
6732+ }
6733+
6734+ // Copy to clipboard and exit visual mode
6735+ cap -> oap -> regname = '+' ;
6736+ cap -> oap -> op_type = OP_YANK ;
6737+ op_yank (cap -> oap , false);
6738+ end_visual_mode ();
6739+ check_cursor_col (curwin );
6740+ curwin -> w_set_curswant = true;
6741+ redraw_curbuf_later (UPD_INVERTED );
6742+ clearop (cap -> oap );
6743+ }
6744+
6745+ /// Shift+Arrow: Start/extend visual selection (EASY mode only)
6746+ static void nv_win_shift_arrow (cmdarg_T * cap )
6747+ {
6748+ if (brutal_mode != BRUTAL_EASY ) {
6749+ // Not in EASY mode - use default behavior
6750+ if (cap -> cmdchar == K_S_UP ) {
6751+ nv_page (cap );
6752+ } else if (cap -> cmdchar == K_S_DOWN ) {
6753+ nv_page (cap );
6754+ } else if (cap -> cmdchar == K_S_LEFT ) {
6755+ nv_bck_word (cap );
6756+ } else if (cap -> cmdchar == K_S_RIGHT ) {
6757+ nv_wordcmd (cap );
6758+ }
6759+ return ;
6760+ }
6761+
6762+ // EASY mode: Start visual selection if not already active
6763+ // Use Visual mode (not Select mode) for Windows-style selection
6764+ if (!VIsual_active ) {
6765+ VIsual_select = false; // Ensure we're in Visual, not Select mode
6766+ n_start_visual_mode ('v' );
6767+ }
6768+
6769+ // Move cursor based on arrow key - visual mode extends automatically
6770+ if (cap -> cmdchar == K_S_UP ) {
6771+ cap -> arg = false; // nv_up expects this
6772+ nv_up (cap );
6773+ } else if (cap -> cmdchar == K_S_DOWN ) {
6774+ cap -> arg = false;
6775+ nv_down (cap );
6776+ } else if (cap -> cmdchar == K_S_LEFT ) {
6777+ nv_left (cap );
6778+ } else if (cap -> cmdchar == K_S_RIGHT ) {
6779+ nv_right (cap );
6780+ }
6781+ }
6782+
66696783void normal_cmd (oparg_T * oap , bool toplevel )
66706784{
66716785 NormalState s ;
0 commit comments