6176 lines · 141.9 KB · C
RawDownload
/* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved	by Bram Moolenaar * * Do ":help uganda"  in Vim to read a list of people who contributed. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ #include "vim.h" #ifdef HAVE_FCNTL_H# include <fcntl.h>	    /* for chdir() */#endif static int path_is_url __ARGS((char_u *p));#if defined(FEAT_WINDOWS) || defined(PROTO)static int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir));static void win_init __ARGS((win_T *newp, win_T *oldp));static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col));static void frame_setheight __ARGS((frame_T *curfrp, int height));#ifdef FEAT_VERTSPLITstatic void frame_setwidth __ARGS((frame_T *curfrp, int width));#endifstatic void win_exchange __ARGS((long));static void win_rotate __ARGS((int, int));static void win_totop __ARGS((int size, int flags));static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height));static int last_window __ARGS((void));static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));static win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp));static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));static tabpage_T *alt_tabpage __ARGS((void));static win_T *frame2win __ARGS((frame_T *frp));static int frame_has_win __ARGS((frame_T *frp, win_T *wp));static void frame_new_height __ARGS((frame_T *topfrp, int height, int topfirst, int wfh));static int frame_fixed_height __ARGS((frame_T *frp));#ifdef FEAT_VERTSPLITstatic int frame_fixed_width __ARGS((frame_T *frp));static void frame_add_statusline __ARGS((frame_T *frp));static void frame_new_width __ARGS((frame_T *topfrp, int width, int leftfirst, int wfw));static void frame_add_vsep __ARGS((frame_T *frp));static int frame_minwidth __ARGS((frame_T *topfrp, win_T *next_curwin));static void frame_fix_width __ARGS((win_T *wp));#endif#endifstatic int win_alloc_firstwin __ARGS((win_T *oldwin));#if defined(FEAT_WINDOWS) || defined(PROTO)static tabpage_T *alloc_tabpage __ARGS((void));static int leave_tabpage __ARGS((buf_T *new_curbuf));static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf));static void frame_fix_height __ARGS((win_T *wp));static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin));static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin));static void win_free __ARGS((win_T *wp, tabpage_T *tp));static void win_append __ARGS((win_T *, win_T *));static void win_remove __ARGS((win_T *, tabpage_T *tp));static void frame_append __ARGS((frame_T *after, frame_T *frp));static void frame_insert __ARGS((frame_T *before, frame_T *frp));static void frame_remove __ARGS((frame_T *frp));#ifdef FEAT_VERTSPLITstatic void win_new_width __ARGS((win_T *wp, int width));static void win_goto_ver __ARGS((int up, long count));static void win_goto_hor __ARGS((int left, long count));#endifstatic void frame_add_height __ARGS((frame_T *frp, int n));static void last_status_rec __ARGS((frame_T *fr, int statusline)); static void make_snapshot __ARGS((void));static void make_snapshot_rec __ARGS((frame_T *fr, frame_T **frp));static void clear_snapshot __ARGS((tabpage_T *tp));static void clear_snapshot_rec __ARGS((frame_T *fr));static void restore_snapshot __ARGS((int close_curwin));static int check_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr)); #endif /* FEAT_WINDOWS */static win_T *win_alloc __ARGS((win_T *after));static void win_new_height __ARGS((win_T *, int)); #define URL_SLASH	1		/* path_is_url() has found "://" */#define URL_BACKSLASH	2		/* path_is_url() has found ":\\" */ #define NOWIN		(win_T *)-1	/* non-existing window */ #ifdef FEAT_WINDOWS# define ROWS_AVAIL (Rows - p_ch - tabline_height())#else# define ROWS_AVAIL (Rows - p_ch)#endif #if defined(FEAT_WINDOWS) || defined(PROTO) static char *m_onlyone = N_("Already only one window"); /* * all CTRL-W window commands are handled here, called from normal_cmd(). */    voiddo_window(nchar, Prenum, xchar)    int		nchar;    long	Prenum;    int		xchar;	    /* extra char from ":wincmd gx" or NUL */{    long	Prenum1;    win_T	*wp;#if defined(FEAT_SEARCHPATH) || defined(FEAT_FIND_ID)    char_u	*ptr;    linenr_T    lnum = -1;#endif#ifdef FEAT_FIND_ID    int		type = FIND_DEFINE;    int		len;#endif    char_u	cbuf[40];     if (Prenum == 0)	Prenum1 = 1;    else	Prenum1 = Prenum; #ifdef FEAT_CMDWIN# define CHECK_CMDWIN if (cmdwin_type != 0) { EMSG(_(e_cmdwin)); break; }#else# define CHECK_CMDWIN#endif     switch (nchar)    {/* split current window in two parts, horizontally */    case 'S':    case Ctrl_S:    case 's':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif#ifdef FEAT_QUICKFIX		/* When splitting the quickfix window open a new buffer in it,		 * don't replicate the quickfix buffer. */		if (bt_quickfix(curbuf))		    goto newwindow;#endif#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_split((int)Prenum, 0);		break; #ifdef FEAT_VERTSPLIT/* split current window in two parts, vertically */    case Ctrl_V:    case 'v':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_split((int)Prenum, WSP_VERT);		break;#endif /* split current window and edit alternate file */    case Ctrl_HAT:    case '^':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		STRCPY(cbuf, "split #");		if (Prenum)		    sprintf((char *)cbuf + 7, "%ld", Prenum);		do_cmdline_cmd(cbuf);		break; /* open new window */    case Ctrl_N:    case 'n':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif#ifdef FEAT_QUICKFIXnewwindow:#endif		if (Prenum)		    sprintf((char *)cbuf, "%ld", Prenum); /* window height */		else		    cbuf[0] = NUL;		STRCAT(cbuf, "new");		do_cmdline_cmd(cbuf);		break; /* quit current window */    case Ctrl_Q:    case 'q':#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		do_cmdline_cmd((char_u *)"quit");		break; /* close current window */    case Ctrl_C:    case 'c':#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		do_cmdline_cmd((char_u *)"close");		break; #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)/* close preview window */    case Ctrl_Z:    case 'z':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		do_cmdline_cmd((char_u *)"pclose");		break; /* cursor to preview window */    case 'P':		for (wp = firstwin; wp != NULL; wp = wp->w_next)		    if (wp->w_p_pvw)			break;		if (wp == NULL)		    EMSG(_("E441: There is no preview window"));		else		    win_goto(wp);		break;#endif /* close all but current window */    case Ctrl_O:    case 'o':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		do_cmdline_cmd((char_u *)"only");		break; /* cursor to next window with wrap around */    case Ctrl_W:    case 'w':/* cursor to previous window with wrap around */    case 'W':		CHECK_CMDWIN		if (lastwin == firstwin && Prenum != 1)	/* just one window */		    beep_flush();		else		{		    if (Prenum)			/* go to specified window */		    {			for (wp = firstwin; --Prenum > 0; )			{			    if (wp->w_next == NULL)				break;			    else				wp = wp->w_next;			}		    }		    else		    {			if (nchar == 'W')	    /* go to previous window */			{			    wp = curwin->w_prev;			    if (wp == NULL)				wp = lastwin;	    /* wrap around */			}			else			    /* go to next window */			{			    wp = curwin->w_next;			    if (wp == NULL)				wp = firstwin;	    /* wrap around */			}		    }		    win_goto(wp);		}		break; /* cursor to window below */    case 'j':    case K_DOWN:    case Ctrl_J:		CHECK_CMDWIN#ifdef FEAT_VERTSPLIT		win_goto_ver(FALSE, Prenum1);#else		for (wp = curwin; wp->w_next != NULL && Prenum1-- > 0;							    wp = wp->w_next)		    ;		win_goto(wp);#endif		break; /* cursor to window above */    case 'k':    case K_UP:    case Ctrl_K:		CHECK_CMDWIN#ifdef FEAT_VERTSPLIT		win_goto_ver(TRUE, Prenum1);#else		for (wp = curwin; wp->w_prev != NULL && Prenum1-- > 0;							    wp = wp->w_prev)		    ;		win_goto(wp);#endif		break; #ifdef FEAT_VERTSPLIT/* cursor to left window */    case 'h':    case K_LEFT:    case Ctrl_H:    case K_BS:		CHECK_CMDWIN		win_goto_hor(TRUE, Prenum1);		break; /* cursor to right window */    case 'l':    case K_RIGHT:    case Ctrl_L:		CHECK_CMDWIN		win_goto_hor(FALSE, Prenum1);		break;#endif /* move window to new tab page */    case 'T':		if (firstwin == lastwin)		    MSG(_(m_onlyone));		else		{		    tabpage_T	*oldtab = curtab;		    tabpage_T	*newtab; 		    /* First create a new tab with the window, then go back to		     * the old tab and close the window there. */		    wp = curwin;		    if (win_new_tabpage((int)Prenum) == OK						     && valid_tabpage(oldtab))		    {			newtab = curtab;			goto_tabpage_tp(oldtab);			if (curwin == wp)			    win_close(curwin, FALSE);			if (valid_tabpage(newtab))			    goto_tabpage_tp(newtab);		    }		}		break; /* cursor to top-left window */    case 't':    case Ctrl_T:		win_goto(firstwin);		break; /* cursor to bottom-right window */    case 'b':    case Ctrl_B:		win_goto(lastwin);		break; /* cursor to last accessed (previous) window */    case 'p':    case Ctrl_P:		if (prevwin == NULL)		    beep_flush();		else		    win_goto(prevwin);		break; /* exchange current and next window */    case 'x':    case Ctrl_X:		CHECK_CMDWIN		win_exchange(Prenum);		break; /* rotate windows downwards */    case Ctrl_R:    case 'r':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		win_rotate(FALSE, (int)Prenum1);    /* downwards */		break; /* rotate windows upwards */    case 'R':		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		win_rotate(TRUE, (int)Prenum1);	    /* upwards */		break; /* move window to the very top/bottom/left/right */    case 'K':    case 'J':#ifdef FEAT_VERTSPLIT    case 'H':    case 'L':#endif		CHECK_CMDWIN		win_totop((int)Prenum,			((nchar == 'H' || nchar == 'L') ? WSP_VERT : 0)			| ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));		break; /* make all windows the same height */    case '=':#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_equal(NULL, FALSE, 'b');		break; /* increase current window height */    case '+':#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_setheight(curwin->w_height + (int)Prenum1);		break; /* decrease current window height */    case '-':#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_setheight(curwin->w_height - (int)Prenum1);		break; /* set current window height */    case Ctrl__:    case '_':#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_setheight(Prenum ? (int)Prenum : 9999);		break; #ifdef FEAT_VERTSPLIT/* increase current window width */    case '>':#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_setwidth(curwin->w_width + (int)Prenum1);		break; /* decrease current window width */    case '<':#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_setwidth(curwin->w_width - (int)Prenum1);		break; /* set current window width */    case '|':#ifdef FEAT_GUI		need_mouse_correct = TRUE;#endif		win_setwidth(Prenum != 0 ? (int)Prenum : 9999);		break;#endif /* jump to tag and split window if tag exists (in preview window) */#if defined(FEAT_QUICKFIX)    case '}':		CHECK_CMDWIN		if (Prenum)		    g_do_tagpreview = Prenum;		else		    g_do_tagpreview = p_pvh;		/*FALLTHROUGH*/#endif    case ']':    case Ctrl_RSB:		CHECK_CMDWIN#ifdef FEAT_VISUAL		reset_VIsual_and_resel();	/* stop Visual mode */#endif		if (Prenum)		    postponed_split = Prenum;		else		    postponed_split = -1; 		/* Execute the command right here, required when

Lines 1–500 of 6176.