mirror of
https://github.com/vim/vim.git
synced 2025-10-14 07:04:10 -04:00
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)
This commit is contained in:
791
src/ui.c
791
src/ui.c
@@ -2917,797 +2917,6 @@ yank_cut_buffer0(Display *dpy, Clipboard_T *cbd)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_MOUSE) || defined(PROTO)
|
||||
|
||||
/*
|
||||
* Move the cursor to the specified row and column on the screen.
|
||||
* Change current window if necessary. Returns an integer with the
|
||||
* CURSOR_MOVED bit set if the cursor has moved or unset otherwise.
|
||||
*
|
||||
* The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column.
|
||||
* The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column.
|
||||
*
|
||||
* If flags has MOUSE_FOCUS, then the current window will not be changed, and
|
||||
* if the mouse is outside the window then the text will scroll, or if the
|
||||
* mouse was previously on a status line, then the status line may be dragged.
|
||||
*
|
||||
* If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the
|
||||
* cursor is moved unless the cursor was on a status line.
|
||||
* This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or
|
||||
* IN_SEP_LINE depending on where the cursor was clicked.
|
||||
*
|
||||
* If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless
|
||||
* the mouse is on the status line of the same window.
|
||||
*
|
||||
* If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since
|
||||
* the last call.
|
||||
*
|
||||
* If flags has MOUSE_SETPOS, nothing is done, only the current position is
|
||||
* remembered.
|
||||
*/
|
||||
int
|
||||
jump_to_mouse(
|
||||
int flags,
|
||||
int *inclusive, /* used for inclusive operator, can be NULL */
|
||||
int which_button) /* MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE */
|
||||
{
|
||||
static int on_status_line = 0; /* #lines below bottom of window */
|
||||
static int on_sep_line = 0; /* on separator right of window */
|
||||
#ifdef FEAT_MENU
|
||||
static int in_winbar = FALSE;
|
||||
#endif
|
||||
#ifdef FEAT_TEXT_PROP
|
||||
static int in_popup_win = FALSE;
|
||||
static win_T *click_in_popup_win = NULL;
|
||||
#endif
|
||||
static int prev_row = -1;
|
||||
static int prev_col = -1;
|
||||
static win_T *dragwin = NULL; /* window being dragged */
|
||||
static int did_drag = FALSE; /* drag was noticed */
|
||||
|
||||
win_T *wp, *old_curwin;
|
||||
pos_T old_cursor;
|
||||
int count;
|
||||
int first;
|
||||
int row = mouse_row;
|
||||
int col = mouse_col;
|
||||
#ifdef FEAT_FOLDING
|
||||
int mouse_char;
|
||||
#endif
|
||||
|
||||
mouse_past_bottom = FALSE;
|
||||
mouse_past_eol = FALSE;
|
||||
|
||||
if (flags & MOUSE_RELEASED)
|
||||
{
|
||||
/* On button release we may change window focus if positioned on a
|
||||
* status line and no dragging happened. */
|
||||
if (dragwin != NULL && !did_drag)
|
||||
flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
|
||||
dragwin = NULL;
|
||||
did_drag = FALSE;
|
||||
#ifdef FEAT_TEXT_PROP
|
||||
if (click_in_popup_win != NULL && popup_dragwin == NULL)
|
||||
popup_close_for_mouse_click(click_in_popup_win);
|
||||
|
||||
popup_dragwin = NULL;
|
||||
click_in_popup_win = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((flags & MOUSE_DID_MOVE)
|
||||
&& prev_row == mouse_row
|
||||
&& prev_col == mouse_col)
|
||||
{
|
||||
retnomove:
|
||||
/* before moving the cursor for a left click which is NOT in a status
|
||||
* line, stop Visual mode */
|
||||
if (on_status_line)
|
||||
return IN_STATUS_LINE;
|
||||
if (on_sep_line)
|
||||
return IN_SEP_LINE;
|
||||
#ifdef FEAT_MENU
|
||||
if (in_winbar)
|
||||
{
|
||||
/* A quick second click may arrive as a double-click, but we use it
|
||||
* as a second click in the WinBar. */
|
||||
if ((mod_mask & MOD_MASK_MULTI_CLICK) && !(flags & MOUSE_RELEASED))
|
||||
{
|
||||
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||
if (wp == NULL)
|
||||
return IN_UNKNOWN;
|
||||
winbar_click(wp, col);
|
||||
}
|
||||
return IN_OTHER_WIN | MOUSE_WINBAR;
|
||||
}
|
||||
#endif
|
||||
if (flags & MOUSE_MAY_STOP_VIS)
|
||||
{
|
||||
end_visual_mode();
|
||||
redraw_curbuf_later(INVERTED); /* delete the inversion */
|
||||
}
|
||||
#if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
|
||||
// Continue a modeless selection in another window.
|
||||
if (cmdwin_type != 0 && row < curwin->w_winrow)
|
||||
return IN_OTHER_WIN;
|
||||
#endif
|
||||
#ifdef FEAT_TEXT_PROP
|
||||
// Continue a modeless selection in a popup window or dragging it.
|
||||
if (in_popup_win)
|
||||
{
|
||||
click_in_popup_win = NULL; // don't close it on release
|
||||
if (popup_dragwin != NULL)
|
||||
{
|
||||
// dragging a popup window
|
||||
popup_drag(popup_dragwin);
|
||||
return IN_UNKNOWN;
|
||||
}
|
||||
return IN_OTHER_WIN;
|
||||
}
|
||||
#endif
|
||||
return IN_BUFFER;
|
||||
}
|
||||
|
||||
prev_row = mouse_row;
|
||||
prev_col = mouse_col;
|
||||
|
||||
if (flags & MOUSE_SETPOS)
|
||||
goto retnomove; /* ugly goto... */
|
||||
|
||||
#ifdef FEAT_FOLDING
|
||||
/* Remember the character under the mouse, it might be a '-' or '+' in the
|
||||
* fold column. */
|
||||
if (row >= 0 && row < Rows && col >= 0 && col <= Columns
|
||||
&& ScreenLines != NULL)
|
||||
mouse_char = ScreenLines[LineOffset[row] + col];
|
||||
else
|
||||
mouse_char = ' ';
|
||||
#endif
|
||||
|
||||
old_curwin = curwin;
|
||||
old_cursor = curwin->w_cursor;
|
||||
|
||||
if (!(flags & MOUSE_FOCUS))
|
||||
{
|
||||
if (row < 0 || col < 0) // check if it makes sense
|
||||
return IN_UNKNOWN;
|
||||
|
||||
// find the window where the row is in and adjust "row" and "col" to be
|
||||
// relative to top-left of the window
|
||||
wp = mouse_find_win(&row, &col, FIND_POPUP);
|
||||
if (wp == NULL)
|
||||
return IN_UNKNOWN;
|
||||
dragwin = NULL;
|
||||
|
||||
#ifdef FEAT_TEXT_PROP
|
||||
// Click in a popup window may start dragging or modeless selection,
|
||||
// but not much else.
|
||||
if (WIN_IS_POPUP(wp))
|
||||
{
|
||||
on_sep_line = 0;
|
||||
in_popup_win = TRUE;
|
||||
if (which_button == MOUSE_LEFT && popup_close_if_on_X(wp, row, col))
|
||||
{
|
||||
return IN_UNKNOWN;
|
||||
}
|
||||
else if ((wp->w_popup_flags & (POPF_DRAG | POPF_RESIZE))
|
||||
&& popup_on_border(wp, row, col))
|
||||
{
|
||||
popup_dragwin = wp;
|
||||
popup_start_drag(wp, row, col);
|
||||
return IN_UNKNOWN;
|
||||
}
|
||||
// Only close on release, otherwise it's not possible to drag or do
|
||||
// modeless selection.
|
||||
else if (wp->w_popup_close == POPCLOSE_CLICK
|
||||
&& which_button == MOUSE_LEFT)
|
||||
{
|
||||
click_in_popup_win = wp;
|
||||
}
|
||||
else if (which_button == MOUSE_LEFT)
|
||||
// If the click is in the scrollbar, may scroll up/down.
|
||||
popup_handle_scrollbar_click(wp, row, col);
|
||||
# ifdef FEAT_CLIPBOARD
|
||||
return IN_OTHER_WIN;
|
||||
# else
|
||||
return IN_UNKNOWN;
|
||||
# endif
|
||||
}
|
||||
in_popup_win = FALSE;
|
||||
popup_dragwin = NULL;
|
||||
#endif
|
||||
#ifdef FEAT_MENU
|
||||
if (row == -1)
|
||||
{
|
||||
/* A click in the window toolbar does not enter another window or
|
||||
* change Visual highlighting. */
|
||||
winbar_click(wp, col);
|
||||
in_winbar = TRUE;
|
||||
return IN_OTHER_WIN | MOUSE_WINBAR;
|
||||
}
|
||||
in_winbar = FALSE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* winpos and height may change in win_enter()!
|
||||
*/
|
||||
if (row >= wp->w_height) /* In (or below) status line */
|
||||
{
|
||||
on_status_line = row - wp->w_height + 1;
|
||||
dragwin = wp;
|
||||
}
|
||||
else
|
||||
on_status_line = 0;
|
||||
if (col >= wp->w_width) /* In separator line */
|
||||
{
|
||||
on_sep_line = col - wp->w_width + 1;
|
||||
dragwin = wp;
|
||||
}
|
||||
else
|
||||
on_sep_line = 0;
|
||||
|
||||
/* The rightmost character of the status line might be a vertical
|
||||
* separator character if there is no connecting window to the right. */
|
||||
if (on_status_line && on_sep_line)
|
||||
{
|
||||
if (stl_connected(wp))
|
||||
on_sep_line = 0;
|
||||
else
|
||||
on_status_line = 0;
|
||||
}
|
||||
|
||||
/* Before jumping to another buffer, or moving the cursor for a left
|
||||
* click, stop Visual mode. */
|
||||
if (VIsual_active
|
||||
&& (wp->w_buffer != curwin->w_buffer
|
||||
|| (!on_status_line && !on_sep_line
|
||||
#ifdef FEAT_FOLDING
|
||||
&& (
|
||||
# ifdef FEAT_RIGHTLEFT
|
||||
wp->w_p_rl ? col < wp->w_width - wp->w_p_fdc :
|
||||
# endif
|
||||
col >= wp->w_p_fdc
|
||||
# ifdef FEAT_CMDWIN
|
||||
+ (cmdwin_type == 0 && wp == curwin ? 0 : 1)
|
||||
# endif
|
||||
)
|
||||
#endif
|
||||
&& (flags & MOUSE_MAY_STOP_VIS))))
|
||||
{
|
||||
end_visual_mode();
|
||||
redraw_curbuf_later(INVERTED); /* delete the inversion */
|
||||
}
|
||||
#ifdef FEAT_CMDWIN
|
||||
if (cmdwin_type != 0 && wp != curwin)
|
||||
{
|
||||
/* A click outside the command-line window: Use modeless
|
||||
* selection if possible. Allow dragging the status lines. */
|
||||
on_sep_line = 0;
|
||||
# ifdef FEAT_CLIPBOARD
|
||||
if (on_status_line)
|
||||
return IN_STATUS_LINE;
|
||||
return IN_OTHER_WIN;
|
||||
# else
|
||||
row = 0;
|
||||
col += wp->w_wincol;
|
||||
wp = curwin;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
/* Only change window focus when not clicking on or dragging the
|
||||
* status line. Do change focus when releasing the mouse button
|
||||
* (MOUSE_FOCUS was set above if we dragged first). */
|
||||
if (dragwin == NULL || (flags & MOUSE_RELEASED))
|
||||
win_enter(wp, TRUE); /* can make wp invalid! */
|
||||
|
||||
if (curwin != old_curwin)
|
||||
{
|
||||
#ifdef CHECK_DOUBLE_CLICK
|
||||
/* set topline, to be able to check for double click ourselves */
|
||||
set_mouse_topline(curwin);
|
||||
#endif
|
||||
#ifdef FEAT_TERMINAL
|
||||
/* when entering a terminal window may change state */
|
||||
term_win_entered();
|
||||
#endif
|
||||
}
|
||||
if (on_status_line) /* In (or below) status line */
|
||||
{
|
||||
/* Don't use start_arrow() if we're in the same window */
|
||||
if (curwin == old_curwin)
|
||||
return IN_STATUS_LINE;
|
||||
else
|
||||
return IN_STATUS_LINE | CURSOR_MOVED;
|
||||
}
|
||||
if (on_sep_line) /* In (or below) status line */
|
||||
{
|
||||
/* Don't use start_arrow() if we're in the same window */
|
||||
if (curwin == old_curwin)
|
||||
return IN_SEP_LINE;
|
||||
else
|
||||
return IN_SEP_LINE | CURSOR_MOVED;
|
||||
}
|
||||
|
||||
curwin->w_cursor.lnum = curwin->w_topline;
|
||||
#ifdef FEAT_GUI
|
||||
/* remember topline, needed for double click */
|
||||
gui_prev_topline = curwin->w_topline;
|
||||
# ifdef FEAT_DIFF
|
||||
gui_prev_topfill = curwin->w_topfill;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
else if (on_status_line && which_button == MOUSE_LEFT)
|
||||
{
|
||||
if (dragwin != NULL)
|
||||
{
|
||||
/* Drag the status line */
|
||||
count = row - dragwin->w_winrow - dragwin->w_height + 1
|
||||
- on_status_line;
|
||||
win_drag_status_line(dragwin, count);
|
||||
did_drag |= count;
|
||||
}
|
||||
return IN_STATUS_LINE; /* Cursor didn't move */
|
||||
}
|
||||
else if (on_sep_line && which_button == MOUSE_LEFT)
|
||||
{
|
||||
if (dragwin != NULL)
|
||||
{
|
||||
/* Drag the separator column */
|
||||
count = col - dragwin->w_wincol - dragwin->w_width + 1
|
||||
- on_sep_line;
|
||||
win_drag_vsep_line(dragwin, count);
|
||||
did_drag |= count;
|
||||
}
|
||||
return IN_SEP_LINE; /* Cursor didn't move */
|
||||
}
|
||||
#ifdef FEAT_MENU
|
||||
else if (in_winbar)
|
||||
{
|
||||
/* After a click on the window toolbar don't start Visual mode. */
|
||||
return IN_OTHER_WIN | MOUSE_WINBAR;
|
||||
}
|
||||
#endif
|
||||
else /* keep_window_focus must be TRUE */
|
||||
{
|
||||
/* before moving the cursor for a left click, stop Visual mode */
|
||||
if (flags & MOUSE_MAY_STOP_VIS)
|
||||
{
|
||||
end_visual_mode();
|
||||
redraw_curbuf_later(INVERTED); /* delete the inversion */
|
||||
}
|
||||
|
||||
#if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
|
||||
/* Continue a modeless selection in another window. */
|
||||
if (cmdwin_type != 0 && row < curwin->w_winrow)
|
||||
return IN_OTHER_WIN;
|
||||
#endif
|
||||
#ifdef FEAT_TEXT_PROP
|
||||
if (in_popup_win)
|
||||
{
|
||||
if (popup_dragwin != NULL)
|
||||
{
|
||||
// dragging a popup window
|
||||
popup_drag(popup_dragwin);
|
||||
return IN_UNKNOWN;
|
||||
}
|
||||
// continue a modeless selection in a popup window
|
||||
click_in_popup_win = NULL;
|
||||
return IN_OTHER_WIN;
|
||||
}
|
||||
#endif
|
||||
|
||||
row -= W_WINROW(curwin);
|
||||
col -= curwin->w_wincol;
|
||||
|
||||
/*
|
||||
* When clicking beyond the end of the window, scroll the screen.
|
||||
* Scroll by however many rows outside the window we are.
|
||||
*/
|
||||
if (row < 0)
|
||||
{
|
||||
count = 0;
|
||||
for (first = TRUE; curwin->w_topline > 1; )
|
||||
{
|
||||
#ifdef FEAT_DIFF
|
||||
if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
|
||||
++count;
|
||||
else
|
||||
#endif
|
||||
count += plines(curwin->w_topline - 1);
|
||||
if (!first && count > -row)
|
||||
break;
|
||||
first = FALSE;
|
||||
#ifdef FEAT_FOLDING
|
||||
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
|
||||
#endif
|
||||
#ifdef FEAT_DIFF
|
||||
if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
|
||||
++curwin->w_topfill;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
--curwin->w_topline;
|
||||
#ifdef FEAT_DIFF
|
||||
curwin->w_topfill = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_DIFF
|
||||
check_topfill(curwin, FALSE);
|
||||
#endif
|
||||
curwin->w_valid &=
|
||||
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
|
||||
redraw_later(VALID);
|
||||
row = 0;
|
||||
}
|
||||
else if (row >= curwin->w_height)
|
||||
{
|
||||
count = 0;
|
||||
for (first = TRUE; curwin->w_topline < curbuf->b_ml.ml_line_count; )
|
||||
{
|
||||
#ifdef FEAT_DIFF
|
||||
if (curwin->w_topfill > 0)
|
||||
++count;
|
||||
else
|
||||
#endif
|
||||
count += plines(curwin->w_topline);
|
||||
if (!first && count > row - curwin->w_height + 1)
|
||||
break;
|
||||
first = FALSE;
|
||||
#ifdef FEAT_FOLDING
|
||||
if (hasFolding(curwin->w_topline, NULL, &curwin->w_topline)
|
||||
&& curwin->w_topline == curbuf->b_ml.ml_line_count)
|
||||
break;
|
||||
#endif
|
||||
#ifdef FEAT_DIFF
|
||||
if (curwin->w_topfill > 0)
|
||||
--curwin->w_topfill;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
++curwin->w_topline;
|
||||
#ifdef FEAT_DIFF
|
||||
curwin->w_topfill =
|
||||
diff_check_fill(curwin, curwin->w_topline);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_DIFF
|
||||
check_topfill(curwin, FALSE);
|
||||
#endif
|
||||
redraw_later(VALID);
|
||||
curwin->w_valid &=
|
||||
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
|
||||
row = curwin->w_height - 1;
|
||||
}
|
||||
else if (row == 0)
|
||||
{
|
||||
/* When dragging the mouse, while the text has been scrolled up as
|
||||
* far as it goes, moving the mouse in the top line should scroll
|
||||
* the text down (done later when recomputing w_topline). */
|
||||
if (mouse_dragging > 0
|
||||
&& curwin->w_cursor.lnum
|
||||
== curwin->w_buffer->b_ml.ml_line_count
|
||||
&& curwin->w_cursor.lnum == curwin->w_topline)
|
||||
curwin->w_valid &= ~(VALID_TOPLINE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEAT_FOLDING
|
||||
/* Check for position outside of the fold column. */
|
||||
if (
|
||||
# ifdef FEAT_RIGHTLEFT
|
||||
curwin->w_p_rl ? col < curwin->w_width - curwin->w_p_fdc :
|
||||
# endif
|
||||
col >= curwin->w_p_fdc
|
||||
# ifdef FEAT_CMDWIN
|
||||
+ (cmdwin_type == 0 ? 0 : 1)
|
||||
# endif
|
||||
)
|
||||
mouse_char = ' ';
|
||||
#endif
|
||||
|
||||
/* compute the position in the buffer line from the posn on the screen */
|
||||
if (mouse_comp_pos(curwin, &row, &col, &curwin->w_cursor.lnum, NULL))
|
||||
mouse_past_bottom = TRUE;
|
||||
|
||||
/* Start Visual mode before coladvance(), for when 'sel' != "old" */
|
||||
if ((flags & MOUSE_MAY_VIS) && !VIsual_active)
|
||||
{
|
||||
check_visual_highlight();
|
||||
VIsual = old_cursor;
|
||||
VIsual_active = TRUE;
|
||||
VIsual_reselect = TRUE;
|
||||
/* if 'selectmode' contains "mouse", start Select mode */
|
||||
may_start_select('o');
|
||||
setmouse();
|
||||
if (p_smd && msg_silent == 0)
|
||||
redraw_cmdline = TRUE; /* show visual mode later */
|
||||
}
|
||||
|
||||
curwin->w_curswant = col;
|
||||
curwin->w_set_curswant = FALSE; /* May still have been TRUE */
|
||||
if (coladvance(col) == FAIL) /* Mouse click beyond end of line */
|
||||
{
|
||||
if (inclusive != NULL)
|
||||
*inclusive = TRUE;
|
||||
mouse_past_eol = TRUE;
|
||||
}
|
||||
else if (inclusive != NULL)
|
||||
*inclusive = FALSE;
|
||||
|
||||
count = IN_BUFFER;
|
||||
if (curwin != old_curwin || curwin->w_cursor.lnum != old_cursor.lnum
|
||||
|| curwin->w_cursor.col != old_cursor.col)
|
||||
count |= CURSOR_MOVED; /* Cursor has moved */
|
||||
|
||||
# ifdef FEAT_FOLDING
|
||||
if (mouse_char == '+')
|
||||
count |= MOUSE_FOLD_OPEN;
|
||||
else if (mouse_char != ' ')
|
||||
count |= MOUSE_FOLD_CLOSE;
|
||||
# endif
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Functions also used for popup windows.
|
||||
#if defined(FEAT_MOUSE) || defined(FEAT_TEXT_PROP) || defined(PROTO)
|
||||
|
||||
/*
|
||||
* Compute the buffer line position from the screen position "rowp" / "colp" in
|
||||
* window "win".
|
||||
* "plines_cache" can be NULL (no cache) or an array with "win->w_height"
|
||||
* entries that caches the plines_win() result from a previous call. Entry is
|
||||
* zero if not computed yet. There must be no text or setting changes since
|
||||
* the entry is put in the cache.
|
||||
* Returns TRUE if the position is below the last line.
|
||||
*/
|
||||
int
|
||||
mouse_comp_pos(
|
||||
win_T *win,
|
||||
int *rowp,
|
||||
int *colp,
|
||||
linenr_T *lnump,
|
||||
int *plines_cache)
|
||||
{
|
||||
int col = *colp;
|
||||
int row = *rowp;
|
||||
linenr_T lnum;
|
||||
int retval = FALSE;
|
||||
int off;
|
||||
int count;
|
||||
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (win->w_p_rl)
|
||||
col = win->w_width - 1 - col;
|
||||
#endif
|
||||
|
||||
lnum = win->w_topline;
|
||||
|
||||
while (row > 0)
|
||||
{
|
||||
int cache_idx = lnum - win->w_topline;
|
||||
|
||||
if (plines_cache != NULL && plines_cache[cache_idx] > 0)
|
||||
count = plines_cache[cache_idx];
|
||||
else
|
||||
{
|
||||
#ifdef FEAT_DIFF
|
||||
/* Don't include filler lines in "count" */
|
||||
if (win->w_p_diff
|
||||
# ifdef FEAT_FOLDING
|
||||
&& !hasFoldingWin(win, lnum, NULL, NULL, TRUE, NULL)
|
||||
# endif
|
||||
)
|
||||
{
|
||||
if (lnum == win->w_topline)
|
||||
row -= win->w_topfill;
|
||||
else
|
||||
row -= diff_check_fill(win, lnum);
|
||||
count = plines_win_nofill(win, lnum, TRUE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
count = plines_win(win, lnum, TRUE);
|
||||
if (plines_cache != NULL)
|
||||
plines_cache[cache_idx] = count;
|
||||
}
|
||||
if (count > row)
|
||||
break; /* Position is in this buffer line. */
|
||||
#ifdef FEAT_FOLDING
|
||||
(void)hasFoldingWin(win, lnum, NULL, &lnum, TRUE, NULL);
|
||||
#endif
|
||||
if (lnum == win->w_buffer->b_ml.ml_line_count)
|
||||
{
|
||||
retval = TRUE;
|
||||
break; /* past end of file */
|
||||
}
|
||||
row -= count;
|
||||
++lnum;
|
||||
}
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
/* Compute the column without wrapping. */
|
||||
off = win_col_off(win) - win_col_off2(win);
|
||||
if (col < off)
|
||||
col = off;
|
||||
col += row * (win->w_width - off);
|
||||
/* add skip column (for long wrapping line) */
|
||||
col += win->w_skipcol;
|
||||
}
|
||||
|
||||
if (!win->w_p_wrap)
|
||||
col += win->w_leftcol;
|
||||
|
||||
/* skip line number and fold column in front of the line */
|
||||
col -= win_col_off(win);
|
||||
if (col < 0)
|
||||
{
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
netbeans_gutter_click(lnum);
|
||||
#endif
|
||||
col = 0;
|
||||
}
|
||||
|
||||
*colp = col;
|
||||
*rowp = row;
|
||||
*lnump = lnum;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the window at screen position "*rowp" and "*colp". The positions are
|
||||
* updated to become relative to the top-left of the window.
|
||||
* When "popup" is FAIL_POPUP and the position is in a popup window then NULL
|
||||
* is returned. When "popup" is IGNORE_POPUP then do not even check popup
|
||||
* windows.
|
||||
* Returns NULL when something is wrong.
|
||||
*/
|
||||
win_T *
|
||||
mouse_find_win(int *rowp, int *colp, mouse_find_T popup UNUSED)
|
||||
{
|
||||
frame_T *fp;
|
||||
win_T *wp;
|
||||
|
||||
#ifdef FEAT_TEXT_PROP
|
||||
win_T *pwp = NULL;
|
||||
|
||||
if (popup != IGNORE_POPUP)
|
||||
{
|
||||
popup_reset_handled();
|
||||
while ((wp = find_next_popup(TRUE)) != NULL)
|
||||
{
|
||||
if (*rowp >= wp->w_winrow && *rowp < wp->w_winrow + popup_height(wp)
|
||||
&& *colp >= wp->w_wincol
|
||||
&& *colp < wp->w_wincol + popup_width(wp))
|
||||
pwp = wp;
|
||||
}
|
||||
if (pwp != NULL)
|
||||
{
|
||||
if (popup == FAIL_POPUP)
|
||||
return NULL;
|
||||
*rowp -= pwp->w_winrow;
|
||||
*colp -= pwp->w_wincol;
|
||||
return pwp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fp = topframe;
|
||||
*rowp -= firstwin->w_winrow;
|
||||
for (;;)
|
||||
{
|
||||
if (fp->fr_layout == FR_LEAF)
|
||||
break;
|
||||
if (fp->fr_layout == FR_ROW)
|
||||
{
|
||||
for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next)
|
||||
{
|
||||
if (*colp < fp->fr_width)
|
||||
break;
|
||||
*colp -= fp->fr_width;
|
||||
}
|
||||
}
|
||||
else /* fr_layout == FR_COL */
|
||||
{
|
||||
for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next)
|
||||
{
|
||||
if (*rowp < fp->fr_height)
|
||||
break;
|
||||
*rowp -= fp->fr_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* When using a timer that closes a window the window might not actually
|
||||
* exist. */
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
if (wp == fp->fr_win)
|
||||
{
|
||||
#ifdef FEAT_MENU
|
||||
*rowp -= wp->w_winbar_height;
|
||||
#endif
|
||||
return wp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MAC) \
|
||||
|| defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
|
||||
|| defined(FEAT_GUI_PHOTON) || defined(FEAT_TERM_POPUP_MENU) \
|
||||
|| defined(PROTO)
|
||||
# define NEED_VCOL2COL
|
||||
|
||||
/*
|
||||
* Translate window coordinates to buffer position without any side effects
|
||||
*/
|
||||
int
|
||||
get_fpos_of_mouse(pos_T *mpos)
|
||||
{
|
||||
win_T *wp;
|
||||
int row = mouse_row;
|
||||
int col = mouse_col;
|
||||
|
||||
if (row < 0 || col < 0) /* check if it makes sense */
|
||||
return IN_UNKNOWN;
|
||||
|
||||
/* find the window where the row is in */
|
||||
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||
if (wp == NULL)
|
||||
return IN_UNKNOWN;
|
||||
/*
|
||||
* winpos and height may change in win_enter()!
|
||||
*/
|
||||
if (row >= wp->w_height) /* In (or below) status line */
|
||||
return IN_STATUS_LINE;
|
||||
if (col >= wp->w_width) /* In vertical separator line */
|
||||
return IN_SEP_LINE;
|
||||
|
||||
if (wp != curwin)
|
||||
return IN_UNKNOWN;
|
||||
|
||||
/* compute the position in the buffer line from the posn on the screen */
|
||||
if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum, NULL))
|
||||
return IN_STATUS_LINE; /* past bottom */
|
||||
|
||||
mpos->col = vcol2col(wp, mpos->lnum, col);
|
||||
|
||||
if (mpos->col > 0)
|
||||
--mpos->col;
|
||||
mpos->coladd = 0;
|
||||
return IN_BUFFER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NEED_VCOL2COL) || defined(FEAT_BEVAL) || defined(FEAT_TEXT_PROP) \
|
||||
|| defined(PROTO)
|
||||
/*
|
||||
* Convert a virtual (screen) column to a character column.
|
||||
* The first column is one.
|
||||
*/
|
||||
int
|
||||
vcol2col(win_T *wp, linenr_T lnum, int vcol)
|
||||
{
|
||||
/* try to advance to the specified column */
|
||||
int count = 0;
|
||||
char_u *ptr;
|
||||
char_u *line;
|
||||
|
||||
line = ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
|
||||
while (count < vcol && *ptr != NUL)
|
||||
{
|
||||
count += win_lbr_chartabsize(wp, line, ptr, count, NULL);
|
||||
MB_PTR_ADV(ptr);
|
||||
}
|
||||
return (int)(ptr - line);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FEAT_MOUSE */
|
||||
|
||||
#if defined(FEAT_GUI) || defined(MSWIN) || defined(PROTO)
|
||||
/*
|
||||
* Called when focus changed. Used for the GUI or for systems where this can
|
||||
|
Reference in New Issue
Block a user