Mercurial > vim
comparison src/normal.c @ 18135:1868ec23360e v8.1.2062
patch 8.1.2062: the mouse code is spread out
Commit: https://github.com/vim/vim/commit/b20b9e14ddd8db111e886ad0494e15b955159426
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Sep 21 20:48:04 2019 +0200
patch 8.1.2062: the mouse code is spread out
Problem: The mouse code is spread out.
Solution: Move all the mouse code to mouse.c. (Yegappan Lakshmanan,
closes #4959)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 21 Sep 2019 21:00:07 +0200 |
parents | aeabc666a119 |
children | 5e10ee16f4b4 |
comparison
equal
deleted
inserted
replaced
18134:c06a2bc8144f | 18135:1868ec23360e |
---|---|
28 static void set_vcount_ca(cmdarg_T *cap, int *set_prevcount); | 28 static void set_vcount_ca(cmdarg_T *cap, int *set_prevcount); |
29 #endif | 29 #endif |
30 static int nv_compare(const void *s1, const void *s2); | 30 static int nv_compare(const void *s1, const void *s2); |
31 static void op_colon(oparg_T *oap); | 31 static void op_colon(oparg_T *oap); |
32 static void op_function(oparg_T *oap); | 32 static void op_function(oparg_T *oap); |
33 #if defined(FEAT_MOUSE) | |
34 static void find_start_of_word(pos_T *); | |
35 static void find_end_of_word(pos_T *); | |
36 static int get_mouse_class(char_u *p); | |
37 #endif | |
38 static void prep_redo(int regname, long, int, int, int, int, int); | |
39 static void clearop(oparg_T *oap); | |
40 static void clearopbeep(oparg_T *oap); | |
41 static void unshift_special(cmdarg_T *cap); | 33 static void unshift_special(cmdarg_T *cap); |
42 static void may_clear_cmdline(void); | 34 static void may_clear_cmdline(void); |
43 #ifdef FEAT_CMDL_INFO | 35 #ifdef FEAT_CMDL_INFO |
44 static void del_from_showcmd(int); | 36 static void del_from_showcmd(int); |
45 #endif | 37 #endif |
53 static void nv_nop(cmdarg_T *cap); | 45 static void nv_nop(cmdarg_T *cap); |
54 static void nv_error(cmdarg_T *cap); | 46 static void nv_error(cmdarg_T *cap); |
55 static void nv_help(cmdarg_T *cap); | 47 static void nv_help(cmdarg_T *cap); |
56 static void nv_addsub(cmdarg_T *cap); | 48 static void nv_addsub(cmdarg_T *cap); |
57 static void nv_page(cmdarg_T *cap); | 49 static void nv_page(cmdarg_T *cap); |
58 #ifdef FEAT_MOUSE | |
59 static void nv_mousescroll(cmdarg_T *cap); | |
60 static void nv_mouse(cmdarg_T *cap); | |
61 #endif | |
62 static void nv_scroll_line(cmdarg_T *cap); | |
63 static void nv_zet(cmdarg_T *cap); | 50 static void nv_zet(cmdarg_T *cap); |
64 #ifdef FEAT_GUI | 51 #ifdef FEAT_GUI |
65 static void nv_ver_scrollbar(cmdarg_T *cap); | 52 static void nv_ver_scrollbar(cmdarg_T *cap); |
66 static void nv_hor_scrollbar(cmdarg_T *cap); | 53 static void nv_hor_scrollbar(cmdarg_T *cap); |
67 #endif | 54 #endif |
2199 #else | 2186 #else |
2200 emsg(_("E775: Eval feature not available")); | 2187 emsg(_("E775: Eval feature not available")); |
2201 #endif | 2188 #endif |
2202 } | 2189 } |
2203 | 2190 |
2204 #if defined(FEAT_MOUSE) || defined(PROTO) | |
2205 /* | |
2206 * Do the appropriate action for the current mouse click in the current mode. | |
2207 * Not used for Command-line mode. | |
2208 * | |
2209 * Normal and Visual Mode: | |
2210 * event modi- position visual change action | |
2211 * fier cursor window | |
2212 * left press - yes end yes | |
2213 * left press C yes end yes "^]" (2) | |
2214 * left press S yes end (popup: extend) yes "*" (2) | |
2215 * left drag - yes start if moved no | |
2216 * left relse - yes start if moved no | |
2217 * middle press - yes if not active no put register | |
2218 * middle press - yes if active no yank and put | |
2219 * right press - yes start or extend yes | |
2220 * right press S yes no change yes "#" (2) | |
2221 * right drag - yes extend no | |
2222 * right relse - yes extend no | |
2223 * | |
2224 * Insert or Replace Mode: | |
2225 * event modi- position visual change action | |
2226 * fier cursor window | |
2227 * left press - yes (cannot be active) yes | |
2228 * left press C yes (cannot be active) yes "CTRL-O^]" (2) | |
2229 * left press S yes (cannot be active) yes "CTRL-O*" (2) | |
2230 * left drag - yes start or extend (1) no CTRL-O (1) | |
2231 * left relse - yes start or extend (1) no CTRL-O (1) | |
2232 * middle press - no (cannot be active) no put register | |
2233 * right press - yes start or extend yes CTRL-O | |
2234 * right press S yes (cannot be active) yes "CTRL-O#" (2) | |
2235 * | |
2236 * (1) only if mouse pointer moved since press | |
2237 * (2) only if click is in same buffer | |
2238 * | |
2239 * Return TRUE if start_arrow() should be called for edit mode. | |
2240 */ | |
2241 int | |
2242 do_mouse( | |
2243 oparg_T *oap, /* operator argument, can be NULL */ | |
2244 int c, /* K_LEFTMOUSE, etc */ | |
2245 int dir, /* Direction to 'put' if necessary */ | |
2246 long count, | |
2247 int fixindent) /* PUT_FIXINDENT if fixing indent necessary */ | |
2248 { | |
2249 static int do_always = FALSE; /* ignore 'mouse' setting next time */ | |
2250 static int got_click = FALSE; /* got a click some time back */ | |
2251 | |
2252 int which_button; /* MOUSE_LEFT, _MIDDLE or _RIGHT */ | |
2253 int is_click; /* If FALSE it's a drag or release event */ | |
2254 int is_drag; /* If TRUE it's a drag event */ | |
2255 int jump_flags = 0; /* flags for jump_to_mouse() */ | |
2256 pos_T start_visual; | |
2257 int moved; /* Has cursor moved? */ | |
2258 int in_status_line; /* mouse in status line */ | |
2259 static int in_tab_line = FALSE; /* mouse clicked in tab line */ | |
2260 int in_sep_line; /* mouse in vertical separator line */ | |
2261 int c1, c2; | |
2262 #if defined(FEAT_FOLDING) | |
2263 pos_T save_cursor; | |
2264 #endif | |
2265 win_T *old_curwin = curwin; | |
2266 static pos_T orig_cursor; | |
2267 colnr_T leftcol, rightcol; | |
2268 pos_T end_visual; | |
2269 int diff; | |
2270 int old_active = VIsual_active; | |
2271 int old_mode = VIsual_mode; | |
2272 int regname; | |
2273 | |
2274 #if defined(FEAT_FOLDING) | |
2275 save_cursor = curwin->w_cursor; | |
2276 #endif | |
2277 | |
2278 /* | |
2279 * When GUI is active, always recognize mouse events, otherwise: | |
2280 * - Ignore mouse event in normal mode if 'mouse' doesn't include 'n'. | |
2281 * - Ignore mouse event in visual mode if 'mouse' doesn't include 'v'. | |
2282 * - For command line and insert mode 'mouse' is checked before calling | |
2283 * do_mouse(). | |
2284 */ | |
2285 if (do_always) | |
2286 do_always = FALSE; | |
2287 else | |
2288 #ifdef FEAT_GUI | |
2289 if (!gui.in_use) | |
2290 #endif | |
2291 { | |
2292 if (VIsual_active) | |
2293 { | |
2294 if (!mouse_has(MOUSE_VISUAL)) | |
2295 return FALSE; | |
2296 } | |
2297 else if (State == NORMAL && !mouse_has(MOUSE_NORMAL)) | |
2298 return FALSE; | |
2299 } | |
2300 | |
2301 for (;;) | |
2302 { | |
2303 which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag); | |
2304 if (is_drag) | |
2305 { | |
2306 /* If the next character is the same mouse event then use that | |
2307 * one. Speeds up dragging the status line. */ | |
2308 if (vpeekc() != NUL) | |
2309 { | |
2310 int nc; | |
2311 int save_mouse_row = mouse_row; | |
2312 int save_mouse_col = mouse_col; | |
2313 | |
2314 /* Need to get the character, peeking doesn't get the actual | |
2315 * one. */ | |
2316 nc = safe_vgetc(); | |
2317 if (c == nc) | |
2318 continue; | |
2319 vungetc(nc); | |
2320 mouse_row = save_mouse_row; | |
2321 mouse_col = save_mouse_col; | |
2322 } | |
2323 } | |
2324 break; | |
2325 } | |
2326 | |
2327 if (c == K_MOUSEMOVE) | |
2328 { | |
2329 // Mouse moved without a button pressed. | |
2330 #ifdef FEAT_BEVAL_TERM | |
2331 ui_may_remove_balloon(); | |
2332 if (p_bevalterm) | |
2333 { | |
2334 profile_setlimit(p_bdlay, &bevalexpr_due); | |
2335 bevalexpr_due_set = TRUE; | |
2336 } | |
2337 #endif | |
2338 #ifdef FEAT_TEXT_PROP | |
2339 popup_handle_mouse_moved(); | |
2340 #endif | |
2341 return FALSE; | |
2342 } | |
2343 | |
2344 #ifdef FEAT_MOUSESHAPE | |
2345 /* May have stopped dragging the status or separator line. The pointer is | |
2346 * most likely still on the status or separator line. */ | |
2347 if (!is_drag && drag_status_line) | |
2348 { | |
2349 drag_status_line = FALSE; | |
2350 update_mouseshape(SHAPE_IDX_STATUS); | |
2351 } | |
2352 if (!is_drag && drag_sep_line) | |
2353 { | |
2354 drag_sep_line = FALSE; | |
2355 update_mouseshape(SHAPE_IDX_VSEP); | |
2356 } | |
2357 #endif | |
2358 | |
2359 /* | |
2360 * Ignore drag and release events if we didn't get a click. | |
2361 */ | |
2362 if (is_click) | |
2363 got_click = TRUE; | |
2364 else | |
2365 { | |
2366 if (!got_click) /* didn't get click, ignore */ | |
2367 return FALSE; | |
2368 if (!is_drag) /* release, reset got_click */ | |
2369 { | |
2370 got_click = FALSE; | |
2371 if (in_tab_line) | |
2372 { | |
2373 in_tab_line = FALSE; | |
2374 return FALSE; | |
2375 } | |
2376 } | |
2377 } | |
2378 | |
2379 /* | |
2380 * CTRL right mouse button does CTRL-T | |
2381 */ | |
2382 if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT) | |
2383 { | |
2384 if (State & INSERT) | |
2385 stuffcharReadbuff(Ctrl_O); | |
2386 if (count > 1) | |
2387 stuffnumReadbuff(count); | |
2388 stuffcharReadbuff(Ctrl_T); | |
2389 got_click = FALSE; /* ignore drag&release now */ | |
2390 return FALSE; | |
2391 } | |
2392 | |
2393 /* | |
2394 * CTRL only works with left mouse button | |
2395 */ | |
2396 if ((mod_mask & MOD_MASK_CTRL) && which_button != MOUSE_LEFT) | |
2397 return FALSE; | |
2398 | |
2399 /* | |
2400 * When a modifier is down, ignore drag and release events, as well as | |
2401 * multiple clicks and the middle mouse button. | |
2402 * Accept shift-leftmouse drags when 'mousemodel' is "popup.*". | |
2403 */ | |
2404 if ((mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT | |
2405 | MOD_MASK_META)) | |
2406 && (!is_click | |
2407 || (mod_mask & MOD_MASK_MULTI_CLICK) | |
2408 || which_button == MOUSE_MIDDLE) | |
2409 && !((mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT)) | |
2410 && mouse_model_popup() | |
2411 && which_button == MOUSE_LEFT) | |
2412 && !((mod_mask & MOD_MASK_ALT) | |
2413 && !mouse_model_popup() | |
2414 && which_button == MOUSE_RIGHT) | |
2415 ) | |
2416 return FALSE; | |
2417 | |
2418 /* | |
2419 * If the button press was used as the movement command for an operator | |
2420 * (eg "d<MOUSE>"), or it is the middle button that is held down, ignore | |
2421 * drag/release events. | |
2422 */ | |
2423 if (!is_click && which_button == MOUSE_MIDDLE) | |
2424 return FALSE; | |
2425 | |
2426 if (oap != NULL) | |
2427 regname = oap->regname; | |
2428 else | |
2429 regname = 0; | |
2430 | |
2431 /* | |
2432 * Middle mouse button does a 'put' of the selected text | |
2433 */ | |
2434 if (which_button == MOUSE_MIDDLE) | |
2435 { | |
2436 if (State == NORMAL) | |
2437 { | |
2438 /* | |
2439 * If an operator was pending, we don't know what the user wanted | |
2440 * to do. Go back to normal mode: Clear the operator and beep(). | |
2441 */ | |
2442 if (oap != NULL && oap->op_type != OP_NOP) | |
2443 { | |
2444 clearopbeep(oap); | |
2445 return FALSE; | |
2446 } | |
2447 | |
2448 /* | |
2449 * If visual was active, yank the highlighted text and put it | |
2450 * before the mouse pointer position. | |
2451 * In Select mode replace the highlighted text with the clipboard. | |
2452 */ | |
2453 if (VIsual_active) | |
2454 { | |
2455 if (VIsual_select) | |
2456 { | |
2457 stuffcharReadbuff(Ctrl_G); | |
2458 stuffReadbuff((char_u *)"\"+p"); | |
2459 } | |
2460 else | |
2461 { | |
2462 stuffcharReadbuff('y'); | |
2463 stuffcharReadbuff(K_MIDDLEMOUSE); | |
2464 } | |
2465 do_always = TRUE; /* ignore 'mouse' setting next time */ | |
2466 return FALSE; | |
2467 } | |
2468 /* | |
2469 * The rest is below jump_to_mouse() | |
2470 */ | |
2471 } | |
2472 | |
2473 else if ((State & INSERT) == 0) | |
2474 return FALSE; | |
2475 | |
2476 /* | |
2477 * Middle click in insert mode doesn't move the mouse, just insert the | |
2478 * contents of a register. '.' register is special, can't insert that | |
2479 * with do_put(). | |
2480 * Also paste at the cursor if the current mode isn't in 'mouse' (only | |
2481 * happens for the GUI). | |
2482 */ | |
2483 if ((State & INSERT) || !mouse_has(MOUSE_NORMAL)) | |
2484 { | |
2485 if (regname == '.') | |
2486 insert_reg(regname, TRUE); | |
2487 else | |
2488 { | |
2489 #ifdef FEAT_CLIPBOARD | |
2490 if (clip_star.available && regname == 0) | |
2491 regname = '*'; | |
2492 #endif | |
2493 if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) | |
2494 insert_reg(regname, TRUE); | |
2495 else | |
2496 { | |
2497 do_put(regname, BACKWARD, 1L, fixindent | PUT_CURSEND); | |
2498 | |
2499 /* Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r */ | |
2500 AppendCharToRedobuff(Ctrl_R); | |
2501 AppendCharToRedobuff(fixindent ? Ctrl_P : Ctrl_O); | |
2502 AppendCharToRedobuff(regname == 0 ? '"' : regname); | |
2503 } | |
2504 } | |
2505 return FALSE; | |
2506 } | |
2507 } | |
2508 | |
2509 /* When dragging or button-up stay in the same window. */ | |
2510 if (!is_click) | |
2511 jump_flags |= MOUSE_FOCUS | MOUSE_DID_MOVE; | |
2512 | |
2513 start_visual.lnum = 0; | |
2514 | |
2515 /* Check for clicking in the tab page line. */ | |
2516 if (mouse_row == 0 && firstwin->w_winrow > 0) | |
2517 { | |
2518 if (is_drag) | |
2519 { | |
2520 if (in_tab_line) | |
2521 { | |
2522 c1 = TabPageIdxs[mouse_col]; | |
2523 tabpage_move(c1 <= 0 ? 9999 : c1 < tabpage_index(curtab) | |
2524 ? c1 - 1 : c1); | |
2525 } | |
2526 return FALSE; | |
2527 } | |
2528 | |
2529 /* click in a tab selects that tab page */ | |
2530 if (is_click | |
2531 # ifdef FEAT_CMDWIN | |
2532 && cmdwin_type == 0 | |
2533 # endif | |
2534 && mouse_col < Columns) | |
2535 { | |
2536 in_tab_line = TRUE; | |
2537 c1 = TabPageIdxs[mouse_col]; | |
2538 if (c1 >= 0) | |
2539 { | |
2540 if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) | |
2541 { | |
2542 /* double click opens new page */ | |
2543 end_visual_mode(); | |
2544 tabpage_new(); | |
2545 tabpage_move(c1 == 0 ? 9999 : c1 - 1); | |
2546 } | |
2547 else | |
2548 { | |
2549 /* Go to specified tab page, or next one if not clicking | |
2550 * on a label. */ | |
2551 goto_tabpage(c1); | |
2552 | |
2553 /* It's like clicking on the status line of a window. */ | |
2554 if (curwin != old_curwin) | |
2555 end_visual_mode(); | |
2556 } | |
2557 } | |
2558 else | |
2559 { | |
2560 tabpage_T *tp; | |
2561 | |
2562 /* Close the current or specified tab page. */ | |
2563 if (c1 == -999) | |
2564 tp = curtab; | |
2565 else | |
2566 tp = find_tabpage(-c1); | |
2567 if (tp == curtab) | |
2568 { | |
2569 if (first_tabpage->tp_next != NULL) | |
2570 tabpage_close(FALSE); | |
2571 } | |
2572 else if (tp != NULL) | |
2573 tabpage_close_other(tp, FALSE); | |
2574 } | |
2575 } | |
2576 return TRUE; | |
2577 } | |
2578 else if (is_drag && in_tab_line) | |
2579 { | |
2580 c1 = TabPageIdxs[mouse_col]; | |
2581 tabpage_move(c1 <= 0 ? 9999 : c1 - 1); | |
2582 return FALSE; | |
2583 } | |
2584 | |
2585 /* | |
2586 * When 'mousemodel' is "popup" or "popup_setpos", translate mouse events: | |
2587 * right button up -> pop-up menu | |
2588 * shift-left button -> right button | |
2589 * alt-left button -> alt-right button | |
2590 */ | |
2591 if (mouse_model_popup()) | |
2592 { | |
2593 if (which_button == MOUSE_RIGHT | |
2594 && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) | |
2595 { | |
2596 #if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \ | |
2597 || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \ | |
2598 || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_PHOTON) \ | |
2599 || defined(FEAT_TERM_POPUP_MENU) | |
2600 # ifdef FEAT_GUI | |
2601 if (gui.in_use) | |
2602 { | |
2603 # if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \ | |
2604 || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) | |
2605 if (!is_click) | |
2606 /* Ignore right button release events, only shows the popup | |
2607 * menu on the button down event. */ | |
2608 return FALSE; | |
2609 # endif | |
2610 # if defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) | |
2611 if (is_click || is_drag) | |
2612 /* Ignore right button down and drag mouse events. Windows | |
2613 * only shows the popup menu on the button up event. */ | |
2614 return FALSE; | |
2615 # endif | |
2616 } | |
2617 # endif | |
2618 # if defined(FEAT_GUI) && defined(FEAT_TERM_POPUP_MENU) | |
2619 else | |
2620 # endif | |
2621 # if defined(FEAT_TERM_POPUP_MENU) | |
2622 if (!is_click) | |
2623 /* Ignore right button release events, only shows the popup | |
2624 * menu on the button down event. */ | |
2625 return FALSE; | |
2626 #endif | |
2627 | |
2628 jump_flags = 0; | |
2629 if (STRCMP(p_mousem, "popup_setpos") == 0) | |
2630 { | |
2631 /* First set the cursor position before showing the popup | |
2632 * menu. */ | |
2633 if (VIsual_active) | |
2634 { | |
2635 pos_T m_pos; | |
2636 | |
2637 /* | |
2638 * set MOUSE_MAY_STOP_VIS if we are outside the | |
2639 * selection or the current window (might have false | |
2640 * negative here) | |
2641 */ | |
2642 if (mouse_row < curwin->w_winrow | |
2643 || mouse_row | |
2644 > (curwin->w_winrow + curwin->w_height)) | |
2645 jump_flags = MOUSE_MAY_STOP_VIS; | |
2646 else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER) | |
2647 jump_flags = MOUSE_MAY_STOP_VIS; | |
2648 else | |
2649 { | |
2650 if ((LT_POS(curwin->w_cursor, VIsual) | |
2651 && (LT_POS(m_pos, curwin->w_cursor) | |
2652 || LT_POS(VIsual, m_pos))) | |
2653 || (LT_POS(VIsual, curwin->w_cursor) | |
2654 && (LT_POS(m_pos, VIsual) | |
2655 || LT_POS(curwin->w_cursor, m_pos)))) | |
2656 { | |
2657 jump_flags = MOUSE_MAY_STOP_VIS; | |
2658 } | |
2659 else if (VIsual_mode == Ctrl_V) | |
2660 { | |
2661 getvcols(curwin, &curwin->w_cursor, &VIsual, | |
2662 &leftcol, &rightcol); | |
2663 getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL); | |
2664 if (m_pos.col < leftcol || m_pos.col > rightcol) | |
2665 jump_flags = MOUSE_MAY_STOP_VIS; | |
2666 } | |
2667 } | |
2668 } | |
2669 else | |
2670 jump_flags = MOUSE_MAY_STOP_VIS; | |
2671 } | |
2672 if (jump_flags) | |
2673 { | |
2674 jump_flags = jump_to_mouse(jump_flags, NULL, which_button); | |
2675 update_curbuf(VIsual_active ? INVERTED : VALID); | |
2676 setcursor(); | |
2677 out_flush(); /* Update before showing popup menu */ | |
2678 } | |
2679 # ifdef FEAT_MENU | |
2680 show_popupmenu(); | |
2681 got_click = FALSE; /* ignore release events */ | |
2682 # endif | |
2683 return (jump_flags & CURSOR_MOVED) != 0; | |
2684 #else | |
2685 return FALSE; | |
2686 #endif | |
2687 } | |
2688 if (which_button == MOUSE_LEFT | |
2689 && (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT))) | |
2690 { | |
2691 which_button = MOUSE_RIGHT; | |
2692 mod_mask &= ~MOD_MASK_SHIFT; | |
2693 } | |
2694 } | |
2695 | |
2696 if ((State & (NORMAL | INSERT)) | |
2697 && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) | |
2698 { | |
2699 if (which_button == MOUSE_LEFT) | |
2700 { | |
2701 if (is_click) | |
2702 { | |
2703 /* stop Visual mode for a left click in a window, but not when | |
2704 * on a status line */ | |
2705 if (VIsual_active) | |
2706 jump_flags |= MOUSE_MAY_STOP_VIS; | |
2707 } | |
2708 else if (mouse_has(MOUSE_VISUAL)) | |
2709 jump_flags |= MOUSE_MAY_VIS; | |
2710 } | |
2711 else if (which_button == MOUSE_RIGHT) | |
2712 { | |
2713 if (is_click && VIsual_active) | |
2714 { | |
2715 /* | |
2716 * Remember the start and end of visual before moving the | |
2717 * cursor. | |
2718 */ | |
2719 if (LT_POS(curwin->w_cursor, VIsual)) | |
2720 { | |
2721 start_visual = curwin->w_cursor; | |
2722 end_visual = VIsual; | |
2723 } | |
2724 else | |
2725 { | |
2726 start_visual = VIsual; | |
2727 end_visual = curwin->w_cursor; | |
2728 } | |
2729 } | |
2730 jump_flags |= MOUSE_FOCUS; | |
2731 if (mouse_has(MOUSE_VISUAL)) | |
2732 jump_flags |= MOUSE_MAY_VIS; | |
2733 } | |
2734 } | |
2735 | |
2736 /* | |
2737 * If an operator is pending, ignore all drags and releases until the | |
2738 * next mouse click. | |
2739 */ | |
2740 if (!is_drag && oap != NULL && oap->op_type != OP_NOP) | |
2741 { | |
2742 got_click = FALSE; | |
2743 oap->motion_type = MCHAR; | |
2744 } | |
2745 | |
2746 /* When releasing the button let jump_to_mouse() know. */ | |
2747 if (!is_click && !is_drag) | |
2748 jump_flags |= MOUSE_RELEASED; | |
2749 | |
2750 /* | |
2751 * JUMP! | |
2752 */ | |
2753 jump_flags = jump_to_mouse(jump_flags, | |
2754 oap == NULL ? NULL : &(oap->inclusive), which_button); | |
2755 | |
2756 #ifdef FEAT_MENU | |
2757 /* A click in the window toolbar has no side effects. */ | |
2758 if (jump_flags & MOUSE_WINBAR) | |
2759 return FALSE; | |
2760 #endif | |
2761 moved = (jump_flags & CURSOR_MOVED); | |
2762 in_status_line = (jump_flags & IN_STATUS_LINE); | |
2763 in_sep_line = (jump_flags & IN_SEP_LINE); | |
2764 | |
2765 #ifdef FEAT_NETBEANS_INTG | |
2766 if (isNetbeansBuffer(curbuf) | |
2767 && !(jump_flags & (IN_STATUS_LINE | IN_SEP_LINE))) | |
2768 { | |
2769 int key = KEY2TERMCAP1(c); | |
2770 | |
2771 if (key == (int)KE_LEFTRELEASE || key == (int)KE_MIDDLERELEASE | |
2772 || key == (int)KE_RIGHTRELEASE) | |
2773 netbeans_button_release(which_button); | |
2774 } | |
2775 #endif | |
2776 | |
2777 /* When jumping to another window, clear a pending operator. That's a bit | |
2778 * friendlier than beeping and not jumping to that window. */ | |
2779 if (curwin != old_curwin && oap != NULL && oap->op_type != OP_NOP) | |
2780 clearop(oap); | |
2781 | |
2782 #ifdef FEAT_FOLDING | |
2783 if (mod_mask == 0 | |
2784 && !is_drag | |
2785 && (jump_flags & (MOUSE_FOLD_CLOSE | MOUSE_FOLD_OPEN)) | |
2786 && which_button == MOUSE_LEFT) | |
2787 { | |
2788 /* open or close a fold at this line */ | |
2789 if (jump_flags & MOUSE_FOLD_OPEN) | |
2790 openFold(curwin->w_cursor.lnum, 1L); | |
2791 else | |
2792 closeFold(curwin->w_cursor.lnum, 1L); | |
2793 /* don't move the cursor if still in the same window */ | |
2794 if (curwin == old_curwin) | |
2795 curwin->w_cursor = save_cursor; | |
2796 } | |
2797 #endif | |
2798 | |
2799 #if defined(FEAT_CLIPBOARD) && defined(FEAT_CMDWIN) | |
2800 if ((jump_flags & IN_OTHER_WIN) && !VIsual_active && clip_star.available) | |
2801 { | |
2802 clip_modeless(which_button, is_click, is_drag); | |
2803 return FALSE; | |
2804 } | |
2805 #endif | |
2806 | |
2807 /* Set global flag that we are extending the Visual area with mouse | |
2808 * dragging; temporarily minimize 'scrolloff'. */ | |
2809 if (VIsual_active && is_drag && get_scrolloff_value()) | |
2810 { | |
2811 /* In the very first line, allow scrolling one line */ | |
2812 if (mouse_row == 0) | |
2813 mouse_dragging = 2; | |
2814 else | |
2815 mouse_dragging = 1; | |
2816 } | |
2817 | |
2818 /* When dragging the mouse above the window, scroll down. */ | |
2819 if (is_drag && mouse_row < 0 && !in_status_line) | |
2820 { | |
2821 scroll_redraw(FALSE, 1L); | |
2822 mouse_row = 0; | |
2823 } | |
2824 | |
2825 if (start_visual.lnum) /* right click in visual mode */ | |
2826 { | |
2827 /* When ALT is pressed make Visual mode blockwise. */ | |
2828 if (mod_mask & MOD_MASK_ALT) | |
2829 VIsual_mode = Ctrl_V; | |
2830 | |
2831 /* | |
2832 * In Visual-block mode, divide the area in four, pick up the corner | |
2833 * that is in the quarter that the cursor is in. | |
2834 */ | |
2835 if (VIsual_mode == Ctrl_V) | |
2836 { | |
2837 getvcols(curwin, &start_visual, &end_visual, &leftcol, &rightcol); | |
2838 if (curwin->w_curswant > (leftcol + rightcol) / 2) | |
2839 end_visual.col = leftcol; | |
2840 else | |
2841 end_visual.col = rightcol; | |
2842 if (curwin->w_cursor.lnum >= | |
2843 (start_visual.lnum + end_visual.lnum) / 2) | |
2844 end_visual.lnum = start_visual.lnum; | |
2845 | |
2846 /* move VIsual to the right column */ | |
2847 start_visual = curwin->w_cursor; /* save the cursor pos */ | |
2848 curwin->w_cursor = end_visual; | |
2849 coladvance(end_visual.col); | |
2850 VIsual = curwin->w_cursor; | |
2851 curwin->w_cursor = start_visual; /* restore the cursor */ | |
2852 } | |
2853 else | |
2854 { | |
2855 /* | |
2856 * If the click is before the start of visual, change the start. | |
2857 * If the click is after the end of visual, change the end. If | |
2858 * the click is inside the visual, change the closest side. | |
2859 */ | |
2860 if (LT_POS(curwin->w_cursor, start_visual)) | |
2861 VIsual = end_visual; | |
2862 else if (LT_POS(end_visual, curwin->w_cursor)) | |
2863 VIsual = start_visual; | |
2864 else | |
2865 { | |
2866 /* In the same line, compare column number */ | |
2867 if (end_visual.lnum == start_visual.lnum) | |
2868 { | |
2869 if (curwin->w_cursor.col - start_visual.col > | |
2870 end_visual.col - curwin->w_cursor.col) | |
2871 VIsual = start_visual; | |
2872 else | |
2873 VIsual = end_visual; | |
2874 } | |
2875 | |
2876 /* In different lines, compare line number */ | |
2877 else | |
2878 { | |
2879 diff = (curwin->w_cursor.lnum - start_visual.lnum) - | |
2880 (end_visual.lnum - curwin->w_cursor.lnum); | |
2881 | |
2882 if (diff > 0) /* closest to end */ | |
2883 VIsual = start_visual; | |
2884 else if (diff < 0) /* closest to start */ | |
2885 VIsual = end_visual; | |
2886 else /* in the middle line */ | |
2887 { | |
2888 if (curwin->w_cursor.col < | |
2889 (start_visual.col + end_visual.col) / 2) | |
2890 VIsual = end_visual; | |
2891 else | |
2892 VIsual = start_visual; | |
2893 } | |
2894 } | |
2895 } | |
2896 } | |
2897 } | |
2898 /* | |
2899 * If Visual mode started in insert mode, execute "CTRL-O" | |
2900 */ | |
2901 else if ((State & INSERT) && VIsual_active) | |
2902 stuffcharReadbuff(Ctrl_O); | |
2903 | |
2904 /* | |
2905 * Middle mouse click: Put text before cursor. | |
2906 */ | |
2907 if (which_button == MOUSE_MIDDLE) | |
2908 { | |
2909 #ifdef FEAT_CLIPBOARD | |
2910 if (clip_star.available && regname == 0) | |
2911 regname = '*'; | |
2912 #endif | |
2913 if (yank_register_mline(regname)) | |
2914 { | |
2915 if (mouse_past_bottom) | |
2916 dir = FORWARD; | |
2917 } | |
2918 else if (mouse_past_eol) | |
2919 dir = FORWARD; | |
2920 | |
2921 if (fixindent) | |
2922 { | |
2923 c1 = (dir == BACKWARD) ? '[' : ']'; | |
2924 c2 = 'p'; | |
2925 } | |
2926 else | |
2927 { | |
2928 c1 = (dir == FORWARD) ? 'p' : 'P'; | |
2929 c2 = NUL; | |
2930 } | |
2931 prep_redo(regname, count, NUL, c1, NUL, c2, NUL); | |
2932 | |
2933 /* | |
2934 * Remember where the paste started, so in edit() Insstart can be set | |
2935 * to this position | |
2936 */ | |
2937 if (restart_edit != 0) | |
2938 where_paste_started = curwin->w_cursor; | |
2939 do_put(regname, dir, count, fixindent | PUT_CURSEND); | |
2940 } | |
2941 | |
2942 #if defined(FEAT_QUICKFIX) | |
2943 /* | |
2944 * Ctrl-Mouse click or double click in a quickfix window jumps to the | |
2945 * error under the mouse pointer. | |
2946 */ | |
2947 else if (((mod_mask & MOD_MASK_CTRL) | |
2948 || (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) | |
2949 && bt_quickfix(curbuf)) | |
2950 { | |
2951 if (curwin->w_llist_ref == NULL) /* quickfix window */ | |
2952 do_cmdline_cmd((char_u *)".cc"); | |
2953 else /* location list window */ | |
2954 do_cmdline_cmd((char_u *)".ll"); | |
2955 got_click = FALSE; /* ignore drag&release now */ | |
2956 } | |
2957 #endif | |
2958 | |
2959 /* | |
2960 * Ctrl-Mouse click (or double click in a help window) jumps to the tag | |
2961 * under the mouse pointer. | |
2962 */ | |
2963 else if ((mod_mask & MOD_MASK_CTRL) || (curbuf->b_help | |
2964 && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)) | |
2965 { | |
2966 if (State & INSERT) | |
2967 stuffcharReadbuff(Ctrl_O); | |
2968 stuffcharReadbuff(Ctrl_RSB); | |
2969 got_click = FALSE; /* ignore drag&release now */ | |
2970 } | |
2971 | |
2972 /* | |
2973 * Shift-Mouse click searches for the next occurrence of the word under | |
2974 * the mouse pointer | |
2975 */ | |
2976 else if ((mod_mask & MOD_MASK_SHIFT)) | |
2977 { | |
2978 if ((State & INSERT) || (VIsual_active && VIsual_select)) | |
2979 stuffcharReadbuff(Ctrl_O); | |
2980 if (which_button == MOUSE_LEFT) | |
2981 stuffcharReadbuff('*'); | |
2982 else /* MOUSE_RIGHT */ | |
2983 stuffcharReadbuff('#'); | |
2984 } | |
2985 | |
2986 /* Handle double clicks, unless on status line */ | |
2987 else if (in_status_line) | |
2988 { | |
2989 #ifdef FEAT_MOUSESHAPE | |
2990 if ((is_drag || is_click) && !drag_status_line) | |
2991 { | |
2992 drag_status_line = TRUE; | |
2993 update_mouseshape(-1); | |
2994 } | |
2995 #endif | |
2996 } | |
2997 else if (in_sep_line) | |
2998 { | |
2999 #ifdef FEAT_MOUSESHAPE | |
3000 if ((is_drag || is_click) && !drag_sep_line) | |
3001 { | |
3002 drag_sep_line = TRUE; | |
3003 update_mouseshape(-1); | |
3004 } | |
3005 #endif | |
3006 } | |
3007 else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT)) | |
3008 && mouse_has(MOUSE_VISUAL)) | |
3009 { | |
3010 if (is_click || !VIsual_active) | |
3011 { | |
3012 if (VIsual_active) | |
3013 orig_cursor = VIsual; | |
3014 else | |
3015 { | |
3016 check_visual_highlight(); | |
3017 VIsual = curwin->w_cursor; | |
3018 orig_cursor = VIsual; | |
3019 VIsual_active = TRUE; | |
3020 VIsual_reselect = TRUE; | |
3021 /* start Select mode if 'selectmode' contains "mouse" */ | |
3022 may_start_select('o'); | |
3023 setmouse(); | |
3024 } | |
3025 if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) | |
3026 { | |
3027 /* Double click with ALT pressed makes it blockwise. */ | |
3028 if (mod_mask & MOD_MASK_ALT) | |
3029 VIsual_mode = Ctrl_V; | |
3030 else | |
3031 VIsual_mode = 'v'; | |
3032 } | |
3033 else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK) | |
3034 VIsual_mode = 'V'; | |
3035 else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK) | |
3036 VIsual_mode = Ctrl_V; | |
3037 #ifdef FEAT_CLIPBOARD | |
3038 /* Make sure the clipboard gets updated. Needed because start and | |
3039 * end may still be the same, and the selection needs to be owned */ | |
3040 clip_star.vmode = NUL; | |
3041 #endif | |
3042 } | |
3043 /* | |
3044 * A double click selects a word or a block. | |
3045 */ | |
3046 if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) | |
3047 { | |
3048 pos_T *pos = NULL; | |
3049 int gc; | |
3050 | |
3051 if (is_click) | |
3052 { | |
3053 /* If the character under the cursor (skipping white space) is | |
3054 * not a word character, try finding a match and select a (), | |
3055 * {}, [], #if/#endif, etc. block. */ | |
3056 end_visual = curwin->w_cursor; | |
3057 while (gc = gchar_pos(&end_visual), VIM_ISWHITE(gc)) | |
3058 inc(&end_visual); | |
3059 if (oap != NULL) | |
3060 oap->motion_type = MCHAR; | |
3061 if (oap != NULL | |
3062 && VIsual_mode == 'v' | |
3063 && !vim_iswordc(gchar_pos(&end_visual)) | |
3064 && EQUAL_POS(curwin->w_cursor, VIsual) | |
3065 && (pos = findmatch(oap, NUL)) != NULL) | |
3066 { | |
3067 curwin->w_cursor = *pos; | |
3068 if (oap->motion_type == MLINE) | |
3069 VIsual_mode = 'V'; | |
3070 else if (*p_sel == 'e') | |
3071 { | |
3072 if (LT_POS(curwin->w_cursor, VIsual)) | |
3073 ++VIsual.col; | |
3074 else | |
3075 ++curwin->w_cursor.col; | |
3076 } | |
3077 } | |
3078 } | |
3079 | |
3080 if (pos == NULL && (is_click || is_drag)) | |
3081 { | |
3082 /* When not found a match or when dragging: extend to include | |
3083 * a word. */ | |
3084 if (LT_POS(curwin->w_cursor, orig_cursor)) | |
3085 { | |
3086 find_start_of_word(&curwin->w_cursor); | |
3087 find_end_of_word(&VIsual); | |
3088 } | |
3089 else | |
3090 { | |
3091 find_start_of_word(&VIsual); | |
3092 if (*p_sel == 'e' && *ml_get_cursor() != NUL) | |
3093 curwin->w_cursor.col += | |
3094 (*mb_ptr2len)(ml_get_cursor()); | |
3095 find_end_of_word(&curwin->w_cursor); | |
3096 } | |
3097 } | |
3098 curwin->w_set_curswant = TRUE; | |
3099 } | |
3100 if (is_click) | |
3101 redraw_curbuf_later(INVERTED); /* update the inversion */ | |
3102 } | |
3103 else if (VIsual_active && !old_active) | |
3104 { | |
3105 if (mod_mask & MOD_MASK_ALT) | |
3106 VIsual_mode = Ctrl_V; | |
3107 else | |
3108 VIsual_mode = 'v'; | |
3109 } | |
3110 | |
3111 /* If Visual mode changed show it later. */ | |
3112 if ((!VIsual_active && old_active && mode_displayed) | |
3113 || (VIsual_active && p_smd && msg_silent == 0 | |
3114 && (!old_active || VIsual_mode != old_mode))) | |
3115 redraw_cmdline = TRUE; | |
3116 | |
3117 return moved; | |
3118 } | |
3119 | |
3120 /* | |
3121 * Move "pos" back to the start of the word it's in. | |
3122 */ | |
3123 static void | |
3124 find_start_of_word(pos_T *pos) | |
3125 { | |
3126 char_u *line; | |
3127 int cclass; | |
3128 int col; | |
3129 | |
3130 line = ml_get(pos->lnum); | |
3131 cclass = get_mouse_class(line + pos->col); | |
3132 | |
3133 while (pos->col > 0) | |
3134 { | |
3135 col = pos->col - 1; | |
3136 col -= (*mb_head_off)(line, line + col); | |
3137 if (get_mouse_class(line + col) != cclass) | |
3138 break; | |
3139 pos->col = col; | |
3140 } | |
3141 } | |
3142 | |
3143 /* | |
3144 * Move "pos" forward to the end of the word it's in. | |
3145 * When 'selection' is "exclusive", the position is just after the word. | |
3146 */ | |
3147 static void | |
3148 find_end_of_word(pos_T *pos) | |
3149 { | |
3150 char_u *line; | |
3151 int cclass; | |
3152 int col; | |
3153 | |
3154 line = ml_get(pos->lnum); | |
3155 if (*p_sel == 'e' && pos->col > 0) | |
3156 { | |
3157 --pos->col; | |
3158 pos->col -= (*mb_head_off)(line, line + pos->col); | |
3159 } | |
3160 cclass = get_mouse_class(line + pos->col); | |
3161 while (line[pos->col] != NUL) | |
3162 { | |
3163 col = pos->col + (*mb_ptr2len)(line + pos->col); | |
3164 if (get_mouse_class(line + col) != cclass) | |
3165 { | |
3166 if (*p_sel == 'e') | |
3167 pos->col = col; | |
3168 break; | |
3169 } | |
3170 pos->col = col; | |
3171 } | |
3172 } | |
3173 | |
3174 /* | |
3175 * Get class of a character for selection: same class means same word. | |
3176 * 0: blank | |
3177 * 1: punctuation groups | |
3178 * 2: normal word character | |
3179 * >2: multi-byte word character. | |
3180 */ | |
3181 static int | |
3182 get_mouse_class(char_u *p) | |
3183 { | |
3184 int c; | |
3185 | |
3186 if (has_mbyte && MB_BYTE2LEN(p[0]) > 1) | |
3187 return mb_get_class(p); | |
3188 | |
3189 c = *p; | |
3190 if (c == ' ' || c == '\t') | |
3191 return 0; | |
3192 | |
3193 if (vim_iswordc(c)) | |
3194 return 2; | |
3195 | |
3196 /* | |
3197 * There are a few special cases where we want certain combinations of | |
3198 * characters to be considered as a single word. These are things like | |
3199 * "->", "/ *", "*=", "+=", "&=", "<=", ">=", "!=" etc. Otherwise, each | |
3200 * character is in its own class. | |
3201 */ | |
3202 if (c != NUL && vim_strchr((char_u *)"-+*/%<>&|^!=", c) != NULL) | |
3203 return 1; | |
3204 return c; | |
3205 } | |
3206 #endif /* FEAT_MOUSE */ | |
3207 | |
3208 /* | 2191 /* |
3209 * Check if highlighting for visual mode is possible, give a warning message | 2192 * Check if highlighting for visual mode is possible, give a warning message |
3210 * if not. | 2193 * if not. |
3211 */ | 2194 */ |
3212 void | 2195 void |
3529 | 2512 |
3530 /* | 2513 /* |
3531 * Prepare for redo of any command. | 2514 * Prepare for redo of any command. |
3532 * Note that only the last argument can be a multi-byte char. | 2515 * Note that only the last argument can be a multi-byte char. |
3533 */ | 2516 */ |
3534 static void | 2517 void |
3535 prep_redo( | 2518 prep_redo( |
3536 int regname, | 2519 int regname, |
3537 long num, | 2520 long num, |
3538 int cmd1, | 2521 int cmd1, |
3539 int cmd2, | 2522 int cmd2, |
3588 return FALSE; | 2571 return FALSE; |
3589 clearopbeep(oap); | 2572 clearopbeep(oap); |
3590 return TRUE; | 2573 return TRUE; |
3591 } | 2574 } |
3592 | 2575 |
3593 static void | 2576 void |
3594 clearop(oparg_T *oap) | 2577 clearop(oparg_T *oap) |
3595 { | 2578 { |
3596 oap->op_type = OP_NOP; | 2579 oap->op_type = OP_NOP; |
3597 oap->regname = 0; | 2580 oap->regname = 0; |
3598 oap->motion_force = NUL; | 2581 oap->motion_force = NUL; |
3599 oap->use_reg_one = FALSE; | 2582 oap->use_reg_one = FALSE; |
3600 } | 2583 } |
3601 | 2584 |
3602 static void | 2585 void |
3603 clearopbeep(oparg_T *oap) | 2586 clearopbeep(oparg_T *oap) |
3604 { | 2587 { |
3605 clearop(oap); | 2588 clearop(oap); |
3606 beep_flush(); | 2589 beep_flush(); |
3607 } | 2590 } |
4511 curwin->w_curswant = MAXCOL; /* stick in the last column */ | 3494 curwin->w_curswant = MAXCOL; /* stick in the last column */ |
4512 | 3495 |
4513 return retval; | 3496 return retval; |
4514 } | 3497 } |
4515 | 3498 |
4516 #ifdef FEAT_MOUSE | |
4517 /* | |
4518 * Mouse scroll wheel: Default action is to scroll three lines, or one page | |
4519 * when Shift or Ctrl is used. | |
4520 * K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or | |
4521 * K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2) | |
4522 */ | |
4523 static void | |
4524 nv_mousescroll(cmdarg_T *cap) | |
4525 { | |
4526 win_T *old_curwin = curwin, *wp; | |
4527 | |
4528 if (mouse_row >= 0 && mouse_col >= 0) | |
4529 { | |
4530 int row, col; | |
4531 | |
4532 row = mouse_row; | |
4533 col = mouse_col; | |
4534 | |
4535 /* find the window at the pointer coordinates */ | |
4536 wp = mouse_find_win(&row, &col, FIND_POPUP); | |
4537 if (wp == NULL) | |
4538 return; | |
4539 #ifdef FEAT_TEXT_PROP | |
4540 if (WIN_IS_POPUP(wp) && !wp->w_has_scrollbar) | |
4541 return; | |
4542 #endif | |
4543 curwin = wp; | |
4544 curbuf = curwin->w_buffer; | |
4545 } | |
4546 | |
4547 if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) | |
4548 { | |
4549 # ifdef FEAT_TERMINAL | |
4550 if (term_use_loop()) | |
4551 /* This window is a terminal window, send the mouse event there. | |
4552 * Set "typed" to FALSE to avoid an endless loop. */ | |
4553 send_keys_to_term(curbuf->b_term, cap->cmdchar, FALSE); | |
4554 else | |
4555 # endif | |
4556 if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) | |
4557 { | |
4558 (void)onepage(cap->arg ? FORWARD : BACKWARD, 1L); | |
4559 } | |
4560 else | |
4561 { | |
4562 // Don't scroll more than half the window height. | |
4563 if (curwin->w_height < 6) | |
4564 { | |
4565 cap->count1 = curwin->w_height / 2; | |
4566 if (cap->count1 == 0) | |
4567 cap->count1 = 1; | |
4568 } | |
4569 else | |
4570 cap->count1 = 3; | |
4571 cap->count0 = cap->count1; | |
4572 nv_scroll_line(cap); | |
4573 } | |
4574 #ifdef FEAT_TEXT_PROP | |
4575 if (WIN_IS_POPUP(curwin)) | |
4576 popup_set_firstline(curwin); | |
4577 #endif | |
4578 } | |
4579 # ifdef FEAT_GUI | |
4580 else | |
4581 { | |
4582 /* Horizontal scroll - only allowed when 'wrap' is disabled */ | |
4583 if (!curwin->w_p_wrap) | |
4584 { | |
4585 int val, step = 6; | |
4586 | |
4587 if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) | |
4588 step = curwin->w_width; | |
4589 val = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); | |
4590 if (val < 0) | |
4591 val = 0; | |
4592 | |
4593 gui_do_horiz_scroll(val, TRUE); | |
4594 } | |
4595 } | |
4596 # endif | |
4597 # ifdef FEAT_SYN_HL | |
4598 if (curwin != old_curwin && curwin->w_p_cul) | |
4599 redraw_for_cursorline(curwin); | |
4600 # endif | |
4601 | |
4602 curwin->w_redr_status = TRUE; | |
4603 | |
4604 curwin = old_curwin; | |
4605 curbuf = curwin->w_buffer; | |
4606 } | |
4607 | |
4608 /* | |
4609 * Mouse clicks and drags. | |
4610 */ | |
4611 static void | |
4612 nv_mouse(cmdarg_T *cap) | |
4613 { | |
4614 (void)do_mouse(cap->oap, cap->cmdchar, BACKWARD, cap->count1, 0); | |
4615 } | |
4616 #endif | |
4617 | |
4618 /* | 3499 /* |
4619 * Handle CTRL-E and CTRL-Y commands: scroll a line up or down. | 3500 * Handle CTRL-E and CTRL-Y commands: scroll a line up or down. |
4620 * cap->arg must be TRUE for CTRL-E. | 3501 * cap->arg must be TRUE for CTRL-E. |
4621 */ | 3502 */ |
4622 static void | 3503 void |
4623 nv_scroll_line(cmdarg_T *cap) | 3504 nv_scroll_line(cmdarg_T *cap) |
4624 { | 3505 { |
4625 if (!checkclearop(cap->oap)) | 3506 if (!checkclearop(cap->oap)) |
4626 scroll_redraw(cap->arg, cap->count1); | 3507 scroll_redraw(cap->arg, cap->count1); |
4627 } | 3508 } |
7570 VIsual_active = TRUE; | 6451 VIsual_active = TRUE; |
7571 VIsual_reselect = TRUE; | 6452 VIsual_reselect = TRUE; |
7572 if (!cap->arg) | 6453 if (!cap->arg) |
7573 /* start Select mode when 'selectmode' contains "cmd" */ | 6454 /* start Select mode when 'selectmode' contains "cmd" */ |
7574 may_start_select('c'); | 6455 may_start_select('c'); |
7575 #ifdef FEAT_MOUSE | |
7576 setmouse(); | 6456 setmouse(); |
7577 #endif | |
7578 if (p_smd && msg_silent == 0) | 6457 if (p_smd && msg_silent == 0) |
7579 redraw_cmdline = TRUE; /* show visual mode later */ | 6458 redraw_cmdline = TRUE; /* show visual mode later */ |
7580 /* | 6459 /* |
7581 * For V and ^V, we multiply the number of lines even if there | 6460 * For V and ^V, we multiply the number of lines even if there |
7582 * was only one -- webb | 6461 * was only one -- webb |
7685 | 6564 |
7686 #ifdef FEAT_FOLDING | 6565 #ifdef FEAT_FOLDING |
7687 foldAdjustVisual(); | 6566 foldAdjustVisual(); |
7688 #endif | 6567 #endif |
7689 | 6568 |
7690 #ifdef FEAT_MOUSE | |
7691 setmouse(); | 6569 setmouse(); |
7692 #endif | |
7693 #ifdef FEAT_CONCEAL | 6570 #ifdef FEAT_CONCEAL |
7694 /* Check for redraw after changing the state. */ | 6571 /* Check for redraw after changing the state. */ |
7695 conceal_check_cursor_line(); | 6572 conceal_check_cursor_line(); |
7696 #endif | 6573 #endif |
7697 | 6574 |
7852 */ | 6729 */ |
7853 if (cap->arg) | 6730 if (cap->arg) |
7854 VIsual_select = TRUE; | 6731 VIsual_select = TRUE; |
7855 else | 6732 else |
7856 may_start_select('c'); | 6733 may_start_select('c'); |
7857 #ifdef FEAT_MOUSE | |
7858 setmouse(); | 6734 setmouse(); |
7859 #endif | |
7860 #ifdef FEAT_CLIPBOARD | 6735 #ifdef FEAT_CLIPBOARD |
7861 /* Make sure the clipboard gets updated. Needed because start and | 6736 /* Make sure the clipboard gets updated. Needed because start and |
7862 * end are still the same, and the selection needs to be owned */ | 6737 * end are still the same, and the selection needs to be owned */ |
7863 clip_star.vmode = NUL; | 6738 clip_star.vmode = NUL; |
7864 #endif | 6739 #endif |