⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 screen.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
			idx = 0;
		    }
		}
		else if (lastwin == firstwin)
		{
		    screenclear();  /* far off: clearing the screen is faster */
		    must_start_top = TRUE;
		    must_end_bot = TRUE;
		}
	    }
	    else if (lastwin == firstwin)
	    {
		screenclear();	    /* far off: clearing the screen is faster */
		must_start_top = TRUE;
		must_end_bot = TRUE;
	    }
	}
	else				/* may scroll up */
	{
	    j = -1;
			/* try to find wp->w_topline in wp->w_lsize_lnum[] */
	    for (i = 0; i < wp->w_lsize_valid; i++)
	    {
		if (wp->w_lsize_lnum[i] == wp->w_topline)
		{
		    j = i;
		    break;
		}
		row += wp->w_lsize[i];
	    }
	    if (j == -1)    /* wp->w_topline is not in wp->w_lsize_lnum */
	    {
		row = 0;    /* start at the first row */
		if (lastwin == firstwin)
		{
		    screenclear();  /* far off: clearing the screen is faster */
		    must_start_top = TRUE;
		    must_end_bot = TRUE;
		}
	    }
	    else
	    {
		/*
		 * Try to delete the correct number of lines.
		 * wp->w_topline is at wp->w_lsize_lnum[i].
		 */
		if (row)
		{
		    check_for_delay(FALSE);
		    if (win_del_lines(wp, 0, row, FALSE, wp == firstwin) == OK)
			must_end_bot = TRUE;
		}
		if ((row == 0 || must_end_bot) && wp->w_lsize_valid)
		{
		    /*
		     * Skip the lines (below the deleted lines) that are still
		     * valid and don't need redrawing.	Copy their info
		     * upwards, to compensate for the deleted lines.  Leave
		     * row and lnum on the first line that needs redrawing.
		     */
		    srow = row;
		    row = 0;
		    for (;;)
		    {
			if ((type == VALID_TO_CURSCHAR &&
						 lnum == wp->w_cursor.lnum) ||
				(type == VALID_BEF_CURSCHAR &&
					       lnum == wp->w_cursor.lnum - 1))
			{
			    wp->w_lsize_valid = idx;
			    break;
			}
			wp->w_lsize[idx] = wp->w_lsize[j];
			wp->w_lsize_lnum[idx] = lnum;
			if (row + srow + (int)wp->w_lsize[j] > wp->w_height)
			{
			    wp->w_lsize_valid = idx + 1;
			    break;
			}
			++lnum;

			row += wp->w_lsize[idx++];
			if ((int)++j >= wp->w_lsize_valid)
			{
			    wp->w_lsize_valid = idx;
			    break;
			}
		    }
		}
		else
		    row = 0;	    /* update all lines */
	    }
	}
	if (endrow == wp->w_height && idx == 0)	    /* no scrolling */
	    wp->w_lsize_valid = 0;
    }

    done = didline = FALSE;

    if (VIsual_active)	    /* check if we are updating the inverted part */
    {
	linenr_t    from, to;

	/*
	 * Find the line numbers that need to be updated: The lines between
	 * the old cursor position and the current cursor position.  Also
	 * check if the Visual position changed.
	 */
	if (curwin->w_cursor.lnum < wp->w_old_cursor_lnum)
	{
	    from = curwin->w_cursor.lnum;
	    to = wp->w_old_cursor_lnum;
	}
	else
	{
	    from = wp->w_old_cursor_lnum;
	    to = curwin->w_cursor.lnum;
	}

	if (VIsual.lnum != wp->w_old_visual_lnum)
	{
	    if (wp->w_old_visual_lnum < from)
		from = wp->w_old_visual_lnum;
	    if (wp->w_old_visual_lnum > to)
		to = wp->w_old_visual_lnum;
	    if (VIsual.lnum < from)
		from = VIsual.lnum;
	    if (VIsual.lnum > to)
		to = VIsual.lnum;
	}

	/*
	 * If in block mode and changed column or curwin->w_curswant: update
	 * all lines.
	 * First compute the actual start and end column.
	 */
	if (VIsual_mode == Ctrl('V'))
	{
	    colnr_t	from1, from2, to1, to2;

	    if (lt(VIsual, curwin->w_cursor))
	    {
		getvcol(wp, &VIsual, &from1, NULL, &to1);
		getvcol(wp, &curwin->w_cursor, &from2, NULL, &to2);
	    }
	    else
	    {
		getvcol(wp, &curwin->w_cursor, &from1, NULL, &to1);
		getvcol(wp, &VIsual, &from2, NULL, &to2);
	    }
	    if (from2 < from1)
		from1 = from2;
	    if (to2 > to1)
	    {
		if (*p_sel == 'e' && from2 - 1 >= to1)
		    to1 = from2 - 1;
		else
		    to1 = to2;
	    }
	    ++to1;
	    if (curwin->w_curswant == MAXCOL)
		to1 = MAXCOL;

	    if (from1 != wp->w_old_cursor_fcol || to1 != wp->w_old_cursor_lcol)
	    {
		if (from > VIsual.lnum)
		    from = VIsual.lnum;
		if (to < VIsual.lnum)
		    to = VIsual.lnum;
	    }
	    wp->w_old_cursor_fcol = from1;
	    wp->w_old_cursor_lcol = to1;
	}

	/*
	 * There is no need to update lines above the top of the window.
	 * If "must_start_top" is set, always start at w_topline.
	 */
	if (from < wp->w_topline || must_start_top)
	    from = wp->w_topline;

	/*
	 * If we know the value of w_botline, use it to restrict the update to
	 * the lines that are visible in the window.
	 */
	if (wp->w_valid & VALID_BOTLINE)
	{
	    if (from >= wp->w_botline)
		from = wp->w_botline - 1;
	    if (to >= wp->w_botline)
		to = wp->w_botline - 1;
	}

	/*
	 * Find the minimal part to be updated.
	 *
	 * If "lnum" is past "from" already, start at w_topline (can
	 * happen when scrolling).
	 */
	if (lnum > from)
	{
	    lnum = wp->w_topline;
	    idx = 0;
	    row = 0;
	}
	while (lnum < from && idx < wp->w_lsize_valid)	    /* find start */
	{
	    row += wp->w_lsize[idx++];
	    ++lnum;
	}
	if (!must_end_bot && !must_start_top)
	{
	    srow = row;
	    for (j = idx; j < wp->w_lsize_valid; ++j)	    /* find end */
	    {
		if (wp->w_lsize_lnum[j] == to + 1)
		{
		    endrow = srow;
		    break;
		}
		srow += wp->w_lsize[j];
	    }
	}
	else
	{
	    /* Redraw until the end, otherwise we could miss something when
	     * doing CTRL-U. */
	    endrow = wp->w_height;
	}

	wp->w_old_cursor_lnum = curwin->w_cursor.lnum;
	wp->w_old_visual_lnum = VIsual.lnum;
	wp->w_old_curswant = curwin->w_curswant;
    }
    else
    {
	wp->w_old_cursor_lnum = 0;
	wp->w_old_visual_lnum = 0;
    }

    /*
     * Update the screen rows from "row" to "endrow".
     * Start at line "lnum" which is at wp->w_lsize_lnum[idx].
     */
    for (;;)
    {
	if (row == endrow)
	{
	    didline = TRUE;
	    break;
	}

	if (lnum > wp->w_buffer->b_ml.ml_line_count)
	{
	    done = TRUE;	/* hit the end of the file */
	    break;
	}
	srow = row;
	row = win_line(wp, lnum, srow, endrow);
	if (row > endrow)	/* past end of screen */
	{
	    /* we may need the size of that too long line later on */
	    wp->w_lsize[idx] = plines_win(wp, lnum);
	    wp->w_lsize_lnum[idx++] = lnum;
	    break;
	}

	wp->w_lsize[idx] = row - srow;
	wp->w_lsize_lnum[idx++] = lnum;
	if (++lnum > wp->w_buffer->b_ml.ml_line_count)
	{
	    done = TRUE;
	    break;
	}
    }
    if (idx > wp->w_lsize_valid)
	wp->w_lsize_valid = idx;

    /* Do we have to do off the top of the screen processing ? */
    if (endrow != wp->w_height)
    {
	row = 0;
	for (idx = 0; idx < wp->w_lsize_valid && row < wp->w_height; idx++)
	    row += wp->w_lsize[idx];

	if (row < wp->w_height)
	{
	    done = TRUE;
	}
	else if (row > wp->w_height)	/* Need to blank out the last line */
	{
	    lnum = wp->w_lsize_lnum[idx - 1];
	    srow = row - wp->w_lsize[idx - 1];
	    didline = FALSE;
	}
	else
	{
	    lnum = wp->w_lsize_lnum[idx - 1] + 1;
	    didline = TRUE;
	}
    }

    wp->w_empty_rows = 0;
    /*
     * If we didn't hit the end of the file, and we didn't finish the last
     * line we were working on, then the line didn't fit.
     */
    if (!done && !didline)
    {
	if (lnum == wp->w_topline)
	{
#if 0
	    /*
	     * Single line that does not fit!
	     * Fill last line with '@' characters.
	     */
	    screen_fill(wp->w_winpos + wp->w_height - 1,
		    wp->w_winpos + wp->w_height, 0, (int)Columns, '@', '@',
		    hl_attr(HLF_AT));
#endif
	    wp->w_botline = lnum + 1;
	}
	else
	{
	    /*
	     * Clear the rest of the screen and mark the unused lines.
	     */
#ifdef RIGHTLEFT
	    if (wp->w_p_rl)
	    {
		screen_fill(wp->w_winpos + srow,
			wp->w_winpos + wp->w_height, 0, (int)Columns - 1,
			' ', ' ', hl_attr(HLF_AT));
		screen_fill(wp->w_winpos + srow,
			wp->w_winpos + wp->w_height, (int)Columns - 1,
			(int)Columns, '@', ' ', hl_attr(HLF_AT));
	    }
	    else
#endif
		screen_fill(wp->w_winpos + srow,
			wp->w_winpos + wp->w_height, 0, (int)Columns, '@', ' ',
			hl_attr(HLF_AT));
	    wp->w_botline = lnum;
	    wp->w_empty_rows = wp->w_height - srow;
	}
    }
    else
    {
	/* make sure the rest of the screen is blank */
	/* put '~'s on rows that aren't part of the file. */
#ifdef RIGHTLEFT
	if (wp->w_p_rl)
	{
	    screen_fill(wp->w_winpos + row,
		    wp->w_winpos + wp->w_height, 0, (int)Columns - 1,
		    ' ', ' ', hl_attr(HLF_AT));
	    screen_fill(wp->w_winpos + row,
		    wp->w_winpos + wp->w_height, (int)Columns - 1,
		    (int)Columns, '~', ' ', hl_attr(HLF_AT));
	}
	else
#endif
	    screen_fill(wp->w_winpos + row,
			wp->w_winpos + wp->w_height, 0, (int)Columns, '~', ' ',
			hl_attr(HLF_AT));
	wp->w_empty_rows = wp->w_height - row;

	if (done)		/* we hit the end of the file */
	    wp->w_botline = wp->w_buffer->b_ml.ml_line_count + 1;
	else
	    wp->w_botline = lnum;
    }

    /*
     * There is a trick with w_botline.  If we invalidate it on each change
     * that might modify it, this will cause a lot of expensive calls to
     * plines() in update_topline() each time.	Therefore the value of
     * w_botline is often approximated, and this value is used to compute the
     * value of w_topline.  If the value of w_botline was wrong, check that
     * the value of w_topline is correct (cursor is on the visible part of the
     * text).  If it's not, we need to redraw again.  Mostly this just means
     * scrolling up a few lines, so it doesn't look too bad.  Only do this for
     * the current window (where changes are relevant).
     */
    wp->w_valid |= VALID_BOTLINE;
    if (wp == curwin && wp->w_botline != old_botline && !recursive)
    {
	recursive = TRUE;
	update_topline();	/* may invalidate w_botline again */
	if (must_redraw)
	{
	    win_update(wp);
	    must_redraw = 0;
	}
	recursive = FALSE;
    }

    /* When insering lines at top, these have been redrawn now.  Still need to
     * redraw other lines with changes */
    if (wp->w_redr_type && !recursive)
    {
	recursive = TRUE;
	win_update(wp);
	recursive = FALSE;
    }
}

