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

📄 screen.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
		    col == Columns - 1)
		&& (*ptr != NUL
		    || (wp->w_p_list && lcs_eol != NUL)
		    || (n_extra && (c_extra != NUL || *p_extra != NUL))))
	{
	    c = lcs_ext;
	    char_attr = hl_attr(HLF_AT);
	}

#ifdef MULTI_BYTE
	if (is_dbcs)
	{
	    /* if an mult-byte character splits by line edge,
	       lead or trail byte is substituted by '~' */
	    if (col == 0 && bCharacter)
	    {
		if (IsTrailByte(line_head, ptr-1))
		    c = '~';
	    }
	    if (
# ifdef RIGHTLEFT
		    wp->w_p_rl ? (col <= 0) :
# endif
		    (col >= Columns-1))
	    {
		if (bCharacter && IsLeadByte(*(ptr-1))
			&& IsTrailByte(line_head, ptr))
		    c = '~';
	    }
	    bCharacter = 0;
	}
#endif

	/* Skip characters that are left of the screen for 'nowrap' */
	if (n_number > 0 || n_skip <= 0)
	{
	    /*
	     * Store the character.
	     */
	    *screenp = c;
	    *(screenp + Columns) = char_attr;

#ifdef RIGHTLEFT
	    if (wp->w_p_rl)
	    {
		--screenp;
		--col;
	    }
	    else
#endif
	    {
		++screenp;
		++col;
	    }
	    --n_number;
	}
	else
	    --n_skip;
	++vcol;

	/* restore attributes after last 'listchars' or 'number' char */
	if (n_attr && --n_attr == 0)
	    char_attr = saved_attr2;

	/* When still displaying '$' of change command, stop at cursor */
	if (dollar_vcol && wp == curwin && vcol >= (long)wp->w_virtcol)
	{
	    SCREEN_LINE(screen_row, col, FALSE, wp->w_p_rl);
	    break;
	}
    }

    return (row);
}

/*
 * Move one "cooked" screen line to the screen, but only the characters that
 * have actually changed.  Handle insert/delete character.
 * 'endcol' gives the columns where valid characters are.
 * 'clear_rest' is TRUE if the rest of the line needs to be cleared.
 * 'rlflag' is TRUE in a rightleft window:
 *	When TRUE and clear_rest, line is cleared in 0 -- endcol.
 *	When FALSE and clear_rest, line is cleared in endcol -- Columns-1.
 */
    static void
screen_line(row, endcol, clear_rest
#ifdef RIGHTLEFT
				    , rlflag
#endif
						)
    int	    row;
    int	    endcol;
    int	    clear_rest;
#ifdef RIGHTLEFT
    int	    rlflag;
#endif
{
    char_u	    *screenp_from;
    char_u	    *screenp_to;
    int		    col = 0;
    int		    force = FALSE;	/* force update rest of the line */

    screenp_from = current_LinePointer;
    screenp_to = LinePointers[row];

#ifdef RIGHTLEFT
    if (rlflag)
    {
	if (clear_rest)
	{
	    while (col <= endcol && *screenp_to == ' '
					      && *(screenp_to + Columns) == 0)
	    {
		++screenp_to;
		++col;
	    }
	    if (col <= endcol)
		screen_fill(row, row + 1, col, endcol + 1, ' ', ' ', 0);
	}
	col = endcol + 1;
	screenp_to = LinePointers[row] + col;
	screenp_from += col;
    }

    while (rlflag ? (col < Columns) : (col < endcol))
#else
    while (col < endcol)
#endif
    {

	if (
#if defined(MULTI_BYTE)
		/* a multi byte ch. is misprinted when right/left scrolling. */
		is_dbcs ||
#endif
		   force
		|| *screenp_from != *screenp_to
		|| *(screenp_from + Columns) != *(screenp_to + Columns)
	   )
	{

	    /*
	     * Special handling when 'xs' termcap flag set (hpterm):
	     * Attributes for characters are stored at the position where the
	     * cursor is when writing the highlighting code.  The
	     * start-highlighting code must be written with the cursor on the
	     * first highlighted character.  The stop-highlighting code must
	     * be written with the cursor just after the last highlighted
	     * character.
	     * Overwriting a character doesn't remove it's highlighting.  Need
	     * to clear the rest of the line, and force redrawing it
	     * completely.
	     */
	    if (       p_wiv
		    && !force
#ifdef USE_GUI
		    && !gui.in_use
#endif
		    && *(screenp_to + Columns)
		    && *(screenp_from + Columns) != *(screenp_to + Columns))
	    {
		/*
		 * Need to remove highlighting attributes here.
		 */
		windgoto(row, col);
		out_str(T_CE);		/* clear rest of this screen line */
		screen_start();		/* don't know where cursor is now */
		force = TRUE;		/* force redraw of rest of the line */

		/*
		 * If the previous character was highlighted, need to stop
		 * highlighting at this character.
		 */
		if (col > 0 && *(screenp_to + Columns - 1))
		{
		    screen_attr = *(screenp_to + Columns - 1);
		    term_windgoto(row, col);
		    screen_stop_highlight();
		}
		else
		    screen_attr = 0;	    /* highlighting has stopped */
	    }
	    *screenp_to = *screenp_from;

#if defined(USE_GUI) || defined(UNIX)
	    /* The bold trick makes a single row of pixels appear in the next
	     * character.  When a bold character is removed, the next
	     * character should be redrawn too.  This happens for our own GUI
	     * and for some xterms. */
	    if (
# ifdef USE_GUI
		    gui.in_use
# endif
# if defined(USE_GUI) && defined(UNIX)
		    ||
# endif
# ifdef UNIX
		    vim_is_xterm(T_NAME)
# endif
		    )
	    {
		int		n;

		n = *(screenp_to + Columns);
		if (col + 1 < Columns && (n > HL_ALL || (n & HL_BOLD)))
		    *(screenp_to + 1) = 0;
	    }
#endif
	    *(screenp_to + Columns) = *(screenp_from + Columns);
	    screen_char(screenp_to, row, col);
	}
	else if (  p_wiv
#ifdef USE_GUI
		&& !gui.in_use
#endif
		&& col > 0)
	{
	    if (*(screenp_to + Columns) == *(screenp_to + Columns - 1))
	    {
		/*
		 * Don't output stop-highlight when moving the cursor, it will
		 * stop the highlighting when it should continue.
		 */
		screen_attr = 0;
	    }
	    else if (screen_attr)
	    {
		screen_stop_highlight();
	    }
	}

	++screenp_to;
	++screenp_from;
	++col;
    }

    if (clear_rest
#ifdef RIGHTLEFT
		    && !rlflag
#endif
				   )
    {
	/* blank out the rest of the line */
	while (col < Columns && *screenp_to == ' ' &&
		*(screenp_to + Columns) == 0)
	{
	    ++screenp_to;
	    ++col;
	}
	if (col < Columns)
	    screen_fill(row, row + 1, col, (int)Columns, ' ', ' ', 0);
    }
}

/*
 * mark all status lines for redraw; used after first :cd
 */
    void
status_redraw_all()
{
    WIN	    *wp;

    for (wp = firstwin; wp; wp = wp->w_next)
	if (wp->w_status_height)
	{
	    wp->w_redr_status = TRUE;
	    redraw_later(NOT_VALID);
	}
}

/*
 * Redraw all status lines that need to be redrawn.
 */
    void
redraw_statuslines()
{
    WIN	    *wp;

    for (wp = firstwin; wp; wp = wp->w_next)
	if (wp->w_redr_status)
	    win_redr_status(wp);
}

/*
 * Redraw the status line of window wp.
 *
 * If inversion is possible we use it. Else '=' characters are used.
 */
    void
win_redr_status(wp)
    WIN	    *wp;
{
    int	    row;
    char_u  *p;
    int	    len;
    int	    fillchar;
    int	    attr;

    if (wp->w_status_height)			/* if there is a status line */
    {
	fillchar = highlight_status(&attr, wp == curwin);

	p = wp->w_buffer->b_fname;
	if (p == NULL)
	    STRCPY(NameBuff, "[No File]");
	else
	{
	    home_replace(wp->w_buffer, p, NameBuff, MAXPATHL, TRUE);
	    trans_characters(NameBuff, MAXPATHL);
	}
	p = NameBuff;
	len = STRLEN(p);

	if (wp->w_buffer->b_help || buf_changed(wp->w_buffer) ||
							 wp->w_buffer->b_p_ro)
	    *(p + len++) = ' ';
	if (wp->w_buffer->b_help)
	{
	    STRCPY(p + len, "[help]");
	    len += 6;
	}
	if (buf_changed(wp->w_buffer))
	{
	    STRCPY(p + len, "[+]");
	    len += 3;
	}
	if (wp->w_buffer->b_p_ro)
	{
	    STRCPY(p + len, "[RO]");
	    len += 4;
	}

	if (len > ru_col - 1)
	{
	    p += len - (ru_col - 1);
	    *p = '<';
	    len = ru_col - 1;
	}

	row = wp->w_winpos + wp->w_height;
	screen_puts(p, row, 0, attr);
	screen_fill(row, row + 1, len, ru_col, fillchar, fillchar, attr);

	win_redr_ruler(wp, TRUE);
    }
    else    /* no status line, can only be last window */
	redraw_cmdline = TRUE;
    wp->w_redr_status = FALSE;
}

/*
 * Output a single character directly to the screen and update NextScreen.
 */
    void
screen_putchar(c, row, col, attr)
    int	    c;
    int	    row, col;
    int	    attr;
{
    char_u	buf[2];

    buf[0] = c;
    buf[1] = NUL;
    screen_puts(buf, row, col, attr);
}

/*
 * Put string '*text' on the screen at position 'row' and 'col', with
 * attributes 'attr', and update NextScreen.
 * Note: only outputs within one row, message is truncated at screen boundary!
 * Note: if NextScreen, row and/or col is invalid, nothing is done.
 */
    void
screen_puts(text, row, col, attr)
    char_u  *text;
    int	    row;
    int	    col;
    int	    attr;
{
    char_u  *screenp;

    if (NextScreen != NULL && row < Rows)	    /* safety check */
    {
	screenp = LinePointers[row] + col;
	while (*text && col < Columns)
	{
	    if (*screenp != *text || *(screenp + Columns) != attr ||
								exmode_active)
	    {
		*screenp = *text;
		*(screenp + Columns) = attr;
		screen_char(screenp, row, col);
	    }
	    ++screenp;
	    ++col;
	    ++text;
	}
    }
}

#ifdef EXTRA_SEARCH
/*
 * Prepare for 'searchhl' highlighting.
 */
    static void
start_search_hl()
{
    if (p_hls && !no_hlsearch)
    {
	search_hl_prog = last_pat_prog();
	search_hl_attr = hl_attr(HLF_L);
	search_hl_ic = reg_ic;
    }
}

/*
 * Clean up for 'searchhl' highlighting.
 */
    static void
end_search_hl()
{
    if (search_hl_prog != NULL)
    {
	vim_free(search_hl_prog);
	search_hl_prog = NULL;
    }
}
#endif

/*
 * Reset cursor position. Use whenever cursor was moved because of outputting
 * something directly to the screen (shell commands) or a terminal control
 * code.
 */
    void
screen_start()
{
    screen_cur_row = screen_cur_col = 9999;
}

/*
 * Note that the cursor has gone down to the next line, column 0.
 * Used for Ex mode.
 */
    void
screen_down()
{
    screen_cur_col = 0;
    if (screen_cur_row < Rows - 1)
	++screen_cur_row;
}

      static void
screen_start_highlight(attr)
      int	attr;
{
    struct attr_entry *aep = NULL;

    screen_attr = attr;
    if (full_screen
#ifdef WIN32
		    && termcap_active
#endif
				       )
    {
#ifdef USE_GUI
	if (gui.in_use)
	{
	    char	buf[20];

	    sprintf(buf, "\033|%dh", attr);		/* internal GUI code */
	    OUT_STR(buf);
	}
	else
#endif
	{
	    if (attr > HL_ALL)				/* special HL attr. */
	    {
		if (*T_CCO != NUL)
		    aep = syn_cterm_attr2entry(attr);
		else
		    aep = syn_term_attr2entry(attr);
		if (aep == NULL)	    /* did ":syntax clear" */
		    attr = 0;
		else
		    attr = aep->ae_attr;
	    }
	    if ((attr & HL_BOLD) && T_MD != NULL)	/* bold */
		out_str(T_MD);
	    if ((attr & HL_STANDOUT) && T_SO != NULL)	/* standout */
		out_str(T_SO);
	    if ((attr & HL_UNDERLINE) && T_US != NULL)	/* underline */
		out_str(T_US);
	    if ((attr & HL_ITALIC) && T_CZH != NULL)	/* italic */
		out_str(T_CZH);
	    if ((attr & HL_INVERSE) && T_MR != NULL)	/* inverse (reverse) */
		out_str(T_MR);

	    /*
	     * Output the color or start string after bold etc., in case the
	     * bold etc. override the color setting.
	     */
	    if (aep != NULL)
	    {
		if (*T_CCO != NUL)
		{
		    if (aep->ae_u.cterm.fg_color)
			term_fg_color(aep->ae_u.cterm.fg_color - 1);
		    if (aep->ae_u.cterm.bg_color)
			term_bg_color(aep->ae_u.cterm.bg_color - 1);
		}
		else
		{
		    if (aep->ae_u.term.start != NULL)
			out_str(aep->ae_u.term.start);
		}
	    }
	}
    }
}

      void
screen_stop_highlight()
{
    int	    do_ME = FALSE;	    /* output T_ME code */

    if (screen_attr
#ifdef WIN32
			&& termcap_active
#endif

⌨️ 快捷键说明

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