/*
 * Display line "lnum" of window 'wp' on the screen.
 * Start at row "startrow", stop when "endrow" is reached.
 * wp->w_virtcol needs to be valid.
 *
 * Return the number of last row the line occupies.
 */

    static int
win_line(wp, lnum, startrow, endrow)
    WIN		    *wp;
    linenr_t	    lnum;
    int		    startrow;
    int		    endrow;
{
    char_u	    *screenp;
    int		    c = 0;		/* init for GCC */
    int		    col;		/* visual column on screen */
    long	    vcol;		/* visual column for tabs */
    long	    v;
#ifdef SYNTAX_HL
    int		    rcol;		/* real column in the line */
#endif
    int		    row;		/* row in the window, excl w_winpos */
    int		    screen_row;		/* row on the screen, incl w_winpos */
    char_u	    *ptr;
#ifdef SYNTAX_HL
    char_u	    *line;
#endif
    char_u	    extra[16];		/* "%ld" must fit in here */
    int		    n_extra = 0;	/* number of extra chars */
    char_u	    *p_extra = NULL;	/* string of extra chars */
    int		    c_extra = NUL;	/* extra chars, all the same */
    char_u	    *showbreak = NULL;
    int		    n_attr = 0;		/* chars with current attr */
    int		    n_skip = 0;		/* nr of chars to skip for 'nowrap' */
    int		    n_number = 0;	/* chars for 'number' */

    int		    fromcol, tocol;	/* start/end of inverting */
    int		    noinvcur = FALSE;	/* don't invert the cursor */
    FPOS	    *top, *bot;
    int		    area_highlighting;	/* Visual or incsearch highlighting in
					   this line */
    int		    attr;		/* attributes for area highlighting */
    int		    area_attr = 0;	/* attributes desired by highlighting */
    int		    search_attr = 0;	/* attributes sesired by 'searchhl' */
#ifdef SYNTAX_HL
    int		    syntax_attr = 0;	/* attributes desired by syntax */
    int		    has_syntax = FALSE;	/* this buffer has syntax highl. */
#endif
    int		    extra_check;	/* has syntax or linebreak */
    int		    char_attr;		/* attributes for next character */
    int		    saved_attr1 = 0;	/* char_attr saved for showbreak */
    int		    saved_attr2 = 0;	/* char_attr saved for listtabstring */
    int		    extra_attr = 0;
#ifdef EXTRA_SEARCH
    char_u	    *matchp;
    char_u	    *search_hl_start = NULL;
    char_u	    *search_hl_end = NULL;
#endif
#ifdef MULTI_BYTE
    int		    bCharacter = 0;
    char_u	    *line_head;
#endif
    char_u	    *trail = NULL;	/* start of trailing spaces */

    if (startrow > endrow)		/* past the end already! */
	return startrow;

    row = startrow;
    screen_row = row + wp->w_winpos;
    attr = hl_attr(HLF_V);

    /*
     * To speed up the loop below, set extra_check when there is linebreak,
     * trailing white spcae and/or syntax processing to be done.
     */
    extra_check = wp->w_p_lbr;
#ifdef SYNTAX_HL
    if (syntax_present(wp->w_buffer))
    {
	syntax_start(wp, lnum);
	has_syntax = TRUE;
	extra_check = TRUE;
    }
#endif
    col = 0;
    vcol = 0;
    fromcol = -10;
    tocol = MAXCOL;
    area_highlighting = FALSE;
    char_attr = 0;

    /*
     * handle visual active in this window
     */
    if (VIsual_active && wp->w_buffer == curwin->w_buffer)
    {
					/* Visual is after curwin->w_cursor */
	if (ltoreq(curwin->w_cursor, VIsual))
	{
	    top = &curwin->w_cursor;
	    bot = &VIsual;
	}
	else				/* Visual is before curwin->w_cursor */
	{
	    top = &VIsual;
	    bot = &curwin->w_cursor;
	}
	if (VIsual_mode == Ctrl('V'))	/* block mode */
	{
	    if (lnum >= top->lnum && lnum <= bot->lnum)
	    {
		fromcol = wp->w_old_cursor_fcol;
		tocol = wp->w_old_cursor_lcol;
	    }
	}
	else				/* non-block mode */
	{
	    if (lnum > top->lnum && lnum <= bot->lnum)
		fromcol = 0;
	    else if (lnum == top->lnum)
	    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -